 Issue 29366552:
  Issue 2879 - Make "view source" command work again  (Closed) 
  Base URL: https://hg.adblockplus.org/elemhidehelper
    
  
    Issue 29366552:
  Issue 2879 - Make "view source" command work again  (Closed) 
  Base URL: https://hg.adblockplus.org/elemhidehelper| Left: | ||
| Right: | 
| 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 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | 7 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | 
| 8 | 8 | 
| 9 let {Prefs} = require("prefs"); | 9 let {Prefs} = require("prefs"); | 
| 10 | 10 | 
| 11 let messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"] | 11 let messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"] | 
| 12 .getService(Ci.nsIMessageListenerManager) | 12 .getService(Ci.nsIMessageListenerManager) | 
| 13 .QueryInterface(Ci.nsIMessageBroadcaster); | 13 .QueryInterface(Ci.nsIMessageBroadcaster); | 
| 14 | 14 | 
| 15 // To be replaced when selection starts | 15 // To be replaced when selection starts | 
| 16 function E(id) {return null;} | 16 function E(id) {return null;} | 
| 17 | 17 | 
| 18 messageManager.addMessageListener("ElemHideHelper:Response", | |
| 19 messageResponse); | |
| 18 messageManager.addMessageListener("ElemHideHelper:SelectionStarted", | 20 messageManager.addMessageListener("ElemHideHelper:SelectionStarted", | 
| 19 selectionStarted); | 21 selectionStarted); | 
| 20 messageManager.addMessageListener("ElemHideHelper:SelectionSucceeded", | 22 messageManager.addMessageListener("ElemHideHelper:SelectionSucceeded", | 
| 21 selectionSucceeded); | 23 selectionSucceeded); | 
| 22 messageManager.addMessageListener("ElemHideHelper:SelectionStopped", | 24 messageManager.addMessageListener("ElemHideHelper:SelectionStopped", | 
| 23 selectionStopped); | 25 selectionStopped); | 
| 24 onShutdown.add(() => | 26 onShutdown.add(() => | 
| 25 { | 27 { | 
| 28 messageManager.removeMessageListener("ElemHideHelper:Response", | |
| 29 messageResponse); | |
| 26 messageManager.removeMessageListener("ElemHideHelper:SelectionStarted", | 30 messageManager.removeMessageListener("ElemHideHelper:SelectionStarted", | 
| 27 selectionStarted); | 31 selectionStarted); | 
| 28 messageManager.removeMessageListener("ElemHideHelper:SelectionSucceeded", | 32 messageManager.removeMessageListener("ElemHideHelper:SelectionSucceeded", | 
| 29 selectionSucceeded); | 33 selectionSucceeded); | 
| 30 messageManager.removeMessageListener("ElemHideHelper:SelectionStopped", | 34 messageManager.removeMessageListener("ElemHideHelper:SelectionStopped", | 
| 31 selectionStopped); | 35 selectionStopped); | 
| 32 | 36 | 
| 33 selectionStopped(); | 37 selectionStopped(); | 
| 34 }); | 38 }); | 
| 35 | 39 | 
| 40 let maxMessageId = 0; | |
| 41 let messageCallbacks = new Map(); | |
| 42 | |
| 43 function sendMessageWithResponse(messageName, data, callback) | |
| 44 { | |
| 45 if (!data) | |
| 46 data = {}; | |
| 47 data.messageId = ++maxMessageId; | |
| 48 messageCallbacks.set(data.messageId, callback); | |
| 49 messageManager.broadcastAsyncMessage(messageName, data); | |
| 50 } | |
| 51 | |
| 52 function messageResponse(message) | |
| 53 { | |
| 54 let callback = messageCallbacks.get(message.data.messageId); | |
| 55 if (callback) | |
| 56 { | |
| 57 messageCallbacks.delete(message.data.messageId); | |
| 58 callback(message.data); | |
| 59 } | |
| 60 } | |
| 61 | |
| 36 function selectionStarted(message) | 62 function selectionStarted(message) | 
| 37 { | 63 { | 
| 38 Aardvark.selectionStarted(); | 64 Aardvark.selectionStarted(); | 
| 39 } | 65 } | 
| 40 | 66 | 
| 41 function selectionSucceeded(message) | 67 function selectionSucceeded(message) | 
| 42 { | 68 { | 
| 43 Aardvark.selectionSucceeded(message.data); | 69 Aardvark.selectionSucceeded(message.data); | 
| 44 } | 70 } | 
| 45 | 71 | 
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 "wider", | 292 "wider", | 
| 267 "narrower", | 293 "narrower", | 
| 268 "lock", | 294 "lock", | 
| 269 "quit", | 295 "quit", | 
| 270 "blinkElement", | 296 "blinkElement", | 
| 271 "viewSource", | 297 "viewSource", | 
| 272 "viewSourceWindow", | 298 "viewSourceWindow", | 
| 273 "showMenu" | 299 "showMenu" | 
| 274 ], | 300 ], | 
| 275 | 301 | 
| 276 viewSource: function(elem) | 302 viewSource: function() | 
| 277 { | 303 { | 
| 278 if (!elem) | 304 let sourceBox = E("ehh-viewsource"); | 
| 279 return false; | |
| 280 | |
| 281 var sourceBox = E("ehh-viewsource"); | |
| 282 if (sourceBox.state == "open") | 305 if (sourceBox.state == "open") | 
| 283 { | 306 { | 
| 284 sourceBox.hidePopup(); | 307 sourceBox.hidePopup(); | 
| 285 return true; | 308 return true; | 
| 286 } | 309 } | 
| 287 sourceBox.hidePopup(); | |
| 288 | 310 | 
| 289 while (sourceBox.firstElementChild) | 311 sendMessageWithResponse("ElemHideHelper:SerializeSelected", null, data => | 
| 290 sourceBox.removeChild(sourceBox.firstElementChild); | 312 { | 
| 291 this.getOuterHtmlFormatted(elem, sourceBox); | 313 sourceBox.hidePopup(); | 
| 292 | 314 | 
| 293 let anchor = this.window.document.documentElement; | 315 while (sourceBox.firstElementChild) | 
| 294 let x = this.mouseX; | 316 sourceBox.removeChild(sourceBox.firstElementChild); | 
| 295 let y = this.mouseY; | 317 this.getOuterHtmlFormatted(data.serialized, sourceBox); | 
| 296 this.viewSourceTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer ); | 318 | 
| 297 this.viewSourceTimer.initWithCallback(function() | 319 let anchor = this.window.document.documentElement; | 
| 298 { | 320 let x = this.mouseX; | 
| 299 sourceBox.showPopup(anchor, x, y, "tooltip", "topleft", "topleft"); | 321 let y = this.mouseY; | 
| 300 Aardvark.viewSourceTimer = null; | 322 this.viewSourceTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITim er); | 
| 301 }, 500, Ci.nsITimer.TYPE_ONE_SHOT); | 323 this.viewSourceTimer.initWithCallback(function() | 
| 324 { | |
| 325 sourceBox.showPopup(anchor, x, y, "tooltip", "topleft", "topleft"); | |
| 326 Aardvark.viewSourceTimer = null; | |
| 327 }, 500, Ci.nsITimer.TYPE_ONE_SHOT); | |
| 328 }); | |
| 302 return true; | 329 return true; | 
| 303 }, | 330 }, | 
| 304 | 331 | 
| 305 viewSourceWindow: function(elem) | 332 viewSourceWindow: function(elem) | 
| 306 { | 333 { | 
| 307 if (!elem) | 334 if (!elem) | 
| 308 return false; | 335 return false; | 
| 309 | 336 | 
| 310 if (Services.vc.compare(Services.appinfo.platformVersion, "43.0") >= 0) | 337 if (Services.vc.compare(Services.appinfo.platformVersion, "43.0") >= 0) | 
| 311 { | 338 { | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 331 "chrome://global/content/viewPartialSource.xul", | 358 "chrome://global/content/viewPartialSource.xul", | 
| 332 "_blank", "scrollbars,resizable,chrome,dialog=no", | 359 "_blank", "scrollbars,resizable,chrome,dialog=no", | 
| 333 null, null, selection, "selection" | 360 null, null, selection, "selection" | 
| 334 ); | 361 ); | 
| 335 } | 362 } | 
| 336 return true; | 363 return true; | 
| 337 }, | 364 }, | 
| 338 | 365 | 
| 339 getOuterHtmlFormatted: function(node, container) | 366 getOuterHtmlFormatted: function(node, container) | 
| 340 { | 367 { | 
| 341 var type = null; | 368 let type = node.type; | 
| 342 switch (node.nodeType) | 369 if (type == "element") | 
| 343 { | 370 { | 
| 344 case node.ELEMENT_NODE: | 371 let box = this.window.document.createElement("vbox"); | 
| 345 var box = this.window.document.createElement("vbox"); | 372 box.className = "elementBox"; | 
| 346 box.className = "elementBox"; | |
| 347 | 373 | 
| 348 var startTag = this.window.document.createElement("hbox"); | 374 let startTag = this.window.document.createElement("hbox"); | 
| 349 startTag.className = "elementStartTag"; | 375 startTag.className = "elementStartTag"; | 
| 350 if (!node.firstChild) | 376 if (!node.children.length) | 
| 351 startTag.className += " elementEndTag"; | 377 startTag.className += " elementEndTag"; | 
| 352 | 378 | 
| 353 this.appendDescription(startTag, "<", null); | 379 this.appendDescription(startTag, "<", null); | 
| 354 this.appendDescription(startTag, node.tagName, "tagName"); | 380 this.appendDescription(startTag, node.tagName, "tagName"); | 
| 355 | 381 | 
| 356 for (var i = 0; i < node.attributes.length; i++) | 382 for (let {name, value} of node.attributes) | 
| 383 { | |
| 384 this.appendDescription(startTag, name, "attrName"); | |
| 385 if (value != "") | |
| 357 { | 386 { | 
| 358 var attr = node.attributes[i]; | 387 this.appendDescription(startTag, "=", null); | 
| 359 this.appendDescription(startTag, attr.name, "attrName"); | 388 this.appendDescription(startTag, '"' + value.replace(/"/, """) + '"', "attrValue"); | 
| 
saroyanm
2016/12/05 17:51:47
Detail: exceeds 80 characters.
 
Wladimir Palant
2016/12/08 13:11:29
Done.
 | |
| 360 if (attr.value != "") | |
| 361 { | |
| 362 this.appendDescription(startTag, "=", null); | |
| 363 this.appendDescription(startTag, '"' + attr.value.replace(/"/, "&quo t;") + '"', "attrValue"); | |
| 364 } | |
| 365 } | 389 } | 
| 390 } | |
| 366 | 391 | 
| 367 this.appendDescription(startTag, node.firstChild ? ">" : " />", null); | 392 this.appendDescription(startTag, node.children.length ? ">" : " />", null) ; | 
| 368 box.appendChild(startTag); | 393 box.appendChild(startTag); | 
| 369 | 394 | 
| 370 if (node.firstChild) | 395 if (node.children.length) | 
| 371 { | 396 { | 
| 372 for (var child = node.firstChild; child; child = child.nextSibling) | 397 for (let child of node.children) | 
| 373 this.getOuterHtmlFormatted(child, box); | 398 this.getOuterHtmlFormatted(child, box); | 
| 374 | 399 | 
| 375 var endTag = this.window.document.createElement("hbox"); | 400 let endTag = this.window.document.createElement("hbox"); | 
| 376 endTag.className = "elementEndTag"; | 401 endTag.className = "elementEndTag"; | 
| 377 this.appendDescription(endTag, "<", null); | 402 this.appendDescription(endTag, "<", null); | 
| 378 this.appendDescription(endTag, "/" + node.tagName, "tagName"); | 403 this.appendDescription(endTag, "/" + node.tagName, "tagName"); | 
| 379 this.appendDescription(endTag, ">", null); | 404 this.appendDescription(endTag, ">", null); | 
| 380 box.appendChild(endTag); | 405 box.appendChild(endTag); | 
| 381 } | 406 } | 
| 382 container.appendChild(box); | 407 container.appendChild(box); | 
| 383 return; | 408 return; | 
| 384 | |
| 385 case node.TEXT_NODE: | |
| 386 type = "text"; | |
| 387 break; | |
| 388 case node.CDATA_SECTION_NODE: | |
| 389 type = "cdata"; | |
| 390 break; | |
| 391 case node.COMMENT_NODE: | |
| 392 type = "comment"; | |
| 393 break; | |
| 394 default: | |
| 395 return; | |
| 396 } | 409 } | 
| 397 | 410 | 
| 398 var text = node.nodeValue.replace(/\r/g, '').replace(/^\s+/, '').replace(/\s +$/, ''); | 411 let text = node.text.replace(/\r/g, "").trim(); | 
| 399 if (text == "") | 412 if (text == "") | 
| 400 return; | 413 return; | 
| 401 | 414 | 
| 402 if (type != "cdata") | 415 text = text.replace(/&/g, "&") | 
| 403 { | 416 .replace(/</g, "<") | 
| 404 text = text.replace(/&/g, "&") | 417 .replace(/>/g, ">") | 
| 405 .replace(/</g, "<") | 418 .replace(/\t/g, " "); | 
| 406 .replace(/>/g, ">"); | 419 if (type == "comment") | 
| 407 } | |
| 408 text = text.replace(/\t/g, " "); | |
| 409 if (type == "cdata") | |
| 410 text = "<![CDATA[" + text + "]]>"; | |
| 411 else if (type == "comment") | |
| 412 text = "<!--" + text + "-->"; | 420 text = "<!--" + text + "-->"; | 
| 413 | 421 | 
| 414 var lines = text.split("\n"); | 422 let lines = text.split("\n"); | 
| 
saroyanm
2016/12/05 17:51:47
detail: we can move this inside of for statement,
 
Wladimir Palant
2016/12/08 13:11:29
Done.
 | |
| 415 for (var i = 0; i < lines.length; i++) | 423 for (let line of lines) | 
| 416 this.appendDescription(container, lines[i].replace(/^\s+/, '').replace(/\s +$/, ''), type); | 424 this.appendDescription(container, line.trim(), type); | 
| 417 }, | 425 }, | 
| 418 | 426 | 
| 419 showMenu: function() | 427 showMenu: function() | 
| 420 { | 428 { | 
| 421 var helpBox = E("ehh-helpbox"); | 429 var helpBox = E("ehh-helpbox"); | 
| 422 if (helpBox.state == "open") | 430 if (helpBox.state == "open") | 
| 423 { | 431 { | 
| 424 helpBox.hidePopup(); | 432 helpBox.hidePopup(); | 
| 425 return true; | 433 return true; | 
| 426 } | 434 } | 
| 427 | 435 | 
| 428 // Show help box | 436 // Show help box | 
| 429 helpBox.showPopup(this.browser, -1, -1, "tooltip", "topleft", "topleft"); | 437 helpBox.showPopup(this.browser, -1, -1, "tooltip", "topleft", "topleft"); | 
| 430 return true; | 438 return true; | 
| 431 } | 439 } | 
| 432 } | 440 } | 
| 433 | 441 | 
| 434 // Makes sure event handlers like Aardvark.onKeyPress always have the correct | 442 // Makes sure event handlers like Aardvark.onKeyPress always have the correct | 
| 435 // this pointer set. | 443 // this pointer set. | 
| 436 for (let method of ["onKeyPress", "onMouseMove", "onTabSelect"]) | 444 for (let method of ["onKeyPress", "onMouseMove", "onTabSelect"]) | 
| 437 Aardvark[method] = Aardvark[method].bind(Aardvark); | 445 Aardvark[method] = Aardvark[method].bind(Aardvark); | 
| OLD | NEW |