mirror of
https://github.com/gorhill/uBlock.git
synced 2024-10-04 16:47:15 +02:00
Remove usage of synchronous localStorage API
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/899 browser.storage.local is now used to store non-critical local settings. These settings are all collated under the key `localStorage`, and vAPI.localStorage is an API to handle access to these values stored under this key. vAPI.localStorage.getItem() is still synchronous but its purpose is to return internally cached values -- this minimizes code changes throughout uBO.
This commit is contained in:
parent
5da3aaaabf
commit
2ac288397c
@ -218,48 +218,92 @@ vAPI.closePopup = function() {
|
||||
// background page or auxiliary pages.
|
||||
// This storage is optional, but it is nice to have, for a more polished user
|
||||
// experience.
|
||||
|
||||
//
|
||||
// https://github.com/gorhill/uBlock/issues/2824
|
||||
// Use a dummy localStorage if for some reasons it's not available.
|
||||
|
||||
//
|
||||
// https://github.com/gorhill/uMatrix/issues/840
|
||||
// Always use a wrapper to seamlessly handle exceptions
|
||||
//
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/899
|
||||
// Convert into asynchronous access API.
|
||||
|
||||
vAPI.localStorage = {
|
||||
started: false,
|
||||
start: function() {
|
||||
this.started = true;
|
||||
if ( this.cache instanceof Object ) { return Promise.resolve(); }
|
||||
if ( this.promise !== undefined ) { return this.promise; }
|
||||
this.promise = new Promise(resolve => {
|
||||
browser.storage.local.get('localStorage', bin => {
|
||||
if (
|
||||
bin instanceof Object === false ||
|
||||
bin.localStorage instanceof Object === false
|
||||
) {
|
||||
this.cache = {};
|
||||
const ls = self.localStorage;
|
||||
for ( let i = 0; i < ls.length; i++ ) {
|
||||
const key = ls.key(i);
|
||||
this.cache[key] = ls.getItem(key);
|
||||
}
|
||||
//ls.clear();
|
||||
browser.storage.local.set({ localStorage: this.cache });
|
||||
} else {
|
||||
try {
|
||||
this.cache = bin.localStorage;
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
if ( this.cache instanceof Object === false ) {
|
||||
this.cache = {};
|
||||
}
|
||||
this.promise = undefined;
|
||||
browser.storage.onChanged.addListener((changes, area) => {
|
||||
if (
|
||||
area !== 'local' ||
|
||||
changes instanceof Object === false ||
|
||||
changes.localStorage instanceof Object === false
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const newValue = changes.localStorage.newValue;
|
||||
this.cache = newValue instanceof Object ? newValue : {};
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return this.promise;
|
||||
},
|
||||
clear: function() {
|
||||
try {
|
||||
window.localStorage.clear();
|
||||
} catch(ex) {
|
||||
}
|
||||
this.cache = {};
|
||||
return browser.storage.local.set({ localStorage: this.cache });
|
||||
},
|
||||
getItem: function(key) {
|
||||
if ( this.started === false ) { return null; }
|
||||
try {
|
||||
return window.localStorage.getItem(key);
|
||||
} catch(ex) {
|
||||
if ( this.cache instanceof Object === false ) {
|
||||
console.info(`localStorage.getItem('${key}') not ready`);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
const value = this.cache[key];
|
||||
return value !== undefined ? value : null;
|
||||
},
|
||||
getItemAsync: function(key) {
|
||||
return this.start().then(( ) => {
|
||||
const value = this.cache[key];
|
||||
return value !== undefined ? value : null;
|
||||
});
|
||||
},
|
||||
removeItem: function(key) {
|
||||
try {
|
||||
window.localStorage.removeItem(key);
|
||||
} catch(ex) {
|
||||
}
|
||||
this.setItem(key);
|
||||
},
|
||||
setItem: function(key, value) {
|
||||
if ( this.started === false ) { return; }
|
||||
try {
|
||||
window.localStorage.setItem(key, value);
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
setItem: function(key, value = undefined) {
|
||||
return this.start().then(( ) => {
|
||||
this.cache[key] = value;
|
||||
return browser.storage.local.set({ localStorage: this.cache });
|
||||
});
|
||||
},
|
||||
promise: undefined,
|
||||
cache: undefined,
|
||||
};
|
||||
|
||||
|
||||
vAPI.localStorage.start();
|
||||
|
||||
|
||||
|
||||
|
@ -45,20 +45,6 @@ let cachedUserFilters = '';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/3706
|
||||
// Save/restore cursor position
|
||||
//
|
||||
// CoreMirror reference: https://codemirror.net/doc/manual.html#api_selection
|
||||
|
||||
window.addEventListener('beforeunload', ( ) => {
|
||||
vAPI.localStorage.setItem(
|
||||
'myFiltersCursorPosition',
|
||||
JSON.stringify(cmEditor.getCursor().line)
|
||||
);
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// This is to give a visual hint that the content of user blacklist has changed.
|
||||
|
||||
const userFiltersChanged = function(changed) {
|
||||
@ -71,7 +57,7 @@ const userFiltersChanged = function(changed) {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const renderUserFilters = async function(first) {
|
||||
const renderUserFilters = async function() {
|
||||
const details = await vAPI.messaging.send('dashboard', {
|
||||
what: 'readUserFilters',
|
||||
});
|
||||
@ -83,18 +69,7 @@ const renderUserFilters = async function(first) {
|
||||
content += '\n';
|
||||
}
|
||||
cmEditor.setValue(content);
|
||||
if ( first ) {
|
||||
cmEditor.clearHistory();
|
||||
try {
|
||||
const line = JSON.parse(
|
||||
vAPI.localStorage.getItem('myFiltersCursorPosition')
|
||||
);
|
||||
if ( typeof line === 'number' ) {
|
||||
cmEditor.setCursor(line, 0);
|
||||
}
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
|
||||
userFiltersChanged(false);
|
||||
};
|
||||
|
||||
@ -224,7 +199,24 @@ uDom('#exportUserFiltersToFile').on('click', exportUserFiltersToFile);
|
||||
uDom('#userFiltersApply').on('click', ( ) => { applyChanges(); });
|
||||
uDom('#userFiltersRevert').on('click', revertChanges);
|
||||
|
||||
renderUserFilters(true);
|
||||
// https://github.com/gorhill/uBlock/issues/3706
|
||||
// Save/restore cursor position
|
||||
//
|
||||
// CoreMirror reference: https://codemirror.net/doc/manual.html#api_selection
|
||||
renderUserFilters().then(( ) => {
|
||||
cmEditor.clearHistory();
|
||||
return vAPI.localStorage.getItemAsync('myFiltersCursorPosition');
|
||||
}).then(line => {
|
||||
if ( typeof line === 'number' ) {
|
||||
cmEditor.setCursor(line, 0);
|
||||
}
|
||||
cmEditor.on('cursorActivity', ( ) => {
|
||||
const line = cmEditor.getCursor().line;
|
||||
if ( vAPI.localStorage.getItem('myFiltersCursorPosition') !== line ) {
|
||||
vAPI.localStorage.setItem('myFiltersCursorPosition', line);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
cmEditor.on('changes', userFiltersChanged);
|
||||
CodeMirror.commands.save = applyChanges;
|
||||
|
@ -34,7 +34,7 @@ const reValidExternalList = /[a-z-]+:\/\/\S*\/\S+/;
|
||||
|
||||
let listDetails = {};
|
||||
let filteringSettingsHash = '';
|
||||
let hideUnusedSet = new Set();
|
||||
let hideUnusedSet = new Set([ '*' ]);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
@ -258,10 +258,6 @@ const renderFilterLists = function(soft) {
|
||||
let groupKey = groupKeys[i];
|
||||
let liGroup = liFromListGroup(groupKey, groups.get(groupKey));
|
||||
liGroup.setAttribute('data-groupkey', groupKey);
|
||||
liGroup.classList.toggle(
|
||||
'collapsed',
|
||||
vAPI.localStorage.getItem('collapseGroup' + (i + 1)) === 'y'
|
||||
);
|
||||
if ( liGroup.parentElement === null ) {
|
||||
ulLists.appendChild(liGroup);
|
||||
}
|
||||
@ -548,7 +544,7 @@ const toggleHideUnusedLists = function(which) {
|
||||
.toggleClass('unused', mustHide);
|
||||
vAPI.localStorage.setItem(
|
||||
'hideUnusedFilterLists',
|
||||
JSON.stringify(Array.from(hideUnusedSet))
|
||||
Array.from(hideUnusedSet)
|
||||
);
|
||||
};
|
||||
|
||||
@ -571,20 +567,11 @@ uDom('#lists').on('click', '.groupEntry[data-groupkey] > .geDetails', function(e
|
||||
});
|
||||
|
||||
// Initialize from saved state.
|
||||
{
|
||||
let aa;
|
||||
try {
|
||||
const json = vAPI.localStorage.getItem('hideUnusedFilterLists');
|
||||
if ( json !== null ) {
|
||||
aa = JSON.parse(json);
|
||||
}
|
||||
} catch (ex) {
|
||||
vAPI.localStorage.getItemAsync('hideUnusedFilterLists').then(value => {
|
||||
if ( Array.isArray(value) ) {
|
||||
hideUnusedSet = new Set(value);
|
||||
}
|
||||
if ( Array.isArray(aa) === false ) {
|
||||
aa = [ '*' ];
|
||||
}
|
||||
hideUnusedSet = new Set(aa);
|
||||
}
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -84,10 +84,10 @@ const discardUnsavedData = function(synchronous = false) {
|
||||
|
||||
const loadDashboardPanel = function(pane = '') {
|
||||
if ( pane === '' ) {
|
||||
pane = vAPI.localStorage.getItem('dashboardLastVisitedPane');
|
||||
if ( pane === null ) {
|
||||
pane = 'settings.html';
|
||||
}
|
||||
vAPI.localStorage.getItemAsync('dashboardLastVisitedPane').then(value => {
|
||||
loadDashboardPanel(value !== null ? value : 'settings.html');
|
||||
});
|
||||
return;
|
||||
}
|
||||
const tabButton = uDom(`[href="#${pane}"]`);
|
||||
if ( !tabButton || tabButton.hasClass('selected') ) { return; }
|
||||
|
@ -194,10 +194,12 @@ uDom.nodeFromId('why').textContent = details.fs;
|
||||
);
|
||||
});
|
||||
|
||||
uDom.nodeFromId('theURL').classList.toggle(
|
||||
'collapsed',
|
||||
vAPI.localStorage.getItem('document-blocked-expand-url') !== 'true'
|
||||
);
|
||||
vAPI.localStorage.getItemAsync('document-blocked-expand-url').then(value => {
|
||||
uDom.nodeFromId('theURL').classList.toggle(
|
||||
'collapsed',
|
||||
value !== 'true' && value !== true
|
||||
);
|
||||
});
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -2675,9 +2675,9 @@ const loggerSettings = (( ) => {
|
||||
linesPerEntry: 4,
|
||||
};
|
||||
|
||||
{
|
||||
vAPI.localStorage.getItemAsync('loggerSettings').then(value => {
|
||||
try {
|
||||
const stored = JSON.parse(vAPI.localStorage.getItem('loggerSettings'));
|
||||
const stored = JSON.parse(value);
|
||||
if ( typeof stored.discard.maxAge === 'number' ) {
|
||||
settings.discard.maxAge = stored.discard.maxAge;
|
||||
}
|
||||
@ -2695,7 +2695,7 @@ const loggerSettings = (( ) => {
|
||||
}
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const valueFromInput = function(input, def) {
|
||||
let value = parseInt(input.value, 10);
|
||||
|
@ -30,19 +30,23 @@
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
let popupFontSize = vAPI.localStorage.getItem('popupFontSize');
|
||||
if ( typeof popupFontSize === 'string' && popupFontSize !== 'unset' ) {
|
||||
document.body.style.setProperty('font-size', popupFontSize);
|
||||
}
|
||||
let popupFontSize;
|
||||
vAPI.localStorage.getItemAsync('popupFontSize').then(value => {
|
||||
if ( typeof value !== 'string' || value === 'unset' ) { return; }
|
||||
document.body.style.setProperty('font-size', value);
|
||||
popupFontSize = value;
|
||||
});
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/996
|
||||
// Experimental: mitigate glitchy popup UI: immediately set the firewall
|
||||
// pane visibility to its last known state. By default the pane is hidden.
|
||||
let dfPaneVisibleStored =
|
||||
vAPI.localStorage.getItem('popupFirewallPane') === 'true';
|
||||
if ( dfPaneVisibleStored ) {
|
||||
document.getElementById('main').classList.add('dfEnabled');
|
||||
}
|
||||
// Experimental: mitigate glitchy popup UI: immediately set the firewall
|
||||
// pane visibility to its last known state. By default the pane is hidden.
|
||||
let dfPaneVisibleStored;
|
||||
vAPI.localStorage.getItemAsync('popupFirewallPane').then(value => {
|
||||
dfPaneVisibleStored = value === true || value === 'true';
|
||||
if ( dfPaneVisibleStored ) {
|
||||
document.getElementById('panes').classList.add('dfEnabled');
|
||||
}
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
@ -838,11 +842,8 @@ document.addEventListener(
|
||||
|
||||
const expandExceptions = new Set();
|
||||
|
||||
(( ) => {
|
||||
vAPI.localStorage.getItemAsync('popupExpandExceptions').then(exceptions => {
|
||||
try {
|
||||
const exceptions = JSON.parse(
|
||||
vAPI.localStorage.getItem('popupExpandExceptions')
|
||||
);
|
||||
if ( Array.isArray(exceptions) === false ) { return; }
|
||||
for ( const exception of exceptions ) {
|
||||
expandExceptions.add(exception);
|
||||
@ -850,13 +851,12 @@ const expandExceptions = new Set();
|
||||
}
|
||||
catch(ex) {
|
||||
}
|
||||
|
||||
})();
|
||||
});
|
||||
|
||||
const saveExpandExceptions = function() {
|
||||
vAPI.localStorage.setItem(
|
||||
'popupExpandExceptions',
|
||||
JSON.stringify(Array.from(expandExceptions))
|
||||
Array.from(expandExceptions)
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -29,10 +29,12 @@
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
let popupFontSize = vAPI.localStorage.getItem('popupFontSize');
|
||||
if ( typeof popupFontSize === 'string' && popupFontSize !== 'unset' ) {
|
||||
document.body.style.setProperty('font-size', popupFontSize);
|
||||
}
|
||||
let popupFontSize;
|
||||
vAPI.localStorage.getItemAsync('popupFontSize').then(value => {
|
||||
if ( typeof value !== 'string' || value === 'unset' ) { return; }
|
||||
document.body.style.setProperty('font-size', value);
|
||||
popupFontSize = value;
|
||||
});
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/3032
|
||||
// Popup panel can be in one of two modes:
|
||||
@ -48,13 +50,15 @@ if (
|
||||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/996
|
||||
// Experimental: mitigate glitchy popup UI: immediately set the firewall
|
||||
// pane visibility to its last known state. By default the pane is hidden.
|
||||
let dfPaneVisibleStored =
|
||||
vAPI.localStorage.getItem('popupFirewallPane') === 'true';
|
||||
if ( dfPaneVisibleStored ) {
|
||||
document.getElementById('panes').classList.add('dfEnabled');
|
||||
}
|
||||
// Experimental: mitigate glitchy popup UI: immediately set the firewall
|
||||
// pane visibility to its last known state. By default the pane is hidden.
|
||||
let dfPaneVisibleStored;
|
||||
vAPI.localStorage.getItemAsync('popupFirewallPane').then(value => {
|
||||
dfPaneVisibleStored = value === true || value === 'true';
|
||||
if ( dfPaneVisibleStored ) {
|
||||
document.getElementById('panes').classList.add('dfEnabled');
|
||||
}
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
@ -931,11 +935,8 @@ document.addEventListener(
|
||||
|
||||
const expandExceptions = new Set();
|
||||
|
||||
(( ) => {
|
||||
vAPI.localStorage.getItemAsync('popupExpandExceptions').then(exceptions => {
|
||||
try {
|
||||
const exceptions = JSON.parse(
|
||||
vAPI.localStorage.getItem('popupExpandExceptions')
|
||||
);
|
||||
if ( Array.isArray(exceptions) === false ) { return; }
|
||||
for ( const exception of exceptions ) {
|
||||
expandExceptions.add(exception);
|
||||
@ -943,13 +944,12 @@ const expandExceptions = new Set();
|
||||
}
|
||||
catch(ex) {
|
||||
}
|
||||
|
||||
})();
|
||||
});
|
||||
|
||||
const saveExpandExceptions = function() {
|
||||
vAPI.localStorage.setItem(
|
||||
'popupExpandExceptions',
|
||||
JSON.stringify(Array.from(expandExceptions))
|
||||
Array.from(expandExceptions)
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -316,10 +316,6 @@ if ( selfieIsValid !== true ) {
|
||||
// Start network observers.
|
||||
µb.webRequest.start();
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/899
|
||||
// Signal that localStorage can be used now that uBO is ready.
|
||||
vAPI.localStorage.start();
|
||||
|
||||
// Ensure that the resources allocated for decompression purpose (likely
|
||||
// large buffers) are garbage-collectable immediately after launch.
|
||||
// Otherwise I have observed that it may take quite a while before the
|
||||
|
Loading…
Reference in New Issue
Block a user