|
|
@ -39,6 +39,16 @@ var manifest = chrome.runtime.getManifest(); |
|
|
|
|
|
|
|
vAPI.chrome = true; |
|
|
|
|
|
|
|
vAPI.webextFlavor = ''; |
|
|
|
if ( |
|
|
|
self.browser instanceof Object && |
|
|
|
typeof self.browser.runtime.getBrowserInfo === 'function' |
|
|
|
) { |
|
|
|
self.browser.runtime.getBrowserInfo().then(function(info) { |
|
|
|
vAPI.webextFlavor = info.vendor + '-' + info.name + '-' + info.version; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
var noopFunc = function(){}; |
|
|
|
|
|
|
|
/******************************************************************************/ |
|
|
@ -845,28 +855,49 @@ vAPI.cookies.remove = function(details, callback) { |
|
|
|
/******************************************************************************/ |
|
|
|
|
|
|
|
vAPI.cloud = (function() { |
|
|
|
// Not all platforms support `chrome.storage.sync`.
|
|
|
|
if ( chrome.storage.sync instanceof Object === false ) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var chunkCountPerFetch = 16; // Must be a power of 2
|
|
|
|
|
|
|
|
// Mind chrome.storage.sync.MAX_ITEMS (512 at time of writing)
|
|
|
|
var maxChunkCountPerItem = Math.floor(512 * 0.75) & ~(chunkCountPerFetch - 1); |
|
|
|
|
|
|
|
// Mind chrome.storage.sync.QUOTA_BYTES_PER_ITEM (8192 at time of writing)
|
|
|
|
var maxChunkSize = Math.floor(chrome.storage.sync.QUOTA_BYTES_PER_ITEM * 0.75); |
|
|
|
|
|
|
|
// Mind chrome.storage.sync.QUOTA_BYTES_PER_ITEM (8192 at time of writing)
|
|
|
|
var maxStorageSize = chrome.storage.sync.QUOTA_BYTES; |
|
|
|
var maxChunkSize = chrome.storage.sync.QUOTA_BYTES_PER_ITEM || 8192; |
|
|
|
|
|
|
|
// Mind chrome.storage.sync.QUOTA_BYTES (128 kB at time of writing)
|
|
|
|
// Firefox:
|
|
|
|
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/sync
|
|
|
|
// > You can store up to 100KB of data using this API/
|
|
|
|
var maxStorageSize = chrome.storage.sync.QUOTA_BYTES || 102400; |
|
|
|
|
|
|
|
// Flavor-specific handling needs to be done here. Reason: to allow time
|
|
|
|
// for vAPI.webextFlavor to be properly set.
|
|
|
|
// https://github.com/gorhill/uBlock/issues/3006
|
|
|
|
// For Firefox, we will use a lower ratio to allow for more overhead for
|
|
|
|
// the infrastructure. Unfortunately this leads to less usable space for
|
|
|
|
// actual data, but all of this is provided for free by browser vendors,
|
|
|
|
// so we need to accept and deal with these limitations.
|
|
|
|
var initialize = function() { |
|
|
|
var ratio = vAPI.webextFlavor.startsWith('Mozilla-Firefox-') ? 0.6 : 0.75; |
|
|
|
maxChunkSize = Math.floor(maxChunkSize * ratio); |
|
|
|
initialize = function(){}; |
|
|
|
}; |
|
|
|
|
|
|
|
var options = { |
|
|
|
defaultDeviceName: window.navigator.platform, |
|
|
|
deviceName: window.localStorage.getItem('deviceName') || '' |
|
|
|
deviceName: vAPI.localStorage.getItem('deviceName') || '' |
|
|
|
}; |
|
|
|
|
|
|
|
// This is used to find out a rough count of how many chunks exists:
|
|
|
|
// We "poll" at specific index in order to get a rough idea of how
|
|
|
|
// large is the stored string.
|
|
|
|
// This allows reading a single item with only 2 sync operations -- a
|
|
|
|
// good thing given chrome.storage.syncMAX_WRITE_OPERATIONS_PER_MINUTE
|
|
|
|
// and chrome.storage.syncMAX_WRITE_OPERATIONS_PER_HOUR.
|
|
|
|
// good thing given chrome.storage.sync.MAX_WRITE_OPERATIONS_PER_MINUTE
|
|
|
|
// and chrome.storage.sync.MAX_WRITE_OPERATIONS_PER_HOUR.
|
|
|
|
|
|
|
|
var getCoarseChunkCount = function(dataKey, callback) { |
|
|
|
var bin = {}; |
|
|
@ -912,6 +943,8 @@ vAPI.cloud = (function() { |
|
|
|
}; |
|
|
|
|
|
|
|
var push = function(dataKey, data, callback) { |
|
|
|
initialize(); |
|
|
|
|
|
|
|
var bin = { |
|
|
|
'source': options.deviceName || options.defaultDeviceName, |
|
|
|
'tstamp': Date.now(), |
|
|
@ -921,7 +954,7 @@ vAPI.cloud = (function() { |
|
|
|
bin.size = JSON.stringify(bin).length; |
|
|
|
var item = JSON.stringify(bin); |
|
|
|
|
|
|
|
// Chunkify taking into account QUOTA_BYTES_PER_ITEM:
|
|
|
|
// Chunkify taking into account QUOTA_BYTES_PER_ITEM:
|
|
|
|
// https://developer.chrome.com/extensions/storage#property-sync
|
|
|
|
// "The maximum size (in bytes) of each individual item in sync
|
|
|
|
// "storage, as measured by the JSON stringification of its value
|
|
|
@ -937,6 +970,9 @@ vAPI.cloud = (function() { |
|
|
|
var errorStr; |
|
|
|
if ( chrome.runtime.lastError ) { |
|
|
|
errorStr = chrome.runtime.lastError.message; |
|
|
|
// https://github.com/gorhill/uBlock/issues/3006#issuecomment-332597677
|
|
|
|
// - Delete all that was pushed in case of failure.
|
|
|
|
chunkCount = 0; |
|
|
|
} |
|
|
|
callback(errorStr); |
|
|
|
|
|
|
@ -946,6 +982,8 @@ vAPI.cloud = (function() { |
|
|
|
}; |
|
|
|
|
|
|
|
var pull = function(dataKey, callback) { |
|
|
|
initialize(); |
|
|
|
|
|
|
|
var assembleChunks = function(bin) { |
|
|
|
if ( chrome.runtime.lastError ) { |
|
|
|
callback(null, chrome.runtime.lastError.message); |
|
|
@ -1002,7 +1040,7 @@ vAPI.cloud = (function() { |
|
|
|
} |
|
|
|
|
|
|
|
if ( typeof details.deviceName === 'string' ) { |
|
|
|
window.localStorage.setItem('deviceName', details.deviceName); |
|
|
|
vAPI.localStorage.setItem('deviceName', details.deviceName); |
|
|
|
options.deviceName = details.deviceName; |
|
|
|
} |
|
|
|
|
|
|
|