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)