diff --git a/assets/checksums.txt b/assets/checksums.txt index 1f04cbec7..43dd1d792 100644 --- a/assets/checksums.txt +++ b/assets/checksums.txt @@ -1,5 +1,5 @@ 7edb2a585b445f28aa5ab06306f1a23f assets/ublock/privacy.txt -2810e208d9ba4912e4e10123283e071a assets/ublock/filters.txt +f3855e8737d6871ea3185020b1f14af9 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 237ce79c5..baa194114 100644 --- a/assets/ublock/filters.txt +++ b/assets/ublock/filters.txt @@ -29,7 +29,8 @@ www.zerohedge.com##.similar-box # entity = domain minus public suffix # The following filters were taken out of EasyList and given an entity name, # which makes them candidates to be injected early in the page. -# Last updated: 2014-11-14 +# Last updated: 2015-01-27 +google.*###center_col > #\5f Emc google.*###center_col > #resultStats + #tads google.*###center_col > #resultStats + #tads + #res + #tads google.*###center_col > #resultStats + div + #res + #tads @@ -63,12 +64,14 @@ google.*##.ch[onclick="ga(this,event)"] google.*##.commercial-unit-desktop-rhs google.*##.commercial-unit-desktop-top google.*##.lads[width="100%"][style="background:#FFF8DD"] +google.*##.mod > ._jH + .rscontainer google.*##.mw > #rcnt > #center_col > #taw > #tvcap > .c google.*##.mw > #rcnt > #center_col > #taw > .c google.*##.ra[align="left"][width="30%"] google.*##.ra[align="right"][width="30%"] google.*##.ra[width="30%"][align="right"] + table[width="70%"][cellpadding="0"] google.*##.rhsvw[style="background-color:#fff;margin:0 0 14px;padding-bottom:1px;padding-top:1px;"] +google.*##.rscontainer > .ellip # https://github.com/gorhill/uBlock/issues/381 google.*###sqh @@ -270,4 +273,14 @@ ovh.strim.io#@##tweets # https://twitter.com/yo_0/status/559748330390323200 # To counter `||clickbank.com^` in Dan Pollock's, Peter Lowe's -@@||clickbank.com^$~third-party \ No newline at end of file +@@||clickbank.com^$~third-party + +# https://github.com/gorhill/uBlock/issues/614 +# To counter `awaps.yandex.ru` in hpHosts +# To counter `mc.yandex.ru` in hpHosts, MVPS +@@||awaps.yandex.ru^$domain=market.yandex.ru +@@||mc.yandex.ru^$domain=market.yandex.ru +@@||yastatic.net/market-export/*/advert.js$domain=market.yandex.ru + +# https://github.com/gorhill/uBlock/issues/618 +deviantart.com##.dp-ad-chrome.dp-ad-visible \ No newline at end of file diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index a360d7168..1124ca046 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -30,7 +30,7 @@ const {Services} = Cu.import('resource://gre/modules/Services.jsm', null); const hostName = Services.io.newURI(Components.stack.filename, null, null).host; let uniqueSandboxId = 1; -// let {console} = Cu.import('resource://gre/modules/devtools/Console.jsm', null); +// Cu.import('resource://gre/modules/devtools/Console.jsm'); /******************************************************************************/ @@ -112,6 +112,13 @@ const contentObserver = { ); }, + getFrameId: function(win) { + return win + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .outerWindowID; + }, + // https://bugzil.la/612921 shouldLoad: function(type, location, origin, context) { if ( !context ) { @@ -122,10 +129,17 @@ const contentObserver = { return this.ACCEPT; } - let openerURL, frameId; + let openerURL = null; if ( type === this.MAIN_FRAME ) { - frameId = -1; + // When an iframe is loaded, it will be reported first as type = 6, + // then immediately after that type = 7, so ignore the first report. + // Origin should be "chrome://browser/content/browser.xul" here. + // The lack of side-effects are not guaranteed though. + if ( origin === null || origin.schemeIs('chrome') === false ) { + return this.ACCEPT; + } + context = context.contentWindow || context; try { @@ -134,9 +148,6 @@ const contentObserver = { } } catch (ex) {} } else { - // TODO: frameId from outerWindowID? - // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindowUtils - frameId = context === context.top ? 0 : 1; context = (context.ownerDocument || context).defaultView; } @@ -146,11 +157,22 @@ const contentObserver = { return this.ACCEPT; } + let isTopLevel = context === context.top; + let parentFrameId; + + if ( isTopLevel ) { + parentFrameId = -1; + } else if ( context.parent === context.top ) { + parentFrameId = 0; + } else { + parentFrameId = this.getFrameId(context.parent); + } + let messageManager = getMessageManager(context); let details = { - frameId: frameId, - openerURL: openerURL || null, - parentFrameId: context === context.top ? -1 : 0, + frameId: isTopLevel ? 0 : this.getFrameId(context), + openerURL: openerURL, + parentFrameId: parentFrameId, type: type, url: location.spec }; @@ -183,14 +205,9 @@ const contentObserver = { wantXHRConstructor: false }); - sandbox.injectScript = function(script, evalCode) { - if ( evalCode ) { - Cu.evalInSandbox(script, this); - return; - } - - Services.scriptloader.loadSubScript(script, this); - }.bind(sandbox); + sandbox.injectScript = function(script) { + Services.scriptloader.loadSubScript(script, sandbox); + }; } else { sandbox = win; @@ -200,43 +217,43 @@ const contentObserver = { sandbox.sendAsyncMessage = messager.sendAsyncMessage; sandbox.addMessageListener = function(callback) { - if ( this._messageListener_ ) { - this.removeMessageListener( - this._sandboxId_, - this._messageListener_ + if ( sandbox._messageListener_ ) { + sandbox.removeMessageListener( + sandbox._sandboxId_, + sandbox._messageListener_ ); } - this._messageListener_ = function(message) { + sandbox._messageListener_ = function(message) { callback(message.data); }; messager.addMessageListener( - this._sandboxId_, - this._messageListener_ + sandbox._sandboxId_, + sandbox._messageListener_ ); messager.addMessageListener( hostName + ':broadcast', - this._messageListener_ + sandbox._messageListener_ ); - }.bind(sandbox); + }; sandbox.removeMessageListener = function() { try { messager.removeMessageListener( - this._sandboxId_, - this._messageListener_ + sandbox._sandboxId_, + sandbox._messageListener_ ); messager.removeMessageListener( hostName + ':broadcast', - this._messageListener_ + sandbox._messageListener_ ); } catch (ex) { // It throws sometimes, mostly when the popup closes } - this._messageListener_ = null; - }.bind(sandbox); + sandbox._messageListener_ = null; + }; return sandbox; }, diff --git a/platform/firefox/install.rdf b/platform/firefox/install.rdf index c1534e143..2607c1433 100644 --- a/platform/firefox/install.rdf +++ b/platform/firefox/install.rdf @@ -5,13 +5,14 @@ {version} {name} {description} - https://github.com/gorhill/uBlock + {homepage} {author} 2 true true 3 chrome://ublock/content/dashboard.html +{localized} diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index e544f06eb..a9820432e 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -252,19 +252,6 @@ vAPI.storage = { /******************************************************************************/ var windowWatcher = { - onTabClose: function(e) { - var tabId = vAPI.tabs.getTabId(e.target); - vAPI.tabs.onClosed(tabId); - delete vAPI.toolbarButton.tabs[tabId]; - }, - - onTabSelect: function(e) { - vAPI.setIcon( - vAPI.tabs.getTabId(e.target), - e.target.ownerDocument.defaultView - ); - }, - onReady: function(e) { if ( e ) { this.removeEventListener(e.type, windowWatcher.onReady); @@ -282,9 +269,9 @@ var windowWatcher = { var tC = this.gBrowser.tabContainer; - this.gBrowser.addTabsProgressListener(tabsProgressListener); - tC.addEventListener('TabClose', windowWatcher.onTabClose); - tC.addEventListener('TabSelect', windowWatcher.onTabSelect); + this.gBrowser.addTabsProgressListener(tabWatcher); + tC.addEventListener('TabClose', tabWatcher.onTabClose); + tC.addEventListener('TabSelect', tabWatcher.onTabSelect); vAPI.contextMenu.register(this.document); @@ -300,7 +287,30 @@ var windowWatcher = { /******************************************************************************/ -var tabsProgressListener = { +var tabWatcher = { + onTabClose: function({target: tab}) { + var tabId = vAPI.tabs.getTabId(tab); + vAPI.tabs.onClosed(tabId); + delete vAPI.toolbarButton.tabs[tabId]; + }, + + onTabSelect: function({target: tab}) { + var URI = tab.linkedBrowser.currentURI; + var aboutPath = URI.schemeIs('about') && URI.path; + var tabId = vAPI.tabs.getTabId(tab); + + if ( !aboutPath || (aboutPath !== 'blank' && aboutPath !== 'newtab') ) { + vAPI.setIcon(tabId, tab.ownerDocument.defaultView); + return; + } + + vAPI.tabs.onNavigation({ + frameId: 0, + tabId: tabId, + url: URI.asciiSpec + }); + }, + onLocationChange: function(browser, webProgress, request, location, flags) { if ( !webProgress.isTopLevel ) { return; @@ -330,10 +340,6 @@ var tabsProgressListener = { /******************************************************************************/ -vAPI.tabs = {}; - -/******************************************************************************/ - vAPI.isNoTabId = function(tabId) { return tabId.toString() === '-1'; }; @@ -342,10 +348,14 @@ vAPI.noTabId = '-1'; /******************************************************************************/ +vAPI.tabs = {}; + +/******************************************************************************/ + vAPI.tabs.registerListeners = function() { - // onNavigation and onUpdated handled with tabsProgressListener - // onClosed - handled in windowWatcher.onTabClose - // onPopup ? + // onNavigation and onUpdated handled with tabWatcher.onLocationChange + // onClosed - handled in tabWatcher.onTabClose + // onPopup - handled in httpObserver.handlePopup for ( var win of this.getWindows() ) { windowWatcher.onReady.call(win); @@ -360,11 +370,11 @@ vAPI.tabs.registerListeners = function() { vAPI.contextMenu.unregister(win.document); win.removeEventListener('DOMContentLoaded', windowWatcher.onReady); - win.gBrowser.removeTabsProgressListener(tabsProgressListener); + win.gBrowser.removeTabsProgressListener(tabWatcher); var tC = win.gBrowser.tabContainer; - tC.removeEventListener('TabClose', windowWatcher.onTabClose); - tC.removeEventListener('TabSelect', windowWatcher.onTabSelect); + tC.removeEventListener('TabClose', tabWatcher.onTabClose); + tC.removeEventListener('TabSelect', tabWatcher.onTabSelect); // close extension tabs for ( var tab of win.gBrowser.tabs ) { @@ -600,11 +610,11 @@ vAPI.tabs.injectScript = function(tabId, details, callback) { return; } - if ( details.file ) { - details.file = vAPI.getURL(details.file); + if ( typeof details.file !== 'string' ) { + return; } - + details.file = vAPI.getURL(details.file); tab.linkedBrowser.messageManager.sendAsyncMessage( location.host + ':broadcast', JSON.stringify({ @@ -636,10 +646,7 @@ vAPI.setIcon = function(tabId, iconStatus, badge) { if ( tabId === undefined ) { tabId = curTabId; } else if ( badge !== undefined ) { - tb.tabs[tabId] = { - badge: badge, - img: iconStatus === 'on' - }; + tb.tabs[tabId] = { badge: badge, img: iconStatus === 'on' }; } if ( tabId !== curTabId ) { @@ -951,7 +958,13 @@ var httpObserver = { } try { - // [type, tabId, sourceTabId - given if it was a popup] + /*[ + type, + tabId, + sourceTabId - given if it was a popup, + frameId, + parentFrameId + ]*/ channelData = channel.getProperty(location.host + 'reqdata'); } catch (ex) { return; @@ -975,7 +988,7 @@ var httpObserver = { result = vAPI.net.onHeadersReceived.callback({ hostname: URI.asciiHost, - parentFrameId: channelData[0] === this.MAIN_FRAME ? -1 : 0, + parentFrameId: channelData[4], responseHeaders: result ? [{name: topic, value: result}] : [], tabId: channelData[1], url: URI.asciiSpec @@ -1040,7 +1053,13 @@ var httpObserver = { if ( channel instanceof Ci.nsIWritablePropertyBag ) { channel.setProperty( location.host + 'reqdata', - [lastRequest.type, lastRequest.tabId, sourceTabId] + [ + lastRequest.type, + lastRequest.tabId, + sourceTabId, + lastRequest.frameId, + lastRequest.parentFrameId + ] ); } }, @@ -1067,20 +1086,21 @@ var httpObserver = { return; } + // TODO: what if a behind-the-scene request is being redirected? + // This data is present only for tabbed requests, so if this throws, + // the redirection won't be evaluated and canceled (if necessary) var channelData = oldChannel.getProperty(location.host + 'reqdata'); - var [type, tabId, sourceTabId] = channelData; - if ( this.handlePopup(URI, tabId, sourceTabId) ) { + if ( this.handlePopup(URI, channelData[1], channelData[2]) ) { result = this.ABORT; return; } var details = { - type: type, - tabId: tabId, - // well... - frameId: type === this.MAIN_FRAME ? -1 : 0, - parentFrameId: -1 + type: channelData[0], + tabId: channelData[1], + frameId: channelData[3], + parentFrameId: channelData[4] }; if ( this.handleRequest(newChannel, URI, details) ) { diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js index d11a84f9e..58bb110ca 100644 --- a/platform/firefox/vapi-client.js +++ b/platform/firefox/vapi-client.js @@ -96,7 +96,7 @@ vAPI.messaging = { return; } - self.injectScript(details.file || details.code, !details.file); + self.injectScript(details.file); } }; }, diff --git a/src/js/contentscript-end.js b/src/js/contentscript-end.js index 82ce59fc7..98b347b1f 100644 --- a/src/js/contentscript-end.js +++ b/src/js/contentscript-end.js @@ -545,7 +545,7 @@ var messager = vAPI.messaging.channel('contentscript-end.js'); if ( typeof src !== 'string' || src === '' ) { return; } - if ( src.slice(0, 4) !== 'http' ) { + if ( src.lastIndexOf('http', 0) !== 0 ) { return; } @@ -584,12 +584,12 @@ var messager = vAPI.messaging.channel('contentscript-end.js'); }; var onResourceLoaded = function(ev) { - //console.debug('Loaded %s[src="%s"]', ev.target.tagName, ev.target.src); + //console.debug('onResourceLoaded(%o)', ev); onResource(ev.target, loadedElements); }; var onResourceFailed = function(ev) { - //console.debug('Failed to load %s[src="%s"]', ev.target.tagName, ev.target.src); + //console.debug('onResourceFailed(%o)', ev); onResource(ev.target, failedElements); }; @@ -661,7 +661,7 @@ var messager = vAPI.messaging.channel('contentscript-end.js'); if ( typeof src !== 'string' || src === '' ) { continue; } - if ( src.slice(0, 4) !== 'http' ) { + if ( src.lastIndexOf('http', 0) !== 0 ) { continue; } requests.push({ diff --git a/tools/make-firefox-meta.py b/tools/make-firefox-meta.py index 55922d546..ba8e4baf0 100644 --- a/tools/make-firefox-meta.py +++ b/tools/make-firefox-meta.py @@ -23,17 +23,16 @@ build_dir = os.path.abspath(sys.argv[1]) source_locale_dir = pj(build_dir, '_locales') target_locale_dir = pj(build_dir, 'locale') language_codes = [] -description = '' +descriptions = OrderedDict({}) for alpha2 in sorted(os.listdir(source_locale_dir)): locale_path = pj(source_locale_dir, alpha2, 'messages.json') with open(locale_path, encoding='utf-8') as f: string_data = json.load(f, object_pairs_hook=OrderedDict) - if alpha2 == 'en': - description = string_data['extShortDesc']['message'] - alpha2 = alpha2.replace('_', '-') + descriptions[alpha2] = string_data['extShortDesc']['message'] + del string_data['extShortDesc'] language_codes.append(alpha2) @@ -54,8 +53,10 @@ with open(chrome_manifest, 'at', encoding='utf-8', newline='\n') as f: f.write(u'\nlocale ublock en ./locale/en/\n') for alpha2 in language_codes: - if alpha2 != 'en': - f.write(u'locale ublock ' + alpha2 + ' ./locale/' + alpha2 + '/\n') + if alpha2 == 'en': + continue + + f.write(u'locale ublock ' + alpha2 + ' ./locale/' + alpha2 + '/\n') rmtree(source_locale_dir) @@ -66,10 +67,32 @@ chromium_manifest = pj(proj_dir, 'platform', 'chromium', 'manifest.json') with open(chromium_manifest, encoding='utf-8') as m: manifest = json.load(m) -manifest['description'] = description +manifest['homepage'] = 'https://github.com/gorhill/uBlock' +manifest['description'] = descriptions['en'] +del descriptions['en'] +manifest['localized'] = [] + +t = ' ' +t3 = 3 * t + +for alpha2 in descriptions: + if alpha2 == 'en': + continue + + manifest['localized'].append( + '\n' + t*2 + '\n' + + t3 + '' + alpha2 + '\n' + + t3 + '' + manifest['name'] + '\n' + + t3 + '' + descriptions[alpha2] + '\n' + + t3 + '' + manifest['author'] + '\n' + + # t3 + '' + ??? + '\n' + + t3 + '' + manifest['homepage'] + '\n' + + t*2 + '' + ) + +manifest['localized'] = '\n'.join(manifest['localized']) install_rdf = pj(build_dir, 'install.rdf') - with open(install_rdf, 'r+t', encoding='utf-8', newline='\n') as f: install_rdf = f.read() f.seek(0)