| 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 |