From 0d6a18207aaea3f995acb5f8d02dcd1dfba044fd Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 5 Dec 2018 15:57:41 -0500 Subject: [PATCH] fix https://github.com/uBlockOrigin/uBlock-issues/issues/329 --- src/js/assets.js | 63 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/js/assets.js b/src/js/assets.js index f1da642a2..b02c43fd8 100644 --- a/src/js/assets.js +++ b/src/js/assets.js @@ -172,42 +172,67 @@ api.fetchText = function(url, onLoad, onError) { // Support the seamless loading of sublists. api.fetchFilterList = function(mainlistURL, onLoad, onError) { - var content = [], - errored = false, - pendingSublistURLs = new Set([ mainlistURL ]), - loadedSublistURLs = new Set(), - toParsedURL = api.fetchFilterList.toParsedURL, - parsedURL = toParsedURL(mainlistURL); + const content = []; + const pendingSublistURLs = new Set([ mainlistURL ]); + const loadedSublistURLs = new Set(); + const toParsedURL = api.fetchFilterList.toParsedURL; + const parsedURL = toParsedURL(mainlistURL); - var processIncludeDirectives = function(details) { - var reInclude = /^!#include +(\S+)/gm; + let errored = false; + + const processIncludeDirectives = function(details) { + const reInclude = /^!#include +(\S+)/gm; + const out = []; + const content = details.content; + let lastIndex = 0; for (;;) { - var match = reInclude.exec(details.content); + const match = reInclude.exec(content); if ( match === null ) { break; } if ( toParsedURL(match[1]) !== undefined ) { continue; } if ( match[1].indexOf('..') !== -1 ) { continue; } - var subURL = - parsedURL.origin + - parsedURL.pathname.replace(/[^/]+$/, match[1]); + const subURL = parsedURL.origin + + parsedURL.pathname.replace(/[^/]+$/, match[1]); if ( pendingSublistURLs.has(subURL) ) { continue; } if ( loadedSublistURLs.has(subURL) ) { continue; } pendingSublistURLs.add(subURL); api.fetchText(subURL, onLocalLoadSuccess, onLocalLoadError); + out.push(content.slice(lastIndex, match.index).trim(), subURL); + lastIndex = reInclude.lastIndex; } + out.push(lastIndex === 0 ? content : content.slice(lastIndex).trim()); + return out; }; - var onLocalLoadSuccess = function(details) { + const onLocalLoadSuccess = function(details) { if ( errored ) { return; } - var isSublist = details.url !== mainlistURL; + const isSublist = details.url !== mainlistURL; pendingSublistURLs.delete(details.url); loadedSublistURLs.add(details.url); - if ( isSublist ) { content.push('\n! ' + '>>>>>>>> ' + details.url); } - content.push(details.content.trim()); - if ( isSublist ) { content.push('! <<<<<<<< ' + details.url); } + + // https://github.com/uBlockOrigin/uBlock-issues/issues/329 + // Insert fetched content at position of related #!include directive + let slot = isSublist ? content.indexOf(details.url) : 0; + if ( isSublist ) { + content.splice( + slot, + 1, + '! >>>>>>>> ' + details.url, + details.content.trim(), + '! <<<<<<<< ' + details.url + ); + slot += 1; + } else { + content[0] = details.content.trim(); + } + + // Find and process #!include directives if ( parsedURL !== undefined && parsedURL.pathname.length > 0 ) { - processIncludeDirectives(details); + const processed = processIncludeDirectives(details); + if ( processed.length > 1 ) { + content.splice(slot, 1, ...processed); + } } if ( pendingSublistURLs.size !== 0 ) { return; } @@ -221,7 +246,7 @@ api.fetchFilterList = function(mainlistURL, onLoad, onError) { // Not checking for `errored` status was causing repeated notifications // to the caller. This can happen when more than one out of multiple // sublists can't be fetched. - var onLocalLoadError = function(details) { + const onLocalLoadError = function(details) { if ( errored ) { return; } errored = true;