Разработка расширения Firefox: как создать глобальную функцию внутри скрипта содержимого, чтобы другие загруженные файлы скриптов могли получить к ней доступ?

В моем файле main.js у меня есть PageMod, который включает файл base.js:

pageMod.PageMod({
    contentScriptFile: ["./base.js"]

У меня есть функция внутри моего файла base.js

function setupPayment(){ /* DO STUFF HERE */ }

Внутри моего файла base.js я также загружаю другие файлы JS.

$.getScript("https://checkout.stripe.com/checkout.js", function(){
    $.getScript( self.options.stripe );
});

Внутри моего файла stripe.js я пытаюсь вызвать функцию setupPayment, которая находится в моем файле base.js.

var yearhandler = StripeCheckout.configure({
    key: "pk_live_...",
    image: "image.png",
    name: "SHINE",
    description: "Subscription",
    panelLabel: "Subscribe",
    allowRememberMe: false,
    token: function(token) {

        plan = "yearly";

        setupPayment(token,plan);

    }
});

Но setupPayment возвращает значение undefined.

И после некоторого тестирования похоже, что любой скрипт, включенный через $.getScript, не может получить доступ к каким-либо функциям внутри моего скрипта содержимого base.js? Есть ли способ сделать функцию внутри моего сценария содержимого base.js глобальной для всех моих других файлов сценариев, которые я загружаю?

Спасибо за вашу помощь!

Изменить: причина, по которой setupPayment() должна находиться в файле base.js, заключается в том, что он может взаимодействовать с файлом main.js и хранить некоторую информацию.


person TyGoss    schedule 21.03.2015    source источник
comment
убедитесь, что ваши функции являются функциями jquery. Внутри document.ready, а не функции Javascript. Также объявите свои переменные внутри document.ready и до начала всех ваших сценариев.   -  person Prodeep Chatterjee    schedule 21.03.2015


Ответы (2)


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

function setupPayment(args, callback) {
  // some code
  callback(result); 
  // your callback should use postMessage to send data back to the
  // content script, see these docs:
  // https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts/Interacting_with_page_scripts#Communicating_with_page_scripts 
}

exportFunction(setupPayment, unsafeWindow, {defineAs: "setupPayment"});
person therealjeffg    schedule 22.03.2015

ContentScripts запускаются в песочницах, я не знаю, что jquery делает внутри, но он, конечно, не предназначен для учета нескольких контекстов javascript и обертки xray, поэтому он, вероятно, просто внедряет тег <script> в DOM, который затем запускает загруженный javascript внутри контекста страницы, а не в песочнице contentScript.

И я даже не уверен, как вы получаете доступ к jquery в своей песочнице, учитывая, что вы загружаете только base.js.

Таким образом, похоже, что большая часть кода вашего аддона на самом деле работает/загружает скрипты в ненадежный контекст страницы.

причина, по которой setupPayment() должна находиться в файле base.js, заключается в том, что он может взаимодействовать с файлом main.js и хранить некоторую информацию.

Не совсем. Вы можете экспортировать привилегированную функцию в контекст страницы с помощью exportFunction, который доступен внутри песочницы.

person the8472    schedule 21.03.2015