Объявление

В связи с наплывом спама и ботов на форуме, регистрация новых пользователей будет приостановлена. О восстановлении регистрации будет сообщено дополнительно

Administrator

№195131-03-2025 18:25:32

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 23-07-2024
Сообщений: 30
UA: Firefox 137.0

Re: UCF - ваши кнопки, скрипты…

Dumby посмотрите пожалуйста этот скрипт от VitaliyV он не работает

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

Выделить код

Код:

(async (
    id = "ucf_sidebar_tabs_button",
    label = "Sidebar Tabs",
    tooltiptext = "ЛКМ: Открыть / Закрыть\nControl + ЛКМ: Отключить / Включить\nСКМ: Отключить / Включить\nПКМ: Переключить AutoHide",
    img = "resource://ucf_sidebar_tabs",
    pref = "extensions.ucf.sidebar_tabs.auto_hide",

    sidebar_tabs = {
        get style() {
            delete this.style;
            return this.style = `data:text/css;charset=utf-8,${encodeURIComponent(`
            #browser > #st_toolbox {
                --v-sidebar-min-width: 10px;
                --v-sidebar-transition-delay-show: .3s;
                --v-sidebar-transition-delay-hide: 2s;
                --v-sidebar-transition-duration: .2s;
                /* ********************************************** */

                position: relative !important;
                z-index: calc(var(--browser-area-z-index-tabbox, 2) + 2) !important;
                min-width: var(--v-sidebar-tabs-width) !important;
                width: var(--v-sidebar-tabs-width) !important;
                max-width: var(--v-sidebar-tabs-width) !important;
                overflow: hidden !important;
                opacity: 0 !important;
                --v-sidebar-margin-max-width: calc(-1 * var(--v-sidebar-tabs-width));
                --v-sidebar-transform-locale-dir: -1;
                --v-sidebar-transform-locale-dir-visible: 1;
                margin-inline-start: 0 !important;
                margin-inline-end: var(--v-sidebar-margin-max-width) !important;
                transform: translateX(calc(var(--v-sidebar-transform-locale-dir) * (var(--v-sidebar-tabs-width) - var(--v-sidebar-min-width)))) !important;
                &[sidebar_tabs_auto_hide] {
                    transition-timing-function: linear, step-start, linear !important;
                    transition-delay: var(--v-sidebar-transition-delay-hide), calc(var(--v-sidebar-transition-delay-hide) + var(--v-sidebar-transition-duration)), 0s !important;
                    transition-duration: var(--v-sidebar-transition-duration), 0s, .2s !important;
                    transition-property: transform, opacity, margin-top !important;
                }
                &[sidebar_tabs_auto_hide][sidebar_tabs_visible="hidden"] {
                    transition-delay: 0s, var(--v-sidebar-transition-duration), 0s !important;
                }
                :root[sidebar_tabs_start="false"] & {
                    margin-inline-start: var(--v-sidebar-margin-max-width) !important;
                    margin-inline-end: 0 !important;
                }
                :root[sidebar_tabs_start="false"]:-moz-locale-dir(ltr) &,
                :root[sidebar_tabs_start="true"]:-moz-locale-dir(rtl) & {
                    --v-sidebar-transform-locale-dir: 1;
                    --v-sidebar-transform-locale-dir-visible: -1;
                }
                &[sidebar_tabs_auto_hide]:hover {
                    transform: translateX(0px) !important;
                    opacity: 1 !important;
                    transition-delay: var(--v-sidebar-transition-delay-show), var(--v-sidebar-transition-delay-show), 0s !important;
                }
                &[sidebar_tabs_auto_hide][sidebar_tabs_visible^="visible"] {
                    transform: translateX(0px) !important;
                    opacity: 1 !important;
                    transition-delay: 0s !important;
                }
                :root[v_vertical_bar_start="true"][sidebar_tabs_start="true"]:is([v_vertical_bar_visible="visible"],[v_vertical_bar_sidebar="true"]) &[sidebar_tabs_auto_hide],
                :root[v_vertical_bar_start="false"][sidebar_tabs_start="false"]:is([v_vertical_bar_visible="visible"],[v_vertical_bar_sidebar="true"]) &[sidebar_tabs_auto_hide] {
                    transform: translateX(calc(var(--v-sidebar-transform-locale-dir-visible) * var(--v-vertical-bar-width, 0px))) !important;
                    opacity: 1 !important;
                    transition-delay: 0s !important;
                }
                :root[v_vertical_bar_visible] & {
                    padding-inline: 0 !important;
                }
            }
            #browser > #st_splitter {
                display: none !important;
            }
        `)}`;
        },
        async loadstyle(win) {
            win.windowUtils.loadSheetUsingURIString(this.style, win.windowUtils.USER_SHEET);
            win.setTimeout(() => win.ucf_custom_scripts_win.ucf_sidebar_tabs.toolbox.setAttribute("sidebar_tabs_auto_hide", "true"), 0);
        },
        async removestyle(win) {
            win.windowUtils.removeSheetUsingURIString(this.style, win.windowUtils.USER_SHEET);
            win.ucf_custom_scripts_win.ucf_sidebar_tabs.toolbox.removeAttribute("sidebar_tabs_auto_hide");
        },
        showHide(win) {
            var st = win.ucf_custom_scripts_win.ucf_sidebar_tabs;
            if (!st.toolbox.hasAttribute("sidebar_tabs_auto_hide")) {
                st.toggle();
                return;
            }
            st.st_vbox_container ||= st.toolbox;
            if (!st._open && st._visible) {
                st.isPanel = false;
                st.hideToolbar(true);
            }
            st.showHide();
            if (!st._visible)
                win.setTimeout(() => st.toolbox.removeAttribute("sidebar_tabs_visible"), 0);
        },
    },
) => CustomizableUI.createWidget({
    id,
    label,
    tooltiptext,
    defaultArea: CustomizableUI.AREA_NAVBAR,
    localized: false,
    onBeforeCreated_(doc) {
        if (Services.prefs.getBoolPref(pref, true))
            sidebar_tabs.loadstyle(doc.defaultView);
    },
    onBeforeCreated(doc) {
        this.onBeforeCreated = this.onBeforeCreated_;
        this.onBeforeCreated_(doc);
        CustomizableUI.destroyWidget("ucf_sidebar_tabs");
    },
    onCreated(btn) {
        btn.style.setProperty("list-style-image", `url("${img}")`);
        btn.setAttribute("context", "");
        var st = btn.ownerGlobal.ucf_custom_scripts_win.ucf_sidebar_tabs;
        btn.checked = st._open;
        st.button = btn;
        var func = st.mouseup.toString();
        Services.scriptloader.loadSubScript(`data:charset=utf-8,${encodeURIComponent(`this.mouseup = ${func.replace(/^(async\s)?.*?\(/, '$1function mouseup(')
            .replace(/\}$/g, 'setTimeout(() => this.toolbox.removeAttribute("sidebar_tabs_visible"), 0);}')}`)}`, st);
    },
    onClick(e) {
        switch (e.button) {
            case 0:
                if (!e.getModifierState("Control"))
                    sidebar_tabs.showHide(e.view);
                else
                    e.view.ucf_custom_scripts_win.ucf_sidebar_tabs.toggle();
                break;
            case 1:
                e.view.ucf_custom_scripts_win.ucf_sidebar_tabs.toggle();
                break;
            case 2:
                let prf = Services.prefs.getBoolPref(pref, true),
                loadremove = !prf ? "loadstyle" : "removestyle";
                Services.prefs.setBoolPref(pref, !prf);
                for (let win of CustomizableUI.windows)
                    sidebar_tabs[loadremove](win);
                break;
        }
    },
}))();

и еще в консоли есть ошибки свяаные с этими кнпками
скрытый текст

Выделить код

Код:

Content-Security-Policy: (Политика Report-Only) Настройки страницы блокируют выполнение обработчика события (script-src-attr), поскольку он нарушает следующую директиву: «script-src-attr 'none' 'report-sample'» ucf-cbbtn-LnkCreator.js:77:8
Content-Security-Policy: (Политика Report-Only) Настройки страницы блокируют выполнение обработчика события (script-src-attr), поскольку он нарушает следующую директиву: «script-src-attr 'none' 'report-sample'» ucf-cbbtn-OpenPageInOtherBrowser.js:33:9

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

Выделить код

Код:

// Открыть страницу в другом браузере
(async id => CustomizableUI.createWidget({
	label: "Открыть страницу в другом браузере",
	get image() {
        var img = `${this.id.toLowerCase()}-img`;
        Services.io.getProtocolHandler("resource")
        .QueryInterface(Ci.nsIResProtocolHandler)
        .setSubstitution(img, Services.io.newURI("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity' d='M7.94.062h.085a7.42 7.42 0 0 1 3.868 1.082l-.035-.02a7.77 7.77 0 0 1 3.033 3.25l.02.043-6.44-.344a4.18 4.18 0 0 0-2.57.672l.016-.01a3.826 3.826 0 0 0-1.6 2.006l-.008.026L1.913 3.01A7.657 7.657 0 0 1 4.569.856l.046-.02A7.54 7.54 0 0 1 7.938.06h.002zM1.455 3.649l2.926 5.875a4.317 4.317 0 0 0 1.81 1.91l.022.012a3.669 3.669 0 0 0 1.81.471c.26 0 .512-.026.756-.077l-.024.004-1.997 3.995a7.788 7.788 0 0 1-5.686-4.153l-.02-.043a7.818 7.818 0 0 1-.864-3.6v-.048.003-.046c0-1.603.474-3.092 1.285-4.332l-.017.029zm13.769 1.497c.32.815.51 1.76.518 2.75v.002l.001.114c0 .93-.154 1.823-.439 2.654l.017-.057a7.898 7.898 0 0 1-1.339 2.423l.01-.013a7.845 7.845 0 0 1-2.098 1.834l-.036.02a7.46 7.46 0 0 1-4.345 1.053l.022.002 3.516-5.519a4.262 4.262 0 0 0 .716-2.582v.01a3.902 3.902 0 0 0-.929-2.464l.004.005 4.382-.232zm-7.256.178c1.447 0 2.62 1.198 2.622 2.675-.001 1.477-1.175 2.675-2.622 2.675-1.448 0-2.621-1.198-2.622-2.675 0-1.477 1.174-2.675 2.622-2.675z'/></svg>"));
        delete this.image;
        return this.image = `resource://${img}`;
    },	
	tooltiptext: [
		"С: Добавить в меню новый браузер",
		"\nФункции кликов мыши для меню:",
			"\tЛ: Открыть страницу",
			"\tС: Добавить разделитель",
			"\tП: Удалить пункт меню или разделитель",
			"\tCtrl+П: Изменить название пункта меню",
		"Перетаскиванием можно передвигать пункты меню или разделители"
	].join("\n"),

	id,
	localized: false,
	onCreated(btn) {
		btn.owner = this;
		btn.type = "menu";
		btn.setAttribute("image", this.image);
		btn.openPopup = btn.openMenu;
		btn.openMenu = this.openMenu;

		var popup = btn.appendChild(btn.ownerDocument.createXULElement("menupopup"));
		popup.setAttribute("context", "");
		popup.setAttribute("oncommand", "owner.command(event)");

		btn.onauxclick = this.auxclick;
		popup.setAttribute("onpopupshowing", "this.shouldRebuild && owner.rebuild(this)");
		popup.ondragstart = this.dragstart;
		popup.shouldRebuild = true;

		var {openDelay, closeDelay} = this;
		this.autoOpenCloseFeature(btn.ownerGlobal, btn, openDelay, closeDelay);
	},
	file: Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile),
	openMenu(...args) {
		if (this.parentNode != this.domParent) {
			this.domParent = this.parentNode;
			this.owner.setPopupPosition(this);
		}
		this.openPopup(...args);
	},
	setPopupPosition(node) {
		if (node.matches(".widget-overflow-list > :scope"))
			var pos = "after_start";
		else var win = node.ownerGlobal, {width, height, top, bottom, left, right} =
			node.closest("toolbar").getBoundingClientRect(), pos = width > height
				? `${win.innerHeight - bottom > top ? "after" : "before"}_start`
				: `${win.innerWidth - right > left ? "end" : "start"}_before`;
		node.firstChild.setAttribute("position", pos);
	},
	// https://github.com/Infocatcher/Custom_Buttons/blob/master/code_snippets/autoOpenCloseMenu.js
	// Automatically open menu on mouse over (and hide it on mouse out)
	autoOpenCloseFeature(win, btn, openDelay = 200, closeDelay = 350) {
		var _openTimer = 0;
		var _closeTimer = 0;
		btn.onmouseover = function(e) {
			win.clearTimeout(_closeTimer);
			if(e.target == btn && closeOtherMenus()) {
				btn.open = true;
				return;
			}
			_openTimer = win.setTimeout(function() {
				btn.open = true;
			}, openDelay);
		};
		btn.onmouseout = function(e) {
			win.clearTimeout(_openTimer);
			_closeTimer = win.setTimeout(function() {
					btn.open = false;
			}, closeDelay);
		};
		function closeOtherMenus() {
			return win.Array.prototype.some.call(
				btn.parentNode.getElementsByTagName("*"),
				function(node) {
					if(
						node != btn
						&& win.XULElement.isInstance(node)
						// See https://github.com/Infocatcher/Custom_Buttons/issues/28
						//&& node.boxObject
						//&& node.boxObject instanceof Components.interfaces.nsIMenuBoxObject
						&& "open" in node
						&& node.open
						&& node.getElementsByTagName("menupopup").length
					) {
						node.open = false;
						return true;
					}
					return false;
				}
			);
		}
	},
	get markup() {
		try {var data = Cu.readUTF8URI(Services.io.newURI(
			`chrome://user_chrome_files/content/custom_scripts/${id}-data.txt`
		)).split("\n").filter(line => /\S/.test(line));}
		catch {var data = [
		];}
		delete this.markup;
		return this.markup = this.dataToMarkup(data);
	},
	setMarkup(popup) {
		this.markup = popup.innerHTML;
		for(var {node} of CustomizableUI.getWidget(id).instances)
			if (node.firstChild != popup) node.firstChild.shouldRebuild = true;
		this.write(Array.from(popup.children,
			node => node.hasAttribute("value")
				? node.tooltipText + (node.value == "true" ? ">" + node.label : "")
				: "separator"
		).join("\n"));
	},
	dataToMarkup(data) {
		var markup = "";
		for(var str of data) markup += str == "separator"
			? "<menuseparator/>" : this.strToMenuitem(str);
		return markup;
	},
	repl: [/^./, c => c.toUpperCase()],
	strToMenuitem(str, ind = str.lastIndexOf(">")) {
		var name, val, path = str;
		if ((val = ind != -1))
			path = str.slice(0, ind),
			name = str.slice(ind + 1);
		else
			this.file.initWithPath(path),
			name = this.file.leafName.split(".")
				.shift().replace(...this.repl);

		return `<menuitem label="${name}" tooltiptext="${path}" value="${val}"`
			+ ` class="menuitem-iconic" image="moz-icon://file://${path}"/>`;
	},
	append(popup, xul = this.markup) {
		popup.append(popup.ownerGlobal.MozXULElement.parseXULToFragment(xul));
	},
	rebuild(popup) {
		popup.textContent = "";
		this.append(popup);
		delete popup.shouldRebuild;
	},
	auxclick(e) {
		var trg = e.target, popup = this.firstChild;
		if (trg == this && e.button == 1)
			return this.owner.addMenuitem(popup);

		else if (trg.parentNode != popup) return;

		if (e.button == 1) {
			var up = e.screenY < trg.screenY + trg.clientHeight/2;
			up = up ? trg.previousSibling : !trg.nextSibling;
			trg[up ? "before" : "after"](
				trg.ownerDocument.createXULElement("menuseparator")
			);
		} else {
			if (e.ctrlKey) {
				if (trg.nodeName.endsWith("r")) return;

				var name = this.owner.prompt(
					"Введите другое название пункта",
					trg.label, trg.ownerGlobal
				);
				if (name && name != trg.label)
					trg.label = name,
					trg.value = true;
			}
			else trg.remove();
		}
		this.owner.changeMarkup(popup);
	},
	prompt(msg, value, domWin) {
		var res = {value};
		return Services.prompt.wrappedJSObject.pickPrompter({
			domWin, modalType: Ci.nsIPrompt.MODAL_TYPE_WINDOW
		}).nsIPrompt_prompt(this.label, msg, res, null, {})
			? res.value : null;
	},
	addMenuitem(popup) {
		var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
		fp.appendFilters(fp.filterApps);
		fp.init(popup.ownerGlobal.browsingContext, "Укажите путь к программе", fp.modeOpen);
		fp.open(res => {
			if (res == fp.returnOK)
				this.append(popup, this.strToMenuitem(fp.file.path, -1)),
				this.setMarkup(popup);
		});
	},
	changeMarkup(popup) {
		popup.state == "open"
			? popup.addEventListener("popuphidden", this, {once: true})
			: this.setMarkup(popup);
	},
	handleEvent(e) {
		this[e.type](e);
	},
	popuphidden(e) {
		this.setMarkup(e.target);
	},
	dragstart(e) {
		var trg = e.target;
		if (trg.parentNode.nodeName != "menupopup") return;

		var {owner} = this.parentNode;
		var pn = trg.flattenedTreeParentNode;
		owner.dragData = {trg, pn, ns: trg.nextSibling};

		trg.style.cssText = "font-weight: bold; color: red;"
			+ "outline: 2px solid red; outline-offset: -2px;"
				.replace(/;/g, " !important;");
		var win = trg.ownerGlobal;
		win.setCursor("grabbing");
		pn.addEventListener("mousemove", owner);
		win.addEventListener("mouseup", owner, {once: true});
	},
	mousemove(e) {
		var trg = e.target, dtrg = this.dragData.trg;
		if (trg == dtrg) return;

		e.movementY > 0
			? trg.nextSibling != dtrg && trg.after(dtrg)
			: trg.previousSibling != dtrg && trg.before(dtrg);
	},
	mouseup(e) {
		e.preventDefault();
		var {trg, pn, ns} = this.dragData;
		delete this.dragData;
		trg.removeAttribute("style");
		trg.ownerGlobal.setCursor("auto");
		pn.removeEventListener("mousemove", this);
		trg.nextSibling != ns && this.changeMarkup(trg.parentNode);
	},

	command(e) {
		this.file.initWithPath(e.target.tooltipText);
		if (this.file.exists()) {
			var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
			process.init(this.file);
			return process.run(false, [e.view.gBrowser.currentURI.spec], 1);
		}
		Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
			.showAlertNotification(this.image, this.label, "Файл не существует");
	},
	write(txt) {
		var file = Services.dirsvc.get("UChrm", Ci.nsIFile), CC = Components.Constructor;
		["user_chrome_files", "custom_scripts", id + "-data.txt"].forEach(file.append);
		var te = new (Cu.getGlobalForObject(Cu).TextEncoder)();
		var fos = CC("@mozilla.org/network/file-output-stream;1", "nsIFileOutputStream", "init")
			// MODE_{WRONLY, CREATE, TRUNCATE}, PERMS_FILE
			.bind(null, file, 0x02 | 0x08 | 0x20, 0o644, 0);
		var bos = CC("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream", "setOutputStream");

		(this.write = txt => {
			var stream = new fos();
			try {new bos(stream).writeByteArray(te.encode(txt));}
			catch(ex) {Cu.reportError(ex);}
			finally {stream.close();}
		})(txt);
	}
}))("ucf-cbbtn-OpenPageInOtherBrowser");

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

Выделить код

Код:

//Вкладки в контейнере.............
(async () => CustomizableUI.createWidget(({
	label: "Вкладки в контейнере",
	get image() {
        var img = `${this.id.toLowerCase()}-img`;
        Services.io.getProtocolHandler("resource")
        .QueryInterface(Ci.nsIResProtocolHandler)
        .setSubstitution(img, Services.io.newURI("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><rect width='6' height='6' x='1' y='1' rx='1'/><path d='M14.75 3H13V1.25a.25.25 0 0 0-.25-.25h-1.5a.25.25 0 0 0-.25.25V3H9.25a.25.25 0 0 0-.25.25v1.5a.25.25 0 0 0 .25.25H11v1.75a.25.25 0 0 0 .25.25h1.5a.25.25 0 0 0 .25-.25V5h1.75a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25'/><rect width='6' height='6' x='1' y='9' rx='1'/><rect width='6' height='6' x='9' y='9' rx='1'/></g></svg>"));
        delete this.image;
        return this.image = `resource://${img}`;
    },
	get defaultFavicon() {
        var img = `${this.id.toLowerCase()}-default-favicon-img`;
        Services.io.getProtocolHandler("resource")
        .QueryInterface(Ci.nsIResProtocolHandler)
        .setSubstitution(img, Services.io.newURI("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity;' d='M13.384 3.408c.535.276 1.22 1.152 1.556 1.963a8 8 0 0 1 .503 3.897l-.009.077-.026.224A7.758 7.758 0 0 1 .006 8.257v-.04q.025-.545.114-1.082c.01-.074.075-.42.09-.489l.01-.051a6.6 6.6 0 0 1 1.041-2.35q.327-.465.725-.87.35-.358.758-.65a1.5 1.5 0 0 1 .26-.137c-.018.268-.04 1.553.268 1.943h.003a5.7 5.7 0 0 1 1.868-1.443 3.6 3.6 0 0 0 .021 1.896q.105.07.2.152c.107.09.226.207.454.433l.068.066.009.009a2 2 0 0 0 .213.18c.383.287.943.563 1.306.741.201.1.342.168.359.193l.004.008c-.012.193-.695.858-.933.858-2.206 0-2.564 1.335-2.564 1.335.087.997.714 1.839 1.517 2.357a4 4 0 0 0 .439.241q.114.05.228.094c.325.115.665.18 1.01.194 3.043.143 4.155-2.804 3.129-4.745v-.001a3 3 0 0 0-.731-.9 3 3 0 0 0-.571-.37l-.003-.002a2.68 2.68 0 0 1 1.87.454 3.92 3.92 0 0 0-3.396-1.983q-.116.001-.23.01l-.042.003V4.31h-.002a4 4 0 0 0-.8.14 7 7 0 0 0-.333-.314 2 2 0 0 0-.2-.152 4 4 0 0 1-.088-.383 5 5 0 0 1 1.352-.289l.05-.003c.052-.004.125-.01.205-.012C7.996 2.212 8.733.843 10.17.002l-.003.005.003-.001.002-.002h.002l.002-.002h.015a.02.02 0 0 1 .012.007 2.4 2.4 0 0 0 .206.48q.09.153.183.297c.49.774 1.023 1.379 1.543 1.968.771.874 1.512 1.715 2.036 3.02l-.001-.013a8 8 0 0 0-.786-2.353'/> </svg>"));
        delete this.defaultFavicon;
        return this.defaultFavicon = `resource://${img}`;
    },
	id: "ucf-cbbtn-LnkCreator",
	localized: false,
	onCreated(btn) {
		btn.owner = this;
		btn.tooltipText = this.label;
		btn.setAttribute("image", this.image);
		btn.setAttribute("oncommand", "owner.createLnk(this)");
	},
	init() {
		this.widget.parent = this;
		this.widget.contextmenu.destroy = id => {
			CustomizableUI.destroyWidget(id);
			delete this.data[id.slice(8)];
			this.save();
		}
		try {this.data = JSON.parse(Cu.readUTF8URI(Services.io.newURI(
			`chrome://user_chrome_files/content/custom_scripts/${this.id}-data.json`
		)))}
		catch {this.data = {}; return this;}
		for(var [id, inf] of Object.entries(this.data))
			this.createWidget(id, inf.url, inf.name);
		return this;
	},
	get fs() {
		delete this.fs;
		return this.fs = Cc["@mozilla.org/browser/favicon-service;1"]
			.getService(Ci.nsIFaviconService);
	},
	createLnk(btn) {
		var id = Date.now();
		var gb = btn.ownerGlobal.gBrowser;
		var uri = gb.currentURI;
		var label = gb.contentTitle.slice(0, 75);

		var widget = this.createWidget(id, uri, label);
		var {area, position} = CustomizableUI.getPlacementOfWidget(this.id);
		CustomizableUI.addWidgetToArea(widget.id, area, position + 1);

		this.data[id] = {name: label, url: uri.spec};
		this.save();
	},
	createWidget(id, url, label) {
		var obj = {
			uri: url.spec ? url : Services.io.newURI(url),
			id: "ucf-lnk-" + id, label, ...this.widget
		};
		var widget = obj.widget = CustomizableUI.createWidget(obj);
		this.fs.getFaviconDataForPage(obj.uri, obj);
		return widget;
	},
	tip: "\nShift+ПКМ - Удалить кнопку",
	widget: {
		localized: false,
		onCreated(btn) {
			btn.uri = this.uri;
			btn.addTab = this.addTab;
			btn.oncontextmenu = this.contextmenu;
			btn.setAttribute("oncommand", "addTab(this)");
			btn.tooltipText = this.label + this.parent.tip;
			this.image && btn.setAttribute("image", this.image);
		},
		addTab(btn) {
			var gb = btn.ownerGlobal.gBrowser;
			gb.selectedTab = gb.addTrustedTab(btn.uri.spec, {userContextId: 1});
		},
		contextmenu: function checkShift(e) {
			if (e.shiftKey)
				e.preventDefault(),
				checkShift.destroy(e.target.id);
		},
		onComplete(uri, len, arr, mmt) {
			this.image = len
				? `data:${mmt};base64,${btoa(String.fromCharCode(...arr))}`
				: this.parent.defaultFavicon
			for(var {node} of this.widget.instances)
				node.hasAttribute("image") || node.setAttribute("image", this.image);
			delete this.widget;
		}
	},
	save() {
		var file = Services.dirsvc.get("UChrm", Ci.nsIFile), CC = Components.Constructor;
		["user_chrome_files", "custom_scripts", this.id + "-data.json"].forEach(file.append);
		var te = new (Cu.getGlobalForObject(Cu).TextEncoder)();
		var fos = CC("@mozilla.org/network/file-output-stream;1", "nsIFileOutputStream", "init")
			// MODE_{WRONLY, CREATE, TRUNCATE}, PERMS_FILE
			.bind(null, file, 0x02 | 0x08 | 0x20, 0o644, 0);
		var bos = CC("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream", "setOutputStream");

		(this.save = () => {
			var stream = new fos();
			try {new bos(stream).writeByteArray(
				te.encode(JSON.stringify(this.data))
			);} catch(ex) {Cu.reportError(ex);}
			finally {stream.close();}
		})();
	}
}).init()))();

[firefox] 137.0

Отредактировано egorsemenov06 (Вчера 08:47:55)

Отсутствует

 

№195231-03-2025 23:03:40

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 23-07-2024
Сообщений: 30
UA: Firefox 137.0

Re: UCF - ваши кнопки, скрипты…

вот еще одна кнопка с такой же ошибкой Content-Security-Policy: (Политика Report-Only) Настройки страницы блокируют выполнение обработчика события (script-src-attr), поскольку он нарушает следующую директиву: «script-src-attr 'none' 'report-sample'» custom_script.js line 131 > Function:45:11

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

Выделить код

Код:

//Save........................................
(async () => CustomizableUI.createWidget({
	id: "ucf-cbbtn-Save",
	tooltiptext: "Сохранить",
	localized: false,
    get initCode() {
		var count = 0;
		var prfx = "ucf-cbbtn-save-resurl-";
		var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
		var ss = url => {
			var subst = prfx + ++count;
			rph.setSubstitution(subst, Services.io.newURI(url));
			return "resource://" + subst;
		}
		this.image = ss("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill  rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M3 .6C1.6.6.6 1.6.6 3v10c0 1.4 1 2.4 2.4 2.4h10c1.4 0 2.4-1 2.4-2.4V4.84L11.2.602Zm5.4 5.8h2V1m-2 0v5.4H7L5.6 5V1m-2 14v-2.6l1-1h6.8l1 1V15'/></svg>");
		var arr = [
			"@-moz-document url(chrome://browser/content/browser.xhtml) {",
			`	#${this.id} menuitem, #content-baseItem, #content-saveItem, #content-editorItem {`,
			"		fill: currentColor !important;",
			"		-moz-context-properties: fill, fill-opacity !important;",
			"	}",
			"}",

			"}"
		];
		var url = "data:text/css;charset=utf-8," + encodeURIComponent(arr.join("\n"));
		var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
		sss.loadAndRegisterSheet(Services.io.newURI(ss(url)), sss.USER_SHEET);

		delete this.initCode;
		return this.initCode = Cu.readUTF8URI(Services.io.newURI(
			"chrome://user_chrome_files/content/custom_scripts/custom_script/ucf-cbbtn-Save.js"
		))
			.replace(/data:image\/svg[^"]+/g, ss);
	},
	cbu: {
		types: {
			128: "Bool", boolean: "Bool",
			64: "Int", number: "Int",
			32: "String", string: "String"
		},
		getPrefs(pref) {
			try {
				return Services.prefs[`get${
					this.types[Services.prefs.getPrefType(pref)]
				}Pref`](pref);
			}
			catch {return null;}
		},
		setPrefs(pref, val) {
			Services.prefs[`set${this.types[typeof val]}Pref`](pref, val);
		}
	},
	gClipboard: {
		get ch() {
			delete this.ch;
			return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"]
				.getService(Ci.nsIClipboardHelper);
		},
		write(str) {
			this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard);
		}
	},
	custombuttonsUtils: {
		writeFile(path, data) {
			try {
				if (path.includes(":\\")) path = path.replace(/\//g, "\\");
				var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
				file.initWithPath(path);
				file.exists() && file.remove(false);

				var strm = Cc["@mozilla.org/network/file-output-stream;1"]
					.createInstance(Ci.nsIFileOutputStream);
				strm.init(file, 0x04 | 0x08, 420, 0);
				strm.write(data, data.length);
				strm.flush();
				strm.close();
			} catch(ex) {
				Cu.reportError("Custom Buttons: " + [path, "---", ex, ex.stack].join("\n"));
			}
		}
	},
	addDestructor(destructor, context) {
		this._destructors.push({destructor, context});
	},
	addEventListener(...args) {
		var trg = args[3];
		if (!trg) trg = args[3] = this.ownerGlobal;
		trg.addEventListener(...args);
		this._handlers.push(args);
	},

    onCreated(btn) {
		var win = btn.ownerGlobal;
		btn._handlers = new win.Array();
		btn._destructors = new win.Array();
		win.addEventListener("unload", this, {once: true});
		new win.Function(
			"self,_id,cbu,xhtmlns,addDestructor,addEventListener,gClipboard,custombuttonsUtils",
			this.initCode
		).call(
			btn, btn, this.id, this.cbu,
			"http://www.w3.org/1999/xhtml",
			this.addDestructor.bind(btn),
			this.addEventListener.bind(btn),
			this.gClipboard, this.custombuttonsUtils
		);
        btn.setAttribute("image", this.image);
    },
	handleEvent(e) {
		var btn = e.target.getElementById(this.id);
		for(var args of btn._handlers)
			args.pop().removeEventListener(...args);
		delete btn._handlers;
		for(var {destructor, context} of btn._destructors)
			try {destructor.call(context, "destructor");}
			catch(ex) {Cu.reportError(ex);}
		delete btn._destructors;
	}
}))();

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

Выделить код

Код:

self.label = "Save";
this.type = "menu";
var folderpath="C:\\Users\\Роман\\Desktop"; 

var array = [
   { label: "Сохранить значок веб-сайта", func: "saveFavicon()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M8.5 1a7.5 7.5 0 1 0 0 15 7.5 7.5 0 0 0 0-15zm2.447 1.75a6.255 6.255 0 0 1 3.756 5.125h-2.229A9.426 9.426 0 0 0 10.54 2.75h.407zm-2.049 0a8.211 8.211 0 0 1 2.321 5.125H5.781A8.211 8.211 0 0 1 8.102 2.75h.796zm-2.846 0h.408a9.434 9.434 0 0 0-1.934 5.125H2.297A6.254 6.254 0 0 1 6.052 2.75zm0 11.5a6.252 6.252 0 0 1-3.755-5.125h2.229A9.426 9.426 0 0 0 6.46 14.25h-.408zm2.05 0a8.211 8.211 0 0 1-2.321-5.125h5.437a8.211 8.211 0 0 1-2.321 5.125h-.795zm2.846 0h-.409a9.418 9.418 0 0 0 1.934-5.125h2.229a6.253 6.253 0 0 1-3.754 5.125z'/></svg>"},
   { label: "Запомнить значок веб-сайта как base64", func: "copyFaviconData()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z'/><path d='M8.646 6.646a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L10.293 9 8.646 7.354a.5.5 0 0 1 0-.708zm-1.292 0a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0 0 .708l2 2a.5.5 0 0 0 .708-.708L5.707 9l1.647-1.646a.5.5 0 0 0 0-.708z'/></g></svg>"},  
   { separator: ''},
   { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M0 1.512v13.101c0 .835.677 1.512 1.512 1.512h13.101c.835 0 1.512-.677 1.512-1.512V1.512C16.125.677 15.448 0 14.613 0H1.512C.677 0 0 .677 0 1.512zm2.719.188a.6.596 0 0 1-.598.6.6.6 0 0 1 0-1.198.6.596 0 0 1 .598.598zm2.22 0a.6.596 0 0 1-.598.6.599.599 0 0 1 0-1.198.6.596 0 0 1 .598.598zm2.221 0a.6.596 0 0 1-.599.6.6.6 0 0 1 0-1.198.6.596 0 0 1 .599.598zm-5.9 1.576h13.606v11.337a.253.251 0 0 1-.253.252H1.512a.253.251 0 0 1-.253-.252V3.276z' class='st0'/><path d='M8.314 6.047h4.787v1.008H8.314V6.047zm-5.543 5.04h10.33v1.007H2.77v-1.008zm0-5.04h3.78v3.78H2.77v-3.78zm6.14 3.527h-.597V8.567h4.788v1.007H8.912z' class='st0'/></g></svg>"},
   { separator: ''},  
   { label: "Кодировать изображение(текст.файл) в base64", func: "copyFaviconbase()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M11.188 5.058a.625.625 0 0 1 .884 0l2.146 2.147c.44.439.44 1.151 0 1.59l-2.146 2.147a.625.625 0 1 1-.884-.884L13.246 8l-2.058-2.058a.625.625 0 0 1 0-.884ZM9.557 3.034c.33.103.513.454.41.783l-2.74 8.74a.625.625 0 0 1-1.193-.374l2.74-8.74a.625.625 0 0 1 .783-.41ZM4.812 5.058a.625.625 0 0 1 0 .884L2.754 8l2.058 2.058a.625.625 0 1 1-.884.884L1.782 8.796a1.125 1.125 0 0 1 0-1.591l2.146-2.147a.625.625 0 0 1 .884 0Z' clip-rule='evenodd'/></svg>"},
   { separator: ''},
   { label: "Сохранить всю страницу как PDF", func: "savePageToPDF()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2zM9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5v2z'/><path d='M4.603 14.087a.81.81 0 0 1-.438-.42c-.195-.388-.13-.776.08-1.102.198-.307.526-.568.897-.787a7.68 7.68 0 0 1 1.482-.645 19.697 19.697 0 0 0 1.062-2.227 7.269 7.269 0 0 1-.43-1.295c-.086-.4-.119-.796-.046-1.136.075-.354.274-.672.65-.823.192-.077.4-.12.602-.077a.7.7 0 0 1 .477.365c.088.164.12.356.127.538.007.188-.012.396-.047.614-.084.51-.27 1.134-.52 1.794a10.954 10.954 0 0 0 .98 1.686 5.753 5.753 0 0 1 1.334.05c.364.066.734.195.96.465.12.144.193.32.2.518.007.192-.047.382-.138.563a1.04 1.04 0 0 1-.354.416.856.856 0 0 1-.51.138c-.331-.014-.654-.196-.933-.417a5.712 5.712 0 0 1-.911-.95 11.651 11.651 0 0 0-1.997.406 11.307 11.307 0 0 1-1.02 1.51c-.292.35-.609.656-.927.787a.793.793 0 0 1-.58.029zm1.379-1.901c-.166.076-.32.156-.459.238-.328.194-.541.383-.647.547-.094.145-.096.25-.04.361.01.022.02.036.026.044a.266.266 0 0 0 .035-.012c.137-.056.355-.235.635-.572a8.18 8.18 0 0 0 .45-.606zm1.64-1.33a12.71 12.71 0 0 1 1.01-.193 11.744 11.744 0 0 1-.51-.858 20.801 20.801 0 0 1-.5 1.05zm2.446.45c.15.163.296.3.435.41.24.19.407.253.498.256a.107.107 0 0 0 .07-.015.307.307 0 0 0 .094-.125.436.436 0 0 0 .059-.2.095.095 0 0 0-.026-.063c-.052-.062-.2-.152-.518-.209a3.876 3.876 0 0 0-.612-.053zM8.078 7.8a6.7 6.7 0 0 0 .2-.828c.031-.188.043-.343.038-.465a.613.613 0 0 0-.032-.198.517.517 0 0 0-.145.04c-.087.035-.158.106-.196.283-.04.192-.03.469.046.822.024.111.054.227.09.346z'/></g></svg>"},
   { label: "Сохранить всю страницу или выбранное как HTML", func: "savePageToHTML()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M12.225.01H2.656v5.993l.955-.125L3.569.677 11 .76l-.042 4.375h4.275l.041 10.125-12.575.042-.042.708h13.281V3.737L12.225.01zm-.272 1.613 2.384 2.394h-2.384V1.623zm2.93 10.318.062 1.333-2.992.063V8.003h1.328v4l1.601-.063zM4.647 8.002h-.664v1.334h.664v4h1.329v-4h.664V8.003H4.648zm5.313 0-.664 1.074-.664-1.074H7.305v5.334h1.328V10.53l.664 1.073.664-1.073v2.807h1.328V8.003H9.961zm-7.969 2h-.664v-2H0v5.334h1.328v-2h.664v2H3.32V8.003H1.992v2z'/></svg>"},
   { label: "Сохранить выделенный текст как txt файл", func: "saveSelectionToTxt()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M5.5 7a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1h-5zM5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z'/><path d='M9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0zm0 1v2A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z'/></g></svg>"},
   { separator: ''},
   { label: "Запомнить изображение как base64, в контекстном меню", value: "Save.WebScreenShotOnImage"},
   { label: "Сохранить выделенный текст в файл, в контекстном меню", value: "Save.SelectionToFile" },
   { label: "Открыть выделенный текст в внешнем редакторе, в контекстном меню", value: "Save.TextToEditor"},
];

var menuPopup = self.appendChild(document.createXULElement("menupopup"));
var PHandler = Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler), count = 0;
array.forEach((m,i)=> {
   if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return };
   var mItem = menuPopup.appendChild(document.createXULElement("menuitem"));
   mItem.setAttribute("label", m.label);
   mItem.setAttribute("class", "menuitem-iconic");
if ("image" in m) {
        let substitution = `ucf-cbbtn-save-${++count}-img`;
        if (!PHandler.hasSubstitution(substitution))
            PHandler.setSubstitution(substitution, Services.io.newURI(m.image || array[i-1].image));
        mItem.style.cssText = `list-style-image:url("resource://${substitution}");-moz-context-properties:fill,fill-opacity;fill:currentColor;`;
    }
   if ("value" in m) { 
       mItem.setAttribute('type', 'checkbox');
       mItem.setAttribute('checked', cbu.getPrefs(m.value) );
       mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value));
       }
   if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString()));
});
menuPopup.setAttribute("onclick", "event.stopPropagation()");


function aDate() {
 var t=new Date();
 var y=1900+t.getYear();
 var min=t.getMinutes(); if (min<10){min="0"+min};
 var h=t.getHours();
 var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";}
 var d=t.getDate();
 var curdate=d+" "+m+" "+y+" "+"г";
 var myfilename=curdate;
 return myfilename;
}
 

function WebScreenShotonImage(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)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Изображение копировано как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0);
      }, "");
};


var saveToFile = function (fileContent, fileName) {
    var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    uc.charset = 'utf-8';
    fileContent = uc.ConvertFromUnicode(fileContent);

    var nsIFilePicker = Components.interfaces.nsIFilePicker;
    var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
    fp.init(window.browsingContext, '', fp.modeSave);
    fp.defaultString = fileName;
    fp.appendFilters(fp.filterHTML);
    fp.appendFilters(fp.filterAll);
    fp.open(function (rv) {
  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
    var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(fp.file, 0x02|0x20|0x08, 0666, 0);
    stream.write(fileContent, fileContent.length);
    stream.close();
  }
});
};


function savePageToHTML() {
var vert = String.raw`javascript:(function(){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 selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.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((/%5C.jpe%3Fg/i.test(src)%3F'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={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},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(Object.prototype.hasOwnProperty.call(obj,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)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/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,b,c,d){return b+encodeImg(qualifyURL(c))+d});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)!='%23')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(){if('$'in win)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 win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();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))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}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('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`;
gBrowser.fixupAndLoadURIString(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
};


function saveShortcuts() {
var file = Components.classes["@mozilla.org/file/local;1"].
           createInstance(Components.interfaces.nsIFile);
file.initWithPath(folderpath);

if( !file.exists() || !file.isDirectory() ) {   file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);}

var savetodir=folderpath+"\\"; 
var urllink=gBrowser.currentURI.spec;
var out=getTabLabel();
var filename=savetodir+out+'.url';
var data="[InternetShortcut]\r\nURL="+urllink+"\r\n";

saveToFile(data, filename);
      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);
   var notific = 'Сохранил в: ' + folderpath;
   var image = gBrowser.selectedBrowser.mIconURL;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific);
};

function copyFaviconbase(){
var fp = window.makeFilePicker();
fp.init(window.browsingContext, "Открыть файл", fp.modeOpen);
fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\
                                    *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw");
  fp.open(re=> { 
  if ( re != fp.returnOK ) return;
   var file = fp.file;
   var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
   inputStream.init(file, 0x01, 0600, 0);
   var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
   stream.setInputStream(inputStream);
   var encoded = btoa(stream.readBytes(stream.available()));
   var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file);
   var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded;
   gClipboard.write(dataURI);
   //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Текст скопирован как  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)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Изображение скопировано как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0);
      }, "");
});
};

function savePageToPDF() {
      var loc = gBrowser.currentURI.spec;
   var vert = "http://pdfmyurl.com?url=" + loc;
  
   gBrowser.fixupAndLoadURIString(vert, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
   });
};

if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length >= 16
	? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) =>
		internalSave(url, null, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin)
	: internalSave.length == 15
		? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) =>
			internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin)
		: (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) =>
			internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin);
function saveFavicon() {
       var uri = gBrowser.currentURI;
       function getSiteName() {
                  try { var domain = uri.host.split('.') } catch(e) { return "" };
                   domain = (domain.length == 2) ? domain[0] : domain[1]
                   return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " ";  
            };
    var url = gBrowser.selectedTab.image;
    url && saveImageURL(
        url, getSiteName(), null, false, false, null, null,
        /^data:(image\/[^;,]+)/i.test(url) ? RegExp.$1.toLowerCase() : Cc["@mozilla.org/mime;1"]
            .getService(Ci.nsIMIMEService).getTypeFromURI(Services.io.newURI(url)),
        null, PrivateBrowsingUtils.isContentWindowPrivate(content || window), document.nodePrincipal
    );
};


function copyFaviconData() {
   var img = new Image();
   img.src = gBrowser.selectedTab.image;
   WebScreenShotonImage(img);
};

(popup => addEventListener("popupshowing", {
    handleEvent(e) {
        if (this.shouldHide) return;

        var menuitem = document.createXULElement("menuitem");
        menuitem.id = "content-baseItem";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("oncommand", "copyImageAsBase64()");
        menuitem.setAttribute("label", "Запомнить изображение как base64");
        menuitem.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z'/><path d='M8.646 6.646a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L10.293 9 8.646 7.354a.5.5 0 0 1 0-.708zm-1.292 0a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0 0 .708l2 2a.5.5 0 0 0 .708-.708L5.707 9l1.647-1.646a.5.5 0 0 0 0-.708z'/></g></svg>");
        popup.append(menuitem);
        addDestructor(() => menuitem.remove());

        menuitem.copyImageAsBase64 = () => {
            var {osPid} = gContextMenu.actor.manager.browsingContext.currentWindowGlobal;
            if (osPid == -1) osPid = Services.appinfo.processID;
            for(var ind = 0, len = Services.ppmm.childCount; ind < len; ind++) {
                var pmm = Services.ppmm.getChildAt(ind);
                if (pmm.osPid == osPid) break;
            }
            pmm.loadProcessScript("data:;charset=utf-8," + encodeURIComponent(this.code()), false);
        }
        this.handleEvent = () => menuitem.hidden = this.shouldHide;
    },
    get shouldHide() {
        return !(gContextMenu.onImage && Services.prefs.getBoolPref("Save.WebScreenShotOnImage", false));
    },
    code: () => `(targetIdentifier => {

        var image = ChromeUtils.import("resource://gre/modules/ContentDOMReference.jsm")
            .ContentDOMReference.resolve(targetIdentifier);

        var canvas = image.ownerDocument.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();

        Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
            .copyStringToClipboard(base64, Ci.nsIClipboard.kGlobalClipboard);

        Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
            .showAlertNotification(base64, "${self.label}", "Запомнил изображение как base64");
    })(${
        JSON.stringify(gContextMenu.targetIdentifier)
    })`
}, false, popup || 1))(document.getElementById("contentAreaContextMenu"));

function saveSelectionToTxt() {
    var {length} = saveURL, splice = length > 9, l11 = length >= 11;
	var msgName = _id + ":Save:GetSelection";
	var receiver = msg => {
		var args = [
			"data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\r\n\r\n" + msg.data),
			getTabLabel() + '  ' + aDate().replace(/:/g, ".") + ".txt",
			null, false, false, null, window.document
		];
        splice && args.splice(5, 0, null) && l11 && args.splice(1, 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("NAME", res);
	}
	var url = "data:charset=utf-8," + encodeURIComponent(`(${func})`.replace("NAME", msgName))
		+ '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));';
	(saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))();
}

((contextMenu, el)=> {
   var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   saveItem.id = "content-saveItem";
   saveItem.setAttribute("label", "Сохр./добавить выбранный текст в файл");
   saveItem.setAttribute("class", "menuitem-iconic");
   saveItem.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M5.5 7a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1h-5zM5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z'/><path d='M9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0zm0 1v2A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z'/></g></svg>");
   saveItem.onclick =()=> saveSelectionToFile();

   var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   editorItem.id = "content-editorItem";
   editorItem.setAttribute("label", "Открыть выбранный текст в редакторе");
   editorItem.setAttribute("class", "menuitem-iconic");
   editorItem.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M4.513 8.821h7.036v1.143H4.513zM4.513 11.107h7.036v1.143H4.513zM4.513 6.536h7.036v1.143H4.513z'/><path d='M11.55 1.393V.25h-1.006v1.143h-2.01V.25H7.529v1.143h-2.01V.25H4.512v1.143H2V16.25h12.062V1.393H11.55zm1.507 13.714H3.005V2.536h1.508v1.143h1.005V2.536h2.01v1.143h1.006V2.536h2.01v1.143h1.005V2.536h1.508v12.571z'/></g></svg>"); 
   editorItem.onclick =()=> textToEditor();

   addEventListener('popupshowing', e=> {
      if (e.target != e.currentTarget) return;
      var sel = gContextMenu.isTextSelected;
      saveItem.hidden = !sel || !cbu.getPrefs("Save.SelectionToFile");
      editorItem.hidden = !sel || !cbu.getPrefs("Save.TextToEditor"); 
      }, false, contextMenu);

   addDestructor(()=> {
      saveItem.remove(); editorItem.remove();
   });   
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open"));

function saveSelectionToFile() {
    var line = ".".repeat(62) + "\n";
    var hint = "Нажмите чтобы открыть файл";
    var prfx = "Выделенный текст сохранен в файл ";

    var img = self.getAttribute("image");
    var desk = Services.dirsvc.get("Desk", Ci.nsIFile);
    var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);

    (saveSelectionToFile = async () => {
        var time = aDate(), url = gBrowser.currentURI.displaySpec;
        var text = `${line}${getTabLabel()} - ${time}\n${url}\n\n${
            gContextMenu.contentData.selectionInfo.fullText
        }\n\n\n`;
        try {
            var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);
            var msg = prfx + "в папку " + file.leafName;
            await IOUtils.makeDirectory(file.path);
        } catch(ex) {
            file && Cu.reportError(ex);
            file = desk.clone();
            var msg = prfx + "на рабочий стол";
        }
        file.append(`Save - ${time}.txt`);
        await IOUtils.writeUTF8(file.path, text, {mode: file.exists() ? "append" : "create"});

        var name = "sstf-" + Cu.now();
        as.showAlertNotification(
            gBrowser.selectedTab.image || img, msg, hint, true, "",
            (s, t) => t == "alertclickcallback" && file.launch(), name
        );
        setTimeout(as.closeAlert, 8e3, name);
    })();
};

function textToEditor() {
 let browserMM = gBrowser.selectedBrowser.messageManager;
 browserMM.addMessageListener('getSelect', function listener(message) {
    var text = convertFromUnicode("UTF-8", message.data); 
    try {var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {file = Services.dirsvc.get("Desk", Ci.nsIFile);}
   file.append("TextToEditor.txt");
   custombuttonsUtils.writeFile(file.path, text);
   file.launch(); 
          

 browserMM.removeMessageListener('getSelect', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false);
};

function convertFromUnicode(charset, str) {
     var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
     converter.charset = charset;
     str = converter.ConvertFromUnicode(str);
     return str + converter.Finish();
 
};

function getTabLabel() { 
   var label = gBrowser.selectedTab.label;      
   var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
   return label.substring(0, 50);
};
 ((main, parts) => this.onmousedown = e => {
    if (e.button) return;
    this.onmousedown = null;

    var df = MozXULElement.parseXULToFragment(`
        <menugroup orient="vertical">
            <menuseparator/>
            <menuitem class="menuitem-iconic"
                image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity' d='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>"
                label="Сохранить всю страницу как PNG"
                value="all"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity' d='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>"
                label="Сохранить видимую часть страницы как PNG"
                value="page"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M11.108 8.852c.327 0 .591-.27.591-.602a.596.596 0 0 0-.59-.602c-.327 0-.591.27-.591.602 0 .332.264.602.59.602z'/><path d='M4.808 7.047c0-.665.53-1.203 1.182-1.203h6.3c.652 0 1.18.538 1.18 1.203v4.01c0 .665-.528 1.203-1.18 1.203h-6.3a1.192 1.192 0 0 1-1.182-1.203v-4.01zm1.182 0v3.524l1.639-1.808a.972.972 0 0 1 1.446 0l2.074 2.287-.008.007h1.149v-4.01h-6.3zm2.362 2.691-1.195 1.32h2.39l-1.195-1.32z'/><path d='M3.036 1.833C1.406 1.833.083 3.18.083 4.841v6.818c0 1.661 1.323 3.008 2.953 3.008h9.844c1.631 0 2.953-1.347 2.953-3.008V4.84c0-1.661-1.322-3.008-2.953-3.008H3.036zM1.265 4.841c0-.997.793-1.805 1.771-1.805h9.844c.979 0 1.772.808 1.772 1.805v6.818c0 .997-.793 1.805-1.772 1.805H3.036c-.978 0-1.771-.808-1.771-1.805V4.84z'/></g></svg>"
                label="Сохранить выбранный элемент страницы как PNG"
                value="click"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M2.63 1.255c-.76 0-1.375.616-1.375 1.375v2.685a.625.625 0 0 1-1.25 0V2.63A2.625 2.625 0 0 1 2.63.005h2.685a.625.625 0 1 1 0 1.25H2.63ZM10.06.63c0-.345.28-.625.625-.625h2.685a2.625 2.625 0 0 1 2.625 2.625v2.685a.625.625 0 1 1-1.25 0V2.63c0-.76-.616-1.375-1.375-1.375h-2.685A.625.625 0 0 1 10.06.63Zm5.31 9.43c.345 0 .625.28.625.625v2.685a2.625 2.625 0 0 1-2.625 2.625h-2.685a.625.625 0 1 1 0-1.25h2.685c.76 0 1.375-.616 1.375-1.375v-2.685c0-.345.28-.625.625-.625ZM2.729 7.3c-.79 0-1.43.64-1.43 1.429v4.542c0 .79.64 1.43 1.43 1.43H7.27c.79 0 1.43-.64 1.43-1.43V8.73c0-.79-.64-1.43-1.43-1.43H2.73ZM0 8.728A2.729 2.729 0 0 1 2.729 6H7.27A2.729 2.729 0 0 1 10 8.729v4.542A2.729 2.729 0 0 1 7.271 16H2.73A2.729 2.729 0 0 1 0 13.271V8.73Z' clip-rule='evenodd'/><path d='M6.9 14.005H2.73a.5.5 0 0 1-.372-.835l2.085-2.317a.5.5 0 0 1 .744 0l2.085 2.317a.5.5 0 0 1-.371.835ZM8 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/></svg>"
                label="Сохранить выбранную область страницы как PNG"
                value="clipping"/>
        </menugroup>
    `);

    var menugroup = df.firstChild;
    menugroup.setAttribute("context", "");
    menugroup.setAttribute("oncommand", "handleCommand(event);");
    menugroup.handleCommand = e => {
        var name = _id + ":DataURLReady";
        main = main.replace("%MESSAGE_NAME%", name);

        var urls = {}, configurable = true, enumerable = true;
        Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, {
            configurable, enumerable, get() {
                var value = `data:;charset=utf-8,({${
                    encodeURIComponent(main + part)
                }%0A}).init("${key}")`;
                Object.defineProperty(urls, key, {configurable, enumerable, value});
                return value;
        }}));
        var getTabLabel = () => {
            var label = gBrowser.selectedTab.label;      
            var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
            return label.substring(0, 50);
        }
        var listener = msg => {
            var fp = makeFilePicker();
            fp.init(window.browsingContext, "Сохранить как…", fp.modeSave);
            fp.appendFilter("", "*.png");
            fp.defaultString = getTabLabel() + ".png";
            fp.open(res => {
                if (res == fp.returnCancel || !fp.file) return;
                var wbp = makeWebBrowserPersist(), args = [
                    Services.io.newURI(msg.data), document.nodePrincipal,
                    null, null, null, null, fp.file, null
                ];
                var {length} = wbp.saveURI;
                length >= 9 && splice(args);
                length == 10 && args.splice(3, 0, null);
                wbp.saveURI(...args);
				
		setTimeout(async lp => {
			var d = await Downloads.createDownload({
				source: "about:blank", target: fp.file
			});
			(await lp).add(d);
			d.refresh(d.succeeded = true);
		}, 777, Downloads.getList(Downloads.ALL));				
            });
        }
        var splice = arr => {
            var fox74 = parseInt(Services.appinfo.platformVersion) >= 74;
            var args = [fox74 ? 7 : 2, 0, fox74 ? Ci.nsIContentPolicy.TYPE_IMAGE : null];
            (splice = arr => arr.splice(...args))(arr);
        }		
        messageManager.addMessageListener(name, listener);
        addDestructor(() => messageManager.removeMessageListener(name, listener));

        (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager
            .loadFrameScript(urls[e.target.value], false)
        )(e);
    }
    menuPopup.querySelector('menuitem[label*="ярлык"]').after(df);
})(`
    init(cmd) {
        cmd.startsWith("c")
            ? this[cmd].init(this[cmd].parent = this)
            : this[cmd]();
    },
    capture(win, x, y, width, height) {
        var canvas = win.document.createElementNS("${xhtmlns}", "canvas");
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var tryDraw = ind => {
            try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")}
            catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);}
        }
        tryDraw(17);
        sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png"));
    },
    `, {

    all: `all() {
        var win = content;
        this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY);
    }`,
    page: `page() {
        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;
        this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight);
    }`,
    clipping: `clipping: {
        handleEvent(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() {
            var win = {};
            Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
                .getFocusedElementForWindow(content, true, win);
            this.win = win.value;

            this.doc = this.win.document;
            this.body = this.doc.body;
            if (!HTMLBodyElement.isInstance(this.body)) {
                Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
                    .showAlertNotification("${self.image}", ${JSON.stringify(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 = this.win.getComputedStyle(this.body, "").cursor;
            this.body.style.cursor = "crosshair";
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            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.parent.capture.apply(this, pos);
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`,
    click: `click: {
        getPosition() {
            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() {
            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() {
            if (this.orgStyle) this.target.style.cssText = this.orgStyle;
            else this.target.removeAttribute("style");
        },
        handleEvent(e) {
            switch(e.type){
                case "click":
                    if (e.button) return;
                    e.preventDefault();
                    e.stopPropagation();
                    this.lowlight();
                    this.parent.capture.apply(this, this.getPosition());
                    this.uninit();
                    break;
                case "mouseover":
                    if (this.target) this.lowlight();
                    this.target = e.target;
                    this.highlight();
                    break;
            }
        },
        init() {
            this.win = content;
            this.doc = content.document;
            ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            this.target = false;
            ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`
});
// Autoopen/close feature
var openDelay = 200;
var closeDelay = 350;

var _openTimer = 0;
var _closeTimer = 0;
this.onmouseover = function(e) {
	clearTimeout(_closeTimer);
	if(e.target == this && closeOtherMenus()) {
		this.open = true;
		return;
	}
	_openTimer = setTimeout(function() {
		self.open = true;
	}, openDelay);
};
this.onmouseout = function(e) {
	clearTimeout(_openTimer);
	_closeTimer = setTimeout(function() {
			self.open = false;
	}, closeDelay);
};
function closeOtherMenus() {
	return Array.prototype.some.call(
		self.parentNode.getElementsByTagName("*"),
		function(node) {
			if(
				node != self
				&& XULElement.isInstance(node)
				// See https://github.com/Infocatcher/Custom_Buttons/issues/28
				//&& node.boxObject
				//&& node.boxObject instanceof Components.interfaces.nsIMenuBoxObject
				&& "open" in node
				&& node.open
				&& node.getElementsByTagName("menupopup").length
			) {
				node.open = false;
				return true;
			}
			return false;
		}
	);
}
(desc => {
	var {set} = desc;
	desc.set = val => {
		if (val) delete this.open, this.onmousedown?.({});
		set.call(this, val);
	}
	Object.defineProperty(this, "open", desc);
})(Object.getOwnPropertyDescriptor(MozElements.ButtonBase.prototype, "open"));

Отсутствует

 

Board footer

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