1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-07 03:12:33 +01:00

this fixes #89

This commit is contained in:
gorhill 2014-07-22 12:26:11 -04:00
parent 59cdeab1ad
commit 34b80450e3

View File

@ -19,7 +19,7 @@
Home: https://github.com/gorhill/uBlock Home: https://github.com/gorhill/uBlock
*/ */
/* global chrome, µBlock */ /* global chrome, µBlock, YaMD5 */
/******************************************************************************* /*******************************************************************************
@ -63,11 +63,122 @@ File system structure:
var fileSystem; var fileSystem;
var fileSystemQuota = 40 * 1024 * 1024; var fileSystemQuota = 40 * 1024 * 1024;
var repositoryRoot = µBlock.projectServerRoot; var repositoryRoot = µBlock.projectServerRoot;
var nullFunc = function() { }; var nullFunc = function() {};
var thirdpartyHomeURLs = null; var thirdpartyHomeURLs = null;
/******************************************************************************/ /******************************************************************************/
var cachedAssetsManager = (function() {
var exports = {};
var entries = null;
var cachedAssetPathPrefix = 'cached_asset_content://';
var getEntries = function(callback) {
if ( entries !== null ) {
callback(entries);
return;
}
var onLoaded = function(bin) {
if ( chrome.runtime.lastError ) {
console.error(
'µBlock> cachedAssetsManager> getEntries():',
chrome.runtime.lastError.message
);
}
entries = bin.cached_asset_entries || {};
callback(entries);
};
chrome.storage.local.get('cached_asset_entries', onLoaded);
};
exports.load = function(path, cbSuccess, cbError) {
cbSuccess = cbSuccess || nullFunc;
cbError = cbError || cbSuccess;
var details = {
'path': path,
'content': ''
};
var cachedContentPath = cachedAssetPathPrefix + path;
var onLoaded = function(bin) {
if ( chrome.runtime.lastError ) {
details.error = 'Error: ' + chrome.runtime.lastError.message;
console.error('µBlock> cachedAssetsManager.load():', details.error);
cbError(details);
} else {
details.content = bin[cachedContentPath];
cbSuccess(details);
}
};
var onEntries = function(entries) {
if ( entries[path] === undefined ) {
details.error = 'Error: not found';
cbError(details);
return;
}
chrome.storage.local.get(cachedContentPath, onLoaded);
};
getEntries(onEntries);
};
exports.save = function(path, content, cbSuccess, cbError) {
cbSuccess = cbSuccess || nullFunc;
cbError = cbError || cbSuccess;
var details = {
path: path,
content: content
};
var cachedContentPath = cachedAssetPathPrefix + path;
var bin = {};
bin[cachedContentPath] = content;
var onSaved = function() {
if ( chrome.runtime.lastError ) {
details.error = 'Error: ' + chrome.runtime.lastError.message;
console.error('µBlock> cachedAssetsManager.save():', details.error);
cbError(details);
} else {
cbSuccess(details);
}
};
var onEntries = function(entries) {
if ( entries[path] === undefined ) {
entries[path] = true;
bin.cached_asset_entries = entries;
}
chrome.storage.local.set(bin, onSaved);
};
getEntries(onEntries);
};
exports.remove = function(pattern) {
var onEntries = function(entries) {
var keystoRemove = [];
var paths = Object.keys(entries);
var i = paths.length;
var path;
while ( i-- ) {
path = paths[i];
if ( typeof pattern === 'string' && path !== pattern ) {
continue;
}
if ( pattern instanceof RegExp && !pattern.test(path) ) {
continue;
}
keystoRemove.push(cachedAssetPathPrefix + path);
delete entries[path];
}
if ( keystoRemove.length ) {
chrome.storage.local.remove(keystoRemove);
chrome.storage.local.set({ 'cached_asset_entries': entries });
}
};
getEntries(onEntries);
};
return exports;
})();
/******************************************************************************/
var getTextFileFromURL = function(url, onLoad, onError) { var getTextFileFromURL = function(url, onLoad, onError) {
// console.log('µBlock> getTextFileFromURL("%s"):', url); // console.log('µBlock> getTextFileFromURL("%s"):', url);
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
@ -82,18 +193,20 @@ var getTextFileFromURL = function(url, onLoad, onError) {
/******************************************************************************/ /******************************************************************************/
// https://github.com/gorhill/uBlock/issues/89
// Remove when I am confident everybody moved to the new storage
// Useful to avoid having to manage a directory tree // Useful to avoid having to manage a directory tree
var cachePathFromPath = function(path) { var cachePathFromPath = function(path) {
return path.replace(/\//g, '___'); return path.replace(/\//g, '___');
}; };
var pathFromCachePath = function(path) {
return path.replace(/___/g, '/');
};
/******************************************************************************/ /******************************************************************************/
// https://github.com/gorhill/uBlock/issues/89
// Remove when I am confident everybody moved to the new storage
var requestFileSystem = function(onSuccess, onError) { var requestFileSystem = function(onSuccess, onError) {
if ( fileSystem ) { if ( fileSystem ) {
onSuccess(fileSystem); onSuccess(fileSystem);
@ -114,6 +227,61 @@ var requestFileSystem = function(onSuccess, onError) {
/******************************************************************************/ /******************************************************************************/
// https://github.com/gorhill/uBlock/issues/89
// Remove when I am confident everybody moved to the new storage
var oldReadCachedFile = function(path, callback) {
var reportBack = function(content, err) {
var details = {
'path': path,
'content': content,
'error': err
};
callback(details);
};
var onCacheFileLoaded = function() {
// console.log('µBlock> readLocalFile() / onCacheFileLoaded()');
reportBack(this.responseText);
this.onload = this.onerror = null;
};
var onCacheFileError = function(ev) {
// This handler may be called under normal circumstances: it appears
// the entry may still be present even after the file was removed.
// console.error('µBlock> readLocalFile() / onCacheFileError("%s")', path);
reportBack('', 'Error');
this.onload = this.onerror = null;
};
var onCacheEntryFound = function(entry) {
// console.log('µBlock> readLocalFile() / onCacheEntryFound():', entry.toURL());
// rhill 2014-04-18: `ublock` query parameter is added to ensure
// the browser cache is bypassed.
getTextFileFromURL(entry.toURL() + '?ublock=' + Date.now(), onCacheFileLoaded, onCacheFileError);
};
var onCacheEntryError = function(err) {
if ( err.name !== 'NotFoundError' ) {
console.error('µBlock> readLocalFile() / onCacheEntryError("%s"):', path, err.name);
}
reportBack('', 'Error');
};
var onRequestFileSystemSuccess = function(fs) {
fs.root.getFile(cachePathFromPath(path), null, onCacheEntryFound, onCacheEntryError);
};
var onRequestFileSystemError = function(err) {
console.error('µBlock> readLocalFile() / onRequestFileSystemError():', err.name);
reportBack('', 'Error');
};
requestFileSystem(onRequestFileSystemSuccess, onRequestFileSystemError);
};
/******************************************************************************/
// Flush cached non-user assets if these are from a prior version. // Flush cached non-user assets if these are from a prior version.
// https://github.com/gorhill/httpswitchboard/issues/212 // https://github.com/gorhill/httpswitchboard/issues/212
@ -125,6 +293,9 @@ var synchronizeCache = function() {
} }
cacheSynchronized = true; cacheSynchronized = true;
// https://github.com/gorhill/uBlock/issues/89
// Remove when I am confident everybody moved to the new storage
var directoryReader; var directoryReader;
var done = function() { var done = function() {
directoryReader = null; directoryReader = null;
@ -138,12 +309,9 @@ var synchronizeCache = function() {
var entry; var entry;
for ( var i = 0; i < n; i++ ) { for ( var i = 0; i < n; i++ ) {
entry = entries[i]; entry = entries[i];
// Ignore whatever is in 'user' folder: these are NOT cached entries.
if ( pathFromCachePath(entry.fullPath).indexOf('/assets/user/') >= 0 ) {
continue;
}
entry.remove(nullFunc); entry.remove(nullFunc);
} }
// Read entries until none returned.
directoryReader.readEntries(onReadEntries, onReadEntriesError); directoryReader.readEntries(onReadEntries, onReadEntriesError);
}; };
@ -169,10 +337,27 @@ var synchronizeCache = function() {
return done(); return done();
} }
chrome.storage.local.set({ 'extensionLastVersion': currentVersion }); chrome.storage.local.set({ 'extensionLastVersion': currentVersion });
cachedAssetsManager.remove(/^assets\/(ublock|thirdparties)\//);
cachedAssetsManager.remove('assets/checksums.txt');
requestFileSystem(onRequestFileSystemSuccess, onRequestFileSystemError); requestFileSystem(onRequestFileSystemSuccess, onRequestFileSystemError);
}; };
chrome.storage.local.get('extensionLastVersion', onLastVersionRead); // https://github.com/gorhill/uBlock/issues/89
// Backward compatiblity.
var onUserFiltersSaved = function() {
chrome.storage.local.get('extensionLastVersion', onLastVersionRead);
};
var onUserFiltersLoaded = function(details) {
if ( details.content !== '' ) {
cachedAssetsManager.save(details.path, details.content, onUserFiltersSaved);
} else {
chrome.storage.local.get('extensionLastVersion', onLastVersionRead);
}
};
oldReadCachedFile('assets/user/filters.txt', onUserFiltersLoaded);
}; };
/******************************************************************************/ /******************************************************************************/
@ -181,9 +366,11 @@ var readLocalFile = function(path, callback) {
var reportBack = function(content, err) { var reportBack = function(content, err) {
var details = { var details = {
'path': path, 'path': path,
'content': content, 'content': content
'error': err
}; };
if ( err ) {
details.error = err;
}
callback(details); callback(details);
}; };
@ -199,44 +386,17 @@ var readLocalFile = function(path, callback) {
this.onload = this.onerror = null; this.onload = this.onerror = null;
}; };
var onCacheFileLoaded = function() { var onCachedContentLoaded = function(details) {
// console.log('µBlock> readLocalFile() / onCacheFileLoaded()'); // console.log('µBlock> readLocalFile() / onCacheFileLoaded()');
reportBack(this.responseText); reportBack(details.content);
this.onload = this.onerror = null;
}; };
var onCacheFileError = function(ev) { var onCachedContentError = function(details) {
// This handler may be called under normal circumstances: it appears
// the entry may still be present even after the file was removed.
// console.error('µBlock> readLocalFile() / onCacheFileError("%s")', path); // console.error('µBlock> readLocalFile() / onCacheFileError("%s")', path);
getTextFileFromURL(chrome.runtime.getURL(path), onLocalFileLoaded, onLocalFileError); getTextFileFromURL(chrome.runtime.getURL(details.path), onLocalFileLoaded, onLocalFileError);
this.onload = this.onerror = null;
}; };
var onCacheEntryFound = function(entry) { cachedAssetsManager.load(path, onCachedContentLoaded, onCachedContentError);
// console.log('µBlock> readLocalFile() / onCacheEntryFound():', entry.toURL());
// rhill 2014-04-18: `ublock` query parameter is added to ensure
// the browser cache is bypassed.
getTextFileFromURL(entry.toURL() + '?ublock=' + Date.now(), onCacheFileLoaded, onCacheFileError);
};
var onCacheEntryError = function(err) {
if ( err.name !== 'NotFoundError' ) {
console.error('µBlock> readLocalFile() / onCacheEntryError("%s"):', path, err.name);
}
getTextFileFromURL(chrome.runtime.getURL(path), onLocalFileLoaded, onLocalFileError);
};
var onRequestFileSystemSuccess = function(fs) {
fs.root.getFile(cachePathFromPath(path), null, onCacheEntryFound, onCacheEntryError);
};
var onRequestFileSystemError = function(err) {
console.error('µBlock> readLocalFile() / onRequestFileSystemError():', err.name);
getTextFileFromURL(chrome.runtime.getURL(path), onLocalFileLoaded, onLocalFileError);
};
requestFileSystem(onRequestFileSystemSuccess, onRequestFileSystemError);
}; };
/******************************************************************************/ /******************************************************************************/
@ -273,75 +433,13 @@ var readRemoteFile = function(path, callback) {
repositoryRoot + path + '?ublock=' + Date.now(), repositoryRoot + path + '?ublock=' + Date.now(),
onRemoteFileLoaded, onRemoteFileLoaded,
onRemoteFileError onRemoteFileError
); );
}; };
/******************************************************************************/ /******************************************************************************/
var writeLocalFile = function(path, content, callback) { var writeLocalFile = function(path, content, callback) {
var reportBack = function(err) { cachedAssetsManager.save(path, content, callback);
var details = {
'path': path,
'content': content,
'error': err
};
callback(details);
};
var onFileWriteSuccess = function() {
// console.log('µBlock> writeLocalFile() / onFileWriteSuccess("%s")', path);
reportBack();
};
var onFileWriteError = function(err) {
console.error('µBlock> writeLocalFile() / onFileWriteError("%s"):', path, err.name);
reportBack(err.name);
};
var onFileTruncateSuccess = function() {
// console.log('µBlock> writeLocalFile() / onFileTruncateSuccess("%s")', path);
this.onwriteend = onFileWriteSuccess;
this.onerror = onFileWriteError;
var blob = new Blob([content], { type: 'text/plain' });
this.write(blob);
};
var onFileTruncateError = function(err) {
console.error('µBlock> writeLocalFile() / onFileTruncateError("%s"):', path, err.name);
reportBack(err.name);
};
var onCreateFileWriterSuccess = function(fwriter) {
fwriter.onwriteend = onFileTruncateSuccess;
fwriter.onerror = onFileTruncateError;
fwriter.truncate(0);
};
var onCreateFileWriterError = function(err) {
console.error('µBlock> writeLocalFile() / onCreateFileWriterError("%s"):', path, err.name);
reportBack(err.name);
};
var onCacheEntryFound = function(file) {
// console.log('µBlock> writeLocalFile() / onCacheEntryFound():', file.toURL());
file.createWriter(onCreateFileWriterSuccess, onCreateFileWriterError);
};
var onCacheEntryError = function(err) {
console.error('µBlock> writeLocalFile() / onCacheEntryError("%s"):', path, err.name);
reportBack(err.name);
};
var onRequestFileSystemError = function(err) {
console.error('µBlock> writeLocalFile() / onRequestFileSystemError():', err.name);
reportBack(err.name);
};
var onRequestFileSystem = function(fs) {
fs.root.getFile(cachePathFromPath(path), { create: true }, onCacheEntryFound, onCacheEntryError);
};
requestFileSystem(onRequestFileSystem, onRequestFileSystemError);
}; };
/******************************************************************************/ /******************************************************************************/
@ -487,4 +585,3 @@ return {
})(); })();
/******************************************************************************/ /******************************************************************************/