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

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

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » Вчера 20:30:25

_zt пишет

Лоадер применительно к mjs не изменился?
Предполагаю что нет, так как один конвертированный скрипт в нем уже работает.

Не понял. Если сделал как написано в первой строке
конвертированного скрипта — значит изменился.


Неизменившийся у меня не работает, хотя мне казалось, что будет.
Но зачем искать себе приключений?
Для сконвертированных модулей следует использовать метод,
который сейчас в браузере для этого предназначен — ChromeUtils.importESModule("……….mjs");

И, пожалуйста, переделайте в mjs jsm-ки:

Хорошо, попробую.

[spoiler][code]var clickInterval = 5*60;
var intervals = [
    10, 15, 30, 60, 3*60,/* 5*60,*/ 15*60, 30*60, 60*60,
];
var name = "TreeStyleTabAutoReloader";
var addonId =

Сustom Buttons » Custom Buttons » Вчера 20:24:49

Stkvsky
А вот это, наоборот.
Удаление закладки — вещь глобальная, лучше в этот добавлять.


Сначала, дописываем CustomizableUI

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

Выделить код

Код:

/*
		var {PlacesUtils: pu, ContextualIdentityService: cis, PlacesUIUtils, PrivateBrowsingUtils}
			= Services.wm.getMostRecentBrowserWindow();
*/
		var {
			PlacesUtils: pu, ContextualIdentityService: cis,
			PlacesUIUtils, PrivateBrowsingUtils, CustomizableUI
		}
			= Services.wm.getMostRecentBrowserWindow();


Затем, после этого фрагмента
скрытый текст

Выделить код

Код:

//
					if (id) obj.deleted.set(guid, id), reg(id), shouldSave = true;
				}
			}


добавляем
[spoiler][code]//
            else if (e.itemType == bm.TYPE_BOOKMARK && e.type[9] == "r") {
                var {url} = e;
                for(var win of CustomizableUI.windows) {
                    var tabs = [], gb = win.gBrowser;
                    for(var br of gb.browsers)
                        br.currentURI?.spec == url && tabs.push(gb.getTabForBrowser(br));
   

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 15-03-2024 14:46:57

unter_officer пишет

Это возможно как-то поправить?

Даже не знаю, может так попробовать

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

Выделить код

Код:

/*
    var root = doc.documentElement;
    var body = doc.body || root;
    var scroller = body.scrollHeight > root.scrollHeight ? body : root;
*/
    var scroller = doc.scrollingElement;

Dobrov пишет

код обновления не пашет в подменю

Разве? Код-то как раз пашет, но пункт не render'ится.


Когда добавляешь пункт в основное меню он render'ится сразу,
но когда в субменю, тогда нет. А когда будет следующий вызов render()
метод уже переопределён и ничего не render'ит.


Можно сразу принудительно отрендерить, но лучше, наверно, отложить.
Плюс, upd() вызывается для пунктов субменю даже просто при открытии основного меню,
а это слегка нехорошо. Возможно, стоит проверять, что субменю открыто.


Вобщем, так поменял фрагмент кода создания виджета
[spoiler][code]CustomizableUI.getWidget(id)?.label || (self => CustomizableUI.createWidget(self = {
        id, label: id,

Сustom Buttons » Custom Buttons » 15-03-2024 14:45:08

Stkvsky пишет

еще и этот код добавить

Код совершенно оконный, не нужно его добавлять ни в какой другой.
Просто дописать в конец, как отдельный, как следующий.

Он при открытии закладки

Нет, не так. Не просто «при открытии закладки»,
а при открытии закладки в новой вкладке (не в текущей).

в новой версии перестал работать

Можно попробовать такую правку применить, и посмотреть как пойдёт.

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

Выделить код

Код:

/*
			var {loadURI} = br;
			br.loadURI = () => {
				br.loadURI = loadURI;
				gBrowser.removeTab(tab);
			}
*/
			br.fixupAndLoadURIString = () => {
				delete br.fixupAndLoadURIString;
				gBrowser.removeTab(tab);
			}

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 14-03-2024 20:06:02

egorsemenov06 пишет

Получаеться что и эта кнпка не будет работать

Ну, что значит не будет работать?
В данном случае речь о том, что перестанут подхватываться иконки
встроенных поисковиков (не поисковиков, которые поставил пользователь),
когда включат search-config-v2 (пока что, только в Nightly).


А правка там простая

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

Выделить код

Код:

/*
        node.setAttribute("image", engine._iconURI ? engine._iconURI.spec : engine.iconURI ? engine.iconURI.spec : this.defaultImg);
*/
        node.setAttribute("image", await engine.getIconURL?.() || engine.iconURI?.spec || this.defaultImg);

unter_officer пишет

в консоль пишет: CustomizableUI: Could not localize property 'ucf-cbbtn-ToggleCurrentSearchEngine.tooltiptext'.

Да, есть такое, за всем не уследишь.
Можно добавить, например, второй строкой
localized: false,


xrun1 пишет

переделать на mjs?

Что-то я не вижу там ничего такого,
что могло бы помешать сделать это самому.


Никаких выкрутасов, никаких __U

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 14-03-2024 17:59:39

Farby пишет

нашел решение от Vitaliy V

Не, Виталий такую шляпу не пишет, у него всё как-то более академично.
Это моё, наверно. Кстати, ошибку свою заметил.


Настройка "browser.search.hiddenOneOffs" дефолтно существовала (до 116),
а значит, если там ничего не было, то значением возвращалась пустая строка.
А выражение ""?.split(",") возвращает массив с пустой строкой, и это совсем не то, что нужно.


Dumby пишет

А когда приземлится это, надо будет смотреть,
не слетят ли иконки встроенных лисьих поисковиков.

Ха, оказывается они уже слетели (причём, во всём браузере),
если руками включить настройку browser.search.newSearchConfig.enabled


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

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 14-03-2024 08:24:55

unter_officer пишет

Пытаюсь разобраться

Это Bug 1870644 - Provide a single function for obtaining icon URLs from search engines


Farby предложил такую конструкцию:
engine._iconURI ? engine._iconURI.spec : engine.iconURI ? engine.iconURI.spec : this.defaultImg
что слегка замудро. Надеюсь, чуть лучше так:
(engine._iconURI || engine.iconURI)?.spec || this.defaultImg


Затем getIconURL() сделали асинхронной,
но пока ещё работает, то есть
img: e => (e._iconURI || e.iconURI)?.spec || "chrome://browser/skin/search-engine-placeholder.png",


А когда приземлится это, надо будет смотреть,
не слетят ли иконки встроенных лисьих поисковиков.


Ну, и на самой кнопке иконка не подхватывается, нужно прицепить wrappedJSObject.
[spoiler][code]/*
            var engine = popup.getDefaultEngine();
*/
            var e

Сustom Buttons » Custom Buttons » 14-03-2024 08:22:17

Stkvsky пишет

Можно вас попросить еще добавить открытие закладки в контейнере?

В смысле вписать в первый код
результирующую фаргментов второго и третьего?
Тогда как-то так, наверно
[spoiler][code](proto => {
    var g = Cu.getGlobalForObject(Cu);
    var name = "userContextId2FolderGuid.json";
    var obj = g[name] ??= g.eval(`(${name => {

        var title;
        var obj = globalThis[name] = Object.create(null);
        var path = obj.path = PathUtils.join(PathUtils.profileDir, name);
        var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);

        obj.deleted = new Map();
        var map = Object.create(null), guids = new Map();
        var running, write = () => {
            running = false;
            for(var k in map) return IOUtils.writeJSON(path, map);
            IOUtils.remove(path);
        }
        var save = () => {
            if (running) timer.cancel();
            timer.initWithCallback(write, 500, timer.TYPE_ONE_SHOT);
            running = true;
        }
        var reg = (id, guid) => {
            if (guid) guids.set(map[id] = guid, +id);
            else guids.delete(map[id

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 08-03-2024 10:27:29

Vitaliy V. пишет

Что ж пусть так и будет.

Сунул в custom_script.js
некий рандомно-тестовый код, и всё работает так, как ожидалось.

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

Выделить код

Код:

var bla = "bla";

var test = {
	"globalThis.bla": globalThis.bla, // user box, expected string
	"SystemGlobal.bla": Cu.getGlobalForObject(Cu).bla, // SystemGlobal, expected undefined

	// expected all exsists

	// dom idl
	PathUtils: PathUtils,
	AbortController: AbortController,
	HTMLAnchorElement: HTMLAnchorElement,

	// global properties
	FileReader: FileReader,
	XMLSerializer: XMLSerializer,
	URLSearchParams: URLSearchParams,

	// modules
	PlacesUtils: PlacesUtils,
	AppConstants: AppConstants,
	CustomizableUI: CustomizableUI,

	// internal stuff
	UcfPrefs: UcfPrefs,
	user_chrome: user_chrome,
	user_chrome_files_sandbox: user_chrome_files_sandbox,
};
for(let key in test) test[key] = typeof test[key];
console.log(JSON.stringify(test, null, "\t"));


Парадигма сдвинута.

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 07-03-2024 17:21:07

Vitaliy V. пишет

Это типа оператором присваивания ?

Да-да, именно им.
Они всё равно перебираются в цикле, вот прямо там и присвоить.

Можно ещё в виде прототипа все унаследовать
sandboxPrototype: UcfPrefs.global

Ууу, мысль, несомненно, интересная.
Это был бы эпический сдвиг само́й парадигмы.
Но тогда, да, действительно, мы получим вообще всё и сразу.

тогда нужно будет опять загружать CustomizableUI и UcfPrefs

Не загружать, а сослаться. Они уже загружены.

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 07-03-2024 10:20:57

О, спасибо!
Тогда код «Восстановить удалённое», будет, наверно, таким
[spoiler][code](async sep => {
    if (!sep) return;

    var key = "hasRemoveTransaction";
    var raws = UcfPrefs.dbg.ref("lazy", PlacesTransactions.undo).TransactionsHistory.proxifiedToRaw;
    raws[key] ??= entry => {
        for(var transaction of entry) {
            if (raws.get(transaction) 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,iVBORw0KGgoAAAANSUhEUgAAABAAAA

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 06-03-2024 18:18:58

Vitaliy V. пишет

именно для BrowserUsageTelemetry я бы не стал добавлять его, но если нужно для некоего кода

Не-не, конечно же, в первую очередь, для пользовательского кода.


Просто когда он уже есть, возникает соблазн
воспользоваться им и для усмирения BrowserUsageTelemetry.


Мягонькое такое воздействие, никакого насилия,
добавляем id'шники как пустые строки, и это дело умолкает.


Если будет принято решение заткнуть BrowserUsageTelemetry
как-то иначе, или не делать с этим ничего, тогда дебаггер мог бы быть lazy getter'ом.


Наверно лучше как свойство UcfPrefs. Он определён как в сандбоксе, так и в окнах браузера.
В других окнах UcfPrefs можно просто импортировать, если вдруг понадобится.


Вот, поискал, нашёл, например, такой код.
Здесь TransactionsHistory не вытащишь никак, когда исчезнет Cu.import()
А с дебаггером просто пишем UcfPrefs.dbg.ref("lazy", PlacesTransactions.undo).TransactionsHistory

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 05-03-2024 22:14:54

Vitaliy V. пишет

Что за проект?

Поскольку никто не мог знать, что нарисуется UCF 2024 от самого́ Автора,
а желающих обезопасить педыдущий UCF от последствий завершения JSM-геноцида
как-то не наблюдалось, то чувствовалось, что отдуваться придётся мне.


Я уже упоминал, что, увы, для некоторых задач, необходим дебаггер.
Вот когда приступил пробовать править UCF, решил, что он будет встроен.


Собственно, ничего особо сделать не успел,
пока там подформатировал всякий xml-like стафф в более человеко-читаемый вид,
пока заменил все четырёх-пробелья на благородную tab'уляцию,
случилось то, что случилось, и проект, соответственно, был мгновенно остановлен.


И это, несомненно, к лучшему.


Так вот, в config.js предполагалось оставить только самый минимум,
определение nsIFile'а с путём %профиль%/chrome/user_chrome_files/init.js
проверка, что он существует, и является файлом,
и загрузка этого init.js в объект {file: этот_файл};


А сырой набросок init.js был такой, скину какой был.
Не г

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 05-03-2024 09:26:14

Vitaliy V. пишет

добавить что это происходит только один раз при первом вызове

Да, разумеется. Но могло бы не происходить вовсе.

а где гарантии что это сейчас заведомо существующее не станет потом просто существующим или вообще не существующим

Ну так можно вообще обо всём сказать.
Хорошо, пусть сочтётся как осторожность.


Кстати, Console.sys.mjs же собираются выпилить,
неплохо бы что-то предусмотреть на такой случай.


Ещё, при переключении тулбаров посредством контекстного меню,
BrowserUsageTelemetry мусорит в консоль записью "widgetId is undefined".


Когда был проект встроить в UCF дебаггер,
то я просто добавлял id'шники в BROWSER_UI_CONTAINER_IDS


А теперь, наверно, надо какую-то функцию переопределять.
Ну, или ничего не делать, в консоль всё равно никто не смотрит.

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 05-03-2024 00:43:51

Vitaliy V. пишет

не было цели чтобы локали изменялись без перезагрузки

OK, принято.

В XPCOMUtils.sys.mjs так и записано

Точно. Запись довольно старая, старше чем globalThis.

В чем проблемма геттера?

Проблем нет никаких.
Геттер это функция. Обратился к свойству — считай вызвал функцию.
А функция всегда возвращает одно и то же.

оставил может пригодится для использования в пользовательском коде

OK, принято.

Возможно излишняя но мне нравится lazy, не используешь не загружается лишнее

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


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


Создание множества этих функций, которые проверяют уже заранее известное,
и возвращающих нечто заведомо сущест

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 04-03-2024 08:12:11

egorsemenov06 пишет

вот эта кнопка отвалиться когда выпилят jsm?

В этом смысле — вроде не должна.


Vitaliy V.
Насчёт UcfPrefs.mjs. Сперва по Fluent'у.
Лис 124 ru. Поставил langpack'и uk и de.


STR: Включаю de, рестарт. Открываю «Настройки UserChromeFiles»,
окно локализировано как ru, это нормально, сборка ведь ru, а de отсутствует.
Теперь переключаюсь на uk.


ER: Локализация в окне меняется на uk, ведь uk есть.
AR: Ничего не происходит, локализация остаётся ru.


Да, я понимаю, что STR довольно экзотичен.
Но, может быть, заменить appLocalesAsBCP47 на availableLocales


И по коду.
Первая строка var global = Cu.getGlobalForObject({}); Разве это не globalThis?
И, UcfPrefs.global да, полезно пробросить, но почему геттер, а не просто значение?


UcfPrefs.defineGlobalGetters есть, но в само́м UCF нигде не используется.


UcfPrefs.defineLazyGlobalGetters есть, но нужно ли это?
Вот, добавил в config.js, в самое начало, ещё до антиподписячего (мне можно),
чтобы не было никаки

Сustom Buttons » Custom Buttons » 02-03-2024 20:35:29

ifln
Вроде помогает заменить setTimeout на content.setTimeout

Сustom Buttons » Custom Buttons » 01-03-2024 20:53:18

Bug 1878401 - Always pass BrowsingContext to nsIFilePicker::Init (Firefox 125+)


Соберу, на всякий случай, Custom Buttons 0.0.7.0.0.33.

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 01-03-2024 16:45:40

Dobrov пишет

Массив вместе с субменю есть в ucf_hookClicks.js, вложенность любая.

Да, теперь чуть понятнее, наверно.
А то я думал, к чему это /^(sub|sep|inf|lab|img)$/.test(key)


Оказывается, что если вписан sub, код прогоняет через for in
объект в который вписан sub.
То есть, и для ключей, упомянутых в этом регулярном выражении
тоже создаётся (ненужный) элемент (как минимум <menuitem>)
и ему присваивается одноимённый атрибут "label".


Если значение ключа окажется строкой, то тогда создаётся не <menuitem>,
а <menu>, и создаётся <menupopup>, который добавляется к этому menu.
Всё потому, что у строки есть sub.
Вот проверь с консоли: var {sub} = "bla-bla"; alert(sub);
Это будет — String.prototype.sub().


Эти ненужные элементы можно посмотреть в консоли,
если добавить в конец метода fill() строку
if (!item.parentNode) console.log(item.outerHTML);


Вот чтобы всё это низачем-со

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 29-02-2024 15:21:27

egorsemenov06 пишет

Ссылки кликабельны

Здесь можно переделать. Переименовать UcfTextToLinkActorChild.{ jsm —> mjs } и правки
[spoiler]
В text-to-link.js

Выделить код

Код:

/*
                    moduleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.jsm",
*/
                    esModuleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.mjs"

В UcfTextToLinkActorChild.mjs
[code]/*
var EXPORTED_SYMBOLS = ["UcfTextToLinkActorChild"];
var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["NodeFilter", "Node"]);
XPCOMUtils.defineLazyGetter(this, "excludedTags", () => {
    return new Set(["a","svg","canvas","applet","input","button","area","embed","noembed","frame","frameset","head","iframe","img","select","option","datalist","map","meta","noscript","video","audio","object","param","script","style","textarea","code"]);
});

class UcfTextToLinkActorC

Сustom Buttons » Custom Buttons » 29-02-2024 15:18:33

Stkvsky
Ууу, это сложновато для меня.
Нужно карту сопоставления userContextId и guid'а папки
куда-то на диск сбрасывать.


Вот, не всё, что хотелось бы, да и запутаться могу запросто,
и тестировать это весьма заморочно.
[spoiler][code](proto => {
    var g = Cu.getGlobalForObject(Cu);
    var name = "userContextId2FolderGuid.json";
    var obj = g[name] ??= g.eval(`(${name => {

        var obj = globalThis[name] = Object.create(null);
        var path = obj.path = PathUtils.join(PathUtils.profileDir, name);
        var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);

        obj.deleted = new Map();
        var map = Object.create(null), guids = new Map();
        var running, write = () => {
            running = false;
            for(var k in map) return IOUtils.writeJSON(path, map);
            IOUtils.remove(path);
        }
        var save = () => {
            if (running) timer.cancel();
            timer.initWithCallback(write, 500, timer.TYPE_ONE_SHOT);
            running = true;
        }
        var reg = (id, guid) => {
            if (guid) guids.set(map[id] = guid, +id);
           

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 26-02-2024 08:26:11

Dobrov пишет

Раз это не в скрипте проблема

Кстати, скрипт под багом ходит (1552815).
Движуха там затихла, но в любой момент это дело могут пнуть,
и баг вывалится как "FIXED". Прикинь тогда разгребать.

.jsm

А вот и баг о временах и сроках.


Может завести какую-нибудь папку с любым условным названием типа «129».
Запилить на неё readme, мол здесь вам (пока) не что-то готовое,
но всего лишь WIP-полигон миграции JSM —> ESM.


Это я в том смысле, что время пока есть,
и «подстелить соломку», а не чтобы как «снег на голову».
Совместимость, разумеется, может и должна быть сброшена.

Сustom Buttons » Custom Buttons » 26-02-2024 08:22:31

Stkvsky
Проблема в том, что закладке хорошо бы назначить имя,
такое же, как у этой вкладки в итоге.


Но вкладка свежеиспечённая, ещё только пошла грузиться,
и когда она разродится своим окончательным именем поймать не получается.
Хотел подрядить ProgressListener, но успеха не снискал,
а пробовать что-то ещё мудрёнее желания нет.


Таким образом, могу предложить лишь таймаут,
типа ждём секунду, и добавляем закладку с таким именем,
которое будет у таба на тот момент. Надеюсь, лучше чем ничего.


Код на замену
[spoiler][code](proto => {
    var title, bm = PlacesUtils.bookmarks;
    var {toolbarGuid: parentGuid, TYPE_FOLDER: type} = bm;
    var wait = resolve => setTimeout(resolve, 1000);

    var ntc = async br => {
        var tab = gBrowser.getTabForBrowser(br);
        var {guid} = await bm.insert({title, parentGuid, type});
        await new Promise(wait);
        bm.insert({title: tab.label, url: br.currentURI.spec, parentGuid: guid});
    }
    var ds = proto.doSearch;
    proto.doSearch = function(str, where, e, para

Сustom Buttons » Custom Buttons » 24-02-2024 09:13:58

Stkvsky пишет

Чтобы если создается контейнер, тогда на панели закладок создается папка с таким же названием как у контейнера

и в эту папку добавляется вкладка из этого контейнера

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

Скрипты » UCF - ваши кнопки, темы, дополнения, скрипты… » 19-02-2024 19:18:10

egorsemenov06 пишет

А с первой не поможите?

Это баг 1872673 - Remove 'console' export from Console.sys.mjs
То есть, дело не в коде кнопки, а в само́м UCF.


Но держать отладочный консольский стафф в кнопке постоянно
не требуется, можешь просто удалить console.log(req)


Однако, вернуть в укфский сандбокс консоль не помешает.
Я тут в user_chrome.js так переставлял
[spoiler][code]/*
                if ("defineLazyModuleGetters" in XPCOMUtils)
                    XPCOMUtils.defineLazyModuleGetters(scope, {
                        console: "resource://gre/modules/Console.jsm",
                        AddonManager: "resource://gre/modules/AddonManager.jsm",
                        AppConstants: "resource://gre/modules/AppConstants.jsm",
                        E10SUtils: "resource://gre/modules/E10SUtils.jsm",
                        FileUtils: "resource://gre/modules/FileUtils.jsm",
                        OS: "resour

Board footer

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