Если вам нужно синхронно использовать настройки из любого асинхронного хранилища - лучший способ сделать это - кэшировать его.
Вам нужно загрузить настройки в кеш при запуске background.js
, а затем вам нужнообновлять кэш каждый раз, когда chrome.storage.onChanged
запускается событие.
Пример, как это сделать:
manifest.js
{
"manifest_version": 2,
"name": "Settings Online demo",
"description": "Settings Online demo",
"applications": {
"gecko": {
"id": "852a5a44289192c3cd3d71e06fdcdb43b1437971@j2me.ws"
}
},
"version": "0.0.1",
"background": {
"scripts": ["background.js"]
},
"permissions": [
"storage",
"webRequest",
"webRequestBlocking",
"<all_urls>"
],
"options_ui": {
"page":"properties.html",
"chrome_style": true
}
}
Обратите внимание, что выесли вы хотите работать с ним в firefox, необходимо иметь временный идентификатор приложения, для получения доступа к любой обработке запроса URL требуется разрешение <all_urls>
.
background.js
((storage) => {
let settings = (function(properties) {
// Save settings
this.set = (properties,ok) => {
for(key in properties || {}){
this[key]=properties[key];
}
storage.set(
properties
,() => {
ok(settings);
});
};
//Default values processing
for(key in properties || {}){
this[key]=properties[key];
}
// Initial settings read
storage.get(properties,(properties) => {
for(key in properties){
this[key]=properties[key];
}
});
// Listen settings change and cache it
chrome.storage.onChanged.addListener((msg) => {
for(key in msg){
this[key]=msg[key].newValue;
}
});
return this;
}).call({},{"property":"default","name":"me"})
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
// Update and persist settings
settings.set({"lastRequest":info},()=>{console.log("Settings saved")});
console.log('Catch', settings.name,settings.property);
},{urls:["https://*/*"]});
})(chrome.storage.sync || chrome.storage.local);
Обратите внимание, что я использую chrome.storage.sync || chrome.storage.local
, потому что некоторые браузеры (Opera, мобильные браузеры) не поддерживают синхронизированное хранилище, но поддерживают локальное хранилище.
И страницу свойств, чтобы узнать, как можно изменять свойстваобрабатывают: properties.html
<html>
<head>
<script src="properties.js" type="text/javascript"></script>
</head>
<body>
<label>Property:<input id="property" type="text"></label>
<input id="save-properties" value="save" type="submit">
</body>
</html>
properties.js
((storage) => {
let saveOptions = () => {
let property = document.getElementById("property").value;
storage.set({
"property": property
},() => {
window.close();
});
}
let restoreOptions = () => {
storage.get({
"property": "default"
}, (properties) => {
document.getElementById("property").value = properties.property;
});
document.getElementById("save-properties").addEventListener("click", saveOptions);
}
document.addEventListener("DOMContentLoaded", restoreOptions);
})(chrome.storage.sync || chrome.storage.local);
Вот и все:)
PS> У этого решения есть слабое место: если ваше приложение чувствительно к настройкам и не может работать с настройками по умолчанию, или вынужно убедиться, что вы используете пользовательские настройки при запуске - вам нужно отложить запуск background.js, пока настройки не загружены.Вы можете сделать это с обратным вызовом или с обещанием:
background.js - подождите, пока настройки будут загружены с обратным вызовом
((storage) => {
let settings = (function(properties) {
// Update settings
this.set = (properties,ok) => {
for(key in properties || {}){
this[key]=properties[key];
}
storage.set(
properties
,() => {
ok(settings);
});
};
//Default values processing
for(key in properties || {}){
this[key]=properties[key];
}
// Listen settings change and cache it
chrome.storage.onChanged.addListener((msg) => {
for(key in msg){
this[key]=msg[key].newValue;
}
});
// Initial settings read
storage.get(properties,(properties) => {
for(key in properties){
this[key]=properties[key];
}
mainLoop();
});
return this;
}).call({},{"property":"default","name":"me"})
let mainLoop = () => {
//.. all you settings-sensitive code
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
// Update settings and persist it
settings.set({"lastRequest":info},()=>{console.log("Settings saved")});
console.log('Catch', settings.name,settings.property);
},{urls:["https://*/*"]});
};
})(chrome.storage.sync || chrome.storage.local);
background.js -подождите, пока настройки будут загружены с обещанием
((storage) => {
let settings = ((properties) => {
this.set = (properties) => {
for(key in properties || {}){
this[key]=properties[key];
}
return new Promise((ok,err) => {
storage.set(
properties
,() => {
ok(settings);
});
});
};
return new Promise((ok,err) => {
//Default values processing
for(key in properties || {}){
this[key]=properties[key];
}
// Listen settings change and cache it
chrome.storage.onChanged.addListener((msg) => {
for(key in msg){
this[key]=msg[key].newValue;
}
});
// Initial settings read
storage.get(properties,(properties) => {
for(key in properties){
this[key]=properties[key];
}
ok(this);
});
});
}).call({},{"property":"default","name":"me"}).then((settings) => {
//.. all you settings-sensitive code
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
// Update settings and persist it
settings.set({"lastRequest":info}).then(()=>{console.log("Settings saved")});
console.log('Catch', settings.name,settings.property);
},{urls:["https://*/*"]});
}).catch(()=>{});
})(chrome.storage.sync || chrome.storage.local);
Подробнее
- Характеристики хранилища / firefox: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage
- Спектр хранения / хром: https://developer.chrome.com/apps/storage
- Запросы на разрешение / firefox: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Request_the_right_permissions