nsBrowserContentHandler.js
Go to the documentation of this file.
1 # ***** BEGIN LICENSE BLOCK *****
2 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 #
4 # The contents of this file are subject to the Mozilla Public License Version
5 # 1.1 (the "License"); you may not use this file except in compliance with
6 # the License. You may obtain a copy of the License at
7 # http://www.mozilla.org/MPL/
8 #
9 # Software distributed under the License is distributed on an "AS IS" basis,
10 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 # for the specific language governing rights and limitations under the
12 # License.
13 #
14 # The Original Code is the Mozilla Firefox browser.
15 #
16 # The Initial Developer of the Original Code is
17 # Benjamin Smedberg <benjamin@smedbergs.us>
18 #
19 # Portions created by the Initial Developer are Copyright (C) 2004
20 # the Initial Developer. All Rights Reserved.
21 #
22 # Contributor(s):
23 #
24 # Alternatively, the contents of this file may be used under the terms of
25 # either the GNU General Public License Version 2 or later (the "GPL"), or
26 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 # in which case the provisions of the GPL or the LGPL are applicable instead
28 # of those above. If you wish to allow use of your version of this file only
29 # under the terms of either the GPL or the LGPL, and not to allow others to
30 # use your version of this file under the terms of the MPL, indicate your
31 # decision by deleting the provisions above and replace them with the notice
32 # and other provisions required by the GPL or the LGPL. If you do not delete
33 # the provisions above, a recipient may use your version of this file under
34 # the terms of any one of the MPL, the GPL or the LGPL.
35 #
36 # ***** END LICENSE BLOCK *****
37 
38 const nsISupports = Components.interfaces.nsISupports;
39 
40 const nsIBrowserDOMWindow = Components.interfaces.nsIBrowserDOMWindow;
41 const nsIBrowserHandler = Components.interfaces.nsIBrowserHandler;
42 const nsIBrowserHistory = Components.interfaces.nsIBrowserHistory;
43 const nsIChannel = Components.interfaces.nsIChannel;
44 const nsICommandLine = Components.interfaces.nsICommandLine;
45 const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
46 const nsIContentHandler = Components.interfaces.nsIContentHandler;
47 const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
48 const nsIDOMChromeWindow = Components.interfaces.nsIDOMChromeWindow;
49 const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
50 const nsIFactory = Components.interfaces.nsIFactory;
51 const nsIFileURL = Components.interfaces.nsIFileURL;
52 const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
53 const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
54 const nsINetUtil = Components.interfaces.nsINetUtil;
55 const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
56 const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
57 const nsISupportsString = Components.interfaces.nsISupportsString;
58 const nsIURIFixup = Components.interfaces.nsIURIFixup;
59 const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
60 const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
61 const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
62 const nsICategoryManager = Components.interfaces.nsICategoryManager;
63 const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo;
64 const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
65 const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
66 
67 const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
68 const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
69 const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
70 
72  .URI_INHERITS_SECURITY_CONTEXT;
73 
74 function shouldLoadURI(aURI) {
75  if (aURI && !aURI.schemeIs("chrome"))
76  return true;
77 
78  dump("*** Preventing external load of chrome: URI into browser window\n");
79  dump(" Use -chrome <uri> instead\n");
80  return false;
81 }
82 
83 function resolveURIInternal(aCmdLine, aArgument) {
84  var uri = aCmdLine.resolveURI(aArgument);
85 
86  if (!(uri instanceof nsIFileURL)) {
87  return uri;
88  }
89 
90  try {
91  if (uri.file.exists())
92  return uri;
93  }
94  catch (e) {
95  Components.utils.reportError(e);
96  }
97 
98  // We have interpreted the argument as a relative file URI, but the file
99  // doesn't exist. Try URI fixup heuristics: see bug 290782.
100 
101  try {
102  var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
103  .getService(nsIURIFixup);
104 
105  uri = urifixup.createFixupURI(aArgument, 0);
106  }
107  catch (e) {
108  Components.utils.reportError(e);
109  }
110 
111  return uri;
112 }
113 
114 const OVERRIDE_NONE = 0;
125 function needHomepageOverride(prefb) {
126  var savedmstone = null;
127  try {
128  savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
129  } catch (e) {}
130 
131  if (savedmstone == "ignore")
132  return OVERRIDE_NONE;
133 
134  var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
135  .getService(nsIHttpProtocolHandler).misc;
136 
137  if (mstone != savedmstone) {
138  // Bug 462254. Previous releases had a default pref to suppress the EULA
139  // agreement if the platform's installer had already shown one. Now with
140  // about:rights we've removed the EULA stuff and default pref, but we need
141  // a way to make existing profiles retain the default that we removed.
142  if (savedmstone)
143  prefb.setBoolPref("browser.rights.3.shown", true);
144 
145  prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
146  return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
147  }
148 
149  return OVERRIDE_NONE;
150 }
151 
152 // Copies a pref override file into the user's profile pref-override folder,
153 // and then tells the pref service to reload its default prefs.
154 function copyPrefOverride() {
155  try {
156  var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
157  .getService(Components.interfaces.nsIProperties);
158  const NS_APP_EXISTING_PREF_OVERRIDE = "ExistingPrefOverride";
159  var prefOverride = fileLocator.get(NS_APP_EXISTING_PREF_OVERRIDE,
160  Components.interfaces.nsIFile);
161  if (!prefOverride.exists())
162  return; // nothing to do
163 
164  const NS_APP_PREFS_OVERRIDE_DIR = "PrefDOverride";
165  var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
166  Components.interfaces.nsIFile);
167 
168  // Check for any existing pref overrides, and remove them if present
169  var existingPrefOverridesFile = prefOverridesDir.clone();
170  existingPrefOverridesFile.append(prefOverride.leafName);
171  if (existingPrefOverridesFile.exists())
172  existingPrefOverridesFile.remove(false);
173 
174  prefOverride.copyTo(prefOverridesDir, null);
175 
176  // Now that we've installed the new-profile pref override file,
177  // re-read the default prefs.
178  var prefSvcObs = Components.classes["@mozilla.org/preferences-service;1"]
179  .getService(Components.interfaces.nsIObserver);
180  prefSvcObs.observe(null, "reload-default-prefs", null);
181  } catch (ex) {
182  Components.utils.reportError(ex);
183  }
184 }
185 
186 // Flag used to indicate that the arguments to openWindow can be passed directly.
188 
189 function openWindow(parent, url, target, features, args, noExternalArgs) {
190  var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
191  .getService(nsIWindowWatcher);
192 
193  if (noExternalArgs == NO_EXTERNAL_URIS) {
194  // Just pass in the defaultArgs directly
195  var argstring;
196  if (args) {
197  argstring = Components.classes["@mozilla.org/supports-string;1"]
198  .createInstance(nsISupportsString);
199  argstring.data = args;
200  }
201 
202  return wwatch.openWindow(parent, url, target, features, argstring);
203  }
204 
205  // Pass an array to avoid the browser "|"-splitting behavior.
206  var argArray = Components.classes["@mozilla.org/supports-array;1"]
207  .createInstance(Components.interfaces.nsISupportsArray);
208 
209  // add args to the arguments array
210  var stringArgs = null;
211  if (args instanceof Array) // array
212  stringArgs = args;
213  else if (args) // string
214  stringArgs = [args];
215 
216  if (stringArgs) {
217  // put the URIs into argArray
218  var uriArray = Components.classes["@mozilla.org/supports-array;1"]
219  .createInstance(Components.interfaces.nsISupportsArray);
220  stringArgs.forEach(function (uri) {
221  var sstring = Components.classes["@mozilla.org/supports-string;1"]
222  .createInstance(nsISupportsString);
223  sstring.data = uri;
224  uriArray.AppendElement(sstring);
225  });
226  argArray.AppendElement(uriArray);
227  } else {
228  argArray.AppendElement(null);
229  }
230 
231  // Pass these as null to ensure that we always trigger the "single URL"
232  // behavior in browser.js's BrowserStartup (which handles the window
233  // arguments)
234  argArray.AppendElement(null); // charset
235  argArray.AppendElement(null); // referer
236  argArray.AppendElement(null); // postData
237  argArray.AppendElement(null); // allowThirdPartyFixup
238 
239  return wwatch.openWindow(parent, url, target, features, argArray);
240 }
241 
242 function openPreferences() {
243  var features = "chrome,titlebar,toolbar,centerscreen,dialog=no";
244  var url = "chrome://browser/content/preferences/preferences.xul";
245 
246  var win = getMostRecentWindow("Browser:Preferences");
247  if (win) {
248  win.focus();
249  } else {
250  openWindow(null, url, "_blank", features);
251  }
252 }
253 
254 function getMostRecentWindow(aType) {
255  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
256  .getService(nsIWindowMediator);
257  return wm.getMostRecentWindow(aType);
258 }
259 
260 // this returns the most recent non-popup browser window
262  var browserGlue = Components.classes["@mozilla.org/browser/browserglue;1"]
263  .getService(Components.interfaces.nsIBrowserGlue);
264  return browserGlue.getMostRecentBrowserWindow();
265 }
266 
267 function doSearch(searchTerm, cmdLine) {
268  var ss = Components.classes["@mozilla.org/browser/search-service;1"]
269  .getService(nsIBrowserSearchService);
270 
271  var submission = ss.defaultEngine.getSubmission(searchTerm, null);
272 
273  // fill our nsISupportsArray with uri-as-wstring, null, null, postData
274  var sa = Components.classes["@mozilla.org/supports-array;1"]
275  .createInstance(Components.interfaces.nsISupportsArray);
276 
277  var wuri = Components.classes["@mozilla.org/supports-string;1"]
278  .createInstance(Components.interfaces.nsISupportsString);
279  wuri.data = submission.uri.spec;
280 
281  sa.AppendElement(wuri);
282  sa.AppendElement(null);
283  sa.AppendElement(null);
284  sa.AppendElement(submission.postData);
285 
286  // XXXbsmedberg: use handURIToExistingBrowser to obey tabbed-browsing
287  // preferences, but need nsIBrowserDOMWindow extensions
288 
289  var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
290  .getService(nsIWindowWatcher);
291 
292  return wwatch.openWindow(null, nsBrowserContentHandler.chromeURL,
293  "_blank",
294  "chrome,dialog=no,all" +
295  nsBrowserContentHandler.getFeatures(cmdLine),
296  sa);
297 }
298 
300  /* helper functions */
301 
302  mChromeURL : null,
303 
304  get chromeURL() {
305  if (this.mChromeURL) {
306  return this.mChromeURL;
307  }
308 
309  var prefb = Components.classes["@mozilla.org/preferences-service;1"]
310  .getService(nsIPrefBranch);
311  this.mChromeURL = prefb.getCharPref("browser.chromeURL");
312 
313  return this.mChromeURL;
314  },
315 
316  /* nsISupports */
317  QueryInterface : function bch_QI(iid) {
318  if (!iid.equals(nsISupports) &&
319  !iid.equals(nsICommandLineHandler) &&
320  !iid.equals(nsIBrowserHandler) &&
321  !iid.equals(nsIContentHandler) &&
322  !iid.equals(nsICommandLineValidator) &&
323  !iid.equals(nsIFactory))
324  throw Components.results.NS_ERROR_NO_INTERFACE;
325 
326  return this;
327  },
328 
329  /* nsICommandLineHandler */
330  handle : function bch_handle(cmdLine) {
331  if (cmdLine.handleFlag("browser", false)) {
332  // Passing defaultArgs, so use NO_EXTERNAL_URIS
333  openWindow(null, this.chromeURL, "_blank",
334  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
335  this.defaultArgs, NO_EXTERNAL_URIS);
336  cmdLine.preventDefault = true;
337  }
338 
339  try {
340  var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
341  }
342  catch (e) {
343  throw NS_ERROR_ABORT;
344  }
345 
346  if (remoteCommand != null) {
347  try {
348  var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
349  var remoteVerb;
350  if (a) {
351  remoteVerb = a[1].toLowerCase();
352  var remoteParams = [];
353  var sepIndex = a[2].lastIndexOf(",");
354  if (sepIndex == -1)
355  remoteParams[0] = a[2];
356  else {
357  remoteParams[0] = a[2].substring(0, sepIndex);
358  remoteParams[1] = a[2].substring(sepIndex + 1);
359  }
360  }
361 
362  switch (remoteVerb) {
363  case "openurl":
364  case "openfile":
365  // openURL(<url>)
366  // openURL(<url>,new-window)
367  // openURL(<url>,new-tab)
368 
369  // First param is the URL, second param (if present) is the "target"
370  // (tab, window)
371  var url = remoteParams[0];
372  var target = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
373  if (remoteParams[1]) {
374  var targetParam = remoteParams[1].toLowerCase()
375  .replace(/^\s*|\s*$/g, "");
376  if (targetParam == "new-tab")
377  target = nsIBrowserDOMWindow.OPEN_NEWTAB;
378  else if (targetParam == "new-window")
379  target = nsIBrowserDOMWindow.OPEN_NEWWINDOW;
380  else {
381  // The "target" param isn't one of our supported values, so
382  // assume it's part of a URL that contains commas.
383  url += "," + remoteParams[1];
384  }
385  }
386 
387  var uri = resolveURIInternal(cmdLine, url);
388  handURIToExistingBrowser(uri, target, cmdLine);
389  break;
390 
391  case "xfedocommand":
392  // xfeDoCommand(openBrowser)
393  if (remoteParams[0].toLowerCase() != "openbrowser")
394  throw NS_ERROR_ABORT;
395 
396  // Passing defaultArgs, so use NO_EXTERNAL_URIS
397  openWindow(null, this.chromeURL, "_blank",
398  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
399  this.defaultArgs, NO_EXTERNAL_URIS);
400  break;
401 
402  default:
403  // Somebody sent us a remote command we don't know how to process:
404  // just abort.
405  throw "Unknown remote command.";
406  }
407 
408  cmdLine.preventDefault = true;
409  }
410  catch (e) {
411  Components.utils.reportError(e);
412  // If we had a -remote flag but failed to process it, throw
413  // NS_ERROR_ABORT so that the xremote code knows to return a failure
414  // back to the handling code.
415  throw NS_ERROR_ABORT;
416  }
417  }
418 
419  var uriparam;
420  try {
421  while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) {
422  var uri = resolveURIInternal(cmdLine, uriparam);
423  if (!shouldLoadURI(uri))
424  continue;
425  openWindow(null, this.chromeURL, "_blank",
426  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
427  uri.spec);
428  cmdLine.preventDefault = true;
429  }
430  }
431  catch (e) {
432  Components.utils.reportError(e);
433  }
434 
435  try {
436  while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) {
437  var uri = resolveURIInternal(cmdLine, uriparam);
438  handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine);
439  cmdLine.preventDefault = true;
440  }
441  }
442  catch (e) {
443  Components.utils.reportError(e);
444  }
445 
446  var chromeParam = cmdLine.handleFlagWithParam("chrome", false);
447  if (chromeParam) {
448 
449  // Handle the old preference dialog URL separately (bug 285416)
450  if (chromeParam == "chrome://browser/content/pref/pref.xul") {
451  openPreferences();
452  cmdLine.preventDefault = true;
453  } else try {
454  // only load URIs which do not inherit chrome privs
455  var features = "chrome,dialog=no,all" + this.getFeatures(cmdLine);
456  var uri = resolveURIInternal(cmdLine, chromeParam);
457  var netutil = Components.classes["@mozilla.org/network/util;1"]
458  .getService(nsINetUtil);
459  if (!netutil.URIChainHasFlags(uri, URI_INHERITS_SECURITY_CONTEXT)) {
460  openWindow(null, uri.spec, "_blank", features);
461  cmdLine.preventDefault = true;
462  }
463  }
464  catch (e) {
465  Components.utils.reportError(e);
466  }
467  }
468  if (cmdLine.handleFlag("preferences", false)) {
469  openPreferences();
470  cmdLine.preventDefault = true;
471  }
472  if (cmdLine.handleFlag("silent", false))
473  cmdLine.preventDefault = true;
474 
475  var searchParam = cmdLine.handleFlagWithParam("search", false);
476  if (searchParam) {
477  doSearch(searchParam, cmdLine);
478  cmdLine.preventDefault = true;
479  }
480 
481  var fileParam = cmdLine.handleFlagWithParam("file", false);
482  if (fileParam) {
483  var file = cmdLine.resolveFile(fileParam);
484  var ios = Components.classes["@mozilla.org/network/io-service;1"]
485  .getService(Components.interfaces.nsIIOService);
486  var uri = ios.newFileURI(file);
487  openWindow(null, this.chromeURL, "_blank",
488  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
489  uri.spec);
490  cmdLine.preventDefault = true;
491  }
492 
493 #ifdef XP_WIN
494  // Handle "? searchterm" for Windows Vista start menu integration
495  for (var i = cmdLine.length - 1; i >= 0; --i) {
496  var param = cmdLine.getArgument(i);
497  if (param.match(/^\? /)) {
498  cmdLine.removeArguments(i, i);
499  cmdLine.preventDefault = true;
500 
501  searchParam = param.substr(2);
502  doSearch(searchParam, cmdLine);
503  }
504  }
505 #endif
506  },
507 
508  helpInfo : " -browser Open a browser window.\n",
509 
510  /* nsIBrowserHandler */
511 
512  get defaultArgs() {
513  var prefb = Components.classes["@mozilla.org/preferences-service;1"]
514  .getService(nsIPrefBranch);
515  var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
516  .getService(Components.interfaces.nsIURLFormatter);
517 
518  var overridePage = "";
519  var haveUpdateSession = false;
520  try {
521  switch (needHomepageOverride(prefb)) {
523  // New profile
524  overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
525  break;
526  case OVERRIDE_NEW_MSTONE:
527  // Existing profile, new build
529 
530  // Check whether we have a session to restore. If we do, we assume
531  // that this is an "update" session.
532  var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
533  .getService(Components.interfaces.nsISessionStartup);
534  haveUpdateSession = ss.doRestore();
535  overridePage = formatter.formatURLPref("startup.homepage_override_url");
536  break;
537  }
538  } catch (ex) {}
539 
540  // formatURLPref might return "about:blank" if getting the pref fails
541  if (overridePage == "about:blank")
542  overridePage = "";
543 
544  var startPage = "";
545  try {
546  var choice = prefb.getIntPref("browser.startup.page");
547  if (choice == 1 || choice == 3)
548  startPage = this.startPage;
549 
550  if (choice == 2)
551  startPage = Components.classes["@mozilla.org/browser/global-history;2"]
552  .getService(nsIBrowserHistory).lastPageVisited;
553  } catch (e) {
554  Components.utils.reportError(e);
555  }
556 
557  if (startPage == "about:blank")
558  startPage = "";
559 
560  // Only show the startPage if we're not restoring an update session.
561  if (overridePage && startPage && !haveUpdateSession)
562  return overridePage + "|" + startPage;
563 
564  return overridePage || startPage || "about:blank";
565  },
566 
567  get startPage() {
568  var prefb = Components.classes["@mozilla.org/preferences-service;1"]
569  .getService(nsIPrefBranch);
570 
571  var uri = prefb.getComplexValue("browser.startup.homepage",
573 
574  if (!uri) {
575  prefb.clearUserPref("browser.startup.homepage");
576  uri = prefb.getComplexValue("browser.startup.homepage",
578  }
579 
580  var count;
581  try {
582  count = prefb.getIntPref("browser.startup.homepage.count");
583  }
584  catch (e) {
585  return uri;
586  }
587 
588  for (var i = 1; i < count; ++i) {
589  try {
590  var page = prefb.getComplexValue("browser.startup.homepage." + i,
592  uri += "\n" + page;
593  }
594  catch (e) {
595  }
596  }
597 
598  return uri;
599  },
600 
601  mFeatures : null,
602 
603  getFeatures : function bch_features(cmdLine) {
604  if (this.mFeatures === null) {
605  this.mFeatures = "";
606 
607  try {
608  var width = cmdLine.handleFlagWithParam("width", false);
609  var height = cmdLine.handleFlagWithParam("height", false);
610 
611  if (width)
612  this.mFeatures += ",width=" + width;
613  if (height)
614  this.mFeatures += ",height=" + height;
615  }
616  catch (e) {
617  }
618  }
619 
620  return this.mFeatures;
621  },
622 
623  /* nsIContentHandler */
624 
625  handleContent : function bch_handleContent(contentType, context, request) {
626  try {
627  var webNavInfo = Components.classes["@mozilla.org/webnavigation-info;1"]
628  .getService(nsIWebNavigationInfo);
629  if (!webNavInfo.isTypeSupported(contentType, null)) {
631  }
632  } catch (e) {
634  }
635 
636  request.QueryInterface(nsIChannel);
637  handURIToExistingBrowser(request.URI,
638  nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null);
639  request.cancel(NS_BINDING_ABORTED);
640  },
641 
642  /* nsICommandLineValidator */
643  validate : function bch_validate(cmdLine) {
644  // Other handlers may use osint so only handle the osint flag if the url
645  // flag is also present and the command line is valid.
646  var osintFlagIdx = cmdLine.findFlag("osint", false);
647  var urlFlagIdx = cmdLine.findFlag("url", false);
648  if (urlFlagIdx > -1 && (osintFlagIdx > -1 ||
649  cmdLine.state == nsICommandLine.STATE_REMOTE_EXPLICIT)) {
650  var urlParam = cmdLine.getArgument(urlFlagIdx + 1);
651  if (cmdLine.length != urlFlagIdx + 2 || /firefoxurl:/.test(urlParam))
652  throw NS_ERROR_ABORT;
653  cmdLine.handleFlag("osint", false)
654  }
655  },
656 
657  /* nsIFactory */
658  createInstance: function bch_CI(outer, iid) {
659  if (outer != null)
660  throw Components.results.NS_ERROR_NO_AGGREGATION;
661 
662  return this.QueryInterface(iid);
663  },
664 
665  lockFactory : function bch_lock(lock) {
666  /* no-op */
667  }
668 };
669 
670 const bch_contractID = "@mozilla.org/browser/clh;1";
671 const bch_CID = Components.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}");
672 const CONTRACTID_PREFIX = "@mozilla.org/uriloader/content-handler;1?type=";
673 
674 function handURIToExistingBrowser(uri, location, cmdLine)
675 {
676  if (!shouldLoadURI(uri))
677  return;
678 
679  var navWin = getMostRecentBrowserWindow();
680  if (!navWin) {
681  // if we couldn't load it in an existing window, open a new one
682  openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
683  "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
684  uri.spec);
685  return;
686  }
687 
688  var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
689  .getInterface(nsIWebNavigation);
690  var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
691  var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
692  .getInterface(nsIDOMWindow);
693  var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
694  bwin.openURI(uri, null, location,
695  nsIBrowserDOMWindow.OPEN_EXTERNAL);
696 }
697 
698 
700  /* nsISupports */
701  QueryInterface : function dch_QI(iid) {
702  if (!iid.equals(nsISupports) &&
703  !iid.equals(nsICommandLineHandler) &&
704  !iid.equals(nsIFactory))
705  throw Components.results.NS_ERROR_NO_INTERFACE;
706 
707  return this;
708  },
709 
710  // List of uri's that were passed via the command line without the app
711  // running and have already been handled. This is compared against uri's
712  // opened using DDE on Win32 so we only open one of the requests.
713  _handledURIs: [ ],
714 #ifdef XP_WIN
715  _haveProfile: false,
716 #endif
717 
718  /* nsICommandLineHandler */
719  handle : function dch_handle(cmdLine) {
720  var urilist = [];
721 
722 #ifdef XP_WIN
723  // If we don't have a profile selected yet (e.g. the Profile Manager is
724  // displayed) we will crash if we open an url and then select a profile. To
725  // prevent this handle all url command line flags and set the command line's
726  // preventDefault to true to prevent the display of the ui. The initial
727  // command line will be retained when nsAppRunner calls LaunchChild though
728  // urls launched after the initial launch will be lost.
729  if (!this._haveProfile) {
730  try {
731  // This will throw when a profile has not been selected.
732  var fl = Components.classes["@mozilla.org/file/directory_service;1"]
733  .getService(Components.interfaces.nsIProperties);
734  var dir = fl.get("ProfD", Components.interfaces.nsILocalFile);
735  this._haveProfile = true;
736  }
737  catch (e) {
738  while ((ar = cmdLine.handleFlagWithParam("url", false))) { }
739  cmdLine.preventDefault = true;
740  }
741  }
742 #endif
743 
744  try {
745  var ar;
746  while ((ar = cmdLine.handleFlagWithParam("url", false))) {
747  var found = false;
748  var uri = resolveURIInternal(cmdLine, ar);
749  // count will never be greater than zero except on Win32.
750  var count = this._handledURIs.length;
751  for (var i = 0; i < count; ++i) {
752  if (this._handledURIs[i].spec == uri.spec) {
753  this._handledURIs.splice(i, 1);
754  found = true;
755  cmdLine.preventDefault = true;
756  break;
757  }
758  }
759  if (!found) {
760  urilist.push(uri);
761  // The requestpending command line flag is only used on Win32.
762  if (cmdLine.handleFlag("requestpending", false) &&
763  cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
764  this._handledURIs.push(uri)
765  }
766  }
767  }
768  catch (e) {
769  Components.utils.reportError(e);
770  }
771 
772  count = cmdLine.length;
773 
774  for (i = 0; i < count; ++i) {
775  var curarg = cmdLine.getArgument(i);
776  if (curarg.match(/^-/)) {
777  Components.utils.reportError("Warning: unrecognized command line flag " + curarg + "\n");
778  // To emulate the pre-nsICommandLine behavior, we ignore
779  // the argument after an unrecognized flag.
780  ++i;
781  } else {
782  try {
783  urilist.push(resolveURIInternal(cmdLine, curarg));
784  }
785  catch (e) {
786  Components.utils.reportError("Error opening URI '" + curarg + "' from the command line: " + e + "\n");
787  }
788  }
789  }
790 
791  if (urilist.length) {
792  if (cmdLine.state != nsICommandLine.STATE_INITIAL_LAUNCH &&
793  urilist.length == 1) {
794  // Try to find an existing window and load our URI into the
795  // current tab, new tab, or new window as prefs determine.
796  try {
797  handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine);
798  return;
799  }
800  catch (e) {
801  }
802  }
803 
804  var URLlist = urilist.filter(shouldLoadURI).map(function (u) u.spec);
805  if (URLlist.length) {
806  openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
807  "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
808  URLlist);
809  }
810 
811  }
812  else if (!cmdLine.preventDefault) {
813  // Passing defaultArgs, so use NO_EXTERNAL_URIS
814  openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
815  "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
817  }
818  },
819 
820  // XXX localize me... how?
821  helpInfo : "Usage: firefox [-flags] [<url>]\n",
822 
823  /* nsIFactory */
824  createInstance: function dch_CI(outer, iid) {
825  if (outer != null)
826  throw Components.results.NS_ERROR_NO_AGGREGATION;
827 
828  return this.QueryInterface(iid);
829  },
830 
831  lockFactory : function dch_lock(lock) {
832  /* no-op */
833  }
834 };
835 
836 const dch_contractID = "@mozilla.org/browser/final-clh;1";
837 const dch_CID = Components.ID("{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}");
838 
839 var Module = {
840  /* nsISupports */
841  QueryInterface: function mod_QI(iid) {
842  if (iid.equals(Components.interfaces.nsIModule) ||
843  iid.equals(Components.interfaces.nsISupports))
844  return this;
845 
846  throw Components.results.NS_ERROR_NO_INTERFACE;
847  },
848 
849  /* nsIModule */
850  getClassObject: function mod_getco(compMgr, cid, iid) {
851  if (cid.equals(bch_CID))
852  return nsBrowserContentHandler.QueryInterface(iid);
853 
854  if (cid.equals(dch_CID))
855  return nsDefaultCommandLineHandler.QueryInterface(iid);
856 
857  throw Components.results.NS_ERROR_NO_INTERFACE;
858  },
859 
860  registerSelf: function mod_regself(compMgr, fileSpec, location, type) {
861  if (Components.classes["@mozilla.org/xre/app-info;1"]) {
862  // Don't register these if Firefox is launching a XULRunner application
863  const FIREFOX_UID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
864  var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
865  .getService(Components.interfaces.nsIXULAppInfo);
866  if (appInfo.ID != FIREFOX_UID)
867  return;
868  }
869 
870  var compReg =
871  compMgr.QueryInterface( Components.interfaces.nsIComponentRegistrar );
872 
873  compReg.registerFactoryLocation( bch_CID,
874  "nsBrowserContentHandler",
876  fileSpec,
877  location,
878  type );
879  compReg.registerFactoryLocation( dch_CID,
880  "nsDefaultCommandLineHandler",
882  fileSpec,
883  location,
884  type );
885 
886  function registerType(contentType) {
887  compReg.registerFactoryLocation( bch_CID,
888  "Browser Cmdline Handler",
889  CONTRACTID_PREFIX + contentType,
890  fileSpec,
891  location,
892  type );
893  }
894 
895  registerType("text/html");
896  registerType("application/vnd.mozilla.xul+xml");
897 #ifdef MOZ_SVG
898  registerType("image/svg+xml");
899 #endif
900  registerType("text/rdf");
901  registerType("text/xml");
902  registerType("application/xhtml+xml");
903  registerType("text/css");
904  registerType("text/plain");
905  registerType("image/gif");
906  registerType("image/jpeg");
907  registerType("image/jpg");
908  registerType("image/png");
909  registerType("image/bmp");
910  registerType("image/x-icon");
911  registerType("image/vnd.microsoft.icon");
912  registerType("application/http-index-format");
913 
914  var catMan = Components.classes["@mozilla.org/categorymanager;1"]
915  .getService(nsICategoryManager);
916 
917  catMan.addCategoryEntry("command-line-handler",
918  "m-browser",
919  bch_contractID, true, true);
920  catMan.addCategoryEntry("command-line-handler",
921  "x-default",
922  dch_contractID, true, true);
923  catMan.addCategoryEntry("command-line-validator",
924  "b-browser",
925  bch_contractID, true, true);
926  },
927 
928  unregisterSelf : function mod_unregself(compMgr, location, type) {
929  var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
930  compReg.unregisterFactoryLocation(bch_CID, location);
931  compReg.unregisterFactoryLocation(dch_CID, location);
932 
933  var catMan = Components.classes["@mozilla.org/categorymanager;1"]
934  .getService(nsICategoryManager);
935 
936  catMan.deleteCategoryEntry("command-line-handler",
937  "m-browser", true);
938  catMan.deleteCategoryEntry("command-line-handler",
939  "x-default", true);
940  catMan.deleteCategoryEntry("command-line-validator",
941  "b-browser", true);
942  },
943 
944  canUnload: function(compMgr) {
945  return true;
946  }
947 };
948 
949 // NSGetModule: Return the nsIModule object.
950 function NSGetModule(compMgr, fileSpec) {
951  return Module;
952 }
var nsDefaultCommandLineHandler
const nsICommandLineValidator
var args
Definition: alert.js:8
#define NS_APP_EXISTING_PREF_OVERRIDE
var nsBrowserContentHandler
const NS_BINDING_ABORTED
const nsIBrowserDOMWindow
const dch_CID
const nsICommandLineHandler
const nsIDocShellTreeItem
SafebrowsingApplicationMod prototype registerSelf
const nsIPrefLocalizedString
const nsIWebNavigation
function openPreferences()
const NO_EXTERNAL_URIS
const NS_ERROR_ABORT
const nsIPrefBranch
sidebarFactory createInstance
Definition: nsSidebar.js:351
sbOSDControlService prototype QueryInterface
const OVERRIDE_NONE
const nsIFactory
const nsIWindowMediator
const bch_contractID
function handle(request, response)
const nsIHttpProtocolHandler
function handURIToExistingBrowser(uri, location, cmdLine)
function width(ele) rect(ele).width
const nsIBrowserHistory
const nsISupportsString
function NSGetModule(compMgr, fileSpec)
const NS_ERROR_WONT_HANDLE_CONTENT
const nsIDOMChromeWindow
const nsICategoryManager
const URI_INHERITS_SECURITY_CONTEXT
const nsIDOMWindow
SafebrowsingApplicationMod prototype getClassObject
const nsIContentHandler
function needHomepageOverride(prefb)
var count
Definition: test_bug7406.js:32
const nsIChannel
function openWindow(parent, url, target, features, args, noExternalArgs)
return null
Definition: FeedWriter.js:1143
_updateDatepicker height
const nsIWebNavigationInfo
function url(spec)
var uri
Definition: FeedWriter.js:1135
const nsIFileURL
const OVERRIDE_NEW_MSTONE
function resolveURIInternal(aCmdLine, aArgument)
function doSearch(searchTerm, cmdLine)
var ios
Definition: head_feeds.js:5
const nsIBrowserSearchService
const nsIURIFixup
const bch_CID
const nsIInterfaceRequestor
const nsINetUtil
const dch_contractID
function getMostRecentWindow(aType)
const CONTRACTID_PREFIX
_getSelectedPageStyle s i
function getMostRecentBrowserWindow()
function copyPrefOverride()
const nsICommandLine
function validate(aNode)
const OVERRIDE_NEW_PROFILE
const nsIWindowWatcher
var file
function shouldLoadURI(aURI)
const nsISupports