Index: lib/crawler.js |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/lib/crawler.js |
@@ -0,0 +1,132 @@ |
+Cu.import("resource://gre/modules/Services.jsm"); |
+ |
+function abprequire(module) |
+{ |
+ let result = {}; |
+ result.wrappedJSObject = result; |
+ Services.obs.notifyObservers(result, "adblockplus-require", module); |
+ return result.exports; |
+} |
+ |
+let {Storage} = require("storage"); |
+let {Client} = require("client"); |
+ |
+let {Policy} = abprequire("contentPolicy"); |
+let {Filter} = abprequire("filterClasses"); |
+let {Utils} = abprequire("utils"); |
+ |
+let origProcessNode = Policy.processNode; |
+ |
+let siteTabs; |
+let currentTabs; |
+ |
+function processNode(wnd, node, contentType, location, collapse) |
+{ |
+ let result = origProcessNode.apply(this, arguments); |
+ let url = (contentType === Policy.type.ELEMHIDE) ? location.text : |
+ location.spec; |
+ |
+ let topWindow = wnd.top; |
+ if (!topWindow.document) |
+ { |
+ Cu.reportError("No document associated with the node's top window"); |
+ return result; |
+ } |
+ |
+ let tabbrowser = Utils.getChromeWindow(topWindow).gBrowser; |
+ if (!tabbrowser) |
+ { |
+ Cu.reportError("Unable to get a tabbrowser reference"); |
+ return result; |
+ } |
+ |
+ let browser = tabbrowser.getBrowserForDocument(topWindow.document); |
+ if (!browser) |
+ { |
+ Cu.reportError("Unable to get browser for the tab"); |
+ return result; |
+ } |
+ |
+ let site = siteTabs.get(browser); |
+ let filtered = !result; |
+ Storage.write([url, site, filtered]); |
+ return result; |
+} |
+ |
+function loadSite(site, window, callback) |
+{ |
+ if (!site) |
+ return; |
+ |
+ let tabbrowser = window.gBrowser; |
+ let tab = tabbrowser.addTab(site); |
+ let browser = tabbrowser.getBrowserForTab(tab); |
+ |
+ siteTabs.set(browser, site); |
+ |
+ let progressListener = { |
+ onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) |
+ { |
+ if (browser !== aBrowser) |
+ return; |
+ |
+ if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)) |
+ return; |
+ |
+ tabbrowser.removeTabsProgressListener(progressListener); |
+ tabbrowser.removeTab(tab); |
+ callback(); |
+ } |
+ }; |
+ tabbrowser.addTabsProgressListener(progressListener); |
+} |
+ |
+function loadSites(backendUrl, parallelTabs, window, sites, callback) |
+{ |
+ while (currentTabs < parallelTabs && sites.length) |
+ { |
+ currentTabs++; |
+ let site = sites.shift(); |
+ loadSite(site, window, function() |
+ { |
+ currentTabs--; |
+ if (!sites.length && !currentTabs) |
+ { |
+ Storage.finish(); |
+ let dataFilePath = Storage.dataFile.path; |
+ Client.sendCrawlerDataFile(backendUrl, dataFilePath, function() |
+ { |
+ Storage.destroy(); |
+ callback(); |
+ }); |
+ } |
+ else |
+ loadSites(backendUrl, parallelTabs, window, sites, callback); |
+ }); |
+ } |
+} |
+ |
+let Crawler = exports.Crawler = {}; |
+ |
+Crawler.crawl = function(backendUrl, parallelTabs, window, callback) |
+{ |
+ if (Policy.processNode != origProcessNode) |
+ return; |
+ |
+ Policy.processNode = processNode; |
+ |
+ siteTabs = new WeakMap(); |
+ currentTabs = 0; |
+ |
+ Storage.init(); |
+ |
+ Client.fetchCrawlableSites(backendUrl, function(sites) |
+ { |
+ loadSites(backendUrl, parallelTabs, window, sites, function() |
+ { |
+ Policy.processNode = origProcessNode; |
+ siteTabs = null; |
+ callback(); |
+ }); |
+ }); |
+}; |