| 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 | 8 |
| 10 let console; | 9 let messageManager = require("messageManager"); |
| 11 try | 10 let {forgetNode, getNodeById} = require("./nodeInfo"); |
| 11 |
| 12 messageManager.addMessageListener("ElemHideHelper:Preview", onTogglePreview); |
| 13 onShutdown.add(() => |
| 12 { | 14 { |
| 13 // Gecko 44+ | 15 messageManager.removeMessageListener("ElemHideHelper:Preview", onTogglePreview
); |
| 14 ({console} = Cu.import("resource://gre/modules/Console.jsm", {})); | 16 }); |
| 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 | |
| 33 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | |
| 34 | |
| 35 let processID = Services.appinfo.processID; | |
| 36 let maxNodeID = 0; | |
| 37 let nodes = new Map(); | |
| 38 | |
| 39 let name = "elemhidehelper"; | |
| 40 let actor = { | |
| 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 { | |
| 54 removeMessageListener("ElemHideHelper:Shutdown", onShutdown); | |
| 55 removeMessageListener("ElemHideHelper:GetNodeInfo", onGetNodeInfo); | |
| 56 removeMessageListener("ElemHideHelper:Preview", onTogglePreview); | |
| 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 | |
| 70 function onGetNodeInfo(message) | |
| 71 { | |
| 72 if (Cu.isCrossProcessWrapper(message.objects.element)) | |
| 73 return; | |
| 74 | |
| 75 let nodeInfo = getNodeInfo(message.objects.element); | |
| 76 nodeInfo.messageId = message.data; | |
| 77 sendAsyncMessage("ElemHideHelper:GetNodeInfo:Response", nodeInfo); | |
| 78 } | |
| 79 | 17 |
| 80 function onTogglePreview(message) | 18 function onTogglePreview(message) |
| 81 { | 19 { |
| 82 togglePreview(message.data.nodeID, message.data.stylesheetData); | 20 togglePreview(message.data.nodeID, message.data.stylesheetData); |
| 83 if (message.data.forgetNode) | 21 if (message.data.forgetNode) |
| 84 forgetNode(message.data.nodeID); | 22 forgetNode(message.data.nodeID); |
| 85 } | 23 } |
| 86 | 24 |
| 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) | |
| 102 { | |
| 103 let nodeData = getNodeData(node); | |
| 104 if (nodeData) | |
| 105 { | |
| 106 let nodeID = processID + "-" + (++maxNodeID); | |
| 107 nodes.set(nodeID, {document: node.ownerDocument, style: null}); | |
| 108 return { | |
| 109 host: node.ownerDocument.defaultView.location.hostname, | |
| 110 nodeData: nodeData, | |
| 111 nodeID: nodeID | |
| 112 }; | |
| 113 } | |
| 114 | |
| 115 return {}; | |
| 116 } | |
| 117 | |
| 118 function getNodeData(node, parentNode) | |
| 119 { | |
| 120 if (!node || node.nodeType != Ci.nsIDOMNode.ELEMENT_NODE) | |
| 121 return null; | |
| 122 | |
| 123 let result = {}; | |
| 124 result.tagName = {value: node.tagName, checked: false}; | |
| 125 | |
| 126 if (typeof parentNode != "undefined") | |
| 127 result.parentNode = parentNode; | |
| 128 else | |
| 129 result.parentNode = getNodeData(node.parentElement); | |
| 130 | |
| 131 let prevSibling = node.previousElementSibling; | |
| 132 result.prevSibling = getNodeData(prevSibling, result.parentNode); | |
| 133 | |
| 134 if (result.parentNode && !prevSibling) | |
| 135 result.firstChild = {checked: false}; | |
| 136 | |
| 137 let nextSibling = node.nextElementSibling; | |
| 138 if (result.parentNode && !nextSibling) | |
| 139 result.lastChild = {checked: false}; | |
| 140 | |
| 141 result.attributes = []; | |
| 142 for (let attribute of node.attributes) | |
| 143 { | |
| 144 let data = { | |
| 145 name: attribute.name, | |
| 146 value: attribute.value, | |
| 147 selected: attribute.value, | |
| 148 checked: false | |
| 149 }; | |
| 150 if (data.name == "id" || data.name == "class") | |
| 151 result.attributes.unshift(data); | |
| 152 else | |
| 153 result.attributes.push(data); | |
| 154 } | |
| 155 | |
| 156 if (result.attributes.length >= 2 && result.attributes[1].name == "id") | |
| 157 { | |
| 158 // Make sure ID attribute comes first | |
| 159 let tmp = result.attributes[1]; | |
| 160 result.attributes[1] = result.attributes[0]; | |
| 161 result.attributes[0] = tmp; | |
| 162 } | |
| 163 | |
| 164 result.customCSS = {selected: "", checked: false}; | |
| 165 return result; | |
| 166 } | |
| 167 | |
| 168 function togglePreview(nodeID, stylesheetData) | 25 function togglePreview(nodeID, stylesheetData) |
| 169 { | 26 { |
| 170 let context = nodes.get(nodeID); | 27 let context = getNodeById(nodeID); |
| 171 if (!context) | 28 if (!context) |
| 172 return; | 29 return; |
| 173 | 30 |
| 174 if (stylesheetData) | 31 if (stylesheetData) |
| 175 { | 32 { |
| 176 if (!context.style || !context.style.parentNode) | 33 if (!context.style || !context.style.parentNode) |
| 177 { | 34 { |
| 178 context.style = context.document.createElementNS( | 35 context.style = context.document.createElementNS( |
| 179 "http://www.w3.org/1999/xhtml", "style"); | 36 "http://www.w3.org/1999/xhtml", "style"); |
| 180 context.style.setAttribute("type", "text/css"); | 37 context.style.setAttribute("type", "text/css"); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 192 } | 49 } |
| 193 catch (e) | 50 catch (e) |
| 194 { | 51 { |
| 195 // If the window was closed (reloaded) we end up with a dead object | 52 // 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 | 53 // reference (https://bugzilla.mozilla.org/show_bug.cgi?id=695480). Just |
| 197 // forget this node then. | 54 // forget this node then. |
| 198 forgetNode(nodeID); | 55 forgetNode(nodeID); |
| 199 } | 56 } |
| 200 } | 57 } |
| 201 } | 58 } |
| 202 | |
| 203 function forgetNode(nodeID) | |
| 204 { | |
| 205 nodes.delete(nodeID); | |
| 206 } | |
| OLD | NEW |