michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: this.EXPORTED_SYMBOLS = [ "BrowserUtils" ]; michael@0: michael@0: const {interfaces: Ci, utils: Cu, classes: Cc} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: this.BrowserUtils = { michael@0: michael@0: /** michael@0: * urlSecurityCheck: JavaScript wrapper for checkLoadURIWithPrincipal michael@0: * and checkLoadURIStrWithPrincipal. michael@0: * If |aPrincipal| is not allowed to link to |aURL|, this function throws with michael@0: * an error message. michael@0: * michael@0: * @param aURL michael@0: * The URL a page has linked to. This could be passed either as a string michael@0: * or as a nsIURI object. michael@0: * @param aPrincipal michael@0: * The principal of the document from which aURL came. michael@0: * @param aFlags michael@0: * Flags to be passed to checkLoadURIStr. If undefined, michael@0: * nsIScriptSecurityManager.STANDARD will be passed. michael@0: */ michael@0: urlSecurityCheck: function(aURL, aPrincipal, aFlags) { michael@0: var secMan = Services.scriptSecurityManager; michael@0: if (aFlags === undefined) { michael@0: aFlags = secMan.STANDARD; michael@0: } michael@0: michael@0: try { michael@0: if (aURL instanceof Ci.nsIURI) michael@0: secMan.checkLoadURIWithPrincipal(aPrincipal, aURL, aFlags); michael@0: else michael@0: secMan.checkLoadURIStrWithPrincipal(aPrincipal, aURL, aFlags); michael@0: } catch (e) { michael@0: let principalStr = ""; michael@0: try { michael@0: principalStr = " from " + aPrincipal.URI.spec; michael@0: } michael@0: catch(e2) { } michael@0: michael@0: throw "Load of " + aURL + principalStr + " denied."; michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Constructs a new URI, using nsIIOService. michael@0: * @param aURL The URI spec. michael@0: * @param aOriginCharset The charset of the URI. michael@0: * @param aBaseURI Base URI to resolve aURL, or null. michael@0: * @return an nsIURI object based on aURL. michael@0: */ michael@0: makeURI: function(aURL, aOriginCharset, aBaseURI) { michael@0: return Services.io.newURI(aURL, aOriginCharset, aBaseURI); michael@0: }, michael@0: michael@0: makeFileURI: function(aFile) { michael@0: return Services.io.newFileURI(aFile); michael@0: }, michael@0: michael@0: /** michael@0: * Return the current focus element and window. If the current focus michael@0: * is in a content process, then this function returns CPOWs michael@0: * (cross-process object wrappers) that refer to the focused michael@0: * items. Note that calling this function synchronously contacts the michael@0: * content process, which may block for a long time. michael@0: * michael@0: * @param document The document in question. michael@0: * @return [focusedElement, focusedWindow] michael@0: */ michael@0: getFocusSync: function(document) { michael@0: let elt = document.commandDispatcher.focusedElement; michael@0: var window = document.commandDispatcher.focusedWindow; michael@0: michael@0: const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; michael@0: if (elt instanceof window.XULElement && michael@0: elt.localName == "browser" && michael@0: elt.namespaceURI == XUL_NS && michael@0: elt.getAttribute("remote")) { michael@0: [elt, window] = elt.syncHandler.getFocusedElementAndWindow(); michael@0: } michael@0: michael@0: return [elt, window]; michael@0: }, michael@0: michael@0: /** michael@0: * For a given DOM element, returns its position in "screen" michael@0: * coordinates. In a content process, the coordinates returned will michael@0: * be relative to the left/top of the tab. In the chrome process, michael@0: * the coordinates are relative to the user's screen. michael@0: */ michael@0: getElementBoundingScreenRect: function(aElement) { michael@0: let rect = aElement.getBoundingClientRect(); michael@0: let window = aElement.ownerDocument.defaultView; michael@0: michael@0: // We need to compensate for any iframes that might shift things michael@0: // over. We also need to compensate for zooming. michael@0: let fullZoom = window.getInterface(Ci.nsIDOMWindowUtils).fullZoom; michael@0: rect = { michael@0: left: (rect.left + window.mozInnerScreenX) * fullZoom, michael@0: top: (rect.top + window.mozInnerScreenY) * fullZoom, michael@0: width: rect.width * fullZoom, michael@0: height: rect.height * fullZoom michael@0: }; michael@0: michael@0: return rect; michael@0: }, michael@0: michael@0: };