OLD | NEW |
1 /* | 1 /* |
2 * This Source Code is subject to the terms of the Mozilla Public License | 2 * This Source Code is subject to the terms of the Mozilla Public License |
3 * version 2.0 (the "License"). You can obtain a copy of the License at | 3 * version 2.0 (the "License"). You can obtain a copy of the License at |
4 * http://mozilla.org/MPL/2.0/. | 4 * http://mozilla.org/MPL/2.0/. |
5 */ | 5 */ |
6 | 6 |
7 Cu.import("resource://gre/modules/Services.jsm"); | 7 dump( "--------\n" ); |
8 | 8 |
9 let {WindowObserver} = require("windowObserver"); | 9 Cu.import( "resource://gre/modules/Services.jsm" ); |
10 | 10 |
| 11 let {WindowObserver} = require( "windowObserver" ); |
| 12 let { Application_Session } = require( "application" ); |
| 13 let { Bootstrap_XPCOM } = require( "bootstrap_xpcom" ); |
| 14 let { Command_Line } = require( "command_line" ); |
| 15 dump( "main.js: all require() finished\n" ); |
| 16 |
| 17 //------------------------------------------------------- |
| 18 // Main |
| 19 //------------------------------------------------------- |
| 20 |
| 21 var Main = new Bootstrap_XPCOM.Singleton_class( |
| 22 "ABP Crawler - Main", |
| 23 Components.ID( "{7beffb8d-13e4-472c-9623-e3f3d7f37383}" ), |
| 24 "@adblockplus.org/abpcrawler/main;1", |
| 25 [ Ci.nsIObserver ], |
| 26 [] ); |
| 27 |
| 28 Main.observe = function( subject, topic, data ) |
| 29 { |
| 30 dump( "Main.observe: topic = " + topic + ( data ? ", data = " + data : "" ) +
"\n" ); |
| 31 switch ( topic ) |
| 32 { |
| 33 case "profile-before-change": |
| 34 this.remove_observation_topic( topic ); |
| 35 break; |
| 36 } |
| 37 }; |
| 38 |
| 39 /** |
| 40 * Startup function. |
| 41 * |
| 42 * Strictly speaking this is only the startup function for automatic sessions at
this time. The interactive version |
| 43 * will already have initialized below. |
| 44 */ |
| 45 Main.startup = function() |
| 46 { |
| 47 dump( "Main/startup: invoked.\n" ); |
| 48 |
| 49 if ( !( "flags" in Command_Line ) ) |
| 50 { |
| 51 throw new Error( "No flags found in Command_Line.\n" ); |
| 52 } |
| 53 var flags = Command_Line.flags; |
| 54 if ( !( "abpcrawler" in flags ) || !flags.abpcrawler ) |
| 55 { |
| 56 // No session for us. |
| 57 return; |
| 58 } |
| 59 /* |
| 60 * There was a command line argument that ordered an automatic run. Here we ch
eck the arguments for validity, |
| 61 * create an Application_Session, and start it running. |
| 62 */ |
| 63 var session = make_session( flags ); |
| 64 if ( !session ) |
| 65 { |
| 66 // Error messages were already generated in make_session. |
| 67 return; |
| 68 } |
| 69 if ( !session.window ) |
| 70 { |
| 71 dump( "Main: session does not have a window. Aborted.\n" ); |
| 72 return; |
| 73 } |
| 74 this.session = session; |
| 75 /* |
| 76 * At this point we have a session and its window, but the window may not be i
nitialized. So what we have to do is |
| 77 * to wait for the window to show up. |
| 78 */ |
| 79 this.ready_listener = this.ready.bind( this ); |
| 80 session.window.addEventListener( "load", this.ready_listener ); |
| 81 // This action should really have a timeout attached to it. |
| 82 dump( "Main/startup: waiting for window load.\n"); |
| 83 }; |
| 84 |
| 85 /** |
| 86 * Launch the session when we're fully ready and have a window object. |
| 87 */ |
| 88 Main.ready = function() |
| 89 { |
| 90 if ( !this.session.window.gBrowser ) |
| 91 { |
| 92 dump( "Main/ready: session window does not have a 'gBrowser' member.\n" ); |
| 93 this.session.window.close(); |
| 94 this.session.close(); |
| 95 return; |
| 96 } |
| 97 this.session.window.removeEventListener( "load", this.ready_listener ); |
| 98 this.ready_listener = null; |
| 99 |
| 100 dump( "Main: running session.\n" ); |
| 101 try |
| 102 { |
| 103 this.session.run( this.done.bind( this ) ); |
| 104 } |
| 105 catch ( e ) |
| 106 { |
| 107 dump( "Main: unexpected error running session = " + e.message + "\n" ); |
| 108 this.done(); |
| 109 } |
| 110 }; |
| 111 |
| 112 Main.done = function() |
| 113 { |
| 114 if ( this.session ) |
| 115 { |
| 116 /* |
| 117 * We have responsibility for the window, since we created it. |
| 118 */ |
| 119 if ( this.session.window ) |
| 120 { |
| 121 this.session.window.close(); |
| 122 } |
| 123 this.session.close(); |
| 124 } |
| 125 }; |
| 126 |
| 127 /* |
| 128 * Initialize the Main object. It's built individually, so this is code that wou
ld otherwise be in a constructor. |
| 129 */ |
| 130 try |
| 131 { |
| 132 Main.init(); |
| 133 Main.add_observation_topic( "profile-before-change" ); |
| 134 Command_Line.set_startup_hook( Main.startup.bind( Main ) ); |
| 135 } |
| 136 catch ( e ) |
| 137 { |
| 138 dump( "main.js: Unexpected exception in Main.init(): " + e.message ); |
| 139 } |
| 140 |
| 141 //------------------------------------------------------- |
| 142 // Automatic |
| 143 //------------------------------------------------------- |
| 144 function make_session( flags ) |
| 145 { |
| 146 /* |
| 147 * Check that the flags are syntactically correct. |
| 148 */ |
| 149 if ( !( "input_file" in flags ) ) |
| 150 { |
| 151 dump( "abpcrawler: Missing flag '-input_file'.\n" ); |
| 152 return null; |
| 153 } |
| 154 if ( !( "output_dir" in flags ) ) |
| 155 { |
| 156 dump( "abpcrawler: Missing flag '-output_dir'.\n" ); |
| 157 return null; |
| 158 } |
| 159 /* |
| 160 * Provide defaults for any absent flags. |
| 161 */ |
| 162 var max_tabs = ( "max_tabs" in flags ) ? flags.max_tabs : 5; |
| 163 var base_name = ( "output_base" in flags ) ? flags.output_base : "crawl_result
s"; |
| 164 /* |
| 165 * At this point all the syntax of the arguments is valid. Now we create the a
ctual resources used. |
| 166 */ |
| 167 var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService( Ci.nsIWindo
wWatcher ); |
| 168 var window = ww.openWindow( null, "chrome://browser/content/", "abpcrawler_mai
n", null, null ); |
| 169 /* |
| 170 * 5 minute timeout |
| 171 */ |
| 172 var session = new Application_Session( window, false, max_tabs, 300000, null )
; |
| 173 try |
| 174 { |
| 175 session.set_input_file( flags.input_file ); |
| 176 session.add_output_file( flags.output_dir, base_name, true, "JSON" ); |
| 177 } |
| 178 catch ( e ) |
| 179 { |
| 180 dump( "abpcrawler: " + e.message + "\n" ); |
| 181 return null; |
| 182 } |
| 183 return session; |
| 184 } |
| 185 |
| 186 //------------------------------------------------------- |
| 187 // Setup |
| 188 //------------------------------------------------------- |
11 let knownWindowTypes = | 189 let knownWindowTypes = |
12 { | 190 { |
13 "navigator:browser": true, | 191 "navigator:browser": true, |
14 __proto__: null | 192 __proto__: null |
15 }; | 193 }; |
16 | 194 |
17 new WindowObserver({ | 195 /* |
18 applyToWindow: function(window) | 196 * We initialize the interactive version, which means hooking into the menu. |
19 { | 197 * |
20 let type = window.document.documentElement.getAttribute("windowtype"); | 198 * At this time, we're doing this regardless of whether we actual need an intera
ctive session. Later, we may initialize |
21 if (!(type in knownWindowTypes)) | 199 * differently or not at all if we're only running an automatic session. |
| 200 */ |
| 201 new WindowObserver( { |
| 202 applyToWindow: function( window ) |
| 203 { |
| 204 let type = window.document.documentElement.getAttribute( "windowtype" ); |
| 205 if ( !(type in knownWindowTypes) ) |
22 return; | 206 return; |
23 | 207 |
24 window.addEventListener("popupshowing", popupShowingHandler, false); | 208 window.addEventListener( "popupshowing", popupShowingHandler, false ); |
25 window.addEventListener("popuphidden", popupHiddenHandler, false); | 209 window.addEventListener( "popuphidden", popupHiddenHandler, false ); |
26 }, | 210 }, |
27 | 211 |
28 removeFromWindow: function(window) | 212 removeFromWindow: function( window ) |
29 { | 213 { |
30 let type = window.document.documentElement.getAttribute("windowtype"); | 214 let type = window.document.documentElement.getAttribute( "windowtype" ); |
31 if (!(type in knownWindowTypes)) | 215 if ( !(type in knownWindowTypes) ) |
32 return; | 216 return; |
33 | 217 |
34 window.removeEventListener("popupshowing", popupShowingHandler, false); | 218 window.removeEventListener( "popupshowing", popupShowingHandler, false ); |
35 window.removeEventListener("popuphidden", popupHiddenHandler, false); | 219 window.removeEventListener( "popuphidden", popupHiddenHandler, false ); |
36 } | 220 } |
37 }); | 221 } ); |
| 222 |
| 223 //------------------------------------------------------- |
| 224 // Interactive |
| 225 //------------------------------------------------------- |
38 | 226 |
39 function getMenuItem() | 227 function getMenuItem() |
40 { | 228 { |
41 // Randomize URI to work around bug 719376 | 229 // Randomize URI to work around bug 719376 |
42 let stringBundle = Services.strings.createBundle("chrome://abpcrawler/locale/g
lobal.properties?" + Math.random()); | 230 let stringBundle = Services.strings.createBundle( "chrome://abpcrawler/locale/
global.properties?" + Math.random() ); |
43 let result = [stringBundle.GetStringFromName("crawler.label")]; | 231 let result = [stringBundle.GetStringFromName( "crawler.label" )]; |
44 | 232 |
45 getMenuItem = function() result; | 233 getMenuItem = function() result; |
46 return getMenuItem(); | 234 return getMenuItem(); |
47 } | 235 } |
48 | 236 |
49 function popupShowingHandler(event) | 237 function popupShowingHandler( event ) |
50 { | 238 { |
51 let popup = event.target; | 239 let popup = event.target; |
52 if (!/^(abp-(?:toolbar|status|menuitem)-)popup$/.test(popup.id)) | 240 if ( !/^(abp-(?:toolbar|status|menuitem)-)popup$/.test( popup.id ) ) |
53 return; | 241 return; |
54 | 242 |
55 popupHiddenHandler(event); | 243 popupHiddenHandler( event ); |
56 | 244 |
57 let [label] = getMenuItem(); | 245 let [label] = getMenuItem(); |
58 let item = popup.ownerDocument.createElement("menuitem"); | 246 let item = popup.ownerDocument.createElement( "menuitem" ); |
59 item.setAttribute("label", label); | 247 item.setAttribute( "label", label ); |
60 item.setAttribute("class", "abpcrawler-item"); | 248 item.setAttribute( "class", "abpcrawler-item" ); |
61 | 249 |
62 item.addEventListener("command", popupCommandHandler, false); | 250 item.addEventListener( "command", popupCommandHandler, false ); |
63 | 251 |
64 let insertBefore = null; | 252 let insertBefore = null; |
65 for (let child = popup.firstChild; child; child = child.nextSibling) | 253 for ( let child = popup.firstChild ; child ; child = child.nextSibling ) |
66 if (/-options$/.test(child.id)) | 254 if ( /-options$/.test( child.id ) ) |
67 insertBefore = child; | 255 insertBefore = child; |
68 popup.insertBefore(item, insertBefore); | 256 popup.insertBefore( item, insertBefore ); |
69 } | 257 } |
70 | 258 |
71 function popupHiddenHandler(event) | 259 function popupHiddenHandler( event ) |
72 { | 260 { |
73 let popup = event.target; | 261 let popup = event.target; |
74 if (!/^(abp-(?:toolbar|status|menuitem)-)popup$/.test(popup.id)) | 262 if ( !/^(abp-(?:toolbar|status|menuitem)-)popup$/.test( popup.id ) ) |
75 return; | 263 return; |
76 | 264 |
77 let items = popup.getElementsByClassName("abpcrawler-item"); | 265 let items = popup.getElementsByClassName( "abpcrawler-item" ); |
78 while (items.length) | 266 while ( items.length ) |
79 items[0].parentNode.removeChild(items[0]); | 267 items[0].parentNode.removeChild( items[0] ); |
80 } | 268 } |
81 | 269 |
82 function popupCommandHandler(event) | 270 function popupCommandHandler( event ) |
83 { | 271 { |
84 if (!("@adblockplus.org/abp/public;1" in Cc)) | 272 if ( !("@adblockplus.org/abp/public;1" in Cc) ) |
85 return; | 273 return; |
86 | 274 |
87 let crawlerWnd = Services.wm.getMostRecentWindow("abpcrawler:crawl"); | 275 let crawlerWnd = Services.wm.getMostRecentWindow( "abpcrawler:crawl" ); |
88 if (crawlerWnd) | 276 if ( crawlerWnd ) |
89 crawlerWnd.focus(); | 277 crawlerWnd.focus(); |
90 else | 278 else |
91 event.target.ownerDocument.defaultView.openDialog("chrome://abpcrawler/conte
nt/crawler.xul", "_blank", "chrome,centerscreen,resizable,dialog=no"); | 279 event.target.ownerDocument.defaultView.openDialog( "chrome://abpcrawler/cont
ent/crawler.xul", "_blank", "chrome,centerscreen,resizable,dialog=no" ); |
92 } | 280 } |
OLD | NEW |