Мое расширение состоит из четырех соответствующих частей. Внедренный скрипт на вкладке, который собирает некоторые данные, всплывающее окно действий на этой вкладке, фоновый скрипт, который передает данные между ними, и страница параметров. Во всплывающем окне есть кнопка, которая открывает страницу параметров.
Я хотел бы открыть страницу параметров во всплывающем окне и предоставить ей некоторые данные, чтобы на ней могли отображаться параметры, относящиеся к этой вкладке. Ниже приведена моя урезанная и отредактированная попытка решить эту проблему:
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. Я бы предпочел, чтобы мне не нужно было добавлять разрешение на вкладки только для этого.
Спасибо за чтение:)