browser/base/content/utilityOverlay.js

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

michael@0 1 # -*- Mode: javascript; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 5
michael@0 6 // Services = object with smart getters for common XPCOM services
michael@0 7 Components.utils.import("resource://gre/modules/Services.jsm");
michael@0 8 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 9 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
michael@0 10 Components.utils.import("resource:///modules/RecentWindow.jsm");
michael@0 11
michael@0 12 XPCOMUtils.defineLazyGetter(this, "BROWSER_NEW_TAB_URL", function () {
michael@0 13 const PREF = "browser.newtab.url";
michael@0 14
michael@0 15 function getNewTabPageURL() {
michael@0 16 if (!Services.prefs.prefHasUserValue(PREF)) {
michael@0 17 if (PrivateBrowsingUtils.isWindowPrivate(window) &&
michael@0 18 !PrivateBrowsingUtils.permanentPrivateBrowsing)
michael@0 19 return "about:privatebrowsing";
michael@0 20 }
michael@0 21 let url = Services.prefs.getComplexValue(PREF, Ci.nsISupportsString).data;
michael@0 22 return url || "about:blank";
michael@0 23 }
michael@0 24
michael@0 25 function update() {
michael@0 26 BROWSER_NEW_TAB_URL = getNewTabPageURL();
michael@0 27 }
michael@0 28
michael@0 29 Services.prefs.addObserver(PREF, update, false);
michael@0 30
michael@0 31 addEventListener("unload", function onUnload() {
michael@0 32 removeEventListener("unload", onUnload);
michael@0 33 Services.prefs.removeObserver(PREF, update);
michael@0 34 });
michael@0 35
michael@0 36 return getNewTabPageURL();
michael@0 37 });
michael@0 38
michael@0 39 var TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
michael@0 40
michael@0 41 var gBidiUI = false;
michael@0 42
michael@0 43 /**
michael@0 44 * Determines whether the given url is considered a special URL for new tabs.
michael@0 45 */
michael@0 46 function isBlankPageURL(aURL) {
michael@0 47 return aURL == "about:blank" || aURL == BROWSER_NEW_TAB_URL;
michael@0 48 }
michael@0 49
michael@0 50 function getBrowserURL()
michael@0 51 {
michael@0 52 return "chrome://browser/content/browser.xul";
michael@0 53 }
michael@0 54
michael@0 55 function getTopWin(skipPopups) {
michael@0 56 // If this is called in a browser window, use that window regardless of
michael@0 57 // whether it's the frontmost window, since commands can be executed in
michael@0 58 // background windows (bug 626148).
michael@0 59 if (top.document.documentElement.getAttribute("windowtype") == "navigator:browser" &&
michael@0 60 (!skipPopups || top.toolbar.visible))
michael@0 61 return top;
michael@0 62
michael@0 63 let isPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
michael@0 64 return RecentWindow.getMostRecentBrowserWindow({private: isPrivate,
michael@0 65 allowPopups: !skipPopups});
michael@0 66 }
michael@0 67
michael@0 68 function openTopWin(url) {
michael@0 69 /* deprecated */
michael@0 70 openUILinkIn(url, "current");
michael@0 71 }
michael@0 72
michael@0 73 function getBoolPref(prefname, def)
michael@0 74 {
michael@0 75 try {
michael@0 76 return Services.prefs.getBoolPref(prefname);
michael@0 77 }
michael@0 78 catch(er) {
michael@0 79 return def;
michael@0 80 }
michael@0 81 }
michael@0 82
michael@0 83 /* openUILink handles clicks on UI elements that cause URLs to load.
michael@0 84 *
michael@0 85 * As the third argument, you may pass an object with the same properties as
michael@0 86 * accepted by openUILinkIn, plus "ignoreButton" and "ignoreAlt".
michael@0 87 */
michael@0 88 function openUILink(url, event, aIgnoreButton, aIgnoreAlt, aAllowThirdPartyFixup,
michael@0 89 aPostData, aReferrerURI) {
michael@0 90 let params;
michael@0 91
michael@0 92 if (aIgnoreButton && typeof aIgnoreButton == "object") {
michael@0 93 params = aIgnoreButton;
michael@0 94
michael@0 95 // don't forward "ignoreButton" and "ignoreAlt" to openUILinkIn
michael@0 96 aIgnoreButton = params.ignoreButton;
michael@0 97 aIgnoreAlt = params.ignoreAlt;
michael@0 98 delete params.ignoreButton;
michael@0 99 delete params.ignoreAlt;
michael@0 100 } else {
michael@0 101 params = {
michael@0 102 allowThirdPartyFixup: aAllowThirdPartyFixup,
michael@0 103 postData: aPostData,
michael@0 104 referrerURI: aReferrerURI,
michael@0 105 initiatingDoc: event ? event.target.ownerDocument : null
michael@0 106 };
michael@0 107 }
michael@0 108
michael@0 109 let where = whereToOpenLink(event, aIgnoreButton, aIgnoreAlt);
michael@0 110 openUILinkIn(url, where, params);
michael@0 111 }
michael@0 112
michael@0 113
michael@0 114 /* whereToOpenLink() looks at an event to decide where to open a link.
michael@0 115 *
michael@0 116 * The event may be a mouse event (click, double-click, middle-click) or keypress event (enter).
michael@0 117 *
michael@0 118 * On Windows, the modifiers are:
michael@0 119 * Ctrl new tab, selected
michael@0 120 * Shift new window
michael@0 121 * Ctrl+Shift new tab, in background
michael@0 122 * Alt save
michael@0 123 *
michael@0 124 * Middle-clicking is the same as Ctrl+clicking (it opens a new tab).
michael@0 125 *
michael@0 126 * Exceptions:
michael@0 127 * - Alt is ignored for menu items selected using the keyboard so you don't accidentally save stuff.
michael@0 128 * (Currently, the Alt isn't sent here at all for menu items, but that will change in bug 126189.)
michael@0 129 * - Alt is hard to use in context menus, because pressing Alt closes the menu.
michael@0 130 * - Alt can't be used on the bookmarks toolbar because Alt is used for "treat this as something draggable".
michael@0 131 * - The button is ignored for the middle-click-paste-URL feature, since it's always a middle-click.
michael@0 132 */
michael@0 133 function whereToOpenLink( e, ignoreButton, ignoreAlt )
michael@0 134 {
michael@0 135 // This method must treat a null event like a left click without modifier keys (i.e.
michael@0 136 // e = { shiftKey:false, ctrlKey:false, metaKey:false, altKey:false, button:0 })
michael@0 137 // for compatibility purposes.
michael@0 138 if (!e)
michael@0 139 return "current";
michael@0 140
michael@0 141 var shift = e.shiftKey;
michael@0 142 var ctrl = e.ctrlKey;
michael@0 143 var meta = e.metaKey;
michael@0 144 var alt = e.altKey && !ignoreAlt;
michael@0 145
michael@0 146 // ignoreButton allows "middle-click paste" to use function without always opening in a new window.
michael@0 147 var middle = !ignoreButton && e.button == 1;
michael@0 148 var middleUsesTabs = getBoolPref("browser.tabs.opentabfor.middleclick", true);
michael@0 149
michael@0 150 // Don't do anything special with right-mouse clicks. They're probably clicks on context menu items.
michael@0 151
michael@0 152 #ifdef XP_MACOSX
michael@0 153 if (meta || (middle && middleUsesTabs))
michael@0 154 #else
michael@0 155 if (ctrl || (middle && middleUsesTabs))
michael@0 156 #endif
michael@0 157 return shift ? "tabshifted" : "tab";
michael@0 158
michael@0 159 if (alt && getBoolPref("browser.altClickSave", false))
michael@0 160 return "save";
michael@0 161
michael@0 162 if (shift || (middle && !middleUsesTabs))
michael@0 163 return "window";
michael@0 164
michael@0 165 return "current";
michael@0 166 }
michael@0 167
michael@0 168 /* openUILinkIn opens a URL in a place specified by the parameter |where|.
michael@0 169 *
michael@0 170 * |where| can be:
michael@0 171 * "current" current tab (if there aren't any browser windows, then in a new window instead)
michael@0 172 * "tab" new tab (if there aren't any browser windows, then in a new window instead)
michael@0 173 * "tabshifted" same as "tab" but in background if default is to select new tabs, and vice versa
michael@0 174 * "window" new window
michael@0 175 * "save" save to disk (with no filename hint!)
michael@0 176 *
michael@0 177 * aAllowThirdPartyFixup controls whether third party services such as Google's
michael@0 178 * I Feel Lucky are allowed to interpret this URL. This parameter may be
michael@0 179 * undefined, which is treated as false.
michael@0 180 *
michael@0 181 * Instead of aAllowThirdPartyFixup, you may also pass an object with any of
michael@0 182 * these properties:
michael@0 183 * allowThirdPartyFixup (boolean)
michael@0 184 * postData (nsIInputStream)
michael@0 185 * referrerURI (nsIURI)
michael@0 186 * relatedToCurrent (boolean)
michael@0 187 * skipTabAnimation (boolean)
michael@0 188 */
michael@0 189 function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI) {
michael@0 190 var params;
michael@0 191
michael@0 192 if (arguments.length == 3 && typeof arguments[2] == "object") {
michael@0 193 params = aAllowThirdPartyFixup;
michael@0 194 } else {
michael@0 195 params = {
michael@0 196 allowThirdPartyFixup: aAllowThirdPartyFixup,
michael@0 197 postData: aPostData,
michael@0 198 referrerURI: aReferrerURI
michael@0 199 };
michael@0 200 }
michael@0 201
michael@0 202 params.fromChrome = true;
michael@0 203
michael@0 204 openLinkIn(url, where, params);
michael@0 205 }
michael@0 206
michael@0 207 function openLinkIn(url, where, params) {
michael@0 208 if (!where || !url)
michael@0 209 return;
michael@0 210
michael@0 211 var aFromChrome = params.fromChrome;
michael@0 212 var aAllowThirdPartyFixup = params.allowThirdPartyFixup;
michael@0 213 var aPostData = params.postData;
michael@0 214 var aCharset = params.charset;
michael@0 215 var aReferrerURI = params.referrerURI;
michael@0 216 var aRelatedToCurrent = params.relatedToCurrent;
michael@0 217 var aDisableMCB = params.disableMCB;
michael@0 218 var aInBackground = params.inBackground;
michael@0 219 var aDisallowInheritPrincipal = params.disallowInheritPrincipal;
michael@0 220 var aInitiatingDoc = params.initiatingDoc;
michael@0 221 var aIsPrivate = params.private;
michael@0 222 var aSkipTabAnimation = params.skipTabAnimation;
michael@0 223
michael@0 224 if (where == "save") {
michael@0 225 if (!aInitiatingDoc) {
michael@0 226 Components.utils.reportError("openUILink/openLinkIn was called with " +
michael@0 227 "where == 'save' but without initiatingDoc. See bug 814264.");
michael@0 228 return;
michael@0 229 }
michael@0 230 saveURL(url, null, null, true, null, aReferrerURI, aInitiatingDoc);
michael@0 231 return;
michael@0 232 }
michael@0 233 const Cc = Components.classes;
michael@0 234 const Ci = Components.interfaces;
michael@0 235
michael@0 236 var w = getTopWin();
michael@0 237 if ((where == "tab" || where == "tabshifted") &&
michael@0 238 w && !w.toolbar.visible) {
michael@0 239 w = getTopWin(true);
michael@0 240 aRelatedToCurrent = false;
michael@0 241 }
michael@0 242
michael@0 243 if (!w || where == "window") {
michael@0 244 var sa = Cc["@mozilla.org/supports-array;1"].
michael@0 245 createInstance(Ci.nsISupportsArray);
michael@0 246
michael@0 247 var wuri = Cc["@mozilla.org/supports-string;1"].
michael@0 248 createInstance(Ci.nsISupportsString);
michael@0 249 wuri.data = url;
michael@0 250
michael@0 251 let charset = null;
michael@0 252 if (aCharset) {
michael@0 253 charset = Cc["@mozilla.org/supports-string;1"]
michael@0 254 .createInstance(Ci.nsISupportsString);
michael@0 255 charset.data = "charset=" + aCharset;
michael@0 256 }
michael@0 257
michael@0 258 var allowThirdPartyFixupSupports = Cc["@mozilla.org/supports-PRBool;1"].
michael@0 259 createInstance(Ci.nsISupportsPRBool);
michael@0 260 allowThirdPartyFixupSupports.data = aAllowThirdPartyFixup;
michael@0 261
michael@0 262 sa.AppendElement(wuri);
michael@0 263 sa.AppendElement(charset);
michael@0 264 sa.AppendElement(aReferrerURI);
michael@0 265 sa.AppendElement(aPostData);
michael@0 266 sa.AppendElement(allowThirdPartyFixupSupports);
michael@0 267
michael@0 268 let features = "chrome,dialog=no,all";
michael@0 269 if (aIsPrivate) {
michael@0 270 features += ",private";
michael@0 271 }
michael@0 272
michael@0 273 Services.ww.openWindow(w || window, getBrowserURL(), null, features, sa);
michael@0 274 return;
michael@0 275 }
michael@0 276
michael@0 277 let loadInBackground = where == "current" ? false : aInBackground;
michael@0 278 if (loadInBackground == null) {
michael@0 279 loadInBackground = aFromChrome ?
michael@0 280 false :
michael@0 281 getBoolPref("browser.tabs.loadInBackground");
michael@0 282 }
michael@0 283
michael@0 284 if (where == "current" && w.gBrowser.selectedTab.pinned) {
michael@0 285 try {
michael@0 286 let uriObj = Services.io.newURI(url, null, null);
michael@0 287 if (!uriObj.schemeIs("javascript") &&
michael@0 288 w.gBrowser.currentURI.host != uriObj.host) {
michael@0 289 where = "tab";
michael@0 290 loadInBackground = false;
michael@0 291 }
michael@0 292 } catch (err) {
michael@0 293 where = "tab";
michael@0 294 loadInBackground = false;
michael@0 295 }
michael@0 296 }
michael@0 297
michael@0 298 // Raise the target window before loading the URI, since loading it may
michael@0 299 // result in a new frontmost window (e.g. "javascript:window.open('');").
michael@0 300 w.focus();
michael@0 301
michael@0 302 switch (where) {
michael@0 303 case "current":
michael@0 304 let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
michael@0 305 if (aAllowThirdPartyFixup) {
michael@0 306 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
michael@0 307 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
michael@0 308 }
michael@0 309 if (aDisallowInheritPrincipal)
michael@0 310 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
michael@0 311 w.gBrowser.loadURIWithFlags(url, flags, aReferrerURI, null, aPostData);
michael@0 312 break;
michael@0 313 case "tabshifted":
michael@0 314 loadInBackground = !loadInBackground;
michael@0 315 // fall through
michael@0 316 case "tab":
michael@0 317 let browser = w.gBrowser;
michael@0 318 browser.loadOneTab(url, {
michael@0 319 referrerURI: aReferrerURI,
michael@0 320 charset: aCharset,
michael@0 321 postData: aPostData,
michael@0 322 inBackground: loadInBackground,
michael@0 323 allowThirdPartyFixup: aAllowThirdPartyFixup,
michael@0 324 relatedToCurrent: aRelatedToCurrent,
michael@0 325 skipAnimation: aSkipTabAnimation,
michael@0 326 disableMCB: aDisableMCB});
michael@0 327 break;
michael@0 328 }
michael@0 329
michael@0 330 w.gBrowser.selectedBrowser.focus();
michael@0 331
michael@0 332 if (!loadInBackground && w.isBlankPageURL(url))
michael@0 333 w.focusAndSelectUrlBar();
michael@0 334 }
michael@0 335
michael@0 336 // Used as an onclick handler for UI elements with link-like behavior.
michael@0 337 // e.g. onclick="checkForMiddleClick(this, event);"
michael@0 338 function checkForMiddleClick(node, event) {
michael@0 339 // We should be using the disabled property here instead of the attribute,
michael@0 340 // but some elements that this function is used with don't support it (e.g.
michael@0 341 // menuitem).
michael@0 342 if (node.getAttribute("disabled") == "true")
michael@0 343 return; // Do nothing
michael@0 344
michael@0 345 if (event.button == 1) {
michael@0 346 /* Execute the node's oncommand or command.
michael@0 347 *
michael@0 348 * XXX: we should use node.oncommand(event) once bug 246720 is fixed.
michael@0 349 */
michael@0 350 var target = node.hasAttribute("oncommand") ? node :
michael@0 351 node.ownerDocument.getElementById(node.getAttribute("command"));
michael@0 352 var fn = new Function("event", target.getAttribute("oncommand"));
michael@0 353 fn.call(target, event);
michael@0 354
michael@0 355 // If the middle-click was on part of a menu, close the menu.
michael@0 356 // (Menus close automatically with left-click but not with middle-click.)
michael@0 357 closeMenus(event.target);
michael@0 358 }
michael@0 359 }
michael@0 360
michael@0 361 // Closes all popups that are ancestors of the node.
michael@0 362 function closeMenus(node)
michael@0 363 {
michael@0 364 if ("tagName" in node) {
michael@0 365 if (node.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
michael@0 366 && (node.tagName == "menupopup" || node.tagName == "popup"))
michael@0 367 node.hidePopup();
michael@0 368
michael@0 369 closeMenus(node.parentNode);
michael@0 370 }
michael@0 371 }
michael@0 372
michael@0 373 // Gather all descendent text under given document node.
michael@0 374 function gatherTextUnder ( root )
michael@0 375 {
michael@0 376 var text = "";
michael@0 377 var node = root.firstChild;
michael@0 378 var depth = 1;
michael@0 379 while ( node && depth > 0 ) {
michael@0 380 // See if this node is text.
michael@0 381 if ( node.nodeType == Node.TEXT_NODE ) {
michael@0 382 // Add this text to our collection.
michael@0 383 text += " " + node.data;
michael@0 384 } else if ( node instanceof HTMLImageElement) {
michael@0 385 // If it has an "alt" attribute, add that.
michael@0 386 var altText = node.getAttribute( "alt" );
michael@0 387 if ( altText && altText != "" ) {
michael@0 388 text += " " + altText;
michael@0 389 }
michael@0 390 }
michael@0 391 // Find next node to test.
michael@0 392 // First, see if this node has children.
michael@0 393 if ( node.hasChildNodes() ) {
michael@0 394 // Go to first child.
michael@0 395 node = node.firstChild;
michael@0 396 depth++;
michael@0 397 } else {
michael@0 398 // No children, try next sibling (or parent next sibling).
michael@0 399 while ( depth > 0 && !node.nextSibling ) {
michael@0 400 node = node.parentNode;
michael@0 401 depth--;
michael@0 402 }
michael@0 403 if ( node.nextSibling ) {
michael@0 404 node = node.nextSibling;
michael@0 405 }
michael@0 406 }
michael@0 407 }
michael@0 408 // Strip leading and tailing whitespace.
michael@0 409 text = text.trim();
michael@0 410 // Compress remaining whitespace.
michael@0 411 text = text.replace( /\s+/g, " " );
michael@0 412 return text;
michael@0 413 }
michael@0 414
michael@0 415 function getShellService()
michael@0 416 {
michael@0 417 var shell = null;
michael@0 418 try {
michael@0 419 shell = Components.classes["@mozilla.org/browser/shell-service;1"]
michael@0 420 .getService(Components.interfaces.nsIShellService);
michael@0 421 } catch (e) {
michael@0 422 }
michael@0 423 return shell;
michael@0 424 }
michael@0 425
michael@0 426 function isBidiEnabled() {
michael@0 427 // first check the pref.
michael@0 428 if (getBoolPref("bidi.browser.ui", false))
michael@0 429 return true;
michael@0 430
michael@0 431 // then check intl.uidirection.<locale>
michael@0 432 var chromeReg = Components.classes["@mozilla.org/chrome/chrome-registry;1"].
michael@0 433 getService(Components.interfaces.nsIXULChromeRegistry);
michael@0 434 if (chromeReg.isLocaleRTL("global"))
michael@0 435 return true;
michael@0 436
michael@0 437 // now see if the system locale is an RTL one.
michael@0 438 var rv = false;
michael@0 439
michael@0 440 try {
michael@0 441 var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
michael@0 442 .getService(Components.interfaces.nsILocaleService);
michael@0 443 var systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE").substr(0,3);
michael@0 444
michael@0 445 switch (systemLocale) {
michael@0 446 case "ar-":
michael@0 447 case "he-":
michael@0 448 case "fa-":
michael@0 449 case "ug-":
michael@0 450 case "ur-":
michael@0 451 case "syr":
michael@0 452 rv = true;
michael@0 453 Services.prefs.setBoolPref("bidi.browser.ui", true);
michael@0 454 }
michael@0 455 } catch (e) {}
michael@0 456
michael@0 457 return rv;
michael@0 458 }
michael@0 459
michael@0 460 function openAboutDialog() {
michael@0 461 var enumerator = Services.wm.getEnumerator("Browser:About");
michael@0 462 while (enumerator.hasMoreElements()) {
michael@0 463 // Only open one about window (Bug 599573)
michael@0 464 let win = enumerator.getNext();
michael@0 465 if (win.closed) {
michael@0 466 continue;
michael@0 467 }
michael@0 468 win.focus();
michael@0 469 return;
michael@0 470 }
michael@0 471
michael@0 472 #ifdef XP_WIN
michael@0 473 var features = "chrome,centerscreen,dependent";
michael@0 474 #elifdef XP_MACOSX
michael@0 475 var features = "chrome,resizable=no,minimizable=no";
michael@0 476 #else
michael@0 477 var features = "chrome,centerscreen,dependent,dialog=no";
michael@0 478 #endif
michael@0 479 window.openDialog("chrome://browser/content/aboutDialog.xul", "", features);
michael@0 480 }
michael@0 481
michael@0 482 function openPreferences(paneID, extraArgs)
michael@0 483 {
michael@0 484 function switchToAdvancedSubPane(doc) {
michael@0 485 if (extraArgs && extraArgs["advancedTab"]) {
michael@0 486 let advancedPaneTabs = doc.getElementById("advancedPrefs");
michael@0 487 advancedPaneTabs.selectedTab = doc.getElementById(extraArgs["advancedTab"]);
michael@0 488 }
michael@0 489 }
michael@0 490
michael@0 491 if (getBoolPref("browser.preferences.inContent")) {
michael@0 492 let win = Services.wm.getMostRecentWindow("navigator:browser");
michael@0 493 if (!win) {
michael@0 494 return;
michael@0 495 }
michael@0 496
michael@0 497 let newLoad = !win.switchToTabHavingURI("about:preferences", true);
michael@0 498 let browser = win.gBrowser.selectedBrowser;
michael@0 499
michael@0 500 function switchToPane() {
michael@0 501 if (paneID) {
michael@0 502 browser.contentWindow.selectCategory(paneID);
michael@0 503 }
michael@0 504 switchToAdvancedSubPane(browser.contentDocument);
michael@0 505 }
michael@0 506
michael@0 507 if (newLoad) {
michael@0 508 browser.addEventListener("load", function onload() {
michael@0 509 browser.removeEventListener("load", onload, true);
michael@0 510 switchToPane();
michael@0 511 }, true);
michael@0 512 } else {
michael@0 513 switchToPane();
michael@0 514 }
michael@0 515 } else {
michael@0 516 var instantApply = getBoolPref("browser.preferences.instantApply", false);
michael@0 517 var features = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal");
michael@0 518
michael@0 519 var win = Services.wm.getMostRecentWindow("Browser:Preferences");
michael@0 520 if (win) {
michael@0 521 win.focus();
michael@0 522 if (paneID) {
michael@0 523 var pane = win.document.getElementById(paneID);
michael@0 524 win.document.documentElement.showPane(pane);
michael@0 525 }
michael@0 526
michael@0 527 switchToAdvancedSubPane(win.document);
michael@0 528 } else {
michael@0 529 openDialog("chrome://browser/content/preferences/preferences.xul",
michael@0 530 "Preferences", features, paneID, extraArgs);
michael@0 531 }
michael@0 532 }
michael@0 533 }
michael@0 534
michael@0 535 function openAdvancedPreferences(tabID)
michael@0 536 {
michael@0 537 openPreferences("paneAdvanced", { "advancedTab" : tabID });
michael@0 538 }
michael@0 539
michael@0 540 /**
michael@0 541 * Opens the troubleshooting information (about:support) page for this version
michael@0 542 * of the application.
michael@0 543 */
michael@0 544 function openTroubleshootingPage()
michael@0 545 {
michael@0 546 openUILinkIn("about:support", "tab");
michael@0 547 }
michael@0 548
michael@0 549 #ifdef MOZ_SERVICES_HEALTHREPORT
michael@0 550 /**
michael@0 551 * Opens the troubleshooting information (about:support) page for this version
michael@0 552 * of the application.
michael@0 553 */
michael@0 554 function openHealthReport()
michael@0 555 {
michael@0 556 openUILinkIn("about:healthreport", "tab");
michael@0 557 }
michael@0 558 #endif
michael@0 559
michael@0 560 /**
michael@0 561 * Opens the feedback page for this version of the application.
michael@0 562 */
michael@0 563 function openFeedbackPage()
michael@0 564 {
michael@0 565 var url = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
michael@0 566 .getService(Components.interfaces.nsIURLFormatter)
michael@0 567 .formatURLPref("app.feedback.baseURL");
michael@0 568 openUILinkIn(url, "tab");
michael@0 569 }
michael@0 570
michael@0 571 function openTourPage()
michael@0 572 {
michael@0 573 let scope = {}
michael@0 574 Components.utils.import("resource:///modules/UITour.jsm", scope);
michael@0 575 openUILinkIn(scope.UITour.url, "tab");
michael@0 576 }
michael@0 577
michael@0 578 function buildHelpMenu()
michael@0 579 {
michael@0 580 // Enable/disable the "Report Web Forgery" menu item.
michael@0 581 if (typeof gSafeBrowsing != "undefined")
michael@0 582 gSafeBrowsing.setReportPhishingMenu();
michael@0 583 }
michael@0 584
michael@0 585 function isElementVisible(aElement)
michael@0 586 {
michael@0 587 if (!aElement)
michael@0 588 return false;
michael@0 589
michael@0 590 // If aElement or a direct or indirect parent is hidden or collapsed,
michael@0 591 // height, width or both will be 0.
michael@0 592 var bo = aElement.boxObject;
michael@0 593 return (bo.height > 0 && bo.width > 0);
michael@0 594 }
michael@0 595
michael@0 596 function makeURLAbsolute(aBase, aUrl)
michael@0 597 {
michael@0 598 // Note: makeURI() will throw if aUri is not a valid URI
michael@0 599 return makeURI(aUrl, null, makeURI(aBase)).spec;
michael@0 600 }
michael@0 601
michael@0 602 /**
michael@0 603 * openNewTabWith: opens a new tab with the given URL.
michael@0 604 *
michael@0 605 * @param aURL
michael@0 606 * The URL to open (as a string).
michael@0 607 * @param aDocument
michael@0 608 * Note this parameter is now ignored. There is no security check & no
michael@0 609 * referrer header derived from aDocument (null case).
michael@0 610 * @param aPostData
michael@0 611 * Form POST data, or null.
michael@0 612 * @param aEvent
michael@0 613 * The triggering event (for the purpose of determining whether to open
michael@0 614 * in the background), or null.
michael@0 615 * @param aAllowThirdPartyFixup
michael@0 616 * If true, then we allow the URL text to be sent to third party services
michael@0 617 * (e.g., Google's I Feel Lucky) for interpretation. This parameter may
michael@0 618 * be undefined in which case it is treated as false.
michael@0 619 * @param [optional] aReferrer
michael@0 620 * This will be used as the referrer. There will be no security check.
michael@0 621 */
michael@0 622 function openNewTabWith(aURL, aDocument, aPostData, aEvent,
michael@0 623 aAllowThirdPartyFixup, aReferrer) {
michael@0 624
michael@0 625 // As in openNewWindowWith(), we want to pass the charset of the
michael@0 626 // current document over to a new tab.
michael@0 627 let originCharset = null;
michael@0 628 if (document.documentElement.getAttribute("windowtype") == "navigator:browser")
michael@0 629 originCharset = gBrowser.selectedBrowser.characterSet;
michael@0 630
michael@0 631 openLinkIn(aURL, aEvent && aEvent.shiftKey ? "tabshifted" : "tab",
michael@0 632 { charset: originCharset,
michael@0 633 postData: aPostData,
michael@0 634 allowThirdPartyFixup: aAllowThirdPartyFixup,
michael@0 635 referrerURI: aReferrer });
michael@0 636 }
michael@0 637
michael@0 638 /**
michael@0 639 * @param aDocument
michael@0 640 * Note this parameter is ignored. See openNewTabWith()
michael@0 641 */
michael@0 642 function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup, aReferrer) {
michael@0 643 // Extract the current charset menu setting from the current document and
michael@0 644 // use it to initialize the new browser window...
michael@0 645 let originCharset = null;
michael@0 646 if (document.documentElement.getAttribute("windowtype") == "navigator:browser")
michael@0 647 originCharset = gBrowser.selectedBrowser.characterSet;
michael@0 648
michael@0 649 openLinkIn(aURL, "window",
michael@0 650 { charset: originCharset,
michael@0 651 postData: aPostData,
michael@0 652 allowThirdPartyFixup: aAllowThirdPartyFixup,
michael@0 653 referrerURI: aReferrer });
michael@0 654 }
michael@0 655
michael@0 656 // aCalledFromModal is optional
michael@0 657 function openHelpLink(aHelpTopic, aCalledFromModal, aWhere) {
michael@0 658 var url = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
michael@0 659 .getService(Components.interfaces.nsIURLFormatter)
michael@0 660 .formatURLPref("app.support.baseURL");
michael@0 661 url += aHelpTopic;
michael@0 662
michael@0 663 var where = aWhere;
michael@0 664 if (!aWhere)
michael@0 665 where = aCalledFromModal ? "window" : "tab";
michael@0 666
michael@0 667 openUILinkIn(url, where);
michael@0 668 }
michael@0 669
michael@0 670 function openPrefsHelp() {
michael@0 671 // non-instant apply prefwindows are usually modal, so we can't open in the topmost window,
michael@0 672 // since its probably behind the window.
michael@0 673 var instantApply = getBoolPref("browser.preferences.instantApply");
michael@0 674
michael@0 675 var helpTopic = document.getElementsByTagName("prefwindow")[0].currentPane.helpTopic;
michael@0 676 openHelpLink(helpTopic, !instantApply);
michael@0 677 }
michael@0 678
michael@0 679 function trimURL(aURL) {
michael@0 680 // This function must not modify the given URL such that calling
michael@0 681 // nsIURIFixup::createFixupURI with the result will produce a different URI.
michael@0 682 return aURL /* remove single trailing slash for http/https/ftp URLs */
michael@0 683 .replace(/^((?:http|https|ftp):\/\/[^/]+)\/$/, "$1")
michael@0 684 /* remove http:// unless the host starts with "ftp\d*\." or contains "@" */
michael@0 685 .replace(/^http:\/\/((?!ftp\d*\.)[^\/@]+(?:\/|$))/, "$1");
michael@0 686 }

mercurial