Полезная информация

Юристы зарабатывают огромные деньги и славу, оперируя хорошим знанием законов. Правила форума — простой путь к успешному общению.

№1605109-11-2021 22:04:39

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 165
UA: Firefox 94.0

Re: Custom Buttons

voqabuhe
Мало ли что и кто напишет. Хочешь сделать хорошо - сделай сам. Тем более, уже сказал ,что

voqabuhe пишет

memoryMinimizationButton.uc.js

-  не того и индикатора нет и чистит так себе...

Отсутствует

 

№1605209-11-2021 22:27:12

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3070
UA: Firefox 94.0

Re: Custom Buttons

ВВП пишет

не того и индикатора нет и чистит так себе...

Дык сказал же, чистит абсолютно идентично about:memory. А "индикатор" есть отдельно №16013. Зато без дополнительных приблуд.

Отсутствует

 

№1605310-11-2021 00:09:38

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 165
UA: Firefox 93.0

Re: Custom Buttons

Dumby
Не могу вставить var args = [link,"/add"];   В кн. видео . Чтобы в плейлист ,а не сходу плей.

скрытый текст

Выделить код

Код:

(func => {
	var sysPlayerName = "Pot Player";
	var path = "D:\\PotPlayer\\PotPlayerMini64.exe";
	var videoMoved = "Видео перенесено в " + sysPlayerName;
	var noFound = "Не найдено видео на странице, доступное для переноса в " + sysPlayerName;

	
	this.label = "Открыть видео в " + sysPlayerName;
	this.tooltipText = "Л: Видео в плеер\nП: Видео из Clipboard";

	this._handleClick = () => {
		var msgName = _id + ":Player";
		var listener = ({data}) => data ? run([data]) : notify();
                var listener = ({data}) => data ? run([data], true) : notify();
		messageManager.addMessageListener(msgName, listener);
		addDestructor(() => messageManager.removeMessageListener(msgName, listener));

		var url = "data:charset=utf-8," + encodeURIComponent(
			`(${func})()`.replace("MSG_NAME", msgName)
				.replace("VIDEO_MOVED", encodeURIComponent(videoMoved))
				.replace("CONFIRM", encodeURIComponent("Открыть ссылку в плеере ?"))
		);
		(this._handleClick = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))();
                
	}
	this.onclick = e => e.button != 1 || gShowPopup(this); 
	this.oncontextmenu = e => {
		if (e.ctrlKey || e.shiftKey || e.altKey) return;
		e.preventDefault();
		custombuttons.confirmBox(null, "Запустить плеер из буфера обмена ?", "Да", "Нет")
                        && run([gClipboard.read(),]);
                      
			
	}
	var popup = document.getElementById("contentAreaContextMenu");
	addEventListener("popupshowing", {
		get hidden() {
			return !(gContextMenu.onLink || gContextMenu.onVideo || gContextMenu.onPlainTextLink);
		},
		handleEvent() {
			if (this.hidden) return;
			var menuitem = document.createXULElement("menuitem");
			for(var args of Object.entries({
				image: self.image,
				oncommand: "play()",
				class: "menuitem-iconic",
				label: "Открыть в " + sysPlayerName
			}))
				menuitem.setAttribute(...args);
			menuitem.play = () => play(gContextMenu.linkURL || gContextMenu.mediaURL);
			document.getElementById("context-savelink").before(menuitem);
			addDestructor(() => menuitem.remove());
			this.handleEvent = e => {
				if (e.target == popup) menuitem.hidden = this.hidden;
			}
		}
	}, false, popup || 1);

	var play = link => custombuttons.confirmBox(null, "Открыть ссылку в плеере ?", "Да", "Отмена") && run([link]);
	/*
	var run = args => {
		var file = FileUtils.File(path);
		(run = args => {
			if (!file.exists()) return custombuttons.alertBox("File not exists!", path);
			var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
			process.init(file);
			process.runwAsync(args, args.length);
		})(args);
	}
*/
	var run = (...a) => {
		var file = FileUtils.File(path);
		(run = (args, quit) => {
			if (!file.exists()) return custombuttons.alertBox("File not exists!", path);
			var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
			process.init(file);
			process.runwAsync(args, args.length);
			quit && window.close();
		})(...a);
	}
	var notify = () => {
		var name = _id + "-noFound";
		var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
		(notify = () => setTimeout(as.closeAlert, 1150, name, as.showAlertNotification(
			"chrome://global/skin/icons/question-48.png", "", noFound, false, "", null, name
		)))();
	}

})(() => {

	var found, videoMoved, SEND = msg => {
		found = true;
		if (!msg || Cc["@mozilla.org/embedcomp/prompt-service;1"]
			.getService(Ci.nsIPromptService)
			.confirm(content, null, decodeURIComponent("CONFIRM"))
		) {
			if (msg) videoMoved = decodeURIComponent("VIDEO_MOVED");
			sendAsyncMessage("MSG_NAME", msg);
		}
		else return true;
	}

	var YoutubeID = /(?:youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})(?:\W|$)/;

	var tmp = '',
	tmpp = '',
	innerA = '<div style="display:block!important;color:#00ff00!important;width:250px!important;font:bold 16px serif!important;z-index:999!important;opacity:1!important;visibility: visible!important;',
	innerB = 'left:5px!important;position:absolute!important;height:auto!important;box-sizing:border-box!important;padding:5px!important;margin:5px!important;',
	//stopPl = "javascript:(function(){v=document.getElementById('movie_player');if(v){v.stopVideo()}else{v=document.getElementsByTagName('video');if(v){v[0].src='';try{v[0].load()}catch(e){}};}})();",
	ytIMGouter = function (ytID) {
		return '<div width="100%"><br /><a target="_blank" href="https://www.youtube.com/watch?v=' + ytID + '"><img src="https://i.ytimg.com/vi/' + ytID + '/hqdefault.jpg"></a><br />' + innerA + 'background-color:black!important;position:relative!important;bottom:20px!important;">&nbsp;&nbsp;' + videoMoved + '</div><br /></div><br />'
	},
	handlWin = function (currentWin) {
		tmp = '';
		var elem = currentWin.document.getElementsByTagName('video'),
		currLoc = currentWin.location;
		if (elem.length > 0) {
			if (currLoc.hostname.indexOf('youtu') != -1 && (tmp = currLoc.toString().match(YoutubeID)) && tmp[1].length == 11) {

				if (SEND('https://www.youtube.com/watch?v=' + tmp[1])) return;

				videoMovedbox = currentWin.document.createElement('videoMoved');
				videoMovedbox.innerHTML = innerA + innerB + 'top:-15px!important;"><b>' + videoMoved + '</b></div>';

				//loadURI(stopPl);
				(function(d){var v=d.getElementById('movie_player');if(v){try{v.stopVideo()}catch{}}
					else{v=d.getElementsByTagName('video');if(v[0]){v[0].src='';try{v[0].load()}catch{}};}})(currentWin.document);

				currentWin.document.getElementById('eow-title').appendChild(videoMovedbox);
				return true;
			};
			for (i = 0; i < elem.length; i++) {
				if (((tmp = getSrc(elem[i].parentNode, currLoc)) && tmp.length > 2) || (i == 0 && currentWin.document.body.innerHTML.substring(0, 7) == '<video ' && (tmp = currLoc.toString()))) {

					if (SEND(tmp)) return;

					videoMovedbox = currentWin.document.createElement('videoMoved');
					videoMovedbox.innerHTML = innerA + innerB + 'top:20px!important;background-color:black!important;">' + videoMoved + '</div>';

					if (currLoc.hostname == 'www.youtube.com') {
						elem[i].parentNode.parentNode.appendChild(videoMovedbox);
					} else {
						elem[i].parentNode.appendChild(videoMovedbox);
					};
					elem[i].src = '';
					try {
						elem[i].load()
					} catch (e) {};
					return true;
				}
			}
		};

		currentWin._elems = currentWin.document.getElementsByTagName('iframe');
		if (currentWin._elems.length > 0) {
			for (currentWin._iCounter = 0; currentWin._iCounter < currentWin._elems.length; currentWin._iCounter++) {
				if ((currentWin._elems[currentWin._iCounter].src.indexOf('youtube.com') > -1) && (tmp = currentWin._elems[currentWin._iCounter].src.match(YoutubeID)) && (tmp[1].length == 11)) {

				if (SEND('https://www.youtube.com/watch?v=' + tmp[1])) return;

				currentWin._elems[currentWin._iCounter].outerHTML = ytIMGouter(tmp[1]);
					return true;
				};
				if (currentWin._elems[currentWin._iCounter].clientWidth > 80 && currentWin._elems[currentWin._iCounter].clientHeight > 40 && handlWin(currentWin._elems[currentWin._iCounter].contentWindow))
					return true;
			}
		};

		elem = currentWin.document.getElementsByTagName('object');
		currLoc = currentWin.location;
		if (elem.length == 0) {
			elem = currentWin.document.getElementsByTagName('embed')
		};
		if (elem.length > 0) {
			for (i = 0; i < elem.length; i++) {
				if (elem[i].innerHTML.indexOf('youtu') != -1 && (tmp = elem[i].innerHTML.match(YoutubeID)) && tmp[1].length == 11) {

					if (SEND('https://www.youtube.com/watch?v=' + tmp[1])) return;

					elem[i].outerHTML = ytIMGouter(tmp[1]);
					return true;
				} else {
					if (elem[i].clientWidth > 80 && elem[i].clientHeight > 40) {
						if (((tmp = getSrc(elem[i].parentNode, currLoc)) || (tmp = getLink(elem[i], currLoc))) && tmp.length > 2) {

							if (SEND(tmp)) return;

							elem[i].outerHTML = innerA + 'background-color:black!important;bottom:20px!important;">&nbsp;&nbsp;' + videoMoved + '</div>';
							return true;
						};
					};
				}
			};
		};
		return false;
	};

	function restProtHost(lnkR, curLoc) {
		if (lnkR.length == 0)
			return '';
		let tr = lnkR.replace(/^:\/\//, curLoc.protocol + "//");
		if (!tr.match(/^https?:\/\//i)) {
			lnkR = tr.replace(/^\/+/, '');
			if (lnkR.split('/')[0].split('?')[0].split('#')[0].toLowerCase().match(/^(?:[-a-z\d]+\.)+[a-z\d]{2,6}$/)) {
				tr = curLoc.protocol + '//' + lnkR;
			} else {
				tr = curLoc.protocol + '//' + curLoc.host + "/" + lnkR;
			}
		};
		return tr;
	};

	function getSrc(vobj, currentLoc) {
		var t = '',
		tt = '';
		if ((((t = vobj.innerHTML.match(/<video.*?\ssrc=(?:(?:'([^']*)')|(?:"([^"]*)")|([^\s]*))/i)) && (t) && (tt = t[1] || t[2] || t[3]) && tt.indexOf('blob:') == -1) || ((t = vobj.innerHTML.match(/<source.*?\ssrc=(?:(?:'([^']*)')|(?:"([^"]*)")|([^\s]*)).*?\stype=['"]?video\//i)) && (t) && (tt = t[1] || t[2] || t[3]))) && tt.length > 2 && tt.indexOf('blob:') == -1) {
			if (tt.indexOf(".mp4/?") == -1) {
				tt = tt.replace(/&amp;/g, "&")
			};
			t = restProtHost(tt, currentLoc);
			return t;
		};
		return '';
	};

	function getLink(obj, curLocation) {

		if (!obj || !obj.tagName)
			return '';
		q = obj.tagName.toLowerCase();

		var getParam = function (e, n) {
			var v = '',
			r = new RegExp('^(' + n + ')$', 'i'),
			param = e.getElementsByTagName('param');
			for (var igp = 0, p; p = param[igp]; igp++) {
				if (p.hasAttribute('name') && p.getAttribute('name').match(r)) {
					v = p.getAttribute('value');
					break
				};
			};
			return v;
		};

		var restPath = function (f, s) {
			return (f.substring(0, 4) == 'http') ? f : s.replace(/[#?].*$/, '').replace(/[^\/]*$/, f)
		};

		function videoLinkExtract(fl) {
			alert(fl);
			var linkArr = [],
			outLinks = [],
			jj = 0,
			lba = '',
			lbb = '',
			decodeURL = gBrowser.currentURI.spec; {
				try {
					return decodeURIComponent(s)
				} catch (e) {
					return unescape(s)
				}
			};

			for (var ij = 0; ij < 3; ij++) {
				lba = lba + String.fromCharCode(parseInt((Math.random() * 15 + 1) + '', 10));
				lbb = lbb + String.fromCharCode(parseInt((Math.random() * 15 + 16) + '', 10));
			};

			function pushWithMerit(lnk) {

				var merit = -11;
				if (lnk.match(/^https?:\/\//i))
					merit = merit + 40;
				if (outLinks.length == 0)
					merit = merit + 1;
				if (lnk.match(/^\//))
					merit = merit + 7;
				if (lnk.match(/^\/\//))
					merit = merit + 30;
				if (lnk.match(/240p([^a-z]|$)/i))
					merit = merit + 1;
				if (lnk.match(/[^a-z]240([^a-z0-9]|$)/i))
					merit = merit + 1;
				if (lnk.match(/360p([^a-z]|$)/i))
					merit = merit + 3;
				if (lnk.match(/[^a-z]360([^a-z0-9]|$)/i))
					merit = merit + 3;
				if (lnk.match(/480p([^a-z]|$)/i))
					merit = merit + 5;
				if (lnk.match(/[^a-z]480([^a-z0-9]|$)/i))
					merit = merit + 5;
				if (lnk.match(/720p([^a-z]|$)/i))
					merit = merit + 7;
				if (lnk.match(/[^a-z]720([^a-z0-9]|$)/i))
					merit = merit + 7;
				if (lnk.match(/\.mp4([^a-z]|$)/i))
					merit = merit + 8;
				if (lnk.match(/_hd([^a-z]|$)/i))
					merit = merit + 6;
				if (lnk.match(/\.(jpg|xml)([^a-z]|$)/i))
					merit = merit - 40;
				if (merit > 0)
					outLinks.push(merit + lba + lnk);
				Services.console.logStringMessage('merit:' + merit + ' lnk->' + lnk);
			};

			linkArr.push(fl);
			while (linkArr.length > jj && jj < 30) {

				var testPaths = [];
				testPaths = linkArr[jj].split(/(\.(?:flv|mp4|m3u8))/i);
				if (testPaths[testPaths.length - 1] == '')
					testPaths.pop();

				for (k = 1; k < testPaths.length; k = k + 2) {

					if (testPaths[k - 1].indexOf(lba) > -1) {
						pref = testPaths[k - 1];
					} else {
						var testAboutDom = testPaths[k - 1].toLowerCase().split(/(https?:\/\/)/);
						if (testAboutDom[testAboutDom.length - 1] == '')
							testAboutDom.pop();
						var pTest = testAboutDom[testAboutDom.length - 1].split(/(\?[^\?]*?&)/);
						if (pTest.length > 2) {
							pTest.pop();
							pTest.pop();
						};
						testAboutDom[testAboutDom.length - 1] = pTest.join('');
						pref = testPaths[k - 1].substring(testAboutDom.join('').lastIndexOf("&") + 1);
					};

					t2 = pref.lastIndexOf(lbb);
					if (t2 > -1) {
						pref = pref.substring(t2 + 3);
					} else {

						t2 = pref.lastIndexOf('{"');
						if (t2 > -1)
							pref = pref.substring(t2 + 2);
						t2 = pref.lastIndexOf('["');
						if (t2 > -1)
							pref = pref.substring(t2 + 2);
						t2 = pref.lastIndexOf(',"');
						if (t2 > -1)
							pref = pref.substring(t2 + 2);
						t2 = pref.toLowerCase().lastIndexOf('"http://');
						if (t2 > -1)
							pref = pref.substring(t2 + 1);
						t2 = pref.toLowerCase().lastIndexOf('"https://');
						if (t2 > -1)
							pref = pref.substring(t2 + 1);
						t2 = pref.toLowerCase().lastIndexOf(',http://');
						if (t2 > -1)
							pref = pref.substring(t2 + 1);
						t2 = pref.toLowerCase().lastIndexOf(',https://');
						if (t2 > -1)
							pref = pref.substring(t2 + 1);
						t2 = pref.toLowerCase().lastIndexOf(';http');
						if (t2 > -1)
							pref = pref.substring(t2 + 1);
						t2 = pref.toLowerCase().lastIndexOf('*https://');
						if (t2 > -1)
							pref = pref.substring(t2 + 1);
						t2 = pref.toLowerCase().lastIndexOf(' or ');
						if (t2 > -1)
							pref = pref.substring(t2 + 4);

						pref = pref.substring(pref.split('/')[0].toLowerCase().split('%2f')[0].lastIndexOf('=') + 1);

					}

					if (pref.length > 0) {

						if (pref.split('?')[0].toLowerCase().match(/%[2-3][0-9a-f]/)) {

							t2 = pref.indexOf('"')
								if (t2 > -1)
									pref = pref.substring(t2 + 1);
								suff = testPaths[k + 1] ? testPaths[k + 1].split('&')[0].split('"')[0].split(';')[0].split(/,http/i)[0] : '';
							if ((suff != testPaths[k + 1]) || (testPaths.length < k + 3)) {
								if (testPaths.length > k + 1) {
									testPaths[k + 1] = ((pref == testPaths[k - 1]) ? '' : '&') + testPaths[k + 1].substr(suff.length)
								};
								t2 = pref.lastIndexOf(lba);
								if (t2 > -1)
									pref = pref.substring(t2 + 3)
										linkArr.push(decodeURL(pref + testPaths[k] + suff));

							} else {
								testPaths[k + 1] = (pref == testPaths[k - 1] ? '' : lbb) + pref + testPaths[k] + suff
							}
						} else {
							suff = testPaths[k + 1] ? testPaths[k + 1].split(';')[0].split('"]')[0].split('"}')[0].split('",')[0].split(/,https?:\/\//i)[0].split('*https://')[0].split(' or ')[0] : '';
							t2 = suff.indexOf('&');
							if ((t2 > -1) && (pref != testPaths[k - 1])) {
								if (t2 == 0)
									suff = '';
								if (suff.charAt(0) != '?')
									suff = suff.split(/(&[^&]+=https?:\/\/)/i)[0];
							};
							if ((suff != testPaths[k + 1]) || (testPaths.length < k + 3)) {
								if (testPaths.length > k + 1) {
									testPaths[k + 1] = ((pref == testPaths[k - 1]) ? '' : '&') + testPaths[k + 1].substr(suff.length)
								};
								t2 = pref.lastIndexOf(lba);
								if (t2 > -1)
									pref = pref.substring(t2 + 3);
								pushWithMerit(pref + testPaths[k] + suff);

							} else {
								testPaths[k + 1] = lba + (pref == testPaths[k - 1] ? '' : lbb) + pref + testPaths[k] + suff
							}
						}
					}
				};
				jj = jj + 1;
			};

			if (outLinks.length == 0)
				return '';
			function srt(a, b) {
				a = parseInt(a.substr(0, a.indexOf(lba)), 10);
				b = parseInt(b.substr(0, b.indexOf(lba)), 10);
				if (a < b)
					return 1;
				if (a > b)
					return -1;
				return 0
			};
			outLinks.sort(srt);
			outLinks[0] = outLinks[0].substr(outLinks[0].indexOf(lba) + 3)
				if (outLinks[0].indexOf('_hq.mp4/?time=') > 0)
					outLinks[0] = outLinks[0].replace(/&/g, '&amp;');
				return outLinks[0];
		};

		if (!ol)
			return '';
		//ol = ol.replace(/^:?\/\//, curLocation.protocol + "//");
		//return restPath(ol, src);
		return restProtHost(ol, curLocation);
	};

	try {handlWin(content);} finally {found || SEND();}
});

 var style = custombutton.buttonGetHelp(self).replace(/id/g, _id);
var uri = makeURI('data:text/css,'+ encodeURIComponent(style));
var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
sss.loadAndRegisterSheet(uri, 0);

Отредактировано ВВП (10-11-2021 00:10:13)

Отсутствует

 

№1605410-11-2021 01:08:02

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 854
UA: Firefox 94.0

Re: Custom Buttons

А у меня такой индикатор памяти, и чистит нормально. Как бы цвет поменять на зелёный и цвет при наведении мышки на красный.

memory_used_in_urlbar.js

Выделить код

Код:

// https://forum.mozilla-russia.org/viewtopic.php?pid=789048#p789048
// https://forum.mozilla-russia.org/viewtopic.php?pid=789076#p789076
// https://forum.mozilla-russia.org/viewtopic.php?pid=791818#p791818
// https://forum.mozilla-russia.org/viewtopic.php?pid=795879#p795879
(async id => ({

	delay: 2e3,

	val: "",
	init(topic, mm) {
		Services.obs.addObserver(mm = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			this.timer?.cancel();
			Services.obs.removeObserver(mm, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
	},
	observe(win) {
		var df = win.MozXULElement.parseXULToFragment(
/*
			`<hbox id="${id}"><label id="${id += "-label"}"/></hbox>`
*/
			`<hbox id="${id}" tooltiptext="${
				"ЛКМ: Минимизировать потребление памяти&#xA;ПКМ: about:performance&#xA;Ctrl+ПКМ: about:debugging#/runtime/this-firefox"
			}" onclick="event.button || ${
				"memoryMinimizationButton.doMinimize()"
			}"><label id="${id += "-label"}"/></hbox>`
		);
		this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
		(this.observe = async win => {
			this.timer.cancel();
			await new Promise(ChromeUtils.idleDispatch);
/*
			win.document.getElementById("star-button-box")
				.after(win.document.importNode(df, true));
			this.notify();
		})(win);
	},
*/
			var clone = win.document.importNode(df, true);
			clone.firstChild.oncontextmenu = this.about;
			win.document.getElementById("star-button-box").after(clone);
			this.notify();
		})(win);
	},
	about(e) {
		var gb = e.view.gBrowser;
		gb.selectedTab = gb.addTrustedTab(`about:${
			e.ctrlKey ? "debugging#/runtime/this-firefox" : "performance"
		}`);
	},
	async notify() {
		var info = await ChromeUtils.requestProcInfo();
		var bytes = info.memory;
		for(var child of info.children) bytes += child.memory;
		this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT);

		var prev = this.val;
		if ((this.val = this.mgb(bytes)) != prev)
			for(var win of CustomizableUI.windows) {
				var lab = win.document.getElementById(id);
				if (lab) lab.value = this.val;
			}
	},
	mgb: bytes => bytes < 1073741824
		? Math.round(bytes / 1048576) + "MB"
		: (bytes / 1073741824).toFixed(2) + "GB"
}).init("browser-delayed-startup-finished"))("ucf-mem-indicator");

Отсутствует

 

№1605510-11-2021 02:08:20

Dobrov
Участник
 
Группа: Members
Зарегистрирован: 04-10-2011
Сообщений: 220
UA: Firefox 87.0

Re: Custom Buttons

Dumby подскажи, как из js-кода перейти в режим «Адаптивный дизайн» ?
В меню нашёл только идентификатор горячей клавиши key_responsive_DesignMode


xrun1 в твоём скрипте тоже недостаток - не показывает цифры без такого дополнения:

Выделить код

Код:

// Bug 1665318 - In about:processes refresh, ResidentUniqueDistinguishedAmount is slow (Firefox 94+)
		// https://bugzilla.mozilla.org/show_bug.cgi?id=1665318
		parseInt(Services.appinfo.platformVersion) < 94 && Object.assign(this, eval(
			`({${this.notify}})`.replace("memory", "residentSetSize").replace("memory", "residentUniqueSize")
		));

Отредактировано Dobrov (10-11-2021 02:42:17)

Отсутствует

 

№1605610-11-2021 04:06:33

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 854
UA: Firefox 94.0

Re: Custom Buttons

Dobrov
Увидел здесь разговор, вспомнил, что у меня есть в копилке такая кнопка, проверил и на моём [firefox] v94.0.1 работает. А так пользоваться ей не вижу для себя смысла.
Знать количество занятой памяти [firefox] - мне это не надо.
Очистка памяти имела бы для меня смысл, если памяти дофига и отключён файл подкачки pagefile.sys. У меня оперативки 4 гига и хотя в [firefox] отключён дисковый кэш и настроено типа "всё держать в памяти", это не так. Смотрим "Монитор ресурсов" и видим постоянную запись в файл подкачки. И что я очищу? Перезапишу pagefile.sys?

Отсутствует

 

№1605710-11-2021 05:46:16

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3070
UA: Firefox 94.0

Re: Custom Buttons

xrun1 пишет

memory_used_in_urlbar.js

Во, спасибо, хороший вариант.

проверил и на моём [firefox] v94.0.1 работает.

Аналогично.

Отсутствует

 

№1605810-11-2021 06:33:25

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3070
UA: Firefox 94.0

Re: Custom Buttons

xrun1
Интересное обнаружил, memory_used_in_urlbar.js чистит только совместно с memoryMinimizationButton.uc.js, что я выше выкладывал. А если memoryMinimizationButton.uc.js отключить, то ЛКМ в memory_used_in_urlbar.js не срабатывает.

Отсутствует

 

№1605910-11-2021 12:17:40

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 854
UA: Firefox 94.0

Re: Custom Buttons

voqabuhe
Ага, забавно.:)
ЛКМ по циферкам потребления памяти вызывает функцию doMinimize() из скрипта memoryMinimizationButton.uc.js.

скрытый текст

Выделить код

Код:

onclick="event.button || ${
				"memoryMinimizationButton.doMinimize()"


Как бы цвет поменять обычный/при наведении мышки?

Отредактировано xrun1 (10-11-2021 14:28:20)

Отсутствует

 

№1606010-11-2021 16:20:23

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 938
UA: Firefox 91.0

Re: Custom Buttons

xrun1

#ucf-mem-indicator-label:hover {
    color: red !important;
}


Fx 91 esr

Отсутствует

 

№1606110-11-2021 18:18:29

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3070
UA: Firefox 94.0

Re: Custom Buttons

xrun1 пишет

ЛКМ по циферкам потребления памяти вызывает функцию doMinimize() из скрипта memoryMinimizationButton.uc.js.

Ну это я тоже уже инспектором отследил oncommand = memoryMinimizationButton.doMinimize(event); Очевидно в своё время Dumby по чьей-то просьбе объединил  подобным образом эти кнопки. :)

_zt пишет

#ucf-mem-indicator-label:hover {
    color: red !important;
}

А чтоб выделять как обычные кнопки при наведение можно?

Отсутствует

 

№1606210-11-2021 21:19:09

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 938
UA: Firefox 91.0

Re: Custom Buttons

voqabuhe

по чьей-то просьбе объединил

https://forum.mozilla-russia.org/viewto … 69#p789069
   

voqabuhe пишет

выделять как обычные кнопки при наведение

Оформляйте как хотите.

Выделить код

Код:

#ucf-mem-indicator:hover {
    border: 1px solid цвет !important;
    background: ... !important;
или
    background-color: ... !important;
еще можно
    opacity: от 0 или 0.1 до 1 !important;
}

Fx 91 esr

Отсутствует

 

№1606310-11-2021 22:19:43

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3070
UA: Firefox 94.0

Re: Custom Buttons

_zt
Спасибо. А размеры выделения как задать и углы скруглить?

Добавлено 10-11-2021 22:28:40

_zt пишет

по чьей-то просьбе объединил

https://forum.mozilla-russia.org/viewto … 69#p789069

Ну вот теперь совсем всё стало ясно, откуда ноги растут. Спасибо. :)

Отредактировано voqabuhe (10-11-2021 22:28:40)

Отсутствует

 

№1606410-11-2021 22:40:36

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 938
UA: Firefox 91.0

Re: Custom Buttons

voqabuhe
Скруглить - border-radius: 1px !important; значение подберите.
Это не размеры выделения, это размеры контейнера. Соответственно нужно не размер задавать, а поля и отступы.
Как обычно - margin: , padding: если надо то с -top: , -bottom: , -left: , -right: .
И тоже самое для #ucf-mem-indicator-label, если надо выровнять текст внутри контейнера. И еще для label можно все что обычно для текста - width: , text-align: , font-size: , font-style: .
   
И вообще тема не та. :)


Fx 91 esr

Отсутствует

 

№1606510-11-2021 23:09:38

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3070
UA: Firefox 94.0

Re: Custom Buttons

_zt
Спасибо.

Отсутствует

 

№1606611-11-2021 09:25:08

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 1566
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

Я извиняюсь, нельзя еще в кодом memory поработать ? Task - чуть не ноль показывает на пустой вкладке, а на индикаторе 140-160 мгб , в 93 - 60мгб. Кажись графич.редактор не трогает очистка...Это расхождение в цифрах парит немного...

Объяснял же — нет туда доступа.
Могу попробовать через ctypes c nsMemoryReporterManager.cpp срисовать,
но никакой уверенности, что выйдет правильно, разумеется нет.
И, тогда уж, и в jsm'ке только residentUnique оставить, вроде так ближе к «Task».

скрытый текст

Выделить код

Код:

(async id => ({

	delay: 2e3,

	xul: `
		<hbox
			id="${id}"
			tooltiptext="ЛКМ: Очистить Память"
		>
			<label value="ram" id="${id += "-label"}"/>
		</hbox>
	`,
	css: `
		min-height: 26px !important;
		height: 26px !important;
		border-radius: 3px !important;
		padding: 0px 5px 0px !important;
		color: #00ffff !important;
		font-size: 15px !important;
		margin: 0px  1px  1px 3px !important;

		font-weight: 400 !important;
		font-family: segoe ui !important;

		background: linear-gradient(rgb(72, 85, 108),rgb(20, 25, 34)) !important;
	`,
	launch() {
		var file = Services.dirsvc.get("ProfD", Ci.nsIFile);
		["memory", "start.vbs"].forEach(file.append);
		(this.launch = file.launch)();
	},
	val: "",
	name: "UCFMemIndReporter",
	init(topic, mm) {
		Services.obs.addObserver(mm = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			this.timer?.cancel();
			this.close?.();
			Services.obs.removeObserver(mm, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
	},
	observe(win) {
		var df = win.MozXULElement.parseXULToFragment(this.xul);
		this.click = e => e.button || this.launch();
		this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
		ChromeUtils.registerProcessActor(this.name, {
			includeParent: true,
			child: {moduleURI: "chrome://user_chrome_files/content/custom_scripts/memreporter.jsm"}
		});
		(this.observe = async win => {
			this.timer.cancel();
			await new Promise(win.requestAnimationFrame);
			var clone = win.document.importNode(df, true);
			var hbox = clone.firstChild;
			win.document.getElementById("page-action-buttons").append(clone);
			hbox.onclick = this.click;
			hbox.style.cssText = this.css;
			hbox.firstChild.style.setProperty("margin", "0", "important");
			this.notify();
		})(win);
	},
	getUSS(pid) {
		var {ctypes} = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
		var kernel32 = ctypes.open("kernel32");
		this.close = () => kernel32.close();

		// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
		var sysInfo = ctypes.StructType("SYSTEM_INFO", [
			{m0: ctypes.unsigned_long},
			{dwPageSize: ctypes.unsigned_long},
			{m2: ctypes.voidptr_t},
			{m3: ctypes.voidptr_t},
			{m4: ctypes.unsigned_long},
			{m5: ctypes.unsigned_long},
			{m6: ctypes.unsigned_long},
			{m7: ctypes.unsigned_long},
			{m8: ctypes.short},
			{m9: ctypes.short}
		])();
		// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
		// void GetNativeSystemInfo([out] LPSYSTEM_INFO lpSystemInfo);
		kernel32.declare(
			"GetNativeSystemInfo", ctypes.winapi_abi, ctypes.void_t,
			ctypes.voidptr_t
		)(sysInfo.address());
		var pageSize = sysInfo.dwPageSize;

		// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx
		// HANDLE WINAPI OpenProcess(_In_ DWORD dwDesiredAccess, _In_ BOOL  bInheritHandle, _In_ DWORD dwProcessId);
		var OpenProcess = kernel32.declare(
			"OpenProcess", ctypes.winapi_abi, ctypes.voidptr_t,
			ctypes.unsigned_long, ctypes.bool, ctypes.unsigned_long
		);
		// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
		// BOOL WINAPI CloseHandle(_In_ HANDLE hObject);
		var CloseHandle = kernel32.declare(
			"CloseHandle", ctypes.winapi_abi, ctypes.bool,
			ctypes.voidptr_t
		);
		// https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-queryworkingset
		// BOOL QueryWorkingSet([in] HANDLE hProcess, [out] PVOID pv, [in] DWORD cb);
		var QueryWorkingSet = kernel32.declare(
			"K32QueryWorkingSet", ctypes.winapi_abi, ctypes.bool,
			ctypes.voidptr_t, ctypes.voidptr_t, ctypes.unsigned_long
		);
		// https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
		// PROCESS_QUERY_INFORMATION | PROCESS_VM_READ
		var desiredAccess = 0x0400 | 0x0010;

		var num = ctypes.int64_t(0);
		var numArgs = [num.address(), ctypes.int64_t.size];

		// https://searchfox.org/mozilla-central/source/xpcom/base/nsMemoryReporterManager.cpp
		return (this.getUSS = pid => {
			var res = 0;
			try {
				var handle = OpenProcess(desiredAccess, false, pid);
				if (handle.isNull()) return res;

				QueryWorkingSet(handle, ...numArgs);
				if (num.value) {
					var entries = 2 * num.value;

					// https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-psapi_working_set_information
					var wsInfo = ctypes.StructType("PSAPI_WORKING_SET_INFORMATION", [
						{NumberOfEntries: ctypes.unsigned_long},
						{WorkingSetInfo: ctypes.ArrayType(ctypes.uint64_t, entries)}
					])();
					if (QueryWorkingSet(
						handle, wsInfo.address(), wsInfo.WorkingSetInfo.constructor.size
					)) {
						var {NumberOfEntries, WorkingSetInfo} = wsInfo;
						var privatePages = 0;
						// https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-psapi_working_set_block
						for(var ind = 0; ind < NumberOfEntries; ind++) {
							var flags = WorkingSetInfo[ind] >>> 55;
							if (!(flags & 1) || flags >>> 1 & 7 <= 1)
								privatePages++;
						}
						res = privatePages * pageSize;
					}
				}
				CloseHandle(handle);
			} catch {};
			return res;
		})(pid);
	},
	async notify() {
		var bytes = 0, pids = [];
		for(var dp of ChromeUtils.getAllDOMProcesses()) try {
			var [pid, mem] = await dp.getActor(this.name).sendQuery("");
			pids.push(pid);
			bytes += mem;
		} catch {}

		var {children} = await ChromeUtils.requestProcInfo();
		for(var {pid} of children)
			if (!pids.includes(pid))
				bytes += this.getUSS(pid);

		this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT);

		var prev = this.val;
		if ((this.val = this.mgb(bytes)) != prev)
			for(var win of CustomizableUI.windows) {
				var lab = win.document.getElementById(id);
				if (lab) lab.value = this.val;
			}
		//bytes > 734003200 && this.launch();
	},
	mgb: bytes => bytes < 1073741824
		? String(Math.round(bytes / 1048576))
		: (bytes / 1073741824).toFixed(2)
}).init("browser-delayed-startup-finished"))("ucf-mem-uss-indicator");
Выделить код

Код:

var EXPORTED_SYMBOLS = ["UCFMemIndReporterChild"];
var pid = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).processID;
var mrm = Cc["@mozilla.org/memory-reporter-manager;1"].getService(Ci.nsIMemoryReporterManager);
class UCFMemIndReporterChild extends JSProcessActorChild {receiveMessage() {return [pid, mrm.residentUnique];}}

ВВП пишет

Не могу вставить var args = [link,"/add"];

Перед process.runwAsync(args, args.length);
добавить args.push("/add");


kokoss пишет

Возможно ли сюда добавить кнопку: "отключения"

Не, задача добавления в расширение нового функционала не стоит,
только сохранение старого, с приемлимыми потерями.
К тому же, это довольно сложно.

Отсутствует

 

№1606711-11-2021 10:22:15

kokoss
Участник
 
Группа: Members
Зарегистрирован: 15-02-2018
Сообщений: 1158
UA: Firefox 52.0

Re: Custom Buttons

Dumby
Понятно, тогда ещё один вопрос по кнопке "Открыть папки и файлы Firefox", как открыть файл config.js находящийся в папке App/firefox64? Нашёл только вариант как открыть этот файл в папке App/firefox -> value: "CurWorkD,,config.js"

Add, нашёл, "GreD"

Отредактировано kokoss (11-11-2021 17:01:12)


Win7

Отсутствует

 

№1606811-11-2021 10:57:00

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 165
UA: Firefox 94.0

Re: Custom Buttons

Dumby

Dumby пишет

И, тогда уж, и в jsm'ке только residentUnique оставить, вроде так ближе к «Task».

Не понял ? Убрать или оставить?  Тронул и ram вместо цифр ....Не трогаю JSM ...Вроде, все близко к TASK как в 93...
Короче, убрал

скрытый текст
var prop = ai.processType == ai.PROCESS_TYPE_DEFAULT ? "resident" : "residentUnique";
, получил самый близкий результат к Task.Если это не косяк, то это то что надо ! Нет, не то ...Что значит "только residentUnique оставить" ?
Хотя, с новым скриптом показывает даже точнее, чем в 92 и 93...Респект,однозначно !

Отредактировано ВВП (11-11-2021 22:22:06)

Отсутствует

 

№1606911-11-2021 11:46:05

Dobrov
Участник
 
Группа: Members
Зарегистрирован: 04-10-2011
Сообщений: 220
UA: Firefox 88.0

Re: Custom Buttons

del

Отредактировано Dobrov (11-11-2021 18:01:43)

Отсутствует

 

№1607011-11-2021 23:08:05

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 1566
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

Что значит "только residentUnique оставить" ?

Это часть строки комментария,
который объясняет почему предлагается изменить memreporter.jsm


Сам изменённый memreporter.jsm (с "только residentUnique оставленным")
идёт вторым (не первым) кодом под спойлером.

Отсутствует

 

№1607111-11-2021 23:20:49

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 165
UA: Firefox 94.0

Re: Custom Buttons

Dumby
Не фига не понял,какой сплойер  ? где первый ,где второй...Да не увидел сам jsm измененный...Но этот старый - точнее показывает !!!

скрытый текст

Выделить код

Код:

var EXPORTED_SYMBOLS = ["UCFMemIndReporterChild"];
var ai = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
var prop = ai.processType == ai.PROCESS_TYPE_DEFAULT ? "resident" : "residentUnique";
var pid = ai.processID;
var mrm = Cc["@mozilla.org/memory-reporter-manager;1"].getService(Ci.nsIMemoryReporterManager);
class UCFMemIndReporterChild extends JSProcessActorChild {receiveMessage() {return [pid, mrm[prop]];}}

Отредактировано ВВП (11-11-2021 23:43:39)

Отсутствует

 

№1607212-11-2021 00:31:45

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 1566
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

Не фига не понял,какой сплойер  ? где первый ,где второй...Да не увидел сам jsm измененный...

Может очки надень.

Но этот старый - точнее показывает !!!

Тогда не трогай, оставь как есть.

Отсутствует

 

№1607313-11-2021 00:38:03

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 436
UA: Firefox 94.0

Re: Custom Buttons

Может вопрос не по теме. Есть кнопка

скрытый текст
// Proxy, от 10.10.2016.

  var iconProxy = 'data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAQAAAAAIAA4GQAAnFmkAHQ5fAAQAKAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEBAQECAgICAgICAgICAgMBAQEAAAQBJBFQOLQ+nX38ecev/mu6of8gfFvtAyUXewAAAAsAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEBAAAAAAMLUza7PKd//3S7oP2849X9zuvh/mW4mf4XiV7/AB4QZwAAAAAAAAAAAQEBAQAAAAAZGhgTKSwnLyYqJDErKCUnID8vXgaAUP9BlnH8b7ea/ojHrv+q2sf/a7CT+zGWbf8PakXGAAIAAAEBAQMHBwcbAAAAD2BiXn76/ff/4ebg/Onm4f+DtZ7/A31L/j2Wb/+Fwaj/ls23/7rh0v9+vaT+M5du/xKGWO0DIxIdAAAAAAEBAQEAAAABBgYFEaSmorbP08z239vX/4OwnP4ail3/RJlz/5HHsP/T7+X/ms64/3K2mP40k2r/D3tM7AUiExwhIx8meXt1mXt+eKJ3eXSce353n6esouDMysf/o7eq/kOdeP92uZv/vuPT/9Hs4P/C4tT/eLWa+juWbv8bcEq7AAYBAF1gWn7//////f39/P//////////////////////////lcKx/3i9pf/K7OD/2O/l/7ndzf6Fw6n/VK+I/AsxHj8AAAAAXF5bf+Ln2P+AnU/4fZ1N+4WiV/yKp13+jKlh/5CsZf+GpFj/Zpxh/4C5nf+i0L7+k8ex/1udf+UTOCZFAAAAAAEBAQJfYF5/3uXR/16IIPxciiH/Z5Iv/26YOP9ymz3/cpw+/3OcPf9wlzb/YI80/1mKNPu707X/YmZjiAAAAAAEBAQGAAAAAF9gXoDg5tT/cJU6/HGaPf9/pE3/hqtX/4uvXf+NsF7/iKxZ/4KoU/9+o0r/cpY6+9zjyf9ubm2JAAAAAAMEAwQAAAAAX2BegODm1P94nEX8e6JJ/4quXP+Vt2n/nb1z/6LBef+jwXz/ob96/527d/+NrGP71+HG/2praogAAAAABAQDBAAAAABfYF2A4ObU/4WlVvyPsmP/osB7/7HMj/+81J3/wdik/8DXo/+60pz/tc6X/6G6ffvY4sf/amtqiAAAAAAEBAMEAAAAAF9gXn/e5dL/n7l7/LLMk//B16X/zuG2/9jpwv/b68b/2enE/9Pkvv/Q4bv/uMud+9jhyP9qa2mHAAAAAAQEAwQAAAAAX2Bef97k0v+gt335sceT/LrNnfzC1Kj8ydmx/MzatfzK2bP8xtav/MbVr/ywwpL41+HH/2tsaokAAAAABAQDBAAAAABZW1Z3+fz1/+Dm1Pzj6db/5u3b/+nv3v/r8eD/6vDe/+ft2//k69j/4efT/9ngzPv7//b/ZGdhfwAAAAADBAMEAAAAABcZFRpZW1Z6YGFfgWBiYIBhYmGAYmJhgGJjYoBiY2KAYmJhgGFiYYBgYWCAX2BegF1fWoAbHRkeAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';

// Настройка функций кликов мыши для кнопки ...................
this.onclick =e=> {

   // действие при клике ЛКМ ....
   if ( e.button == 0 )openMenuPopup();

   // действие при клике СКМ ....   
   if ( e.button == 1 )
        cbu.getPrefs("CB.Proxy.connectionsInTab") ? openConnectionsInTab() : openConnections();
};



// Подсказка для кнопки ...................
this.onmouseover =()=> {
   var arr = ["Без прокси", "Ручная настройка", "Автоматическая через URL", "", "Автоматическая настройка", "Системная настройка"];
   var str = arr.map((m, i)=> (cbu.getPrefs("network.proxy.type") == i ? "●" : "  ") + m).filter(m=> /\S/.test(m)).join("\n");
     
   this.tooltipText = "Proxy +\n"
      + "\n" + str
      + "\n\nЛ: Mеню кнопки \nС: Открыть настройки прокси"
      + "\n\nТекущие настройки прокси:"
      + "\nIP: " + cbu.getPrefs("network.proxy.http")
      + "\nПорт: " + cbu.getPrefs("network.proxy.http_port")
};



// Создать меню для кнопки ...................
function openMenuPopup() {

   
var array = [
   { label: "Без прокси", value: 0, radio: ''},
   { label: "Ручная настройка сервиса прокси:", value: 1, radio: ''},
   { label: "URL автоматической настройки сервиса прокси", value: 2, radio: ''},
   { label: "Автоматически определять настройки прокси для этой сети", value: 4, radio: ''},
   { label: "Использовать системные настройки прокси", value: 5, radio: ''},
   { separator: ''},
   { label: "Добавление прокси в контекстом меню", value: 'CB.Proxy.inContextMenu', checkbox: ''},
   { label: "Открывать настройки прокси как вкладку", value: 'CB.Proxy.connectionsInTab', checkbox: ''},
   { label: "Переключать на режим 'Без прокси' при закрытии браузера ", value: 'CB.Proxy.reset', checkbox: ''}
   ];
var menuPopup = self.appendChild( document.createXULElement("menupopup") );
menuPopup.setAttribute("onclick", "event.stopPropagation()");

   menuPopup.textContent = "";
 
   array.forEach(m=> {
      if ( "separator" in m ) { menuPopup.appendChild( document.createXULElement("menuseparator") ); return };
      var mItem = menuPopup.appendChild(document.createXULElement("menuitem"))
      mItem.setAttribute("label", m.label);

      if ( "radio" in m ) {
           mItem.setAttribute('type', 'radio');
           mItem.setAttribute('checked', cbu.getPrefs("network.proxy.type") == m.value);
           mItem.onclick =()=> cbu.setPrefs("network.proxy.type", m.value); 
           } 
      if ( "checkbox" in m ) {
           mItem.setAttribute('type', 'checkbox');
           mItem.setAttribute('checked', cbu.getPrefs(m.value) );
           mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); 
           }
   });
menuPopup.openPopup(self, "after_start");
};

var listenClick = win => {
    var args = ["click", win.close.bind(win), true];
    var unload = () => gBrowser.removeEventListener(...args);
    gBrowser.addEventListener(...args);
    win.addEventListener("unload", unload, {once: true});
}
var version = parseInt(Services.appinfo.platformVersion);
var url = `chrome://browser/content/preferences/dialogs/connection.x${version >= 72 ? "htm" : "u"}l`;

var fox73 = version >= 73, noop = () => {};
if (fox73) var grid = win => {
    var url = "data:text/css;charset=utf-8," + encodeURIComponent(`
        #proxy-grid, #dnsOverHttps-grid {
            display: grid;
            grid-template-columns: auto 1fr;
            align-items: center;
        }
        #proxy-grid > .thin {
            grid-column-end: 3;
            height: 20px;
        }
        #dnsOverHttps-grid.custom-container-hidden #networkCustomDnsOverHttpsInput,
        #dnsOverHttps-grid.custom-container-hidden #networkCustomDnsOverHttpsInputLabelContainer {
            display: none;
        }
    `);
    (grid = win => win.windowUtils.loadSheetUsingURIString(url, win.windowUtils.AUTHOR_SHEET))(win);
}
var winOpen = win => win.addEventListener("readystatechange", winReady, {once: true, capture: true});
var winReady = e => {
    var win = e.target.ownerGlobal, cw = win.isChromeWindow;
    if (cw || (win.location == url && !win.docShell.name)) winPatch(win, cw);
}
var winPatch = (win, cw) => {
    win.opener = {gSubDialog: {_dialogs: [{
        _frame: {get contentDocument() {
            cw && listenClick(win);
            delete this.contentDocument;
            return this.contentDocument = win.document;
        }},
        resizeVertically: cw ? () => win.sizeToContent() : noop
    }]}};
    fox73 && grid(win);
}
addEventListener("MozBeforeInitialXULLayout", winReady, false, gBrowser.tabpanels || 1);

for(var {contentWindow: win} of gBrowser.browsers)
    win && win.location == url && !win.opener && winPatch(win);


// Функция открывает настройки прокси в окне ................... 
function openConnections() {
    var win = [...Services.wm.getEnumerator(null)].find(w => w.location == url);
    win ? win.focus() : winOpen(openDialog(url, "Proxy", "centerscreen"));
}

// Функция открывает настройки прокси в вкладке ...................
function openConnectionsInTab() {
    var connections = gBrowser.getBrowserForTab(
        gBrowser.selectedTab = gBrowser.addTrustedTab(url)
    );

    // oбработчик ждет пока откроется прокси, удаляет себя и добавляет атрибут
    connections.addEventListener("pageshow",
        e => e.target.documentElement.setAttribute("type", "prefwindow")
    , {once: true});
}


// Установливать нужную иконку кнопки при старте баузера или при изменениях в 'about:config' ...................
var s = "network.proxy.type";
function toggleImage() {
   var icon = self.icon || self.ownerDocument.getAnonymousElementByAttribute(self, "class", "toolbarbutton-icon");
   switch( cbu.getPrefs(s) ) {
      case 0: icon.src = self.image; break;         
      case 1: icon.src = iconProxy; break;
      case 2: icon.src = iconProxy; break;
      case 4: icon.src = iconProxy; break;
      case 5: icon.src = iconProxy; break;
      default:icon.src = self.image;
   }
}; 
toggleImage();
Services.prefs.addObserver(s, toggleImage, false);
addDestructor(()=> Services.prefs.removeObserver(s, toggleImage));

// Переключать на режим 'Без прокси' при закрытии браузера если это разрешено в 'about:config' ...................
var switchOffProxy = {
    observe: function(subject, topic, data) {
       if ( data == "shutdown" && cbu.getPrefs("CB.Proxy.reset") ) cbu.setPrefs("network.proxy.type", 0); 
    }
};
Services.obs.addObserver(switchOffProxy, "quit-application", false);



// Создаем меню для добавление прокси в контекстном меню выделенного текста на странице ...................
var contextMenu = document.getElementById("contentAreaContextMenu");
var menuitem = document.createElementNS(xulns,"menuitem");
menuitem.setAttribute("label", "Добавить прокси");
menuitem.setAttribute("class", "menuitem-iconic");
menuitem.setAttribute("image", self.image);
menuitem.onclick =()=> addNewProxy(menuitem);
contextMenu.appendChild(menuitem); // как последний пункт меню
addDestructor(() => menuitem.remove());
addEventListener("popupshowing", () => {
    menuitem.hidden = !cbu.getPrefs("CB.Proxy.inContextMenu") || !gContextMenu.isContentSelected; // !gContextMenu.isTextSelected;
}, false, contextMenu);


// добавление прокси ...................
function addNewProxy(menuitem) {
    var sel = gBrowser.contentDocument
        ? gBrowser.contentDocument.defaultView.getSelection().toString() // Pale Moon 
        : gContextMenu.selectionInfo.fullText; // Firefox

    sel = sel.replace(/^\s+|\s+$/g, ""); // удалить пробелы, слева и справа от строки
    sel = sel.replace(/\s+/g, ":");      // заменить пробелы внутри строки

    // если только порт ...
    if (sel.length < 6 && isFinite(sel)) {
        var lab = 'порт';
        cbu.setPrefs("network.proxy.http_port", +sel);                   
    }

    // если только адрес ...
    if (sel.length > 5 && !/:/.test(sel) && sel.split(".").length == 4) {
        var lab = 'адрес';
        cbu.setPrefs("network.proxy.http", convertFromUnicode("UTF-8", sel)); 
    }

    // если адрес и порт ...   
    if (sel.length > 5 && /:/.test(sel) && sel.split(":").length == 2 && sel.split(".").length == 4) {
        var lab = 'адрес и порт';
        var arr = sel.split(":"), IP = arr[0], port = arr[1];
        cbu.setPrefs("network.proxy.http_port", +port);
        cbu.setPrefs("network.proxy.http", convertFromUnicode("UTF-8", IP));
    }

    // всплывающая подсказка рядом с выделенным текстом ...
    var mainPopupSet = document.getElementById('mainPopupSet');
    var tooltip = mainPopupSet.appendChild(document.createElementNS(xulns,"tooltip"));
    tooltip.style.cssText = "color: red !important; font-weight: bold !important; font-size: 14px !important; -moz-box-orient: horizontal; text-align: center;";

    var image = tooltip.appendChild(document.createElementNS(xulns, "image"));
    image.setAttribute("src", self.image);

    var label = tooltip.appendChild(document.createElementNS(xulns, "label"));
    label.setAttribute("value", "Установлен " + lab + " прокси: " + sel);

    tooltip.openPopup(menuitem.parentNode, "before_start");
    setTimeout(() => mainPopupSet.removeChild(tooltip), 3000);
};


// Конвертировать текст в юникод ............. 
function convertFromUnicode(charset, str) {
    var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
    converter.charset = charset;
    str = converter.ConvertFromUnicode(str);
    return str + converter.Finish();
}


В пункте URL автоматической настройки стоит http://antizapret.prostovpn.org/proxy.pac
Чтобы зайти на допустим сайт https://4pda.to/forum (в списке запрещеных) приходится пару раз нажать кнопку "Обновить" в пункте URL автоматической настройки и тогда все открывается.
Кто может объяснить

Отсутствует

 

№1607413-11-2021 16:09:57

Senflex
Участник
 
Группа: Members
Зарегистрирован: 18-07-2021
Сообщений: 29
UA: Chrome 95.0

Re: Custom Buttons

Как программно сделать скриншот сайта и сохранить его в определённую папку. Лиса 56.0.2. Заранее благодарю!

Отредактировано Senflex (13-11-2021 17:00:54)

Отсутствует

 

№1607513-11-2021 18:59:51

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 293
UA: Firefox 91.0

Re: Custom Buttons

Senflex пишет

Как программно сделать скриншот сайта и сохранить его в определённую папку. Лиса 56.0.2. Заранее благодарю!

За давностью не помню кто выкладывал кнопку.
Попробуйте, может подойдёт.

скрытый текст

Выделить код

Код:

/*Initialization Code*/

// Сохранить как PNG ..........

self.label = "Сохранить как PNG";
self._handleClick =()=> menuPopup.showPopup(this, -1, -1, "popup", "bottomleft", "topleft");
self.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGwSURBVHjarJPPaxNBGIafmd1km23saqtRaLB6kFYl2ELpRayCVL20RvCmJwk9ePNWvPsXtCA9eNCDeO0hLemPo96LYAuKkRhtsBViEtI0rrt+GyFQ1oMkfjAf883M+8w7w4zyfZ9uwsxms10RzCBNTd3sSLy2lvsDCCKzWMCKGHgotOTAlpamJPm+jCmFL00bmmbD5WlmsKXTdBltB3bcxowaLWJwsTpi4bvNVu1JMmVn5cmcqTB6/DAg3hcjGpUFskjZjlgFKdmvVIiISKlfUhlyQMVPywgDjvX1YCjpOBZ2fZ+9+TuUpxcZuz7Ebl7ArkfM0dgDcOAFCvfwHTi9URJJi2RCqEuPmRxPUXn9imodLo1D6orGjMHW6govZqfDDkYviDXBlZ4vsFsrk8vXqZRWeDY8hz55lvvpGU7sFEn0RhhTtTBg/tETCvlNdj68papsUoND3Lh6iyPOOYrvv/JufYNrqcssbW8zkjwdBnz7/JKL50/x4F4at9GgsFckX/2IefQHZyb6mbl9l2LpE8ff1PnufWkD/t87yC1v/pvi4V8AwZvuNFS33/m3AAMAhEeAiqLmty4AAAAASUVORK5CYII=";


var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);


// Создать меню для кнопки .....
var array = [
   { label: "Сохранить всю страницу как PNG", func: "WebScreenShot.captureAll()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { separator: ''},
   { label: "Сохранить видимую часть страницы как PNG", func: "WebScreenShot.capturePage()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { separator: ''},
   { label: "Сохранить выбранный элемент страницы как PNG", func: "WebScreenShotByClick.init()", image: "data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { separator: ''},
   { label: "Сохранить выбранную область страницы как PNG", func: "WebScreenShotByClipping.init()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
];

var menuPopup = self.appendChild(document.createElement("menupopup"));
array.forEach((m,i)=> {
   if ("separator" in m) { menuPopup.appendChild(document.createElement("menuseparator")); return };
   var mItem = menuPopup.appendChild(document.createElement("menuitem"));
   mItem.setAttribute("label", m.label);
   mItem.setAttribute("class", "menuitem-iconic");
   if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image);
   if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString()));
});
menuPopup.setAttribute("onclick", "event.stopPropagation()");



// Сохранить как PNG страницу или части страницы .....
WebScreenShot = {
   capture: function(win, x, y, width, height) {
      var canvas = document.createElementNS(xhtmlns, 'canvas');
      canvas.style.display = 'inline';
      canvas.width = width;
      canvas.height = height;
      var ctx = canvas.getContext("2d");
      ctx.clearRect(0, 0, width, height);
      ctx.save();
      try {
        ctx.scale(1.0, 1.0);
      }
      catch(e) {
        alertsService.showAlertNotification("chrome://global/skin/icons/error-16.png", "Слишком большая страница, не могу сохранить всё",
                                            "Кликни чтобы сохранить сколько можно", true, "", (s, t)=> {
           if ( t == 'alertclickcallback' ) WebScreenShot.capture(content, 0, 0, width, width*17);
        }, "");
        return;
      }
      ctx.drawWindow(win, x, y, width, height, "rgb(255,255,255)");
      ctx.restore();
      var url = canvas.toDataURL("image/png");
      var url = Services.io.newURI(url, null, null);

      var fp = window.makeFilePicker();
      fp.init(window, "Сохранить как…", fp.modeSave);
      fp.appendFilters(fp.filterImages);
      fp.defaultExtension = "png";

      var fileName = getTabLabel();
      fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '').replace(/\s+/g, '_').slice(0, 100).replace(/^\s+|\s+$/g, '');
      var fileDate = (function () {
        var d = new Date(), z = function(n){return (n < 10 ? '0' : '') + n};
        return '[' + z(d.getFullYear()) + '_' + z(d.getMonth()+1) + '_' + z(d.getDate()) + '÷' + z(d.getHours()) + '_' + z(d.getMinutes()) + '_' + z(d.getSeconds()) + ']';
      })();

      fp.defaultString = fileName + "_" + fileDate + ".png";
      if (fp.show() == fp.returnCancel || !fp.file) return;
      var wbp = window.makeWebBrowserPersist();
      parseInt(Services.appinfo.version) < 36
      ? wbp.saveURI(url, null, null, null, null, fp.file, null)
      : wbp.saveURI(url, null, null, null, null, null, fp.file, null); // если FF36+

      canvas.remove();
   },
   captureAll: function() {
      var win = content;
      WebScreenShot.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY);
   },
   capturePage: function() {
      var win = content, doc = win.document, body = doc.body, html = doc.documentElement;
      var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft;
      var scrY = (body.scrollTop || html.scrollTop) - html.clientTop;
      WebScreenShot.capture(win, scrX, scrY, win.innerWidth, win.innerHeight);
   },
   // Запомнить изображение на странице как base64 .....
   onImage: function(image) {
      var canvas = document.createElementNS(xhtmlns, 'canvas');
      canvas.width = image.naturalWidth;
      canvas.height = image.naturalHeight;
      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);
      var base64 = canvas.toDataURL();
      gClipboard.write(base64);

      // стиль для изображение на сплывающей подсказке .....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);

      // всплывающая подсказка .....
      alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
   }
};


// Сохранить выбранную область страницы как PNG .....
WebScreenShotByClipping = {
   capture: WebScreenShot.capture,
   handleEvent: function(e) {
      if (e.button) return false;
          e.preventDefault();
          e.stopPropagation();
          switch(e.type){
                 case 'mousedown':
                    this.downX = e.pageX;
                    this.downY = e.pageY;
                    this.bs.left = this.downX + 'px';
                    this.bs.top = this.downY + 'px';
                    this.body.appendChild(this.box);
                    this.flag = true;
                    break;
                 case 'mousemove':
                    if (!this.flag) return;
                    this.moveX = e.pageX;
                    this.moveY = e.pageY;
                    if (this.downX > this.moveX) this.bs.left = this.moveX + 'px';
                    if (this.downY > this.moveY) this.bs.top  = this.moveY + 'px';
                    this.bs.width = Math.abs(this.moveX - this.downX) + 'px';
                    this.bs.height = Math.abs(this.moveY - this.downY) + 'px';
                    break;
                 case 'mouseup':
                    this.uninit();
                    break;
          }
   },
   init: function() {
      this.win = document.commandDispatcher.focusedWindow;
      if (this.win == window) this.win = content;
      this.doc = this.win.document;
      this.body = this.doc.body;
      if (!this.body instanceof HTMLBodyElement){
          alertsService.showAlertNotification(self.image, self.label, "Не удается захватить!");
          return false;
      }
      this.flag = null;
      this.box = this.doc.createElement('div');
      this.bs = this.box.style;
      this.bs.border = '#0f0 dashed 2px';
      this.bs.position = 'absolute';
      this.bs.zIndex = '2147483647';
      this.defaultCursor = getComputedStyle(this.body, '').cursor;
      this.body.style.cursor = 'crosshair';
      ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true));
   },
   uninit: function() {
      var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)];
      this.body.style.cursor = this.defaultCursor;
      this.body.removeChild(this.box);
      this.capture.apply(this, pos);
      ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true));
   },
};


// Сохранить фрейм на странице как PNG .....
WebScreenShotByClick = {
   capture: WebScreenShot.capture,
   getPosition: function() {
   var html = this.doc.documentElement;
   var body = this.doc.body;
   var rect = this.target.getBoundingClientRect();
   return [
          this.win
          ,Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft
          ,Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop
          ,parseInt(rect.width)
          ,parseInt(rect.height)
          ];
   },
   highlight: function() {
      this.orgStyle = this.target.hasAttribute('style') ? this.target.style.cssText : false;
      this.target.style.cssText += 'outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;';
   },
   lowlight: function(e) {
      if (this.orgStyle) this.target.style.cssText = this.orgStyle;
      else this.target.removeAttribute('style');
   },
   handleEvent: function(e) {
      switch(e.type){
             case 'click':
                if (e.button) return;
                e.preventDefault();
                e.stopPropagation();
                this.lowlight();
                var pos = this.getPosition();
                this.capture.apply(this, pos);
                this.uninit();
                break;
             case 'mouseover':
                if (this.target) this.lowlight();
                this.target = e.target;
                this.highlight();
                break;
      }
   },
   init: function() {
      this.win = content;
      this.doc = content.document;
      ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true));
   },
   uninit: function() {
      this.target = false;
      ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true));
   },
};


// Получить название вкладки без не сохраняемых символов и лишних пробелов .....
function getTabLabel() {
   var label = gBrowser.selectedTab.label;
   var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
   return label.substring(0, 50);
};


«The Truth Is Out There»

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]