Расширение Chrome: стартовая страница настроек с параметрами - PullRequest
0 голосов
/ 13 мая 2018

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

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

popup.js

var popup = (function() {

    var tabId;

    function openOptions() {
        port.postMessage({
            action: 'openOptions',
            id: tabId
        });
    }

    function connectToBackground(tabs) {
        if (tabs.length > 0) {
            tabId = tabs[0].id;
            port = chrome.runtime.connect();
            port.postMessage({
                action: 'connect',
                id: tabId
            });
        }
    }

    return {
        initialize: function() {
            document.getElementById('settings').addEventListener('click', openOptions);
            chrome.tabs.query({active: true, currentWindow: true}, connectToBackground);
        }
    };
})();
popup.initialize();

background.js

var background = (function() {
    var tabs = {};
    return {
        onConnectInjected: function(port) {
            chrome.pageAction.show(port.sender.tab.id);

            port.onMessage.addListener(function(message, port) {
                if (message.action === 'connect') {
                    if (!tabs[port.sender.tab.id]) {
                        tabs[port.sender.tab.id] = {};
                    }
                    tabs[port.sender.tab.id].injected = port;
                    tabs[port.sender.tab.id].tabData = message.data;
                }
            });
            port.onDisconnect.addListener(function() {
                tabs[port.sender.tab.id].injected = null;
            });
        },
        onConnectPopup: function(port) {
            port.onMessage.addListener(function(message) {
                if (message.action === 'openOptions') {
                    chrome.runtime.openOptionsPage(function() {
                        for (let view of chrome.extension.getViews()) {
                            if (view.options) {
                                view.options.showOptionsRelevantToTab(tabs[message.id].tabData);
                            }
                        }
                    });
                } else if (message.action === 'connect') {
                    if (!tabs[message.id]) {
                        tabs[message.id] = {};
                    }
                    tabs[message.id].popup = port;
                    port.onDisconnect.addListener(function(port) {
                        tabs[message.id].popup = null;
                    });
                }
            });
        }
    };
})();
chrome.runtime.onConnectExternal.addListener(background.onConnectInjected);
chrome.runtime.onConnect.addListener(background.onConnectPopup);

options.js

var options = (function() {

    return {
        showDefaultOptions: function() {

        },
        showOptionsRelevantToTab: function(data) {

        }
    };
})();
options.showDefaultOptions();

Волшебство должно происходить в background.js при обратном вызове chrome.runtime.openOptionsPage. Из того, что я понял, этот обратный вызов вызывается, когда страница параметров успешно открылась, но chrome.extension.getViews() возвращает только фоновое представление (и, как ни странно, всплывающее окно).

Я пытался открыть страницу параметров прямо из всплывающего окна, но поскольку параметры открываются на другой вкладке, всплывающее окно теряет фокус и закрывается, поэтому обратный вызов никогда не срабатывает. Я также исследовал отправку сообщения со страницы параметров в фоновый скрипт, но затем у background.js нет точного способа узнать, какая вкладка породила страницу параметров.

Я также протестировал вызов getViews в options.js, и он на самом деле возвращает всплывающее окно (которое, в свою очередь, может предоставить данные), но я не могу быть уверен, что это согласованно, учитывая, что всплывающее окно закрывается в тот же момент .

Итак, еще раз, как background.js может получить объект окна страницы параметров при создании, чтобы он мог предоставить ему соответствующие данные, или, альтернативно, - сообщить settings.js, какая вкладка создала его, чтобы он мог получить соответствующие данные из background.js. Я бы предпочел, чтобы мне не нужно было добавлять разрешение на вкладки только для этого.

Спасибо за чтение:)

1 Ответ

0 голосов
/ 13 мая 2018

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

// options.js init code:
chrome.runtime.sendMessage({action: "getOptionsData"}, (response) => {
  // Now that you have the response, you can set your settings and then make the page visible
});

В вашем background.js вам нужно это обработать.Самый простой способ - сохранить глобальную переменную optionsState, которую вы задали бы в обработчике openOptions, а затем вернуть эти данные в getOptionsData

. Это не должно быть проблемой, поскольку несколько вкладокне должны открывать опции в вашем примере.

например

// at the top of background.js
let optionsData = null;

// inside openOptions, before calling openOptionsPage,
optionsData = tabs[message.id].tabData;

// inside getOptionsData (make sure to expose sendResponse as a function param
return sendResponse(optionsData);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...