|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const Cc = Components.classes; |
|
6 const Ci = Components.interfaces; |
|
7 const Cu = Components.utils; |
|
8 const Cr = Components.results; |
|
9 |
|
10 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
11 Cu.import("resource://gre/modules/Services.jsm"); |
|
12 |
|
13 function MetroUIUtils() { |
|
14 } |
|
15 |
|
16 const URLElements = { |
|
17 "a": "href", |
|
18 "applet": ["archive", "code", "codebase"], |
|
19 "area": "href", |
|
20 "audio": "src", |
|
21 "base": "href", |
|
22 "blockquote": ["cite"], |
|
23 "body": "background", |
|
24 "button": "formaction", |
|
25 "command": "icon", |
|
26 "del": ["cite"], |
|
27 "embed": "src", |
|
28 "form": "action", |
|
29 "frame": ["longdesc", "src"], |
|
30 "iframe": ["longdesc", "src"], |
|
31 "img": ["longdesc", "src"], |
|
32 "input": ["formaction", "src"], |
|
33 "ins": ["cite"], |
|
34 "link": "href", |
|
35 "object": ["archive", "codebase", "data"], |
|
36 "q": ["cite"], |
|
37 "script": "src", |
|
38 "source": "src", |
|
39 }; |
|
40 |
|
41 MetroUIUtils.prototype = { |
|
42 classID : Components.ID("e4626085-17f7-4068-a225-66c1acc0485c"), |
|
43 QueryInterface : XPCOMUtils.generateQI([Ci.nsIMetroUIUtils]), |
|
44 /** |
|
45 * Loads the specified panel in the browser. |
|
46 * @ param aPanelId The identifier of the pane to load |
|
47 */ |
|
48 showPanel: function(aPanelId) { |
|
49 let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); |
|
50 browserWin.PanelUI.show(aPanelId); |
|
51 }, |
|
52 |
|
53 /** |
|
54 * Determines if the browser has selected content |
|
55 */ |
|
56 get hasSelectedContent() { |
|
57 try { |
|
58 let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); |
|
59 let tabBrowser = browserWin.getBrowser(); |
|
60 if (!browserWin || !tabBrowser || !tabBrowser.contentWindow) { |
|
61 return false; |
|
62 } |
|
63 |
|
64 let sel = tabBrowser.contentWindow.getSelection(); |
|
65 return sel && sel.toString(); |
|
66 } catch(e) { |
|
67 return false; |
|
68 } |
|
69 }, |
|
70 |
|
71 /** |
|
72 * Obtains the current page title |
|
73 */ |
|
74 get currentPageTitle() { |
|
75 let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); |
|
76 if (!browserWin || !browserWin.content || !browserWin.content.document) { |
|
77 throw Cr.NS_ERROR_FAILURE; |
|
78 } |
|
79 return browserWin.content.document.title || ""; |
|
80 }, |
|
81 |
|
82 /** |
|
83 * Obtains the current page URI |
|
84 */ |
|
85 get currentPageURI() { |
|
86 let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); |
|
87 if (!browserWin || !browserWin.content || !browserWin.content.document) { |
|
88 throw Cr.NS_ERROR_FAILURE; |
|
89 } |
|
90 return browserWin.content.document.URL || ""; |
|
91 }, |
|
92 |
|
93 /** |
|
94 * Determines the text that should be shared |
|
95 */ |
|
96 get shareText() { |
|
97 let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); |
|
98 let tabBrowser = browserWin.getBrowser(); |
|
99 if (browserWin && tabBrowser && tabBrowser.contentWindow) { |
|
100 let sel = tabBrowser.contentWindow.getSelection(); |
|
101 if (sel && sel.rangeCount) |
|
102 return sel; |
|
103 } |
|
104 |
|
105 throw Cr.NS_ERROR_FAILURE; |
|
106 }, |
|
107 |
|
108 /** |
|
109 * Replaces the node's attribute value to be a fully qualified URL |
|
110 */ |
|
111 _expandAttribute : function(ioService, doc, node, attrName) { |
|
112 let attrValue = node.getAttribute(attrName); |
|
113 if (!attrValue) |
|
114 return; |
|
115 |
|
116 try { |
|
117 let uri = ioService.newURI(attrValue, null, doc.baseURIObject); |
|
118 node.setAttribute(attrName, uri.spec); |
|
119 } catch (e) { |
|
120 } |
|
121 }, |
|
122 |
|
123 /* |
|
124 * Replaces all attribute values in 'n' which contain URLs recursiely |
|
125 * to fully qualified URLs. |
|
126 */ |
|
127 _expandURLs: function(doc, n) { |
|
128 let ioService = Cc["@mozilla.org/network/io-service;1"]. |
|
129 getService(Ci.nsIIOService); |
|
130 for (let i = 0; i < n.children.length; i++) { |
|
131 let child = n.children[i]; |
|
132 let childTagName = child.tagName.toLowerCase(); |
|
133 |
|
134 // Iterate through all known tags which can contain URLs. A tag either |
|
135 // contains a single attribute name or an array of attribute names. |
|
136 for (let tagName in URLElements) { |
|
137 if (tagName === childTagName) { |
|
138 if (URLElements[tagName] instanceof Array) { |
|
139 URLElements[tagName].forEach(function(attrName) { |
|
140 this._expandAttribute(ioService ,doc, child, attrName); |
|
141 }, this); |
|
142 } else { |
|
143 this._expandAttribute(ioService ,doc, child, URLElements[tagName]); |
|
144 } |
|
145 } |
|
146 } |
|
147 |
|
148 this._expandURLs(doc, child); |
|
149 } |
|
150 }, |
|
151 |
|
152 /** |
|
153 * Determines the HTML that should be shared |
|
154 */ |
|
155 get shareHTML() { |
|
156 let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); |
|
157 let tabBrowser = browserWin.getBrowser(); |
|
158 let sel; |
|
159 if (browserWin && tabBrowser && tabBrowser.contentWindow && |
|
160 (sel = tabBrowser.contentWindow.getSelection()) && sel.rangeCount) { |
|
161 let div = tabBrowser.contentWindow.document.createElement("DIV"); |
|
162 for (let i = 0; i < sel.rangeCount; i++) { |
|
163 let contents = sel.getRangeAt(i).cloneContents(true); |
|
164 div.appendChild(contents); |
|
165 } |
|
166 this._expandURLs(tabBrowser.contentWindow.document, div); |
|
167 return div.outerHTML; |
|
168 } |
|
169 |
|
170 throw Cr.NS_ERROR_FAILURE; |
|
171 } |
|
172 }; |
|
173 |
|
174 var component = [MetroUIUtils]; |
|
175 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component); |