Greasemonkey: Выполнить в кадрах

Созданный на 21 сент. 2017  ·  48Комментарии  ·  Источник: greasemonkey/greasemonkey

Greasemonkey 4 на сегодняшний день обнаруживает события навигации только на верхнем уровне, поэтому эффективно применяет @noframes к каждому скрипту.

Самый полезный комментарий

Привет,
Собираетесь ли вы исправить проблему? Это довольно старый дефект, который влияет на все скрипты, основанные на структуре iframe ...

Все 48 Комментарий

webNavigation.onCommitted не «видит» начальное создание фрейма / рендеринг страницы, хотя, если фрейм перемещается в другое место, кроме начальной страницы, слушатель его поймает. Если параметры должны были включать ключ 'allFrames': true проблема _некоторо_ решена. В любой фрейм на статической html-странице будет внедрен скрипт, хотя тогда у вас возникнут проблемы с сопоставлением источника / URL-адреса. Кроме того, если фрейм создается с использованием Javascript, скрипт не внедряется.

Самым простым решением, которое я мог придумать, было бы заменить webNavigation.onCommitted на webRequest.onResponseStarted с фильтром {'urls': ['<all_urls>'], 'types': ['main_frame', 'sub_frame']} .

Я провел ограниченное тестирование, и никаких дополнительных изменений не потребовалось. Мне удалось выполнить скрипт внутри фрейма и фрейма, созданного с помощью Javascript.

@arantius есть ли планы объединить исправление от @Sxderp ?

Это влияет на сценарии, в которых фреймы являются объектами из разных источников, поэтому невозможно внести какие-либо изменения без запуска GM для этих конкретных фреймов.

Спасибо !

Пропустил, скоро разберусь.

Просто наблюдение во время тестирования старых скриптов, не знаю, поможет ли ...

Учитывая сценарий, который должен работать с iframe,
похоже, что он выполняет изменения на странице,
но затем снова обновляется до неизмененной страницы.

Я вижу только мерцание, когда очень быстро обновляю страницу.

Просто наблюдение во время тестирования старых скриптов, не знаю, поможет ли ...

Это с моим патчем или с выпущенной версией?

Тьфу, думаю это была 4.0 релиз ...
У меня БЫЛ @ 4.1b3, но для тестов я почти уверен, что переустановил релизную версию (до сих пор!)

То же самое и с iframe, описанным в Eselce. Каким-то образом он выполняется, но затем останавливается после загрузки iframe или страницы.

Если я введу этот скрипт, я получу только 1 и «self! == top»:

console.log('1');
if (self !== top) {
   console.log('self !== top');
   setTimeout(function() {
      console.log('Timeout');
   }, 2000);  
} else {
   console.log('self === top');
}

«Тайм-аут» не отображается в журнале, как и все функции и привязки.

Я использую 4.1b3.

У меня такая же проблема с GM 4.0 на Quantum. Я написал очень простой фиктивный пример с двумя страницами: main.html и framed.html и скриптом GM, который загружается на каждой странице и выводит URL-адрес страницы, на которой он загружен.

В большинстве случаев я получаю уведомления только о main.html , но примерно в 5% случаев, особенно если я удерживаю F5, я также могу получить уведомление о framed.html .

Есть ли какой-нибудь взлом, чтобы заставить GM 4.0 работать внутри iframe до тех пор, пока не выйдет патч?

Я только что обнаружил, что пользовательские скрипты надежно выполняются в <embed src="..."> но не в <iframe src="..">
Я написал небольшой тестовый скрипт:
https://openuserjs.org/scripts/cuzi/iframe_embed_Test_Greasemonkey_4

Еще несколько деталей: в некоторых случаях мои сценарии полностью выполняются во фрейме (но представление перезаписывается позже сценариями страницы и т. Д.).
Иногда синхронные части моего скрипта заканчиваются, но асинхронные части внезапно прерываются из-за активности страницы ...
Надеюсь, это поможет!

Есть ли у кого-нибудь еще информация по этому поводу?

Просто краткое изложение этой темы (проблемы):

  • Забудьте о большинстве сообщений, они не применяются
  • Возможно, скрипты выполняются всегда (но не до конца)
  • К сожалению, позже страница обновляется - макет пересчитывается, выполнение прерывается.
  • Это применимо в основном (но не полностью) к асинхронным частям скриптов.

Я не очень разбираюсь в этих внутренностях, но, наверное, кто-то ...

В качестве временного исправления я заменил фреймы для встраивания ( пример скрипта ), который действительно работает, чтобы получить скрипт, соответствующий запускаемому фрейму (кредит @cvzi за то, что выяснил, что <embed src="..."> действительно работает) .

Возможно, стоит отметить, что Violentmonkey и Tampermonkey прекрасно работают во встроенных фреймах. Поскольку виртуальная машина с открытым исходным кодом, может быть, посмотреть, как они это сделали?

К сожалению, Violentmonkey и Tampermonkey все еще используют старую схему именования GM_ для специальных функций, поэтому скрипты еще не переносимы.

https://github.com/greasemonkey/gm4-polyfill

Tampermonkey => GM. * Звонит, если не указан
Violentmonkey => GM. * Звонит
Greasemonkey -3.17 / FF -56.0 => GM. * Звонки
Greasemonkey 4.0+ / FF 57.0+ => встроенные вызовы GM. *

// <strong i="11">@grant</strong>        GM.getValue
// <strong i="12">@grant</strong>        GM.setValue
// <strong i="13">@require</strong>      https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// <strong i="14">@grant</strong>        GM_getValue
// <strong i="15">@grant</strong>        GM_setValue

Исправление @Sxderp уже включено в основную ветку? Если нет, как я могу установить его вилку?

Исправление @Sxderp уже включено в основную ветку? Если нет, как я могу установить его вилку?

  1. Нет, это не так.
  2. К сожалению, это один из моих PR, который я не синхронизировал с мастером и поэтому не был перебазирован. Таким образом, в самой ветке отсутствуют некоторые из текущих изменений.
  3. Я также никогда не реализовывал изменения, предложенные в PR-комментариях. Честно говоря, эти изменения _ не должны_ требоваться, но поскольку Mozilla постоянно что-то портит, изменения необходимы.
  4. Если вы все еще хотите его использовать (не рекомендуется), вы можете выполнить следующие шаги.

  1. git clone -b use-on-response-started-for-execute --single-branch https://github.com/Sxderp/greasemonkey.git [1]
  2. Запустите ./package.sh , это создаст файл XPI.
  3. Перейдите к about:config в Firefox и установите для xpinstall.signatures.required значение false
  4. Перейдите к about:addons в Firefox, щелкните шестеренку и выберите установку из файла.
  5. Выберите XPI, созданный на шаге 2.

[1] Если ваша версия git не поддерживает флаги -b и / или --single-branch (старая версия git), вы можете использовать git clone https://github.com/Sxderp/greasemonkey.git и git checkout use-on-response-started-for-execute .

Привет,
Собираетесь ли вы исправить проблему? Это довольно старый дефект, который влияет на все скрипты, основанные на структуре iframe ...

Напоминаем, что завтра 13 марта (см. Firefox 59.0 ) ...

Я хочу сослаться на @Sxderp :

webNavigation.onCommitted не «видит» начальное создание фрейма / рендеринг страницы, хотя, если фрейм перемещается в другое место, кроме начальной страницы, слушатель его поймает. Если бы параметры включали ключ allFrames: true, проблема в некоторой степени решалась. В любой фрейм на статической html-странице будет внедрен скрипт, хотя тогда у вас возникнут проблемы с сопоставлением источника / URL-адреса. Кроме того, если фрейм создается с использованием Javascript, скрипт не внедряется.

На самом деле, у меня есть доказательство того, что (в моей системе) слушатель executeUserscriptOnNavigation вызывается надежно с помощью chrome.webNavigation.onCommitted , так что chrome.tabs.executeScriptInFrame вызывается с правильным frameId . Почему это не решает всех наших проблем с фреймами? Нам не нужно chrome.webRequest.onResponseStarted чтобы реагировать на iframe! (Или ты имел ввиду, что он реагирует на событие, а рамки не видно?) Это точно называется ...

Есть ли известная ошибка с chrome.tabs.executeScriptInFrame и frameId ? Проблемы были много лет назад, но теперь они устранены. all_frames не задано, поэтому frameId должно быть действительным. Установка параметра matchAboutBlank на true похоже, имеет значение (в противном случае executeScript вернул ошибку <unavailable> ), хотя я не совсем понял, что about:blank stuff (где это?) ...

Любые идеи?

Функции? Это базовая функциональность, отсутствующая с самого начала ... Надеюсь, я неверно это истолковал.

@Eselce , это было давно, и я не уверен, что полностью помню, о чем имел в виду, но я

Теперь к вопросу. Когда я проводил начальное тестирование, у меня была статическая страница с тем же исходным фреймом и удаленным фреймом. При начальной загрузке страницы я мог только один раз запустить обратный вызов onCommitted . Он сработал для основного документа, но не сработал ни для одного из статических фреймов в документе [1]. Таким образом, в них не будут вставляться скрипты.

Однако после начальной загрузки, если я заставил один из фреймов «перемещаться» где-то, будет вызван обратный вызов onCommitted , и скрипты будут вставлены во фрейм в новом месте.

Была предпринята попытка использовать ключ опции all_frames , чтобы обойти указанную выше проблему. Хотя использование ключа приводило к встраиванию скриптов во фреймы на странице, имелся очевидный недостаток, заключающийся в неправильном сопоставлении происхождения + пути фрейма с тем, на чем скрипт должен или не должен выполняться.

Кроме того, я также упомянул, что использование ключа all_frames не приведет к внедрению скриптов во фреймы, созданные Javascript.

[1] Я не знаю, сохраняется ли эта проблема. Если я помню, этой проблемы не было в FF 52 ESR, но присутствовало в 56 (57?) (Следовательно, регресс). Возможно, это исправили.

Я согласен с вами почти во всем.

И вы правы в том, что каждый кадр сопоставляется отдельно, как если бы это была целая вкладка (со своим собственным window и своим собственным document , встроенным в кадр).

Что ж, я почти всегда использовал одну и ту же структуру меню / фрейма, так что, возможно, мне стоит протестировать другую.

Когда вы говорите «выстрелил», вы имеете в виду чистый зов слушателя?

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

all_frames не может работать из-за неправильного location (разные window , разные document ). Кстати: меню обрабатывает только URL-адреса мэйнфрейма каждой вкладки - если меню неправильное, это не означает, что скрипт не вызывается ...

Когда вы говорите «выстрелил», вы имеете в виду чистый зов слушателя?

В этом конкретном сообщении я имел в виду «Была вызвана функция, переданная в onCommitted.addListener ».

Привет,

Я внимательно прочитал этот пост, но не понимаю, как использовать ваше альтернативное решение в моем локальном скрипте ".user.js". Как я могу применить ваше решение? Извини, я новенькая.

(После обновления Firefox созданное всплывающее окно iframe больше не распознается дополнительным скриптом, но если я открою то же всплывающее окно в новом окне, скрипт будет применен.)

Заранее спасибо за вашу помощь

Вы точно описали, в чем проблема: это похоже @noframes активацию

Спасибо, Eselce.
И всегда, начиная с обновления Firefox, я обязан в заголовке объявлять все scipts '.js' (с требованием), уже использованные на целевом сайте. (включая jquerry)
И это не то же самое .... Это создает ошибки или конфликты.
Вы тоже знаете эту проблему?

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

Я не решаюсь давать конкретные URL-адреса, которые я тестирую, поскольку они находятся вне моего контроля, но я нахожу некоторое последовательное, но странное поведение, которое можно передать.

У меня есть сайт, с которым мне нужно взаимодействовать. Первоначально он загружает набор фреймов / фрейм с rows = "100%, 0" (один фрейм для заполнения экрана) в другом домене. Этот кадр содержит один набор кадров / 3 кадра в домене промежуточного набора кадров / кадра.

Некоторые из скриптов GM дочерних фреймов 1 + 3 «вспыхивают», а затем исчезают после начального цикла - они никогда не возвращаются после какой-либо асинхронной операции. Это соответствует некоторому поведению, описанному в этой ветке. Обратите внимание, какие из них «вспыхивают» и описанное ниже поведение зависит от версии браузера / GM, но это не случайно; паттерны странные, но на 100% повторяемые для любой данной настройки.

  1. Первый набор фреймов / фрейм НИКОГДА не появится. Я пробовал отсоединить и перестроить тег кадра как через window.document, так и через unsafeWindow.document, как в начальном цикле, так и после задержки, но ничто не заставит сценарий GM этого кадра сообщать что-либо в console.log. ( @Include - это *, без @exclude или другой фильтрации URL-адресов.)
  2. Некоторое последующее поведение будет отличаться между Firefox 52.8 / GM 4.1 и Firefox 60.0 / GM 4.3, но я могу заставить скрипты GM фреймов в каждом случае «всплывать», независимо от того , установлен ли @includes *, без других фильтров URL. Они никогда не должны появляться с установленным
  3. В Firefox 52.8 / GM 4.1 следующий набор фреймов / 3 фрейма ВСЕГДА появятся. В Firefox 60.0 / GM 4.3 они не «мигают» при начальной загрузке кадра.
  4. В Firefox 60.0 / GM 4.3 щелчок по ссылке в одном из 3 фреймов, который перемещается по другому из 3 фреймов (через атрибут "target" в ссылке привязки, а не скрипт) будет "всплывать" - не новый URL, а старый URL-адрес для фрейма с переходом. (Это один из фреймов, появившихся при начальной загрузке в пункте №3.)
  5. Вот самое странное. В обеих настройках браузера --- Следуя инструкциям, мы открыли начальную страницу с 2 слоями наборов фреймов, всего 4 фреймами и щелкнули ссылку в одном фрейме, чтобы перейти к другому фрейму на той же странице. Чтобы дать этому название, наш первоначально отображаемый набор фреймов второго уровня имел фреймы «top.htm», «menu.htm» и «start, htm». Мы щелкнули ссылку во фрейме «menu.htm», чтобы заставить фрейм, содержащий «start.htm», перейти к «content.htm», с аналогичным, но немного другим поведением в зависимости от настроек браузера, как указано выше. Теперь мы щелкаем ссылку внутри фрейма «content.htm», чтобы перемещаться внутри того же фрейма, в том же домене.

На этом этапе сценарий для «content.htm» не только «вспыхивает» ... он также останется активным после завершения GM.xmlHttpRequest - асинхронного события. На данный момент "content.htm" нигде не отображается в браузере, но его сценарий будет продолжать работать.

Мне кажется, что причина, по которой скрипты GM на страницах внутри фреймов не работают, заключается в том, что скрипт загружается при выгрузке страницы, а не при загрузке страницы. Установка @ run-at для document-start и помещение скрипта в событие DOMContentReady для unsafeWindow.document не дало никаких улучшений. (Установка его на window.document никогда не запускает событие.)

-Райан

В Firefox 52.8 / GM 4.1 следующий набор фреймов / 3 фрейма ВСЕГДА появятся. В Firefox 60.0 / GM 4.3 они не «мигают» при начальной загрузке кадра.

При переходе на Firefox 57 Mozilla кое-что изменила. Как бы то ни было, он изменил (или сломал) способ срабатывания фреймов. Об этом вкратце говорилось в другом номере. В результате скрипты не запускались при начальной загрузке кадра (57+).

Возможный переход на userScript или contentScript API все равно должен разрешить все это.

Люди продолжают говорить, но Violentmonkey продолжает казнить в кадрах. Виртуальная машина не отделяет пользовательские скрипты от содержимого веб-страницы должным образом (CSP блокируют пользовательские скрипты, веб-страницы могут перезаписывать глобальные объекты и т. Д.), Иначе я бы давно отказался от Greasemonkey. Возможно, это связанные проблемы, но я использую движки пользовательских скриптов, поэтому мне не нужно изучать Chrome достаточно глубоко, чтобы выяснить это самостоятельно.

Хм, это сложная проблема, некоторые из моих скриптов больше не работают, потому что не могут работать с фреймами. Так что, похоже, это невозможно исправить, и нам нужно, чтобы Mozilla реализовала какой-то API? Разве мы ничего не можем сделать сами, как обходной путь? Мне просто нужно что-то сделать со страницей в iframe, часто даже из того же домена.

Мой собственный обходной путь на данный момент - запустить Greasemonkey в верхних фреймах и Violentmonkey в дочерних фреймах. Я не могу использовать Tampermonkey, потому что у него неоднозначная самодельная лицензия, но если это не проблема для вас, тогда он может работать или не работать лучше.

Имейте в виду, что виртуальная машина помещает скрипт в собственный контекст страницы. Это как unsafeWindow GM без безопасного эквивалента. Одним из самых запоминающихся моментов, которые у меня были, была отладка сценария, в котором содержимое страницы определяло метод toJSON () в Array.prototype, в результате чего JSON.stringify () выдавал неверный JSON внутри моего сценария. Мне пришлось защитно заманите их в ловушку и исправьте, как я их нашел.

Еще одна серьезная проблема с виртуальной машиной заключается в том, что она соблюдает политику безопасности содержимого страницы содержимого, поэтому любая директива, ограничивающая источники сценария, приведет к тому, что сценарий виртуальной машины никогда не будет выполняться. Вы можете увидеть это в консоли браузера (но не в веб-консоли). Вот почему я не могу полностью запустить виртуальную машину и просто избавиться от GM. Я еще не встречал дочерний frme с набором CSP, но когда я это сделаю, он будет полностью непригоден для использования.

@RyanHanekamp Спасибо за подсказку! Возможно, тогда я буду использовать Violentmonkey для каких-то скриптов.

Есть ли у Violent что-то вроде синхронного GM_getValue? Это еще одна проблемная проблема, которая нарушает работу множества скриптов в новом Greasemonkey. Я по-прежнему больше всего доверяю Greasemonkey по разным причинам, поэтому я не брошу его.

Что касается iframe, я пытался заменить их тегами объектов, к которым, по-видимому, можно получить доступ напрямую с помощью Javascript, например:

myObject= document.createElement('object');
myObject.setAttribute('id', 'myObject'); 
document.body.appendChild(myObject);
myObject.setAttribute('src', 'https://example.com');

Затем, когда объект загружен:
document.querySelector('#myObject').contentDocument.defaultView.document.querySelectorAll('someElementInsideObjectPage')
По крайней мере, у меня это работает в сценарии, где объект находится на том же хосте, что и главная страница. Вы также можете отправлять сообщения от объекта и к ( ... contentDocument.defaultView.postMessage('hello, object') ) объекту.

Я не эксперт по виртуальным машинам, но считаю, что он реализует, по крайней мере, большую часть оригинального API GM_ *. Я бы подумал, что лучше адаптировать ваши скрипты к асинхронным, чем возвращаться к синхронной платформе в долгосрочной перспективе. Насколько я понимаю, Greasemonkey сделал это для повышения производительности в новой структуре Quantum, которая не допускает синхронных вызовов между фоновыми сценариями и сценариями содержимого.

Что касается объектного решения, оно не решит мою конкретную проблему, но я рад, что другие сочли его полезным. Помимо маршалинга CSS / свойств / и т. Д. И обеспечения его работы с фреймами, а также с фреймами, я должен отфильтровать объекты в процессе захвата как потенциально небезопасные. Есть способы обойти все эти проблемы, но VM была более легкой промежуточной задачей, пока GM, наконец, не сделала то, что она говорит на жестяной банке.

Кроме того, если у вас есть фрейм / iframe того же происхождения, вы также можете напрямую получить доступ к их содержимому. Более сложная часть - это перекрестное происхождение, поэтому мне нужны пользовательские скрипты внутри фрейма. Он устанавливает канал window.postMessage () для обратной связи с родительским окном.

@RyanHanekamp Приятно знать, что у Violent Monkey все еще есть старый, простой GM_ *. Я действительно хотел бы, чтобы Greasemonkey сохранил старый синхронный GM_getValue для обратной совместимости в дополнение к новой версии. Я мог бы попытаться реализовать новую асинхронную функцию в новом скрипте, но я не программист и не уверен, смогу ли я заставить ее работать. И я определенно не могу реорганизовать использование старого GM_getValue в древнем скрипте из 2000 строк, который я нашел в Интернете ... так много скриптов сейчас сломано.

Я понимаю, почему Violent был для вас лучшим вариантом. Будем надеяться, что Энтони, Sxderp или кто-то еще в конце концов узнает, как это реализовать. Я действительно хотел бы внести свой вклад, но я полный профан.

О, вы можете напрямую получить доступ к содержимому iframe того же происхождения (без postMessage и т. Д.)? Я помню, как тратил много времени, пытаясь найти способ, но это казалось невозможным. Вот почему я тоже перешел на postMessage.

Фреймы и фреймы имеют свойство contentWindow, эквивалентное свойству window. У обоих есть свойство документа для доступа к DOM.

Самая сложная часть работы с iframe (в одном и том же источнике) - это определить, когда его содержимое загружено, потому что вы не можете выполнять приседания, пока это не произойдет. onload не работает так, как выглядит. Firefox предоставляет событие DOMFrameContentLoaded, которое запускается для КАЖДОГО загруженного кадра, включая кадры внуков / правнуков и т. Д., Которые вы можете сопоставить с исходным элементом кадра / iframe с помощью свойства event.target. Если вы управляете содержимым фрейма / iframe, вы также можете заставить его разговаривать с родителем с помощью postMessage или вызова глобального метода для объекта window.parent.

Кстати ... это потенциальное решение этой проблемы. Если существует или может быть способ кодирования сценария GM для ручного внедрения пользовательского скрипта в междоменную ссылку на окно, для создателя пользовательского скрипта потребовалось бы намного больше кода, но он мог бы выполнить свою работу. Шаблон будет прослушивать DOMFrameContentLoaded, проверять, является ли event.target первым поколением, и вручную вводить скрипт, если это так. (Предполагая, что сценарий кадра первого поколения может прослушивать DOMContentLoaded для кадров второго поколения и, таким образом, получить полную цепочку.) Не будет никакого способа получить поведение @ run-at dom-start, а также могут быть проблемы с синхронизацией, но мы, вероятно, могли бы обойти их для большинства случаев использования.

Я лично отказался от решения этой проблемы и вместо этого перешел к непосредственному кодированию расширения. Которая отлично работает во всех кадрах!

Разница между Greasemonkey и Violentmonkey в этом вопросе, по-видимому, заключается в том, что Violentmonkey запускается из сценариев содержимого, для которых all_frames установлено значение true, в то время как Greasemonkey не имеет сценариев содержимого во время установки и полностью полагается на сомнительную способность фонового сценария обнюхивать, когда фрейм вкладки переместился. (И Violentmonkey не работает на страницах CSP, потому что он временно вводит тег SCRIPT вместо использования гораздо более безопасного tabs.executeScript ().)

Поместите сценарий статического содержимого с all_frames, run_at start, сопоставьте все, чтобы уведомить фоновый процесс для start / document.DOMContentLoaded / document.Idle, чтобы запускать пользовательские сценарии для каждого run_at, и все готово. Нетривиальный, но выполнимый объем работы, чтобы решить эту проблему. Я бы исправил это сам, но мне неинтересно разбираться с вашими зависимостями разработчиков, и я могу только создать выходной код.

@RyanHanekamp

и вместо этого перешли к непосредственному кодированию расширения. Которая отлично работает во всех кадрах!

Не могли бы вы поделиться своим кодом расширения?

Мое расширение не общего назначения. Дело в том, что при использовании статического content_script в манифесте с all_urls all_frames будет запускать скрипт всякий раз, когда загружается любой фрейм или выполняется навигация, и даже код конструктора eval / Function может отлично работать независимо от Content-Security-Policy страницы.

Я не тестировал программно созданные фреймы / окна, но я предполагаю, что они будут запускаться при первоначальном создании независимо от настройки run_at, потому что такие фреймы изначально создаются пустыми, а затем заполняются - движок, вероятно, увидит только первоначальное создание. Я также не тестировал данные: URL-адреса, для которых может потребоваться явное сопоставление - я не уверен, покрывает ли их all_urls или просто http / https.

Возможно, это и не обязательно должна быть статическая ссылка на content_script, но из документации неясно, загружаются ли динамически вызываемые сценарии содержимого автоматически при переходе по странице. У меня сложилось впечатление, что они вводятся только в совпадающие в данный момент вкладки / фреймы в соответствии с предоставленным шаблоном соответствия, и навигация не вызывает повторного внедрения. Но я не вижу недостатков в использовании для этой цели статического content_script.

Greasemonkey, очевидно, не может включать пользовательские сценарии в качестве статических ресурсов в манифест, а сценарии содержимого, похоже, не имеют прямого доступа к tabs.executeScript (хотя я вряд ли эксперт в этом, поскольку у меня всего несколько дней), но что МОЖЕТ сделать сценарий статического содержимого, так это сообщение фоновому процессу, чтобы сообщить ему, что был выполнен переход по frameId и по какому URL. Это было бы более надежно, чем то, как я воспринимаю попытки, упомянутые в этой ветке, перехватить правильное событие в webRequest или webNavigation. Сигнал от статического content_script становится событием, которое мы ищем для запуска загрузчика / инжектора пользовательского скрипта Greasemonkey.

Возможно, возникнет задержка для пользовательских скриптов, которые ОБЯЗАТЕЛЬНО ДОЛЖНЫ run_at document_start. Вызов фонового сценария является асинхронным, и документ будет обработан к моменту вызова пользовательского сценария. Вполне возможно, что Violentmonkey использует временный тег сценария вместо tabs.executeScript, поскольку внедрение тега сценария может быть выполнено непосредственно из content_script, синхронно. Мне было бы неудобно работать над неопределенностью состояния документа для run_at document_start, но это было бы предпочтительнее, чем сценарий, который вообще не запускается.

Greasemonkey ... МОЖЕТ [использовать сценарий статического содержимого] для сообщения фоновому процессу, чтобы он знал, что был выполнен переход по frameId и по какому URL ...

Это то, что мы обычно делали для обнаружения .user.js навигации. Кажется очевидным и хорошим решением: обнаруживать контент, запустив контентный скрипт!

Но оказывается, что даже сценарии содержимого расширений могут быть нарушены CSP (# 2631 и http://bugzil.la/1267027 и http://bugzil.la/1411641).

Я могу запустить свой собственный плагин, включая конструктор Function (), прямо из content_script в Firefox 60.0.1 и 52.8.1ESR со следующим набором CSP:

frame-src data :; объект-источник 'нет'; script-src 'нет'; style-src 'unsafe-inline' data :; connect-src 'нет'; media-src 'нет';

2631 был закрыт, по-видимому, потому, что Firefox исправил основную ошибку. Первый bugzilla касается внедрения тегов сценария (метод Violentmonkey), а не самого content_script. Второй относится к атрибуту песочницы для CSP, что неудивительно, потому что он заставляет домен никогда не завершать успешное совпадение домена даже с самим собой. Вроде как NaN! == NaN.

Когда это было впервые подано несколько месяцев назад, мы поступили по-другому. Сегодня мы используем webNavigation.onCommitted для обнаружения навигации, и в тесте, который я запускаю прямо сейчас, по какой-то причине я не вижу, чтобы он запускался на (ni) кадре).

Привет, теперь это решено?

Мне не удалось заставить скрипт, который я создал для Tampermonkey, запускать в iframe с Greasemonkey.

Код для исполнения с нашей стороны не изменился. Так что, если Mozilla не изменила что-то на своей стороне, это все равно не работает. Однако # 2663 должен решить эту проблему.

Возможно, стоит отметить, что Violentmonkey и Tampermonkey прекрасно работают во встроенных фреймах.

У Tampermonkey проблемы с фреймами в Chrome, по крайней мере, для меня.

Возможно, стоит отметить, что Violentmonkey и Tampermonkey прекрасно работают во встроенных фреймах.

У Tampermonkey проблемы с фреймами в Chrome, по крайней мере, для меня.

Но у меня это работает в Firefox Violentmonkey. Вот и интересно, как это может там работать?

Я только что заметил, что скрипт, использующий старую синхронизацию GM_GetValue, по-прежнему отлично работает и в Violentmonkey. Как такое возможно? Я думал, что Firefox принудительно использовал асинхронный GM.GetValue? Я сейчас так сбит с толку: предположительно, Violentmonkey пришлось пожертвовать чем-то еще, чтобы по-прежнему поддерживать синхронизацию и другие вещи?

@ Cerberus-tm Изменение в Firefox означало, что данные могут запрашиваться только из хранилища расширений или из фонового контекста асинхронно (сами пользовательские скрипты отправляются в скрипт содержимого асинхронно). Однако данные могут быть предоставлены пользовательским скриптам синхронно, если каждый скрипт контента GM4 предварительно загружает и кэширует в скрипте контента данные, которые хранятся для каждого пользовательского скрипта, загружаемого на эту страницу.

Такой кеш позволит сценарию содержимого синхронно отвечать на запросы данных пользовательского сценария. При внедрении кеша возникают проблемы с поддержанием согласованности между различными сценариями содержимого, но это можно решить, если сценарии содержимого будут отслеживать все изменения в хранилище расширений GM4. Кроме того, если пользовательский скрипт хранит большой объем данных, то его кеширование в каждом сценарии содержимого, в котором выполняется пользовательский сценарий, также значительно увеличивает объем памяти, необходимый для каждого сценария содержимого.

TM и VM решили сделать что-то подобное вышеизложенному, чтобы не нарушать совместимость с исходными API Greasemonkey, когда эти менеджеры пользовательских скриптов были реализованы для Chrome, который имеет те же ограничения по отношению к. асинхронная связь с хранилищем расширений и т. д. Учитывая, что они уже делают это для Chrome, у них не было причин менять при реализации для Firefox.

Таким образом, переход FF57 к WebExtensions заставил переписать GM, но не заставил принять асинхронные API для GM.getValue , GM.setValue и т. Д. WebExtensions действительно использовали API на основе асинхронного программирования проще реализовать, чем синхронный, но это не требовало этого.

Лично я считаю, что выбор и другие варианты нарушения совместимости были неудачными. Отсутствие обратной совместимости со скриптами, которые нормально работали в GM3, и / или совместимость с TM приводят к тому, что многие люди предпочитают не использовать GM4. Мой опыт показывает, что более 30 пользовательских скриптов, которые я использую, все из которых отлично работали в GM3, не работают с GM4 (или, по крайней мере, не работали до того, как были переписаны для совместимости с GM4). Я все еще использую 28 пользовательских скриптов, которые нормально работают под GM3, но не работают с GM4.

Я опубликовал обходной путь для этой проблемы в Stack Overflow в качестве ответа на то, как применить Greasemonkey / ‌Tampermonkey / ‌userscript к iframe . По сути, я жду загрузки кадра, а затем работаю с массивом window.frames . Я использую специальный маркер в теле каждого кадра, чтобы обозначить, что я уже видел кадр.

Возможно, Greasemonkey сможет реализовать решение аналогичным образом?

Было бы здорово, если бы у нас также был GM.waitFor(css_selector, action_function) такой как waitForKeyElements () , но это отступление.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги