Deathamns
10 years ago
committed by
gorhill
1 changed files with 169 additions and 0 deletions
@ -0,0 +1,169 @@ |
|||||
|
/* global Services, Components, XPCOMUtils */ |
||||
|
/* exported EXPORTED_SYMBOLS, isTabbed */ |
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
var EXPORTED_SYMBOLS = ['contentPolicy', 'docObserver']; |
||||
|
|
||||
|
Components.utils['import']('resource://gre/modules/Services.jsm'); |
||||
|
Components.utils['import']('resource://gre/modules/XPCOMUtils.jsm'); |
||||
|
|
||||
|
const Ci = Components.interfaces, appName = 'ublock'; |
||||
|
|
||||
|
let getMessager = function(win) { |
||||
|
try { |
||||
|
// e10s
|
||||
|
return win |
||||
|
.QueryInterface(Ci.nsIInterfaceRequestor) |
||||
|
.getInterface(Ci.nsIWebNavigation) |
||||
|
.QueryInterface(Ci.nsIDocShellTreeItem) |
||||
|
.rootTreeItem |
||||
|
.QueryInterface(Ci.nsIInterfaceRequestor) |
||||
|
.getInterface(Ci.nsIContentFrameMessageManager); |
||||
|
} catch (ex) { |
||||
|
return win |
||||
|
.QueryInterface(Ci.nsIInterfaceRequestor) |
||||
|
.getInterface(Ci.nsIWebNavigation) |
||||
|
.QueryInterface(Ci.nsIDocShell) |
||||
|
.QueryInterface(Ci.nsIInterfaceRequestor) |
||||
|
.getInterface(Ci.nsIContentFrameMessageManager); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
let contentPolicy = { |
||||
|
classDescription: 'ContentPolicy implementation', |
||||
|
classID: Components.ID('{e6d173c8-8dbf-4189-a6fd-189e8acffd27}'), |
||||
|
contractID: '@ublock/content-policy;1', |
||||
|
ACCEPT: Ci.nsIContentPolicy.ACCEPT, |
||||
|
REJECT: Ci.nsIContentPolicy.REJECT_REQUEST, |
||||
|
get componentRegistrar() { |
||||
|
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar); |
||||
|
}, |
||||
|
get categoryManager() { |
||||
|
return Components.classes['@mozilla.org/categorymanager;1'] |
||||
|
.getService(Ci.nsICategoryManager); |
||||
|
}, |
||||
|
QueryInterface: XPCOMUtils.generateQI([ |
||||
|
Ci.nsIFactory, |
||||
|
Ci.nsIContentPolicy, |
||||
|
Ci.nsISupportsWeakReference |
||||
|
]), |
||||
|
createInstance: function(outer, iid) { |
||||
|
if (outer) { |
||||
|
throw Components.results.NS_ERROR_NO_AGGREGATION; |
||||
|
} |
||||
|
|
||||
|
return this.QueryInterface(iid); |
||||
|
}, |
||||
|
register: function() { |
||||
|
this.componentRegistrar.registerFactory( |
||||
|
this.classID, |
||||
|
this.classDescription, |
||||
|
this.contractID, |
||||
|
this |
||||
|
); |
||||
|
this.categoryManager.addCategoryEntry( |
||||
|
'content-policy', |
||||
|
this.contractID, |
||||
|
this.contractID, |
||||
|
false, |
||||
|
true |
||||
|
); |
||||
|
}, |
||||
|
unregister: function() { |
||||
|
this.componentRegistrar.unregisterFactory(this.classID, this); |
||||
|
this.categoryManager.deleteCategoryEntry( |
||||
|
'content-policy', |
||||
|
this.contractID, |
||||
|
false |
||||
|
); |
||||
|
}, |
||||
|
shouldLoad: function(type, location, origin, context) { |
||||
|
if (type === 6 || !context || !/^https?$/.test(location.scheme)) { |
||||
|
return this.ACCEPT; |
||||
|
} |
||||
|
|
||||
|
let win = (context.ownerDocument || context).defaultView; |
||||
|
|
||||
|
if (!win) { |
||||
|
return this.ACCEPT; |
||||
|
} |
||||
|
|
||||
|
let result = getMessager(win).sendSyncMessage('ublock:onBeforeRequest', { |
||||
|
url: location.spec, |
||||
|
type: type, |
||||
|
tabId: -1, |
||||
|
frameId: win === win.top ? 0 : 1, |
||||
|
parentFrameId: win === win.top ? -1 : 0 |
||||
|
})[0]; |
||||
|
|
||||
|
return result === true ? this.REJECT : this.ACCEPT; |
||||
|
}/*, |
||||
|
shouldProcess: function() { |
||||
|
return this.ACCEPT; |
||||
|
}*/ |
||||
|
}; |
||||
|
|
||||
|
let docObserver = { |
||||
|
contentBaseURI: 'chrome://ublock/content/js/', |
||||
|
initContext: function(win, sandbox) { |
||||
|
let messager = getMessager(win); |
||||
|
|
||||
|
if (sandbox) { |
||||
|
win = Components.utils.Sandbox([win], { |
||||
|
sandboxPrototype: win, |
||||
|
wantComponents: false, |
||||
|
wantXHRConstructor: false |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
win.sendAsyncMessage = messager.sendAsyncMessage; |
||||
|
win.addMessageListener = messager.ublock_addMessageListener; |
||||
|
win.removeMessageListener = messager.ublock_removeMessageListener; |
||||
|
|
||||
|
return win; |
||||
|
}, |
||||
|
register: function() { |
||||
|
Services.obs.addObserver(this, 'document-element-inserted', false); |
||||
|
}, |
||||
|
unregister: function() { |
||||
|
Services.obs.removeObserver(this, 'document-element-inserted'); |
||||
|
}, |
||||
|
observe: function(doc) { |
||||
|
let win = doc.defaultView; |
||||
|
|
||||
|
if (!win) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!/^https?:$/.test(win.location.protocol)) { |
||||
|
if (win.location.protocol === 'chrome:' |
||||
|
&& win.location.host === appName) { |
||||
|
this.initContext(win); |
||||
|
} |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
let lss = Services.scriptloader.loadSubScript; |
||||
|
win = this.initContext(win, true); |
||||
|
|
||||
|
lss(this.contentBaseURI + 'vapi-client.js', win); |
||||
|
lss(this.contentBaseURI + 'contentscript-start.js', win); |
||||
|
|
||||
|
if (doc.readyState === 'interactive' || doc.readyState === 'complete') { |
||||
|
lss(this.contentBaseURI + 'contentscript-end.js', win); |
||||
|
} |
||||
|
else { |
||||
|
let docReady = function(e) { |
||||
|
this.removeEventListener(e.type, docReady, true); |
||||
|
lss(docObserver.contentBaseURI + 'contentscript-end.js', win); |
||||
|
}; |
||||
|
|
||||
|
doc.addEventListener('DOMContentLoaded', docReady, true); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
contentPolicy.register(); |
||||
|
docObserver.register(); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue