В более новых версиях Firefox по-прежнему можно переопределить функцию JS веб-страницы?


Я пишу расширение, чтобы переопределить функцию JS веб-страницы, и начал с этого вопроса, но ответ, похоже, не работает в Firefox 42 на Linux.

Затем я попытался использовать exportFunction, как описано в документации , но это также молчаливо провалилось.

Внутри package.json я добавил следующее описание.

  "permissions": {
      "unsafe-content-script": true
  }

Вот мой файл index.js.

var self = require('sdk/self');
require("sdk/tabs").on("ready", fixGoogle);

function fixGoogle(tab) {
    if (tab.url.indexOf("google.com") > -1) {
        tab.attach({
            contentScriptFile: self.data.url("google-script.js")
        });
    } 
}

Вот мой текущий data/google-script.js.

unsafeWindow.rwt=function(){};

Обратите внимание, что ввод текста вручную rwt=function(){}; в консоли браузера достигается желаемый эффект, как и с помощью букмарклета (который требует нажатия), но я пишу плагин, чтобы получить это автоматически каждый раз, когда я использую Google.

Можно ли переопределить функцию страницы rwt с помощью расширения Firefox? Если да, то каков правильный API для использования?

3 2

3 ответа:

Прочитайте документацию, на которую вы ссылаетесь, в частности главу под названием Expose functions to page scripts - которая ссылается на exportFunction

function blah() {}

exportFunction(blah, unsafeWindow, {defineAs: 'rwt'});

Оказывается, что проблема заключается в том, что переопределение функции rwt идет наперегонки с исходным определением и побеждает. Оригинал запускается после и переопределяет функцию, которую я определил, тем самым делая его похожим на мое переопределение, которое молча провалилось.

Как только я понял, что это проблема, проще всего было добавить тайм-аут к переопределению внутри data/google-script.js.

setTimeout(function() {
    unsafeWindow.rwt=function(){};
}, 1000);

Таким образом, исходный ответ все еще верен, но просто не был адресован состязание.

Несмотря на то, что сценарии содержимого совместно используют DOM, в остальном они изолированы от сценариев страниц. Как вы правильно предположили, можно использовать unsafeWindow в Firefox, чтобы обойти эту изоляцию.

Лично мне почему-то не нравится название unsafeWindow;)

Поэтому я предлагаю другой способ сделать это: использовать то, что разделено между этими областями, то есть DOM.

Вы можете создать сценарий страницы из сценария содержимого:

var script = 'rwt=function()();';
document.addEventListener('DOMContentLoaded', function() {
    var scriptEl = document.createElement('script');
    scriptEl.textContent = script;
    document.head.appendChild(scriptEl);
});

Преимущество этого подхода заключается в том, что вы может использовать его в средах без unsafeWindow, например, расширения chrome.