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

Список ответов на каверзные вопросы можно получить в FAQ-разделе форума.

№1550113-05-2021 12:36:18

foxboy
Участник
 
Группа: Members
Зарегистрирован: 06-06-2015
Сообщений: 34
UA: Palemoon 24.0

Re: Custom Buttons

Dobrov пишет

Stkvsky пишетПодскажите как поставить Custom Buttons на 781) В папку, куда установлен Firefox, скопируй одноимённую папку из данного архива. (Костыли для FF)2) ставь обычным способом расширение custom_buttons-0.0.7.0.0.17-fx-bootstrap.xpi

На 78.10.1 ESR portable не ставится.

Отредактировано foxboy (13-05-2021 12:37:24)

Отсутствует

 

№1550213-05-2021 16:20:32

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

Re: Custom Buttons

foxboy пишет

На 78.10.1 ESR portable не ставится.

custom_buttons-0.0.7.0.0.17-fx-paxmod.xpi


Win7

Отсутствует

 

№1550313-05-2021 19:56:07

Deriax
Участник
 
Группа: Members
Зарегистрирован: 27-03-2021
Сообщений: 37
UA: Chrome 90.0

Re: Custom Buttons

Здравствуйте форумчане. Как получить ip, активной вкладки?

Отсутствует

 

№1550414-05-2021 02:43:11

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

Re: Custom Buttons

Вопрос: как получить текст первого конкретного html-тэга текущей страницы? Так не работает: doc.getElementsByTagName("label")[0];


Dumby пишет

В коде, вместо статического path, определить геттер.

Расширение Text Linky Tool открывает страницу moz-extension://…/imglist.html, хочу доработать Сохранение картинки перетаскиванием,
чтобы создаваемое имя папки было осмысленным, а не moz-extension.
То есть, в код, где получаю Заголовок текущей вкладки, хочу добавить проверку, что это страница moz-extension:// и тогда брать заголовок из label-тэга текущей страницы.

Выделить код

Код:

<body>
    <label id="lblFrom">Custom Buttons | Форум Mozilla Россия(https://forum.mozilla-russia.org/viewtopic.php?id=9591&amp;p=623/page/2)</label>
    <label>Images Viewer</label><span id="spnCount"> - 65 pics</span>
kazarin пишет

Да я понял уже, что вам такой вариант решения неинтересен, надоедать больше не буду.

Не в интересе дело, а в том, что расширение Image Picka не подгружает картинки, по которым не кликали, то есть оно бесполезно!

Отредактировано Dobrov (14-05-2021 02:51:24)

Отсутствует

 

№1550514-05-2021 16:14:00

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

Dumby
Посмотрите, пожалуйста, кнопкуSave, от 07.03.2017. .............
Идет неправильное сохранение через пункт "Сохранить всю страницу или выбранное как HTML"
Не сохраняются изображения и стили. При просмотре сохраненной страницы в автономном режиме(без инета) получается ерунда,
например здесь.

Отсутствует

 

№1550614-05-2021 18:12:24

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

Re: Custom Buttons

rubel
№15464

Отсутствует

 

№1550715-05-2021 01:44:38

Deriax
Участник
 
Группа: Members
Зарегистрирован: 27-03-2021
Сообщений: 37
UA: Chrome 90.0

Re: Custom Buttons

Подскажите пожалуйста, как можно сделать так, чтобы вкладка оставалась активной, даже после того, как осуществлён переход на другую вкладку?

Отредактировано Deriax (15-05-2021 12:25:43)

Отсутствует

 

№1550815-05-2021 02:41:25

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

voqabuhe
Кнопка с твоей ссылки точно также не сохраняет изображения и стили. При просмотре сохраненной страницы в автономном режиме(без инета) получается ерунда.
Твой код применяю для UCF.

Отсутствует

 

№1550915-05-2021 03:56:16

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

Re: Custom Buttons

rubel пишет

При просмотре сохраненной страницы в автономном режиме(без инета) получается ерунда.

Точно, без инета не проверял. Действительно ерунда получается.

Отсутствует

 

№1551015-05-2021 10:00:03

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

Re: Custom Buttons

rubel пишет

Кнопка с твоей ссылки точно также не сохраняет изображения и стили. При просмотре сохраненной страницы в автономном режиме(без инета) получается ерунда.
Твой код применяю для UCF.

вот кнопка SaveHTML от Dumby, с моими доработками. Данная ссылка с рецептами без интернета открывается нормально.

Выделить код

Код:

(async (id, func) => { // дополнительные клики на downloads-button для custom_script_win.js
	await window.delayedStartupPromise;
	var btn = document.getElementById("downloads-button");
	if (!btn) return;
	btn.setAttribute("context", "event.stopPropagation()"); // откл контекстное меню
	btn.tooltipText = GetDynamicShortcutTooltipText(btn.id) +`

ПКМ:	Сохранить единый .html
…Shift	Обзор папки «Загрузки»
Ролик:	Сохранить как файл .txt
		всё | выделенный текст
…Shift	Сайт: графика Вкл/Выкл
Alt⇧S	нажать SingleSave`; // если такой кнопки нет, то выполнить save()

	var addDestructor = nextDestructor => {
		var {destructor} = ucf[id];
		ucf[id].destructor = () => {
			try {destructor();} catch(ex) {Cu.reportError(ex);}
			nextDestructor();
		}
	}
	var saveSelectionToTxt = async () => { // сохранить страницу или выделенный текст как файл .txt
		var splice = saveURL.length == 10;
		var msgName = id + ":Save:GetSelection";

		var receiver = msg => {
			var title = document.title || gBrowser.selectedTab.label;
			var args = [
				"data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data),
				title.replace(/[:\\\/<>?*|"]+/g,'_').replace(/\s+/g,' ').slice(0, 100).trim() + '_' + new Date().toLocaleString('ru').replace(', ','-').replace(/:/g, '։') + '.txt',
				null, false, true, null, window.document
			];
			splice && args.splice(5, 0, null);
			saveURL(...args);
		}
		messageManager.addMessageListener(msgName, receiver);
		addDestructor(() => messageManager.removeMessageListener(msgName, receiver));

		var func = fm => {
			var res, fed, win = {};
			var fe = fm.getFocusedElementForWindow(content, true, win);
			var sel = (win = win.value).getSelection();
			if (sel.isCollapsed) {
				var ed = fe && fe.editor;
				if (ed && ed instanceof Ci.nsIEditor)
					sel = ed.selection, fed = fe;
			}
			if (sel.isCollapsed)
				fed && fed.blur(),
				docShell.doCommand("cmd_selectAll"),
				res = win.getSelection().toString(),
				docShell.doCommand("cmd_selectNone"),
				fed && fed.focus();

			res = res || sel.toString();
			/\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res);
		}
		var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));';

		(saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))();
	} // end

	var save = async () => { // автор: Лекс, правка: Dumby, Dobrov
		var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML";
		if (typeof IOUtils != "object") { // Firefox 78 ESR
			var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
			var PathUtils = {join: (...args) => OS.Path.join(...args)};
			var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))};
		}
		var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8";

		var Title = function (type) { // получить заголовок (без обрезки, если type не указан) или домен (type <0)
			var title = (document.title || gBrowser.selectedTab.label);
			if ( !type ) return title; // заголовок
			if ( type > 0 ) return title.substr(0, type).trim(); // ограничить длину имени
			var host = (/^file:\/\//.test(gURLBar.value)) ? '' : gURLBar.value.replace(/^.*url=/,'').replace(/^https?:\/\//,'').replace(/\/.*/,'');
			return host.replace(/^www\./,'').replace(/^ru\./,'').replace(/^m\./,'').replace(/^forum\./,'').replace(/^club\.dns/,'dns');
		}
		var FatMs = (str) => {return str.replace(/[:\\\/<>?*|"'`]+/g,'').replace(/\s+/g,' ').replace(/  /g,' ');}
		var msgListener = async msg => {
			var [fileContent, fileName] = msg.data;
			var savedir = PathUtils.join(await Downloads.getPreferredDownloadsDirectory(), "_Web", FatMs(Title(-1))); // каталог Загрузки + домен
			var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
			file.initWithPath(savedir);
			if ( !file.exists() || !file.isDirectory() ) file.create(Ci.nsIFile.DIRECTORY_TYPE, 0777); // создать папку, если не существует…
			var path = PathUtils.join(savedir, FatMs(fileName));
			await IOUtils[write](path, fileContent);
			var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(path)});
			(await Downloads.getList(Downloads.ALL)).add(d);
			d.refresh(d.succeeded = true); // кнопка Загрузки мигает
		}
		messageManager.addMessageListener(msgName, msgListener);
		addDestructor(() => messageManager.removeMessageListener(msgName, msgListener));

		var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services';
		var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName));
		(save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))();
	} // end save

	var listener = e => { // Clicks
		var trg = e.target, {prefs} = Services;
		if (e.button == 1) {
			if (e.shiftKey) { // СКМ + Shift
				if ( prefs.getIntPref("permissions.default.image", 1) == 1)
					prefs.setIntPref("permissions.default.image", 2), trg.style.filter = "hue-rotate(180deg) brightness(95%)"
				else
					prefs.setIntPref("permissions.default.image", 1), trg.style.filter = "";
				BrowserReload();
			} else	// СКМ Click
				saveSelectionToTxt(); // сохранить .txt
		} else if (e.button == 2) {
			if (e.shiftKey)
				Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки»
			else	// ПКМ Click
				save(); // Single HTML
		}
	}
	var keydown_win = e => { // нажатие клавиш
		if (!(e.keyCode == 83 && e.shiftKey && e.altKey)) return;
		var singlesave = document.getElementById("_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action"); // SingleSave
		singlesave ? singlesave.click() : save(); // имитировать клик по кнопке, используя её ID
	}
	btn.addEventListener("click", listener);
	window.addEventListener("keydown", keydown_win);
	var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win;
	ucf[id] = {destructor() {
		btn.removeEventListener("click", listener);
		window.removeEventListener("keydown", keydown_win);
	}};
	ucf.unloadlisteners.push(id);

})("downloads-button-click-listener", ({io, focus}) => {

	var resolveURL = function (url, base) {
		try {
			return io.newURI(url, null, io.newURI(base)).spec;
		} catch {}
	};
	var getSelWin = function (w) {
		if (w.getSelection().toString()) return w;
		for (var i = 0, f, r; f = w.frames[i]; i++) {
			try {
				if (r = getSelWin(f)) return r;
			} catch(e) {}
		}
	};
	var encodeImg = function (src, obj) {
		var canvas, img, ret = src;
		if (/^https?:\/\//.test(src)) {
			canvas = doc.createElement('canvas');
			if (!obj || obj.nodeName.toLowerCase() != 'img') {
				img = doc.createElement('img');
				img.src = src;
			} else {
				img = obj;
			};
			if (img.complete) try{
				canvas.width = img.width;
				canvas.height = img.height;
				canvas.getContext('2d').drawImage(img, 0, 0);
				ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png'));
			} catch (e) {};
			if (img != obj) img.src = 'about:blank';
		};
		return ret;
	};
	var toSrc = function (obj) {
		var strToSrc = function (str) {
			var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'};
			while (chr = str.charAt(i++)) {
				ret += meta[chr] || chr;
			};
			return '\x22' + ret + '\x22';
		},
		arrToSrc = function (arr) {
			var ret = [];
			for (var i = 0; i < arr.length; i++) {
				ret[i] = toSrc(arr[i]) || 'null';
			};
			return '[' + ret.join(',') + ']';
		},
		objToSrc = function (obj) {
			var val, ret = [];
			for (var prop in obj) {
				if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val);
			};
			return '{' + ret.join(',') + '}';
		};
		switch (Object.prototype.toString.call(obj).slice(8, -1)) {
			case 'Array': return arrToSrc(obj);
			case 'Boolean':
			case 'Function':
			case 'RegExp': return obj.toString();
			case 'Date': return 'new Date(' + obj.getTime() + ')';
			case 'Math': return 'Math';
			case 'Number': return isFinite(obj) ? String(obj) : 'null';
			case 'Object': return objToSrc(obj);
			case 'String': return strToSrc(obj);
			default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null';
		}
	};
	var mainWin = {};
	focus.getFocusedElementForWindow(content, true, mainWin);
	mainWin = mainWin.value;

	var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location;
	var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g;

	if (selWin) {
		var rng = win.getSelection().getRangeAt(0);
		pEle = rng.commonAncestorContainer;
		ele = rng.cloneContents();
	} else {
		pEle = doc.documentElement;
		ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true);
	};
	while (pEle) {
		if (pEle.nodeType == 1) {
			clone = pEle.cloneNode(false);
			clone.appendChild(ele);
			ele = clone;
		};
		pEle = pEle.parentNode
	};
	var sel = doc.createElement('div');
	sel.appendChild(ele);

	for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) {
		el = all[i];
		if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) {
			if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href);
			return prev + encodeImg(url) + next;
		});
		switch (el.nodeName.toLowerCase()) {
			case 'link':
			case 'style':
			case 'script': el.parentNode.removeChild(el); break;
			case 'a': 
			case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break;
			case 'img':
			case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break;
			case 'audio':
			case 'video':
			case 'embed':
			case 'frame':
			case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break;
			case 'object': if (el.hasAttribute('data')) el.data = el.data; break;
			case 'form': if (el.hasAttribute('action')) el.action = el.action; break;
		}
	};
	var head = ele.insertBefore(doc.createElement('head'), ele.firstChild);
	var meta = doc.createElement('meta');
	meta.httpEquiv = 'content-type';
	meta.content = 'text/html; charset=utf-8';
	head.appendChild(meta);
	var title = doc.getElementsByTagName('title')[0];
	if (title) head.appendChild(title.cloneNode(true));

	head.copyScript = function (unsafeWin) {
		if ('$' in unsafeWin) return;
		var f = doc.createElement('iframe');
		f.src = 'about:blank';
		f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');
		doc.documentElement.appendChild(f);
		var str, script = doc.createElement('script');
		script.type = 'text/javascript';
		for (var name in unsafeWin) {
			if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue;
			try {
				str = toSrc(unsafeWin[name]);
				if (!/\{\s*\[native code\]\s*\}/.test(str)) {
					script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n'));
				}
			} catch (e) {};
		};
		f.parentNode.removeChild(f);
		if (script.childNodes.length) this.nextSibling.appendChild(script);
	};
	head.copyScript(win.wrappedJSObject || win);

	head.copyStyle = function (s) {
		if (!s) return;
		var style = doc.createElement('style');
		style.type = 'text/css';
		if (s.media && s.media.mediaText) style.media = s.media.mediaText;
		try {
			for (var i = 0, rule; rule = s.cssRules[i]; i++) {
				if (rule.type != 3) {
					if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) {
						var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) {
							if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href);
							if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url);
							return prev + url + next;
						});
						style.appendChild(doc.createTextNode(css + '\n'));
					}
				} else {
					this.copyStyle(rule.styleSheet);
				}
			}
		} catch(e) {
			if (s.ownerNode) style = s.ownerNode.cloneNode(false);
		};
		this.appendChild(style);
	};
	var sheets = doc.styleSheets;
	for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]);
	head.appendChild(doc.createTextNode('\n'));

	var doctype = '', dt = doc.doctype;
	if (dt && dt.name) {
		doctype += '<!DOCTYPE ' + dt.name;
		if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22';
		if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22';
		doctype += '>\n';
	};

	var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());
	fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).trim();
	fileName += "_" + new Date().toLocaleString("ru").replace(", ","-").replace(/:/g, "։");
	if (!/\.html?$/.test(fileName)) fileName += '.html';

	sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', fileName]);

}); // END hookClicks

Отсутствует

 

№1551116-05-2021 03:27:43

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

Re: Custom Buttons

Dumby - есть два кода, показывающих при наведении на Звёздочку адрес закладки или последнюю папку, куда добавлялась закладка.


Первый работает в custom_script_win.js , а Второй почему-то только в кнопке CustomButton.
Нужно устранить три недостатка либо первого либо второго скрипта (ещё второй не работает в custom_script_win.js):
1) Оба скрипта зачем-то удаляют стандартную подсказку Звёздочки: у меня это «Добавить страницу в Закладки (⌘D)».
2) Нет строки "Недавняя папка\n:" перед текстом последней папки, куда добавлялась закладка [как в этом же коде "Адрес закладки:\n"]. Я не смог найти строку кода, где нужно добавить этот текст!
3) нет обработки кликов Звёздочки, я их добавил в более старый вариант, но у него нет "Недавней папки":

Выделить код

Код:

try {((bu, bm, {star} = bu) => { // показать расположение закладки в Избранном. Клики на Звёздочке:
	var listener = { 	// СКМ: Вернуть вкладку, СКМ+Alt страница about:newtab, СКМ+Shift google.ru
		async handleEvent() {
			var result = [];
			await this.fetch();
			for(var guid of this.guids) {
				var arr = [];
				while(true) {
					if (!this.hover) return;
					var res = await bm.fetch(guid);
					if ((guid = res.parentGuid) == bm.rootGuid) {
						arr.unshift(bm.getLocalizedTitle(res));
						break;
					}
					arr.unshift(res.title || "[Безымянная папка]");
				}
				result.push(arr.join("\\"));
			}
			this.hover && this.setTooltip(result);
		},
		get fetch() {
			var set = this.guids = new Set();
			var args = [b => set.add(b.parentGuid), {concurrent: true}];
			delete this.fetch; return this.fetch = () => set.clear()
				|| bm.fetch({url: gBrowser.currentURI.spec}, ...args);
		},
		setTooltip(arr) {
			var m = arr.length > 1;
			var help = '\nРолик:	Вернуть вкладку \n…+Alt	Быстрый доступ\n…+Shift	поиск в Google', text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${arr.join("\n")}\n`+ help;
			if (bu._itemGuids.size)
				star.tooltipText = "\u3164"
			else
				text = star.tooltipText + help;
			if (/Ролик/.test(star.tooltipText)) return;
			document.tooltipNode == star ? this.tt.label = text : star.tooltipText = text;
		},
		get tt() {
			var list = InspectorUtils.getChildrenForNode(document.documentElement, true);
			delete this.tt; return this.tt = list.item(list.length - 1);
		},
		get hover() {return star.matches(":hover");}
	},
	loadURI_ex = (url, newtab) => { newtab = newtab || false; // параметры по-умолчанию
		if (newtab)
			switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()})
		else
			gBrowser.loadURI(url, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
	},
	clicks = e => { if (e.button != 1) return; // CKM Click
		if (e.shiftKey)
			loadURI_ex('https://www.google.ru', true)
		else if (e.altKey)
			loadURI_ex('about:newtab')
		else
			document.defaultView.undoCloseTab();
	};
	star.addEventListener("mouseenter", listener);
	star.addEventListener("click", clicks);
	addEventListener("unload", () => {
			star.removeEventListener("mouseenter", listener);
			star.removeEventListener("click", clicks)
		}
	, {once: true});
})(BookmarkingUI, PlacesUtils.bookmarks);} catch(ex) {Cu.reportError(ex);}

Отсутствует

 

№1551216-05-2021 05:38:15

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

Dobrov пишет

вот кнопка SaveHTML от Dumby, с моими доработками

Что-то у меня ничего не получилось с этим кодом. Создал файл SaveHTML.js,  прописал его в загрузчик custom_script_win.js.
Никаких кнопок, меню ни где не появилось, в коде написано дополнительные клики на downloads-button для custom_script_win.js. А что это такое downloads-button ? у меня вроде нигде нет такого.:)

Отсутствует

 

№1551316-05-2021 06:57:09

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

Re: Custom Buttons

rubel это стандартная кнопка «Загрузки», всё и так ясно по названию downloads-button.


Alt+Shift+S для сохранения страницы или жми на «Загрузки» правой кнопкой мыши, включив постоянный показ:
Персонализация > Правый клик на кнопке «Загрузки» > Снять флажок: Автоматически скрывать на панели инструментов.

Отсутствует

 

№1551416-05-2021 07:20:59

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

Dobrov
ОК. Спасибо, все работает и сохраняет как надо ! Но вот путь сохранения для меня не удобен, да еще и по домену.
У меня все сохраняется в "D:\Downloads" вот нужно и прописать в ваш скрипт этот путь. Как правильно прописать ?
И еще бы сделать при сохранение открытие  диалогового окна, чтобы корректировать имя файла. :)

Отредактировано rubel (16-05-2021 07:32:26)

Отсутствует

 

№1551516-05-2021 08:08:26

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

Re: Custom Buttons

rubel - строка 82:

Выделить код

Код:

var savedir = PathUtils.join(await Downloads.getPreferredDownloadsDirectory(), "_Web", FatMs(Title(-1))); // каталог Загрузки + домен

Отсутствует

 

№1551616-05-2021 08:50:48

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

Dobrov
Исправил -- var savedir = PathUtils.join(await Downloads.getPreferredDownloadsDirectory(), );
Теперь сохраняет просто в "D:\Downloads" . Но вот с именами файлов беда. Например вот с этой страницы сохраняет название файла:
Mozilla Firefox 87.0 08.02.2021 _ Cento8 Название программы_ Firefox Версия программы_ 87.0 Разработ_16.05.2021-09։41։18 Чушь какая-то. Как сделать чтоб было нормально, с выбором названия файла ?

Отсутствует

 

№1551716-05-2021 09:47:20

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

Re: Custom Buttons

rubel пишет

Как сделать чтоб было нормально, с выбором названия файла ?

Удобство этого скрипта именно в том, что нет навязчивого запроса имени файла! Имя файла равно заголовку вкладки, это задано в последних строках.
Что-то ты не так исправил, у меня с этой ссылки сохраняет как: Mozilla Firefox 87.0 _ effect ∞_16.05.2021-14։42։47.html

Отсутствует

 

№1551816-05-2021 11:00:48

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

Dobrov пишет

Удобство этого скрипта именно в том, что нет навязчивого запроса имени файла!

Ну кому как, а мне удобно присваивать имена файлов как я хочу.... Все равно спасибо.
Уважаемые гуру Dobrov Andrey_Krropotkin Dumby Vitaliy V.
сделайте, пожалуйста, кнопку Save snapshot to html для UCF.

Отсутствует

 

№1551916-05-2021 20:32:56

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

Re: Custom Buttons

Dumby
Как бы на "отмена" код  SidebarUI.hide(); сработал ?

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

Выделить код

Код:

/*Initialization Code*/

this.onclick = this.oncontextmenu = function(event) {
if (event.button == 1) {
SidebarUI.toggle('viewHistorySidebar'); 
 if (custombuttons.confirmBox(null, "Вниманиее ! Очистка Истории!", "Да", "Отмена") ) {

PlacesUtils.history.clear();
SidebarUI.hide();

}
}

 if(event.button == 0 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){
SidebarUI.toggle('viewHistorySidebar');
}
     
if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){
Sanitizer.showUI(window);   
CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed);
 var s = "browser.zoom.full";
      cbu.setPrefs(s, cbu.getPrefs(s) == true ? true : true); 
 var s = "intl.accept_languages";
 cbu.setPrefs(s, cbu.getPrefs(s) == "ru" ? "ru": "ru");

  var s = "media.autoplay.default";
 cbu.setPrefs(s, cbu.getPrefs(s) == 5 ? 5: 5);
SidebarUI.hide();
    var s = "extensions.long_left_click.timeContent";
     cbu.setPrefs(s, cbu.getPrefs(s) == 350 ? 350: 350);
document.querySelector(
    "#mainPopupSet > tooltip[onpopupshowing*=undoCloseTabsList]"
)?.undoCloseTabsList.updUI();
             

}
};

this.oncontextmenu =e=> { e.button && !e.ctrlKey && e.preventDefault() };

this.tooltipText = "ЛКМ: Боковая история\nСКМ: Очистка Истории \nПКМ: Окно очистки всего";

Отсутствует

 

№1552016-05-2021 22:09:52

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

Re: Custom Buttons

Dobrov пишет

и тогда брать заголовок из label-тэга текущей страницы

Жаль, что слова «в другом процессе» — пустой звук.
Если title страницы Text Linky Tool не ценность, то можно так попробовать

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

Выделить код

Код:

/*
				this.drag("add");
		},
*/
				this.drag("add"),
				this.checkTLT();
		},
		checkTLT() {
			var tltHost = WebExtensionPolicy.getByID(
				"{3efee51a-7d3b-4412-a889-addc6ff6276b}"
			)?.mozExtensionHostname;
			tltHost && (this.checkTLT = () =>
				gBrowser.selectedTab.label.startsWith(tltHost) &&
				gBrowser.selectedBrowser.messageManager.loadFrameScript(this.tltFs, false)
			)();
		},
		get tltFs() {
			delete this.tltFs;
			return this.tltFs = "data:;charset=utf-8,(" + encodeURIComponent(doc => {
				var tc = doc.getElementById("lblFrom").textContent;
				doc.title = tc.slice(0, tc.lastIndexOf("("));
			}) + ")(content.document)";
		},

Первый работает в custom_script_win.js , а Второй почему-то только в кнопке CustomButton.
Нужно устранить три недостатка

Потому что первый сделан под ucf, а второй под CB.
И не «устранить три недостатка», а «добавить три хотелки».

UPD: bugzil.la/1706479 FF90+

Выделить код

Код:

(async (id, sel) => {
	var g = Cu.getGlobalForObject(Cu), stt = g[id];
	if (!stt) {
		var {obs, prefs} = Services, {bookmarks: bm, observers: pobs} = PlacesUtils;
		stt = g[id] = {
			bm,
			pref: `ucf.${id}Guid`,
			events: ["bookmark-added"],
			async init() {
				this.handleEvent = e => this[e.type](e);

				if ((this.pbm = typeof PlacesBookmarkMoved == "function"))
					this.events.push("bookmark-moved");
				else
					this.QueryInterface = g.ChromeUtils.generateQI([Ci.nsINavBookmarkObserver]),
					bm.addObserver(this);

				pobs.addListener(this.events, this.added = events => {
					for(var e of events) e.isTagging || this[e.constructor.name](e);
				});
				obs.addObserver(this, "quit-application-granted");
				this.args = [b => this.bguids.add(b.parentGuid), {concurrent: true}];
				var guid = prefs.getStringPref(this.pref, "");
				if (!guid) try {var [guid] = await PlacesUtils.metadata.get(
					PlacesUIUtils.LAST_USED_FOLDERS_META_KEY, []
				)} catch {}
				this.guids.push(guid || await PlacesUIUtils.defaultParentGuid || bm.unfiledGuid);
			},
			observe() {
				this.pbm || bm.removeObserver(this);
				pobs.removeListener(this.events, this.added);
				obs.removeObserver(this, "quit-application-granted");
				prefs.setStringPref(this.pref, this.guids[0]);
			},
			skipTags: true,
			bguids: new g.Set(),
			guids: new g.Array(),
			PlacesBookmarkAddition(e) {
				if (e.itemType == bm.TYPE_BOOKMARK && e.source == bm.SOURCES.DEFAULT)
					this.guids[0] = e.parentGuid;
			},
			PlacesBookmarkMoved(e) {
				e.parentGuid != e.oldParentGuid && this.PlacesBookmarkAddition(e);
			},
			onItemMoved(a, b, c, d, e, itemType, f, oldParentGuid, parentGuid, source) {
				this.PlacesBookmarkMoved({itemType, source, oldParentGuid, parentGuid});
			},
			fetch(win) {
				this.bguids.clear();
				return bm.fetch({url: win.gBrowser.currentURI.spec}, ...this.args);
			},
			tt(win) {
				var list = win.InspectorUtils
					.getChildrenForNode(win.document.documentElement, true);
				return list.item(list.length - 1);
			},
			find: obj => obj.name == "tooltiptext",
			opts: {
				relatedToCurrent: true,
				triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
			},
			loadURI_ex(win, url, newtab) {newtab
				? win.switchToTabHavingURI(url, true, this.opts)
				: win.gBrowser.loadURI(url, this.opts);
			},
			auxclick(e) {
				if (e.button != 1) return;
				var win = e.view;
				if (e.shiftKey) this.loadURI_ex(win, "https://www.google.ru", true);
				else if (e.altKey) this.loadURI_ex(win, "about:newtab");
				else win.undoCloseTab();
			}	
		};
		var ps = ["onBeginUpdateBatch", "onEndUpdateBatch", "onItemChanged", "onItemVisited"];
		var noop = () => {}; for(var p of ps) stt[p] = noop; stt.init();

		var func = id => this[id].mouseenter = async function(e) {
			var win = e.view;
			var star = e.target;
			star.tooltipText = "\u3164";
			var starred = win.BookmarkingUI.status == win.BookmarkingUI.STATUS_STARRED;
			starred && await this.fetch(win);
			var result = [];
			for(var guid of (starred ? this.bguids : this.guids)) {
				var arr = [], num = 50;
				while(--num) {
					if (!star.matches(":hover")) return;
					var res = await this.bm.fetch(guid);
					if (!res) break;
					if ((guid = res.parentGuid) == this.bm.rootGuid) {
						arr.unshift(this.bm.getLocalizedTitle(res));
						break;
					}
					arr.unshift(res.title || "[Безымянная папка]");
				}
				arr.length && result.push(arr.join("\\"));
			}
			if (!star.matches(":hover")) return;

			var text = (await win.document.l10n.formatMessages([{
				id: star.getAttribute("data-l10n-id"),
				args: JSON.parse(star.getAttribute("data-l10n-args"))
			}]))[0].attributes.find(this.find).value;
	
			if (result.length) {
				var txt = result.join("\n");
				if (starred) {
					var m = result.length > 1;
					txt = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${txt}`;
				} else
					txt = "Недавняя папка:\n" + txt;
				text += "\n\n" + txt;
			}
			win.document.tooltipNode == star
				? this.tt(win).label = text : star.tooltipText = text;
		}
		var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})("${id}")`);
		g.ChromeUtils.compileScript(url).then(ps => ps.executeInGlobal(g));
	}
	await delayedStartupPromise;
	var stars = Array.from(document.querySelectorAll(sel));
	for(var star of stars)
		star.addEventListener("auxclick", stt),
		star.addEventListener("mouseenter", stt);
		
	var destructor = () => {
		for(var star of stars)
			star.removeEventListener("auxclick", stt),
			star.removeEventListener("mouseenter", stt);
	}
	var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win;
	if (ucf)
		ucf[id] = {destructor},
		ucf.unloadlisteners.push(id);
	else
		window.addEventListener("unload", destructor, {once: true});
})("ucfBookmarksStarFTooltipHelper", ":is(#star-button, #star-button-box)[role], #context-bookmarkpage");

rubel пишет

сделайте, пожалуйста, кнопку Save snapshot to html для UCF.

Попробую JSM'кой. Создать AppMenuTbbSaveHTMLChild.jsm
и подключть в custom_script.js (путь свой).

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

Выделить код

Код:

(async url => ChromeUtils.import(url))(
	"chrome://user_chrome_files/content/custom_scripts/Actors/AppMenuTbbSaveHTMLChild.jsm"
);


AppMenuTbbSaveHTMLChild.jsm

Выделить код

Код:

var self, name = "AppMenuTbbSaveHTML", EXPORTED_SYMBOLS = [name + "Child"];
var {io, focus, obs} = globalThis.Services ||
	ChromeUtils.import("resource://gre/modules/Services.jsm").Services;

class AppMenuTbbSaveHTMLChild extends JSWindowActorChild {
	receiveMessage() {
		return htmlAndName(this.contentWindow);
	}
}
ChromeUtils.domProcessChild.childID || ({
	init(topic) {
		ChromeUtils.registerWindowActor(name, {
			allFrames: true,
			child: {moduleURI: __URI__},
			messageManagerGroups: ["browsers"]
		});
		obs.addObserver(self = this, topic);
		obs.addObserver(function quit(s, t) {
			obs.removeObserver(quit, t);
			obs.removeObserver(self, topic);
		}, "quit-application-granted");
		this.handleEvent = e => this[e.type](e);
	},
	observe(win) {
		win.document.getElementById("appMenu-popup")
			.addEventListener("popupshowing", this);
		win.addEventListener("unload", this);
	},
	popupshowing(e) {
		this.unload(e);
		var popup = e.target;
		var btn = popup.ownerDocument.createXULElement("toolbarbutton");
		btn.id = "appMenu-ucf-save-html-button";
		btn.className = "subviewbutton subviewbutton-iconic";
		btn.setAttribute("label", "Сохранить страницу или выбранное как HTML");
		btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII=");
		btn.setAttribute("oncommand", "saveHTML();");
		btn.saveHTML = this.saveHTML;
		popup.querySelector('toolbarbutton[id^="appMenu-print-button"]').before(btn);
	},
	unload(e) {
		var win = e.target.ownerGlobal;
		win.removeEventListener("unload", this);
		win.document.getElementById("appMenu-popup")
			.removeEventListener("popupshowing", this);
	},
	async saveHTML() {
		var win = this.ownerGlobal;
		var br = win.gBrowser.selectedBrowser;
		var bc = focus.focusedContentBrowsingContext;
		if (bc?.top.embedderElement != br) bc = br.browsingContext;

		var actor = bc?.currentWindowGlobal?.getActor(name);
		actor && self.save(win, ...await actor.sendQuery(""));
	},
	async save(win, fileContent, fileName) {
		var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
		fp.init(win, "", fp.modeSave);
		fp.defaultString = fileName;
		fp.appendFilters(fp.filterHTML);
		fp.appendFilters(fp.filterAll);
		var res = await new Promise(fp.open);
		if (res == fp.returnOK || res == fp.returnReplace)
			this.write(fp.file.path, fileContent);
	},
	write(path, html) {
		if (typeof IOUtils != "object") {
			var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
			var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))};
		}
		(this.write = IOUtils.writeUTF8 || IOUtils.writeAtomicUTF8)(path, html);
	}
	
}).init("browser-delayed-startup-finished");

var htmlAndName = async mainWin => {

	var resolveURL = function (url, base) {
		try {
			return io.newURI(url, null, io.newURI(base)).spec;
		} catch {}
	};

	var getSelWin = function (w) {
		if (w.getSelection().toString()) return w;
		for (var i = 0, f, r; f = w.frames[i]; i++) {
			try {
				if (r = getSelWin(f)) return r;
			} catch(e) {}
		}
	};

	var encodeImg = function (src, obj) {
		var canvas, img, ret = src;
		if (/^https?:\/\//.test(src)) {
			canvas = doc.createElement('canvas');
			if (!obj || obj.nodeName.toLowerCase() != 'img') {
				img = doc.createElement('img');
				img.src = src;
			} else {
				img = obj;
			};
			if (img.complete) try{
				canvas.width = img.width;
				canvas.height = img.height;
				canvas.getContext('2d').drawImage(img, 0, 0);
				ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png'));
			} catch (e) {};
			if (img != obj) img.src = 'about:blank';
		};
		return ret;
	};
	var toSrc = function (obj) {
		var strToSrc = function (str) {
			var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'};
			while (chr = str.charAt(i++)) {
				ret += meta[chr] || chr;
			};
			return '\x22' + ret + '\x22';
		},
		arrToSrc = function (arr) {
			var ret = [];
			for (var i = 0; i < arr.length; i++) {
				ret[i] = toSrc(arr[i]) || 'null';
			};
			return '[' + ret.join(',') + ']';
		},
		objToSrc = function (obj) {
			var val, ret = [];
			for (var prop in obj) {
				if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val);
			};
			return '{' + ret.join(',') + '}';
		};

		switch (Object.prototype.toString.call(obj).slice(8, -1)) {
			case 'Array': return arrToSrc(obj);
			case 'Boolean':
			case 'Function':
			case 'RegExp': return obj.toString();
			case 'Date': return 'new Date(' + obj.getTime() + ')';
			case 'Math': return 'Math';
			case 'Number': return isFinite(obj) ? String(obj) : 'null';
			case 'Object': return objToSrc(obj);
			case 'String': return strToSrc(obj);
			default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null';
		}
	};

	var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location;
	var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g;

	if (selWin) {
		var rng = win.getSelection().getRangeAt(0);
		pEle = rng.commonAncestorContainer;
		ele = rng.cloneContents();
	} else {
		pEle = doc.documentElement;
		ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true);
	};
	while (pEle) {
		if (pEle.nodeType == 1) {
			clone = pEle.cloneNode(false);
			clone.appendChild(ele);
			ele = clone;
		};
		pEle = pEle.parentNode
	};
	var sel = doc.createElement('div');
	sel.appendChild(ele);

	for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) {
		el = all[i];
		if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) {
			if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href);
			return prev + encodeImg(url) + next;
		});
		switch (el.nodeName.toLowerCase()) {
			case 'link':
			case 'style':
			case 'script': el.parentNode.removeChild(el); break;
			case 'a': 
			case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break;
			case 'img':
			case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break;
			case 'audio':
			case 'video':
			case 'embed':
			case 'frame':
			case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break;
			case 'object': if (el.hasAttribute('data')) el.data = el.data; break;
			case 'form': if (el.hasAttribute('action')) el.action = el.action; break;
		}
	};

	var head = ele.insertBefore(doc.createElement('head'), ele.firstChild);
	var meta = doc.createElement('meta');
	meta.httpEquiv = 'content-type';
	meta.content = 'text/html; charset=utf-8';
	head.appendChild(meta);
	var title = doc.getElementsByTagName('title')[0];
	if (title) head.appendChild(title.cloneNode(true));

	head.copyScript = function (unsafeWin) {
		if ('$' in unsafeWin) return;
		var f = doc.createElement('iframe');
		f.src = 'about:blank';
		f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');
		doc.documentElement.appendChild(f);
		var str, script = doc.createElement('script');
		script.type = 'text/javascript';
		for (var name in unsafeWin) {
			if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue;
			try {
				str = toSrc(unsafeWin[name]);
				if (!/\{\s*\[native code\]\s*\}/.test(str)) {
					script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n'));
				}
			} catch (e) {};
		};
		f.parentNode.removeChild(f);
		if (script.childNodes.length) this.nextSibling.appendChild(script);
	};
	head.copyScript(win.wrappedJSObject || win);

	head.copyStyle = function (s) {
		if (!s) return;
		var style = doc.createElement('style');
		style.type = 'text/css';
		if (s.media && s.media.mediaText) style.media = s.media.mediaText;
		try {
			for (var i = 0, rule; rule = s.cssRules[i]; i++) {
				if (rule.type != 3) {
					if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) {
						var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) {
							if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href);
							if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url);
							return prev + url + next;
						});
						style.appendChild(doc.createTextNode(css + '\n'));
					}
				} else {
					this.copyStyle(rule.styleSheet);
				}
			}
		} catch(e) {
			if (s.ownerNode) style = s.ownerNode.cloneNode(false);
		};
		this.appendChild(style);
	};
	var sheets = doc.styleSheets;
	for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]);
	head.appendChild(doc.createTextNode('\n'));

	var doctype = '', dt = doc.doctype;
	if (dt && dt.name) {
		doctype += '<!DOCTYPE ' + dt.name;
		if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22';
		if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22';
		doctype += '>\n';
	};
	var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());
	fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');
	fileName += (function () {
		var d = new Date(), z = function(n){return '_' + (n < 10 ? '0' : '') + n};
		return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());
	})();
	if(!/\.html?$/.test(fileName))fileName += '.html';

	return [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName];
}

ВВП пишет

Как бы на "отмена" код  SidebarUI.hide(); сработал ?

Скобку «}», которая идёт после SidebarUI.hide();
переставить так, чтобы она шла перед SidebarUI.hide();

Отредактировано Dumby (23-05-2021 17:53:01)

Отсутствует

 

№1552116-05-2021 22:51:23

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

Re: Custom Buttons

Dumby

Dumby пишет

Скобку «}», которая идёт после SidebarUI.hide();
переставить так, чтобы она шла перед SidebarUI.hide();

Класс!

Отсутствует

 

№1552217-05-2021 04:51:13

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

Dumby пишет

Попробую JSM'кой. Создать AppMenuTbbSaveHTMLChild.jsm
и подключть в custom_script.js (путь свой).

Все сделал по вашей методе, но меню  не появилось.

Отсутствует

 

№1552317-05-2021 06:02:37

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

Re: Custom Buttons

Dumby Спасибо! Скрипты для Звёздочки и Загрузки картинки отличные! :beer: (я лишь добавил обрезку имён вкладок)


Ещё просьба [финальная :)]: скрипт Загрузки картинки перетаскивание вправо с изменениями не всегда может сохранить картинку.
Некоторые изображения нельзя тащить, например Cover Гости из прошлого и там же фотки актрис.
Убрал стилем мешающий сохранению div на данном сайте, клик по обложке откроет Слайд-шоу на всё окно, но перетаскивание на картинке не работает.


Dumby - нельзя ли в скрипт "Сохранить картинку перетаскиванием" добавить ещё сохранение картинки по событию двойной click или click+Ctrl или клик колёсиком мыши (это в строке events: ["dragover", "drop", "dragend"],) ???
А лучше сделать отдельный скрипт, который может по кликам сохранить картинку или скрытую некликабельную картинку, которая под курсором.

Выделить код

Код:

@-moz-document domain(doramatv.live), domain(mose.live) { /* позволяет сохранять картинки */
  .fotorama__fullscreen-icon { max-height: 300px !important; max-width: 300px !important;}
}
rubel пишет

Все сделал по вашей методе, но меню  не появилось.

AppMenuTbbSaveHTMLChild.jsm - Всё работает, строка "Сохранить страницу или выбранное как HTML" есть в меню, которое на кнопке Firefox.

Отредактировано Dobrov (17-05-2021 08:13:59)

Отсутствует

 

№1552417-05-2021 08:44:51

rubel
Участник
 
Группа: Members
Откуда: г.Самара
Зарегистрирован: 10-05-2005
Сообщений: 559
UA: Firefox 86.0

Re: Custom Buttons

Dobrov, Dumby
Помогите, пожалуйста.
Вот мои действия:
1.Создаю файл AppMenuTbbSaveHTMLChild.jsm
2.помещаю его в папку custom_scripts
3.в файл custom_script.js в самый верх добавляю

Выделить код

Код:

(async url => ChromeUtils.import(url))(
	"chrome://user_chrome_files/content/custom_scripts/AppMenuTbbSaveHTMLChild.jsm"
);

Получается вот так:

Выделить код

Код:

(async url => ChromeUtils.import(url))(
	"chrome://user_chrome_files/content/custom_scripts/AppMenuTbbSaveHTMLChild.jsm"
);

(() => {
    var loadscript = name => {
        try {
            Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${name}`, globalThis, "UTF-8");
        } catch(e) {}
    };
    loadscript("cs/Icons in Sidebar.js");
    loadscript("cs/extension_manager_button.js");
	loadscript("cs/closeothertabs.uc.js");
	loadscript("cs/BBCode-Multi.js");
	loadscript("cs/undo_tab.js");
	loadscript("cs/download_and_switch_proxy_buttons.js");
	loadscript("cs/Ram.js");
	loadscript("cs/Nightly.js");
	
    // и т. д.
})();

Удаляю полностью папку startupCache, запускаю браузер и ничего не появилось в меню, которое на кнопке Firefox.
Что у меня не так ?

Отредактировано rubel (17-05-2021 13:41:10)

Отсутствует

 

№1552517-05-2021 12:19:15

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

Re: Custom Buttons

del

Отредактировано ВВП (17-05-2021 17:15:24)

Отсутствует

 

Board footer

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