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

В мире Mozilla происходит много интересных событий. Но вам не нужно постоянно посещать новостные сайты, чтобы быть в курсе всех изменений. Зайдите на ленту новостей Mozilla Россия.

№1702601-09-2023 10:11:09

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 184
UA: Google 2.1

Re: Custom Buttons

Dumby пишет

bootstrap-loader.js не зачищен от Services.jsm

Спасибю, за новый bootstrap-loader-mini.js
Правда я сам понять не могу почему у меня старый на 117`м работает :cool:


Жизнь иногда такое выкидывает, что хочется подобрать...

Отсутствует

 

№1702701-09-2023 10:29:14

vitalii201
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 672
UA: Firefox 117.0

Re: Custom Buttons

Dumby, спасибо!

Отредактировано vitalii201 (01-09-2023 13:37:33)

Отсутствует

 

№1702806-09-2023 14:36:50

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

Re: Custom Buttons

Dumby или Farby - гляньте скрипт "Жесты мыши"


На сайте vk.com действия выполняются только первый раз - копирование в буфер, открытие ссылки…
Потом только строка статуса показывает следующие жесты, но команды не выполняются. Жесты заработают, если обновить страницу - но второй и последующие не сработают…

ucf_mousedrag.js

Выделить код

Код:

(async win => ({ // UCF drag and go жесты мыши https://forum.mozilla-russia.org/viewtopic.php?pid=797234#p797234
	link: {
		L: {
			name: "Копировать ссылку в буфер обмена", cmd() {
				this.gClipboard.write(this.val);
				this.flash();
			}
		},
		U: {
			name: "Копировать текст ссылки в буфер", cmd() {
				this.gClipboard.write(this.txt);
				this.flash();
			}
		},
		R: {
			name: "Открыть ссылку в новой активной странице", cmd() {
				win.openUILinkIn(this.val, "tab", this.opts);
			}
		},
		D: {
			name: "Открыть ссылку в новой фоновой странице", cmd() {
				win.openUILinkIn(this.val, "tabshifted", this.opts);
			}
		}
	},
	text: {
		U: {
			name: "Поиск текста поисковиком по умолчанию в новой активной странице", cmd() {
				this.search("tab");
			}
		},
		D: {
			name: "Поиск текста поисковиком по умолчанию в новой фоновой странице", cmd() {
				this.search("tabshifted");
			}
		},
		L: {
			name: "Копировать текст в буфер обмена", cmd() {
				this.gClipboard.write(this.val);
				this.flash();
			}
		}
	},
	toStatus(txt) {
		win.StatusPanel._labelElement.value = win.StatusPanel._label = txt;
		win.StatusPanel.panel.removeAttribute("inactive");
	},
	gClipboard: {
		write(str, ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)) {
			(this.write = str => ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard))(str);
		}
	},
	flash(color = 'rgba(240,176,0,0.5)', sec = 250, id = 'urlbar-input-container') {
		id = win.document.getElementById(id); id.style.background = color;
		setTimeout(() => { id.style.removeProperty('background-color');}, sec);
	},
	search(where) {
		var engine = Services.search[`default${this.opts.private ? "Private" : ""}Engine`];
		var submission = engine.getSubmission(this.val, null, "");
		win.openUILinkIn(submission.uri.spec, where, {postData: submission.postData, ...this.opts});
	},
	opts: { //relatedToCurrent: true,
		triggeringPrincipal: Cu.getObjectPrincipal(this),
		get userContextId() {
			return parseInt(win.gBrowser.selectedBrowser.getAttribute("usercontextid"));
		},
		get private() {
			return win.PrivateBrowsingUtils.isWindowPrivate(win);
		}
	},
	dragstart(e) {
		win = e.view.windowRoot.ownerGlobal;
		//if (!win.gBrowser.currentURI.spec.startsWith("http")) return;
		if (!e.dataTransfer.mozItemCount || !win.gBrowser.selectedBrowser.matches(":hover"))
			return;

		var dt = e.dataTransfer;
		this.type = this.link;
		this.dir = this.val = "";
		var txt = dt.getData("text/plain");
		var url = dt.getData("text/x-moz-url-data");
		if (url)
			this.val = url, this.txt = dt.getData("text/x-moz-url").split("\n")[1];
		else if (!txt) return;
		try {
			this.val = new URL(txt.trim());
		} catch {
			this.val = txt;
			if (!this.textLinkRe.test(txt))
				this.type = this.text;
		}
		this.x = e.screenX; this.y = e.screenY;
		this.drag(true);
	},
	drag(init) {
		var meth = `${init ? "add" : "remove"}EventListener`;
		for(var type of this.events) win[meth](type, this, true);
		init || win.StatusPanel.panel.setAttribute("inactive", true);
	},
	events: ["dragover", "drop", "dragend"],
	dragover(e) {
		var {x, y} = this, cx = e.screenX, cy = e.screenY;
		var dx = cx - x, ax = Math.abs(dx), dy = cy - y, ay = Math.abs(dy);
		if (ax < 10 && ay < 10) return;

		this.x = cx; this.y = cy;
		var dir = ax > ay ? dx > 0 ? "R" : "L" : dy > 0 ? "D" : "U";
		if (this.dir.endsWith(dir)) return;

		dir = this.dir += dir;
		var obj = this.type[dir];
		var txt = `${obj ? "Ж" : "Неизвестный ж"}ест мыши: ${dir + (obj ? "  " + obj.name : "")}`;
		this.toStatus(txt);
	},
	dragend(e) {
		var dt = e.dataTransfer;
		this.drag();
		var obj = this.type[this.dir];
		if (!obj || dt.mozUserCancelled) return;

		var x = e.screenX, y = e.screenY;
		var wx = win.mozInnerScreenX, wy = win.mozInnerScreenY;
		x > wx && y > wy && x < wx + win.innerWidth && y < wy + win.innerHeight
			&& obj.cmd.call(this);
	},
	textLinkRe: /^([a-z]+:\/\/)?([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&amp;]*)?)?(#[a-z][a-z0-9_]*)?$|^custombutton:\/\/\S+$/,

	observe(w) {
		this.drop = () => this.drag();
		this.handleEvent = e => this[e.type](e);
		var unload = e => {
			var w = e.target.ownerGlobal;
			w.gBrowser.tabpanels.removeEventListener("dragstart", this, true);
			if (w == win) win = null;
		}
		(this.observe = w => {
			//if (!w.toolbar.visible) return;
			w.gBrowser.tabpanels.addEventListener("dragstart", this, true);
			w.addEventListener("unload", unload, {once: true});
		})(w);
	},
	init(topic, self) {
		delete this.init;
		Services.obs.addObserver(self = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			Services.obs.removeObserver(self, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
	}
}).init("browser-delayed-startup-finished"))();

Отсутствует

 

№1702906-09-2023 17:28:40

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 184
UA: Google 2.1

Re: Custom Buttons

..

Добавлено 06-09-2023 17:41:06
Dobrov
Почти все удалось починить, но поломал - "Копировать текст ссылки в буфер"
Что-то не так с этим

кодом

Выделить код

Код:

`
		var txt = dt.getData("text/plain");
		var url = dt.getData("text/x-moz-url-data");
		if (url)
			this.val = url, this.txt = dt.getData("text/x-moz-url").split("\n")[1];
		else if (!txt) return;
		try {
			this.val = new URL(txt.trim());
		} catch {
			this.val = txt;
			if (!this.textLinkRe.test(txt))
				this.type = this.text;


И я не понимаю что этим сказано..
ucf_mousedrag.js

Выделить код

Код:

// UCF drag and go жесты мыши https://forum.mozilla-russia.org/viewtopic.php?pid=806832#p806832
(async win => ({
	link: {
		L: {
			name: "Копировать ссылку в буфер обмена", cmd() {
				this.gClipboard.write(this.val);
				this.flash();
			}
		},
		U: {
			name: "Копировать текст ссылки в буфер", cmd() {
				this.gClipboard.write(this.txt);
				this.flash();
			}
		},
		R: {
			name: "Открыть ссылку в новой активной странице", cmd() {
				win.openTrustedLinkIn(this.val, "tab", this.opts);
			}
		},
		D: {
			name: "Открыть ссылку в новой фоновой странице", cmd() {
				win.openTrustedLinkIn(this.val, "tabshifted", this.opts);
			}
		}
	},
	text: {
		U: {
			name: "Поиск текста поисковиком по умолчанию в новой активной странице", cmd() {
				this.search("tab");
			}
		},
		D: {
			name: "Поиск текста поисковиком по умолчанию в новой фоновой странице", cmd() {
				this.search("tabshifted");
			}
		},
		L: {
			name: "Копировать текст в буфер обмена", cmd() {
				this.gClipboard.write(this.val);
				this.flash();
			}
		}
	},
	toStatus(txt) {
		win.StatusPanel._labelElement.value = win.StatusPanel._label = txt;
		win.StatusPanel.panel.removeAttribute("inactive");
	},
	gClipboard: {
		write(str, ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)) {
			(this.write = str => ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard))(str);
		}
	},
	flash(color = 'rgba(240,176,0,0.5)', sec = 250, id = 'urlbar-input-container') {
		id = win.document.getElementById(id); id.style.background = color;
		setTimeout(() => { id.style.removeProperty('background-color');}, sec);
	},
	search(where) {
		var engine = Services.search[`default${this.opts.private ? "Private" : ""}Engine`];
		var submission = engine.getSubmission(this.val, null, "");
		win.openTrustedLinkIn(submission.uri.spec, where, {postData: submission.postData, ...this.opts});
	},
	opts: { //relatedToCurrent: true,
		triggeringPrincipal: Cu.getObjectPrincipal(this),
		get userContextId() {
			return parseInt(win.gBrowser.selectedBrowser.getAttribute("usercontextid"));
		},
		get private() {
			return win.PrivateBrowsingUtils.isWindowPrivate(win);
		}
	},
	dragstart(e) {
		win = e.view.windowRoot.ownerGlobal;
		//if (!win.gBrowser.currentURI.spec.startsWith("http")) return;
		if (!e.dataTransfer.mozItemCount || !win.gBrowser.selectedBrowser.matches(":hover"))
			return;

		var dt = e.dataTransfer;
		this.type = this.link;
		this.dir = this.val = "";

		var url = dt.getData("text/x-moz-url-data");
		if (url) this.val = url;
		else {
		var txt = dt.getData("text/plain");
			if (txt) {
			this.val = txt;
				if (!this.textLinkRe.test(txt)) this.type = this.text;
			}
			else return;
		}
		this.x = e.screenX; this.y = e.screenY;
		this.drag(true);
	},
	drag(init) {
		var meth = `${init ? "add" : "remove"}EventListener`;
		for(var type of this.events) win[meth](type, this, true);
		init || win.StatusPanel.panel.setAttribute("inactive", true);
	},
	events: ["dragover", "drop", "dragend"],
	dragover(e) {
		var {x, y} = this, cx = e.screenX, cy = e.screenY;
		var dx = cx - x, ax = Math.abs(dx), dy = cy - y, ay = Math.abs(dy);
		if (ax < 10 && ay < 10) return;

		this.x = cx; this.y = cy;
		var dir = ax > ay ? dx > 0 ? "R" : "L" : dy > 0 ? "D" : "U";
		if (this.dir.endsWith(dir)) return;

		dir = this.dir += dir;
		var obj = this.type[dir];
		var txt = `${obj ? "Ж" : "Неизвестный ж"}ест мыши: ${dir + (obj ? "  " + obj.name : "")}`;
		this.toStatus(txt);
	},
	dragend(e) {
		var dt = e.dataTransfer;
		this.drag();
		var obj = this.type[this.dir];
		if (!obj || dt.mozUserCancelled) return;

		var x = e.screenX, y = e.screenY;
		var wx = win.mozInnerScreenX, wy = win.mozInnerScreenY;
		x > wx && y > wy && x < wx + win.innerWidth && y < wy + win.innerHeight
			&& obj.cmd.call(this);
	},
	textLinkRe: /^([a-z]+:\/\/)?([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&amp;]*)?)?(#[a-z][a-z0-9_]*)?$|^custombutton:\/\/\S+$/,

	observe(w) {
		this.drop = () => this.drag();
		this.handleEvent = e => this[e.type](e);
		var unload = e => {
			var w = e.target.ownerGlobal;
			w.gBrowser.tabpanels.removeEventListener("dragstart", this, true);
			if (w == win) win = null;
		}
		(this.observe = w => {
			//if (!w.toolbar.visible) return;
			w.gBrowser.tabpanels.addEventListener("dragstart", this, true);
			w.addEventListener("unload", unload, {once: true});
		})(w);
	},
	init(topic, self) {
		delete this.init;
		Services.obs.addObserver(self = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			Services.obs.removeObserver(self, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
	}
}).init("browser-delayed-startup-finished"))();


Может Dumby подскажет или сам перепишешь...

Отредактировано Farby (06-09-2023 17:41:06)


Жизнь иногда такое выкидывает, что хочется подобрать...

Отсутствует

 

№1703007-09-2023 02:11:56

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

Re: Custom Buttons

Farby пишет

Почти все удалось починить, но поломал - "Копировать текст ссылки в буфер"

Нет, всё также на сайте vk.com после первого жеста второй и следующие не выполняются. Проверял на чистом профиле в Firefox 115 + UCF.

Что-то не так с этим кодом

на других сайтах работает - запоминается имя ссылки в this.txt = dt.getData("text/x-moz-url").split("\n")[1]…
и если жест для копирования имени ссылки (у меня "U"), тогда вместо URL в буфере будет имя ссылки.

Отсутствует

 

№1703107-09-2023 09:35:57

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 184
UA: Google 2.1

Re: Custom Buttons

Ну тогда есть ещё вариант, правда китайской, но с пометкой от Dumby. На UCF должен работать.

ucf Drag & Go

Выделить код

Код:

// ==UserScript==
// @name            ucf Drag & Go
// @description     鼠标拖拽 Drag & Go,来自于 Mozilla-Russia 论坛,Ryan 修改自用
// @author          Ryan, Dumby
// @include         main
// @homepageURL     https://github.com/benzBrake/FirefoxCustomize/tree/master/userChromeJS
// @referenceURL    https://forum.mozilla-russia.org/viewtopic.php?pid=797234#p797234
// @onlyonce
// ==/UserScript==

(async win => ({
    debug: false,
    link: {
        U: {
            name: "Open Link new Tab", cmd(val) {
                win.openTrustedLinkIn(val, "tab", this.opts);
            }
        },
        R: {
            name: "Open Link new Tab in background", cmd(val) {
                win.openTrustedLinkIn(val, "tabshifted", this.opts);
            }
        },
        RD: {
            name: "Save As Link", cmd(val) {
                this.saveAs(val);
            }
        },
        L: {
            name: "Copy Link", cmd(val) {
                this.copyString(val);
            }
        },
        D: {
            name: "Open Link in Tab", cmd(val) {
                win.openTrustedLinkIn(val, "current", this.opts);
            }
        },
        LD: {
            name: "Similar Sites new Tab", cmd(val) {
                if (!val) return;
                var TERM = "https://www.similarsites.com/site/" + new URL(val).hostname.replace(/^www./, '');
                if (val)
                    win.openTrustedLinkIn(TERM, "tab", this.opts);
            }
        },
        "LD-Shift": {
            name: "Web history new Tab", cmd(val) {
                if (!val) return;
                var TERM = "https://web.archive.org/web/*/" + new URL(val).hostname.replace(/^www./, '');
                if (val)
                    win.openTrustedLinkIn(TERM, "tab", this.opts);
            }
        },
    },
    text: {
        U: {
            name: "Search text new Tab", cmd(val) {
                this.searchWithEngine(val, "tab", "@default");
            }
        },
        "U-Shift": {
            name: "Search text new Tab in background", cmd(val) {
                this.searchWithEngine(val, "tabshifted", "@default");
            }
        },
        R: {
            name: "Search text new Tab (Yandex)", cmd(val) {
                this.searchWithEngine(val, 'tab', 'Yandex');
            }
        },
        "R-Shift": {
            name: "Search text new Tab in background (Yandex)", cmd(val) {
                this.searchWithEngine(val, 'tabshifted', 'Yandex');
            }
        },
        RD: {
            name: "Save Text", cmd(val) {
                this.saveText(val);
            }
        },
        D: {
            name: "Search in site", cmd(val, event) {
                var currentPageUrl = event.originalTarget._urlMetaData['url'];
                var TERM = "site:" + new URL(currentPageUrl).hostname.replace(/^www./, '') + " " + val;
                if (val)
                    this.searchWithEngine(TERM, 'current', '@default');
            }
        },
        "D-Shift": {
            name: "Search in site in background", cmd(val, event) {
                var currentPageUrl = event.originalTarget._urlMetaData['url'];
                var TERM = "site:" + new URL(currentPageUrl).hostname.replace(/^www./, '') + " " + val;
                if (val)
                    this.searchWithEngine(TERM, 'tab', '@default');
            }
        },
        L: {
            name: "Copy Text", cmd(val) {
                this.copyString(val);
            }
        },
        LD: {
            name: "Cambridge Dictionary new Tab", cmd(val) {
                var TERM = "https://dictionary.cambridge.org/dictionary/english-russian/" + val;
                if (val)
                    win.openTrustedLinkIn(TERM, "tab", this.opts);
            }
        },
        "LD-Shift": {
            name: "Cambridge Dictionary new Tab in background", cmd(val) {
                var TERM = "https://dictionary.cambridge.org/dictionary/english-russian/" + val;
                if (val)
                    win.openTrustedLinkIn(TERM, "tabshifted", this.opts);
            }
        }
    },
    image: {
        U: {
            name: "Open Image", cmd() {
                win.openTrustedLinkIn(this.val, "tab", this.opts);
            }
        },
        R: {
            name: "Open Image in background", cmd() {
                win.openTrustedLinkIn(this.val, "tabshifted", this.opts);
            }
        },
        RD: {
            name: "Save Image", cmd(val) {
                this.saveAs(val);
            }
        },
        L: {
            name: "Copy Image Link", cmd(val) {
                this.copyString(val);
            }
        },
        LD: {
            name: "Search Image by Google", cmd(val) {
                var TERM = "https://www.google.com/searchbyimage?image_url=" + val;
                if (val)
                    win.openTrustedLinkIn(TERM, "tabshifted", this.opts);
            }
        },
        "LD-Shift": {
            name: "Search Image by Yandex", cmd(val) {
                var TERM = "https://yandex.com/images/search?source=collections&rpt=imageview&url=" + val;
                if (val)
                    win.openTrustedLinkIn(TERM, "tabshifted", this.opts);
            }
        },
    },
    searchWithEngine(val, where, engine, addToHistory) {
        val || (val = this.val);
        var engine = this.getEngineByName(engine);
        var submission = engine.getSubmission(val, null);
        win.openTrustedLinkIn(submission.uri.spec, where, { postData: submission.postData, ...this.opts });
        if (addToHistory) {
            this.updateSearchbarHistory(val);
        }
    },
    getEngineByName(aEngineName) {
        const UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
            createInstance(Ci.nsIScriptableUnicodeConverter);
        UI.charset = "UTF-8";
        const nsIBSS = Ci.nsIBrowserSearchService || Ci.nsISearchService;
        const searchService = Cc["@mozilla.org/browser/search-service;1"].getService(nsIBSS);
        if (aEngineName.toUpperCase() == "CURRENT") {
            var searchbar = this.searchbar;
            if (searchbar) return searchbar.currentEngine;
        } else {
            try {
                aEngineName = UI.ConvertToUnicode(aEngineName)
            } catch (e) { }
            var engine = searchService.getEngineByName(aEngineName);
            if (engine) return engine;
        }
        //Default
        return searchService.defaultEngine;
    },
    copyToSearchBar(searchText) {
        var searchbar = this.searchbar;
        if (!searchbar)
            return;
        searchbar.value = searchText;
    },
    updateSearchbarHistory(searchText) {
        this.copyToSearchBar(searchText);

        //var event = document.createEvent("UIEvents");
        //event.initUIEvent("input", true, true, window, 0);
        var searchbar = this.searchbar;
        //searchbar.dispatchEvent(event);
        if (typeof searchbar.FormHistory == "object") {
            if (searchText && !win.PrivateBrowsingUtils.isWindowPrivate(window)) {
                searchbar.FormHistory.update({
                    op: "bump",
                    fieldname: searchbar._textbox.getAttribute("autocompletesearchparam"),
                    value: searchText
                }, {
                    handleError: function (aError) {
                        Components.utils.reportError("Saving search to form history failed: " + aError.message);
                    }
                });
            }
        } else {
            if (searchText) {
                searchbar._textbox._formHistSvc
                    .addEntry(searchbar._textbox.getAttribute("autocompletesearchparam"),
                        searchText);
            }
        }
    },
    copyString(text) {
        const cs = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
        cs.copyString(text);
    },
    saveAs(aURL, aFileName, aReferrer, aSourceDocument, aContentType, aContentDisposition) {
        const { gBrowser, PrivateBrowsingUtils, internalSave, saveImageURL, saveURL } = win;
        let createContentPrincipal = Services.scriptSecurityManager.createContentPrincipal || Services.scriptSecurityManager.createCodebasePrincipal;
        let aPrincipal = createContentPrincipal(Services.io.newURI(aURL), {});
        let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser);
        const firefoxVer = parseFloat(Services.appinfo.version);
        const imageLinkRegExp = /(.+)\.(png|jpg|jpeg|gif|bmp)$/i;
        if (aReferrer instanceof HTMLDocument) {
            aReferrer = aReferrer.documentURIObject;
        } else if (typeof aReferrer == 'string') {
            aReferrer = Services.io.newURI(aReferrer);
        }
        if (firefoxVer >= 70) {
            let referrerInfo = Cc["@mozilla.org/referrer-info;1"].createInstance(Ci.nsIReferrerInfo);
            referrerInfo.init(
                Ci.nsIHttpChannel.REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE,
                true,
                aReferrer
            );
            aReferrer = referrerInfo;
        }
        if (imageLinkRegExp.test(aURL) || /^image\//i.test(aContentType)) {
            if (firefoxVer >= 102.3) {
                let cookieJarSettings = gBrowser.selectedBrowser.cookieJarSettings;
                if (/^data:/.test(aURL)) {
                    internalSave(aURL, null, null, "index.png", aContentDisposition, aContentType, true, null, null, aReferrer, cookieJarSettings, aSourceDocument, false, null, isPrivate, aPrincipal);
                } else {
                    internalSave(aURL, null, null, null, aContentDisposition, aContentType, false, null, null, aReferrer, cookieJarSettings, aSourceDocument, false, null, isPrivate, aPrincipal);
                }
            } else if (firefoxVer >= 84) {
                let cookieJarSettings = gBrowser.selectedBrowser.cookieJarSettings;
                if (/^data:/.test(aURL)) {
                    internalSave(aURL, null, "index.png", aContentDisposition, aContentType, true, null, null, aReferrer, cookieJarSettings, aSourceDocument, false, null, isPrivate, aPrincipal);
                } else {
                    internalSave(aURL, null, null, aContentDisposition, aContentType, false, null, null, aReferrer, cookieJarSettings, aSourceDocument, false, null, isPrivate, aPrincipal);
                }
            } else if (firefoxVer >= 77) {
                if (/^data:/.test(aURL)) {
                    internalSave(aURL, null, "index.png", aContentDisposition, aContentType, true, null, null, aReferrer, aSourceDocument, false, null, isPrivate, aPrincipal);
                } else {
                    internalSave(aURL, null, null, aContentDisposition, aContentType, false, null, null, aReferrer, aSourceDocument, false, null, isPrivate, aPrincipal);
                }
            } else {
                if (/^data:/.test(aURL)) {
                    saveImageURL(aURL, "index.png", null, true, false, aReferrer, aSourceDocument, aContentType, aContentDisposition, isPrivate, aPrincipal);
                } else {
                    saveImageURL(aURL, null, null, false, false, aReferrer, aSourceDocument, aContentType, aContentDisposition, isPrivate, aPrincipal);
                }
            }
        } else {
            if (firefoxVer >= 102.3) {
                let cookieJarSettings = gBrowser.selectedBrowser.cookieJarSettings;
                saveURL(aURL, null, aFileName, null, true, false, aReferrer, cookieJarSettings, aSourceDocument, isPrivate, aPrincipal);
            } else if (firefoxVer >= 84) {
                let cookieJarSettings = gBrowser.selectedBrowser.cookieJarSettings;
                saveURL(aURL, aFileName, null, true, false, aReferrer, cookieJarSettings, aSourceDocument, isPrivate, aPrincipal);
            } else {
                saveURL(aURL, aFileName, null, true, false, aReferrer, aSourceDocument, isPrivate, aPrincipal);
            }
        }
    },
    saveText: async function saveText(text) {
        const { Cc, Ci, gBrowser } = win;;
        const { nsIFilePicker } = Ci;
        var fp = Cc['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
        fp.init(win, "Select a File", Ci.nsIFilePicker.modeSave);
        fp.appendFilters(nsIFilePicker.filterText);
        fp.defaultString = gBrowser.contentTitle.replace(/\s-\s.*/i, "").replace(/_[^\[\]【】]+$/, "") + '.txt';
        switch (await new Promise(resolve => { fp.open(rv => { resolve(rv); }); })) {
            case (nsIFilePicker.returnOK):
            case (nsIFilePicker.returnReplace):
                file = fp.file;
                break;
            case (nsIFilePicker.returnCancel):
            default:
                return null;
        }
        var strm = Cc["@mozilla.org/network/file-output-stream;1"]
            .createInstance(Ci.nsIFileOutputStream);
        var convert = Cc['@mozilla.org/intl/scriptableunicodeconverter']
            .getService(Ci.nsIScriptableUnicodeConverter);
        convert.charset = "UTF-8";
        ext = convert.ConvertFromUnicode(text);
        try {
            strm.init(file, 0x02 | 0x08 | 0x20, parseInt(664, 8), 0); // write, create, truncate
            strm.write(text, text.length);
            strm.flush();
        } catch (ex) {
            alert('failed:\n' + ex);
            file = null;
        }
        strm.close();

        return file;
    },
    getDroppedURL_Fixup: function getDroppedURL_Fixup(url) {
        if (!url) return null;
        if (/^h?.?.p(s?):(.+)$/i.test(url)) {
            url = "http" + RegExp.$1 + ':' + RegExp.$2;
            if (!RegExp.$2) return null;
        }
        try {
            url = Services.uriFixup.getFixupURIInfo(url, Services.uriFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP).preferredURI.spec;
            // valid urls don't contain spaces ' '; if we have a space it
            // isn't a valid url, or if it's a javascript: or data: url,
            // bail out
            if (!url ||
                !url.length ||
                url.indexOf(" ", 0) != -1 ||
                /^\s*javascript:/.test(url) ||
                /^\s*data:/.test(url) && !/^\s*data:image\//.test(url))
                return null;
            return url;
        } catch (e) {
            return null;
        }
    },
    printDataTransferTypes: function (e) {
        var dt = e.dataTransfer;
        console.info("print dataTransfer type:");
        var types = dt.types;
        for (var i = 0; i < types.length; i += 1) {
            console.info(types[i] + ": " + dt.getData(types[i]));
        }
    },
    opts: {
        //relatedToCurrent: true,
        triggeringPrincipal: Cu.getObjectPrincipal(this),
        get userContextId() {
            return parseInt(win.gBrowser.selectedBrowser.getAttribute("usercontextid"));
        },
        get private() {
            return win.PrivateBrowsingUtils.isWindowPrivate(win);
        }
    },
    dragstart(e) {
        win = e.view.windowRoot.ownerGlobal;
        //if (!win.gBrowser.currentURI.spec.startsWith("http")) return;
        if (!e.dataTransfer.mozItemCount || !win.gBrowser.selectedBrowser.matches(":hover"))
            return;

        if (this.debug)
            this.printDataTransferTypes(e);

        var dt = e.dataTransfer;
        this.type = this.link;
        this.dir = this.val = "";

        var url = dt.getData("text/x-moz-url-data");

        if (url) {
            this.val = url;
            if (this.imageLinkRe.test(url)) {
                this.type = this.image;
            } else {
                var promiseUrl = dt.getData("application/x-moz-file-promise-url");
                var dragHTML = dt.getData("text/html");
                var parser = new DOMParser();
                var doc = parser.parseFromString(dragHTML, "text/html");
                var onImage = doc.getRootNode().body?.firstElementChild?.tagName == "IMG" || doc.getRootNode().body?.firstElementChild.querySelectorAll("img").length;
                if (onImage && e.ctrlKey) {
                    // force to image type when ctrlKey is pressed
                    this.type = this.image;
                    this.val = promiseUrl;
                }
            }
        } else {
            var txt = dt.getData("text/plain");
            if (txt) {
                this.val = txt;
                if (false) {
                    // 未来加入特殊文本处理 比如网盘链接
                } else {
                    if (!this.textLinkRe.test(txt)) this.type = this.text;
                    if (this.imageLinkRe.test(txt)) this.type = this.image;
                }
            }
            else return;
        }
        this.x = e.screenX; this.y = e.screenY;
        this.drag(true);
    },
    drag(init) {
        var meth = `${init ? "add" : "remove"}EventListener`;
        for (var type of this.events) win[meth](type, this, true);
        init || win.StatusPanel.panel.setAttribute("inactive", true);
    },
    events: ["dragover", "drop", "dragend"],
    dragover(e) {
        var { x, y } = this, cx = e.screenX, cy = e.screenY;
        var dx = cx - x, ax = Math.abs(dx), dy = cy - y, ay = Math.abs(dy);
        if (ax < 10 && ay < 10) return;

        this.x = cx; this.y = cy;
        var dir = ax > ay ? dx > 0 ? "R" : "L" : dy > 0 ? "D" : "U";
        if (this.dir.endsWith(dir)) return;

        dir = this.dir += dir;
        var obj;
        if (e.shiftKey) {
            obj = this.type[dir + "-Shift"];
        } else {
            obj = this.type[dir];
        }

        var txt = `${obj ? "Mouse" : "Unknown"
            } Gesture: ${dir + (obj ? "  " + obj.name : "")}`;

        win.StatusPanel._labelElement.value = txt;
        win.StatusPanel.panel.removeAttribute("inactive");
    },
    dragend(e) {
        var dt = e.dataTransfer;
        this.drag();
        var obj;
        if (e.shiftKey) {
            obj = this.type[this.dir + "-Shift"];
        } else {
            obj = this.type[this.dir];
        }
        if (!obj || dt.mozUserCancelled) return;

        var x = e.screenX, y = e.screenY;
        var wx = win.mozInnerScreenX, wy = win.mozInnerScreenY;
        x > wx && y > wy && x < wx + win.innerWidth && y < wy + win.innerHeight
            && obj.cmd.call(this, this.val, e);
    },
    textLinkRe: /^([a-z]+:\/\/)?([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&amp;]*)?)?(#[a-z][a-z0-9_]*)?$|^custombutton:\/\/\S+$/,
    imageLinkRe: /(http)?s?:?(\/\/[^"']*\.(?:png|jpg|jpeg|gif|png|svg|avif|webp))/,
    observe(w) {
        this.drop = () => this.drag();
        this.handleEvent = e => this[e.type](e);
        var unload = e => {
            var w = e.target.ownerGlobal;
            w.gBrowser.tabpanels.removeEventListener("dragstart", this, true);
            if (w == win) win = null;
        }
        (this.observe = w => {
            //if (!w.toolbar.visible) return;
            w.gBrowser.tabpanels.addEventListener("dragstart", this, true);
            w.addEventListener("unload", unload, { once: true });
        })(w);
    },
    init(topic, self) {
        delete this.init;
        Services.obs.addObserver(self = this, topic);
        Services.obs.addObserver(function quit(s, t) {
            Services.obs.removeObserver(self, topic);
            Services.obs.removeObserver(quit, t);
        }, "quit-application-granted");
    }
}).init("browser-delayed-startup-finished"))();


ЗЫ: зашел с этом на vk.com, но повторить пропадание не смог


Жизнь иногда такое выкидывает, что хочется подобрать...

Отсутствует

 

№1703207-09-2023 22:48:25

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

Re: Custom Buttons

Dumby на 117 опять сломался DOM Inspector. скажи пожалуйста у тебя на эту версию есть рабочий вариант?

Отсутствует

 

№1703308-09-2023 18:25:53

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

Re: Custom Buttons

Farby пишет

Что-то не так с этим

кодом

Выделить код

Код:

`
		var txt = dt.getData("text/plain");
		var url = dt.getData("text/x-moz-url-data");
		if (url)
			this.val = url, this.txt = dt.getData("text/x-moz-url").split("\n")[1];
		else if (!txt) return;
		try {
			this.val = new URL(txt.trim());
		} catch {
			this.val = txt;
			if (!this.textLinkRe.test(txt))
				this.type = this.text;

Там используется экземпляр URL как таковой,
но, по дороге, прицепили на него вызов строкового метода includes()
поэтому следует привести его к строке, например, new URL(txt.trim()).href


Dobrov пишет

на сайте vk.com

Но я-то сайт обрести не могу.
Вот если бы его файлом, чтобы тоже воспроизводилось,
но, даже не знаю, возможно ли такое.


Andrey_Krropotkin пишет

у тебя на эту версию есть рабочий вариант?

У меня такой.

Отсутствует

 

№1703408-09-2023 21:10:47

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 184
UA: Google 2.1

Re: Custom Buttons

Dumby

У меня такой.

Спасибо, у меня уже тоже такой, ой то бишь поставил уже!!


Жизнь иногда такое выкидывает, что хочется подобрать...

Отсутствует

 

№1703509-09-2023 03:17:38

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 315
UA: Firefox 117.0

Re: Custom Buttons

Ребята, у меня не работает антиподписячий код.
Он же должен лежать в файле config.js?

ФФ обновился до 117.
Перестали работать все неподписанные приложения.
На старнице about:addons с установленными дополнениями на многих приложениях висит теперь красная табличка "Работа дополнения не была проверенна, поэтому оно было отключено."
А когда пытаюсь установить custom_buttons-0.0.7.0.0.32-fx-paxmod или custom_buttons-0.0.7.0.0.32-fx-bootstrap, то вылетает ошибка: "дополнение не может быть установленно так как оно по-видимуму, повреждено."

C:\Program Files\Mozilla firefox\defaults\pref\

config.js

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

Выделить код

Код:

//
try {(jsval => {
	var dbg, gref, genv = func => {
		var sandbox = new Cu.Sandbox(g, {freshCompartment: true});
		Cc["@mozilla.org/jsdebugger;1"].createInstance(Ci.IJSDebugger).addClass(sandbox);
		(dbg = new sandbox.Debugger()).addDebuggee(g);
		gref = dbg.makeGlobalObjectReference(g);
		return (genv = func => func && gref.makeDebuggeeValue(func).environment)(func);
	}
	var g = Cu.getGlobalForObject(jsval), o = g.Object, {freeze} = o, disleg;

	var lexp = () => lockPref("extensions.experiments.enabled", true);
	var MRS = "MOZ_REQUIRE_SIGNING", AC = "AppConstants", uac = `resource://gre/modules/${AC}.`;

	if (o.isFrozen(o)) { // Fx 102.0b7+
		lexp(); disleg = true; genv();

		dbg.onEnterFrame = frame => {
			var {script} = frame;
			try {if (!script.url.startsWith(uac)) return;} catch {return;}
			dbg.onEnterFrame = undefined;

			if (script.isModule) { // ESM, Fx 108+
				var env = frame.environment;
				frame.onPop = () => env.setVariable(AC, gref.makeDebuggeeValue(freeze(
					o.assign(new o(), env.getVariable(AC).unsafeDereference(), {[MRS]: false})
				)));
			}
			else { // JSM
				var nsvo = frame.this.unsafeDereference();
				nsvo.Object = {freeze(ac) {
					ac[MRS] = false;
					delete nsvo.Object;
					return freeze(ac);
				}};
			}
		}
	}
	else o.freeze = obj => {
		if (!Components.stack.caller.filename.startsWith(uac)) return freeze(obj);
		obj[MRS] = false;

		if ((disleg = "MOZ_ALLOW_ADDON_SIDELOAD" in obj)) lexp();
		else
			obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true,
			lockPref("extensions.legacy.enabled", true);

		return (o.freeze = freeze)(obj);
	}
	lockPref("xpinstall.signatures.required", false);
	lockPref("extensions.langpacks.signatures.required", false);

	var useDbg = true, xpii = "resource://gre/modules/addons/XPIInstall.";
	if (Ci.nsINativeFileWatcherService) { // Fx < 100
		jsval = Cu.import(xpii + "jsm", {});
		var shouldVerify = jsval.shouldVerifySignedState;
		if (shouldVerify.length == 1)
			useDbg = false,
			jsval.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon);
	}
	if (useDbg) { // Fx 99+
		try {var exp = ChromeUtils.importESModule(xpii + "sys.mjs");}
		catch {exp = g.ChromeUtils.import(xpii + "jsm");}
		jsval = o.assign({}, exp);

		var env = genv(jsval.XPIInstall.installTemporaryAddon);
		var ref = name => {try {return env.find(name).getVariable(name).unsafeDereference();} catch {}}
		jsval.XPIDatabase = (ref("lazy") || {}).XPIDatabase || ref("XPIDatabase");

		var proto = ref("Package").prototype;
		var verify = proto.verifySignedState;
		proto.verifySignedState = function(id) {
			return id ? {cert: null, signedState: undefined} : verify.apply(this, arguments);
		}
		dbg.removeAllDebuggees();
	}
	if (disleg) jsval.XPIDatabase.isDisabledLegacy = () => false;
})(
	"permitCPOWsInScope" in Cu ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu
);}
catch(ex) {Cu.reportError(ex);}


config-prefs.js

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

Выделить код

Код:

pref("general.config.obscure_value", 0);
pref("general.config.filename", "config.js");
pref("general.config.sandbox_enabled", false);


Папку startupCache в локальный каталоге, вычистил. СВ не работает.

Отредактировано leex (09-09-2023 03:18:48)

Отсутствует

 

№1703609-09-2023 17:57:13

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 184
UA: Google 2.1

Re: Custom Buttons

leex пишет

Ребята, у меня не работает антиподписячий код.

А попробуйте прочитать хотя-бы от сюда и далее...


Жизнь иногда такое выкидывает, что хочется подобрать...

Отсутствует

 

№1703709-09-2023 20:06:43

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 315
UA: Firefox 117.0

Re: Custom Buttons

Farby пишет

А попробуйте прочитать хотя-бы от сюда и далее...

Читал конечно же и это и далее.

Антиподписячий код надо брать здесь

Именно этот код.




Добавлено.

Вот я тупанул. Все заработало.
Файл config.js должен был лежать в C:\Program Files\Mozilla firefox.
У меня он был в C:\Program Files\Mozilla firefox\defaults\pref

Отредактировано leex (09-09-2023 21:03:53)

Отсутствует

 

Board footer

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