From fedb7c5b7c648aac014b53ce4f86fe097e0b5bf5 Mon Sep 17 00:00:00 2001 From: gorhill Date: Thu, 22 Jan 2015 14:40:55 -0500 Subject: [PATCH 01/10] see https://github.com/gorhill/uBlock/issues/510#issuecomment-71078475 --- assets/checksums.txt | 2 +- assets/ublock/filters.txt | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/assets/checksums.txt b/assets/checksums.txt index 37dd7033c..89338ab9d 100644 --- a/assets/checksums.txt +++ b/assets/checksums.txt @@ -1,5 +1,5 @@ 7edb2a585b445f28aa5ab06306f1a23f assets/ublock/privacy.txt -c120e92f634173e63362651858766da2 assets/ublock/filters.txt +bc576ccff04e28691eb020c48e22f109 assets/ublock/filters.txt dcf3e05bae803343c9d632f0baf8bedd assets/ublock/mirror-candidates.txt 9947b5510d67e47ea59ce876e4fc67be assets/ublock/filter-lists.json 132b3ecc9da8a68c3faf740c00af734b assets/thirdparties/adblock-plus-japanese-filter.googlecode.com/hg/abp_jp.txt diff --git a/assets/ublock/filters.txt b/assets/ublock/filters.txt index 390ba160e..4badaae43 100644 --- a/assets/ublock/filters.txt +++ b/assets/ublock/filters.txt @@ -242,3 +242,8 @@ ovh.strim.io#@##tweets # https://github.com/gorhill/uBlock/issues/510#issuecomment-71050211 ||racksauce.com^$domain=promptfile.com + +# https://github.com/gorhill/uBlock/issues/510#issuecomment-71078475 +|http://$popup,domain=filenuke.com|sharesix.com +||filenuke.com/a/script.js$script +||sharesix.com/a/script.js$script \ No newline at end of file From 53b3532746e2882585d874859dbba3f889a14fec Mon Sep 17 00:00:00 2001 From: gorhill Date: Thu, 22 Jan 2015 15:07:58 -0500 Subject: [PATCH 02/10] this fixes #580 --- assets/checksums.txt | 2 +- assets/ublock/filters.txt | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/assets/checksums.txt b/assets/checksums.txt index 89338ab9d..19833d7a9 100644 --- a/assets/checksums.txt +++ b/assets/checksums.txt @@ -1,5 +1,5 @@ 7edb2a585b445f28aa5ab06306f1a23f assets/ublock/privacy.txt -bc576ccff04e28691eb020c48e22f109 assets/ublock/filters.txt +8d042172d292a74a9f0f43827f79f98d assets/ublock/filters.txt dcf3e05bae803343c9d632f0baf8bedd assets/ublock/mirror-candidates.txt 9947b5510d67e47ea59ce876e4fc67be assets/ublock/filter-lists.json 132b3ecc9da8a68c3faf740c00af734b assets/thirdparties/adblock-plus-japanese-filter.googlecode.com/hg/abp_jp.txt diff --git a/assets/ublock/filters.txt b/assets/ublock/filters.txt index 4badaae43..4a59ffd29 100644 --- a/assets/ublock/filters.txt +++ b/assets/ublock/filters.txt @@ -246,4 +246,8 @@ ovh.strim.io#@##tweets # https://github.com/gorhill/uBlock/issues/510#issuecomment-71078475 |http://$popup,domain=filenuke.com|sharesix.com ||filenuke.com/a/script.js$script -||sharesix.com/a/script.js$script \ No newline at end of file +||sharesix.com/a/script.js$script + +# https://github.com/gorhill/uBlock/issues/580 +# To counter `liverail.com` in Dan Pollock's, hpHosts, MVPS, Peter Lowe's +@@||cdn-static.liverail.com$domain=9to5mac.com \ No newline at end of file From a2ff66e20fdc4297a227abfac42de613e8085834 Mon Sep 17 00:00:00 2001 From: gorhill Date: Thu, 22 Jan 2015 15:36:32 -0500 Subject: [PATCH 03/10] more subdomains as per alexa --- assets/checksums.txt | 2 +- assets/ublock/filters.txt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/assets/checksums.txt b/assets/checksums.txt index 19833d7a9..b163dbeee 100644 --- a/assets/checksums.txt +++ b/assets/checksums.txt @@ -1,5 +1,5 @@ 7edb2a585b445f28aa5ab06306f1a23f assets/ublock/privacy.txt -8d042172d292a74a9f0f43827f79f98d assets/ublock/filters.txt +1972fb1f3f18805a3e2468c9ea3cbdbd assets/ublock/filters.txt dcf3e05bae803343c9d632f0baf8bedd assets/ublock/mirror-candidates.txt 9947b5510d67e47ea59ce876e4fc67be assets/ublock/filter-lists.json 132b3ecc9da8a68c3faf740c00af734b assets/thirdparties/adblock-plus-japanese-filter.googlecode.com/hg/abp_jp.txt diff --git a/assets/ublock/filters.txt b/assets/ublock/filters.txt index 4a59ffd29..173299ca6 100644 --- a/assets/ublock/filters.txt +++ b/assets/ublock/filters.txt @@ -246,7 +246,15 @@ ovh.strim.io#@##tweets # https://github.com/gorhill/uBlock/issues/510#issuecomment-71078475 |http://$popup,domain=filenuke.com|sharesix.com ||filenuke.com/a/script.js$script +||mwem.filenuke.com/*/*$script +||rrnq.filenuke.com/*/*$script +||szbek.filenuke.com/*/*$script +||wwegr.filenuke.com/*/*$script ||sharesix.com/a/script.js$script +||hhg.sharesix.com/*/*$script +||jha.sharesix.com/*/*$script +||lsg.sharesix.com/*/*$script +||nvy.sharesix.com/*/*$script # https://github.com/gorhill/uBlock/issues/580 # To counter `liverail.com` in Dan Pollock's, hpHosts, MVPS, Peter Lowe's From 673b8774beeef903cf075412c5ce219c044485ec Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 23 Jan 2015 11:32:49 -0500 Subject: [PATCH 04/10] this fixes #582 --- platform/chromium/manifest.json | 2 +- platform/firefox/vapi-background.js | 2 +- src/css/devtool-log.css | 14 +- src/js/background.js | 2 +- src/js/contentscript-end.js | 9 + src/js/contentscript-start.js | 12 +- src/js/devtool-log.js | 17 +- src/js/static-net-filtering.js | 463 +++++++++++++++++----------- src/js/storage.js | 78 +++-- 9 files changed, 386 insertions(+), 213 deletions(-) diff --git a/platform/chromium/manifest.json b/platform/chromium/manifest.json index 2e7e33c19..9195aac3b 100644 --- a/platform/chromium/manifest.json +++ b/platform/chromium/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "µBlock", - "version": "0.8.5.7", + "version": "0.8.6.0", "default_locale": "en", "description": "__MSG_extShortDesc__", diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 5d9b30bb0..500e8a987 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -45,7 +45,7 @@ vAPI.firefox = true; // TODO: read these data from somewhere... vAPI.app = { name: 'µBlock', - version: '0.8.5.7' + version: '0.8.6.0' }; /******************************************************************************/ diff --git a/src/css/devtool-log.css b/src/css/devtool-log.css index 3011fbd19..36557925b 100644 --- a/src/css/devtool-log.css +++ b/src/css/devtool-log.css @@ -61,27 +61,31 @@ body[dir="rtl"] #content { vertical-align: top; } #content table tr td:nth-of-type(1) { + padding: 3px 0; + text-align: center; + } +#content table tr td:nth-of-type(2) { white-space: normal; width: 25%; word-break: break-all; word-wrap: break-word; } -#content table tr td:nth-of-type(2) { +#content table tr td:nth-of-type(3) { white-space: nowrap; } -#content table tr td:nth-of-type(3) { +#content table tr td:nth-of-type(4) { border-right: none; white-space: normal; width: 60%; word-break: break-all; word-wrap: break-word; } -#content table tr td:nth-of-type(3) b { +#content table tr td:nth-of-type(4) b { font-weight: normal; } -#content table tr.blocked td:nth-of-type(3) b { +#content table tr.blocked td:nth-of-type(4) b { background-color: rgba(192, 0, 0, 0.2); } -#content table tr.allowed td:nth-of-type(3) b { +#content table tr.allowed td:nth-of-type(4) b { background-color: rgba(0, 160, 0, 0.2); } \ No newline at end of file diff --git a/src/js/background.js b/src/js/background.js index 4306d65b9..4cbdf72a5 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -107,7 +107,7 @@ return { firstUpdateAfter: 5 * oneMinute, nextUpdateAfter: 7 * oneHour, - selfieMagic: 'qidcglrwobsm', + selfieMagic: 'knreayqtuguf', selfieAfter: 7 * oneMinute, pageStores: {}, diff --git a/src/js/contentscript-end.js b/src/js/contentscript-end.js index b6bbbf0a6..6b936018d 100644 --- a/src/js/contentscript-end.js +++ b/src/js/contentscript-end.js @@ -33,20 +33,29 @@ // https://github.com/gorhill/uBlock/issues/464 if ( document instanceof HTMLDocument === false ) { + //console.debug('contentscript-end.js > not a HTLMDocument'); return false; } if ( !vAPI ) { + //console.debug('contentscript-end.js > vAPI not found'); return; } if ( vAPI.canExecuteContentScript() !== true ) { + //console.debug('contentscript-end.js > can\'t execute'); + return; +} + +// Pointless to execute without the start script having done its job. +if ( !vAPI.contentscriptStartInjected ) { return; } // https://github.com/gorhill/uBlock/issues/456 // Already injected? if ( vAPI.contentscriptEndInjected ) { + //console.debug('contentscript-end.js > content script already injected'); return; } vAPI.contentscriptEndInjected = true; diff --git a/src/js/contentscript-start.js b/src/js/contentscript-start.js index ab95b3427..83166b21e 100644 --- a/src/js/contentscript-start.js +++ b/src/js/contentscript-start.js @@ -36,22 +36,26 @@ // https://github.com/gorhill/uBlock/issues/464 if ( document instanceof HTMLDocument === false ) { + //console.debug('contentscript-start.js > not a HTLMDocument'); return false; } // Because in case if ( !vAPI ) { + //console.debug('contentscript-start.js > vAPI not found'); return; } // Because Safari if ( vAPI.canExecuteContentScript() !== true ) { + //console.debug('contentscript-start.js > can\'t execute'); return; } // https://github.com/gorhill/uBlock/issues/456 // Already injected? if ( vAPI.contentscriptStartInjected ) { + //console.debug('contentscript-start.js > content script already injected'); return; } vAPI.contentscriptStartInjected = true; @@ -139,7 +143,13 @@ var filteringHandler = function(details) { // The port will never be used again at this point, disconnecting allows // the browser to flush this script from memory. } - // Do not close the port before we are done. + + // If no filters were found, maybe the script was injected before uBlock's + // process was fully initialized. When this happens, pages won't be + // cleaned right after browser launch. + vAPI.contentscriptStartInjected = !details || details.cosmeticHide.length !== 0; + + // Cleanup before leaving localMessager.close(); }; diff --git a/src/js/devtool-log.js b/src/js/devtool-log.js index 5646b8ab1..f2a8e67b2 100644 --- a/src/js/devtool-log.js +++ b/src/js/devtool-log.js @@ -51,6 +51,8 @@ var renderURL = function(url, filter) { } if ( reText === '*' ) { reText = '\\*'; + } else if ( reText.charAt(0) === '/' && reText.slice(-1) === '/' ) { + reText = reText.slice(1, -1); } else { reText = reText .replace(/\./g, '\\.') @@ -87,6 +89,7 @@ var createRow = function() { tr.appendChild(doc.createElement('td')); tr.appendChild(doc.createElement('td')); tr.appendChild(doc.createElement('td')); + tr.appendChild(doc.createElement('td')); return tr; }; @@ -96,18 +99,26 @@ var renderLogEntry = function(entry) { var tr = createRow(); if ( entry.result.charAt(1) === 'b' ) { tr.classList.add('blocked'); + tr.cells[0].textContent = '\u2009\u2212\u2009'; } else if ( entry.result.charAt(1) === 'a' ) { tr.classList.add('allowed'); if ( entry.result.charAt(0) === 'm' ) { tr.classList.add('mirrored'); } + tr.cells[0].textContent = '\u2009+\u2009'; + } else { + tr.cells[0].textContent = '\u2009\u00A0\u2009'; } if ( entry.type === 'main_frame' ) { tr.classList.add('maindoc'); } - tr.cells[0].textContent = entry.result.slice(3); - tr.cells[1].textContent = entry.type; - vAPI.insertHTML(tr.cells[2], renderURL(entry.url, entry.result)); + var filterText = entry.result.slice(3); + if ( entry.result.lastIndexOf('sa', 0) === 0 ) { + filterText = '@@' + filterText; + } + tr.cells[1].textContent = filterText; + tr.cells[2].textContent = entry.type; + vAPI.insertHTML(tr.cells[3], renderURL(entry.url, entry.result)); tbody.insertBefore(tr, tbody.firstChild); }; diff --git a/src/js/static-net-filtering.js b/src/js/static-net-filtering.js index 8013e3c41..c795eeb03 100644 --- a/src/js/static-net-filtering.js +++ b/src/js/static-net-filtering.js @@ -79,8 +79,6 @@ const AllowAnyParty = AllowAction | AnyParty; var pageHostname = ''; // short-lived register -var reIgnoreEmpty = /^\s+$/; -var reIgnoreComment = /^\[|^!/; var reHostnameRule = /^[0-9a-z][0-9a-z.-]+[0-9a-z]$/; var reHostnameToken = /^[0-9a-z]+/g; var reGoodToken = /[%0-9a-z]{2,}/g; @@ -813,6 +811,61 @@ FilterManyWildcardsHostname.fromSelfie = function(s) { return new FilterManyWildcardsHostname(args[0], atoi(args[1]), args[2]); }; +/******************************************************************************/ + +// Regex-based filters + +var FilterRegex = function(s) { + this.re = new RegExp(s); +}; + +FilterRegex.prototype.match = function(url) { + return this.re.test(url); +}; + +FilterRegex.prototype.fid = '//'; + +FilterRegex.prototype.toString = function() { + return '/' + this.re.source + '/'; +}; + +FilterRegex.prototype.toSelfie = function() { + return this.re.source; +}; + +FilterRegex.fromSelfie = function(s) { + return new FilterRegex(s); +}; + +/******************************************************************************/ + +var FilterRegexHostname = function(s, hostname) { + this.re = new RegExp(s); + this.hostname = hostname; +}; + +FilterRegexHostname.prototype.match = function(url) { + // test hostname first, it's cheaper than evaluating a regex + return pageHostname.slice(-this.hostname.length) === this.hostname && + this.re.test(url); +}; + +FilterRegexHostname.prototype.fid = '//h'; + +FilterRegexHostname.prototype.toString = function() { + return '/' + this.re.source + '/$domain=' + this.hostname; +}; + +FilterRegexHostname.prototype.toSelfie = function() { + return this.re.source + '\t' + + this.hostname; +}; + +FilterRegexHostname.fromSelfie = function(s) { + var pos = s.indexOf('\t'); + return new FilterRegexHostname(s.slice(0, pos), s.slice(pos + 1)); +}; + /******************************************************************************/ /******************************************************************************/ @@ -920,12 +973,15 @@ FilterBucket.fromSelfie = function() { /******************************************************************************/ -var makeFilter = function(details, tokenBeg) { +var makeFilter = function(details) { var s = details.f; + if ( details.isRegex ) { + return new FilterRegex(s); + } var wcOffset = s.indexOf('*'); if ( wcOffset !== -1 ) { if ( s.indexOf('*', wcOffset + 1) !== -1 ) { - return details.anchor === 0 ? new FilterManyWildcards(s, tokenBeg) : null; + return details.anchor === 0 ? new FilterManyWildcards(s, details.tokenBeg) : null; } var lSegment = s.slice(0, wcOffset); var rSegment = s.slice(wcOffset + 1); @@ -935,10 +991,10 @@ var makeFilter = function(details, tokenBeg) { if ( details.anchor > 0 ) { return new FilterSingleWildcardRightAnchored(lSegment, rSegment); } - if ( tokenBeg === 0 ) { + if ( details.tokenBeg === 0 ) { return new FilterSingleWildcardPrefix0(lSegment, rSegment); } - return new FilterSingleWildcard(lSegment, rSegment, tokenBeg); + return new FilterSingleWildcard(lSegment, rSegment, details.tokenBeg); } if ( details.anchor < 0 ) { return new FilterPlainLeftAnchored(s); @@ -949,23 +1005,26 @@ var makeFilter = function(details, tokenBeg) { if ( details.hostnameAnchored ) { return new FilterPlainHnAnchored(s); } - if ( tokenBeg === 0 ) { + if ( details.tokenBeg === 0 ) { return new FilterPlainPrefix0(s); } - if ( tokenBeg === 1 ) { + if ( details.tokenBeg === 1 ) { return new FilterPlainPrefix1(s); } - return new FilterPlain(s, tokenBeg); + return new FilterPlain(s, details.tokenBeg); }; /******************************************************************************/ -var makeHostnameFilter = function(details, tokenBeg, hostname) { +var makeHostnameFilter = function(details, hostname) { var s = details.f; + if ( details.isRegex ) { + return new FilterRegexHostname(s, hostname); + } var wcOffset = s.indexOf('*'); if ( wcOffset !== -1 ) { if ( s.indexOf('*', wcOffset + 1) !== -1 ) { - return details.anchor === 0 ? new FilterManyWildcardsHostname(s, tokenBeg, hostname) : null; + return details.anchor === 0 ? new FilterManyWildcardsHostname(s, details.tokenBeg, hostname) : null; } var lSegment = s.slice(0, wcOffset); var rSegment = s.slice(wcOffset + 1); @@ -975,10 +1034,10 @@ var makeHostnameFilter = function(details, tokenBeg, hostname) { if ( details.anchor > 0 ) { return new FilterSingleWildcardRightAnchoredHostname(lSegment, rSegment, hostname); } - if ( tokenBeg === 0 ) { + if ( details.tokenBeg === 0 ) { return new FilterSingleWildcardPrefix0Hostname(lSegment, rSegment, hostname); } - return new FilterSingleWildcardHostname(lSegment, rSegment, tokenBeg, hostname); + return new FilterSingleWildcardHostname(lSegment, rSegment, details.tokenBeg, hostname); } if ( details.anchor < 0 ) { return new FilterPlainLeftAnchoredHostname(s, hostname); @@ -986,13 +1045,13 @@ var makeHostnameFilter = function(details, tokenBeg, hostname) { if ( details.anchor > 0 ) { return new FilterPlainRightAnchoredHostname(s, hostname); } - if ( tokenBeg === 0 ) { + if ( details.tokenBeg === 0 ) { return new FilterPlainPrefix0Hostname(s, hostname); } - if ( tokenBeg === 1 ) { + if ( details.tokenBeg === 1 ) { return new FilterPlainPrefix1Hostname(s, hostname); } - return new FilterPlainHostname(s, tokenBeg, hostname); + return new FilterPlainHostname(s, details.tokenBeg, hostname); }; /******************************************************************************/ @@ -1060,7 +1119,10 @@ var trimChar = function(s, c) { /******************************************************************************/ var FilterParser = function() { + this.reHasWildcard = /[\^\*]/; + this.reHasUppercase = /[A-Z]/; this.hostnames = []; + this.notHostnames = []; this.types = []; this.reset(); }; @@ -1092,8 +1154,12 @@ FilterParser.prototype.reset = function() { this.hostnameAnchored = false; this.hostnamePure = false; this.hostnames.length = 0; - this.notHostname = false; + this.notHostnames.length = 0; + this.isRegex = false; this.thirdParty = false; + this.token = ''; + this.tokenBeg = 0; + this.tokenEnd = 0; this.types.length = 0; this.important = 0; this.unsupported = false; @@ -1140,101 +1206,22 @@ FilterParser.prototype.parseOptParty = function(not) { FilterParser.prototype.parseOptHostnames = function(raw) { var hostnames = raw.split('|'); - var hostname, not; + var hostname; for ( var i = 0; i < hostnames.length; i++ ) { hostname = hostnames[i]; - not = hostname.charAt(0) === '~'; - if ( not ) { - hostname = hostname.slice(1); + if ( hostname.charAt(0) === '~' ) { + this.notHostnames.push(hostname.slice(1)); + } else { + this.hostnames.push(hostname); } - // https://github.com/gorhill/uBlock/issues/191 - // Well it doesn't seem to make a whole lot of sense to have both - // non-negated hostnames mixed with negated hostnames. - if ( this.hostnames.length !== 0 && not !== this.notHostname ) { - console.error('FilterContainer.parseOptHostnames(): ambiguous filter syntax: "%s"', this.f); - this.unsupported = true; - return; - } - this.notHostname = not; - this.hostnames.push(hostname); } }; /******************************************************************************/ -FilterParser.prototype.parse = function(s) { - // important! - this.reset(); - - if ( reHostnameRule.test(s) ) { - this.f = s; - this.hostnamePure = this.hostnameAnchored = true; - return this; - } - - // element hiding filter? - if ( s.indexOf('##') >= 0 || s.indexOf('#@') >= 0 ) { - this.elemHiding = true; - return this; - } - - // block or allow filter? - if ( s.slice(0, 2) === '@@' ) { - this.action = AllowAction; - s = s.slice(2); - } - - // options - var pos = s.indexOf('$'); - if ( pos > 0 ) { - this.fopts = s.slice(pos + 1); - s = s.slice(0, pos); - } - - // regex? (not supported) - if ( s.charAt(0) === '/' && s.slice(-1) === '/' ) { - this.unsupported = true; - return this; - } - - // hostname anchoring - if ( s.slice(0, 2) === '||' ) { - this.hostnameAnchored = true; - s = s.slice(2); - } - - // left-anchored - if ( s.charAt(0) === '|' ) { - this.anchor = -1; - s = s.slice(1); - } - - // right-anchored - if ( s.slice(-1) === '|' ) { - this.anchor = 1; - s = s.slice(0, -1); - } - - // normalize placeholders - // TODO: transforming `^` into `*` is not a strict interpretation of - // ABP syntax. - s = s.replace(/\^/g, '*'); - s = s.replace(/\*\*+/g, '*'); - - // remove leading and trailing wildcards - s = trimChar(s, '*'); - - // pure hostname-based? - this.hostnamePure = this.hostnameAnchored && reHostnameRule.test(s); - - this.f = s; - - if ( !this.fopts ) { - return this; - } - - // parse options - var opts = this.fopts.split(','); +FilterParser.prototype.parseOptions = function(s) { + this.fopts = s; + var opts = s.split(','); var opt, not; for ( var i = 0; i < opts.length; i++ ) { opt = opts[i]; @@ -1270,9 +1257,119 @@ FilterParser.prototype.parse = function(s) { this.unsupported = true; break; } +}; + +/******************************************************************************/ + +FilterParser.prototype.parse = function(s) { + // important! + this.reset(); + + // plain hostname? + if ( reHostnameRule.test(s) ) { + this.f = s; + this.hostnamePure = this.hostnameAnchored = true; + return this; + } + + // element hiding filter? + var pos = s.indexOf('#'); + if ( pos !== -1 ) { + var c = s.charAt(pos + 1); + if ( c === '#' || c === '@' ) { + console.error('static-net-filtering.js > unexpected cosmetic filters'); + this.elemHiding = true; + return this; + } + } + + // options + pos = s.indexOf('$'); + if ( pos !== -1 ) { + this.parseOptions(s.slice(pos + 1)); + s = s.slice(0, pos); + } + + // block or allow filter? + if ( s.lastIndexOf('@@', 0) === 0 ) { + this.action = AllowAction; + s = s.slice(2); + } + + // regex? + if ( s.charAt(0) === '/' && s.slice(-1) === '/' ) { + this.isRegex = true; + this.f = s.slice(1, -1); + return this; + } + + // hostname anchoring + if ( s.lastIndexOf('||', 0) === 0 ) { + this.hostnameAnchored = true; + s = s.slice(2); + } + + // left-anchored + if ( s.charAt(0) === '|' ) { + this.anchor = -1; + s = s.slice(1); + } + + // right-anchored + if ( s.slice(-1) === '|' ) { + this.anchor = 1; + s = s.slice(0, -1); + } + + // normalize placeholders + // TODO: transforming `^` into `*` is not a strict interpretation of + // ABP syntax. + if ( this.reHasWildcard.test(s) ) { + s = s.replace(/\^/g, '*').replace(/\*\*+/g, '*'); + s = trimChar(s, '*'); + } + + // plain hostname? + this.hostnamePure = this.hostnameAnchored && reHostnameRule.test(s); + + // This might look weird but we gain memory footprint by not going through + // toLowerCase(), at least on Chromium. Because copy-on-write? + + this.f = this.reHasUppercase.test(s) ? s.toLowerCase() : s; + return this; }; +/******************************************************************************/ + +FilterParser.prototype.makeToken = function() { + if ( this.isRegex ) { + this.token = '*'; + return; + } + + var matches; + + if ( this.hostnameAnchored ) { + matches = findHostnameToken(this.f); + if ( !matches || matches[0].length === 0 ) { + return; + } + this.tokenBeg = matches.index; + this.tokenEnd = reHostnameToken.lastIndex; + this.token = this.f.slice(this.tokenBeg, this.tokenEnd); + return; + } + + matches = findFirstGoodToken(this.f); + if ( !matches || matches[0].length === 0 ) { + return; + } + this.tokenBeg = matches.index; + this.tokenEnd = reGoodToken.lastIndex; + this.token = this.f.slice(this.tokenBeg, this.tokenEnd); +}; + /******************************************************************************/ /******************************************************************************/ @@ -1410,7 +1507,9 @@ FilterContainer.prototype.fromSelfie = function(selfie) { '*|': FilterSingleWildcardRightAnchored, '*|h': FilterSingleWildcardRightAnchoredHostname, '*+': FilterManyWildcards, - '*+h': FilterManyWildcardsHostname + '*+h': FilterManyWildcardsHostname, + '//': FilterRegex, + '//h': FilterRegexHostname }; var catKey, tokenKey; @@ -1463,26 +1562,28 @@ FilterContainer.prototype.add = function(s) { // ORDER OF TESTS IS IMPORTANT! // Ignore empty lines - if ( reIgnoreEmpty.test(s) ) { + s = s.trim(); + if ( s.length === 0 ) { return false; } // Ignore comments - if ( reIgnoreComment.test(s) ) { + var c = s.charAt(0); + if ( c === '[' || c === '!' ) { return false; } var parsed = this.filterParser.parse(s); - // Ignore rules with other conditions for now - if ( parsed.unsupported ) { - this.rejectedCount += 1; - // console.log('µBlock> abp-filter.js/FilterContainer.add(): unsupported filter "%s"', s); + // Ignore element-hiding filters + if ( parsed.elemHiding ) { return false; } - // Ignore element-hiding filters - if ( parsed.elemHiding ) { + // Ignore filters with unsupported options + if ( parsed.unsupported ) { + this.rejectedCount += 1; + // console.log('µBlock> abp-filter.js/FilterContainer.add(): unsupported filter "%s"', s); return false; } @@ -1533,95 +1634,95 @@ FilterContainer.prototype.add = function(s) { /******************************************************************************/ FilterContainer.prototype.addFilter = function(parsed) { - // TODO: avoid duplicates - - var matches = parsed.hostnameAnchored ? - findHostnameToken(parsed.f) : - findFirstGoodToken(parsed.f); - if ( !matches || !matches[0].length ) { + parsed.makeToken(); + if ( parsed.token === '' ) { + console.error('static-net-filtering.js > FilterContainer.addFilter("%s"): can\'t tokenize', parsed.f); return false; } - var tokenBeg = matches.index; - var tokenEnd = parsed.hostnameAnchored ? - reHostnameToken.lastIndex : - reGoodToken.lastIndex; - var filter; - - var i = parsed.hostnames.length; - - // Applies to specific domains - - if ( i !== 0 && !parsed.notHostname ) { - while ( i-- ) { - filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]); - if ( !filter ) { - return false; - } - this.addFilterEntry(filter, parsed, AnyParty, tokenBeg, tokenEnd); - } - return true; - } var party = AnyParty; if ( parsed.firstParty !== parsed.thirdParty ) { party = parsed.firstParty ? FirstParty : ThirdParty; } - // Applies to all domains, with exception(s) + var filter; + var i = parsed.hostnames.length; + var j = parsed.notHostnames.length; - // https://github.com/gorhill/uBlock/issues/191 - // Invert the purpose of the filter for negated hostnames - if ( i !== 0 && parsed.notHostname ) { - filter = makeFilter(parsed, tokenBeg); + // Applies to all domains without exceptions + if ( i === 0 && j === 0 ) { + filter = makeFilter(parsed); + if ( !filter ) { + return false; + } + this.addFilterEntry(filter, parsed, party); + return true; + } + + // Applies to specific domains + if ( i !== 0 ) { + while ( i-- ) { + filter = makeHostnameFilter(parsed, parsed.hostnames[i]); + if ( !filter ) { + return false; + } + this.addFilterEntry(filter, parsed, party); + } + } + // No exceptions + if ( j === 0 ) { + return true; + } + + // Case: + // - applies everywhere except to specific domains + // Example: + // - ||adm.fwmrm.net/p/msnbc_live/$object-subrequest,third-party,domain=~msnbc.msn.com|~www.nbcnews.com + if ( i === 0 ) { + filter = makeFilter(parsed); if ( !filter ) { return false; } // https://github.com/gorhill/uBlock/issues/251 // Apply third-party option if it is present - this.addFilterEntry(filter, parsed, party, tokenBeg, tokenEnd); - // Reverse purpose of filter - parsed.action ^= ToggleAction; - while ( i-- ) { - filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]); - if ( !filter ) { - return false; - } - // https://github.com/gorhill/uBlock/issues/191#issuecomment-53654024 - // If it is a block filter, we need to reverse the order of - // evaluation. - if ( parsed.action === BlockAction ) { - parsed.important = Important; - } - this.addFilterEntry(filter, parsed, AnyParty, tokenBeg, tokenEnd); + this.addFilterEntry(filter, parsed, party); + } + + // Cases: + // - applies everywhere except to specific domains + // - applies to specific domains except other specific domains + // Example: + // - /^https?\:\/\/(?!(...)\/)/$script,third-party,xmlhttprequest,domain=photobucket.com|~secure.photobucket.com + + // Reverse purpose of filter + parsed.action ^= ToggleAction; + while ( j-- ) { + filter = makeHostnameFilter(parsed, parsed.notHostnames[j]); + if ( !filter ) { + return false; } - return true; + // https://github.com/gorhill/uBlock/issues/191#issuecomment-53654024 + // If it is a block filter, we need to reverse the order of + // evaluation. + if ( parsed.action === BlockAction ) { + parsed.important = Important; + } + this.addFilterEntry(filter, parsed, party); } - - // Applies to all domains without exceptions - - filter = makeFilter(parsed, tokenBeg); - if ( !filter ) { - return false; - } - - this.addFilterEntry(filter, parsed, party, tokenBeg, tokenEnd); - return true; }; /******************************************************************************/ -FilterContainer.prototype.addFilterEntry = function(filter, parsed, party, tokenBeg, tokenEnd) { - var s = parsed.f; - var tokenKey = s.slice(tokenBeg, tokenEnd); +FilterContainer.prototype.addFilterEntry = function(filter, parsed, party) { var bits = parsed.action | parsed.important | party; if ( parsed.types.length === 0 ) { - this.addToCategory(bits | AnyType, tokenKey, filter); + this.addToCategory(bits | AnyType, parsed.token, filter); return; } var n = parsed.types.length; for ( var i = 0; i < n; i++ ) { - this.addToCategory(bits | parsed.types[i], tokenKey, filter); + this.addToCategory(bits | parsed.types[i], parsed.token, filter); } }; @@ -1691,6 +1792,13 @@ FilterContainer.prototype.matchTokens = function(bucket, url) { return f; } } + + // Regex-based filters + f = bucket['*']; + if ( f !== undefined && f.match(url) !== false ) { + return f; + } + return false; }; @@ -1756,7 +1864,7 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r var type = typeNameToTypeValue[requestType]; var categories = this.categories; - var bucket; + var bf = false, bucket; // Tokenize only once this.tokenize(url); @@ -1777,7 +1885,6 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r } // Test against block filters - bf = false; if ( bucket = categories[this.makeCategoryKey(BlockAnyParty | type)] ) { bf = this.matchTokens(bucket, url); } @@ -1853,7 +1960,7 @@ FilterContainer.prototype.matchString = function(context) { pageHostname = context.pageHostname || ''; var categories = this.categories; - var bucket; + var bf, bucket; // Tokenize only once this.tokenize(url); diff --git a/src/js/storage.js b/src/js/storage.js index ac87a64e3..3855f8d5b 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -374,12 +374,15 @@ var cosmeticFilteringEngine = this.cosmeticFilteringEngine; var parseCosmeticFilters = this.userSettings.parseAllABPHideFilters; - var reIsCosmeticFilter = /#@?#/; - var reLocalhost = /(?:^|\s)(?:localhost\.localdomain|localhost|local|broadcasthost|0\.0\.0\.0|127\.0\.0\.1|::1|fe80::1%lo0)(?=\s|$)/g; - var reAsciiSegment = /^[\x21-\x7e]+$/; + var reIsCosmeticFilter = /#[@#]/; + var reIsWhitespaceChar = /\s/; + var reMaybeLocalIp = /^[\d:f]/; + var reIsLocalhostRedirect = /\s+(?:broadcasthost|local|localhost|localhost\.localdomain)(?=\s|$)/; + var reLocalIp = /^(?:0\.0\.0\.0|127\.0\.0\.1|::1|fe80::1%lo0)/; + //var reAsciiSegment = /^[\x21-\x7e]+$/; var matches; var lineBeg = 0, lineEnd, currentLineBeg; - var line, c; + var line, lineRaw, c, pos; while ( lineBeg < rawEnd ) { lineEnd = rawText.indexOf('\n', lineBeg); @@ -393,10 +396,14 @@ // rhill 2014-04-18: The trim is important here, as without it there // could be a lingering `\r` which would cause problems in the // following parsing code. - line = rawText.slice(lineBeg, lineEnd).trim(); + line = lineRaw = rawText.slice(lineBeg, lineEnd).trim(); currentLineBeg = lineBeg; lineBeg = lineEnd + 1; + if ( line.length === 0 ) { + continue; + } + // Strip comments c = line.charAt(0); if ( c === '!' || c === '[' ) { @@ -404,6 +411,7 @@ } // Parse or skip cosmetic filters + // All cosmetic filters are caught here if ( parseCosmeticFilters ) { if ( cosmeticFilteringEngine.add(line) ) { continue; @@ -412,36 +420,59 @@ continue; } + // Whatever else is next can be assumed to not be a cosmetic filter + + // Most comments start in first column if ( c === '#' ) { continue; } + // Catch comments somewhere on the line + // Remove: + // ... #blah blah blah + // ... # blah blah blah + // Don't remove: + // ...#blah blah blah + // because some ABP filters uses the `#` character (URL fragment) + pos = line.indexOf('#'); + if ( pos !== -1 && reIsWhitespaceChar.test(line.charAt(pos - 1)) ) { + line = line.slice(0, pos).trim(); + } + // https://github.com/gorhill/httpswitchboard/issues/15 // Ensure localhost et al. don't end up in the ubiquitous blacklist. - // TODO: do this only if it's not an [Adblock] list - line = line - .replace(/\s+#.*$/, '') - .toLowerCase() - .replace(reLocalhost, '') - .trim(); + // With hosts files, we need to remove local IP redirection + if ( reMaybeLocalIp.test(c) ) { + // Ignore hosts file redirect configuration + // 127.0.0.1 localhost + // 255.255.255.255 broadcasthost + if ( reIsLocalhostRedirect.test(line) ) { + continue; + } + line = line.replace(reLocalIp, '').trim(); + } + + if ( line.length === 0 ) { + continue; + } // The filter is whatever sequence of printable ascii character without // whitespaces - matches = reAsciiSegment.exec(line); - if ( matches === null ) { - //console.debug('µBlock.mergeFilterList(): skipping "%s"', lineRaw); - continue; - } + //matches = reAsciiSegment.exec(line); + //if ( matches === null ) { + // console.debug('storage.js > µBlock.mergeFilterList(): skipping "%s"', lineRaw); + // continue; + //} // Bypass anomalies // For example, when a filter contains whitespace characters, or // whatever else outside the range of printable ascii characters. - if ( matches[0] !== line ) { - // console.error('"%s" !== "%s"', matches[0], line); - continue; - } + //if ( matches[0] !== line ) { + // console.error('"%s" !== "%s"', matches[0], line); + // continue; + //} - staticNetFilteringEngine.add(matches[0]); + staticNetFilteringEngine.add(line); } }; @@ -607,16 +638,17 @@ if ( countdown !== 0 ) { return; } + // https://github.com/gorhill/uBlock/issues/426 // Important: remove barrier to remote fetching, this was useful only // for launch time. µb.assets.allowRemoteFetch = true; - vAPI.onLoadAllCompleted(); - // https://github.com/gorhill/uBlock/issues/184 // Check for updates not too far in the future. µb.updater.restart(µb.firstUpdateAfter); + + vAPI.onLoadAllCompleted(); }; // Filters are in memory. From eeb5e8de5bbef67369be042fbb444aca64d034f9 Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 23 Jan 2015 11:47:31 -0500 Subject: [PATCH 05/10] associate code change with issue #587 --- src/js/contentscript-end.js | 1 + src/js/contentscript-start.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/js/contentscript-end.js b/src/js/contentscript-end.js index 6b936018d..82ce59fc7 100644 --- a/src/js/contentscript-end.js +++ b/src/js/contentscript-end.js @@ -47,6 +47,7 @@ if ( vAPI.canExecuteContentScript() !== true ) { return; } +// https://github.com/gorhill/uBlock/issues/587 // Pointless to execute without the start script having done its job. if ( !vAPI.contentscriptStartInjected ) { return; diff --git a/src/js/contentscript-start.js b/src/js/contentscript-start.js index 83166b21e..a190ef25e 100644 --- a/src/js/contentscript-start.js +++ b/src/js/contentscript-start.js @@ -144,6 +144,7 @@ var filteringHandler = function(details) { // the browser to flush this script from memory. } + // https://github.com/gorhill/uBlock/issues/587 // If no filters were found, maybe the script was injected before uBlock's // process was fully initialized. When this happens, pages won't be // cleaned right after browser launch. From 44bc263a69af8475e7ef3f2c973ac2aeca53f9f5 Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 23 Jan 2015 11:56:43 -0500 Subject: [PATCH 06/10] code review: oops --- src/js/contentscript-start.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/contentscript-start.js b/src/js/contentscript-start.js index a190ef25e..a60275ddc 100644 --- a/src/js/contentscript-start.js +++ b/src/js/contentscript-start.js @@ -148,7 +148,7 @@ var filteringHandler = function(details) { // If no filters were found, maybe the script was injected before uBlock's // process was fully initialized. When this happens, pages won't be // cleaned right after browser launch. - vAPI.contentscriptStartInjected = !details || details.cosmeticHide.length !== 0; + vAPI.contentscriptStartInjected = details && details.cosmeticHide.length !== 0; // Cleanup before leaving localMessager.close(); From 1a5a42238e1c3a0d4e9b6d81cfa820ed83c3681e Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 23 Jan 2015 13:09:26 -0500 Subject: [PATCH 07/10] do not rely on core to do the transposition --- platform/firefox/vapi-background.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 500e8a987..07d3c1d2d 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -787,7 +787,8 @@ var httpObserver = { 5: 'object', 6: 'main_frame', 7: 'sub_frame', - 11: 'xmlhttprequest' + 11: 'xmlhttprequest', + 12: 'object' }, lastRequest: { url: null, From 91142ce84743ed3bea86e0e71de5a3597d7fedb3 Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 23 Jan 2015 13:39:06 -0500 Subject: [PATCH 08/10] code review: removed unused member --- src/js/static-net-filtering.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/js/static-net-filtering.js b/src/js/static-net-filtering.js index c795eeb03..4d4308321 100644 --- a/src/js/static-net-filtering.js +++ b/src/js/static-net-filtering.js @@ -1384,7 +1384,6 @@ var TokenEntry = function() { var FilterContainer = function() { this.reAnyToken = /[%0-9a-z]+/g; this.tokens = []; - this.buckets = new Array(4); this.blockedAnyPartyHostnames = new µb.LiquidDict(); this.blocked3rdPartyHostnames = new µb.LiquidDict(); this.filterParser = new FilterParser(); From 448931248d25e980f3d2ebd7aa2fa0e69ed4a201 Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 23 Jan 2015 14:20:04 -0500 Subject: [PATCH 09/10] translation work from Crowdin --- dist/description/description-nl.txt | 12 ++--- src/_locales/ar/messages.json | 2 +- src/_locales/cs/messages.json | 2 +- src/_locales/de/messages.json | 8 +-- src/_locales/el/messages.json | 6 +-- src/_locales/es/messages.json | 8 +-- src/_locales/hi/messages.json | 2 +- src/_locales/hu/messages.json | 82 ++++++++++++++--------------- src/_locales/ja/messages.json | 20 +++---- src/_locales/nl/messages.json | 16 +++--- src/_locales/pt_PT/messages.json | 8 +-- src/_locales/sv/messages.json | 74 +++++++++++++------------- src/_locales/uk/messages.json | 8 +-- src/_locales/zh_CN/messages.json | 10 ++-- src/_locales/zh_TW/messages.json | 26 ++++----- 15 files changed, 142 insertions(+), 142 deletions(-) diff --git a/dist/description/description-nl.txt b/dist/description/description-nl.txt index 39f9804f8..73c61566a 100644 --- a/dist/description/description-nl.txt +++ b/dist/description/description-nl.txt @@ -1,8 +1,8 @@ -Een efficiënte blokkeerder: light geheugen- en CPU-verbruik. Toch kan het duizenden filters meer laden en gebruiken dan andere populaire blokkeerders. +Een efficiënte blokkeerder: licht geheugen- en CPU-verbruik. Toch kan het duizenden filters meer laden en gebruiken dan andere populaire blokkeerders. -Geïllustreerd overzicht van de efficiëntie : https://github.com/gorhill/uBlock/wiki/%C2%B5Block-vs.-ABP:-efficiency-compared +Geïllustreerd overzicht van de efficiëntie: https://github.com/gorhill/uBlock/wiki/%C2%B5Block-vs.-ABP:-efficiency-compared -Gebruik: De grote aan/uit-knop in de popup is om permanent µBlock in/uit te schakelen voor de huidige website. Het past enkel op de huidige website toe. Het is geen globale aan/uit-knop. +Hoe te gebruiken: De grote aan/uit-knop in de popup is om µBlock permanent in/uit te schakelen voor de huidige website. Het wordt enkel op de huidige website toegepast. Het is geen globale aan/uit-knop. *** @@ -26,13 +26,13 @@ Meer lijsten zijn beschikbaar om te selecteren indien gewenst: - Spam404 - Etc. -Natuurlijk wordt het geheugenverbruik groter naarmate er meer filters worden ingeschakeld. Zelfs na Fanboy's two extra lijsten, hpHosts’s Ad and tracking servers toe te voegen heeft µBlock een lagere geheugenverbruik dan andere populaire blokkeerders. +Natuurlijk wordt het geheugenverbruik groter naarmate er meer filters worden ingeschakeld. Maar zelfs na Fanboy's two extra lijsten, hpHosts’s Ad en tracking servers toe te voegen heeft µBlock een lager geheugenverbruik dan andere populaire blokkeerders. -Let op, sommige van deze extra lijsten verhoogt de kans dat websites breken -- zeker de lijsten die normaal als hosts-bestand worden gebruikt. +Let op, het gebruik van sommige van deze extra lijsten verhoogt de kans dat websites breken -- zeker de lijsten die normaal als hosts-bestand worden gebruikt. *** -Zonder de standaard filterlijst doet deze extensie niets. Dus als je ooit echt een bijdrage wilt leveren, denk dan aan de mensen die hard werken om deze filterlijsten die je aan het gebruiken bent de onderhouden, die allemaal gratis beschikbaar en te gebruiken zijn. +Zonder de standaard filterlijst doet deze extensie niets. Dus als je ooit echt een bijdrage wilt leveren, denk dan aan de mensen die hard werken om de filterlijsten die je aan het gebruiken bent te onderhouden, die allemaal gratis beschikbaar en te gebruiken zijn. *** diff --git a/src/_locales/ar/messages.json b/src/_locales/ar/messages.json index bb4dd13f6..53a046fdf 100644 --- a/src/_locales/ar/messages.json +++ b/src/_locales/ar/messages.json @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"ميكرو بلوك - سجل الإتصال بالشبكة", "description":"Title for the network request log window" }, "aboutPageName":{ diff --git a/src/_locales/cs/messages.json b/src/_locales/cs/messages.json index 2d588737f..165b544e6 100644 --- a/src/_locales/cs/messages.json +++ b/src/_locales/cs/messages.json @@ -280,7 +280,7 @@ "description":"English: Multipurpose" }, "3pGroupRegions":{ - "message":"Regiony, jazyky", + "message":"Regionální, jazykové", "description":"English: Regions, languages" }, "3pGroupCustom":{ diff --git a/src/_locales/de/messages.json b/src/_locales/de/messages.json index bfc85bbc3..6605d98bd 100644 --- a/src/_locales/de/messages.json +++ b/src/_locales/de/messages.json @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock — Protokoll der Netzwerk-Anforderungen", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -352,11 +352,11 @@ "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"Liste deiner dynamischen Filterregeln.", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ - "message":"Rule syntax: source destination type action<\/code> (full documentation<\/a>).", + "message":"Regel-Syntax: Quelle Ziel Typ Action<\/code> ( vollständige Dokumentation<\/a>).", "description":"English: dynamic rule syntax and full documentation." }, "whitelistPrompt":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"Hintergrundanfragen", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ diff --git a/src/_locales/el/messages.json b/src/_locales/el/messages.json index 837fb0e37..944710ea3 100644 --- a/src/_locales/el/messages.json +++ b/src/_locales/el/messages.json @@ -24,7 +24,7 @@ "description":"appears as tab name in dashboard" }, "rulesPageName":{ - "message":"My rules", + "message":"Οι κανόνες μου", "description":"appears as tab name in dashboard" }, "whitelistPageName":{ @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"μBlock - Καταγραφή δικτυακής αίτησης", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -152,7 +152,7 @@ "description":"" }, "popupImageRulePrompt":{ - "message":"images", + "message":"Εικόνες", "description":"" }, "popupInlineScriptRulePrompt":{ diff --git a/src/_locales/es/messages.json b/src/_locales/es/messages.json index 40b7a2153..eb6d87b6d 100644 --- a/src/_locales/es/messages.json +++ b/src/_locales/es/messages.json @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock — Registro de peticiones de red", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -352,11 +352,11 @@ "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"Listado de sus reglas de filtrado dinámico.", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ - "message":"Rule syntax: source destination type action<\/code> (full documentation<\/a>).", + "message":"Sintaxis de las reglas: origen destino tipo acción<\/code> ( documentación completa<\/a>).", "description":"English: dynamic rule syntax and full documentation." }, "whitelistPrompt":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"Peticiones ocultas", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ diff --git a/src/_locales/hi/messages.json b/src/_locales/hi/messages.json index 2d367556f..8f04b615f 100644 --- a/src/_locales/hi/messages.json +++ b/src/_locales/hi/messages.json @@ -24,7 +24,7 @@ "description":"appears as tab name in dashboard" }, "rulesPageName":{ - "message":"My rules", + "message":"मेरे नियम", "description":"appears as tab name in dashboard" }, "whitelistPageName":{ diff --git a/src/_locales/hu/messages.json b/src/_locales/hu/messages.json index 75d1558e4..d3aa1ffb2 100644 --- a/src/_locales/hu/messages.json +++ b/src/_locales/hu/messages.json @@ -4,7 +4,7 @@ "description":"extension name." }, "extShortDesc":{ - "message":"Végre egy hatékony reklám és követésblokkoló, amely kíméletes a processzorral és a memóriával.", + "message":"Végre egy hatékony reklám- és követésblokkoló böngészőkhöz, amely kíméletes a processzorral és a memóriával.", "description":"this will be in the chrome web store: must be 132 characters or less" }, "dashboardName":{ @@ -24,7 +24,7 @@ "description":"appears as tab name in dashboard" }, "rulesPageName":{ - "message":"My rules", + "message":"Saját szabályok", "description":"appears as tab name in dashboard" }, "whitelistPageName":{ @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock — Hálózati forgalom napló", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -72,107 +72,107 @@ "description":"English: Go to request log" }, "popupSiteInlineScriptEnabled":{ - "message":"Inline script<\/code> tags are allowed<\/b> on this site", + "message":"Beszúrt parancsfájl<\/code> tag-ek engedélyezve<\/b> ezen a webhelyen", "description":"" }, "popupSiteInlineScriptDisabled":{ - "message":"Inline script<\/code> tags are blocked<\/b> on this site", + "message":"Beszúrt parancsfájl<\/code> tag-ek letiltva<\/b> ezen a webhelyen", "description":"" }, "popupSite1pScriptEnabled":{ - "message":"1st-party scripts are allowed<\/b> on this site", + "message":"Webhelytől származó parancsfájlok engedélyezve<\/b> ezen a webhelyen", "description":"" }, "popupSite1pScriptDisabled":{ - "message":"1st-party scripts are blocked<\/b> on this site", + "message":"Webhelytől származó parancsfájlok letiltva<\/b> ezen a webhelyen", "description":"" }, "popupSite3pScriptEnabled":{ - "message":"3rd-party scripts are allowed<\/b> on this site", + "message":"Külső webhelytől származó parancsfájlok engedélyezve<\/b> ezen a webhelyen", "description":"" }, "popupSite3pScriptDisabled":{ - "message":"3rd-party scripts are blocked<\/b> on this site", + "message":"Külső webhelytől származó parancsfájlok letiltva<\/b> ezen a webhelyen", "description":"" }, "popupSite1pFrameEnabled":{ - "message":"1st-party frames are allowed<\/b> on this site", + "message":"Webhelytől származó keretek engedélyezve<\/b> ezen a webhelyen", "description":"" }, "popupSite1pFrameDisabled":{ - "message":"1st-party frames are blocked<\/b> on this site", + "message":"Webhelytől származó keretek letiltva<\/b> ezen a webhelyen", "description":"" }, "popupSite3pFrameEnabled":{ - "message":"3rd-party frames are allowed<\/b> on this site", + "message":"Külső webhelytől származó keretek engedélyezve<\/b> ezen a webhelyen", "description":"" }, "popupSite3pFrameDisabled":{ - "message":"3rd-party frames are blocked<\/b> on this site", + "message":"Külső webhelytől származó keretek letiltva<\/b> ezen a webhelyen", "description":"" }, "popupDefaultInlineScriptEnabled":{ - "message":"Inline script<\/code> tags are allowed<\/b> everywhere by default", + "message":"Beszúrt parancsfájl<\/code> tag-ek alapértelmezetten engedélyezve<\/b> minden webhelyen", "description":"" }, "popupDefaultInlineScriptDisabled":{ - "message":"Inline script<\/code> tags are blocked<\/b> everywhere by default", + "message":"Beszúrt parancsfájl<\/code> tag-ek alapértelmezetten letiltva<\/b> minden webhelyen", "description":"" }, "popupDefault1pScriptEnabled":{ - "message":"1st-party scripts are allowed<\/b> everywhere by default", + "message":"Webhelytől származó parancsfájlok alapértelmezetten engedélyezve<\/b> minden webhelyen", "description":"" }, "popupDefault1pScriptDisabled":{ - "message":"1st-party scripts are blocked<\/b> everywhere by default", + "message":"Webhelytől származó parancsfájlok alapértelmezetten letiltva<\/b> minden webhelyen", "description":"" }, "popupDefault3pScriptEnabled":{ - "message":"3rd-party scripts are allowed<\/b> everywhere by default", + "message":"Külső webhelytől származó parancsfájlok alapértelmezetten engedélyezve<\/b> minden webhelyen", "description":"" }, "popupDefault3pScriptDisabled":{ - "message":"3rd-party scripts are blocked<\/b> everywhere by default", + "message":"Külső webhelytől származó parancsfájlok alapértelmezetten letiltva<\/b> minden webhelyen", "description":"" }, "popupDefault1pFrameEnabled":{ - "message":"1st-party frames are allowed<\/b> everywhere by default", + "message":"Webhelytől származó keretek alapértelmezetten engedélyezve<\/b> minden webhelyen", "description":"" }, "popupDefault1pFrameDisabled":{ - "message":"1st-party frames are blocked<\/b> everywhere by default", + "message":"Webhelytől származó keretek alapértelmezetten letiltva<\/b> minden webhelyen", "description":"" }, "popupDefault3pFrameEnabled":{ - "message":"3rd-party frames are allowed<\/b> everywhere by default", + "message":"Külső webhelytől származó keretek alapértelmezetten engedélyezve<\/b> minden webhelyen", "description":"" }, "popupDefault3pFrameDisabled":{ - "message":"3rd-party frames are blocked<\/b> everywhere by default", + "message":"Külső webhelytől származó keretek alapértelmezetten letiltva<\/b> minden webhelyen", "description":"" }, "popupImageRulePrompt":{ - "message":"images", + "message":"képek", "description":"" }, "popupInlineScriptRulePrompt":{ - "message":"inline scripts", + "message":"beszúrt parancsfájlok", "description":"" }, "popup1pScriptRulePrompt":{ - "message":"1st-party scripts", + "message":"Webhelytől származó parancsfájlok", "description":"" }, "popup3pScriptRulePrompt":{ - "message":"3rd-party scripts", + "message":"Külső webhelytől származó parancsfájlok", "description":"" }, "popup3pFrameRulePrompt":{ - "message":"3rd-party frames", + "message":"Külső webhelytől származó keretek", "description":"" }, "popupHitDomainCountPrompt":{ - "message":"Connected to {{count}} distinct domain(s) out of {{total}}", + "message":"Kapcsolódva {{count}} eltérő tartományhoz, összesen: {{total}}", "description":"appear in dynamic filtering pane" }, "pickerCreate":{ @@ -216,7 +216,7 @@ "description":"English: Make use of context menu where appropriate" }, "settingsAdvancedUserPrompt":{ - "message":"I am an advanced user (Required reading<\/a>)", + "message":"Haladó felhasználó vagyok (További tudnivalók<\/a>)", "description":"English: " }, "settingsExperimentalPrompt":{ @@ -320,7 +320,7 @@ "description":"English: Export" }, "1pExportFilename":{ - "message":"my-ublock-static-filters_{{datetime}}.txt", + "message":"ublock-statikus-szabalyok_{{datetime}}.txt", "description":"English: my-ublock-static-filters_{{datetime}}.txt" }, "1pApplyChanges":{ @@ -336,27 +336,27 @@ "description":"Will save manually-edited content and exit manual-edit mode" }, "rulesEditDiscard":{ - "message":"Mégsem", + "message":"Mégse", "description":"Will discard manually-edited content and exit manual-edit mode" }, "rulesImport":{ - "message":"Importálás fájlból...", + "message":"Importálás fájlból…", "description":"" }, "rulesExport":{ - "message":"Exportálás fájlba...", + "message":"Exportálás fájlba…", "description":"" }, "rulesDefaultFileName":{ - "message":"ublock-dinamikus_szabalyaim.txt", + "message":"ublock-dinamikus-szabalyok_{{datetime}}.txt", "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"Saját szűrőszabályok listája.", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ - "message":"Rule syntax: source destination type action<\/code> (full documentation<\/a>).", + "message":"Szabályrendszer: forrás cél típus művelet<\/code> (Teljes dokumentáció<\/a>).", "description":"English: dynamic rule syntax and full documentation." }, "whitelistPrompt":{ @@ -372,7 +372,7 @@ "description":"English: Export" }, "whitelistExportFilename":{ - "message":"my-ublock-whitelist_{{datetime}}.txt", + "message":"ublock-kivetelek_{{datetime}}.txt", "description":"English: my-ublock-whitelist_{{datetime}}.txt" }, "whitelistApply":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"Hálózati forgalom a háttérben", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ @@ -444,7 +444,7 @@ "description":"English: Backup to file" }, "aboutBackupFilename":{ - "message":"my-ublock-backup_{{datetime}}.txt", + "message":"ublock-mentes_{{datetime}}.txt", "description":"English: my-ublock-backup_{{datetime}}.txt" }, "aboutRestoreDataButton":{ @@ -460,7 +460,7 @@ "description":"Message asking user to confirm restore" }, "aboutRestoreDataError":{ - "message":"The data could not be read or is invalid", + "message":"Nem olvasható vagy érvénytelen adat", "description":"Message to display when an error occurred during restore" }, "aboutResetDataConfirm":{ diff --git a/src/_locales/ja/messages.json b/src/_locales/ja/messages.json index 58fa78792..59a369827 100644 --- a/src/_locales/ja/messages.json +++ b/src/_locales/ja/messages.json @@ -1,6 +1,6 @@ { "extName":{ - "message":"μブロック", + "message":"µBlock", "description":"extension name." }, "extShortDesc":{ @@ -16,7 +16,7 @@ "description":"appears as tab name in dashboard" }, "3pPageName":{ - "message":"第三者製フィルター", + "message":"サードパーティ製フィルター", "description":"appears as tab name in dashboard" }, "1pPageName":{ @@ -40,7 +40,7 @@ "description":"appears as tab name in dashboard" }, "popupPowerSwitchInfo":{ - "message":"このボタンを押して
今のサイトだけに
エクステンションを完全にオンかオフにする", + "message":"µBlock の有効 \/ 無効を切り替えます。\n\nクリック: サイト全体 \nCtrl+クリック: このページのみ", "description":"English: Click: disable\/enable µBlock for this site.\n\nCtrl+click: disable µBlock only on this page." }, "popupBlockedRequestPrompt":{ @@ -52,7 +52,7 @@ "description":"English: on this page" }, "popupBlockedSinceInstallPrompt":{ - "message":"インストール以来", + "message":"インストールしてから", "description":"English: since install" }, "popupOr":{ @@ -220,7 +220,7 @@ "description":"English: " }, "settingsExperimentalPrompt":{ - "message":"実験的な機能を有効にする", + "message":"実験的な機能を有効にする (
About<\/a>)", "description":"English: Enable experimental features" }, "3pListsOfBlockedHostsPrompt":{ @@ -380,7 +380,7 @@ "description":"English: Apply changes" }, "logNetRequestsPrompt":{ - "message":"ネットワークリクエストのログ収集を有効にする", + "message":"ネットワークリクエストのログを有効にする", "description":"English: Enable the logging of network requests" }, "logNetRequestsHelp":{ @@ -388,7 +388,7 @@ "description":"English: see _locales\/en\/messages.log" }, "logBlockedRequestsHeader":{ - "message":"ブロックされたリルエスト", + "message":"ブロックされたリクエスト", "description":"English: Blocked requests" }, "logAllowedRequestsHeader":{ @@ -404,7 +404,7 @@ "description":"English: Domain" }, "logRequestsHeaderURL":{ - "message":"インターネットアドレス", + "message":"URL", "description":"English: URL" }, "logRequestsHeaderFilter":{ @@ -424,7 +424,7 @@ "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ - "message":"の変更履歴", + "message":"バージョン更新履歴 (Change log)", "description":"English: Change log" }, "aboutWiki":{ @@ -432,7 +432,7 @@ "description":"English: project' wiki on Github" }, "aboutCode":{ - "message":"根源コード(GPLバージョン3)", + "message":"ソースコード (GPLバージョン3)", "description":"English: Source code (GPLv3)" }, "aboutContributors":{ diff --git a/src/_locales/nl/messages.json b/src/_locales/nl/messages.json index bf45cfd3e..346228331 100644 --- a/src/_locales/nl/messages.json +++ b/src/_locales/nl/messages.json @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock — Log van netwerkverzoeken", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -320,7 +320,7 @@ "description":"English: Export" }, "1pExportFilename":{ - "message":"my-ublock-static-filters_{{datetime}}.txt", + "message":"mijn-ublock-statische-filters_{{datetime}}.txt", "description":"English: my-ublock-static-filters_{{datetime}}.txt" }, "1pApplyChanges":{ @@ -348,15 +348,15 @@ "description":"" }, "rulesDefaultFileName":{ - "message":"my-ublock-dynamic-rules_{{datetime}}.txt", + "message":"mijn-ublock-dynamische-regels_{{datetime}}.txt", "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"Lijst van uw dynamische filterregels.", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ - "message":"Rule syntax: source destination type action<\/code> (full documentation<\/a>).", + "message":"Regelsyntax: bron bestemming type actie<\/code> (volledige documentatie<\/a>).", "description":"English: dynamic rule syntax and full documentation." }, "whitelistPrompt":{ @@ -372,7 +372,7 @@ "description":"English: Export" }, "whitelistExportFilename":{ - "message":"my-ublock-whitelist_{{datetime}}.txt", + "message":"mijn-ublock-whitelist_{{datetime}}.txt", "description":"English: my-ublock-whitelist_{{datetime}}.txt" }, "whitelistApply":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"Achter de schermen", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ @@ -444,7 +444,7 @@ "description":"English: Backup to file" }, "aboutBackupFilename":{ - "message":"my-ublock-backup_{{datetime}}.txt", + "message":"mijn-ublock-backup_{{datetime}}.txt", "description":"English: my-ublock-backup_{{datetime}}.txt" }, "aboutRestoreDataButton":{ diff --git a/src/_locales/pt_PT/messages.json b/src/_locales/pt_PT/messages.json index f7750a06e..8fc4fd941 100644 --- a/src/_locales/pt_PT/messages.json +++ b/src/_locales/pt_PT/messages.json @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock — Registo de pedidos de rede", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -352,11 +352,11 @@ "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"Lista das suas regras de filtragem dinâmicas.", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ - "message":"Rule syntax: source destination type action<\/code> (full documentation<\/a>).", + "message":"Regra de sintaxe: origem destino tipo ação<\/code> (documentação completa<\/a>).", "description":"English: dynamic rule syntax and full documentation." }, "whitelistPrompt":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"Bastiadores", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ diff --git a/src/_locales/sv/messages.json b/src/_locales/sv/messages.json index ac5fefe35..cc263081b 100644 --- a/src/_locales/sv/messages.json +++ b/src/_locales/sv/messages.json @@ -24,7 +24,7 @@ "description":"appears as tab name in dashboard" }, "rulesPageName":{ - "message":"My rules", + "message":"Mina regler", "description":"appears as tab name in dashboard" }, "whitelistPageName":{ @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock - Nätverks log", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -72,103 +72,103 @@ "description":"English: Go to request log" }, "popupSiteInlineScriptEnabled":{ - "message":"Inline script<\/code> tags are allowed<\/b> on this site", + "message":"Inline skript<\/code>-taggar är tillåtna på<\/b> denna sida", "description":"" }, "popupSiteInlineScriptDisabled":{ - "message":"Inline script<\/code> tags are blocked<\/b> on this site", + "message":"Inline skript<\/code>-taggar är blockerade<\/b> på denna sida", "description":"" }, "popupSite1pScriptEnabled":{ - "message":"1st-party scripts are allowed<\/b> on this site", + "message":"förstapartsskript är tillåtna<\/b> på denna webbplats", "description":"" }, "popupSite1pScriptDisabled":{ - "message":"1st-party scripts are blocked<\/b> on this site", + "message":"förstapartsskript är blockerde<\/b> på denna webbplats", "description":"" }, "popupSite3pScriptEnabled":{ - "message":"3rd-party scripts are allowed<\/b> on this site", + "message":"tredjepartsskript är tillåtna<\/b> på denna webbplats", "description":"" }, "popupSite3pScriptDisabled":{ - "message":"3rd-party scripts are blocked<\/b> on this site", + "message":"tredjepartsskript är blockerade<\/b> på denna webbplats", "description":"" }, "popupSite1pFrameEnabled":{ - "message":"1st-party frames are allowed<\/b> on this site", + "message":"förstapartsramar är tillåtna<\/b> på denna webbplats", "description":"" }, "popupSite1pFrameDisabled":{ - "message":"1st-party frames are blocked<\/b> on this site", + "message":"förstapartsramar är blockerade<\/b> på denna webbplats", "description":"" }, "popupSite3pFrameEnabled":{ - "message":"3rd-party frames are allowed<\/b> on this site", + "message":"tredjepartsramar är tillåtna<\/b> på denna webbplats", "description":"" }, "popupSite3pFrameDisabled":{ - "message":"3rd-party frames are blocked<\/b> on this site", + "message":"tredjepartsramar är blockerade<\/b> på denna webbplats", "description":"" }, "popupDefaultInlineScriptEnabled":{ - "message":"Inline script<\/code> tags are allowed<\/b> everywhere by default", + "message":"Inline skripttaggarna<\/code> är tillåtna<\/b> överallt som standard", "description":"" }, "popupDefaultInlineScriptDisabled":{ - "message":"Inline script<\/code> tags are blocked<\/b> everywhere by default", + "message":"Inline skripttaggarna<\/code> är blockerade<\/b> överallt som standard", "description":"" }, "popupDefault1pScriptEnabled":{ - "message":"1st-party scripts are allowed<\/b> everywhere by default", + "message":"förstapartsskript är tillåtna<\/b> överallt som standard", "description":"" }, "popupDefault1pScriptDisabled":{ - "message":"1st-party scripts are blocked<\/b> everywhere by default", + "message":"förstapartsskript är blockerade<\/b> överallt som standard", "description":"" }, "popupDefault3pScriptEnabled":{ - "message":"3rd-party scripts are allowed<\/b> everywhere by default", + "message":"tredjepartsskript är tillåtna<\/b> överallt som standard", "description":"" }, "popupDefault3pScriptDisabled":{ - "message":"3rd-party scripts are blocked<\/b> everywhere by default", + "message":"tredjepartsskript är blockerade<\/b> överallt som standard", "description":"" }, "popupDefault1pFrameEnabled":{ - "message":"1st-party frames are allowed<\/b> everywhere by default", + "message":"förstapartsramar är tillåtna<\/b> överallt som standard", "description":"" }, "popupDefault1pFrameDisabled":{ - "message":"1st-party frames are blocked<\/b> everywhere by default", + "message":"förstapartsramar är blockerade<\/b> överallt som standard", "description":"" }, "popupDefault3pFrameEnabled":{ - "message":"3rd-party frames are allowed<\/b> everywhere by default", + "message":"tredjepartsramar är tillåtna<\/b> överallt som standard", "description":"" }, "popupDefault3pFrameDisabled":{ - "message":"3rd-party frames are blocked<\/b> everywhere by default", + "message":"tredjepartsramar är blockerade<\/b> överallt som standard", "description":"" }, "popupImageRulePrompt":{ - "message":"images", + "message":"bilder", "description":"" }, "popupInlineScriptRulePrompt":{ - "message":"inline scripts", + "message":"inline skript", "description":"" }, "popup1pScriptRulePrompt":{ - "message":"1st-party scripts", + "message":"förstaparstpartsskripts", "description":"" }, "popup3pScriptRulePrompt":{ - "message":"3rd-party scripts", + "message":"tredjepartsskript", "description":"" }, "popup3pFrameRulePrompt":{ - "message":"3rd-party frames", + "message":"tredjepartsramar", "description":"" }, "popupHitDomainCountPrompt":{ @@ -216,7 +216,7 @@ "description":"English: Make use of context menu where appropriate" }, "settingsAdvancedUserPrompt":{ - "message":"I am an advanced user (Required reading<\/a>)", + "message":"Jag är en avancerad användare ( obligatorisk läsning<\/a>)", "description":"English: " }, "settingsExperimentalPrompt":{ @@ -328,23 +328,23 @@ "description":"English: Apply changes" }, "rulesEdit":{ - "message":"Edit", + "message":"Redigera", "description":"Will enable manual-edit mode (textarea)" }, "rulesEditSave":{ - "message":"Save", + "message":"Spara", "description":"Will save manually-edited content and exit manual-edit mode" }, "rulesEditDiscard":{ - "message":"Discard", + "message":"Kasta", "description":"Will discard manually-edited content and exit manual-edit mode" }, "rulesImport":{ - "message":"Import from file...", + "message":"Importera från fil...", "description":"" }, "rulesExport":{ - "message":"Export to file...", + "message":"Exportera till fil...", "description":"" }, "rulesDefaultFileName":{ @@ -352,7 +352,7 @@ "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"Lista över din dynamiska filterregler.", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ @@ -372,7 +372,7 @@ "description":"English: Export" }, "whitelistExportFilename":{ - "message":"my-ublock-whitelist_{{datetime}}.txt", + "message":"min-ublock-vitlista_{{datetime}}.txt", "description":"English: my-ublock-whitelist_{{datetime}}.txt" }, "whitelistApply":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"Under huven", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ @@ -460,7 +460,7 @@ "description":"Message asking user to confirm restore" }, "aboutRestoreDataError":{ - "message":"The data could not be read or is invalid", + "message":"Datan gick inte att läsa eller är ogiltig", "description":"Message to display when an error occurred during restore" }, "aboutResetDataConfirm":{ diff --git a/src/_locales/uk/messages.json b/src/_locales/uk/messages.json index b7c765301..1a74acb57 100644 --- a/src/_locales/uk/messages.json +++ b/src/_locales/uk/messages.json @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock — Журнал мережевих запитів", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -352,11 +352,11 @@ "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"Список правил динамічного фільтрування.", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ - "message":"Rule syntax: source destination type action<\/code> (full documentation<\/a>).", + "message":"Синтаксис правил: джерело призначення тип дія<\/code> (повна документація<\/a>).", "description":"English: dynamic rule syntax and full documentation." }, "whitelistPrompt":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"За лаштунками", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ diff --git a/src/_locales/zh_CN/messages.json b/src/_locales/zh_CN/messages.json index b33f966a2..456d9aee9 100644 --- a/src/_locales/zh_CN/messages.json +++ b/src/_locales/zh_CN/messages.json @@ -4,7 +4,7 @@ "description":"extension name." }, "extShortDesc":{ - "message":"一款基于Chromium浏览器的高效广告拦截工具,超低的CPU与内存使用。", + "message":"高效的广告拦截工具,超低的CPU与内存使用。", "description":"this will be in the chrome web store: must be 132 characters or less" }, "dashboardName":{ @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock 网络请求日志", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -352,11 +352,11 @@ "description":"default file name to use" }, "rulesHint":{ - "message":"List of your dynamic filtering rules.", + "message":"动态过滤规则列表。", "description":"English: List of your dynamic filtering rules." }, "rulesFormatHint":{ - "message":"Rule syntax: source destination type action<\/code> (full documentation<\/a>).", + "message":"规则语法: 示范操作描述<\/code> ( 完整的文档<\/a>)。", "description":"English: dynamic rule syntax and full documentation." }, "whitelistPrompt":{ @@ -420,7 +420,7 @@ "description":"English: No non-blocked requests logged for this page" }, "logBehindTheScene":{ - "message":"Behind the scene", + "message":"后台", "description":"Pretty name for behind-the-scene network requests" }, "aboutChangelog":{ diff --git a/src/_locales/zh_TW/messages.json b/src/_locales/zh_TW/messages.json index 5040c62c0..4b032f338 100644 --- a/src/_locales/zh_TW/messages.json +++ b/src/_locales/zh_TW/messages.json @@ -24,7 +24,7 @@ "description":"appears as tab name in dashboard" }, "rulesPageName":{ - "message":"My rules", + "message":"自訂規則", "description":"appears as tab name in dashboard" }, "whitelistPageName":{ @@ -32,7 +32,7 @@ "description":"appears as tab name in dashboard" }, "statsPageName":{ - "message":"µBlock — Network request log", + "message":"µBlock — 網路請求日誌", "description":"Title for the network request log window" }, "aboutPageName":{ @@ -152,23 +152,23 @@ "description":"" }, "popupImageRulePrompt":{ - "message":"images", + "message":"圖片", "description":"" }, "popupInlineScriptRulePrompt":{ - "message":"inline scripts", + "message":"行內的腳本", "description":"" }, "popup1pScriptRulePrompt":{ - "message":"1st-party scripts", + "message":"第一方腳本", "description":"" }, "popup3pScriptRulePrompt":{ - "message":"3rd-party scripts", + "message":"協力廠商腳本", "description":"" }, "popup3pFrameRulePrompt":{ - "message":"3rd-party frames", + "message":"協力廠商框架", "description":"" }, "popupHitDomainCountPrompt":{ @@ -328,27 +328,27 @@ "description":"English: Apply changes" }, "rulesEdit":{ - "message":"Edit", + "message":"編輯", "description":"Will enable manual-edit mode (textarea)" }, "rulesEditSave":{ - "message":"Save", + "message":"儲存", "description":"Will save manually-edited content and exit manual-edit mode" }, "rulesEditDiscard":{ - "message":"Discard", + "message":"捨棄", "description":"Will discard manually-edited content and exit manual-edit mode" }, "rulesImport":{ - "message":"Import from file...", + "message":"從檔案匯入...", "description":"" }, "rulesExport":{ - "message":"Export to file...", + "message":"匯出至檔案...", "description":"" }, "rulesDefaultFileName":{ - "message":"my-ublock-dynamic-rules_{{datetime}}.txt", + "message":"ublock自訂動態規則_{{datetime}}.txt", "description":"default file name to use" }, "rulesHint":{ From f718e8e1f239690eae7ff964e1e2c3535c781043 Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 23 Jan 2015 15:02:47 -0500 Subject: [PATCH 10/10] better/safer fix for #587 --- src/js/contentscript-start.js | 2 +- src/js/cosmetic-filtering.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/js/contentscript-start.js b/src/js/contentscript-start.js index a60275ddc..1e9e4d3ef 100644 --- a/src/js/contentscript-start.js +++ b/src/js/contentscript-start.js @@ -148,7 +148,7 @@ var filteringHandler = function(details) { // If no filters were found, maybe the script was injected before uBlock's // process was fully initialized. When this happens, pages won't be // cleaned right after browser launch. - vAPI.contentscriptStartInjected = details && details.cosmeticHide.length !== 0; + vAPI.contentscriptStartInjected = details && details.ready; // Cleanup before leaving localMessager.close(); diff --git a/src/js/cosmetic-filtering.js b/src/js/cosmetic-filtering.js index e8452f249..e24d58c05 100644 --- a/src/js/cosmetic-filtering.js +++ b/src/js/cosmetic-filtering.js @@ -933,7 +933,6 @@ FilterContainer.prototype.fromSelfie = function(selfie) { return dict; }; - this.frozen = true; this.acceptedCount = selfie.acceptedCount; this.duplicateCount = selfie.duplicateCount; this.hostnameFilters = dictFromSelfie(selfie.hostnameSpecificFilters); @@ -951,6 +950,7 @@ FilterContainer.prototype.fromSelfie = function(selfie) { this.highHighGenericDonthide = selfie.highHighGenericDonthide; this.highHighGenericHideCount = selfie.highHighGenericHideCount; this.highHighGenericDonthideCount = selfie.highHighGenericDonthideCount; + this.frozen = true; }; /******************************************************************************/ @@ -1127,7 +1127,12 @@ FilterContainer.prototype.retrieveDomainSelectors = function(request) { var domain = µb.URI.domainFromHostname(hostname) || hostname; var pos = domain.indexOf('.'); + // https://github.com/gorhill/uBlock/issues/587 + // r.ready will tell the content script the cosmetic filtering engine is + // up and ready. + var r = { + ready: this.frozen, domain: domain, entity: pos === -1 ? domain : domain.slice(0, pos - domain.length), skipCosmeticFiltering: this.acceptedCount === 0,