А вот поиск по картинке жалко.
Но есть же расширения для такого поиска. Например, Search by Image
Отсутствует
tabcounter
Переделал вывод числа вкладок в кнопку extensions-button, так проще и не занимает место в строке адреса:
(async btn => { await document.documentReadyForIdle; btn.setAttribute("badged", true); btn.setAttribute("badgeStyle", "color: white; background-color: blue"); btn.textContent = ""; btn.render(); var tid, lab = () => { tid = null; btn.setAttribute("badge", String(gBrowser.tabs.length)); } var count = () => { tid && clearTimeout(tid); tid = setTimeout(lab, 500); } lab(); var tc = gBrowser.tabContainer; tc.addEventListener("TabOpen", count); tc.addEventListener("TabClose", count); ucf_custom_scripts_win.setUnloadMap(Symbol(), () => { tc.removeEventListener("TabOpen", count); tc.removeEventListener("TabClose", count); }, this); })(document.getElementById("unified-extensions-button"));
Отсутствует
_zt, yup
Расширения есть, но мы же в теме про UCF. И работало ещё в 137-й.
https://imgsh.net/i/f5d4611f8c
https://imgsh.net/i/86991739bd
UPD: А "кривенько" там гугл ищет.
Отредактировано xrun1 (10-05-2025 19:52:59)
Отсутствует
Расширения есть, но мы же в теме про UCF. И работало ещё в 137-й.
Ткнуть пальчиком в существующее расширение я могу, а помочь со 138-ым Firefox - нет. "Будете у нас в 52-м - заходите."
Отредактировано yup (10-05-2025 21:04:16)
Отсутствует
Dobrov
Вы же разбираетесь в скриптах. Подскажите пожалуйста, как в этой конструкции избавиться от eval с сохранением функционала?
var save = eval(`(function ${gContextMenu.saveMedia})`.replace("\n false, // don't", "\n true, //"));
Это из скрипта, который я выкладывал чуть выше.
«The Truth Is Out There»
Отсутствует
Будете у нас в 52-м - заходите
Я в курсе. Жалуюсь по привычке: вдруг кто-нибудь теоретическим советом поможет?
P.S. Автор UCF читает форум, как я понимаю. На заметку: слиплись название и кнопка, профиль чистый.
https://imgsh.net/i/1a35d31e3b
https://github.com/VitaliyVstyle/VitaliyVstyle.github.io/blob/main/UserChromeFiles/FullTheme/chrome/user_chrome_files/custom_scripts/menusrestartitems.js
Отсутствует
Подскажите пожалуйста, как в этой конструкции избавиться от eval с сохранением функционала?
Один из вариантов - взять текст функции saveMedia() (он маленький) и целиком задействовать в своём скрипте, проделав в нём ту же замену.
Конечно, в какой-нибудь будущей версии FF работа может поломаться, но она и так ломаeтся.
Отредактировано yup (10-05-2025 23:44:34)
Отсутствует
Похоже, что про скрипты потихоньку можно забывать.
Судя по всему, после ухода с форума Dumby и Виталия, других альтруистов, среди знатоков по скриптам, нет и помощи больше ждать не от кого.
Вместо первого есть ClickPicSave.mjs: Сохранить картинку кликом колёсика или перетащив вправо; Двойной клик поиск похожих в Яндекс.
Вы же разбираетесь в скриптах. Подскажите пожалуйста, как в этой конструкции избавиться от eval с сохранением функционала?
Здесь никак. А насчёт разбираетесь в скриптах -> я неплохо знаю Java-код и слабо понимаю Java-особенности и функции в Firefox, т.к. это практически целая операционная система.
Отредактировано Dobrov (Вчера 02:38:07)
Отсутствует
Вместо первого есть ClickPicSave.mjs: Сохранить картинку кликом колёсика или перетащив вправо; Двойной клик поиск похожих в Яндекс.
Любопытно. Но есть вопросики.
1. Зачем в папке, куда сохраняется картинка, дополнительно создается папка _Pics с вложенной в неё папкой по названию картинки и можно ли это как-то отключить?
2. Хотелось бы, чтобы картинка сохранялась с оригинальным названием (с тем именем, который ей дал владелец сайта), а не по title вкладки.
3. Мне поиск в Яндекс не нужен, для этого у меня есть другой скрипт и поэтому хотелось бы совсем убрать клик по колесу, а сохранение повесить на двойной клик.
«The Truth Is Out There»
Отсутствует
Зачем в папке, куда сохраняется картинка, дополнительно создается папка _Pics с вложенной в неё папкой по названию картинки и можно ли это как-то отключить?
Это подкатегории папок в загрузках, автосортировка сайтов и фото, т.к. часто имена фото не имеют смысла и их источник можно узнать лишь по имени вкладки.
Справку трудно не заметить в самом скрипте: «Html/subdir|Pics/subdir» subdir: пусто | 0 заголовок | 1 домен
Вместо Загрузок можно сохранять сайты и фото в подпапки с именем вкладки или url хоста.
Для отключения прописать пустую строку в опцию extensions.user_chrome_files.savedirs
Мне поиск в Яндекс не нужен, для этого у меня есть другой скрипт и поэтому хотелось бы совсем убрать клик по колесу, а сохранение повесить на двойной клик.
Двойной клик по фото на многих сайтах приводит к проблемам, поэтому я просил Dumby сделать именно клик колёсиком.
А если Вам что-то не нравится в чужих скриптах, то код для Яндекса легко убрать самому…
Отредактировано Dobrov (Вчера 06:46:37)
Отсутствует
Переделал вывод числа вкладок в кнопку extensions-button, так проще и не занимает место в строке адреса:
Просто инфо: счетчик вкладок реализуется css-стилем, без скрипта https://www.reddit.com/r/FirefoxCSS/com … _all_tabs/
Отсутствует
Подскажите пожалуйста, как в этой конструкции избавиться от eval с сохранением функционала?
Выделить кодКод:
var save = eval(`(function ${gContextMenu.saveMedia})`.replace("\n false, // don't", "\n true, //"));
Кстати, а в какой версии Firefox этот код вообще был рабочим?
У меня в примерно 70-й функция saveMedia() выглядит вот как:
saveMedia() { let doc = this.ownerDoc; let isContentWindowPrivate = this.isRemote ? this.ownerDoc.isPrivate : undefined; let referrerInfo = this.contentData.referrerInfo; let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.browser); if (this.onCanvas) { // Bypass cache, since it's a data: URL. this._canvasToBlobURL(this.target).then(function(blobURL) { internalSave( blobURL, null, // document "canvas.png", null, // content disposition "image/png", // _canvasToBlobURL uses image/png by default. true, // bypass cache "SaveImageTitle", null, // chosen data referrerInfo, null, // initiating doc false, // don't skip prompt for where to save null, // cache key isPrivate, document.nodePrincipal /* system, because blob: */ ); }, Cu.reportError); } else if (this.onImage) { urlSecurityCheck(this.mediaURL, this.principal); internalSave( this.mediaURL, null, // document null, // file name; we'll take it from the URL this.contentData.contentDisposition, this.contentData.contentType, false, // do not bypass the cache "SaveImageTitle", null, // chosen data referrerInfo, null, // initiating doc false, // don't skip prompt for where to save null, // cache key isPrivate, this.principal ); } else if (this.onVideo || this.onAudio) { var dialogTitle = this.onVideo ? "SaveVideoTitle" : "SaveAudioTitle"; this.saveHelper( this.mediaURL, null, dialogTitle, false, doc, referrerInfo, this.frameOuterWindowID, "", isContentWindowPrivate ); } }
Причём я посмотрел исходники нынешней версии (на сайте searchfox.org) - там текст функции уже несколько другой, но ситуация такая же - подлежащих изменению мест два:
saveMedia() { let doc = this.ownerDoc; let isPrivate = lazy.PrivateBrowsingUtils.isBrowserPrivate(this.browser); let referrerInfo = this.contentData.referrerInfo; let cookieJarSettings = this.contentData.cookieJarSettings; if (this.onCanvas) { // Bypass cache, since it's a data: URL. this._canvasToBlobURL(this.targetIdentifier).then(blobURL => { this.window.internalSave( blobURL, null, // originalURL null, // document "canvas.png", null, // content disposition "image/png", // _canvasToBlobURL uses image/png by default. true, // bypass cache "SaveImageTitle", null, // chosen data referrerInfo, cookieJarSettings, null, // initiating doc false, // don't skip prompt for where to save null, // cache key isPrivate, this.document.nodePrincipal /* system, because blob: */ ); }, console.error); } else if (this.onImage) { this.window.urlSecurityCheck(this.mediaURL, this.principal); this.window.internalSave( this.mediaURL, null, // originalURL null, // document null, // file name; we'll take it from the URL this.contentData.contentDisposition, this.contentData.contentType, false, // do not bypass the cache "SaveImageTitle", null, // chosen data referrerInfo, cookieJarSettings, null, // initiating doc false, // don't skip prompt for where to save null, // cache key isPrivate, this.principal ); } else if (this.onVideo || this.onAudio) { let defaultFileName = ""; if (this.mediaURL.startsWith("data")) { // Use default file name "Untitled" for data URIs defaultFileName = this.window.ContentAreaUtils.stringBundle.GetStringFromName( "UntitledSaveFileName" ); } var dialogTitle = this.onVideo ? "SaveVideoTitle" : "SaveAudioTitle"; this.saveHelper( this.mediaURL, null, dialogTitle, false, doc, referrerInfo, cookieJarSettings, this.frameOuterWindowID, defaultFileName, isPrivate ); } }
Так что решением для нынешнего FF может быть вот что: взять этот текст, поменять в нём две строки (с false на true), выбросить ненужный хвостик для звука и видео, и то, что останется, вставить вместо строки из вопроса как локальную функцию save() (чтобы в тексте кнопки больше ничего не менять):
function save() { let doc = this.ownerDoc; let isPrivate = lazy.PrivateBrowsingUtils.isBrowserPrivate(this.browser); let referrerInfo = this.contentData.referrerInfo; let cookieJarSettings = this.contentData.cookieJarSettings; if (this.onCanvas) { // Bypass cache, since it's a data: URL. this._canvasToBlobURL(this.targetIdentifier).then(blobURL => { this.window.internalSave( blobURL, null, // originalURL null, // document "canvas.png", null, // content disposition "image/png", // _canvasToBlobURL uses image/png by default. true, // bypass cache "SaveImageTitle", null, // chosen data referrerInfo, cookieJarSettings, null, // initiating doc true, // skip prompt for where to save null, // cache key isPrivate, this.document.nodePrincipal /* system, because blob: */ ); }, console.error); } else if (this.onImage) { this.window.urlSecurityCheck(this.mediaURL, this.principal); this.window.internalSave( this.mediaURL, null, // originalURL null, // document null, // file name; we'll take it from the URL this.contentData.contentDisposition, this.contentData.contentType, false, // do not bypass the cache "SaveImageTitle", null, // chosen data referrerInfo, cookieJarSettings, null, // initiating doc true, // skip prompt for where to save null, // cache key isPrivate, this.principal ); } }
Отредактировано yup (Вчера 13:13:47)
Отсутствует
Кстати, а в какой версии Firefox этот код вообще был рабочим?
Работал до 139 версии. И, если в 139 изменить параметр: security.allow_unsafe_dangerous_privileged_evil_eval -> true , то тоже прекрасно работает. Но как я говорил выше, изменять все эти параметры я не хочу.
взять этот текст, поменять в нём две строки (с false на true), выбросить ненужный хвостик для звука и видео, и то, что останется, вставить вместо строки из вопроса как локальную функцию save()
Это я сделал ещё до того, как попросил исправить скрипт. В целом работает, но есть нюансы.
Добавлено Вчера 15:54:21
А если Вам что-то не нравится в чужих скриптах, то код для Яндекса легко убрать самому…
Когда я сказал, что с уходом с форума Dumby и Виталия других альтруистов среди знатоков по скриптам не осталось, именно это я и имел ввиду. Либо пользуйся тем, что дают, либо делай сам.
Но все равно за скрипт большое спасибо. Если мой скрипт совсем загнется, то теперь есть альтернатива.
Отредактировано unter_officer (Вчера 15:54:34)
«The Truth Is Out There»
Отсутствует
Работал до 139 версии.
А вот непонятно. Судя по комментарию, этот параметр определяет, показывать диалог выбора места сохранения файла или нет. Но ведь код кнопки изменяет этот параметр только в том месте, которое срабатывает при сохранении содержимого canvas. А то место, которое срабатывает при сохранении обычной картинки, остаётся нетронутым. (Для него даже шаблон для поиска должен быть другим.)
Как же оно умудрялось в прежних версиях молча сохранять? Может, комментарий возле параметра не соответствует действительности, и на самом деле всё строго наоборот? Но тогда для картинок из файлов можно просто вызывать исходную функцию, не заморачиваясь на внесение в неё изменений.
И, если в 139 изменить параметр: security.allow_unsafe_dangerous_privileged_evil_eval -> true
Совершенно очевидно, что из браузера изживают возможность применять трюки, подобные тому, который используется в этой кнопке. А значит, и этот параметр через какое-то время отменят.
Однажды много лет назад мне тоже понадобилось сохранять уйму картинок - программно (из скрипта) и без запросов. Методы наподобие тех, что используются в кнопках CB, применить было нельзя, и тогда я изобрёл фокус с изменением параметров обработки MIME-типов браузером, после чего картинки стали сохраняться простым вызовом метода click() у них.
Чуть позже я избавился от необходимости редактировать MIME-типы (тогда это был файл mimeTypes.rdf, и его редактирование было занятием очень нудным). Вместо этого я стал просто подменять MIME-типы картинок в ответах браузера.
Отредактировано yup (Вчера 16:23:29)
Отсутствует
Возвращаясь к CB.
Взять текст браузерной функции, подправить его и заставить выполниться можно двумя способами:
1. Нынешний - запускать текст на исполнение через eval.
2. Засунуть изменённую функцию в браузер как полноценный скрипт. Для этого: создать элемент <script>, в его свойство textContent засунуть нужный JS-текст и добавить его в окно (window) с помощью append() или appendChild().
С первым способом мозилловцы начали бороться. А со вторым?
Отсутствует
Но все равно за скрипт большое спасибо. Если мой скрипт совсем загнется, то теперь есть альтернатива.
Тут у многих проблема с поиском скрипта, который должен выполнять определёное действие, нужное пользователю.
Именно для этого я сделал Демо-профиль несколько лет назад, в котором собрал и обновляю множество полезных фишек.
Просто читаем справку Демо-профиля в шапке и там наверняка найдётся скрипт с нужным действием.
Если это полезная фишка входит в скрипт ucf_hookClicks.js, то наверняка эту фишку можно найти отдельным скриптом, т.к. весь код взят из этой темы или из CustomButtons.
Отсутствует
Dobrov
Я же без претензий. И в справку в шапке иногда заглядываю, скажу честно, не часто.
Просто, если вы делаете скрипт лично для себя, как вам удобно, то вообще никаких вопросов.
Если же вы предлагаете скрипт кому-то ещё, на надо быть готовым и к критике, и к просьбам что-то добавить/убрать/изменить. Все люди разные, и понятия "удобно" или "эффективно" у всех разные. И многие сами ничего добавить/убрать/изменить не могут, им нужна помощь знающих людей.
А в целом, на мой взгляд, вы делаете нужные скрипты, и за это вам искренняя благодарность.
«The Truth Is Out There»
Отсутствует
и replace() поменяет в ней только первый вызов internalSave() (в ветке для <canvas>), а в самой часто используемой ветке (для обычных картинок) он останется нетронутым
Нет, все наоборот. Поменяет для картинок, а канвас не тронет. Брауз выставит на исполнение только часть функции для картинок и только к этой части применится replace
Отсутствует
dinn
Я не понял две вещи:
1. Как можно "выставить на исполнение только часть функции"? Функция это "замкнутая единица", "искусственного интеллекта" браузера хватает только на то, что бы найти и проигнорировать фрагменты, которые никогда ни при каких обстоятельствах не будут исполняться. Но понять, что "вот эта ветка отработает, только если мышкой щёлкнули по картинке, взятой из файла" он не в состоянии. И если какой-то код вычитывает текст этой функции, то он вычитает его весь (вместе со всеми проигнорированными при компиляции фрагментами, если таковые были). Тем более, что вычитывающий код не отчитывается перед браузером, для какой цели ему этот текст нужен и что он с ним делать собирается.
2. Как может replace(), ищущая строку "\n false" (перед false 8 пробелов), найти строку "\n false" (перед false 6 пробелов)?
А 8 пробелов перед false есть только в ветке для canvas.
Отредактировано yup (Сегодня 02:25:09)
Отсутствует
yup, ну я значит нафантазировал, раз кол-во пробелов разное.
А 8 пробелов перед false есть только в ветке для canvas
В 138 версии их 10. Первый раз скрипт с такой заменой стал доступен миру с релизом Firefox 77. Хотя это не столько важно. Не прошла замена, появилась бы окно с подтверждением
Отредактировано dinn (Сегодня 02:51:36)
Отсутствует
Не прошла замена, появилась бы окно с подтверждением
Вот, именно поэтому вопрос: "Как же оно работало раньше?" - и был поднят.
Но я разобрался в причинах нынешнего недоразумения. Это я недавно лазил по настройкам своего текстового редактора и случайно включил его "искусственный интеллект", подстраивающий отступы вставляемого из буфера текста под "окружающую среду".
В файле Firefox вся функция в целом имеет сдвиг в 2 позиции. Выделяю её, копирую, вставляю у себя в новый файл - и редактор располагает её от начала строки. Где было 10 пробелов - стало 8. Где было 8 - стало 6.
Отсутствует