Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/. */
5 const Cc = Components.classes;
6 const Ci = Components.interfaces;
7 const Cu = Components.utils;
8 const Cr = Components.results;
10 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
11 Cu.import("resource://gre/modules/Services.jsm");
13 function MetroUIUtils() {
14 }
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 };
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 },
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 }
64 let sel = tabBrowser.contentWindow.getSelection();
65 return sel && sel.toString();
66 } catch(e) {
67 return false;
68 }
69 },
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 },
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 },
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 }
105 throw Cr.NS_ERROR_FAILURE;
106 },
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;
116 try {
117 let uri = ioService.newURI(attrValue, null, doc.baseURIObject);
118 node.setAttribute(attrName, uri.spec);
119 } catch (e) {
120 }
121 },
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();
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 }
148 this._expandURLs(doc, child);
149 }
150 },
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 }
170 throw Cr.NS_ERROR_FAILURE;
171 }
172 };
174 var component = [MetroUIUtils];
175 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);