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 nsICategoryManager
= Components
.interfaces
.nsICategoryManager
;
66 const nsIWebNavigationInfo
= Components
.interfaces
.nsIWebNavigationInfo
;
67 const nsIBrowserSearchService
= Components
.interfaces
.nsIBrowserSearchService
;
68 const nsICommandLineValidator
= Components
.interfaces
.nsICommandLineValidator
;
69 const nsIXULAppInfo
= Components
.interfaces
.nsIXULAppInfo
;
71 const NS_BINDING_ABORTED
= Components
.results
.NS_BINDING_ABORTED
;
72 const NS_ERROR_WONT_HANDLE_CONTENT
= 0x805d0001;
73 const NS_ERROR_ABORT
= Components
.results
.NS_ERROR_ABORT
;
75 const URI_INHERITS_SECURITY_CONTEXT
= nsIHttpProtocolHandler
76 .URI_INHERITS_SECURITY_CONTEXT
;
78 function shouldLoadURI(aURI
) {
79 if (aURI
&& !aURI
.schemeIs("chrome"))
82 dump("*** Preventing external load of chrome: URI into browser window\n");
83 dump(" Use -chrome <uri> instead\n");
87 function resolveURIInternal(aCmdLine
, aArgument
) {
88 var uri
= aCmdLine
.resolveURI(aArgument
);
90 if (!(uri
instanceof nsIFileURL
)) {
95 if (uri
.file
.exists())
99 Components
.utils
.reportError(e
);
102 // We have interpreted the argument as a relative file URI, but the file
103 // doesn't exist. Try URI fixup heuristics: see bug 290782.
106 var urifixup
= Components
.classes
["@mozilla.org/docshell/urifixup;1"]
107 .getService(nsIURIFixup
);
109 uri
= urifixup
.createFixupURI(aArgument
, 0);
112 Components
.utils
.reportError(e
);
118 const OVERRIDE_NONE
= 0;
119 const OVERRIDE_NEW_PROFILE
= 1;
120 const OVERRIDE_NEW_MSTONE
= 2;
121 const OVERRIDE_NEW_BUILD_ID
= 3;
123 * Determines whether a home page override is needed.
125 * OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
126 * OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
127 * Gecko milestone (i.e. right after an upgrade).
128 * OVERRIDE_NEW_BUILD_ID if this is the first run with a new build ID of the
129 * same Gecko milestone (i.e. after a nightly upgrade).
130 * OVERRIDE_NONE otherwise.
132 function needHomepageOverride(prefb
) {
133 var savedmstone
= null;
135 savedmstone
= prefb
.getCharPref("browser.startup.homepage_override.mstone");
138 if (savedmstone
== "ignore")
139 return OVERRIDE_NONE
;
141 var mstone
= Components
.classes
["@mozilla.org/network/protocol;1?name=http"]
142 .getService(nsIHttpProtocolHandler
).misc
;
144 var savedBuildID
= null;
146 savedBuildID
= prefb
.getCharPref("browser.startup.homepage_override.buildID");
149 var buildID
= Components
.classes
["@mozilla.org/xre/app-info;1"]
150 .getService(nsIXULAppInfo
).platformBuildID
;
152 if (mstone
!= savedmstone
) {
153 // Bug 462254. Previous releases had a default pref to suppress the EULA
154 // agreement if the platform's installer had already shown one. Now with
155 // about:rights we've removed the EULA stuff and default pref, but we need
156 // a way to make existing profiles retain the default that we removed.
158 prefb
.setBoolPref("browser.rights.3.shown", true);
160 prefb
.setCharPref("browser.startup.homepage_override.mstone", mstone
);
161 prefb
.setCharPref("browser.startup.homepage_override.buildID", buildID
);
162 return (savedmstone
? OVERRIDE_NEW_MSTONE
: OVERRIDE_NEW_PROFILE
);
165 if (buildID
!= savedBuildID
) {
166 prefb
.setCharPref("browser.startup.homepage_override.buildID", buildID
);
167 return OVERRIDE_NEW_BUILD_ID
;
170 return OVERRIDE_NONE
;
174 * Gets the override page for the first run after the application has been
176 * @param defaultOverridePage
177 * The default override page.
178 * @return The override page.
180 function getPostUpdateOverridePage(defaultOverridePage
) {
181 var um
= Components
.classes
["@mozilla.org/updates/update-manager;1"]
182 .getService(Components
.interfaces
.nsIUpdateManager
);
184 // If the updates.xml file is deleted then getUpdateAt will throw.
185 var update
= um
.getUpdateAt(0)
186 .QueryInterface(Components
.interfaces
.nsIPropertyBag
);
188 // This should never happen.
189 Components
.utils
.reportError("Unable to find update: " + e
);
190 return defaultOverridePage
;
193 let actions
= update
.getProperty("actions");
194 // When the update doesn't specify actions fallback to the original behavior
195 // of displaying the default override page.
197 return defaultOverridePage
;
199 // The existence of silent or the non-existence of showURL in the actions both
200 // mean that an override page should not be displayed.
201 if (actions
.indexOf("silent") != -1 || actions
.indexOf("showURL") == -1)
204 return update
.getProperty("openURL") || defaultOverridePage
;
207 // Copies a pref override file into the user's profile pref-override folder,
208 // and then tells the pref service to reload its default prefs.
209 function copyPrefOverride() {
211 var fileLocator
= Components
.classes
["@mozilla.org/file/directory_service;1"]
212 .getService(Components
.interfaces
.nsIProperties
);
213 const NS_APP_EXISTING_PREF_OVERRIDE
= "ExistingPrefOverride";
214 var prefOverride
= fileLocator
.get(NS_APP_EXISTING_PREF_OVERRIDE
,
215 Components
.interfaces
.nsIFile
);
216 if (!prefOverride
.exists())
217 return; // nothing to do
219 const NS_APP_PREFS_OVERRIDE_DIR
= "PrefDOverride";
220 var prefOverridesDir
= fileLocator
.get(NS_APP_PREFS_OVERRIDE_DIR
,
221 Components
.interfaces
.nsIFile
);
223 // Check for any existing pref overrides, and remove them if present
224 var existingPrefOverridesFile
= prefOverridesDir
.clone();
225 existingPrefOverridesFile
.append(prefOverride
.leafName
);
226 if (existingPrefOverridesFile
.exists())
227 existingPrefOverridesFile
.remove(false);
229 prefOverride
.copyTo(prefOverridesDir
, null);
231 // Now that we've installed the new-profile pref override file,
232 // re-read the default prefs.
233 var prefSvcObs
= Components
.classes
["@mozilla.org/preferences-service;1"]
234 .getService(Components
.interfaces
.nsIObserver
);
235 prefSvcObs
.observe(null, "reload-default-prefs", null);
237 Components
.utils
.reportError(ex
);
241 // Flag used to indicate that the arguments to openWindow can be passed directly.
242 const NO_EXTERNAL_URIS
= 1;
244 function openWindow(parent
, url
, target
, features
, args
, noExternalArgs
) {
245 var wwatch
= Components
.classes
["@mozilla.org/embedcomp/window-watcher;1"]
246 .getService(nsIWindowWatcher
);
248 if (noExternalArgs
== NO_EXTERNAL_URIS
) {
249 // Just pass in the defaultArgs directly
252 argstring
= Components
.classes
["@mozilla.org/supports-string;1"]
253 .createInstance(nsISupportsString
);
254 argstring
.data
= args
;
257 return wwatch
.openWindow(parent
, url
, target
, features
, argstring
);
260 // Pass an array to avoid the browser "|"-splitting behavior.
261 var argArray
= Components
.classes
["@mozilla.org/supports-array;1"]
262 .createInstance(Components
.interfaces
.nsISupportsArray
);
264 // add args to the arguments array
265 var stringArgs
= null;
266 if (args
instanceof Array
) // array
268 else if (args
) // string
272 // put the URIs into argArray
273 var uriArray
= Components
.classes
["@mozilla.org/supports-array;1"]
274 .createInstance(Components
.interfaces
.nsISupportsArray
);
275 stringArgs
.forEach(function (uri
) {
276 var sstring
= Components
.classes
["@mozilla.org/supports-string;1"]
277 .createInstance(nsISupportsString
);
279 uriArray
.AppendElement(sstring
);
281 argArray
.AppendElement(uriArray
);
283 argArray
.AppendElement(null);
286 // Pass these as null to ensure that we always trigger the "single URL"
287 // behavior in browser.js's BrowserStartup (which handles the window
289 argArray
.AppendElement(null); // charset
290 argArray
.AppendElement(null); // referer
291 argArray
.AppendElement(null); // postData
292 argArray
.AppendElement(null); // allowThirdPartyFixup
294 return wwatch
.openWindow(parent
, url
, target
, features
, argArray
);
297 function openPreferences() {
298 var features
= "chrome,titlebar,toolbar,centerscreen,dialog=no";
299 var url
= "chrome://browser/content/preferences/preferences.xul";
301 var win
= getMostRecentWindow("Browser:Preferences");
305 openWindow(null, url
, "_blank", features
);
309 function getMostRecentWindow(aType
) {
310 var wm
= Components
.classes
["@mozilla.org/appshell/window-mediator;1"]
311 .getService(nsIWindowMediator
);
312 return wm
.getMostRecentWindow(aType
);
315 // this returns the most recent non-popup browser window
316 function getMostRecentBrowserWindow() {
317 var browserGlue
= Components
.classes
["@mozilla.org/browser/browserglue;1"]
318 .getService(Components
.interfaces
.nsIBrowserGlue
);
319 return browserGlue
.getMostRecentBrowserWindow();
322 function doSearch(searchTerm
, cmdLine
) {
323 var ss
= Components
.classes
["@mozilla.org/browser/search-service;1"]
324 .getService(nsIBrowserSearchService
);
326 var submission
= ss
.defaultEngine
.getSubmission(searchTerm
);
328 // fill our nsISupportsArray with uri-as-wstring, null, null, postData
329 var sa
= Components
.classes
["@mozilla.org/supports-array;1"]
330 .createInstance(Components
.interfaces
.nsISupportsArray
);
332 var wuri
= Components
.classes
["@mozilla.org/supports-string;1"]
333 .createInstance(Components
.interfaces
.nsISupportsString
);
334 wuri
.data
= submission
.uri
.spec
;
336 sa
.AppendElement(wuri
);
337 sa
.AppendElement(null);
338 sa
.AppendElement(null);
339 sa
.AppendElement(submission
.postData
);
341 // XXXbsmedberg: use handURIToExistingBrowser to obey tabbed-browsing
342 // preferences, but need nsIBrowserDOMWindow extensions
344 var wwatch
= Components
.classes
["@mozilla.org/embedcomp/window-watcher;1"]
345 .getService(nsIWindowWatcher
);
347 return wwatch
.openWindow(null, gBrowserContentHandler
.chromeURL
,
349 "chrome,dialog=no,all" +
350 gBrowserContentHandler
.getFeatures(cmdLine
),
354 function nsBrowserContentHandler() {
356 nsBrowserContentHandler
.prototype = {
357 classID
: Components
.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}"),
360 createInstance
: function bch_factory_ci(outer
, iid
) {
362 throw Components
.results
.NS_ERROR_NO_AGGREGATION
;
363 return gBrowserContentHandler
.QueryInterface(iid
);
367 /* helper functions */
372 if (this.mChromeURL
) {
373 return this.mChromeURL
;
376 var prefb
= Components
.classes
["@mozilla.org/preferences-service;1"]
377 .getService(nsIPrefBranch
);
378 this.mChromeURL
= prefb
.getCharPref("browser.chromeURL");
380 return this.mChromeURL
;
384 QueryInterface
: XPCOMUtils
.generateQI([nsICommandLineHandler
,
387 nsICommandLineValidator
]),
389 /* nsICommandLineHandler */
390 handle
: function bch_handle(cmdLine
) {
391 if (cmdLine
.handleFlag("browser", false)) {
392 // Passing defaultArgs, so use NO_EXTERNAL_URIS
393 openWindow(null, this.chromeURL
, "_blank",
394 "chrome,dialog=no,all" + this.getFeatures(cmdLine
),
395 this.defaultArgs
, NO_EXTERNAL_URIS
);
396 cmdLine
.preventDefault
= true;
400 var remoteCommand
= cmdLine
.handleFlagWithParam("remote", true);
403 throw NS_ERROR_ABORT
;
406 if (remoteCommand
!= null) {
408 var a
= /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand
);
411 remoteVerb
= a
[1].toLowerCase();
412 var remoteParams
= [];
413 var sepIndex
= a
[2].lastIndexOf(",");
415 remoteParams
[0] = a
[2];
417 remoteParams
[0] = a
[2].substring(0, sepIndex
);
418 remoteParams
[1] = a
[2].substring(sepIndex
+ 1);
422 switch (remoteVerb
) {
426 // openURL(<url>,new-window)
427 // openURL(<url>,new-tab)
429 // First param is the URL, second param (if present) is the "target"
431 var url
= remoteParams
[0];
432 var target
= nsIBrowserDOMWindow
.OPEN_DEFAULTWINDOW
;
433 if (remoteParams
[1]) {
434 var targetParam
= remoteParams
[1].toLowerCase()
435 .replace(/^\s*|\s*$/g, "");
436 if (targetParam
== "new-tab")
437 target
= nsIBrowserDOMWindow
.OPEN_NEWTAB
;
438 else if (targetParam
== "new-window")
439 target
= nsIBrowserDOMWindow
.OPEN_NEWWINDOW
;
441 // The "target" param isn't one of our supported values, so
442 // assume it's part of a URL that contains commas.
443 url
+= "," + remoteParams
[1];
447 var uri
= resolveURIInternal(cmdLine
, url
);
448 handURIToExistingBrowser(uri
, target
, cmdLine
);
452 // xfeDoCommand(openBrowser)
453 if (remoteParams
[0].toLowerCase() != "openbrowser")
454 throw NS_ERROR_ABORT
;
456 // Passing defaultArgs, so use NO_EXTERNAL_URIS
457 openWindow(null, this.chromeURL
, "_blank",
458 "chrome,dialog=no,all" + this.getFeatures(cmdLine
),
459 this.defaultArgs
, NO_EXTERNAL_URIS
);
463 // Somebody sent us a remote command we don't know how to process:
465 throw "Unknown remote command.";
468 cmdLine
.preventDefault
= true;
471 Components
.utils
.reportError(e
);
472 // If we had a -remote flag but failed to process it, throw
473 // NS_ERROR_ABORT so that the xremote code knows to return a failure
474 // back to the handling code.
475 throw NS_ERROR_ABORT
;
481 while ((uriparam
= cmdLine
.handleFlagWithParam("new-window", false))) {
482 var uri
= resolveURIInternal(cmdLine
, uriparam
);
483 if (!shouldLoadURI(uri
))
485 openWindow(null, this.chromeURL
, "_blank",
486 "chrome,dialog=no,all" + this.getFeatures(cmdLine
),
488 cmdLine
.preventDefault
= true;
492 Components
.utils
.reportError(e
);
496 while ((uriparam
= cmdLine
.handleFlagWithParam("new-tab", false))) {
497 var uri
= resolveURIInternal(cmdLine
, uriparam
);
498 handURIToExistingBrowser(uri
, nsIBrowserDOMWindow
.OPEN_NEWTAB
, cmdLine
);
499 cmdLine
.preventDefault
= true;
503 Components
.utils
.reportError(e
);
506 var chromeParam
= cmdLine
.handleFlagWithParam("chrome", false);
509 // Handle the old preference dialog URL separately (bug 285416)
510 if (chromeParam
== "chrome://browser/content/pref/pref.xul") {
512 cmdLine
.preventDefault
= true;
514 // only load URIs which do not inherit chrome privs
515 var features
= "chrome,dialog=no,all" + this.getFeatures(cmdLine
);
516 var uri
= resolveURIInternal(cmdLine
, chromeParam
);
517 var netutil
= Components
.classes
["@mozilla.org/network/util;1"]
518 .getService(nsINetUtil
);
519 if (!netutil
.URIChainHasFlags(uri
, URI_INHERITS_SECURITY_CONTEXT
)) {
520 openWindow(null, uri
.spec
, "_blank", features
);
521 cmdLine
.preventDefault
= true;
525 Components
.utils
.reportError(e
);
528 if (cmdLine
.handleFlag("preferences", false)) {
530 cmdLine
.preventDefault
= true;
532 if (cmdLine
.handleFlag("silent", false))
533 cmdLine
.preventDefault
= true;
534 if (cmdLine
.findFlag("private-toggle", false) >= 0)
535 cmdLine
.preventDefault
= true;
537 var searchParam
= cmdLine
.handleFlagWithParam("search", false);
539 doSearch(searchParam
, cmdLine
);
540 cmdLine
.preventDefault
= true;
543 var fileParam
= cmdLine
.handleFlagWithParam("file", false);
545 var file
= cmdLine
.resolveFile(fileParam
);
546 var ios
= Components
.classes
["@mozilla.org/network/io-service;1"]
547 .getService(Components
.interfaces
.nsIIOService
);
548 var uri
= ios
.newFileURI(file
);
549 openWindow(null, this.chromeURL
, "_blank",
550 "chrome,dialog=no,all" + this.getFeatures(cmdLine
),
552 cmdLine
.preventDefault
= true;
556 // Handle "? searchterm" for Windows Vista start menu integration
557 for (var i
= cmdLine
.length
- 1; i
>= 0; --i
) {
558 var param
= cmdLine
.getArgument(i
);
559 if (param
.match(/^\? /)) {
560 cmdLine
.removeArguments(i
, i
);
561 cmdLine
.preventDefault
= true;
563 searchParam
= param
.substr(2);
564 doSearch(searchParam
, cmdLine
);
570 helpInfo
: " -browser Open a browser window.\n",
572 /* nsIBrowserHandler */
575 var prefb
= Components
.classes
["@mozilla.org/preferences-service;1"]
576 .getService(nsIPrefBranch
);
578 var overridePage
= "";
579 var haveUpdateSession
= false;
581 let override
= needHomepageOverride(prefb
);
582 if (override
!= OVERRIDE_NONE
) {
583 // Setup the default search engine to about:home page.
584 AboutHomeUtils
.loadDefaultSearchEngine();
585 AboutHomeUtils
.loadSnippetsURL();
588 case OVERRIDE_NEW_PROFILE
:
590 overridePage
= Services
.urlFormatter
.formatURLPref("startup.homepage_welcome_url");
592 case OVERRIDE_NEW_MSTONE
:
593 // Existing profile, new milestone build.
596 // Check whether we have a session to restore. If we do, we assume
597 // that this is an "update" session.
598 var ss
= Components
.classes
["@mozilla.org/browser/sessionstartup;1"]
599 .getService(Components
.interfaces
.nsISessionStartup
);
600 haveUpdateSession
= ss
.doRestore();
601 overridePage
= Services
.urlFormatter
.formatURLPref("startup.homepage_override_url");
602 if (prefb
.prefHasUserValue("app.update.postupdate"))
603 overridePage
= getPostUpdateOverridePage(overridePage
);
608 // No need to override homepage, but update snippets url if the pref has
609 // been manually changed.
610 if (Services
.prefs
.prefHasUserValue(AboutHomeUtils
.SNIPPETS_URL_PREF
)) {
611 AboutHomeUtils
.loadSnippetsURL();
616 // formatURLPref might return "about:blank" if getting the pref fails
617 if (overridePage
== "about:blank")
622 var choice
= prefb
.getIntPref("browser.startup.page");
623 if (choice
== 1 || choice
== 3)
624 startPage
= this.startPage
;
627 startPage
= Components
.classes
["@mozilla.org/browser/global-history;2"]
628 .getService(nsIBrowserHistory
).lastPageVisited
;
630 Components
.utils
.reportError(e
);
633 if (startPage
== "about:blank")
636 // Only show the startPage if we're not restoring an update session.
637 if (overridePage
&& startPage
&& !haveUpdateSession
)
638 return overridePage
+ "|" + startPage
;
640 return overridePage
|| startPage
|| "about:blank";
644 var prefb
= Components
.classes
["@mozilla.org/preferences-service;1"]
645 .getService(nsIPrefBranch
);
647 var uri
= prefb
.getComplexValue("browser.startup.homepage",
648 nsIPrefLocalizedString
).data
;
651 prefb
.clearUserPref("browser.startup.homepage");
652 uri
= prefb
.getComplexValue("browser.startup.homepage",
653 nsIPrefLocalizedString
).data
;
658 count
= prefb
.getIntPref("browser.startup.homepage.count");
664 for (var i
= 1; i
< count
; ++i
) {
666 var page
= prefb
.getComplexValue("browser.startup.homepage." + i
,
667 nsIPrefLocalizedString
).data
;
679 getFeatures
: function bch_features(cmdLine
) {
680 if (this.mFeatures
=== null) {
684 var width
= cmdLine
.handleFlagWithParam("width", false);
685 var height
= cmdLine
.handleFlagWithParam("height", false);
688 this.mFeatures
+= ",width=" + width
;
690 this.mFeatures
+= ",height=" + height
;
696 return this.mFeatures
;
699 /* nsIContentHandler */
701 handleContent
: function bch_handleContent(contentType
, context
, request
) {
703 var webNavInfo
= Components
.classes
["@mozilla.org/webnavigation-info;1"]
704 .getService(nsIWebNavigationInfo
);
705 if (!webNavInfo
.isTypeSupported(contentType
, null)) {
706 throw NS_ERROR_WONT_HANDLE_CONTENT
;
709 throw NS_ERROR_WONT_HANDLE_CONTENT
;
712 request
.QueryInterface(nsIChannel
);
713 handURIToExistingBrowser(request
.URI
,
714 nsIBrowserDOMWindow
.OPEN_DEFAULTWINDOW
, null);
715 request
.cancel(NS_BINDING_ABORTED
);
718 /* nsICommandLineValidator */
719 validate
: function bch_validate(cmdLine
) {
720 // Other handlers may use osint so only handle the osint flag if the url
721 // flag is also present and the command line is valid.
722 var osintFlagIdx
= cmdLine
.findFlag("osint", false);
723 var urlFlagIdx
= cmdLine
.findFlag("url", false);
724 if (urlFlagIdx
> -1 && (osintFlagIdx
> -1 ||
725 cmdLine
.state
== nsICommandLine
.STATE_REMOTE_EXPLICIT
)) {
726 var urlParam
= cmdLine
.getArgument(urlFlagIdx
+ 1);
727 if (cmdLine
.length
!= urlFlagIdx
+ 2 || /firefoxurl:/.test(urlParam
))
728 throw NS_ERROR_ABORT
;
729 cmdLine
.handleFlag("osint", false)
733 var gBrowserContentHandler
= new nsBrowserContentHandler();
735 const CONTRACTID_PREFIX
= "@mozilla.org/uriloader/content-handler;1?type=";
737 function handURIToExistingBrowser(uri
, location
, cmdLine
)
739 if (!shouldLoadURI(uri
))
742 var navWin
= getMostRecentBrowserWindow();
744 // if we couldn't load it in an existing window, open a new one
745 openWindow(null, gBrowserContentHandler
.chromeURL
, "_blank",
746 "chrome,dialog=no,all" + gBrowserContentHandler
.getFeatures(cmdLine
),
751 var navNav
= navWin
.QueryInterface(nsIInterfaceRequestor
)
752 .getInterface(nsIWebNavigation
);
753 var rootItem
= navNav
.QueryInterface(nsIDocShellTreeItem
).rootTreeItem
;
754 var rootWin
= rootItem
.QueryInterface(nsIInterfaceRequestor
)
755 .getInterface(nsIDOMWindow
);
756 var bwin
= rootWin
.QueryInterface(nsIDOMChromeWindow
).browserDOMWindow
;
757 bwin
.openURI(uri
, null, location
,
758 nsIBrowserDOMWindow
.OPEN_EXTERNAL
);
761 function nsDefaultCommandLineHandler() {
764 nsDefaultCommandLineHandler
.prototype = {
765 classID
: Components
.ID("{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}"),
768 QueryInterface
: function dch_QI(iid
) {
769 if (!iid
.equals(nsISupports
) &&
770 !iid
.equals(nsICommandLineHandler
))
771 throw Components
.results
.NS_ERROR_NO_INTERFACE
;
776 // List of uri's that were passed via the command line without the app
777 // running and have already been handled. This is compared against uri's
778 // opened using DDE on Win32 so we only open one of the requests.
784 /* nsICommandLineHandler */
785 handle
: function dch_handle(cmdLine
) {
789 // If we don't have a profile selected yet (e.g. the Profile Manager is
790 // displayed) we will crash if we open an url and then select a profile. To
791 // prevent this handle all url command line flags and set the command line's
792 // preventDefault to true to prevent the display of the ui. The initial
793 // command line will be retained when nsAppRunner calls LaunchChild though
794 // urls launched after the initial launch will be lost.
795 if (!this._haveProfile
) {
797 // This will throw when a profile has not been selected.
798 var fl
= Components
.classes
["@mozilla.org/file/directory_service;1"]
799 .getService(Components
.interfaces
.nsIProperties
);
800 var dir
= fl
.get("ProfD", Components
.interfaces
.nsILocalFile
);
801 this._haveProfile
= true;
804 while ((ar
= cmdLine
.handleFlagWithParam("url", false))) { }
805 cmdLine
.preventDefault
= true;
812 while ((ar
= cmdLine
.handleFlagWithParam("url", false))) {
814 var uri
= resolveURIInternal(cmdLine
, ar
);
815 // count will never be greater than zero except on Win32.
816 var count
= this._handledURIs
.length
;
817 for (var i
= 0; i
< count
; ++i
) {
818 if (this._handledURIs
[i
].spec
== uri
.spec
) {
819 this._handledURIs
.splice(i
, 1);
821 cmdLine
.preventDefault
= true;
827 // The requestpending command line flag is only used on Win32.
828 if (cmdLine
.handleFlag("requestpending", false) &&
829 cmdLine
.state
== nsICommandLine
.STATE_INITIAL_LAUNCH
)
830 this._handledURIs
.push(uri
)
835 Components
.utils
.reportError(e
);
838 count
= cmdLine
.length
;
840 for (i
= 0; i
< count
; ++i
) {
841 var curarg
= cmdLine
.getArgument(i
);
842 if (curarg
.match(/^-/)) {
843 Components
.utils
.reportError("Warning: unrecognized command line flag " + curarg
+ "\n");
844 // To emulate the pre-nsICommandLine behavior, we ignore
845 // the argument after an unrecognized flag.
849 urilist
.push(resolveURIInternal(cmdLine
, curarg
));
852 Components
.utils
.reportError("Error opening URI '" + curarg
+ "' from the command line: " + e
+ "\n");
857 if (urilist
.length
) {
858 if (cmdLine
.state
!= nsICommandLine
.STATE_INITIAL_LAUNCH
&&
859 urilist
.length
== 1) {
860 // Try to find an existing window and load our URI into the
861 // current tab, new tab, or new window as prefs determine.
863 handURIToExistingBrowser(urilist
[0], nsIBrowserDOMWindow
.OPEN_DEFAULTWINDOW
, cmdLine
);
870 var URLlist
= urilist
.filter(shouldLoadURI
).map(function (u
) u
.spec
);
871 if (URLlist
.length
) {
872 openWindow(null, gBrowserContentHandler
.chromeURL
, "_blank",
873 "chrome,dialog=no,all" + gBrowserContentHandler
.getFeatures(cmdLine
),
878 else if (!cmdLine
.preventDefault
) {
879 // Passing defaultArgs, so use NO_EXTERNAL_URIS
880 openWindow(null, gBrowserContentHandler
.chromeURL
, "_blank",
881 "chrome,dialog=no,all" + gBrowserContentHandler
.getFeatures(cmdLine
),
882 gBrowserContentHandler
.defaultArgs
, NO_EXTERNAL_URIS
);
889 let AboutHomeUtils
= {
890 SNIPPETS_URL_PREF
: "browser.aboutHomeSnippets.updateUrl",
892 let aboutHomeURI
= Services
.io
.newURI("moz-safe-about:home", null, null);
893 let principal
= Components
.classes
["@mozilla.org/scriptsecuritymanager;1"].
894 getService(Components
.interfaces
.nsIScriptSecurityManager
).
895 getCodebasePrincipal(aboutHomeURI
);
896 let dsm
= Components
.classes
["@mozilla.org/dom/storagemanager;1"].
897 getService(Components
.interfaces
.nsIDOMStorageManager
);
898 return dsm
.getLocalStorageForPrincipal(principal
, "");
901 loadDefaultSearchEngine
: function AHU_loadDefaultSearchEngine()
903 let defaultEngine
= Services
.search
.originalDefaultEngine
;
904 let submission
= defaultEngine
.getSubmission("_searchTerms_");
905 if (submission
.postData
)
906 throw new Error("Home page does not support POST search engines.");
908 name
: defaultEngine
.name
909 , searchUrl
: submission
.uri
.spec
911 this._storage
.setItem("search-engine", JSON
.stringify(engine
));
914 loadSnippetsURL
: function AHU_loadSnippetsURL()
916 const STARTPAGE_VERSION
= 1;
917 let updateURL
= Services
.prefs
918 .getCharPref(this.SNIPPETS_URL_PREF
)
919 .replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION
);
920 updateURL
= Services
.urlFormatter
.formatURL(updateURL
);
921 this._storage
.setItem("snippets-update-url", updateURL
);
925 var components
= [nsBrowserContentHandler
, nsDefaultCommandLineHandler
];
926 var NSGetFactory
= XPCOMUtils
.generateNSGetFactory(components
);