OLD | NEW |
1 /* | 1 /* |
2 * This Source Code is subject to the terms of the Mozilla Public License | 2 * This Source Code is subject to the terms of the Mozilla Public License |
3 * version 2.0 (the "License"). You can obtain a copy of the License at | 3 * version 2.0 (the "License"). You can obtain a copy of the License at |
4 * http://mozilla.org/MPL/2.0/. | 4 * http://mozilla.org/MPL/2.0/. |
5 */ | 5 */ |
6 | 6 |
7 const Ci = Components.interfaces; | 7 "use strict"; |
8 const Cu = Components.utils; | |
9 | |
10 let console; | |
11 try | |
12 { | |
13 // Gecko 44+ | |
14 ({console} = Cu.import("resource://gre/modules/Console.jsm", {})); | |
15 } | |
16 catch (e) | |
17 { | |
18 ({console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {})); | |
19 } | |
20 | |
21 let DebuggerServer; | |
22 try | |
23 { | |
24 // Firefox 44+ | |
25 let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); | |
26 ({DebuggerServer} = require("devtools/server/main")); | |
27 } | |
28 catch (e) | |
29 { | |
30 ({DebuggerServer} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm"
, {})); | |
31 } | |
32 | 8 |
33 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | 9 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); |
34 | 10 |
| 11 let messageManager = require("messageManager"); |
| 12 |
35 let processID = Services.appinfo.processID; | 13 let processID = Services.appinfo.processID; |
36 let maxNodeID = 0; | 14 let maxNodeID = 0; |
37 let nodes = new Map(); | 15 let nodes = new Map(); |
38 | 16 |
39 let name = "elemhidehelper"; | 17 messageManager.addMessageListener("ElemHideHelper:GetNodeInfo", onGetNodeInfo); |
40 let actor = { | 18 onShutdown.add(() => |
41 constructorFun: Actor, | |
42 constructorName: name, | |
43 name: name | |
44 }; | |
45 | |
46 addMessageListener("ElemHideHelper:Shutdown", onShutdown); | |
47 addMessageListener("ElemHideHelper:GetNodeInfo", onGetNodeInfo); | |
48 addMessageListener("ElemHideHelper:Preview", onTogglePreview); | |
49 | |
50 DebuggerServer.addTabActor(actor, name); | |
51 | |
52 function onShutdown() | |
53 { | 19 { |
54 removeMessageListener("ElemHideHelper:Shutdown", onShutdown); | 20 messageManager.removeMessageListener("ElemHideHelper:GetNodeInfo", |
55 removeMessageListener("ElemHideHelper:GetNodeInfo", onGetNodeInfo); | 21 onGetNodeInfo); |
56 removeMessageListener("ElemHideHelper:Preview", onTogglePreview); | 22 }); |
57 | |
58 try | |
59 { | |
60 DebuggerServer.removeTabActor(actor); | |
61 } | |
62 catch (e) | |
63 { | |
64 // The call above will throw in the content process despite succeeding, | |
65 // see https://bugzilla.mozilla.org/show_bug.cgi?id=1189780. | |
66 Cu.reportError(e); | |
67 } | |
68 } | |
69 | 23 |
70 function onGetNodeInfo(message) | 24 function onGetNodeInfo(message) |
71 { | 25 { |
72 if (Cu.isCrossProcessWrapper(message.objects.element)) | 26 if (Cu.isCrossProcessWrapper(message.objects.element)) |
73 return; | 27 return; |
74 | 28 |
75 let nodeInfo = getNodeInfo(message.objects.element); | 29 let nodeInfo = getNodeInfo(message.objects.element); |
76 nodeInfo.messageId = message.data; | 30 nodeInfo.messageId = message.data; |
77 sendAsyncMessage("ElemHideHelper:GetNodeInfo:Response", nodeInfo); | 31 messageManager.sendAsyncMessage("ElemHideHelper:GetNodeInfo:Response", |
| 32 nodeInfo); |
78 } | 33 } |
79 | 34 |
80 function onTogglePreview(message) | |
81 { | |
82 togglePreview(message.data.nodeID, message.data.stylesheetData); | |
83 if (message.data.forgetNode) | |
84 forgetNode(message.data.nodeID); | |
85 } | |
86 | |
87 function Actor(connection, tabActor) | |
88 { | |
89 } | |
90 | |
91 Actor.prototype = { | |
92 requestTypes: { | |
93 nodeinfo: function(request, connection) | |
94 { | |
95 let nodeActor = connection.getActor(request.nodeActor); | |
96 return getNodeInfo(nodeActor ? nodeActor.rawNode: null); | |
97 } | |
98 } | |
99 }; | |
100 | |
101 function getNodeInfo(node) | 35 function getNodeInfo(node) |
102 { | 36 { |
103 let nodeData = getNodeData(node); | 37 let nodeData = getNodeData(node); |
104 if (nodeData) | 38 if (nodeData) |
105 { | 39 { |
106 let nodeID = processID + "-" + (++maxNodeID); | 40 let nodeID = processID + "-" + (++maxNodeID); |
107 nodes.set(nodeID, {document: node.ownerDocument, style: null}); | 41 nodes.set(nodeID, {document: node.ownerDocument, style: null}); |
108 return { | 42 return { |
109 host: node.ownerDocument.defaultView.location.hostname, | 43 host: node.ownerDocument.defaultView.location.hostname, |
110 nodeData: nodeData, | 44 nodeData: nodeData, |
111 nodeID: nodeID | 45 nodeID: nodeID |
112 }; | 46 }; |
113 } | 47 } |
114 | 48 |
115 return {}; | 49 return {}; |
116 } | 50 } |
| 51 exports.getNodeInfo = getNodeInfo; |
| 52 |
| 53 function getNodeById(nodeId) |
| 54 { |
| 55 return nodes.get(nodeId); |
| 56 } |
| 57 exports.getNodeById = getNodeById; |
117 | 58 |
118 function getNodeData(node, parentNode) | 59 function getNodeData(node, parentNode) |
119 { | 60 { |
120 if (!node || node.nodeType != Ci.nsIDOMNode.ELEMENT_NODE) | 61 if (!node || node.nodeType != Ci.nsIDOMNode.ELEMENT_NODE) |
121 return null; | 62 return null; |
122 | 63 |
123 let result = {}; | 64 let result = {}; |
124 result.tagName = {value: node.tagName, checked: false}; | 65 result.tagName = {value: node.tagName, checked: false}; |
125 | 66 |
126 if (typeof parentNode != "undefined") | 67 if (typeof parentNode != "undefined") |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 // Make sure ID attribute comes first | 99 // Make sure ID attribute comes first |
159 let tmp = result.attributes[1]; | 100 let tmp = result.attributes[1]; |
160 result.attributes[1] = result.attributes[0]; | 101 result.attributes[1] = result.attributes[0]; |
161 result.attributes[0] = tmp; | 102 result.attributes[0] = tmp; |
162 } | 103 } |
163 | 104 |
164 result.customCSS = {selected: "", checked: false}; | 105 result.customCSS = {selected: "", checked: false}; |
165 return result; | 106 return result; |
166 } | 107 } |
167 | 108 |
168 function togglePreview(nodeID, stylesheetData) | |
169 { | |
170 let context = nodes.get(nodeID); | |
171 if (!context) | |
172 return; | |
173 | |
174 if (stylesheetData) | |
175 { | |
176 if (!context.style || !context.style.parentNode) | |
177 { | |
178 context.style = context.document.createElementNS( | |
179 "http://www.w3.org/1999/xhtml", "style"); | |
180 context.style.setAttribute("type", "text/css"); | |
181 context.document.documentElement.appendChild(context.style); | |
182 } | |
183 context.style.textContent = stylesheetData; | |
184 } | |
185 else | |
186 { | |
187 try | |
188 { | |
189 if (context.style && context.style.parentNode) | |
190 context.style.parentNode.removeChild(context.style); | |
191 context.style = null; | |
192 } | |
193 catch (e) | |
194 { | |
195 // If the window was closed (reloaded) we end up with a dead object | |
196 // reference (https://bugzilla.mozilla.org/show_bug.cgi?id=695480). Just | |
197 // forget this node then. | |
198 forgetNode(nodeID); | |
199 } | |
200 } | |
201 } | |
202 | |
203 function forgetNode(nodeID) | 109 function forgetNode(nodeID) |
204 { | 110 { |
205 nodes.delete(nodeID); | 111 nodes.delete(nodeID); |
206 } | 112 } |
| 113 exports.forgetNode = forgetNode; |
OLD | NEW |