1 # ***** BEGIN LICENSE BLOCK *****
2 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
14 # The Original Code is the Mozilla Firefox browser.
16 # The Initial Developer of the Original Code is
17 # Benjamin Smedberg <benjamin@smedbergs.us>
19 # Portions created by the Initial Developer are Copyright (C) 2004
20 # the Initial Developer. All Rights Reserved.
23 # Robert Strong <robert.bugzilla@gmail.com>
25 # Alternatively, the contents of this file may be used under the terms of
26 # either the GNU General Public License Version 2 or later (the "GPL"), or
27 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 # in which case the provisions of the GPL or the LGPL are applicable instead
29 # of those above. If you wish to allow use of your version of this file only
30 # under the terms of either the GPL or the LGPL, and not to allow others to
31 # use your version of this file under the terms of the MPL, indicate your
32 # decision by deleting the provisions above and replace them with the notice
33 # and other provisions required by the GPL or the LGPL. If you do not delete
34 # the provisions above, a recipient may use your version of this file under
35 # the terms of any one of the MPL, the GPL or the LGPL.
37 # ***** END LICENSE BLOCK *****
39 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
40 Components.utils.import("resource://gre/modules/Services.jsm");
42 const nsISupports = Components.interfaces.nsISupports;
44 const nsIBrowserDOMWindow = Components.interfaces.nsIBrowserDOMWindow;
45 const nsIBrowserHandler = Components.interfaces.nsIBrowserHandler;
46 const nsIBrowserHistory = Components.interfaces.nsIBrowserHistory;
47 const nsIChannel = Components.interfaces.nsIChannel;
48 const nsICommandLine = Components.interfaces.nsICommandLine;
49 const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
50 const nsIContentHandler = Components.interfaces.nsIContentHandler;
51 const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
52 const nsIDOMChromeWindow = Components.interfaces.nsIDOMChromeWindow;
53 const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
54 const nsIFileURL = Components.interfaces.nsIFileURL;
55 const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
56 const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
57 const nsINetUtil = Components.interfaces.nsINetUtil;
58 const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
59 const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
60 const nsISupportsString = Components.interfaces.nsISupportsString;
61 const nsIURIFixup = Components.interfaces.nsIURIFixup;
62 const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
63 const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
64 const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
65 const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo;
66 const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
67 const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
68 const nsIXULAppInfo = Components.interfaces.nsIXULAppInfo;
70 const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
71 const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
72 const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
74 const URI_INHERITS_SECURITY_CONTEXT = nsIHttpProtocolHandler
75 .URI_INHERITS_SECURITY_CONTEXT;
77 function shouldLoadURI(aURI) {
78 if (aURI && !aURI.schemeIs("chrome"))
81 dump("*** Preventing external load of chrome: URI into browser window\n");
82 dump(" Use -chrome <uri> instead\n");
86 function resolveURIInternal(aCmdLine, aArgument) {
87 var uri = aCmdLine.resolveURI(aArgument);
89 if (!(uri instanceof nsIFileURL)) {
94 if (uri.file.exists())
98 Components.utils.reportError(e);
101 // We have interpreted the argument as a relative file URI, but the file
102 // doesn't exist. Try URI fixup heuristics: see bug 290782.
105 var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
106 .getService(nsIURIFixup);
108 uri = urifixup.createFixupURI(aArgument, 0);
111 Components.utils.reportError(e);
117 const OVERRIDE_NONE = 0;
118 const OVERRIDE_NEW_PROFILE = 1;
119 const OVERRIDE_NEW_MSTONE = 2;
120 const OVERRIDE_NEW_BUILD_ID = 3;
122 * Determines whether a home page override is needed.
124 * OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
125 * OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
126 * Gecko milestone (i.e. right after an upgrade).
127 * OVERRIDE_NEW_BUILD_ID if this is the first run with a new build ID of the
128 * same Gecko milestone (i.e. after a nightly upgrade).
129 * OVERRIDE_NONE otherwise.
131 function needHomepageOverride(prefb) {
132 var savedmstone = null;
134 savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
137 if (savedmstone == "ignore")
138 return OVERRIDE_NONE;
140 var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
141 .getService(nsIHttpProtocolHandler).misc;
143 var savedBuildID = null;
145 savedBuildID = prefb.getCharPref("browser.startup.homepage_override.buildID");
148 var buildID = Components.classes["@mozilla.org/xre/app-info;1"]
149 .getService(nsIXULAppInfo).platformBuildID;
151 if (mstone != savedmstone) {
152 // Bug 462254. Previous releases had a default pref to suppress the EULA
153 // agreement if the platform's installer had already shown one. Now with
154 // about:rights we've removed the EULA stuff and default pref, but we need
155 // a way to make existing profiles retain the default that we removed.
157 prefb.setBoolPref("browser.rights.3.shown", true);
159 prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
160 prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
161 return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
164 if (buildID != savedBuildID) {
165 prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
166 return OVERRIDE_NEW_BUILD_ID;
169 return OVERRIDE_NONE;
173 * Gets the override page for the first run after the application has been
175 * @param defaultOverridePage
176 * The default override page.
177 * @return The override page.
179 function getPostUpdateOverridePage(defaultOverridePage) {
180 var um = Components.classes["@mozilla.org/updates/update-manager;1"]
181 .getService(Components.interfaces.nsIUpdateManager);
183 // If the updates.xml file is deleted then getUpdateAt will throw.
184 var update = um.getUpdateAt(0)
185 .QueryInterface(Components.interfaces.nsIPropertyBag);
187 // This should never happen.
188 Components.utils.reportError("Unable to find update: " + e);
189 return defaultOverridePage;
192 let actions = update.getProperty("actions");
193 // When the update doesn't specify actions fallback to the original behavior
194 // of displaying the default override page.
196 return defaultOverridePage;
198 // The existence of silent or the non-existence of showURL in the actions both
199 // mean that an override page should not be displayed.
200 if (actions.indexOf("silent") != -1 || actions.indexOf("showURL") == -1)
203 return update.getProperty("openURL") || defaultOverridePage;
206 // Copies a pref override file into the user's profile pref-override folder,
207 // and then tells the pref service to reload its default prefs.
208 function copyPrefOverride() {
210 var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
211 .getService(Components.interfaces.nsIProperties);
212 const NS_APP_EXISTING_PREF_OVERRIDE = "ExistingPrefOverride";
213 var prefOverride = fileLocator.get(NS_APP_EXISTING_PREF_OVERRIDE,
214 Components.interfaces.nsIFile);
215 if (!prefOverride.exists())
216 return; // nothing to do
218 const NS_APP_PREFS_OVERRIDE_DIR = "PrefDOverride";
219 var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
220 Components.interfaces.nsIFile);
222 // Check for any existing pref overrides, and remove them if present
223 var existingPrefOverridesFile = prefOverridesDir.clone();
224 existingPrefOverridesFile.append(prefOverride.leafName);
225 if (existingPrefOverridesFile.exists())
226 existingPrefOverridesFile.remove(false);
228 prefOverride.copyTo(prefOverridesDir, null);
230 // Now that we've installed the new-profile pref override file,
231 // re-read the default prefs.
232 var prefSvcObs = Components.classes["@mozilla.org/preferences-service;1"]
233 .getService(Components.interfaces.nsIObserver);
234 prefSvcObs.observe(null, "reload-default-prefs", null);
236 Components.utils.reportError(ex);
240 // Flag used to indicate that the arguments to openWindow can be passed directly.
241 const NO_EXTERNAL_URIS = 1;
243 function openWindow(parent, url, target, features, args, noExternalArgs) {
244 var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
245 .getService(nsIWindowWatcher);
247 if (noExternalArgs == NO_EXTERNAL_URIS) {
248 // Just pass in the defaultArgs directly
251 argstring = Components.classes["@mozilla.org/supports-string;1"]
252 .createInstance(nsISupportsString);
253 argstring.data = args;
256 return wwatch.openWindow(parent, url, target, features, argstring);
259 // Pass an array to avoid the browser "|"-splitting behavior.
260 var argArray = Components.classes["@mozilla.org/supports-array;1"]
261 .createInstance(Components.interfaces.nsISupportsArray);
263 // add args to the arguments array
264 var stringArgs = null;
265 if (args instanceof Array) // array
267 else if (args) // string
271 // put the URIs into argArray
272 var uriArray = Components.classes["@mozilla.org/supports-array;1"]
273 .createInstance(Components.interfaces.nsISupportsArray);
274 stringArgs.forEach(function (uri) {
275 var sstring = Components.classes["@mozilla.org/supports-string;1"]
276 .createInstance(nsISupportsString);
278 uriArray.AppendElement(sstring);
280 argArray.AppendElement(uriArray);
282 argArray.AppendElement(null);
285 // Pass these as null to ensure that we always trigger the "single URL"
286 // behavior in browser.js's BrowserStartup (which handles the window
288 argArray.AppendElement(null); // charset
289 argArray.AppendElement(null); // referer
290 argArray.AppendElement(null); // postData
291 argArray.AppendElement(null); // allowThirdPartyFixup
293 return wwatch.openWindow(parent, url, target, features, argArray);
296 function openPreferences() {
297 var features = "chrome,titlebar,toolbar,centerscreen,dialog=no";
298 var url = "chrome://browser/content/preferences/preferences.xul";
300 var win = getMostRecentWindow("Browser:Preferences");
304 openWindow(null, url, "_blank", features);
308 function getMostRecentWindow(aType) {
309 var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
310 .getService(nsIWindowMediator);
311 return wm.getMostRecentWindow(aType);
314 // this returns the most recent non-popup browser window
315 function getMostRecentBrowserWindow() {
316 var browserGlue = Components.classes["@mozilla.org/browser/browserglue;1"]
317 .getService(Components.interfaces.nsIBrowserGlue);
318 return browserGlue.getMostRecentBrowserWindow();
321 function doSearch(searchTerm, cmdLine) {
322 var ss = Components.classes["@mozilla.org/browser/search-service;1"]
323 .getService(nsIBrowserSearchService);
325 var submission = ss.defaultEngine.getSubmission(searchTerm);
327 // fill our nsISupportsArray with uri-as-wstring, null, null, postData
328 var sa = Components.classes["@mozilla.org/supports-array;1"]
329 .createInstance(Components.interfaces.nsISupportsArray);
331 var wuri = Components.classes["@mozilla.org/supports-string;1"]
332 .createInstance(Components.interfaces.nsISupportsString);
333 wuri.data = submission.uri.spec;
335 sa.AppendElement(wuri);
336 sa.AppendElement(null);
337 sa.AppendElement(null);
338 sa.AppendElement(submission.postData);
340 // XXXbsmedberg: use handURIToExistingBrowser to obey tabbed-browsing
341 // preferences, but need nsIBrowserDOMWindow extensions
343 var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
344 .getService(nsIWindowWatcher);
346 return wwatch.openWindow(null, gBrowserContentHandler.chromeURL,
348 "chrome,dialog=no,all" +
349 gBrowserContentHandler.getFeatures(cmdLine),
353 function nsBrowserContentHandler() {
355 nsBrowserContentHandler.prototype = {
356 classID: Components.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}"),
359 createInstance: function bch_factory_ci(outer, iid) {
361 throw Components.results.NS_ERROR_NO_AGGREGATION;
362 return gBrowserContentHandler.QueryInterface(iid);
366 /* helper functions */
371 if (this.mChromeURL) {
372 return this.mChromeURL;
375 var prefb = Components.classes["@mozilla.org/preferences-service;1"]
376 .getService(nsIPrefBranch);
377 this.mChromeURL = prefb.getCharPref("browser.chromeURL");
379 return this.mChromeURL;
383 QueryInterface : XPCOMUtils.generateQI([nsICommandLineHandler,
386 nsICommandLineValidator]),
388 /* nsICommandLineHandler */
389 handle : function bch_handle(cmdLine) {
390 if (cmdLine.handleFlag("browser", false)) {
391 // Passing defaultArgs, so use NO_EXTERNAL_URIS
392 openWindow(null, this.chromeURL, "_blank",
393 "chrome,dialog=no,all" + this.getFeatures(cmdLine),
394 this.defaultArgs, NO_EXTERNAL_URIS);
395 cmdLine.preventDefault = true;
399 var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
402 throw NS_ERROR_ABORT;
405 if (remoteCommand != null) {
407 var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
410 remoteVerb = a[1].toLowerCase();
411 var remoteParams = [];
412 var sepIndex = a[2].lastIndexOf(",");
414 remoteParams[0] = a[2];
416 remoteParams[0] = a[2].substring(0, sepIndex);
417 remoteParams[1] = a[2].substring(sepIndex + 1);
421 switch (remoteVerb) {
425 // openURL(<url>,new-window)
426 // openURL(<url>,new-tab)
428 // First param is the URL, second param (if present) is the "target"
430 var url = remoteParams[0];
431 var target = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
432 if (remoteParams[1]) {
433 var targetParam = remoteParams[1].toLowerCase()
434 .replace(/^\s*|\s*$/g, "");
435 if (targetParam == "new-tab")
436 target = nsIBrowserDOMWindow.OPEN_NEWTAB;
437 else if (targetParam == "new-window")
438 target = nsIBrowserDOMWindow.OPEN_NEWWINDOW;
440 // The "target" param isn't one of our supported values, so
441 // assume it's part of a URL that contains commas.
442 url += "," + remoteParams[1];
446 var uri = resolveURIInternal(cmdLine, url);
447 handURIToExistingBrowser(uri, target, cmdLine);
451 // xfeDoCommand(openBrowser)
452 if (remoteParams[0].toLowerCase() != "openbrowser")
453 throw NS_ERROR_ABORT;
455 // Passing defaultArgs, so use NO_EXTERNAL_URIS
456 openWindow(null, this.chromeURL, "_blank",
457 "chrome,dialog=no,all" + this.getFeatures(cmdLine),
458 this.defaultArgs, NO_EXTERNAL_URIS);
462 // Somebody sent us a remote command we don't know how to process:
464 throw "Unknown remote command.";
467 cmdLine.preventDefault = true;
470 Components.utils.reportError(e);
471 // If we had a -remote flag but failed to process it, throw
472 // NS_ERROR_ABORT so that the xremote code knows to return a failure
473 // back to the handling code.
474 throw NS_ERROR_ABORT;
480 while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) {
481 var uri = resolveURIInternal(cmdLine, uriparam);
482 if (!shouldLoadURI(uri))
484 openWindow(null, this.chromeURL, "_blank",
485 "chrome,dialog=no,all" + this.getFeatures(cmdLine),
487 cmdLine.preventDefault = true;
491 Components.utils.reportError(e);
495 while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) {
496 var uri = resolveURIInternal(cmdLine, uriparam);
497 handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine);
498 cmdLine.preventDefault = true;
502 Components.utils.reportError(e);
505 var chromeParam = cmdLine.handleFlagWithParam("chrome", false);
508 // Handle the old preference dialog URL separately (bug 285416)
509 if (chromeParam == "chrome://browser/content/pref/pref.xul") {
511 cmdLine.preventDefault = true;
513 // only load URIs which do not inherit chrome privs
514 var features = "chrome,dialog=no,all" + this.getFeatures(cmdLine);
515 var uri = resolveURIInternal(cmdLine, chromeParam);
516 var netutil = Components.classes["@mozilla.org/network/util;1"]
517 .getService(nsINetUtil);
518 if (!netutil.URIChainHasFlags(uri, URI_INHERITS_SECURITY_CONTEXT)) {
519 openWindow(null, uri.spec, "_blank", features);
520 cmdLine.preventDefault = true;
524 Components.utils.reportError(e);
527 if (cmdLine.handleFlag("preferences", false)) {
529 cmdLine.preventDefault = true;
531 if (cmdLine.handleFlag("silent", false))
532 cmdLine.preventDefault = true;
533 if (cmdLine.findFlag("private-toggle", false) >= 0)
534 cmdLine.preventDefault = true;
536 var searchParam = cmdLine.handleFlagWithParam("search", false);
538 doSearch(searchParam, cmdLine);
539 cmdLine.preventDefault = true;
542 var fileParam = cmdLine.handleFlagWithParam("file", false);
544 var file = cmdLine.resolveFile(fileParam);
545 var ios = Components.classes["@mozilla.org/network/io-service;1"]
546 .getService(Components.interfaces.nsIIOService);
547 var uri = ios.newFileURI(file);
548 openWindow(null, this.chromeURL, "_blank",
549 "chrome,dialog=no,all" + this.getFeatures(cmdLine),
551 cmdLine.preventDefault = true;
555 // Handle "? searchterm" for Windows Vista start menu integration
556 for (var i = cmdLine.length - 1; i >= 0; --i) {
557 var param = cmdLine.getArgument(i);
558 if (param.match(/^\? /)) {
559 cmdLine.removeArguments(i, i);
560 cmdLine.preventDefault = true;
562 searchParam = param.substr(2);
563 doSearch(searchParam, cmdLine);
569 helpInfo : " -browser Open a browser window.\n" +
570 " -new-window <url> Open <url> in a new window.\n" +
571 " -new-tab <url> Open <url> in a new tab.\n" +
573 " -preferences Open Options dialog.\n" +
575 " -preferences Open Preferences dialog.\n" +
577 " -search <term> Search <term> with your default search engine.\n",
579 /* nsIBrowserHandler */
582 var prefb = Components.classes["@mozilla.org/preferences-service;1"]
583 .getService(nsIPrefBranch);
585 var overridePage = "";
586 var haveUpdateSession = false;
588 let override = needHomepageOverride(prefb);
589 if (override != OVERRIDE_NONE) {
590 // Setup the default search engine to about:home page.
591 AboutHomeUtils.loadDefaultSearchEngine();
592 AboutHomeUtils.loadSnippetsURL();
595 case OVERRIDE_NEW_PROFILE:
597 overridePage = Services.urlFormatter.formatURLPref("startup.homepage_welcome_url");
599 case OVERRIDE_NEW_MSTONE:
600 // Existing profile, new milestone build.
603 // Check whether we have a session to restore. If we do, we assume
604 // that this is an "update" session.
605 var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
606 .getService(Components.interfaces.nsISessionStartup);
607 haveUpdateSession = ss.doRestore();
608 overridePage = Services.urlFormatter.formatURLPref("startup.homepage_override_url");
609 if (prefb.prefHasUserValue("app.update.postupdate"))
610 overridePage = getPostUpdateOverridePage(overridePage);
615 // No need to override homepage, but update snippets url if the pref has
616 // been manually changed.
617 if (Services.prefs.prefHasUserValue(AboutHomeUtils.SNIPPETS_URL_PREF)) {
618 AboutHomeUtils.loadSnippetsURL();
623 // formatURLPref might return "about:blank" if getting the pref fails
624 if (overridePage == "about:blank")
629 var choice = prefb.getIntPref("browser.startup.page");
630 if (choice == 1 || choice == 3)
631 startPage = this.startPage;
633 Components.utils.reportError(e);
636 if (startPage == "about:blank")
639 // Only show the startPage if we're not restoring an update session.
640 if (overridePage && startPage && !haveUpdateSession)
641 return overridePage + "|" + startPage;
643 return overridePage || startPage || "about:blank";
647 var uri = Services.prefs.getComplexValue("browser.startup.homepage",
648 nsIPrefLocalizedString).data;
650 Services.prefs.clearUserPref("browser.startup.homepage");
651 uri = Services.prefs.getComplexValue("browser.startup.homepage",
652 nsIPrefLocalizedString).data;
659 getFeatures : function bch_features(cmdLine) {
660 if (this.mFeatures === null) {
664 var width = cmdLine.handleFlagWithParam("width", false);
665 var height = cmdLine.handleFlagWithParam("height", false);
668 this.mFeatures += ",width=" + width;
670 this.mFeatures += ",height=" + height;
676 return this.mFeatures;
679 /* nsIContentHandler */
681 handleContent : function bch_handleContent(contentType, context, request) {
683 var webNavInfo = Components.classes["@mozilla.org/webnavigation-info;1"]
684 .getService(nsIWebNavigationInfo);
685 if (!webNavInfo.isTypeSupported(contentType, null)) {
686 throw NS_ERROR_WONT_HANDLE_CONTENT;
689 throw NS_ERROR_WONT_HANDLE_CONTENT;
692 request.QueryInterface(nsIChannel);
693 handURIToExistingBrowser(request.URI,
694 nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null);
695 request.cancel(NS_BINDING_ABORTED);
698 /* nsICommandLineValidator */
699 validate : function bch_validate(cmdLine) {
700 // Other handlers may use osint so only handle the osint flag if the url
701 // flag is also present and the command line is valid.
702 var osintFlagIdx = cmdLine.findFlag("osint", false);
703 var urlFlagIdx = cmdLine.findFlag("url", false);
704 if (urlFlagIdx > -1 && (osintFlagIdx > -1 ||
705 cmdLine.state == nsICommandLine.STATE_REMOTE_EXPLICIT)) {
706 var urlParam = cmdLine.getArgument(urlFlagIdx + 1);
707 if (cmdLine.length != urlFlagIdx + 2 || /firefoxurl:/.test(urlParam))
708 throw NS_ERROR_ABORT;
709 cmdLine.handleFlag("osint", false)
713 var gBrowserContentHandler = new nsBrowserContentHandler();
715 function handURIToExistingBrowser(uri, location, cmdLine)
717 if (!shouldLoadURI(uri))
720 var navWin = getMostRecentBrowserWindow();
722 // if we couldn't load it in an existing window, open a new one
723 openWindow(null, gBrowserContentHandler.chromeURL, "_blank",
724 "chrome,dialog=no,all" + gBrowserContentHandler.getFeatures(cmdLine),
729 var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
730 .getInterface(nsIWebNavigation);
731 var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
732 var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
733 .getInterface(nsIDOMWindow);
734 var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
735 bwin.openURI(uri, null, location,
736 nsIBrowserDOMWindow.OPEN_EXTERNAL);
739 function nsDefaultCommandLineHandler() {
742 nsDefaultCommandLineHandler.prototype = {
743 classID: Components.ID("{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}"),
746 QueryInterface : function dch_QI(iid) {
747 if (!iid.equals(nsISupports) &&
748 !iid.equals(nsICommandLineHandler))
749 throw Components.results.NS_ERROR_NO_INTERFACE;
754 // List of uri's that were passed via the command line without the app
755 // running and have already been handled. This is compared against uri's
756 // opened using DDE on Win32 so we only open one of the requests.
762 /* nsICommandLineHandler */
763 handle : function dch_handle(cmdLine) {
767 // If we don't have a profile selected yet (e.g. the Profile Manager is
768 // displayed) we will crash if we open an url and then select a profile. To
769 // prevent this handle all url command line flags and set the command line's
770 // preventDefault to true to prevent the display of the ui. The initial
771 // command line will be retained when nsAppRunner calls LaunchChild though
772 // urls launched after the initial launch will be lost.
773 if (!this._haveProfile) {
775 // This will throw when a profile has not been selected.
776 var fl = Components.classes["@mozilla.org/file/directory_service;1"]
777 .getService(Components.interfaces.nsIProperties);
778 var dir = fl.get("ProfD", Components.interfaces.nsILocalFile);
779 this._haveProfile = true;
782 while ((ar = cmdLine.handleFlagWithParam("url", false))) { }
783 cmdLine.preventDefault = true;
790 while ((ar = cmdLine.handleFlagWithParam("url", false))) {
792 var uri = resolveURIInternal(cmdLine, ar);
793 // count will never be greater than zero except on Win32.
794 var count = this._handledURIs.length;
795 for (var i = 0; i < count; ++i) {
796 if (this._handledURIs[i].spec == uri.spec) {
797 this._handledURIs.splice(i, 1);
799 cmdLine.preventDefault = true;
805 // The requestpending command line flag is only used on Win32.
806 if (cmdLine.handleFlag("requestpending", false) &&
807 cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
808 this._handledURIs.push(uri)
813 Components.utils.reportError(e);
816 count = cmdLine.length;
818 for (i = 0; i < count; ++i) {
819 var curarg = cmdLine.getArgument(i);
820 if (curarg.match(/^-/)) {
821 Components.utils.reportError("Warning: unrecognized command line flag " + curarg + "\n");
822 // To emulate the pre-nsICommandLine behavior, we ignore
823 // the argument after an unrecognized flag.
827 urilist.push(resolveURIInternal(cmdLine, curarg));
830 Components.utils.reportError("Error opening URI '" + curarg + "' from the command line: " + e + "\n");
835 if (urilist.length) {
836 if (cmdLine.state != nsICommandLine.STATE_INITIAL_LAUNCH &&
837 urilist.length == 1) {
838 // Try to find an existing window and load our URI into the
839 // current tab, new tab, or new window as prefs determine.
841 handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine);
848 var URLlist = urilist.filter(shouldLoadURI).map(function (u) u.spec);
849 if (URLlist.length) {
850 openWindow(null, gBrowserContentHandler.chromeURL, "_blank",
851 "chrome,dialog=no,all" + gBrowserContentHandler.getFeatures(cmdLine),
856 else if (!cmdLine.preventDefault) {
857 // Passing defaultArgs, so use NO_EXTERNAL_URIS
858 openWindow(null, gBrowserContentHandler.chromeURL, "_blank",
859 "chrome,dialog=no,all" + gBrowserContentHandler.getFeatures(cmdLine),
860 gBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS);
867 let AboutHomeUtils = {
868 SNIPPETS_URL_PREF: "browser.aboutHomeSnippets.updateUrl",
870 let aboutHomeURI = Services.io.newURI("moz-safe-about:home", null, null);
871 let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
872 getService(Components.interfaces.nsIScriptSecurityManager).
873 getCodebasePrincipal(aboutHomeURI);
874 let dsm = Components.classes["@mozilla.org/dom/storagemanager;1"].
875 getService(Components.interfaces.nsIDOMStorageManager);
876 return dsm.getLocalStorageForPrincipal(principal, "");
879 loadDefaultSearchEngine: function AHU_loadDefaultSearchEngine()
881 let defaultEngine = Services.search.originalDefaultEngine;
882 let submission = defaultEngine.getSubmission("_searchTerms_");
883 if (submission.postData)
884 throw new Error("Home page does not support POST search engines.");
886 name: defaultEngine.name
887 , searchUrl: submission.uri.spec
889 this._storage.setItem("search-engine", JSON.stringify(engine));
892 loadSnippetsURL: function AHU_loadSnippetsURL()
894 const STARTPAGE_VERSION = 1;
895 let updateURL = Services.prefs
896 .getCharPref(this.SNIPPETS_URL_PREF)
897 .replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION);
898 updateURL = Services.urlFormatter.formatURL(updateURL);
899 this._storage.setItem("snippets-update-url", updateURL);
903 var components = [nsBrowserContentHandler, nsDefaultCommandLineHandler];
904 var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);