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: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: const Cr = Components.results; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: function MetroUIUtils() { michael@0: } michael@0: michael@0: const URLElements = { michael@0: "a": "href", michael@0: "applet": ["archive", "code", "codebase"], michael@0: "area": "href", michael@0: "audio": "src", michael@0: "base": "href", michael@0: "blockquote": ["cite"], michael@0: "body": "background", michael@0: "button": "formaction", michael@0: "command": "icon", michael@0: "del": ["cite"], michael@0: "embed": "src", michael@0: "form": "action", michael@0: "frame": ["longdesc", "src"], michael@0: "iframe": ["longdesc", "src"], michael@0: "img": ["longdesc", "src"], michael@0: "input": ["formaction", "src"], michael@0: "ins": ["cite"], michael@0: "link": "href", michael@0: "object": ["archive", "codebase", "data"], michael@0: "q": ["cite"], michael@0: "script": "src", michael@0: "source": "src", michael@0: }; michael@0: michael@0: MetroUIUtils.prototype = { michael@0: classID : Components.ID("e4626085-17f7-4068-a225-66c1acc0485c"), michael@0: QueryInterface : XPCOMUtils.generateQI([Ci.nsIMetroUIUtils]), michael@0: /** michael@0: * Loads the specified panel in the browser. michael@0: * @ param aPanelId The identifier of the pane to load michael@0: */ michael@0: showPanel: function(aPanelId) { michael@0: let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); michael@0: browserWin.PanelUI.show(aPanelId); michael@0: }, michael@0: michael@0: /** michael@0: * Determines if the browser has selected content michael@0: */ michael@0: get hasSelectedContent() { michael@0: try { michael@0: let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); michael@0: let tabBrowser = browserWin.getBrowser(); michael@0: if (!browserWin || !tabBrowser || !tabBrowser.contentWindow) { michael@0: return false; michael@0: } michael@0: michael@0: let sel = tabBrowser.contentWindow.getSelection(); michael@0: return sel && sel.toString(); michael@0: } catch(e) { michael@0: return false; michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Obtains the current page title michael@0: */ michael@0: get currentPageTitle() { michael@0: let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); michael@0: if (!browserWin || !browserWin.content || !browserWin.content.document) { michael@0: throw Cr.NS_ERROR_FAILURE; michael@0: } michael@0: return browserWin.content.document.title || ""; michael@0: }, michael@0: michael@0: /** michael@0: * Obtains the current page URI michael@0: */ michael@0: get currentPageURI() { michael@0: let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); michael@0: if (!browserWin || !browserWin.content || !browserWin.content.document) { michael@0: throw Cr.NS_ERROR_FAILURE; michael@0: } michael@0: return browserWin.content.document.URL || ""; michael@0: }, michael@0: michael@0: /** michael@0: * Determines the text that should be shared michael@0: */ michael@0: get shareText() { michael@0: let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); michael@0: let tabBrowser = browserWin.getBrowser(); michael@0: if (browserWin && tabBrowser && tabBrowser.contentWindow) { michael@0: let sel = tabBrowser.contentWindow.getSelection(); michael@0: if (sel && sel.rangeCount) michael@0: return sel; michael@0: } michael@0: michael@0: throw Cr.NS_ERROR_FAILURE; michael@0: }, michael@0: michael@0: /** michael@0: * Replaces the node's attribute value to be a fully qualified URL michael@0: */ michael@0: _expandAttribute : function(ioService, doc, node, attrName) { michael@0: let attrValue = node.getAttribute(attrName); michael@0: if (!attrValue) michael@0: return; michael@0: michael@0: try { michael@0: let uri = ioService.newURI(attrValue, null, doc.baseURIObject); michael@0: node.setAttribute(attrName, uri.spec); michael@0: } catch (e) { michael@0: } michael@0: }, michael@0: michael@0: /* michael@0: * Replaces all attribute values in 'n' which contain URLs recursiely michael@0: * to fully qualified URLs. michael@0: */ michael@0: _expandURLs: function(doc, n) { michael@0: let ioService = Cc["@mozilla.org/network/io-service;1"]. michael@0: getService(Ci.nsIIOService); michael@0: for (let i = 0; i < n.children.length; i++) { michael@0: let child = n.children[i]; michael@0: let childTagName = child.tagName.toLowerCase(); michael@0: michael@0: // Iterate through all known tags which can contain URLs. A tag either michael@0: // contains a single attribute name or an array of attribute names. michael@0: for (let tagName in URLElements) { michael@0: if (tagName === childTagName) { michael@0: if (URLElements[tagName] instanceof Array) { michael@0: URLElements[tagName].forEach(function(attrName) { michael@0: this._expandAttribute(ioService ,doc, child, attrName); michael@0: }, this); michael@0: } else { michael@0: this._expandAttribute(ioService ,doc, child, URLElements[tagName]); michael@0: } michael@0: } michael@0: } michael@0: michael@0: this._expandURLs(doc, child); michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Determines the HTML that should be shared michael@0: */ michael@0: get shareHTML() { michael@0: let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); michael@0: let tabBrowser = browserWin.getBrowser(); michael@0: let sel; michael@0: if (browserWin && tabBrowser && tabBrowser.contentWindow && michael@0: (sel = tabBrowser.contentWindow.getSelection()) && sel.rangeCount) { michael@0: let div = tabBrowser.contentWindow.document.createElement("DIV"); michael@0: for (let i = 0; i < sel.rangeCount; i++) { michael@0: let contents = sel.getRangeAt(i).cloneContents(true); michael@0: div.appendChild(contents); michael@0: } michael@0: this._expandURLs(tabBrowser.contentWindow.document, div); michael@0: return div.outerHTML; michael@0: } michael@0: michael@0: throw Cr.NS_ERROR_FAILURE; michael@0: } michael@0: }; michael@0: michael@0: var component = [MetroUIUtils]; michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);