Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/aardvark.js

Issue 29363476: Issue 2879 - Move element selection into the content process (Closed) Base URL: https://hg.adblockplus.org/elemhidehelper
Patch Set: Addressed comments and marked extension as E10S-compatible Created Nov. 24, 2016, 2 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/child/commands.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // Make sure to stop selection when we are uninstalled 11 let messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"]
12 onShutdown.add(() => Aardvark.quit()); 12 .getService(Ci.nsIMessageListenerManager)
13 .QueryInterface(Ci.nsIMessageBroadcaster);
13 14
14 // To be replaced when selection starts 15 // To be replaced when selection starts
15 function E(id) {return null;} 16 function E(id) {return null;}
16 17
17 let messageCounter = 0; 18 messageManager.addMessageListener("ElemHideHelper:SelectionStarted",
19 selectionStarted);
20 messageManager.addMessageListener("ElemHideHelper:SelectionSucceeded",
21 selectionSucceeded);
22 messageManager.addMessageListener("ElemHideHelper:SelectionStopped",
23 selectionStopped);
24 onShutdown.add(() =>
25 {
26 messageManager.removeMessageListener("ElemHideHelper:SelectionStarted",
27 selectionStarted);
28 messageManager.removeMessageListener("ElemHideHelper:SelectionSucceeded",
29 selectionSucceeded);
30 messageManager.removeMessageListener("ElemHideHelper:SelectionStopped",
31 selectionStopped);
18 32
19 /********************************* 33 selectionStopped();
20 * Minimal element creation code * 34 });
21 *********************************/
22 35
23 function createElement(doc, tagName, attrs, children) 36 function selectionStarted(message)
24 { 37 {
25 let el = doc.createElement(tagName); 38 Aardvark.selectionStarted();
26 if (attrs) 39 }
27 for (let key in attrs) 40
28 el.setAttribute(key, attrs[key]); 41 function selectionSucceeded(message)
29 if (children) 42 {
30 for (let child of children) 43 Aardvark.selectionSucceeded(message.data);
31 el.appendChild(child) 44 }
32 return el; 45
33 }; 46 function selectionStopped(message)
47 {
48 Aardvark.selectionStopped();
49 }
34 50
35 /********************************** 51 /**********************************
36 * General element selection code * 52 * General element selection code *
37 **********************************/ 53 **********************************/
38 54
39 let Aardvark = exports.Aardvark = 55 let Aardvark = exports.Aardvark =
40 { 56 {
41 window: null, 57 window: null,
42 browser: null, 58 browser: null,
43 anchorElem: null, 59 rememberedWrapper: null,
44 selectedElem: null,
45 isUserSelected: false,
46 lockedAnchor: null,
47 commentElem: null,
48 mouseX: -1, 60 mouseX: -1,
49 mouseY: -1, 61 mouseY: -1,
50 prevSelectionUpdate: -1,
51 commandLabelTimer: null, 62 commandLabelTimer: null,
52 viewSourceTimer: null, 63 viewSourceTimer: null,
53 boxElem: null,
54 paintNode: null,
55 prevPos: null,
56 64
57 start: function(wrapper) 65 start: function(wrapper)
58 { 66 {
59 if (!this.canSelect(wrapper.browser)) 67 this.rememberedWrapper = wrapper;
60 return; 68 let browser = wrapper.browser;
69 if ("selectedBrowser" in browser)
70 browser = browser.selectedBrowser;
71 messageManager.broadcastAsyncMessage(
72 "ElemHideHelper:StartSelection",
73 browser.outerWindowID
74 );
75 },
61 76
62 if (this.browser) 77 selectionStarted: function()
63 this.quit(); 78 {
79 let wrapper = this.rememberedWrapper;
80 this.rememberedWrapper = null;
64 81
65 this.window = wrapper.window; 82 this.window = wrapper.window;
66 this.browser = wrapper.browser; 83 this.browser = wrapper.browser;
67 E = id => wrapper.E(id); 84 E = id => wrapper.E(id);
68 85
69 this.browser.addEventListener("click", this.onMouseClick, true);
70 this.browser.addEventListener("DOMMouseScroll", this.onMouseScroll, true);
71 this.browser.addEventListener("keypress", this.onKeyPress, true); 86 this.browser.addEventListener("keypress", this.onKeyPress, true);
72 this.browser.addEventListener("mousemove", this.onMouseMove, true); 87 this.browser.addEventListener("mousemove", this.onMouseMove, false);
73 this.browser.addEventListener("select", this.quit, false); 88 this.browser.addEventListener("select", this.onTabSelect, false);
74 this.browser.contentWindow.addEventListener("pagehide", this.onPageHide, tru e);
75
76 this.browser.contentWindow.focus();
77
78 let doc = this.browser.contentDocument;
79 let {elementMarkerClass} = require("main");
80 this.boxElem = createElement(doc, "div", {"class": elementMarkerClass}, [
81 createElement(doc, "div", {"class": "ehh-border"}),
82 createElement(doc, "div", {"class": "ehh-label"}, [
83 createElement(doc, "span", {"class": "ehh-labelTag"}),
84 createElement(doc, "span", {"class": "ehh-labelAddition"})
85 ])
86 ]);
87 89
88 this.initHelpBox(); 90 this.initHelpBox();
89 91
90 if (Prefs.showhelp) 92 if (Prefs.showhelp)
91 this.showMenu(); 93 this.showMenu();
92
93 // Make sure to select some element immeditely (whichever is in the center o f the browser window)
94 let [wndWidth, wndHeight] = this.getWindowSize(doc.defaultView);
95 this.isUserSelected = false;
96 this.onMouseMove({clientX: wndWidth / 2, clientY: wndHeight / 2, screenX: -1 , screenY: -1, target: null});
97 }, 94 },
98 95
99 canSelect: function(browser) 96 selectionSucceeded: function(nodeInfo)
100 { 97 {
101 if (!browser || !browser.contentWindow || 98 this.window.openDialog("chrome://elemhidehelper/content/composer.xul",
102 !(browser.contentDocument instanceof Ci.nsIDOMHTMLDocument)) 99 "_blank", "chrome,centerscreen,resizable,dialog=no", nodeInfo);
103 { 100 },
104 return false;
105 }
106 101
107 let location = browser.contentWindow.location; 102 selectionStopped: function()
108 if (location.href == "about:blank") 103 {
109 return false; 104 if (!this.browser)
105 return;
110 106
111 if (!Prefs.acceptlocalfiles && 107 if (this.commandLabelTimer)
112 location.hostname == "" && 108 this.commandLabelTimer.cancel();
113 location.protocol != "mailbox:" && 109 if (this.viewSourceTimer)
114 location.protocol != "imap:" && 110 this.viewSourceTimer.cancel();
115 location.protocol != "news:" && 111 this.commandLabelTimer = null;
116 location.protocol != "snews:") 112 this.viewSourceTimer = null;
117 {
118 return false;
119 }
120 113
121 return true; 114 this.hideTooltips();
115
116 this.browser.removeEventListener("keypress", this.onKeyPress, true);
117 this.browser.removeEventListener("mousemove", this.onMouseMove, false);
118 this.browser.removeEventListener("select", this.onTabSelect, false);
119
120 this.window = null;
121 this.browser = null;
122 E = id => null;
122 }, 123 },
123 124
124 doCommand: function(command, event) 125 doCommand: function(command, event)
125 { 126 {
126 if (this[command](this.selectedElem)) 127 let showFeedback;
128 if (this.hasOwnProperty(command))
129 showFeedback = this[command]();
130 else
131 {
132 showFeedback = (command != "select" && command != "quit");
133 messageManager.broadcastAsyncMessage("ElemHideHelper:Command", command);
134 }
135
136 if (showFeedback)
127 { 137 {
128 this.showCommandLabel(this.commands[command + "_key"], this.commands[comma nd + "_altkey"], this.commands[command + "_label"]); 138 this.showCommandLabel(this.commands[command + "_key"], this.commands[comma nd + "_altkey"], this.commands[command + "_label"]);
129 if (event) 139 if (event)
130 event.stopPropagation(); 140 event.stopPropagation();
131 } 141 }
132 if (event) 142 if (event)
133 event.preventDefault(); 143 event.preventDefault();
134 }, 144 },
135 145
136 showCommandLabel: function(key, alternativeKey, label) 146 showCommandLabel: function(key, alternativeKey, label)
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 { 207 {
198 let tooltips = ["ehh-helpbox", "ehh-commandlabel", "ehh-viewsource"]; 208 let tooltips = ["ehh-helpbox", "ehh-commandlabel", "ehh-viewsource"];
199 for (let i = 0; i < tooltips.length; i++) 209 for (let i = 0; i < tooltips.length; i++)
200 { 210 {
201 let tooltip = E(tooltips[i]); 211 let tooltip = E(tooltips[i]);
202 if (tooltip) 212 if (tooltip)
203 tooltip.hidePopup(); 213 tooltip.hidePopup();
204 } 214 }
205 }, 215 },
206 216
207 onMouseClick: function(event)
208 {
209 if (event.button != 0 || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
210 return;
211
212 this.doCommand("select", event);
213 },
214
215 onMouseScroll: function(event)
216 {
217 if (!event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
218 return;
219
220 if ("axis" in event && event.axis != event.VERTICAL_AXIS)
221 return;
222
223 this.doCommand(event.detail > 0 ? "wider" : "narrower", event);
224 },
225
226 onKeyPress: function(event) 217 onKeyPress: function(event)
227 { 218 {
228 if (event.altKey || event.ctrlKey || event.metaKey) 219 if (event.altKey || event.ctrlKey || event.metaKey)
229 return; 220 return;
230 221
231 var command = null; 222 var command = null;
232 if (event.keyCode == event.DOM_VK_ESCAPE) 223 if (event.keyCode == event.DOM_VK_ESCAPE)
233 command = "quit"; 224 command = "quit";
234 else if (event.keyCode == event.DOM_VK_RETURN) 225 else if (event.keyCode == event.DOM_VK_RETURN)
235 command = "select"; 226 command = "select";
236 else if (event.charCode) 227 else if (event.charCode)
237 { 228 {
238 var key = String.fromCharCode(event.charCode).toLowerCase(); 229 var key = String.fromCharCode(event.charCode).toLowerCase();
239 var commands = this.commands; 230 var commands = this.commands;
240 for (var i = 0; i < commands.length; i++) 231 for (var i = 0; i < commands.length; i++)
241 if (commands[commands[i] + "_key"] == key || commands[commands[i] + "_al tkey"] == key) 232 if (commands[commands[i] + "_key"] == key || commands[commands[i] + "_al tkey"] == key)
242 command = commands[i]; 233 command = commands[i];
243 } 234 }
244 235
245 if (command) 236 if (command)
246 this.doCommand(command, event); 237 this.doCommand(command, event);
247 }, 238 },
248 239
249 onPageHide: function(event)
250 {
251 this.doCommand("quit", null);
252 },
253
254 onMouseMove: function(event) 240 onMouseMove: function(event)
255 { 241 {
256 this.mouseX = event.screenX; 242 this.mouseX = event.screenX;
257 this.mouseY = event.screenY; 243 this.mouseY = event.screenY;
258
259 this.hideSelection();
260 if (!this.browser)
261 {
262 // hideSelection() called quit()
263 return;
264 }
265
266 let x = event.clientX;
267 let y = event.clientY;
268
269 // We might have coordinates relative to a frame, recalculate relative to to p window
270 let node = event.target;
271 while (node && node.ownerDocument && node.ownerDocument.defaultView && node. ownerDocument.defaultView.frameElement)
272 {
273 node = node.ownerDocument.defaultView.frameElement;
274 let rect = node.getBoundingClientRect();
275 x += rect.left;
276 y += rect.top;
277 }
278
279 let elem = this.browser.contentDocument.elementFromPoint(x, y);
280 while (elem && "contentDocument" in elem && this.canSelect(elem))
281 {
282 let rect = elem.getBoundingClientRect();
283 x -= rect.left;
284 y -= rect.top;
285 elem = elem.contentDocument.elementFromPoint(x, y);
286 }
287
288 if (elem)
289 {
290 if (!this.lockedAnchor)
291 this.setAnchorElement(elem);
292 else
293 {
294 this.lockedAnchor = elem;
295 this.selectElement(this.selectedElem);
296 }
297 }
298 }, 244 },
299 245
300 onAfterPaint: function() 246 onTabSelect: function(event)
301 { 247 {
302 // Don't update position too often 248 this.doCommand("quit", null);
303 if (this.selectedElem && Date.now() - this.prevSelectionUpdate > 20)
304 {
305 let pos = this.getElementPosition(this.selectedElem);
306 if (!this.prevPos || this.prevPos.left != pos.left || this.prevPos.right ! = pos.right
307 || this.prevPos.top != pos.top || this.prevPos.bottom != pos.bottom)
308 {
309 this.selectElement(this.selectedElem);
310 }
311 }
312 },
313
314 setAnchorElement: function(anchor)
315 {
316 this.anchorElem = anchor;
317
318 let newSelection = anchor;
319 if (this.isUserSelected)
320 {
321 // User chose an element via wider/narrower commands, keep the selection i f
322 // out new anchor is still a child of that element
323 let e = newSelection;
324 while (e && e != this.selectedElem)
325 e = this.getParentElement(e);
326
327 if (e)
328 newSelection = this.selectedElem;
329 else
330 this.isUserSelected = false;
331 }
332
333 this.selectElement(newSelection);
334 }, 249 },
335 250
336 appendDescription: function(node, value, className) 251 appendDescription: function(node, value, className)
337 { 252 {
338 var descr = this.window.document.createElement("description"); 253 var descr = this.window.document.createElement("description");
339 descr.setAttribute("value", value); 254 descr.setAttribute("value", value);
340 if (className) 255 if (className)
341 descr.setAttribute("class", className); 256 descr.setAttribute("class", className);
342 node.appendChild(descr); 257 node.appendChild(descr);
343 }, 258 },
344 259
345 /**************************
346 * Element marker display *
347 **************************/
348
349 getElementLabel: function(elem)
350 {
351 let tagName = elem.tagName.toLowerCase();
352 let addition = "";
353 if (elem.id != "")
354 addition += ", id: " + elem.id;
355 if (elem.className != "")
356 addition += ", class: " + elem.className;
357 if (elem.style.cssText != "")
358 addition += ", style: " + elem.style.cssText;
359
360 return [tagName, addition];
361 },
362
363 selectElement: function(elem)
364 {
365 this.selectedElem = elem;
366 this.prevSelectionUpdate = Date.now();
367
368 let border = this.boxElem.getElementsByClassName("ehh-border")[0];
369 let label = this.boxElem.getElementsByClassName("ehh-label")[0];
370 let labelTag = this.boxElem.getElementsByClassName("ehh-labelTag")[0];
371 let labelAddition = this.boxElem.getElementsByClassName("ehh-labelAddition") [0];
372
373 if (this.boxElem.parentNode)
374 this.boxElem.parentNode.removeChild(this.boxElem);
375
376 let doc = this.browser.contentDocument;
377 let [wndWidth, wndHeight] = this.getWindowSize(doc.defaultView);
378
379 let pos = this.getElementPosition(elem);
380 this.boxElem.style.left = Math.min(pos.left - 1, wndWidth - 2) + "px";
381 this.boxElem.style.top = Math.min(pos.top - 1, wndHeight - 2) + "px";
382 border.style.width = Math.max(pos.right - pos.left - 2, 0) + "px";
383 border.style.height = Math.max(pos.bottom - pos.top - 2, 0) + "px";
384
385 [labelTag.textContent, labelAddition.textContent] = this.getElementLabel(ele m);
386
387 // If there is not enough space to show the label move it up a little
388 if (pos.bottom < wndHeight - 25)
389 label.className = "ehh-label";
390 else
391 label.className = "ehh-label onTop";
392
393 doc.documentElement.appendChild(this.boxElem);
394
395 this.paintNode = doc.defaultView;
396 if (this.paintNode)
397 {
398 this.prevPos = pos;
399 this.paintNode.addEventListener("MozAfterPaint", this.onAfterPaint, false) ;
400 }
401 },
402
403 hideSelection: function()
404 {
405 try
406 {
407 if (this.boxElem.parentNode)
408 this.boxElem.parentNode.removeChild(this.boxElem);
409 }
410 catch (e)
411 {
412 // Are we using CPOW whose process is gone? Quit!
413 // Clear some variables to prevent recursion (quit will call us again).
414 this.boxElem = {};
415 this.paintNode = null;
416 this.quit();
417 return;
418 }
419
420 if (this.paintNode)
421 this.paintNode.removeEventListener("MozAfterPaint", this.onAfterPaint, fal se);
422
423 this.paintNode = null;
424 this.prevPos = null;
425 },
426
427 getWindowSize: function(wnd)
428 {
429 return [wnd.innerWidth, wnd.document.documentElement.clientHeight];
430 },
431
432 getElementPosition: function(element)
433 {
434 // Restrict rectangle coordinates by the boundaries of a window's client are a
435 function intersectRect(rect, wnd)
436 {
437 let [wndWidth, wndHeight] = this.getWindowSize(wnd);
438 rect.left = Math.max(rect.left, 0);
439 rect.top = Math.max(rect.top, 0);
440 rect.right = Math.min(rect.right, wndWidth);
441 rect.bottom = Math.min(rect.bottom, wndHeight);
442 }
443
444 let rect = element.getBoundingClientRect();
445 let wnd = element.ownerDocument.defaultView;
446
447 rect = {left: rect.left, top: rect.top,
448 right: rect.right, bottom: rect.bottom};
449 while (true)
450 {
451 intersectRect.call(this, rect, wnd);
452
453 if (!wnd.frameElement)
454 break;
455
456 // Recalculate coordinates to be relative to frame's parent window
457 let frameElement = wnd.frameElement;
458 wnd = frameElement.ownerDocument.defaultView;
459
460 let frameRect = frameElement.getBoundingClientRect();
461 let frameStyle = wnd.getComputedStyle(frameElement, null);
462 let relLeft = frameRect.left + parseFloat(frameStyle.borderLeftWidth) + pa rseFloat(frameStyle.paddingLeft);
463 let relTop = frameRect.top + parseFloat(frameStyle.borderTopWidth) + parse Float(frameStyle.paddingTop);
464
465 rect.left += relLeft;
466 rect.right += relLeft;
467 rect.top += relTop;
468 rect.bottom += relTop;
469 }
470
471 return rect;
472 },
473
474 getParentElement: function(elem)
475 {
476 let result = elem.parentNode;
477 if (result && result.nodeType == Ci.nsIDOMElement.DOCUMENT_NODE && result.de faultView && result.defaultView.frameElement)
478 result = result.defaultView.frameElement;
479
480 if (result && result.nodeType != Ci.nsIDOMElement.ELEMENT_NODE)
481 return null;
482
483 return result;
484 },
485
486 /*************************** 260 /***************************
487 * Commands implementation * 261 * Commands implementation *
488 ***************************/ 262 ***************************/
489 263
490 commands: [ 264 commands: [
491 "select", 265 "select",
492 "wider", 266 "wider",
493 "narrower", 267 "narrower",
494 "lock", 268 "lock",
495 "quit", 269 "quit",
496 "blinkElement", 270 "blinkElement",
497 "viewSource", 271 "viewSource",
498 "viewSourceWindow", 272 "viewSourceWindow",
499 "showMenu" 273 "showMenu"
500 ], 274 ],
501 275
502 wider: function(elem)
503 {
504 if (!elem)
505 return false;
506
507 let newElem = this.getParentElement(elem);
508 if (!newElem)
509 return false;
510
511 this.isUserSelected = true;
512 this.selectElement(newElem);
513 return true;
514 },
515
516 narrower: function(elem)
517 {
518 if (elem)
519 {
520 // Search selected element in the parent chain, starting with the anchor e lement.
521 // We need to select the element just before the selected one.
522 let e = this.anchorElem;
523 let newElem = null;
524 while (e && e != elem)
525 {
526 newElem = e;
527 e = this.getParentElement(e);
528 }
529
530 if (!e || !newElem)
531 return false;
532
533 this.isUserSelected = true;
534 this.selectElement(newElem);
535 return true;
536 }
537 return false;
538 },
539
540 lock: function(elem)
541 {
542 if (!elem)
543 return false;
544
545 if (this.lockedAnchor)
546 {
547 this.setAnchorElement(this.lockedAnchor);
548 this.lockedAnchor = null;
549 }
550 else
551 this.lockedAnchor = this.anchorElem;
552
553 return true;
554 },
555
556 quit: function()
557 {
558 if (!this.browser)
559 return false;
560
561 if ("blinkTimer" in this)
562 this.stopBlinking();
563
564 if (this.commandLabelTimer)
565 this.commandLabelTimer.cancel();
566 if (this.viewSourceTimer)
567 this.viewSourceTimer.cancel();
568 this.commandLabelTimer = null;
569 this.viewSourceTimer = null;
570
571 this.hideSelection();
572 this.hideTooltips();
573
574 this.browser.removeEventListener("click", this.onMouseClick, true);
575 this.browser.removeEventListener("DOMMouseScroll", this.onMouseScroll, true) ;
576 this.browser.removeEventListener("keypress", this.onKeyPress, true);
577 this.browser.removeEventListener("mousemove", this.onMouseMove, true);
578 this.browser.removeEventListener("select", this.quit, false);
579 this.browser.contentWindow.removeEventListener("pagehide", this.onPageHide, true);
580
581 this.anchorElem = null;
582 this.selectedElem = null;
583 this.window = null;
584 this.browser = null;
585 this.commentElem = null;
586 this.lockedAnchor = null;
587 this.boxElem = null;
588 E = id => null;
589 return false;
590 },
591
592 select: function(elem)
593 {
594 if (!elem || !this.window)
595 return false;
596
597 let messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"]
598 .getService(Ci.nsIMessageBroadcaster);
599 let messageId = ++messageCounter;
600 let callback = (message) =>
601 {
602 let response = message.data;
603 if (response.messageId != messageId)
604 return;
605
606 messageManager.removeMessageListener(
607 "ElemHideHelper:GetNodeInfo:Response",
608 callback
609 );
610
611 if (!response.nodeData)
612 return;
613
614 this.window.openDialog("chrome://elemhidehelper/content/composer.xul",
615 "_blank", "chrome,centerscreen,resizable,dialog=no", response);
616 this.quit();
617 };
618
619 messageManager.addMessageListener(
620 "ElemHideHelper:GetNodeInfo:Response",
621 callback
622 );
623 messageManager.broadcastAsyncMessage(
624 "ElemHideHelper:GetNodeInfo",
625 messageId,
626 {
627 element: elem
628 }
629 );
630 return false;
631 },
632
633 blinkElement: function(elem)
634 {
635 if (!elem)
636 return false;
637
638 if ("blinkTimer" in this)
639 this.stopBlinking();
640
641 let counter = 0;
642 this.blinkElem = elem;
643 this.blinkOrigValue = elem.style.visibility;
644 this.blinkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
645 this.blinkTimer.initWithCallback(function()
646 {
647 counter++;
648 elem.style.visibility = (counter % 2 == 0 ? "visible" : "hidden");
649 if (counter == 6)
650 Aardvark.stopBlinking();
651 }, 250, Ci.nsITimer.TYPE_REPEATING_SLACK);
652
653 return true;
654 },
655
656 stopBlinking: function()
657 {
658 this.blinkTimer.cancel();
659 this.blinkElem.style.visibility = this.blinkOrigValue;
660
661 delete this.blinkElem;
662 delete this.blinkOrigValue;
663 delete this.blinkTimer;
664 },
665
666 viewSource: function(elem) 276 viewSource: function(elem)
667 { 277 {
668 if (!elem) 278 if (!elem)
669 return false; 279 return false;
670 280
671 var sourceBox = E("ehh-viewsource"); 281 var sourceBox = E("ehh-viewsource");
672 if (sourceBox.state == "open" && this.commentElem == elem) 282 if (sourceBox.state == "open")
673 { 283 {
674 sourceBox.hidePopup(); 284 sourceBox.hidePopup();
675 return true; 285 return true;
676 } 286 }
677 sourceBox.hidePopup(); 287 sourceBox.hidePopup();
678 288
679 while (sourceBox.firstElementChild) 289 while (sourceBox.firstElementChild)
680 sourceBox.removeChild(sourceBox.firstElementChild); 290 sourceBox.removeChild(sourceBox.firstElementChild);
681 this.getOuterHtmlFormatted(elem, sourceBox); 291 this.getOuterHtmlFormatted(elem, sourceBox);
682 this.commentElem = elem;
683 292
684 let anchor = this.window.document.documentElement; 293 let anchor = this.window.document.documentElement;
685 let x = this.mouseX; 294 let x = this.mouseX;
686 let y = this.mouseY; 295 let y = this.mouseY;
687 this.viewSourceTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer ); 296 this.viewSourceTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer );
688 this.viewSourceTimer.initWithCallback(function() 297 this.viewSourceTimer.initWithCallback(function()
689 { 298 {
690 sourceBox.showPopup(anchor, x, y, "tooltip", "topleft", "topleft"); 299 sourceBox.showPopup(anchor, x, y, "tooltip", "topleft", "topleft");
691 Aardvark.viewSourceTimer = null; 300 Aardvark.viewSourceTimer = null;
692 }, 500, Ci.nsITimer.TYPE_ONE_SHOT); 301 }, 500, Ci.nsITimer.TYPE_ONE_SHOT);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 } 426 }
818 427
819 // Show help box 428 // Show help box
820 helpBox.showPopup(this.browser, -1, -1, "tooltip", "topleft", "topleft"); 429 helpBox.showPopup(this.browser, -1, -1, "tooltip", "topleft", "topleft");
821 return true; 430 return true;
822 } 431 }
823 } 432 }
824 433
825 // Makes sure event handlers like Aardvark.onKeyPress always have the correct 434 // Makes sure event handlers like Aardvark.onKeyPress always have the correct
826 // this pointer set. 435 // this pointer set.
827 for (let method of ["onMouseClick", "onMouseScroll", "onKeyPress", "onPageHide", "onMouseMove", "onAfterPaint", "quit"]) 436 for (let method of ["onKeyPress", "onMouseMove", "onTabSelect"])
828 Aardvark[method] = Aardvark[method].bind(Aardvark); 437 Aardvark[method] = Aardvark[method].bind(Aardvark);
OLDNEW
« no previous file with comments | « no previous file | lib/child/commands.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld