From b12e0e05ea9d319ba3b6c2b97d9322c347230bd7 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 18 Nov 2020 10:02:22 -0500 Subject: [PATCH] Extract `Homepage` URL from a list when present Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/1346 Additionally, fixed a case of filter list being compiled twice at subscription time. --- src/js/assets.js | 11 ++++++++--- src/js/storage.js | 39 ++++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/js/assets.js b/src/js/assets.js index 3390351fa..b173ba151 100644 --- a/src/js/assets.js +++ b/src/js/assets.js @@ -538,10 +538,12 @@ const assetCacheRead = async function(assetKey, updateReadTime = false) { const assetCacheWrite = async function(assetKey, details) { let content = ''; + let options = {}; if ( typeof details === 'string' ) { content = details; } else if ( details instanceof Object ) { content = details.content || ''; + options = details; } if ( content === '' ) { @@ -555,8 +557,8 @@ const assetCacheWrite = async function(assetKey, details) { entry = cacheDict[assetKey] = {}; } entry.writeTime = entry.readTime = Date.now(); - if ( details instanceof Object && typeof details.url === 'string' ) { - entry.remoteURL = details.url; + if ( options.url === 'string' ) { + entry.remoteURL = options.url; } µBlock.cacheStorage.set({ assetCacheRegistry, @@ -565,7 +567,9 @@ const assetCacheWrite = async function(assetKey, details) { const result = { assetKey, content }; // https://github.com/uBlockOrigin/uBlock-issues/issues/248 - fireNotification('after-asset-updated', result); + if ( options.silent !== true ) { + fireNotification('after-asset-updated', result); + } return result; }; @@ -733,6 +737,7 @@ api.get = async function(assetKey, options = {}) { assetCacheWrite(assetKey, { content: details.content, url: contentURL, + silent: options.silent === true, }); } return reportBack(details.content, contentURL); diff --git a/src/js/storage.js b/src/js/storage.js index 1fcde7527..96c190454 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -749,7 +749,7 @@ self.addEventListener('hiddenSettingsChanged', ( ) => { return { assetKey, content: '' }; } - const rawDetails = await this.assets.get(assetKey); + const rawDetails = await this.assets.get(assetKey, { silent: true }); // Compiling an empty string results in an empty string. if ( rawDetails.content === '' ) { rawDetails.assetKey = assetKey; @@ -782,6 +782,10 @@ self.addEventListener('hiddenSettingsChanged', ( ) => { // https://github.com/gorhill/uBlock/issues/3406 // Lower minimum update period to 1 day. +// https://bugs.chromium.org/p/v8/issues/detail?id=2869 +// orphanizeString is to work around String.slice() potentially causing +// the whole raw filter list to be held in memory just because we cut out +// the title as a substring. µBlock.extractFilterListMetadata = function(assetKey, raw) { const listEntry = this.availableFilterLists[assetKey]; @@ -790,27 +794,32 @@ self.addEventListener('hiddenSettingsChanged', ( ) => { const head = raw.slice(0, 1024); // https://github.com/gorhill/uBlock/issues/313 // Always try to fetch the name if this is an external filter list. - if ( listEntry.title === '' || listEntry.group === 'custom' ) { - const matches = head.match(/(?:^|\n)(?:!|# )[\t ]*Title[\t ]*:([^\n]+)/i); - if ( matches !== null ) { - // https://bugs.chromium.org/p/v8/issues/detail?id=2869 - // orphanizeString is to work around String.slice() - // potentially causing the whole raw filter list to be held in - // memory just because we cut out the title as a substring. - listEntry.title = this.orphanizeString(matches[1].trim()); + if ( listEntry.group === 'custom' ) { + let matches = head.match(/(?:^|\n)(?:!|# )[\t ]*Title[\t ]*:([^\n]+)/i); + const title = matches && matches[1].trim() || ''; + if ( title !== '' && title !== listEntry.title ) { + listEntry.title = this.orphanizeString(title); + this.assets.registerAssetSource(assetKey, { title }); + } + matches = head.match(/(?:^|\n)(?:!|# )[\t ]*Homepage[\t ]*:[\t ]*(https?:\/\/\S+)/i); + const supportURL = matches && matches[1] || ''; + if ( supportURL !== '' && supportURL !== listEntry.supportURL ) { + listEntry.supportURL = this.orphanizeString(supportURL); + this.assets.registerAssetSource(assetKey, { supportURL }); } } // Extract update frequency information const matches = head.match(/(?:^|\n)(?:!|# )[\t ]*Expires[\t ]*:[\t ]*(\d+)[\t ]*(h)?/i); if ( matches !== null ) { - let v = parseInt(matches[1], 10); - if ( isNaN(v) === false ) { + let updateAfter = parseInt(matches[1], 10); + if ( isNaN(updateAfter) === false ) { if ( matches[2] !== undefined ) { - v = Math.ceil(v / 24); + updateAfter = Math.ceil(updateAfter / 24); } - v = Math.max(v, 1); - if ( v !== listEntry.updateAfter ) { - this.assets.registerAssetSource(assetKey, { updateAfter: v }); + updateAfter = Math.max(updateAfter, 1); + if ( updateAfter !== listEntry.updateAfter ) { + listEntry.updateAfter = updateAfter; + this.assets.registerAssetSource(assetKey, { updateAfter }); } } }