/** @UCF @param {"prop":"JsChrome.load","ucfobj":true,"disable":true} @UCF */ // Пункт для контекстного меню адресной строки, подставляющий модификаторы поиска (async ( id = "ucf_searchmodifiers", label = "Вставить mod", modifiers = [ "* ― Закладки", "% ― Вкладки", "^ ― История", "> ― Действия", "# ― Названия", "+ ― С метками", "~ ― Набранные", "@ ― URL-адреса" ], ) => ({ init() { var urlbar = this.urlbar = gURLBar.textbox; if (!urlbar) return; setUnloadMap(Symbol(id), this.destructor, this); urlbar.addEventListener("popupshowing", this); }, handleEvent(e) { this[e.type](e); }, popupshowing({target}) { if (target != (this.popup ||= gURLBar.inputField.parentElement.menupopup)) return; this.urlbar.removeEventListener("popupshowing", this); this.urlbar = null; var sep = this.popup.querySelector("menuseparator.menuseparator-add-engine") || this.popup.lastElementChild; var menu = this.append("menu", sep, {label}, "before"); this.append("menuseparator", menu, null, "before"); var pp = this.pp = this.append("menupopup", menu, null, "append"); pp.addEventListener("command", this); var df = document.createDocumentFragment(); for (let label of modifiers) this.append("menuitem", df, {label}, "append"); pp.append(df); }, command(e) { gURLBar.search(e.target.label[0]); }, append(name, parent, attrs, func) { var elm = document.createXULElement(name); if (attrs) for (let a in attrs) elm.setAttribute(a, attrs[a]); parent[func](elm); return elm; }, destructor() { this.urlbar?.removeEventListener("popupshowing", this); this.pp?.removeEventListener("command", this); }, }).init())();
/** @UCF @param {"prop":"JsChrome.load","ucfobj":true,"disable":true} @UCF */ // Добавить подменю "Поиск изображения в" в контекстном меню изображений (async ( id = "ucf_searchimagecontextmenu", label = "Поиск изображения в ...", label2 = "Искать во всех поисковиках", engines = [ ["Google", "https://www.google.lv/favicon.ico", "https://lens.google.com/v3/upload?url="], ["Яндекс", "https://yastatic.net/morda-logo/i/favicon_islands.ico", "https://yandex.ru/images/search?rpt=imageview&url="], ["Bing", "https://www.bing.com/s/a/bing_p.ico", "https://www.bing.com/images/search?view=detailv2&iss=sbi&form=SBIHMP&sbisrc=UrlPaste&q=imgurl:"], ["Tineye", "https://tineye.com/favicon.ico", "https://tineye.com/search?pluginver=bookmark_1.0&url="], ], ) => ({ init() { var popup = this.popup = document.querySelector("#contentAreaContextMenu"); if (!popup) return; setUnloadMap(Symbol(id), this.destructor, this); popup.addEventListener("popupshowing", this); }, handleEvent(e) { this[e.type](e); }, click(e) { if (e.target != this.menu) return; this.command(e); e.target.parentElement.hidePopup(); }, command({target}) { for (let engine of target._engines || [target._engine]) gBrowser.selectedTab = gBrowser.addTrustedTab(engine[2] + encodeURIComponent(gContextMenu.imageInfo.currentSrc), { index: gBrowser.selectedTab._tPos + 1 }); }, popupshowing(e) { if (!gContextMenu?.imageInfo?.currentSrc || gContextMenu.webExtBrowserType === "popup") return; this.popupshowing = this.showing; var menu = this.menu = document.createXULElement("menu"); menu.setAttribute("label", label); menu.setAttribute("class", "menu-iconic"); menu.setAttribute("image", engines[0][1]); menu.addEventListener("click", this); menu._engine = engines[0]; var mPopup = this.mPopup = document.createXULElement("menupopup"); mPopup.addEventListener("command", this); menu.append(mPopup); for (let engine of engines) { let m = document.createXULElement("menuitem"); m.setAttribute("label", engine[0]); m.setAttribute("image", engine[1]); m.setAttribute("class", "menuitem-iconic"); m._engine = engine; mPopup.append(m); } var mItem = document.createXULElement("menuitem"); mItem.setAttribute("label", label2); mItem._engines = engines; mPopup.append(mItem); this.popup.querySelector("#context-copyimage-contents")?.before(menu); this.popup.addEventListener("popuphiding", this); }, showing({target}) { if (target != this.popup || !gContextMenu?.imageInfo?.currentSrc || gContextMenu.webExtBrowserType === "popup") return; this.menu.hidden = false; }, popuphiding({target}) { if (target != this.popup) return; this.menu.hidden = true; }, destructor() { this.popup.removeEventListener("popupshowing", this); this.popup.removeEventListener("popuphiding", this); this.menu.removeEventListener("click", this); this.mPopup.removeEventListener("command", this); }, }).init())();
Отсутствует
Вы здесь выложили два одинаковых.
Суть одна, а реализация разная.
«The Truth Is Out There»
Отсутствует
_zt
Вы про ucfobj?
То, о чём написал yup на предыдущей странице для меня слишком заумно.
Раз мой вопрос дискуссии не вызвал, значит никто не знает для чего это. Я для себя давно сделал вывод, это моё личное мнение - это авторская метка.
Скрипты, сделанные лично/полностью переделанные автором UCF - "правильные" true.
А всякие *.uc.js от какого-нибудь alice0775 или Aris-t2, включая Dumby - это "неправильные", с авторской точки зрения, false-скрипты.
Если Вы про этот, то, конечно, true. Хотя у меня скрипт с поздними правками от Dumby.
Я выкладывал свой здесь.
Добавлено 23-05-2025 16:19:45
Актуальный код у меня немного другой, если надо - выложу. Но думаю, не надо, раз пошла "большая перепись скриптов".
Отредактировано xrun1 (23-05-2025 16:19:45)
Отсутствует
xrun1
Я не про это, скрипт не работает, а в консоли
Uncaught EvalError: call to eval() blocked by CSP
и
Content-Security-Policy: Параметры страницы заблокировали выполнение JavaScript eval (script-src), поскольку он нарушает следующую директиву: «script-src chrome: moz-src: resource: 'report-sample'» (Отсутствует 'unsafe-eval')
Отсутствует
То, о чём написал yup на предыдущей странице для меня слишком заумно.
Раз мой вопрос дискуссии не вызвал, значит никто не знает для чего это.
Я могу разъяснить подробнее, что имел в виду Vitaliy V. Но во-первых, это получится достаточно пространно, и я не знаю, насколько оно здесь уместно. А во-вторых, кое-чего я сам не очень хорошо представляю (не в смысле "что это", а "почему автор UCF сделал именно так").
Но на второй странице этой темы есть вот такой его комментарий:
параметр ucfobj должен быть true для моих скриптов (если не указано), и false или отсутствовать для других (если автором скрипта не указано обратное)
Скрипты, сделанные лично/полностью переделанные автором UCF - "правильные" true.
А всякие *.uc.js от какого-нибудь alice0775 или Aris-t2, включая Dumby - это "неправильные", с авторской точки зрения, false-скрипты.
Почти да. У тех скриптов, которые true, и тех, которые false, разные глобальные окружения.
Для false это window, а для true - отдельный объект, создаваемый UCF.
В результате true-скрипты в случае возникновения конфликта имён переменных/функций будут гадить только себе подобным, а false-скрипты - себе подобным и всему остальному браузеру в целом.
Отредактировано yup (23-05-2025 16:52:50)
Отсутствует
_zt
У меня работает. Только скрипт бесполезен, гугл-переводчик скриптовый г*о.
https://imgsh.net/i/0cc205e905
Добавлено 23-05-2025 18:46:42
yup
Не помню, видел я комментарий автора или нет, но "опыт сын ошибок трудных"(с) меня в этом убедил.
Отредактировано xrun1 (23-05-2025 18:46:42)
Отсутствует
гугл-переводчик
Отсутствует
xrun1
Портированный "на скорую руку" скрипт от другой системы, который прекрасно работает при false, может неправильно работать (или вообще не работать) при true.
Для true некоторые вещи нужно писать особым образом.
Потому автор и говорил использовать false, что людям, не разбирающимся в тонкостях внутренних дел UCF, так проще - можно всё делать так, как они привыкли.
Отредактировано yup (23-05-2025 20:45:39)
Отсутствует
fuchsfan
Спасибо, но нет. Перевод - то же самое гуано.
https://imgsh.net/i/72938ab41d
В моём варианте окошко подстраивается под размер текста и вообще привык. Ещё в фоне QTranslate работает.
Добавлено 23-05-2025 21:30:09
yup
Сам я ничего не портирую. А чужие пишу с false. У меня сложился набор кнопок и скриптов и новые давно не ставлю.
Отредактировано xrun1 (23-05-2025 21:30:09)
Отсутствует
xrun1
Вы так и не ответили, каким образом он у вас работает? Или на 138 еще нет проблемы с eval?
Ну так следующее обновление это исправит.
А вот context-translate-enhanced.uc.js работает. И тоже подстраивается под размер текста, а минимальный размер в скрипте задается. Как и все остальное.
Отредактировано _zt (23-05-2025 23:36:21)
Отсутствует
_zt
Я уже отвечал Вам на подобный вопрос. У меня релизные версии. Я обычный пользователь, не тестер, скрипты/css не пишу. Зачем мне альфы-беты-гаммы? Будет 139 - будет видно. На 138.0.3 работает.
И тоже подстраивается под размер текста
Да ладно.) А что так много пустого места снизу осталось?
Отредактировано xrun1 (23-05-2025 23:36:05)
Отсутствует
_zt
Просто в теме по поводу размера окна скриптом Google Translate был большой трёп и Dumby долго делал приемлемый вариант. У меня какой-то промежуточный этап, который лично меня устроил.
https://imgsh.net/i/b43778b539
Что касается перевода, то гугл то ли с февраля, то ли с марта изменил отдачу перевода скриптам. Я пытался посмотреть, какие там post/get запросы идут. Но быстро понял, что люди, понимающие в этом больше меня тоже в ах*е.
Раньше гугл отдавал 2 варианта.
Примерно, как сейчас перевод https://translate.google.com/translate_a/single?client=gt&sl=
И хороший и правильный при добавлении всего одной буковки (gt --> gtx) https://translate.google.com/translate_a/single?client=gtx&sl=
Теперь оба неприемлемые. В обоих скриптах используется этот запрос.
Отсутствует
xrun1
Набрал я руками в адресной строке браузера то, что на Вашей картинке. Получил перевод - тот самый, который "то же самое гуано".
Тогда набрал просто "https://translate.google.com", на странице ввёл фразу - получил ровно тот же перевод.
Попробовал в другом браузере - "Ба, знакомые всё яйца!"
Как Вам удалось получить "хороший" перевод?
Отредактировано yup (Вчера 14:24:19)
Отсутствует
Тогда набрал просто "https://translate.google.com", на странице ввёл фразу - получил ровно тот же перевод.
Может, куки прицепились? У меня на сайте правильно переводит. Проверил сейчас эту же фразу в Cent, правильно перевёл.
Добавлено Вчера 15:57:08
_zt
Менял сегодня иконки в кнопке Save_Script.js и столкнулся с проблемой. Если в секции с PNG заменить иконки на svg, отображаться не будут. В этом виновата кнопка Save_Button.js. Если я беру старую кнопку, которая у меня в custom_script.js, всё отображается правильно. Можете проверить и подтвердить или опровергнуть, а то я запутался?
Пути к скрипту поправьте только.
// Скрипт Save // Правка Vitaliy V. 2505 // Предыдущая версия // https://forum.mozilla-russia.org/viewtopic.php?pid=781458#p781458 // https://forum.mozilla-russia.org/viewtopic.php?pid=799602#p799602 // https://forum.mozilla-russia.org/viewtopic.php?pid=799639#p799639 // https://forum.mozilla-russia.org/viewtopic.php?pid=805016#p805016 // Кнопка-виджет в Save_Button.js self.label = "Save"; self.type = "menu"; // Создать меню для кнопки ... var array = [ { label: "Сохранить favicon сайта", func: () => saveFavicon(), image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="}, { label: "Копировать favicon сайта в base64", func: () => copyFaviconData(), image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="}, { separator: ''}, { label: "Сохранить ярлык страницы как …", func: () => saveShortcuts(), image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="}, { separator: ''}, { label: "Сохранить страницу как PDF", func: () => savePageToPDF(), image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYUw4pJt3V/+Rb1D8lnFP/55zTf+VcVH/lXJS/5VyUv+VclL/lXJS/5VyUv+VclL/k3BR/J56Wv9cRzSkAAAAAJNvUKTto2L/4ppe/uehZf/Pmmr/noZv/9Scav/Wl17/1plh/9eZYf/XmWH/15lh/9eZYf/WmGD/2Jlg/suRXP9mRiuk8rWA/397dP1akKn/rqqi/3LF3f8Mntj/4dLJ///+9f/48u3/9e7n//bt5v/47+f/+O/n//jv5//rvZP/1ZJX/a9/VP9+lrD8AIvz/xOt+f8Douv/ALb6/wC28/9tmar/z8jJ//Lq5/////7//v////n9///6/P3//////+Ta0P/PjVP/pnpT/IWds/+aiXj/5efl/8Px//951/3/LMz//wCx8/8GltL/NIu3/4ycqf/l29L////+//n6+//8/v//3tXM/8+OVP+oe1P/6K57/86QWP/r6Ob////////++v/r9/z/oOb9/zDL//8Arf//AI/r/ydysv+hpqr//PTr///////d1Mz/0I5U/6h7U//osH//wo5g/+fm5P/7/f//9vf5//z7+////vv/9/r8/5Dc/P8Oqv7/AJf//wF02v9ffZ7/8Ojh/+Ha1P/NjFL/qHtT/+ewf//Ej1//7O3r///////+/v7//v7+//f5+v/6+vv////8/8Tq/f8hp/7/AJH//wB18/8/bqj/1MGu/9mXXv+leVH/569+/8iSYv+/tKn/wLew/8O5sf/P0M////////7+/v/3+fv////7/9Hv/v8hoP3/AIn//wB4/v84ZqL/w4NH/619VP/nsYD/x45c/9W5of/bv6j/0Jxt/6J/YP+spqD/2N3i//7////6+/3///76/8vr/v8Slv7/AIb+/wBz//83VH7/nW1B/+ewfv/Fjl7/7Ozr///////9+/r/9d7K/9Ghdv+jd1D/pJ6Y/+jt8f/9///////7/6fb/v8Ahv7/AYD//wRp6f95YlT/57B//8SOXv/n5uT//v7///r7/P/8/v////////XRsv/DhEv/loBu/9DX3P/9/v/////7/2O6/f8Afv//FnTU/5JtTf/nsH//xY9e/+jn5f/+/f//+fj5//n4+P/5+Pn/+/////Xbxf/Wj1D/nX1h/+Ll6P////7/3+/3/w+V//8tcbP/qHJB/+WuffzCjV7/5efn///////+/v7//////////////v7///////XRsP/TnW3/8fT3//////////z/ddD//0Nxl/+zdkH88LmH/9CRWP2+qJT/0M7N/8/Jxv/Pysf/z8rH/8/Kxv/Py8n/zsO6/7+pmP/PzMv/zsnG/9bNyP+nsK7/h4R3/b2BT/+Sb1Ck7qxw/9GSW/69hlb/wYhX/8CIV//AiFf/wIhX/8CIVv/BiVj/xI1d/8CIVv/BiFf/vYZW/9STW/7ppmv/bE80pAAAAACUd16k+sui/+7AmPzwwpr/8MKa//DCmv/wwpr/8MKa//DCmf/vwZj/8MKa//DCmv/uwJj8+cui/5N3XaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { label: "Печать страницы / печать в PDF", func: () => document.querySelector("#mainCommandSet > command#cmd_print").doCommand(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAC6ElEQVRYCd2WzW8NURjGZ6hqKFckNIidhUY/fCysmm7KxkaIhAVNETtJcxf+AURISxMbEZvGBgtBokU3NrpxW410JxVarCiVNKQtx+/Re2TmzseZe29Xmud3zpz3fd53zkzn3ju+52X/M8Ycwn0V3kMBRkDzG9/3Dcdlyy+ngg2M498BpfpOYBS0GbupiSybyrwBTr6LE+gkTN4kwyZYAUn6RkKbsRTY0FtiIZWzgV4q87AAW0AnaGbeA7tBs9YrOU7SVxLBu/Qk0wa4+uUUToGueoArOcBxRPh0R5pI2A1pbmVdB3EqxAUjMRrvA6ujEUNKgKIaaIEuuA7DMA+SnqmU6mIKZz9IMwyriuGKJuo3wAJIF5xNcNXDLEi3nAUOA03OgJUe7PQKnMfBqj3d7c7SaBCkCbcbB84BkKYYlhGqWNTn4CdIfc5GuBrAPjCXnQUOA72Cd7PNYfc8CvJg1egscBho9BikdwzurwBMIyBl+7ymbIAm62EOpN4U62IKVxNYdS9GKx9pdBKs9jo74TwPkj6zm50FDgONBkGaZMh0+x9ilJ46ejvTNGkA+zBfCRWQaIW1oSALYo1wCbaxrEr06AarllAzondBn817zB3gvj2hDu4FPV+BNBpxEx2GoF6yOA2rI+YKAvRpBqt8pAWZIYjTD4J/70qkqIwAPS6C9ItB7xHhaoI3wKUXGE5A0u96uGlxhb8WPoE0VAyHJzJtkFVfMF6D7eEu8St8x8DqSLyLKA49iEyZ9RvnKUoTRd6HMZA+MuhtKeK3v25dZB5AVvkYN0KaDpPU6xiT18Nr3LwOUmGX++EZZFF/UjOK14Gumsnom68uyRsbp2on3IY5SNI0ifrSBorBc7A6WOrJvKbDVuiBGYjTfYI5NWTW/7yDeRysbipXNXTLwTn4AKWaJTBdhOmf7nBUU/XJgw1oWAudxpjXkKTPJM6CH6xd0mM1h3ZjTB+MgU76iLnTGLNmSU/23zf7A6yAD944M8WnAAAAAElFTkSuQmCC"}, { label: "Сохранить страницу / выбор как HTML", func: () => savePageToHTML(), image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M12.225.01H2.656v5.993l.955-.125L3.569.677 11 .76l-.042 4.375h4.275l.041 10.125-12.575.042-.042.708h13.281V3.737L12.225.01zm-.272 1.613 2.384 2.394h-2.384V1.623zm2.93 10.318.062 1.333-2.992.063V8.003h1.328v4l1.601-.063zM4.647 8.002h-.664v1.334h.664v4h1.329v-4h.664V8.003H4.648zm5.313 0-.664 1.074-.664-1.074H7.305v5.334h1.328V10.53l.664 1.073.664-1.073v2.807h1.328V8.003H9.961zm-7.969 2h-.664v-2H0v5.334h1.328v-2h.664v2H3.32V8.003H1.992v2z'/></svg>"}, { label: "Сохранить URL, страницу / выбор как TXT", func: () => saveSelectionToTxt(), image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { separator: ''}, { label: "Копировать изображение / текст в base64", func: () => copyFileToBase(), image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ=="}, { separator: ''}, { label: "(Меню ПКМ) Сохр./добавить текст в файл", value: "Save.SelectionToFile" }, { label: "(Меню ПКМ) Открыть текст в редакторе", value: "Save.TextToEditor"}, ]; var menuPopup = self.appendChild(document.createXULElement("menupopup")); array.forEach((m,i)=> { if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return }; var mItem = menuPopup.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", m.label); mItem.setAttribute("class", "menuitem-iconic"); if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); if ("value" in m) { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('checked', cbu.getPrefs(m.value) ); mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); } if ("func" in m) mItem.addEventListener("command", m.func); }); menuPopup.onclick = e => e.stopPropagation(); function aDate() { var t=new Date(); var y=1900+t.getYear(); var min=t.getMinutes(); if (min<10){min="0"+min}; var h=t.getHours(); var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";} var d=t.getDate(); var curdate=d+" "+m+" "+y+" "+"г"; var myfilename=curdate; return myfilename; } // Копировать favicon сайта в base64 function FaviconToBase(image) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); gClipboard.write(base64); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); var alertName = "FaviconToBase"; as.showAlertNotification( base64, "Скрипт Save - FaviconToBase", "Значок скопирован как base64", false, "", null, alertName ); setTimeout(as.closeAlert, 5e3, alertName); }; // Сохранить страницу / выбор как HTML function savePageToHTML() { var vert = String.raw`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.style.cssText ='position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;';doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`; gBrowser.fixupAndLoadURIString(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }; // Получить имя файла async function pick(fileName) { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } var fp = makeFilePicker(); fp.init(window.browsingContext, "", fp.modeSave); fp.displayDirectory = file; fp.defaultString = fileName; return await new Promise(fp.open) != fp.returnCancel && fp.file; } // Сохранить favicon сайта function saveFavicon() { var dn = "favicon"; var re = /^data:(image\/[^;,]+)/i; var ms = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); (saveFavicon = async () => { var url = gBrowser.selectedTab.image; if (!url) return; if (re.test(url)) { try {var name = gBrowser.currentURI.host || dn;} catch {name = dn;} name += "." + ms.getPrimaryExtension(RegExp.$1, "ico"); } else var name = Services.io.newURI(url).QueryInterface(Ci.nsIURL).fileName; var file = await pick(name); file && IOUtils.write(file.path, new Uint8Array(await (await fetch(url)).arrayBuffer())); })(); } // Сохранить ярлык страницы как … function saveShortcuts() { var img = self.getAttribute("image"); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveShortcuts = async () => { var file = await pick(getTabLabel() + ".url"); if (file) await IOUtils.writeUTF8(file.path, `[InternetShortcut]\r\nURL=${gBrowser.currentURI.spec}\r\n`), as.showAlertNotification( gBrowser.selectedTab.image || img, file.leafName, "Сохранил в: " + file.parent.path ); })(); } // Копировать изображение или текстовой файл в base64 ... function copyFileToBase(){ var fp = window.makeFilePicker(); fp.init(window.browsingContext, "Открыть файл", fp.modeOpen); fp.appendFilter( "Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml;\ *.xhtml; *.json; *.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; *.ico; *.svg;\ *.svgz; *.tif; *.tiff; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw; *.webp"); fp.open(re=> { if ( re != fp.returnOK ) return; var file = fp.file; var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); inputStream.init(file, 0x01, 0o600, 0); var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(inputStream); var encoded = btoa(stream.readBytes(stream.available())); var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file); var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded; gClipboard.write(dataURI); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); var alertName = "FileToBase"; as.showAlertNotification( dataURI, "Скрипт Save - FileToBase", "Файл скопирован как base64", false, "", null, alertName ); setTimeout(as.closeAlert, 5e3, alertName); }); }; // Сохранить страницу как PDF, скриптом ... function savePageToPDF() { var ps = Ci.nsIPrintSettings, cfg = { paperWidth: 8.5, paperHeight: 11, paperSizeUnit: ps.kPaperSizeInches, // kPaperSizeMillimeters marginLeft: .2, marginRight: .2, marginTop: .2, marginBottom: .2, edgeLeft: .1, edgeRight: .1, edgeTop: 0, edgeBottom: 0, headerStrLeft: "&T", headerStrCenter: "", headerStrRight: "&U", footerStrLeft: "&PT", footerStrCenter: "", footerStrRight: "&D", printBGColors: true, printBGImages: false, scaling: 1, shrinkToFit: true, // overrides scaling orientation: ps.kPortraitOrientation, // kLandscapeOrientation printerName: "", printSilent: true, printToFile: true, showPrintProgress: false, isInitializedFromPrefs: false, isInitializedFromPrinter: false, outputFormat: ps.kOutputFormatPDF, outputDestination: ps.kOutputDestinationFile, }; ps = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService).createNewPrintSettings(); for(var key in cfg) if (key in ps) ps[key] = cfg[key]; (savePageToPDF = async () => { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } file.append(`Snap ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")}.pdf`); ps.toFileName = file.path; await gBrowser.selectedBrowser.browsingContext.print(ps); //file.launch(); })(); }; // Копировать favicon сайта в base64 ... function copyFaviconData() { var img = new Image(); img.src = gBrowser.selectedTab.image; FaviconToBase(img); }; // Сохранить URL, страницу / выбор как TXT ... function saveSelectionToTxt() { // [129+] l11 = length >= 11; https://forum.mozilla-russia.org/profile.php?id=71856 var {length} = saveURL, splice = length > 9, l11 = length >= 11; var msgName = _id + ":Save:GetSelection"; var receiver = msg => { var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\r\n\r\n" + msg.data), getTabLabel() + ' ' + aDate().replace(/:/g, ".") + ".txt", null, false, false, null, window.document ]; splice && args.splice(5, 0, null) && l11 && args.splice(1, 0, null); saveURL(...args); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}; var fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("NAME", res); } var url = "data:charset=utf-8," + encodeURIComponent(`(${func})`.replace("NAME", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); } // Добавляем в контекстного меню страницы новые пункты ... ((contextMenu, el)=> { // в контекстное меню выделенного текста ... var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); saveItem.id = "content-saveItem"; saveItem.setAttribute("label", "Сохр./добавить текст в файл"); saveItem.setAttribute("class", "menuitem-iconic"); saveItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); saveItem.onclick =()=> saveSelectionToFile(); var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); editorItem.id = "content-editorItem"; editorItem.setAttribute("label", "Открыть текст в редакторе"); editorItem.setAttribute("class", "menuitem-iconic"); editorItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXFz/Wlpa/1paWv9aWlr/Wlpa/1paWv9aWlr/Wlpa/1paWv9aWlr/Wlpa/1paWv9cXFz/AAAAAAAAAAAAAAAAXFxc//n7+f39/v3+/f79/v7+/v7+/v7+/v7+/f7+/v3+/v78/v7+/P////v////2XV1d/wAAAAAAAAAAAAAAAF9fX//7/fv/FVcX/wBIAv8ASAL/AEgC/wBIAv8ASAL/AEgC/wBIAv8VVxf//f78/2BgYP8AAAAAAAAAAAAAAABhYWH/+/78/zRtNf8otUX/KLVF/yi1Rf8otUX/ZLal/ypBSf9Upcv/NG01//z+/P9kZGT/AAAAAAAAAAAAAAAAZGRk//v+/P9Yh1n/MtB1/zLQdf8y0HX/MtB1/3PZrv9Tpcz/AXfF/2WYiP/8/v3/Z2dn/wAAAAAAAAAAAAAAAGZmZv/8/v3/gKSB/zvdof873aH/O92h/zvdof873aH/Fsj4/wSo6/8Ldr3//f7+/2tra/8AAAAAAAAAAAAAAABpaWn//P/+/6fAqP9C4bn/QuG5/0Lhuf9C4bn/QuG5/1vkxf8GwP7/AXfH/5HD4v9ubm7/AAAAAAAAAAAAAAAAa2tr//z//v/L2sz/lt7S/5be0v+W3tL/lt7S/5be0v+W3tL/Ms34/wSv8P8Abr7/cnJy/wAAAAAAAAAAAAAAAG5ubv/9/v7/6vDq/2Xo3f9l6N3/Zejd/2Xo3f9l6N3/Zejd/2Xo3f8GwP7/AXvJ/1uPsP8AAAAAAAAAAAAAAABwcHD//v////Hu5//l4NT/5eDU/+Xg1P/l4NT/5eDU/+Xg1P/l4NT/XNT5/wS39/8Abr//5PH2GgAAAAAAAAAAc3Nz/////////////v79//7+/f/+/v3//v79//7+/f/+/v3//v79//////8Gwf7/AYPN/xh+wukAAAAAAAAAAHV1df//////7Onh/+Xg1P/l4NT/5eDU/+Xg1P/l4NT/gYGB/4CAgP+AgID/U67L/wS2+P8AbcD/4ezzIAAAAAB4eHj///////39/P///////////////////////Pv6/4CAgP/9/f3//f39/4GBgf4Nwv3+UI+q/4x+d9IAAAAAenp6//////+Wlpf/9/X0/5OTlP/18/L/k5OU//Lv7f+AgID//f39/4GBgf6EhIRd8OXhU8yplP9yWU7/zsjCXH19ff+3t7f/////KLq6uv////8ourq6/////yi6urr/gICA/4GBgf6EhIRdAAAAAAAAAACxqMC5HhmE/wAAdP+AgID/gICA/56entOBgYH/n5+f1oGBgf+fn5/WgYGB/4GBgf+EhIRJAAAAAAAAAAAAAAAA5Of3EAcKj/8AAHP/AAesQQAHrEEAB6xBAAesQQAHrEEAB6xBAAesQQAHrEEAB6xBAAOsQQADrEEAAaxBAAGsQQAArEEAGKxBADisQQ=="); editorItem.onclick =()=> textToEditor(); // устанавливаем где и при каких настройках показывать новые пункты .... addEventListener('popupshowing', e=> { if (e.target != e.currentTarget) return; var sel = gContextMenu.isTextSelected; saveItem.hidden = !sel || !cbu.getPrefs("Save.SelectionToFile"); editorItem.hidden = !sel || !cbu.getPrefs("Save.TextToEditor"); }, false, contextMenu); // удалять новые пункти при изменениях .... addDestructor(()=> { saveItem.remove(); editorItem.remove(); }); })(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open")); // Сохранить или добавить выделенный текст в файл в папке загрузок, если назначена, // иначе на Рабочий стол ............. function saveSelectionToFile() { var line = ".".repeat(62) + "\n"; var hint = "Нажмите чтобы открыть файл"; var prfx = "Выбранный текст сохранен в файл "; var img = self.getAttribute("image"); var desk = Services.dirsvc.get("Desk", Ci.nsIFile); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveSelectionToFile = async () => { var time = aDate(), url = gBrowser.currentURI.displaySpec; var text = `${line}${getTabLabel()} - ${time}\n${url}\n\n${ gContextMenu.contentData.selectionInfo.fullText }\n\n\n`; try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); var msg = prfx + "в папку " + file.leafName; await IOUtils.makeDirectory(file.path); } catch(ex) { file && Cu.reportError(ex); file = desk.clone(); var msg = prfx + "на рабочий стол"; } file.append(`Save - ${time}.txt`); await IOUtils.writeUTF8(file.path, text, {mode: file.exists() ? "append" : "create"}); var name = "sstf-" + Cu.now(); as.showAlertNotification( gBrowser.selectedTab.image || img, msg, hint, true, "", (s, t) => t == "alertclickcallback" && file.launch(), name ); setTimeout(as.closeAlert, 8e3, name); })(); }; // Создать текстовой файл с выбранным текстом в папке загрузок, если назначена, // иначе на Рабочий стол, и открыть в редакторе ... function textToEditor() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelect', function listener(message) { // создать текст для записи var text = convertFromUnicode("UTF-8", message.data); try {var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {file = Services.dirsvc.get("Desk", Ci.nsIFile);} file.append("TextToEditor.txt"); custombuttonsUtils.writeFile(file.path, text); file.launch(); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }; // Конвертировать текст в юникод ... function convertFromUnicode(charset, str) { var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = charset; str = converter.ConvertFromUnicode(str); return str + converter.Finish(); }; // Получить название вкладки без не сохраняемых символов и лишних пробелов ... function getTabLabel() { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); }; ((main, parts) => this.onmousedown = e => { if (e.button) return; this.onmousedown = null; var df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity' d='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity' d='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить видимую часть как PNG" value="page"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M11.108 8.852c.327 0 .591-.27.591-.602a.596.596 0 0 0-.59-.602c-.327 0-.591.27-.591.602 0 .332.264.602.59.602z'/><path d='M4.808 7.047c0-.665.53-1.203 1.182-1.203h6.3c.652 0 1.18.538 1.18 1.203v4.01c0 .665-.528 1.203-1.18 1.203h-6.3a1.192 1.192 0 0 1-1.182-1.203v-4.01zm1.182 0v3.524l1.639-1.808a.972.972 0 0 1 1.446 0l2.074 2.287-.008.007h1.149v-4.01h-6.3zm2.362 2.691-1.195 1.32h2.39l-1.195-1.32z'/><path d='M3.036 1.833C1.406 1.833.083 3.18.083 4.841v6.818c0 1.661 1.323 3.008 2.953 3.008h9.844c1.631 0 2.953-1.347 2.953-3.008V4.84c0-1.661-1.322-3.008-2.953-3.008H3.036zM1.265 4.841c0-.997.793-1.805 1.771-1.805h9.844c.979 0 1.772.808 1.772 1.805v6.818c0 .997-.793 1.805-1.772 1.805H3.036c-.978 0-1.771-.808-1.771-1.805V4.84z'/></g></svg>" label="Сохранить выбранный элемент как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M2.63 1.255c-.76 0-1.375.616-1.375 1.375v2.685a.625.625 0 0 1-1.25 0V2.63A2.625 2.625 0 0 1 2.63.005h2.685a.625.625 0 1 1 0 1.25H2.63ZM10.06.63c0-.345.28-.625.625-.625h2.685a2.625 2.625 0 0 1 2.625 2.625v2.685a.625.625 0 1 1-1.25 0V2.63c0-.76-.616-1.375-1.375-1.375h-2.685A.625.625 0 0 1 10.06.63Zm5.31 9.43c.345 0 .625.28.625.625v2.685a2.625 2.625 0 0 1-2.625 2.625h-2.685a.625.625 0 1 1 0-1.25h2.685c.76 0 1.375-.616 1.375-1.375v-2.685c0-.345.28-.625.625-.625ZM2.729 7.3c-.79 0-1.43.64-1.43 1.429v4.542c0 .79.64 1.43 1.43 1.43H7.27c.79 0 1.43-.64 1.43-1.43V8.73c0-.79-.64-1.43-1.43-1.43H2.73ZM0 8.728A2.729 2.729 0 0 1 2.729 6H7.27A2.729 2.729 0 0 1 10 8.729v4.542A2.729 2.729 0 0 1 7.271 16H2.73A2.729 2.729 0 0 1 0 13.271V8.73Z' clip-rule='evenodd'/><path d='M6.9 14.005H2.73a.5.5 0 0 1-.372-.835l2.085-2.317a.5.5 0 0 1 .744 0l2.085 2.317a.5.5 0 0 1-.371.835ZM8 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/></svg>" label="Сохранить выбранную область как PNG" value="clipping"/> </menugroup> `); var menugroup = df.firstChild; menugroup.setAttribute("context", ""); menugroup.handleCommand = e => { var name = _id + ":DataURLReady"; main = main.replace("%MESSAGE_NAME%", name); var urls = {}, configurable = true, enumerable = true; Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, { configurable, enumerable, get() { var value = `data:;charset=utf-8,({${ encodeURIComponent(main + part) }%0A}).init("${key}")`; Object.defineProperty(urls, key, {configurable, enumerable, value}); return value; }})); var getTabLabel = () => { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); } var listener = msg => { var fp = makeFilePicker(); fp.init(window.browsingContext, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); fp.defaultString = getTabLabel() + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; var wbp = makeWebBrowserPersist(), args = [ Services.io.newURI(msg.data), document.nodePrincipal, null, null, null, null, fp.file, null ]; //wbp.saveURI.length == 9 && splice(args); var {length} = wbp.saveURI; length >= 9 && splice(args); length == 10 && args.splice(3, 0, null); wbp.saveURI(...args); }); } var splice = arr => { var fox74 = parseInt(Services.appinfo.platformVersion) >= 74; var args = [fox74 ? 7 : 2, 0, fox74 ? Ci.nsIContentPolicy.TYPE_IMAGE : null]; (splice = arr => arr.splice(...args))(arr); } messageManager.addMessageListener(name, listener); addDestructor(() => messageManager.removeMessageListener(name, listener)); (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager .loadFrameScript(urls[e.target.value], false) )(e); } menugroup.addEventListener("command", e => menugroup.handleCommand(e)); menuPopup.querySelector('menuitem[label*="ярлык"]').after(df); })(` init(cmd) { cmd.startsWith("c") ? this[cmd].init(this[cmd].parent = this) : this[cmd](); }, capture(win, x, y, width, height) { var canvas = win.document.createElementNS("${xhtmlns}", "canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); var tryDraw = ind => { try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")} catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);} } tryDraw(17); sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png")); }, `, { all: `all() { var win = content; this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }`, page: `page() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }`, clipping: `clipping: { handleEvent(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type) { case "mousedown": this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + "px"; this.bs.top = this.downY + "px"; this.body.appendChild(this.box); this.flag = true; break; case "mousemove": if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + "px"; if (this.downY > this.moveY) this.bs.top = this.moveY + "px"; this.bs.width = Math.abs(this.moveX - this.downX) + "px"; this.bs.height = Math.abs(this.moveY - this.downY) + "px"; break; case "mouseup": this.uninit(); break; } }, init() { var win = {}; Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, win); this.win = win.value; this.doc = this.win.document; this.body = this.doc.body; if (!HTMLBodyElement.isInstance(this.body)) { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement("div"); this.bs = this.box.style; this.bs.border = "#0f0 dashed 2px"; this.bs.position = "absolute"; this.bs.zIndex = "2147483647"; this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor; this.body.style.cursor = "crosshair"; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.parent.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }`, click: `click: { getPosition() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win, Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft, Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop, parseInt(rect.width), parseInt(rect.height) ]; }, highlight() { this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false; this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;"; }, lowlight() { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute("style"); }, handleEvent(e) { switch(e.type){ case "click": if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); this.parent.capture.apply(this, this.getPosition()); this.uninit(); break; case "mouseover": if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }` });
/** @UCF @param {"prop":"JsBackground"} @UCF */ // Кнопка Save - Основной скрипт в Save_Script.js // Правка Vitaliy V. 2505 // Предыдущая версия // https://forum.mozilla-russia.org/viewtopic.php?pid=809376#p809376 (async () => CustomizableUI.createWidget({ id: "ucf-cbbtn-Save", tooltiptext: "Сохранить страницу\n/ часть / выбранное", nameSaveScript: "Save_Script.js", localized: false, cbu: { types: { 128: "Bool", boolean: "Bool", 64: "Int", number: "Int", 32: "String", string: "String" }, getPrefs(pref) { try { return Services.prefs[`get${ this.types[Services.prefs.getPrefType(pref)] }Pref`](pref); } catch {return null;} }, setPrefs(pref, val) { Services.prefs[`set${this.types[typeof val]}Pref`](pref, val); } }, gClipboard: { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard); } }, custombuttonsUtils: { writeFile(path, data) { try { if (path.includes(":\\")) path = path.replace(/\//g, "\\"); var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); file.exists() && file.remove(false); var strm = Cc["@mozilla.org/network/file-output-stream;1"] .createInstance(Ci.nsIFileOutputStream); strm.init(file, 0x04 | 0x08, 420, 0); strm.write(data, data.length); strm.flush(); strm.close(); } catch(ex) { Cu.reportError("Custom Buttons: " + [path, "---", ex, ex.stack].join("\n")); } } }, addDestructor(destructor, context) { this._destructors.push({destructor, context}); }, addEventListener(...args) { var trg = args[3]; if (!trg) trg = args[3] = this.ownerGlobal; trg.addEventListener(...args); this._handlers.push(args); }, onCreated(btn) { var win = btn.ownerGlobal; btn._handlers = new win.Array(); btn._destructors = new win.Array(); win.addEventListener("unload", this, {once: true}); btn.self = btn; btn._id = this.id; btn.cbu = this.cbu; btn.xhtmlns = "http://www.w3.org/1999/xhtml"; btn.addDestructor = this.addDestructor.bind(btn); btn.addEventListener = this.addEventListener.bind(btn); btn.gClipboard = this.gClipboard; btn.custombuttonsUtils = this.custombuttonsUtils; Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/cs/${this.nameSaveScript}`, btn); btn.setAttribute("image", this.image); }, get image() { var img = `${this.id.toLowerCase()}-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")); delete this.image; return this.image = `resource://${img}`; }, handleEvent(e) { var btn = e.target.getElementById(this.id); for(var args of btn._handlers) args.pop().removeEventListener(...args); delete btn._handlers; for(var {destructor, context} of btn._destructors) try {destructor.call(context, "destructor");} catch(ex) {Cu.reportError(ex);} delete btn._destructors; } }))();
/** @UCF @param {"prop":"JsBackground","disable":true} @UCF */ (async () => CustomizableUI.createWidget({ id: "ucf-cbbtn-Save", tooltiptext: "Сохранить", localized: false, get initCode() { var count = 0; var prfx = "ucf-cbbtn-save-resurl-"; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var ss = url => { var subst = prfx + ++count; rph.setSubstitution(subst, Services.io.newURI(url)); return "resource://" + subst; } this.image = ss("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); var arr = [ "@-moz-document url(chrome://browser/content/browser.xhtml) {", ` #${this.id} menuitem, #content-baseItem, #content-saveItem, #content-editorItem {`, " fill: currentColor !important;", " -moz-context-properties: fill, fill-opacity !important;", " }", "}", "}" ]; var url = "data:text/css;charset=utf-8," + encodeURIComponent(arr.join("\n")); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(Services.io.newURI(ss(url)), sss.USER_SHEET); delete this.initCode; return this.initCode = Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/cs/Save_Script.js" )) .replace(/data:image\/svg[^"]+/g, ss); }, cbu: { types: { 128: "Bool", boolean: "Bool", 64: "Int", number: "Int", 32: "String", string: "String" }, getPrefs(pref) { try { return Services.prefs[`get${ this.types[Services.prefs.getPrefType(pref)] }Pref`](pref); } catch {return null;} }, setPrefs(pref, val) { Services.prefs[`set${this.types[typeof val]}Pref`](pref, val); } }, gClipboard: { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard); } }, custombuttonsUtils: { writeFile(path, data) { try { if (path.includes(":\\")) path = path.replace(/\//g, "\\"); var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); file.exists() && file.remove(false); var strm = Cc["@mozilla.org/network/file-output-stream;1"] .createInstance(Ci.nsIFileOutputStream); strm.init(file, 0x04 | 0x08, 420, 0); strm.write(data, data.length); strm.flush(); strm.close(); } catch(ex) { Cu.reportError("Custom Buttons: " + [path, "---", ex, ex.stack].join("\n")); } } }, addDestructor(destructor, context) { this._destructors.push({destructor, context}); }, addEventListener(...args) { var trg = args[3]; if (!trg) trg = args[3] = this.ownerGlobal; trg.addEventListener(...args); this._handlers.push(args); }, onCreated(btn) { var win = btn.ownerGlobal; btn._handlers = new win.Array(); btn._destructors = new win.Array(); win.addEventListener("unload", this, {once: true}); new win.Function( "self,_id,cbu,xhtmlns,addDestructor,addEventListener,gClipboard,custombuttonsUtils", this.initCode ).call( btn, btn, this.id, this.cbu, "http://www.w3.org/1999/xhtml", this.addDestructor.bind(btn), this.addEventListener.bind(btn), this.gClipboard, this.custombuttonsUtils ); btn.setAttribute("image", this.image); }, handleEvent(e) { var btn = e.target.getElementById(this.id); for(var args of btn._handlers) args.pop().removeEventListener(...args); delete btn._handlers; for(var {destructor, context} of btn._destructors) try {destructor.call(context, "destructor");} catch(ex) {Cu.reportError(ex);} delete btn._destructors; } }))();
Добавлено Вчера 16:07:18
https://imgsh.net/i/794afa4da1
Отредактировано xrun1 (Вчера 16:07:18)
Отсутствует
Если в секции с PNG заменить иконки на svg, отображаться не будут.
Попробовал. В консоли две ошибки: Ошибка синтаксического анализа XML и Uncaught Error: not well-formed XML.
Что с этим делать я не знаю. Может знатоки подскажут.
Отредактировано unter_officer (Вчера 17:12:31)
«The Truth Is Out There»
Отсутствует
Может, куки прицепились? У меня на сайте правильно переводит.
Попробовал из абсолютно нового профиля (причём в этом профиле и набор предпочитаемых языков другой, и даже язык интерфейса программы). Результат такой же, как и раньше.
Может, у Google ещё и какие-то географические привязки есть?
Из любопытства попробовал ту же фразу перевести ещё несколькими переводчиками. Получил:
В общем, "не Гуглом единым..."
Отредактировано yup (Вчера 17:34:19)
Отсутствует
Если в секции с PNG заменить иконки на svg, отображаться не будут
Я в другом скрипте с этим столкнулся, конвертируйте файл svg в base.
У меня какой-то промежуточный этап
Выложите его, может смогу скрестить. А то вчера поковырял, там непонятная для меня формула или ее отсутствие.
Перевод реально уг, раньше в Simple Translate нормальный был, а теперь так же.
Отсутствует
Менял сегодня иконки в кнопке Save_Script.js и столкнулся с проблемой. Если в секции с PNG заменить иконки на svg, отображаться не будут. В этом виновата кнопка Save_Button.js.
замените в своем Save_Script.js
на
((main, parts) => this.onmousedown = e => { if (e.button) return; this.onmousedown = null; const icon1 = encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity' d='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>`); const icon2 = encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M11.108 8.852c.327 0 .591-.27.591-.602a.596.596 0 0 0-.59-.602c-.327 0-.591.27-.591.602 0 .332.264.602.59.602z'/><path d='M4.808 7.047c0-.665.53-1.203 1.182-1.203h6.3c.652 0 1.18.538 1.18 1.203v4.01c0 .665-.528 1.203-1.18 1.203h-6.3a1.192 1.192 0 0 1-1.182-1.203v-4.01zm1.182 0v3.524l1.639-1.808a.972.972 0 0 1 1.446 0l2.074 2.287-.008.007h1.149v-4.01h-6.3zm2.362 2.691-1.195 1.32h2.39l-1.195-1.32z'/><path d='M3.036 1.833C1.406 1.833.083 3.18.083 4.841v6.818c0 1.661 1.323 3.008 2.953 3.008h9.844c1.631 0 2.953-1.347 2.953-3.008V4.84c0-1.661-1.322-3.008-2.953-3.008H3.036zM1.265 4.841c0-.997.793-1.805 1.771-1.805h9.844c.979 0 1.772.808 1.772 1.805v6.818c0 .997-.793 1.805-1.772 1.805H3.036c-.978 0-1.771-.808-1.771-1.805V4.84z'/></g></svg>`); const icon3 = encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M2.63 1.255c-.76 0-1.375.616-1.375 1.375v2.685a.625.625 0 0 1-1.25 0V2.63A2.625 2.625 0 0 1 2.63.005h2.685a.625.625 0 1 1 0 1.25H2.63ZM10.06.63c0-.345.28-.625.625-.625h2.685a2.625 2.625 0 0 1 2.625 2.625v2.685a.625.625 0 1 1-1.25 0V2.63c0-.76-.616-1.375-1.375-1.375h-2.685A.625.625 0 0 1 10.06.63Zm5.31 9.43c.345 0 .625.28.625.625v2.685a2.625 2.625 0 0 1-2.625 2.625h-2.685a.625.625 0 1 1 0-1.25h2.685c.76 0 1.375-.616 1.375-1.375v-2.685c0-.345.28-.625.625-.625ZM2.729 7.3c-.79 0-1.43.64-1.43 1.429v4.542c0 .79.64 1.43 1.43 1.43H7.27c.79 0 1.43-.64 1.43-1.43V8.73c0-.79-.64-1.43-1.43-1.43H2.73ZM0 8.728A2.729 2.729 0 0 1 2.729 6H7.27A2.729 2.729 0 0 1 10 8.729v4.542A2.729 2.729 0 0 1 7.271 16H2.73A2.729 2.729 0 0 1 0 13.271V8.73Z' clip-rule='evenodd'/><path d='M6.9 14.005H2.73a.5.5 0 0 1-.372-.835l2.085-2.317a.5.5 0 0 1 .744 0l2.085 2.317a.5.5 0 0 1-.371.835ZM8 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/></svg>`); const df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,${icon1}" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,${icon1}" label="Сохранить видимую часть как PNG" value="page"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,${icon2}" label="Сохранить выбранный элемент как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,${icon3}" label="Сохранить выбранную область как PNG" value="clipping"/> </menugroup> `);
Отредактировано egorsemenov06 (Вчера 20:51:47)
Отсутствует
Там eval есть, не знаю, будет ли работать не 139. То, что закомментировал - убирать не стал. Там есть ссылки, почему и откуда.
// https://forum.mozilla-russia.org/viewtopic.php?pid=780231#p780231 // мой пост с этой версией https://forum.mozilla-russia.org/viewtopic.php?pid=807350#p807350 (this.googletranslate = { init(that) { var lc = navigator.lastClick = {}, w = null, xhtmlns = 'http://www.w3.org/1999/xhtml'; var mouseUp = (e) => { if (e.button) return; lc.X = e.screenX - mozInnerScreenX; lc.Y = e.screenY - mozInnerScreenY; }; gBrowser.tabpanels.addEventListener('mouseup', mouseUp, false); /* https://forum.mozilla-russia.org/viewtopic.php?pid=812525#p812525 this.destructor = () => { gBrowser.tabpanels.removeEventListener('mouseup', mouseUp, false); if (w) w.closeWin(); }; that.unloadlisteners.push("googletranslate"); */ // правка для деструктора из ссылки выше setUnloadMap("googletranslate", () => { gBrowser.tabpanels.removeEventListener("mouseup", mouseUp, false); w?.closeWin(); }); var createWindow = function(text, status, title, id, pos, size) { var win = window, doc = win.document, wId = 'ujs_window'+(id || ''); w = doc.getElementById(wId); var keyDown = function(e) {if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin();}; var mouseDown = function() {doc.getElementById(wId).closeWin();}; if (w) w.closeWin(); w = doc.createElementNS(xhtmlns, 'div'); w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:2px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#eaeaea;padding-top:0px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");')); w.id = wId; w.closeWin = function() { doc.removeEventListener('keydown', keyDown, false); gBrowser.tabpanels.removeEventListener('mousedown', mouseDown, false); this.parentNode.removeChild(this); w = null; }; w.addEle = function(str, style) { var ele = doc.createElementNS(xhtmlns, 'div'); ele.setAttribute('style', style); if (str) { ele.innerHTML = str; for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) { el.parentNode.removeChild(el); } else { for (var att = el.attributes, j = att.length; j--;) { if (/^on[a-z]+$/i.test(att[j].name))att[j].value = ''; } } } } return this.appendChild(ele); }; /* https://forum.mozilla-russia.org/viewtopic.php?pid=807299#p807299 w.addEle1 = function(str, style) { var ele = doc.createElementNS(xhtmlns, 'textarea'); ele.setAttribute('style', style); if (str) { ele.innerHTML = str; for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) { el.parentNode.removeChild(el); } else { for (var att = el.attributes, j = att.length; j--;) { if (/^on[a-z]+$/i.test(att[j].name))att[j].value = ''; } } } } return this.appendChild(ele); }; */ var img = doc.createElementNS(xhtmlns, 'div'); img.setAttribute('style', 'display:block;float:right;width:16px;height:16px;padding:0;margin-top:2px;margin-right:1px;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACQUlEQVR4Xm2SPUhbURTHfzfNJ4nU0Axx7CJCN2kQtIgVCtq6OdQuBUftWIQqFNsKDo6iHTqIqN3a0kklUKTS2AZrcOjioFtRjFWUfH+803cS9GHwB4dzcu75/+8L9xgaSEDbLXhaASzAyXAMn5/DHxwwjeJgKLRxd3Q0atxuLhGgWqmQmp9PJ7LZJ5Ow3WhQFweDG20LC1FfRwc3kUsm+T48fPIzl3s8VTdxxLt+/2FhdlZkc1MkmdR8Pba2ajlrz3z1+9OvIOaIfb7DwsSEyNKSyM6OSLksEo/rbw2ttadntV7Gnv3k86VfqskvmDzv7hZ580Zkelrk4kJqFIsii4satVrRs+rYmBQHBuRvS4u8g/fuCmDOz+HgAIWpKRgfh3AYhoZQ8Hqxjo4o9PdT3d1FcQEl8KoBnJ7C/j6KZkZGYG4OIhEUFed7erD29q69jGrd1qVBqcQVKgwEuMSEQhjtXRk4JvW/kM1i2WGMga4uzMoKBIOIfbNiolEC6+uU+/qQRALFA1QBlwVYxmBcLmhuxqytQSgEKu7t1dBavwKvbeINh/Has2IMqnXpem4bky6qWLdvZgaOj2FwEHNyoqG19vRMZ8jZs1+NOfsNcZS3EFvzeNL51laRe/dEYrFadsLpZeyZDx7P6QN4Btwx1OE1xO4HAquP2tsjAZ+Pm8gWi3xMpc6W8/kXPyAO/DM4oOsZa2pafdjZGXF7PAgOpXKZL4nE2XImcyUGMDSg63kbhgvgtYCq8+akIL4J3y7Fyn+DokZOnLlMyQAAAABJRU5ErkJggg==");background:-o-skin("Caption Close Button Skin");'); img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close'; img.addEventListener('click', function() {this.parentNode.closeWin();}, false); w.appendChild(img); var title = w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;'); title.onclick = e => { e.preventDefault(); var url = e.target.href; // Здесь открываем url как хотим. var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); doc.getElementById(wId).closeWin(); }; /* https://forum.mozilla-russia.org/viewtopic.php?pid=807299#p807299 var cnt = w.addEle1(text, 'display:block;border:1px solid #aaa;padding-bottom:3px;padding-left:3px;background-color:#fafcfe;color:#000;font:16px Times New Roman;width:310px;height:160px;overflow:auto;cursor:text;-moz-user-focus:normal;-moz-user-select:text;'); cnt.contentEditable="true"; cnt.context="contentAreaContextMenu"; */ var cnt = doc.createElement("textarea"); cnt.style.cssText = ` color: #000; width: 310px; height: 160px; outline: none; padding-left: 3px; padding-bottom: 3px; border: 1px solid #aaa; background-color: #fafcfe; font: 17px Times New Roman; `; // if (text) cnt.value = text; --> if (text) cnt.value = text.trim(); if (text) cnt.value = text.trim(); w.append(cnt); w.addEle(status, 'display:table;font:12px Times New Roman;font-weight:bold;color:blue;width:auto;height:auto;padding-top:2px;margin:0 3px;cursor:pointer;'); w.addEventListener('mousedown', function(e) { if (e.target == w) { e.preventDefault(); /* https://forum.mozilla-russia.org/viewtopic.php?pid=807257#p807257 var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top); var mouseMove = function(ev) { w.style.left = origX+ev.clientX-grabX+'px'; w.style.top = origY+ev.clientY-grabY+'px'; }; */ var st = w.style; var mouseMove = e => { st.top = parseInt(st.top) + e.movementY + "px"; st.left = parseInt(st.left) + e.movementX + "px"; } doc.addEventListener('mousemove', mouseMove, false); doc.addEventListener('mouseup', function() {doc.removeEventListener('mousemove', mouseMove, false);}, false); } }, false); doc.documentElement.appendChild(w); if (size) { cnt.style.height = size.height; cnt.style.width = size.width; } else { for (var i = 3; i < 10; i++) { if (cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth) { cnt.style.height = 80*i+'px'; cnt.style.width = 160*i+'px'; } else break; } } var docEle = (doc.compatMode == 'CSS1Compat' && win.postMessage) ? doc.documentElement : doc.body; var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight; if (mX < 0) {cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0;} if (mY < 0) {cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0;} var hW = parseInt(w.offsetWidth/2); w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px'; w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px'; w.style.visibility = 'visible'; doc.addEventListener('keydown', keyDown, false); gBrowser.tabpanels.addEventListener('mousedown', mouseDown, false); // https://forum.mozilla-russia.org/viewtopic.php?pid=807326#p807326 if (text) { var st = cnt.style; var div = cnt.editor.rootElement; var range = new Range(); range.selectNode(div.firstChild); var rect = range.getBoundingClientRect(); let w = Math.ceil(rect.width); if (cnt.scrollTopMax) { if (!matchMedia("(-moz-overlay-scrollbars)").matches) // ??? w += InspectorUtils.getChildrenForNode(div, true, false).at(-1).clientWidth; } else st.height = Math.max(50, Math.ceil(rect.height) + 1) + "px"; // к строке выше; изменить, если font-size > 22 https://forum.mozilla-russia.org/viewtopic.php?pid=807332#p807332 st.width = Math.max(200, w) + "px"; } return w; }; var getHash = function (txt) { TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())'); function sM(a) { var b; if (null !== yr) b = yr; else { b = wr(String.fromCharCode(84)); var c = wr(String.fromCharCode(75)); b = [b(), b()]; b[1] = c(); b = (yr = window[b.join(c())] || "") || ""; } var d = wr(String.fromCharCode(116)), c = wr(String.fromCharCode(107)), d = [d(), d()]; d[1] = c(); c = "&" + d.join("") + "="; d = b.split("."); b = Number(d[0]) || 0; for (var e = [], f = 0, g = 0; g < a.length; g++) { var l = a.charCodeAt(g); 128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023), e[f++] = l >> 18 | 240, e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224, e[f++] = l >> 6 & 63 | 128), e[f++] = l & 63 | 128); } a = b; for (f = 0; f < e.length; f++) a += e[f], a = xr(a, "+-a^+6"); a = xr(a, "+-3^+b+-f"); a ^= Number(d[1]) || 0; 0 > a && (a = (a & 2147483647) + 2147483648); a %= 1E6; return c + (a.toString() + "." + (a ^ b)); } var yr = null; var wr = function(a) { return function() { return a; }; }, xr = function(a, b) { for (var c = 0; c < b.length - 2; c += 3) { var d = b.charAt(c + 2), d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d), d = "+" == b.charAt(c + 1) ? a >>> d : a << d; a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d; } return a; }; return sM(txt); }; var ujs_google_translate = function (dir) { var lng = window.navigator.language.slice(0, 2), txt = gContextMenu.selectionInfo.fullText, l = dir.split('|'); var encTxt = encodeURIComponent(txt); var winWait = function(lng) {createWindow('', (lng == 'ru' ? 'Подождите идет перевод' : 'Wait, is going Translating')+'\u2026', 'Google Translate', '_gt', window.navigator.lastClick);}; if (txt) { winWait(lng); var xhr = new XMLHttpRequest(); var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt); // для urlt изменил http --> https (14.10.2023); тестирую var urlt = "https://translate.google.com/translate_t?text=" + encTxt + "&sl=' + langFrom_google_text + '&tl=' + langTo_google_text +'&hl=' + lng + '&eotf=0&ujs=gtt"; xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); xhr.onreadystatechange = function() { try { if (xhr.readyState == 4 && xhr.status == 200) { // var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />")); var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "")); for (var i = 0, n; n = tmp[0][i]; i++) { if (n[0])result += n[0].toString(); }; status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase(); createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick); } } catch(e) {}; }; xhr.send('q=' + encodeURIComponent(txt)); } else { var urlt = gBrowser.currentURI.spec; // Изменил строку ниже. Добавил параметр '&tl='+l[1] https://forum.mozilla-russia.org/viewtopic.php?pid=796999#p796999 & http --> https (14.10.2023) var url = "https://translate.google.com/translate?u=" + encodeURIComponent(urlt) + '&tl=' + l[1] + "&hl=" + lng + "&langpair=" + dir + "&tbb=1"; var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); }; }; var contextMenu = document.getElementById("contentAreaContextMenu"); var nextEleMenu = document.getElementById("context-inspect"); var menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", "context-ru-google-translate"); menuItem.setAttribute("label", "Перевести на русский"); menuItem.setAttribute("class", "menuitem-iconic"); menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABBUlEQVR4Ac2RMU4DMRREB2MqihQpAkUaqnAduuQw4Sx03CGcJYIiDYqQ0lCsZ77535ZFcgAkRuPvV7zd/dLiz3N1PFb8hmRckrfELZrF9ONQ1B6Yz0MyM7S0O6zGkVprh/3+Kw/JzkHSpRpJKZkpr9fYbOx0cjVsCbWG31oHBM9mtt0q73ZcrdLhAMlYQKkUI22aqsNo8HKZAMQhvVaKSHWj2Q2aPU3mJQFY7nuHyvYFduP83WF3AJRfcPNYnr/Lp1G1uK4m9sno1LaUbnX/htf8BNzoneUD5NhjvLCMhURQSQ93QCZwXYjFwg3I0NZKrvoknQPMIHkt/jRAQKMeG2yX89/mB4EJbKbZxIhFAAAAAElFTkSuQmCC"); menuItem.addEventListener("command", function() {ujs_google_translate('auto|ru');}, false); contextMenu.insertBefore(menuItem, nextEleMenu); menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", "context-en-google-translate"); menuItem.setAttribute("label", "Перевести на английский"); menuItem.setAttribute("class", "menuitem-iconic"); menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAB5UlEQVR4AWOgPZg0c9+Oq2+qpx9LaQaiw4mNB27efbs2uXFNQh2Q4Zm9zSNth23MhqjGnXMC86vnHmUS4udxv7OvOd2yPE7PTlfCTk9GVVEoyJA7WI8dyPA0k3U1l+jJMV7CeThpTZeoKDdDUsvBPSff/V+6/P/Bvf///2+bdvU/EKRm/k9IBNIlfZe+LFrzvbsbyJ636pKkyQyQhoUb7tZNvPpw3/0/TfX/ISAm5n94BIiRm/n/xYsLd946ei4vajoiqDuRAejQf//+o4PQ0P9+fmhiQGVnrr1kXJNYG2zEzXDxDsPv3wy/fkFJoOTPn39+/fr/69e/37//AUX+/mXRkO458wWHDba2f8wswCyQ3N+/f//8/fP7z5+TV18w2Mdt6plzPiptx5Wr7/+/ffMzOR6kysjkt74hWMPfp06O+2dulZCeFZKwnkE4m8E8bN3i9aCQ+dxY96GrK6bkGJD9R1v3l6Y20NVW9kt+/v//ZdbcFwkxTVPPMQimM8XEqkb7a/zoqLxkH9v4zVyI5+///wyMmtKMmhJAnbLqQjHxaw5r2orOmZN5uj470Zahat6BKS7JzpmLBHXm8GhM5lCdcP7ai1ZpixZxk9NXXjKIFzOIFjAI54oY1vXuue5qmscw+AAAW0tKxtPoicEAAAAASUVORK5CYII="); menuItem.addEventListener("command", function() {ujs_google_translate('auto|en');}, false); contextMenu.insertBefore(menuItem, nextEleMenu); contextMenu.insertBefore(document.createXULElement("menuseparator"), nextEleMenu); } }).init(this);
Добавлено Вчера 19:59:17
unter_officer
Скрестить ужа и ежа: старая кнопка из custom_script.js + новый скрипт. Я буду пока так делать, конвертировать иконки не хочу. Когда отвалится - буду здесь плакаться.
Отредактировано xrun1 (Вчера 19:59:17)
Отсутствует