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

Пользователи не любят читать документацию. Станьте оригинальным, будьте не как все. Ознакомьтесь с нашей базой знаний.

№90106-07-2023 21:01:59

vassemm
Участник
 
Группа: Members
Зарегистрирован: 11-02-2019
Сообщений: 26
UA: Firefox 115.0

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

Dumby пишет

Можно заменить все (два) « instanceof Ci.nsIDOMChromeWindow» на «.isChromeWindow»

Благодарю.
На первый беглый взгляд все заработало. WIN11  FF116 FF117
:beer:

Отсутствует

 

№90206-07-2023 21:11:44

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

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

Dumby пишет

Можно заменить все (два) « instanceof Ci.nsIDOMChromeWindow» на «.isChromeWindow»

Большое спасибо! :beer:



Добавлено 06-07-2023 21:16:32

Viatcheslav пишет

скриптом для UCF размещения фавиконки сайта в адресной строке

Если ничего не путаю, то вот: https://forum.mozilla-russia.org/viewto … 52#p793152

Отредактировано unter_officer (06-07-2023 21:16:47)


«The Truth Is Out There»

Отсутствует

 

№90306-07-2023 23:55:05

Viatcheslav
Участник
 
Группа: Members
Откуда: г. Бобруйск, Беларусь
Зарегистрирован: 23-11-2016
Сообщений: 323
UA: Firefox 88.0

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

unter_officer пишет

Если ничего не путаю, то вот: https://forum.mozilla-russia.org/viewto … 52#p793152

Спасибо большое, но... Всё время показывает дефолтную иконку.
А вот этот работает - https://github.com/Aris-t2/CustomJSforFx/blob/master/scripts/favicon_in_urlbar.uc.js

Отсутствует

 

№90407-07-2023 00:43:38

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

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

Viatcheslav
Вот это рабочий, если нет, то проблема у вас.
Иконку дефолтную свою вписать или положить по прописанному пути.

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

Выделить код

Код:

// FavIcon in URL-bar - Иконка сайта в url-баре
// https://forum.mozilla-russia.org/viewtopic.php?pid=789469#p789469
(this.faviconinurlbar = {
            init(that) {
                var identity = document.querySelector("#identity-icon");
                if (!identity)
                    return;
                var iconDefault = "chrome://user_chrome_files/content/custom_styles/png/globe-16.png"; // или свою иконку
                var style = "data:text/css;charset=utf-8," + encodeURIComponent(`
                    #identity-faviconinurlbar {
                        --v-faviconinurlbar-default: url("${iconDefault}");

                        list-style-image: var(--v-faviconinurlbar, none) !important;
                        pointer-events: none !important;
                        height: 16px !important;
                        width: auto !important;
                        margin-inline-start: 4px !important;
                        -moz-context-properties: fill, fill-opacity;
                        fill: currentColor;
                        fill-opacity: var(--urlbar-icon-fill-opacity, 1);
                    }
                    #identity-faviconinurlbar:not([faviconinurlbar="true"]),
                    #identity-faviconinurlbar[favbusy="true"] {
                        --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important;
                    }
                    #identity-faviconinurlbar[faviconchrome="true"],
                    #urlbar[actiontype="extension"] #identity-faviconinurlbar,
                    #identity-box:is(.extensionPage,.chromeUI,.localResource) #identity-faviconinurlbar,
                    #urlbar:not(.searchButton) #identity-box[pageproxystate="invalid"] #identity-faviconinurlbar {
                        display: none !important;
                    }
                `);
                windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET);
                var faviconinurlbar = document.createXULElement("image");
                faviconinurlbar.id = "identity-faviconinurlbar";
                identity.after(faviconinurlbar);
                gBrowser.tabContainer.addEventListener("TabAttrModified", this);
                gBrowser.addProgressListener(this);
                that.unloadlisteners.push("faviconinurlbar");
                var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener;
                var updatefavicon = image => {
                    if (image) {
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`);
                        faviconinurlbar.setAttribute("faviconinurlbar", "true");
                        faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`);
                    } else {
                        faviconinurlbar.setAttribute("faviconinurlbar", "false");
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", "");
                    }
                };
                this.handleEvent = e => {
                    var tab = e.target, changed;
                    if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return;
                    updatefavicon(tab.image);
                };
                this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => {
                    if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) {
                        if (aStateFlags & STATE_START)
                            faviconinurlbar.setAttribute("favbusy", "true");
                        else if (aStateFlags & STATE_STOP) {
                            faviconinurlbar.setAttribute("favbusy", "false");
                            updatefavicon(gBrowser.selectedTab.image);
                        }
                    }
                };
            },
            destructor() {
                gBrowser.tabContainer.removeEventListener("TabAttrModified", this);
                gBrowser.removeProgressListener(this);
            }
        }).init(this);

Отсутствует

 

№90507-07-2023 09:59:38

Viatcheslav
Участник
 
Группа: Members
Откуда: г. Бобруйск, Беларусь
Зарегистрирован: 23-11-2016
Сообщений: 323
UA: Firefox 88.0

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

_zt пишет

Вот это рабочий, если нет, то проблема у вас

Наверное... :(
А каким способом подключали?
У меня вот этот - https://github.com/Aris-t2/CustomJSforFx/blob/master/scripts/favicon_in_urlbar.uc.js
подключен к UCF в custom_script_win.js по событию "DOMContentLoaded".
Только не зря его Виталий назвал "ужасным... :usch:

Отсутствует

 

№90607-07-2023 19:51:45

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

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

Viatcheslav Они разные, может и подключать по разному надо, у меня в CustomStylesScripts.jsm

scriptschrome: { // Для докум. окна браузера [ChromeOnly]
        load: [ // По событию "load"

Это аналог custom_script_win.js после секции ...

Выделить код

Код:

load() {
        if (this.initialized)
            return;
        this.initialized = true;
        /* ************************************************ */
тут коды или импорт

Импорт раньше у меня такой был ...

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

Выделить код

Код:

// Для скриптов отдельными файлами (см. примеры)
        // С уточнением в каком "документе" работать
        // https://forum.mozilla-russia.org/viewtopic.php?pid=788301#p788301
        (async () => {
            var loadscript = (relpath, obj) => {
                try {
                    Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${relpath}`, obj, "UTF-8");
                    return true;
                } catch(e) { }
                return false;
            },
            load_scripts_by_url = {
                browser: win => {
                    //>>>>>>>>>>| Блок требуется для боковой панели и т.п. |>>>>>>>>>>
                    var box = document.querySelector("#browser") || window;
                    var listener = e => {
                        var doc = e.target || ({});
                        load_scripts_by_url[doc.documentURI]?.(doc.defaultView);
                    };
                    box.addEventListener("pageshow", listener);
                    this.loadscriptswinandsidebar = {
                        destructor() {
                            box.removeEventListener("pageshow", listener);
                        }
                    };
                    this.unloadlisteners.push("loadscriptswinandsidebar");
                    /* <<<<<<<<<<<<<<<<<<<< */
                    
                    //>>>>>>>>>>| Загрузка скриптов для browser.xhtml |>>>>>>>>>>
                        // Здесь скрипты для основного окна
                        loadscript("custom_js_win/ucf_Bookmarks_Star_Tooltip_Helper.uc.js", win);
                        loadscript("custom_js_win/ucf_Context_Menu_Open_With.us.js", this) && this.unloadlisteners.push("contextmenuopenwith");
                        loadscript("custom_js_win/ucf_FavIcon_In_URL-bar.uc.js", this);
                        loadscript("custom_js_win/ucf_Open_Hisory_Bookmark_In_NewTab.uc.js", win) && win.ucf_where_to_open_link.browser();
                        loadscript("custom_js_win/ucf_SidebarTabs.us.js", this) && this.unloadlisteners.push("sidebar_tabs");
                        // и т.д.

                    //<<<<<<<<<<<<<<<<<<<<
                },
                //>>>>>>>>>>| Загрузка скриптов для др. документов |>>>>>>>>>>
                "chrome://browser/content/places/bookmarksSidebar.xhtml": win => {
                    // Здесь скрипты для боковой панели закладок
                    loadscript("custom_js_win/s_AutoCloseBookMarkFolder_Fx37.uc.js", win);
                    loadscript("custom_js_win/ucf_Open_Hisory_Bookmark_In_NewTab.uc.js", win) && win.ucf_where_to_open_link.bookmarksSidebar();
                    // и т.д.

                },
                "chrome://browser/content/places/historySidebar.xhtml": win => {
                    // Здесь скрипты для боковой панели истории
                    loadscript("custom_js_win/s_AutoCloseHistoryFolder_Fx37.uc.js", win);
                    loadscript("custom_js_win/ucf_Open_Hisory_Bookmark_In_NewTab.uc.js", win) && win.ucf_where_to_open_link.historySidebar();
                    // и т.д.

                },
                //<<<<<<<<<<<<<<<<<<<<
            };
            load_scripts_by_url.browser(window);
        })();


Понятия не имею бкдет ли оно сейчас работать.

Отредактировано _zt (07-07-2023 20:03:41)

Отсутствует

 

№90707-07-2023 20:19:08

Viatcheslav
Участник
 
Группа: Members
Откуда: г. Бобруйск, Беларусь
Зарегистрирован: 23-11-2016
Сообщений: 323
UA: Firefox 88.0

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

_zt пишет

Импорт раньше у меня такой был ...

Это для старой версии UCF
Спасибо за помощь :beer:

Отсутствует

 

№90810-07-2023 13:38:30

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

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

Dumby
Есть ваш скриптик "Восстановление удалённых закладок".

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

Выделить код

Код:

//
// Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=801497#p801497
//
(async sep => {
	if (!sep) return;

	var key = "hasRemoveTransaction";
	var g = Cu.import("resource://gre/modules/PlacesTransactions.jsm", {});

	var raws = (g.lazy || g).TransactionsHistory?.proxifiedToRaw;
	if (raws) g = raws;

	if (!g[key]) {
		if (!raws) {
			Services.scriptloader.loadSubScript(
				`data:,this.${key}=TransactionsHistory.proxifiedToRaw;`, g
			);
			raws = g[key];
		}
		g[key] = entry => {
			for(var tr of entry)
				if (raws.get(tr) instanceof PlacesTransactions.Remove)
					return true;
		}
	}
	var menuitem = document.createXULElement("menuitem");
	for(var args of Object.entries({
		closemenu: "single",
		class: "menuitem-iconic",
		id: "placesCmd_undoRemove",
		label: "Восстановить удалённое",
		oncommand: "PlacesTransactions.undo().catch(Cu.reportError);",
		image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAEd0lEQVRIx53Ve2yW5RkG8N/7ft8Hxa/9CgjSSDnMA4xVTUMQWzadhzhnjSCC0y0jSjom+JdGp844ZhSjHLJsowaNZoCCHOWglXGoQbo2fBW3obDNUBfXKpsUVhxn6OHdH8+31GXGmL3/3M913ffzPNed93qeBxvmI8umCNjyPFEDSRJw40qKa9jyHSbdzY77Ar+9FTvZ+nHAb9T7P76YcwlOktlBdJia2SSthfRvaR/Mync5tp85Q2mbEHJ/X0bqRTpOBJyehog3C3j1HV9RQP91xG9T8z2SofyphMELWH4zW5s40s7kQ/T0cnYfXfPD1OgM0TlGzSN1DZkzxG1EdURjaa9HCfddEupfuSkIfHXJ5wVENA8Iw9QcRnbzXj31++g8w+WVZHMhXzaKhu2MGMtd36f5CTrn8WAJyf001KCYpA6dDBtLlOfoYuI6kgp6XuLsbhQRfw39ovDPx7/JgYS1b3NkCxcvoPgTevIULyFVTm4jyinp4uRJiirYt5BMLc15kvE0lnCsgZaE2wdx6LVCo9/ghQn4LhdFxEOonELv8ogVV9Iyjd9fx8T1FE2nq5XSQWQuJbsmrJH9JclMsldhFsW3EU0iuxsb6f9zTA3dHj1J1yPsKaPrIOtnkn6KDY2cvYF/vkfmINGuiPdnUD6Pd/7Mur/x0RCqXqTfj+m5glyO1B8ovR1pijeil6KvBw8V1QaB/QYWzNgSYu+TmMm5GVhKT47OBWR28kgnvxvKS/OjvuMGuTSr72FtBR/WctNe4l+H3GUt7DxB2TKe+CmnF5IZRzSZzFmS4wy9n2QGY2eR3Mx193DqAao+4vh04lZS2/EkQyqo7cWux4Kjwf4gKF3N5hEs+QsLlwVuVRPLP2FeTSh95hZSpSx6OOAkwWCWLSEqYWVz4JtLqd3GiuX0/oS6XKjd/BQbF6SRJynij4eJKpl7WSg8cCdzxjHjH3QuIsaorQx7NCx8QQdxCYM2kzxL423BbGN6SP+I6tmcO86hahqu4MA2To3mX+eTxbA2er6VJjcA/Yl2kOzlrutJxrDraaI1XH09j3fQVk7pcG5sCgIOttLVzejpmMPrnxJvYnIZXelwxGHTCOaX0PorsmUMOC/wpeNofg4fjg9EW3+k6CzcYJ99M7h6fSfxFFJrMZzFm0I+fzXxlTQ1EHf3eSlJyI3mlYGs/yEPx4F7/NkQ11zEymFhnDoY9RnwcHmIZ34Q1CcTkBD9FSM58gu8SmUHbmVuJbYRt2AiE/cwZT/tG3h+Gh29lH3A+VPZ+zMq1rHwcq6tY1U31ReQXPgFt3M+/9+xJRvM9f5S3NnX6btLqfqYt1p44xQrFnH0aX6zmBXIj+Hae0N95qG+ea/PJjrB7tV47csE7CzEJqKXyTcW8CquaibfwTOX0FjPLSfYk+G8XWyb+rlTUcndVUQjWXOK+FiBn/QfQen/FVBVVdhoc4FIkczqM5WBvPMWp4fQMpzFHeEN2NCFCcyNSH2b1AiSl3nhVnrnkjpNkqP9jrBvdzX8G2rIlxvMK3a7AAAAInpUWHRTb2Z0d2FyZQAAeNorLy/Xy8zLLk5OLEjVyy9KBwA22AZYEFPKXAAAAABJRU5ErkJggg==",
	}))
		menuitem.setAttribute(...args);

	var desc = Object.getOwnPropertyDescriptor(XULElement.prototype, "hidden");
	var {set} = desc;
	desc.set = () => {
		var entry = PlacesTransactions.topUndoEntry;
		var vis = entry && g[key](entry);
		vis && menuitem.removeAttribute("disabled");
		set.call(menuitem, !vis);
	}
	Object.defineProperty(menuitem, "hidden", desc);
	sep.after(menuitem);
})(document.getElementById("placesContext_deleteSeparator"));

Заметил в FF115 такой момент. Если вызвать контекстное меню на свободном месте панели закладок, то пункт "Восстановить удалённое" остаётся затенённым.
Untitled-2.png
В предыдущих версиях [firefox] всё работает нормально.
Возможно поправить?


«The Truth Is Out There»

Отсутствует

 

№90910-07-2023 14:09:58

b0ttle
Участник
 
Группа: Members
Зарегистрирован: 22-10-2020
Сообщений: 182
UA: Firefox 115.0

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

ucf_hookClicks.js некорректно работает в 115.0.1, где-то нет тултипов, отвалилась подсветка и вся система алертов при копирований адресной строки через identity-box, и еще что-то. Все остальное работает, пока не разобрался что еще отвалилось.
Кстати, как в консоли высматривать ошибки? Тот который Ctrl+Shift+J.

Отредактировано b0ttle (10-07-2023 14:13:43)

Отсутствует

 

№91011-07-2023 08:24:44

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

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

unter_officer пишет

В предыдущих версиях [firefox] всё работает нормально.

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


Можно попробовать вообще просто поставить на disabled заглушку

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

Выделить код

Код:

/*
		var vis = entry && g[key](entry);
		vis && menuitem.removeAttribute("disabled");
		set.call(menuitem, !vis);
	}
*/
		set.call(menuitem, !entry || !g[key](entry));
	}
	Object.defineProperty(menuitem, "disabled", {});


Bug 1780695 - «Remove Services.jsm» (Firefox 117+)
See also: Bug 1667455 - «Expose a "Services" property on all privileged JS scopes (like Cu/Cc/Ci)» (Firefox 104+)

Отсутствует

 

№91111-07-2023 14:12:13

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

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

Dumby пишет

Можно попробовать вообще просто поставить на disabled заглушку

Большое спасибо! :beer:


«The Truth Is Out There»

Отсутствует

 

№91211-07-2023 15:32:36

b0ttle
Участник
 
Группа: Members
Зарегистрирован: 22-10-2020
Сообщений: 182
UA: Firefox 115.0

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

Тут тултипы работают в hookClicks, но при запуске firefox почему-то пишет, что файл не запущен, хотя по виду все работает. Странно.
Проверил. В коде по ссылке, там тултипы работают, а функций нет, при кликах ничего не происходит.
Хотел свою версию сюда(код то не мой, не умею кодить. просто чуть-чуть под себя подогнал), но там какие-то символы мешают, сайт не принимает, а в base64txt, не умею.
Смог сделать в base64txt, но теперь из-за размера не пропустил, что-то про (64 КБ).
В общем, https://pastebin.com/fn2WwQVS Судя по длине кода, наверно никто не захочет в ней возиться.

Отредактировано b0ttle (11-07-2023 17:25:12)

Отсутствует

 

№91312-07-2023 02:31:44

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

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

b0ttle пишет

Тут тултипы работают в hookClicks, но при запуске firefox почему-то пишет, что файл не запущен, хотя по виду все работает.

на FF114 всё работало. На 115 перехват кликов не работает, базовый hookClicks выдаёт много ошибок в консоли.


Dumby - проверьте на Firefox 115 ваш базовый hookClicks, на его основе я делал все доработки для профиля в шапке.

Отсутствует

 

№91412-07-2023 03:18:40

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

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

Dumby - просьба доработать скрипт, чтобы его запускать по перехвату кликов из любых кнопок:

AppMenuTbbSaveHTMLChild.jsm

Выделить код

Код:

/* для UCF CustomStylesScripts.jsm
	scriptsbackground: [ // В фоне [System Principal]
		{ func: jsmImport("AppMenuTbbSaveHTMLChild.jsm"), }, */

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

class AppMenuTbbSaveHTMLChild extends JSWindowActorChild {
	receiveMessage() {
		return htmlAndName(this.contentWindow);
	}
}
ChromeUtils.domProcessChild.childID || ({
	init(topic) {
		ChromeUtils.registerWindowActor(name, {
			allFrames: true,
			child: {moduleURI: __URI__},
			messageManagerGroups: ["browsers"]
		});
		obs.addObserver(self = this, topic);
		obs.addObserver(function quit(s, t) {
			obs.removeObserver(quit, t);
			obs.removeObserver(self, topic);
		}, "quit-application-granted");
		this.handleEvent = e => this[e.type](e);
	},
	observe(win) {
		win.document.getElementById("appMenu-popup")
			.addEventListener("popupshowing", this);
		win.addEventListener("unload", this);
	},
	popupshowing(e) {
		this.unload(e);
		var popup = e.target;
		var btn = popup.ownerDocument.createXULElement("toolbarbutton");
		btn.id = "appMenu-ucf-save-html-button";
		btn.setAttribute("label", "Страница | выбранное в единый HTML");
		var before = "appMenu-save-file-button2", subviewbutton = "subviewbutton";
		if ( parseInt(popup.ownerGlobal.Services.appinfo.version) < 89 ) {
			subviewbutton = "subviewbutton subviewbutton-iconic", before = "appMenu-print-button";
			btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAACNJREFUCNdjYH/AgBX9/89Q/4/B/g+D/A8G/g8gEeYDDIwNAIB7EDCcKCcMAAAAAElFTkSuQmCC");
		}
		btn.className = subviewbutton;
		btn.setAttribute("oncommand", "saveHTML();");
		btn.saveHTML = this.saveHTML;
		popup.querySelector('toolbarbutton[id^="'+ before +'"]').before(btn);
	},
	unload(e) {
		var win = e.target.ownerGlobal;
		win.removeEventListener("unload", this);
		win.document.getElementById("appMenu-popup").removeEventListener("popupshowing", this);
	},
	async saveHTML() {
		var win = this.ownerGlobal;
		var br = win.gBrowser.selectedBrowser;
		var bc = focus.focusedContentBrowsingContext;
		if (bc?.top.embedderElement != br) bc = br.browsingContext;

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

var htmlAndName = async mainWin => {

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

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

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

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

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

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

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

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

Этот скрипт спрашивает, куда сохранять страницу в единый HTML. Второй подобный код ты делал для скрипта ucf_hookClicks.js – сохранять страницу без запроса (я его доработал для сохранения в папку с имёнем сайта и прочими условиями).


Просьба такая - сделать единый скрипт, который работает в зависимости от переданных опций, то есть либо сохраняет в единый HTML с запросом "Куда?", либо сохраняет сразу без запроса в "Загрузки".
То есть, чтобы скрипт можно было вызывать из разных кнопок (например, по перехвату кликов из ucf_hookClicks) с разными опциями – например "Спросить", куда сохранять или "Не спрашивать".

Отсутствует

 

№91512-07-2023 11:11:18

Northtech
Участник
 
Группа: Members
Зарегистрирован: 16-04-2011
Сообщений: 267
UA: Firefox 115.0

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

Не знаю в какую тему написать... В FX115 отвалилась кнопка восстановления вкладок после закрытия (не показывает список закрытых вкладок), вроде она относится к расширению add_toolbar_buttons@vitaliy.ru. Можно как-то ее починить?

https://dropmefiles.com/XaeKh - расширение


скрытый текст
YN0MUcQ.png

Отсутствует

 

№91612-07-2023 11:33:30

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

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

Northtech
https://forum.mozilla-russia.org/viewtopic.php?pid=804061#p804061


Add, надеюсь оно, я просто эту кнопку не использую.

Отредактировано kokoss (12-07-2023 11:38:06)


Win7

Отсутствует

 

№91712-07-2023 11:51:37

Northtech
Участник
 
Группа: Members
Зарегистрирован: 16-04-2011
Сообщений: 267
UA: Firefox 115.0

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

kokoss
нет, к сожалению не то. Эти изменения я вносил уже...

Отсутствует

 

№91812-07-2023 12:51:54

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

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

egorsemenov06 пишет

Возможно ли запускать перевод горячими клавишами (двойнм Ctrl) в этом скрипте?

Это как-то неудобно. Скрипт завязан на контекстное меню,
и берёт выделенный текст из его машинерии. А если клавишей, то взять негде.


Разве что через буфер обмена. Ну попробуй дописать после строки
contextMenu.insertBefore(document.createXULElement("menuseparator"), nextEleMenu);

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

Выделить код

Код:

//
                var translate = async () => {
                    var br = gBrowser.selectedBrowser;
                    var fw = Services.focus.focusedWindow;
                    if (fw == window) {
                        if (document.activeElement != br) return;
                    }
                    else if (fw.browsingContext.top != br.browsingContext) return;

                    var cb = navigator.clipboard;
                    var was = await cb.readText();
                    if (was) await cb.writeText("");

                    docShell.doCommand("cmd_copy");
                    await new Promise(r => setTimeout(r, 100));
                    var txt = await cb.readText();

                    if (txt || was) cb.writeText(was);
                    if (!txt && !br.currentURI.scheme.startsWith("http")) return;
                    window.gContextMenu = {selectionInfo: {
                        get fullText() {
                            window.gContextMenu = null;
                            return txt;
                        }
                    }};
                    ujs_google_translate("auto|ru");
                }
                var ts = 0, destr = this.destructor, args = ["keyup", e =>
                    e.key == "Control" && ts - (ts = Cu.now()) > -300
                    && !e.shiftKey && !e.altKey && translate(ts = 0)
                ];
                addEventListener(...args);
                this.destructor = () => destr(removeEventListener(...args));

Dobrov пишет

ваш базовый hookClicks

Нет у меня никакого hookClicks, не сочиняй.
Мы там что-то когда-то обсуждали, и ты его родил.

проверьте на Firefox 115

Ну я убрал кусок кода if (typeof IOUtils != "object") {…};
и, на первый взгляд, вроде нормализовалось.
Так, потыкал немного, там же невозможно всё проверить,
нужно что-то поконкретнее.


В этом куске всё тот же косяк с непониманием работы var.
Вчера вот Services.jsm удалили, так у меня всё рухнуло в основном из-за этого.
Вобщем, тоже удали, или перепиши кусок правильно.


Да, кстати, потерялся var перед str_cut = …
Без него, в окно добавятся ненужные там
str_cut, url_color, switchToTab, showInStatusPanel, Title,
saveSelectionToTxt, save, bright, help, GetSelection, data,


и gClipboard конечно, который может перезаписать
тот, что от Custom Buttons, а это уже совсем нехорошо.

чтобы скрипт можно было вызывать

Скрипт нельзя «вызвать», только загрузить. Вызвать можно функцию.


Это надо что-то в SystemGlobal добавить, чтобы с других мест вызывать.
Попробую расписать, чисто для примера. Следи за мыслью

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

Сначала в init() дописываем
globalThis[Symbol.for(name)] = this.saveHTML;


Затем, из saveHTML() убираем var win = this.ownerGlobal;
а в саму функцию добавляем наш аргумент, и вторым аргументом окно
async saveHTML(arg, win = this.ownerGlobal) {


и, в последней строке функции, наш аргумент пробрасываем
actor && self.save(win, ...await actor.sendQuery(""), arg);


Далее вписываем его и в save()
async save(win, fileContent, fileName, arg) {


Таким образом, внутри save() теперь можно его использовать
if (arg) {
    win.alert(arg); // test
    // Здесь делаем что-то одно, типа вычисляем путь для файла
} else {
    // Здесь делаем что-то другое, типа открываем файл-пикер и забираем путь с него
}
// Здесь записываем файл


Всё. Теперь можно вызывать снаружи, например, с консоли браузера:

(() => {
    var save = Cu.getGlobalForObject(Cu)[Symbol.for("AppMenuTbbSaveHTML")];
    save("TesT", window);
})();

Northtech пишет

dropmefiles.com

javascript:void(0); — нет уж, разрешите отказаться.


Но наверняка дело в getClosedTabCount
Можно заменить в parent.js все два на getClosedTabCountForWindow


Если нужна обратная совместимость, то два
sessionStore.getClosedTabCount
заменить на
(sessionStore.getClosedTabCountForWindow || sessionStore.getClosedTabCount)

Отсутствует

 

№91912-07-2023 13:18:45

Northtech
Участник
 
Группа: Members
Зарегистрирован: 16-04-2011
Сообщений: 267
UA: Firefox 115.0

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

Dumby

javascript:void(0); — нет уж, разрешите отказаться.

Да я этого и не видел никогда, у меня ublock. :)

getClosedTabCountForWindow

сработало, спасибо.

Отсутствует

 

№92012-07-2023 14:06:35

6e73epo
Участник
 
Группа: Members
Зарегистрирован: 06-05-2022
Сообщений: 207
UA: Firefox 116.0

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

В Firefox 117 не открывается старый about:config. Достаточно ли закомментировать строку с импортом Services.jsm?

Отсутствует

 

№92115-07-2023 11:25:05

odd74RUS
Участник
 
Группа: Members
Зарегистрирован: 15-08-2021
Сообщений: 29
UA: Firefox 115.0

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

После какого-то из недавних обновлений перестал работать скрипт (contextsearch.uc.js), вот он: https://forum.mozilla-russia.org/viewto … 83#p780283 , переключающий поисковые системы в контекстном меню выделенного текста.
В данный момент стоит [firefox] 115.02 (Windows 7).
В скриптах я, к сожалению, совсем не разбираюсь. Подскажите пожалуйста, как теперь его снова заставить работать?

Отсутствует

 

№92215-07-2023 12:07:57

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

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

Dumby пишет

Попробую расписать, чисто для примера. Следи за мыслью…

Спасибо за подсказки! Доработал скрипт AppMenuTbbSaveHTMLChild, проверь, может я накосячил где-то…
1) теперь запускается так: Cu.getGlobalForObject(Cu)[Symbol.for("SingleHTML")](true, window);
2) можно сохранять страницу автоматически или с запросом "Куда"
3) может сохранять в разные папки в зависимости от опции ucf.savedirs: Загрузки[домен]имя вкладки
или указать любой путь сохранения, например: Загрузки/Web/домен/имя …for("SingleHTML")]("Web|1", window)

SingleHTMLChild.jsm

Выделить код

Код:

/* SingleHtml by Лекс, правка: Dumby, mod Dobrov
для UCF CustomStylesScripts.jsm
	scriptsbackground: [ // В фоне [System Principal]
		{ func: jsmImport("SingleHTMLChild.jsm"), },
вызов: Cu.getGlobalForObject(Cu)[Symbol.for("SingleHTML")](arg, window)
	если arg False, то диалог выбора пути сохранения */

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

class SingleHTMLChild extends JSWindowActorChild { //класс = name + Child
	receiveMessage() { return htmlAndName(this.contentWindow);}
}
ChromeUtils.domProcessChild.childID || ({
	init(topic) {
		ChromeUtils.registerWindowActor(name, {
			allFrames: true,
			child: {moduleURI: __URI__},
			messageManagerGroups: ["browsers"]
		});
		obs.addObserver(self = this, topic);
		obs.addObserver(function quit(s, t) {
			obs.removeObserver(quit, t);
			obs.removeObserver(self, topic);
		}, "quit-application-granted");
		this.handleEvent = e => this[e.type](e);
		globalThis[Symbol.for(name)] = this.saveHTML;
	},
	observe(win) {
		win.document.getElementById("appMenu-popup")
			.addEventListener("popupshowing", this);
		win.addEventListener("unload", this);
	},
	popupshowing(e) {
		this.unload(e);
		var popup = e.target;
		var btn = popup.ownerDocument.createXULElement("toolbarbutton");
		btn.id = "appMenu-ucf-save-html-button";
		btn.setAttribute("label", "Страница | выбранное в единый HTML");
		var before = "appMenu-save-file-button2", subviewbutton = "subviewbutton";
		btn.className = subviewbutton;
		btn.setAttribute("oncommand", "saveHTML();");
		btn.saveHTML = this.saveHTML;
		popup.querySelector('toolbarbutton[id^="'+ before +'"]').before(btn);
	},
	unload(e) {
		var win = e.target.ownerGlobal;
		win.removeEventListener("unload", this);
		win.document.getElementById("appMenu-popup").removeEventListener("popupshowing", this);
	},
	async saveHTML(arg, win = this.ownerGlobal) {
		var br = win.gBrowser.selectedBrowser;
		var bc = focus.focusedContentBrowsingContext;
		if (bc?.top.embedderElement != br) bc = br.browsingContext;
		var actor = bc?.currentWindowGlobal?.getActor(name);
		actor && self.save(win, ...await actor.sendQuery(""), arg); // htmlAndName
	},
	async save(win, data, fname, host, arg, d = prefs.getStringPref("ucf.savedirs","_Web||_Pic|0")) {
		if (/.*\|/.test(arg)) d = arg; //Dir/Subdir|[пусто|0 title|1 host]
		if (!/.*\|/.test(d)) d += '|'; d = d.split('|').slice(0,2); //Загрузки[домен]имя
		fname = fname.replace(/\s+/g,' ').replace(/[\\\/?*\"'`]+/g,'').replace(/[|<>]+/g,'_').replace(/:/g,'։').slice(0,100).trim();
		d[1] = (d[1] == "0") ? fname.slice(0,48).trim() : (d[1] == "1") ? host.replace(/\/.*/,'') : "";
		try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);}
		d.forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777);
		fname += (function() {var d = new Date(), z = function(n){return '։' + (n < 10 ? '0' : '') + n}; return '_'+ d.getHours() + z(d.getMinutes()) + z(d.getSeconds());})();
		dir.append(fname +'.html'); var path = dir.path; //назначить путь сохранения

		if (!arg) { // диалог выбора папки
			var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
			fp.init(win, "", fp.modeSave);
			fp.defaultString = path.split(/.*[\/|\\]/)[1];
			fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll);
			var res = await new Promise(fp.open);
			if (res == fp.returnOK || res == fp.returnReplace)
				path = fp.file.path
			else return;
		}
		this.write(path, data);
		d = await win.Downloads.createDownload({source: "about:blank",target: win.FileUtils.File(path)}); (await win.Downloads.getList(win.Downloads.ALL)).add(d); await d.refresh(d.succeeded = true); //flash DWButton
	},
	write(path, html) {
		if (typeof IOUtils == "object")
			var write = IOUtils.writeUTF8 || IOUtils.writeAtomicUTF8; // Fx 85+ || 82-84
		if (!write) { // Fx 79-81
			var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
			write = (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt));
		}
		(this.write = write)(path, html);
	}
}).init("browser-delayed-startup-finished");

var htmlAndName = async mainWin => {

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

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

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

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

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

	var doctype = '', dt = doc.doctype;
	if (dt && dt.name) {
		doctype += '<!DOCTYPE ' + dt.name;
		if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22';
		if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22';
		doctype += '>\n';
	};
	var onlyName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());
	return [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', onlyName, loc.hostname];
}

Отредактировано Dobrov (15-07-2023 18:36:11)

Отсутствует

 

№92316-07-2023 05:43:08

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

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

Dumby - ещё нужна помощь!
хочу добавить в SystemGlobal вторую функцию, в ней нужны адрес и имя текущей вкладки.
gURLBar и gBrowser не работают, а win.location.hostname и doc.getElementsByTagName('title')[0] работают только в var htmlAndName = async mainWin => {
не знаю, как получить адрес и имя текущей вкладки без receiveMessage()


как в JSM-ке SingleHTMLChild получить адрес и имя текущей вкладки ?

Отсутствует

 

№92416-07-2023 09:54:01

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

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

odd74RUS пишет

стоит [firefox] 115.02

Нет такой версии.
Но есть 115.0.2 и на ней скрипт работает.


А вот в 116, да, отвалится:
Move handling of search engine one-off hidden from preferences into the search settings.


Можно будет так поправить

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

Выделить код

Код:

/*
        var pref = Services.prefs.getStringPref("browser.search.hiddenOneOffs");
        var hiddenList = pref ? pref.split(",") : [];
        var engines = await Services.search.getVisibleEngines();
        for (let engine of engines.filter(e => !hiddenList.includes(e.name))) {
*/
        var engines = await Services.search.getVisibleEngines();
        for(let engine of engines.filter(e => !e.hideOneOffButton)) {


Или, если нужна какая-то обратная совместимость, например, так
скрытый текст

Выделить код

Код:

/*
    async rebuild(menu) {
        var de = Services.search.defaultEngine;
        de = de.wrappedJSObject || de;
        this.setAttrs(menu, de, `Искать в ${de.name} или в ...`);
        menu.ePopup.textContent = "";
        var pref = Services.prefs.getStringPref("browser.search.hiddenOneOffs");
        var hiddenList = pref ? pref.split(",") : [];
        var engines = await Services.search.getVisibleEngines();
        for (let engine of engines.filter(e => !hiddenList.includes(e.name))) {
*/
    getEngines() {
        var args = "hideOneOffButton" in Services.search.defaultEngine
            ? [e => !e.hideOneOffButton]
            : Object.defineProperty(
                [function(e) {return !this.includes(e.name);}], "1", {
                    get: () => Services.prefs.getStringPref(this.hide)?.split(",") || []
                }
            );
        return (this.getEngines = async () =>
            (await Services.search.getVisibleEngines()).filter(...args)
        )();
    },
    async rebuild(menu) {
        var de = Services.search.defaultEngine;
        de = de.wrappedJSObject || de;
        this.setAttrs(menu, de, `Искать в ${de.name} или в ...`);
        menu.ePopup.textContent = "";
        for(let engine of await this.getEngines()) {


И да, я понимаю, что разговоры про 116+ для Win7 не слишком актуальны,
так что это просто так, на всякий случай.


Dobrov пишет

gURLBar и gBrowser не работают

Что-то я не понимаю твоего затруднения.
gURLBar и gBrowser — это свойства окна браузера, а не свойства SystemGlobal.


Есть ссылка на окно — есть и его свойства,
через оператор доступа к свойству объекта «.» (точка),
то есть: окно.gURLBar и окно.gBrowser


У тебя же самого, например, написано win.Downloads и win.FileUtils
Эти, конечно, можно получить и импортом модулей, но зачем, когда они уже есть в окне.


И gBrowser в модуле используется, смотри первую строку в saveHTML()

Отсутствует

 

№92516-07-2023 15:18:46

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

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

Dumby пишет

Что-то я не понимаю твоего затруднения.

Я тоже! :) Накосячил - разные функции с одним именем прописал в globalThis[Symbol.for(…
В итоге доработал 3 скрипта, в них сокращён код, используются 2 общие функции:
ucf_hookClicks.js ClickPicSave.jsm SingleHTMLChild.jsm


:( Ещё не получилось добавить setTimeout(… в скрипты scriptsbackground: [ // В фоне [System Principal]

Отредактировано Dobrov (16-07-2023 15:49:12)

Отсутствует

 

Board footer

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