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 // 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 Loading... |
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 Loading... |
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); |
OLD | NEW |