Greasy Fork

Greasy Fork is available in English.

Youtube polymer engine fixes

Some fixes for Youtube polymer engine

当前为 2020-06-21 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Youtube polymer engine fixes
// @description  Some fixes for Youtube polymer engine
// @namespace    bo.gd.an[at]rambler.ru
// @version      0.4
// @match        https://www.youtube.com/*
// @compatible   firefox 56
// @author       Bogudan
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';
	// test local storage availability (required for settings saving) and load settings
	var settings = {}, ls, styles = [];
	function lsTest (st, v) {
		st.setItem ('__fix_test__', v);
		return st.getItem ('__fix_test__') == v;
	    };
	try {
		var _s = window.localStorage;
		if (lsTest (_s, 'qwe') && lsTest (_s, 'rty')) { // do 2 times just in case LS stored value once, but does not let change it later
			ls = _s;
			settings = JSON.parse (ls.getItem ('__fix__settings__')) || {};
		    }
	    }
	catch (e) { }
	// settings
	console.log ('fix settings:', settings);
	function getSetting (nm, def) { return nm in settings ? settings [nm] : def; }
	var presettings = {
	    // hide "guide" menu
		"hide_guide": {
			type: "bool",
			def: true,
			desc: "Hide \"Guide\" menu when page opens",
			act: (X) => {
				if (!X) return;
				var guide_button = document.getElementById ('guide-button');
				if (!guide_button) return;
			    var tmp = guide_button.getElementsByTagName ('button');
				if (!tmp.length) return;
				tmp = tmp [0].attributes;
				if (tmp && tmp ['aria-pressed'].value == 'true')
					guide_button.click ();
		        }
			},
		// decrease text sizes
		"reduce_font": {
			type: "bool",
			def: true,
			desc: "Reduce font size in video descriptions",
			act: (X) => {
				if (!X) return;
				styles.push ('#video-title.ytd-rich-grid-video-renderer,#text.ytd-channel-name,#metadata-line.ytd-video-meta-block{font-size:14px!important;line-height:1.2em!important}');
				// fix: "not interested" placeholder bigger than original element by about 40%
				styles.push ('paper-button.style-blue-text{padding:0!important}');
			    }
		    },
		// fix: home page thumbnails size (1/3 of original image sizes)
		"reduce_thumbnail": {
			type: "bool",
			def: true,
			desc: "Reduce thumbnails width to 240px",
			act: (X) => {
				if (X)
					styles.push ('ytd-rich-item-renderer{width:240px!important}');
			    }
		    },
		"default_player_640": {
			type: "bool",
			def: false,
			desc: "Set player width to 640px in default mode",
			act: (X) => {
				if (X)
					styles.push ('ytd-watch-flexy[flexy_] #player-container-outer.ytd-watch-flexy{min-width:640px!important;max-width:640px!important}');
				// maybe all selector for entire column: ytd-watch-flexy[flexy_][is-two-columns_][is-four-three-to-sixteen-nine-video_] #primary.ytd-watch-flexy
			    }
		    },
		"hide_yt_suggested_blocks": {
			type: "bool",
			def: true,
			desc: "Hide YouTube suggestions blocks like \"Recommended playlists\" or \"Latest YouTube posts\"",
			act: (X) => {
				if (X)
					styles.push ('div#contents.ytd-rich-grid-renderer ytd-rich-section-renderer{display:none!important}');
			    }
		    },
		"unfix_header": {
			type: "bool",
			def: true,
			desc: "Unstick header bar from top of the screen",
			act: (X) => {
				if (X)
					styles.push ('div#masthead-container.ytd-app,ytd-mini-guide-renderer.ytd-app{position:absolute!important}');
			    }
		    },
	    };
	// catch "settings" page
    if (document.location.pathname == '/fix-settings') {
		document.title = "YouTube Polymer Fixes: Settings";
		var plane = document.createElement ('div'), e1, e2;
		plane.setAttribute ('style', 'position:absolute;left:0;top:0;right:0;bottom:0;background:#eee;padding:3em');
		function addLine () {
			var q = document.createElement ('div');
			for (var i = 0, L = arguments.length; i < L; ++i)
				q.appendChild (arguments [i]);
			q.setAttribute ('style', 'margin:1em');
			plane.appendChild (q);
		    }
		e1 = document.createElement ('b');
		e1.appendChild (document.createTextNode ('YouTube Polymer Fixes: Settings'));
		addLine (e1);
		if (!ls) {
			e1 = document.createElement ('span');
			e1.style = 'color:red';
			e1.appendChild (document.createTextNode ('Cannot edit settings: no access to local storage.'));
			e2 = document.createElement ('span');
			e2.appendChild (document.createTextNode ('If you using Firefox, allow cookies for this site.'));
			addLine (e1, e2);
		    }
		else {
			for (var S in presettings) {
				var p = presettings [S];
				var val = getSetting (S, p.def);
				if (p.type == "bool") {
					e1 = document.createElement ('input');
					e1.setAttribute ('type', 'checkbox');
					if (val)
						e1.setAttribute ('checked', '');
					e1.name = '__fix__' + S;
					e2 = document.createElement ('span');
					e2.appendChild (document.createTextNode (p.desc));
					addLine (e1, e2);
				    }
			    }
			e1 = document.createElement ('input');
			e1.setAttribute ('type', 'button');
			e1.setAttribute ('style', 'padding:0.4em;border:1px solid #888');
			e1.value = 'Save settings and return to YouTube';
			e1.addEventListener ('click', function () {
				settings = {};
				for (var S in presettings) {
					var p = presettings [S];
					var e = document.getElementsByName ('__fix__' + S);
					if (p.type == "bool")
						settings [S] = e [0].checked; // checkbox
				    }
				ls.setItem ('__fix__settings__', JSON.stringify (settings));
				alert ('Settings saved');
				history.back ();
			    });
			e2 = document.createElement ('input');
			e2.setAttribute ('type', 'button');
			e2.setAttribute ('style', 'padding:0.4em;border:1px solid #888');
			e2.value = 'Return to YouTube without saving';
			e2.addEventListener ('click', function () {
				history.back ();
			    });
			addLine (e1, document.createTextNode (' '), e2);
		    }
		document.body.appendChild (plane);
		return;
	    }
	// "settings" button
	function createSettingsButton () {
	    var toolBar = document.getElementsByTagName ('ytd-topbar-menu-button-renderer');
		var _1st = toolBar [0];
		if (!_1st)
			return setTimeout (createSettingsButton, 1000);
		toolBar = _1st.parentNode;
		var sb = document.createElement ('ytd-topbar-menu-button-renderer');
		sb.className = 'style-scope ytd-masthead style-default';
		sb.setAttribute ('use-keyboard-focused', '');
		sb.setAttribute ('is-icon-button', '');
		sb.setAttribute ('has-no-text', '');
		toolBar.insertBefore (sb, toolBar.childNodes [0]);
		var icb = document.createElement ('yt-icon-button');
		icb.id = 'button';
		icb.className = 'style-scope ytd-topbar-menu-button-renderer style-default';
		var aa = document.createElement ('a');
		aa.className = 'yt-simple-endpoint style-scope ytd-topbar-menu-button-renderer';
		aa.setAttribute ('tabindex', '-1');
		aa.setAttribute ('href', '/fix-settings');
		aa.appendChild (icb);
		//aa.appendChild (tt);
		sb.getElementsByTagName ('div') [0].appendChild (aa); // created by YT scripts
		var bb = icb.getElementsByTagName ('button') [0]; // created by YT scripts
		bb.setAttribute ('aria-label', 'fixes settings');
		var ic = document.createElement ('yt-icon');
		ic.className = 'style-scope ytd-topbar-menu-button-renderer';
		bb.appendChild (ic);
		var gpath = document.createElementNS ('http://www.w3.org/2000/svg', 'path');
		gpath.className.baseVal = 'style-scope yt-icon';
		gpath.setAttribute ('d', 'M1 20l6-6h2l11-11v-1l2-1 1 1-1 2h-1l-11 11v2l-6 6h-1l-2-2zM13 15l2-2 8 8v1l-1 1h-1zM9 11l2-2-2-2 1.5-3-3-3h-2l3 3-1.5 3-3 1.5-3-3v2l3 3 3-1.5z');
		var svgg = document.createElementNS ('http://www.w3.org/2000/svg', 'g');
		svgg.className.baseVal = 'style-scope yt-icon';
		svgg.appendChild (gpath);
		var svg = document.createElementNS ('http://www.w3.org/2000/svg', 'svg');
		svg.className.baseVal = 'style-scope yt-icon';
		svg.setAttributeNS (null, 'viewBox', '0 0 24 24');
		svg.setAttributeNS (null, 'preserveAspectRatio', 'xMidYMid meet');
		svg.setAttribute ('focusable', 'false');
		svg.setAttribute ('style', 'pointer-events: none; display: block; width: 100%; height: 100%;');
		svg.appendChild (svgg);
		ic.appendChild (svg); // YT clears *ic
	    }
    createSettingsButton ();
	// hide "guide" menu
	for (var S in presettings) {
		var p = presettings [S];
		p.act (getSetting (S, p.def));
	    }
	// styles
	if (styles.length > 0) {
	    var style_element = document.createElement ('style');
	    style_element.type = 'text/css';
	    style_element.innerHTML = styles.join ('');
		document.body.appendChild(style_element);
	    }
    })();