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

Side by Side Diff: lib/aardvark.js

Issue 5671525202001920: Issue 227 - Element hiding selection by mouse wheel broken (Closed)
Patch Set: Created May 1, 2014, 11:31 a.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 | no next file » | 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 {Prefs} = require("prefs"); 7 let {Prefs} = require("prefs");
8 8
9 // Make sure to stop selection when we are uninstalled 9 // Make sure to stop selection when we are uninstalled
10 onShutdown.add(function() Aardvark.quit()); 10 onShutdown.add(function() Aardvark.quit());
(...skipping 20 matching lines...) Expand all
31 commandLabelTimer: null, 31 commandLabelTimer: null,
32 viewSourceTimer: null, 32 viewSourceTimer: null,
33 boxElem: null, 33 boxElem: null,
34 paintNode: null, 34 paintNode: null,
35 prevPos: null, 35 prevPos: null,
36 36
37 start: function(wrapper) 37 start: function(wrapper)
38 { 38 {
39 if (!this.canSelect(wrapper.browser)) 39 if (!this.canSelect(wrapper.browser))
40 return; 40 return;
41 41
42 if (this.browser) 42 if (this.browser)
43 this.quit(); 43 this.quit();
44 44
45 this.window = wrapper.window; 45 this.window = wrapper.window;
46 this.browser = wrapper.browser; 46 this.browser = wrapper.browser;
47 E = function(id) wrapper.E(id); 47 E = function(id) wrapper.E(id);
48 48
49 this.browser.addEventListener("click", this.onMouseClick, true); 49 this.browser.addEventListener("click", this.onMouseClick, true);
50 this.browser.addEventListener("DOMMouseScroll", this.onMouseScroll, true); 50 this.browser.addEventListener("DOMMouseScroll", this.onMouseScroll, true);
51 this.browser.addEventListener("keypress", this.onKeyPress, true); 51 this.browser.addEventListener("keypress", this.onKeyPress, true);
52 this.browser.addEventListener("mousemove", this.onMouseMove, true); 52 this.browser.addEventListener("mousemove", this.onMouseMove, true);
53 this.browser.addEventListener("select", this.quit, false); 53 this.browser.addEventListener("select", this.quit, false);
54 this.browser.contentWindow.addEventListener("pagehide", this.onPageHide, tru e); 54 this.browser.contentWindow.addEventListener("pagehide", this.onPageHide, tru e);
55 55
56 this.browser.contentWindow.focus(); 56 this.browser.contentWindow.focus();
57 57
58 let doc = this.browser.contentDocument; 58 let doc = this.browser.contentDocument;
59 this.boxElem = doc.importNode(E("ehh-elementmarker").firstElementChild.clone Node(true), true); 59 this.boxElem = doc.importNode(E("ehh-elementmarker").firstElementChild.clone Node(true), true);
60 60
61 this.initHelpBox(); 61 this.initHelpBox();
62 62
63 if (Prefs.showhelp) 63 if (Prefs.showhelp)
64 this.showMenu(); 64 this.showMenu();
65 65
66 // Make sure to select some element immeditely (whichever is in the center o f the browser window) 66 // Make sure to select some element immeditely (whichever is in the center o f the browser window)
67 let [wndWidth, wndHeight] = this.getWindowSize(doc.defaultView); 67 let [wndWidth, wndHeight] = this.getWindowSize(doc.defaultView);
68 this.isUserSelected = false; 68 this.isUserSelected = false;
69 this.onMouseMove({clientX: wndWidth / 2, clientY: wndHeight / 2, screenX: -1 , screenY: -1, target: null}); 69 this.onMouseMove({clientX: wndWidth / 2, clientY: wndHeight / 2, screenX: -1 , screenY: -1, target: null});
70 }, 70 },
71 71
72 canSelect: function(browser) 72 canSelect: function(browser)
73 { 73 {
74 if (!browser || !browser.contentWindow || 74 if (!browser || !browser.contentWindow ||
75 !(browser.contentDocument instanceof Ci.nsIDOMHTMLDocument)) 75 !(browser.contentDocument instanceof Ci.nsIDOMHTMLDocument))
76 { 76 {
77 return false; 77 return false;
78 } 78 }
79 79
80 let location = browser.contentWindow.location; 80 let location = browser.contentWindow.location;
81 if (location.href == "about:blank") 81 if (location.href == "about:blank")
82 return false; 82 return false;
83 83
84 if (!Prefs.acceptlocalfiles && 84 if (!Prefs.acceptlocalfiles &&
85 location.hostname == "" && 85 location.hostname == "" &&
86 location.protocol != "mailbox:" && 86 location.protocol != "mailbox:" &&
87 location.protocol != "imap:" && 87 location.protocol != "imap:" &&
88 location.protocol != "news:" && 88 location.protocol != "news:" &&
89 location.protocol != "snews:") 89 location.protocol != "snews:")
90 { 90 {
91 return false; 91 return false;
92 } 92 }
93 93
94 return true; 94 return true;
95 }, 95 },
96 96
97 doCommand: function(command, event) 97 doCommand: function(command, event)
98 { 98 {
99 if (this[command](this.selectedElem)) 99 if (this[command](this.selectedElem))
100 { 100 {
101 this.showCommandLabel(this.commands[command + "_key"], this.commands[comma nd + "_altkey"], this.commands[command + "_label"]); 101 this.showCommandLabel(this.commands[command + "_key"], this.commands[comma nd + "_altkey"], this.commands[command + "_label"]);
102 if (event) 102 if (event)
103 event.stopPropagation(); 103 event.stopPropagation();
104 } 104 }
105 if (event) 105 if (event)
106 event.preventDefault(); 106 event.preventDefault();
107 }, 107 },
108 108
109 showCommandLabel: function(key, alternativeKey, label) 109 showCommandLabel: function(key, alternativeKey, label)
110 { 110 {
111 if (this.commandLabelTimer) 111 if (this.commandLabelTimer)
112 this.commandLabelTimer.cancel(); 112 this.commandLabelTimer.cancel();
113 113
114 E("ehh-commandlabel-key").textContent = key.toUpperCase(); 114 E("ehh-commandlabel-key").textContent = key.toUpperCase();
115 E("ehh-commandlabel-alternativeKey").textContent = alternativeKey.toUpperCas e(); 115 E("ehh-commandlabel-alternativeKey").textContent = alternativeKey.toUpperCas e();
116 E("ehh-commandlabel-label").setAttribute("value", label); 116 E("ehh-commandlabel-label").setAttribute("value", label);
117 117
118 var commandLabel = E("ehh-commandlabel"); 118 var commandLabel = E("ehh-commandlabel");
119 commandLabel.showPopup(this.window.document.documentElement, this.mouseX, th is.mouseY, "tooltip", "topleft", "topleft"); 119 commandLabel.showPopup(this.window.document.documentElement, this.mouseX, th is.mouseY, "tooltip", "topleft", "topleft");
120 120
121 this.commandLabelTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITim er); 121 this.commandLabelTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITim er);
122 this.commandLabelTimer.initWithCallback(function() 122 this.commandLabelTimer.initWithCallback(function()
123 { 123 {
124 commandLabel.hidePopup(); 124 commandLabel.hidePopup();
125 Aardvark.commandLabelTimer = null; 125 Aardvark.commandLabelTimer = null;
126 }, 400, Ci.nsITimer.TYPE_ONE_SHOT); 126 }, 400, Ci.nsITimer.TYPE_ONE_SHOT);
127 }, 127 },
128 128
129 initHelpBox: function() 129 initHelpBox: function()
130 { 130 {
131 var helpBoxRows = E("ehh-helpbox-rows"); 131 var helpBoxRows = E("ehh-helpbox-rows");
132 if (helpBoxRows.firstElementChild) 132 if (helpBoxRows.firstElementChild)
133 return; 133 return;
134 134
135 // Help box hasn't been filled yet, need to do it now 135 // Help box hasn't been filled yet, need to do it now
136 var stringService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsI StringBundleService); 136 var stringService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsI StringBundleService);
137 var strings = stringService.createBundle("chrome://elemhidehelper/locale/glo bal.properties"); 137 var strings = stringService.createBundle("chrome://elemhidehelper/locale/glo bal.properties");
138 138
139 for (var i = 0; i < this.commands.length; i++) 139 for (var i = 0; i < this.commands.length; i++)
140 { 140 {
141 var command = this.commands[i]; 141 var command = this.commands[i];
142 var key = strings.GetStringFromName("command." + command + ".key"); 142 var key = strings.GetStringFromName("command." + command + ".key");
143 var alternativeKey = strings.GetStringFromName("command." + command + ".al ternativeKey"); 143 var alternativeKey = strings.GetStringFromName("command." + command + ".al ternativeKey");
144 var label = strings.GetStringFromName("command." + command + ".label"); 144 var label = strings.GetStringFromName("command." + command + ".label");
145 this.commands[command + "_key"] = key.toLowerCase(); 145 this.commands[command + "_key"] = key.toLowerCase();
146 this.commands[command + "_altkey"] = alternativeKey.toLowerCase(); 146 this.commands[command + "_altkey"] = alternativeKey.toLowerCase();
147 this.commands[command + "_label"] = label; 147 this.commands[command + "_label"] = label;
148 148
149 var row = this.window.document.createElement("row"); 149 var row = this.window.document.createElement("row");
150 helpBoxRows.appendChild(row); 150 helpBoxRows.appendChild(row);
151 151
152 var element = this.window.document.createElement("description"); 152 var element = this.window.document.createElement("description");
153 element.textContent = key.toUpperCase(); 153 element.textContent = key.toUpperCase();
154 element.className = "key"; 154 element.className = "key";
155 row.appendChild(element); 155 row.appendChild(element);
156 156
157 var element = this.window.document.createElement("description"); 157 var element = this.window.document.createElement("description");
158 element.textContent = alternativeKey.toUpperCase(); 158 element.textContent = alternativeKey.toUpperCase();
159 element.className = "key"; 159 element.className = "key";
160 row.appendChild(element); 160 row.appendChild(element);
161 161
162 element = this.window.document.createElement("description"); 162 element = this.window.document.createElement("description");
163 element.setAttribute("value", label); 163 element.setAttribute("value", label);
164 element.className = "label"; 164 element.className = "label";
165 row.appendChild(element); 165 row.appendChild(element);
166 } 166 }
167 }, 167 },
168 168
169 hideTooltips: function() 169 hideTooltips: function()
170 { 170 {
171 let tooltips = ["ehh-helpbox", "ehh-commandlabel", "ehh-viewsource"]; 171 let tooltips = ["ehh-helpbox", "ehh-commandlabel", "ehh-viewsource"];
172 for (let i = 0; i < tooltips.length; i++) 172 for (let i = 0; i < tooltips.length; i++)
173 { 173 {
174 let tooltip = E(tooltips[i]); 174 let tooltip = E(tooltips[i]);
175 if (tooltip) 175 if (tooltip)
176 tooltip.hidePopup(); 176 tooltip.hidePopup();
177 } 177 }
178 }, 178 },
179 179
180 onMouseClick: function(event) 180 onMouseClick: function(event)
181 { 181 {
182 if (event.button != 0 || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) 182 if (event.button != 0 || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
183 return; 183 return;
184 184
185 this.doCommand("select", event); 185 this.doCommand("select", event);
186 }, 186 },
187 187
188 onMouseScroll: function(event) 188 onMouseScroll: function(event)
189 { 189 {
190 if (!event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) 190 if (!event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
191 return; 191 return;
192 192
193 if ("axis" in event && event.axis != event.VERTICAL_AXIS) 193 if ("axis" in event && event.axis != event.VERTICAL_AXIS)
194 return; 194 return;
195 195
196 for (let i = 0; i < Math.abs(event.detail); i++) 196 this.doCommand(event.detail > 0 ? "wider" : "narrower", event);
197 this.doCommand(event.detail > 0 ? "wider" : "narrower", event);
198 }, 197 },
199 198
200 onKeyPress: function(event) 199 onKeyPress: function(event)
201 { 200 {
202 if (event.altKey || event.ctrlKey || event.metaKey) 201 if (event.altKey || event.ctrlKey || event.metaKey)
203 return; 202 return;
204 203
205 var command = null; 204 var command = null;
206 if (event.keyCode == event.DOM_VK_ESCAPE) 205 if (event.keyCode == event.DOM_VK_ESCAPE)
207 command = "quit"; 206 command = "quit";
208 else if (event.keyCode == event.DOM_VK_RETURN) 207 else if (event.keyCode == event.DOM_VK_RETURN)
209 command = "select"; 208 command = "select";
210 else if (event.charCode) 209 else if (event.charCode)
211 { 210 {
212 var key = String.fromCharCode(event.charCode).toLowerCase(); 211 var key = String.fromCharCode(event.charCode).toLowerCase();
213 var commands = this.commands; 212 var commands = this.commands;
214 for (var i = 0; i < commands.length; i++) 213 for (var i = 0; i < commands.length; i++)
215 if (commands[commands[i] + "_key"] == key || commands[commands[i] + "_al tkey"] == key) 214 if (commands[commands[i] + "_key"] == key || commands[commands[i] + "_al tkey"] == key)
216 command = commands[i]; 215 command = commands[i];
217 } 216 }
218 217
219 if (command) 218 if (command)
220 this.doCommand(command, event); 219 this.doCommand(command, event);
221 }, 220 },
222 221
223 onPageHide: function(event) 222 onPageHide: function(event)
224 { 223 {
225 this.doCommand("quit", null); 224 this.doCommand("quit", null);
226 }, 225 },
227 226
228 onMouseMove: function(event) 227 onMouseMove: function(event)
229 { 228 {
230 this.mouseX = event.screenX; 229 this.mouseX = event.screenX;
231 this.mouseY = event.screenY; 230 this.mouseY = event.screenY;
232 231
233 this.hideSelection(); 232 this.hideSelection();
234 233
235 let x = event.clientX; 234 let x = event.clientX;
236 let y = event.clientY; 235 let y = event.clientY;
237 236
238 // We might have coordinates relative to a frame, recalculate relative to to p window 237 // We might have coordinates relative to a frame, recalculate relative to to p window
239 let node = event.target; 238 let node = event.target;
240 while (node && node.ownerDocument && node.ownerDocument.defaultView && node. ownerDocument.defaultView.frameElement) 239 while (node && node.ownerDocument && node.ownerDocument.defaultView && node. ownerDocument.defaultView.frameElement)
241 { 240 {
242 node = node.ownerDocument.defaultView.frameElement; 241 node = node.ownerDocument.defaultView.frameElement;
243 let rect = node.getBoundingClientRect(); 242 let rect = node.getBoundingClientRect();
244 x += rect.left; 243 x += rect.left;
245 y += rect.top; 244 y += rect.top;
246 } 245 }
247 246
248 let elem = this.browser.contentDocument.elementFromPoint(x, y); 247 let elem = this.browser.contentDocument.elementFromPoint(x, y);
249 while (elem && "contentDocument" in elem && this.canSelect(elem)) 248 while (elem && "contentDocument" in elem && this.canSelect(elem))
250 { 249 {
251 let rect = elem.getBoundingClientRect(); 250 let rect = elem.getBoundingClientRect();
252 x -= rect.left; 251 x -= rect.left;
253 y -= rect.top; 252 y -= rect.top;
254 elem = elem.contentDocument.elementFromPoint(x, y); 253 elem = elem.contentDocument.elementFromPoint(x, y);
255 } 254 }
256 255
257 if (elem) 256 if (elem)
258 { 257 {
259 if (!this.lockedAnchor) 258 if (!this.lockedAnchor)
260 this.setAnchorElement(elem); 259 this.setAnchorElement(elem);
261 else 260 else
262 { 261 {
263 this.lockedAnchor = elem; 262 this.lockedAnchor = elem;
264 this.selectElement(this.selectedElem); 263 this.selectElement(this.selectedElem);
265 } 264 }
266 } 265 }
267 }, 266 },
268 267
269 onAfterPaint: function() 268 onAfterPaint: function()
270 { 269 {
271 // Don't update position too often 270 // Don't update position too often
272 if (this.selectedElem && Date.now() - this.prevSelectionUpdate > 20) 271 if (this.selectedElem && Date.now() - this.prevSelectionUpdate > 20)
273 { 272 {
274 let pos = this.getElementPosition(this.selectedElem); 273 let pos = this.getElementPosition(this.selectedElem);
275 if (!this.prevPos || this.prevPos.left != pos.left || this.prevPos.right ! = pos.right 274 if (!this.prevPos || this.prevPos.left != pos.left || this.prevPos.right ! = pos.right
276 || this.prevPos.top != pos.top || this.prevPos.bottom != pos.bottom) 275 || this.prevPos.top != pos.top || this.prevPos.bottom != pos.bottom)
277 { 276 {
278 this.selectElement(this.selectedElem); 277 this.selectElement(this.selectedElem);
279 } 278 }
280 } 279 }
281 }, 280 },
282 281
283 setAnchorElement: function(anchor) 282 setAnchorElement: function(anchor)
284 { 283 {
285 this.anchorElem = anchor; 284 this.anchorElem = anchor;
286 285
287 let newSelection = anchor; 286 let newSelection = anchor;
288 if (this.isUserSelected) 287 if (this.isUserSelected)
289 { 288 {
290 // User chose an element via wider/narrower commands, keep the selection i f 289 // User chose an element via wider/narrower commands, keep the selection i f
291 // out new anchor is still a child of that element 290 // out new anchor is still a child of that element
292 let e = newSelection; 291 let e = newSelection;
293 while (e && e != this.selectedElem) 292 while (e && e != this.selectedElem)
294 e = this.getParentElement(e); 293 e = this.getParentElement(e);
295 294
296 if (e) 295 if (e)
297 newSelection = this.selectedElem; 296 newSelection = this.selectedElem;
298 else 297 else
299 this.isUserSelected = false; 298 this.isUserSelected = false;
300 } 299 }
301 300
302 this.selectElement(newSelection); 301 this.selectElement(newSelection);
303 }, 302 },
304 303
305 appendDescription: function(node, value, className) 304 appendDescription: function(node, value, className)
306 { 305 {
307 var descr = this.window.document.createElement("description"); 306 var descr = this.window.document.createElement("description");
308 descr.setAttribute("value", value); 307 descr.setAttribute("value", value);
309 if (className) 308 if (className)
310 descr.setAttribute("class", className); 309 descr.setAttribute("class", className);
311 node.appendChild(descr); 310 node.appendChild(descr);
312 }, 311 },
313 312
314 /************************** 313 /**************************
315 * Element marker display * 314 * Element marker display *
316 **************************/ 315 **************************/
317 316
318 getElementLabel: function(elem) 317 getElementLabel: function(elem)
319 { 318 {
320 let tagName = elem.tagName.toLowerCase(); 319 let tagName = elem.tagName.toLowerCase();
321 let addition = ""; 320 let addition = "";
322 if (elem.id != "") 321 if (elem.id != "")
323 addition += ", id: " + elem.id; 322 addition += ", id: " + elem.id;
324 if (elem.className != "") 323 if (elem.className != "")
325 addition += ", class: " + elem.className; 324 addition += ", class: " + elem.className;
326 if (elem.style.cssText != "") 325 if (elem.style.cssText != "")
327 addition += ", style: " + elem.style.cssText; 326 addition += ", style: " + elem.style.cssText;
328 327
329 return [tagName, addition]; 328 return [tagName, addition];
330 }, 329 },
331 330
332 selectElement: function(elem) 331 selectElement: function(elem)
333 { 332 {
334 this.selectedElem = elem; 333 this.selectedElem = elem;
335 this.prevSelectionUpdate = Date.now(); 334 this.prevSelectionUpdate = Date.now();
336 335
337 let border = this.boxElem.getElementsByClassName("ehh-border")[0]; 336 let border = this.boxElem.getElementsByClassName("ehh-border")[0];
338 let label = this.boxElem.getElementsByClassName("ehh-label")[0]; 337 let label = this.boxElem.getElementsByClassName("ehh-label")[0];
339 let labelTag = this.boxElem.getElementsByClassName("ehh-labelTag")[0]; 338 let labelTag = this.boxElem.getElementsByClassName("ehh-labelTag")[0];
340 let labelAddition = this.boxElem.getElementsByClassName("ehh-labelAddition") [0]; 339 let labelAddition = this.boxElem.getElementsByClassName("ehh-labelAddition") [0];
341 340
342 if (this.boxElem.parentNode) 341 if (this.boxElem.parentNode)
343 this.boxElem.parentNode.removeChild(this.boxElem); 342 this.boxElem.parentNode.removeChild(this.boxElem);
344 343
345 let doc = this.browser.contentDocument; 344 let doc = this.browser.contentDocument;
346 let [wndWidth, wndHeight] = this.getWindowSize(doc.defaultView); 345 let [wndWidth, wndHeight] = this.getWindowSize(doc.defaultView);
347 346
348 let pos = this.getElementPosition(elem); 347 let pos = this.getElementPosition(elem);
349 this.boxElem.style.left = Math.min(pos.left - 1, wndWidth - 2) + "px"; 348 this.boxElem.style.left = Math.min(pos.left - 1, wndWidth - 2) + "px";
350 this.boxElem.style.top = Math.min(pos.top - 1, wndHeight - 2) + "px"; 349 this.boxElem.style.top = Math.min(pos.top - 1, wndHeight - 2) + "px";
351 border.style.width = Math.max(pos.right - pos.left - 2, 0) + "px"; 350 border.style.width = Math.max(pos.right - pos.left - 2, 0) + "px";
352 border.style.height = Math.max(pos.bottom - pos.top - 2, 0) + "px"; 351 border.style.height = Math.max(pos.bottom - pos.top - 2, 0) + "px";
353 352
354 [labelTag.textContent, labelAddition.textContent] = this.getElementLabel(ele m); 353 [labelTag.textContent, labelAddition.textContent] = this.getElementLabel(ele m);
355 354
356 // If there is not enough space to show the label move it up a little 355 // If there is not enough space to show the label move it up a little
357 if (pos.bottom < wndHeight - 25) 356 if (pos.bottom < wndHeight - 25)
358 label.className = "ehh-label"; 357 label.className = "ehh-label";
359 else 358 else
360 label.className = "ehh-label onTop"; 359 label.className = "ehh-label onTop";
361 360
362 doc.documentElement.appendChild(this.boxElem); 361 doc.documentElement.appendChild(this.boxElem);
363 362
364 this.paintNode = doc.defaultView; 363 this.paintNode = doc.defaultView;
365 if (this.paintNode) 364 if (this.paintNode)
366 { 365 {
367 this.prevPos = pos; 366 this.prevPos = pos;
368 this.paintNode.addEventListener("MozAfterPaint", this.onAfterPaint, false) ; 367 this.paintNode.addEventListener("MozAfterPaint", this.onAfterPaint, false) ;
369 } 368 }
370 }, 369 },
371 370
(...skipping 17 matching lines...) Expand all
389 { 388 {
390 // Restrict rectangle coordinates by the boundaries of a window's client are a 389 // Restrict rectangle coordinates by the boundaries of a window's client are a
391 function intersectRect(rect, wnd) 390 function intersectRect(rect, wnd)
392 { 391 {
393 let [wndWidth, wndHeight] = this.getWindowSize(wnd); 392 let [wndWidth, wndHeight] = this.getWindowSize(wnd);
394 rect.left = Math.max(rect.left, 0); 393 rect.left = Math.max(rect.left, 0);
395 rect.top = Math.max(rect.top, 0); 394 rect.top = Math.max(rect.top, 0);
396 rect.right = Math.min(rect.right, wndWidth); 395 rect.right = Math.min(rect.right, wndWidth);
397 rect.bottom = Math.min(rect.bottom, wndHeight); 396 rect.bottom = Math.min(rect.bottom, wndHeight);
398 } 397 }
399 398
400 let rect = element.getBoundingClientRect(); 399 let rect = element.getBoundingClientRect();
401 let wnd = element.ownerDocument.defaultView; 400 let wnd = element.ownerDocument.defaultView;
402 401
403 rect = {left: rect.left, top: rect.top, 402 rect = {left: rect.left, top: rect.top,
404 right: rect.right, bottom: rect.bottom}; 403 right: rect.right, bottom: rect.bottom};
405 while (true) 404 while (true)
406 { 405 {
407 intersectRect.call(this, rect, wnd); 406 intersectRect.call(this, rect, wnd);
408 407
409 if (!wnd.frameElement) 408 if (!wnd.frameElement)
410 break; 409 break;
411 410
412 // Recalculate coordinates to be relative to frame's parent window 411 // Recalculate coordinates to be relative to frame's parent window
413 let frameElement = wnd.frameElement; 412 let frameElement = wnd.frameElement;
414 wnd = frameElement.ownerDocument.defaultView; 413 wnd = frameElement.ownerDocument.defaultView;
415 414
416 let frameRect = frameElement.getBoundingClientRect(); 415 let frameRect = frameElement.getBoundingClientRect();
417 let frameStyle = wnd.getComputedStyle(frameElement, null); 416 let frameStyle = wnd.getComputedStyle(frameElement, null);
418 let relLeft = frameRect.left + parseFloat(frameStyle.borderLeftWidth) + pa rseFloat(frameStyle.paddingLeft); 417 let relLeft = frameRect.left + parseFloat(frameStyle.borderLeftWidth) + pa rseFloat(frameStyle.paddingLeft);
419 let relTop = frameRect.top + parseFloat(frameStyle.borderTopWidth) + parse Float(frameStyle.paddingTop); 418 let relTop = frameRect.top + parseFloat(frameStyle.borderTopWidth) + parse Float(frameStyle.paddingTop);
420 419
421 rect.left += relLeft; 420 rect.left += relLeft;
422 rect.right += relLeft; 421 rect.right += relLeft;
423 rect.top += relTop; 422 rect.top += relTop;
424 rect.bottom += relTop; 423 rect.bottom += relTop;
425 } 424 }
426 425
427 return rect; 426 return rect;
428 }, 427 },
429 428
430 getParentElement: function(elem) 429 getParentElement: function(elem)
431 { 430 {
432 let result = elem.parentNode; 431 let result = elem.parentNode;
433 if (result && result.nodeType == Ci.nsIDOMElement.DOCUMENT_NODE && result.de faultView && result.defaultView.frameElement) 432 if (result && result.nodeType == Ci.nsIDOMElement.DOCUMENT_NODE && result.de faultView && result.defaultView.frameElement)
434 result = result.defaultView.frameElement; 433 result = result.defaultView.frameElement;
435 434
436 if (result && result.nodeType != Ci.nsIDOMElement.ELEMENT_NODE) 435 if (result && result.nodeType != Ci.nsIDOMElement.ELEMENT_NODE)
437 return null; 436 return null;
438 437
439 return result; 438 return result;
440 }, 439 },
441 440
442 /*************************** 441 /***************************
443 * Commands implementation * 442 * Commands implementation *
444 ***************************/ 443 ***************************/
445 444
446 commands: [ 445 commands: [
447 "select", 446 "select",
448 "wider", 447 "wider",
449 "narrower", 448 "narrower",
450 "lock", 449 "lock",
451 "quit", 450 "quit",
452 "blinkElement", 451 "blinkElement",
453 "viewSource", 452 "viewSource",
454 "viewSourceWindow", 453 "viewSourceWindow",
455 "showMenu" 454 "showMenu"
456 ], 455 ],
457 456
458 wider: function(elem) 457 wider: function(elem)
459 { 458 {
460 if (!elem) 459 if (!elem)
461 return false; 460 return false;
462 461
463 let newElem = this.getParentElement(elem); 462 let newElem = this.getParentElement(elem);
464 if (!newElem) 463 if (!newElem)
465 return false; 464 return false;
466 465
467 this.isUserSelected = true; 466 this.isUserSelected = true;
468 this.selectElement(newElem); 467 this.selectElement(newElem);
469 return true; 468 return true;
470 }, 469 },
471 470
472 narrower: function(elem) 471 narrower: function(elem)
473 { 472 {
474 if (elem) 473 if (elem)
475 { 474 {
476 // Search selected element in the parent chain, starting with the anchor e lement. 475 // Search selected element in the parent chain, starting with the anchor e lement.
477 // We need to select the element just before the selected one. 476 // We need to select the element just before the selected one.
478 let e = this.anchorElem; 477 let e = this.anchorElem;
479 let newElem = null; 478 let newElem = null;
480 while (e && e != elem) 479 while (e && e != elem)
481 { 480 {
482 newElem = e; 481 newElem = e;
483 e = this.getParentElement(e); 482 e = this.getParentElement(e);
484 } 483 }
485 484
486 if (!e || !newElem) 485 if (!e || !newElem)
487 return false; 486 return false;
488 487
489 this.isUserSelected = true; 488 this.isUserSelected = true;
490 this.selectElement(newElem); 489 this.selectElement(newElem);
491 return true; 490 return true;
492 } 491 }
493 return false; 492 return false;
494 }, 493 },
495 494
496 lock: function(elem) 495 lock: function(elem)
497 { 496 {
498 if (!elem) 497 if (!elem)
499 return false; 498 return false;
500 499
501 if (this.lockedAnchor) 500 if (this.lockedAnchor)
502 { 501 {
503 this.setAnchorElement(this.lockedAnchor); 502 this.setAnchorElement(this.lockedAnchor);
504 this.lockedAnchor = null; 503 this.lockedAnchor = null;
505 } 504 }
506 else 505 else
507 this.lockedAnchor = this.anchorElem; 506 this.lockedAnchor = this.anchorElem;
508 507
509 return true; 508 return true;
510 }, 509 },
511 510
512 quit: function() 511 quit: function()
513 { 512 {
514 if (!this.browser) 513 if (!this.browser)
515 return false; 514 return false;
516 515
517 if ("blinkTimer" in this) 516 if ("blinkTimer" in this)
518 this.stopBlinking(); 517 this.stopBlinking();
519 518
520 if (this.commandLabelTimer) 519 if (this.commandLabelTimer)
521 this.commandLabelTimer.cancel(); 520 this.commandLabelTimer.cancel();
522 if (this.viewSourceTimer) 521 if (this.viewSourceTimer)
523 this.viewSourceTimer.cancel(); 522 this.viewSourceTimer.cancel();
524 this.commandLabelTimer = null; 523 this.commandLabelTimer = null;
525 this.viewSourceTimer = null; 524 this.viewSourceTimer = null;
526 525
527 this.hideSelection(); 526 this.hideSelection();
528 this.hideTooltips(); 527 this.hideTooltips();
529 528
530 this.browser.removeEventListener("click", this.onMouseClick, true); 529 this.browser.removeEventListener("click", this.onMouseClick, true);
531 this.browser.removeEventListener("DOMMouseScroll", this.onMouseScroll, true) ; 530 this.browser.removeEventListener("DOMMouseScroll", this.onMouseScroll, true) ;
532 this.browser.removeEventListener("keypress", this.onKeyPress, true); 531 this.browser.removeEventListener("keypress", this.onKeyPress, true);
533 this.browser.removeEventListener("mousemove", this.onMouseMove, true); 532 this.browser.removeEventListener("mousemove", this.onMouseMove, true);
534 this.browser.removeEventListener("select", this.quit, false); 533 this.browser.removeEventListener("select", this.quit, false);
535 this.browser.contentWindow.removeEventListener("pagehide", this.onPageHide, true); 534 this.browser.contentWindow.removeEventListener("pagehide", this.onPageHide, true);
536 535
537 this.anchorElem = null; 536 this.anchorElem = null;
538 this.selectedElem = null; 537 this.selectedElem = null;
539 this.window = null; 538 this.window = null;
540 this.browser = null; 539 this.browser = null;
541 this.commentElem = null; 540 this.commentElem = null;
542 this.lockedAnchor = null; 541 this.lockedAnchor = null;
543 this.boxElem = null; 542 this.boxElem = null;
544 E = function(id) null; 543 E = function(id) null;
545 return false; 544 return false;
546 }, 545 },
547 546
548 select: function(elem) 547 select: function(elem)
549 { 548 {
550 if (!elem) 549 if (!elem)
551 return false; 550 return false;
552 551
553 this.window.openDialog("chrome://elemhidehelper/content/composer.xul", "_bla nk", 552 this.window.openDialog("chrome://elemhidehelper/content/composer.xul", "_bla nk",
554 "chrome,centerscreen,resizable,dialog=no", elem); 553 "chrome,centerscreen,resizable,dialog=no", elem);
555 this.quit(); 554 this.quit();
556 return false; 555 return false;
557 }, 556 },
558 557
559 blinkElement: function(elem) 558 blinkElement: function(elem)
560 { 559 {
561 if (!elem) 560 if (!elem)
562 return false; 561 return false;
563 562
564 if ("blinkTimer" in this) 563 if ("blinkTimer" in this)
565 this.stopBlinking(); 564 this.stopBlinking();
566 565
567 let counter = 0; 566 let counter = 0;
568 this.blinkElem = elem; 567 this.blinkElem = elem;
569 this.blinkOrigValue = elem.style.visibility; 568 this.blinkOrigValue = elem.style.visibility;
570 this.blinkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 569 this.blinkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
571 this.blinkTimer.initWithCallback(function() 570 this.blinkTimer.initWithCallback(function()
572 { 571 {
573 counter++; 572 counter++;
574 elem.style.visibility = (counter % 2 == 0 ? "visible" : "hidden"); 573 elem.style.visibility = (counter % 2 == 0 ? "visible" : "hidden");
575 if (counter == 6) 574 if (counter == 6)
576 Aardvark.stopBlinking(); 575 Aardvark.stopBlinking();
577 }, 250, Ci.nsITimer.TYPE_REPEATING_SLACK); 576 }, 250, Ci.nsITimer.TYPE_REPEATING_SLACK);
578 577
579 return true; 578 return true;
580 }, 579 },
581 580
582 stopBlinking: function() 581 stopBlinking: function()
583 { 582 {
584 this.blinkTimer.cancel(); 583 this.blinkTimer.cancel();
585 this.blinkElem.style.visibility = this.blinkOrigValue; 584 this.blinkElem.style.visibility = this.blinkOrigValue;
586 585
587 delete this.blinkElem; 586 delete this.blinkElem;
588 delete this.blinkOrigValue; 587 delete this.blinkOrigValue;
589 delete this.blinkTimer; 588 delete this.blinkTimer;
590 }, 589 },
591 590
592 viewSource: function(elem) 591 viewSource: function(elem)
593 { 592 {
594 if (!elem) 593 if (!elem)
595 return false; 594 return false;
596 595
597 var sourceBox = E("ehh-viewsource"); 596 var sourceBox = E("ehh-viewsource");
598 if (sourceBox.state == "open" && this.commentElem == elem) 597 if (sourceBox.state == "open" && this.commentElem == elem)
599 { 598 {
600 sourceBox.hidePopup(); 599 sourceBox.hidePopup();
601 return true; 600 return true;
602 } 601 }
603 sourceBox.hidePopup(); 602 sourceBox.hidePopup();
604 603
605 while (sourceBox.firstElementChild) 604 while (sourceBox.firstElementChild)
606 sourceBox.removeChild(sourceBox.firstElementChild); 605 sourceBox.removeChild(sourceBox.firstElementChild);
607 this.getOuterHtmlFormatted(elem, sourceBox); 606 this.getOuterHtmlFormatted(elem, sourceBox);
608 this.commentElem = elem; 607 this.commentElem = elem;
609 608
610 let anchor = this.window.document.documentElement; 609 let anchor = this.window.document.documentElement;
611 let x = this.mouseX; 610 let x = this.mouseX;
612 let y = this.mouseY; 611 let y = this.mouseY;
613 this.viewSourceTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer ); 612 this.viewSourceTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer );
614 this.viewSourceTimer.initWithCallback(function() 613 this.viewSourceTimer.initWithCallback(function()
615 { 614 {
616 sourceBox.showPopup(anchor, x, y, "tooltip", "topleft", "topleft"); 615 sourceBox.showPopup(anchor, x, y, "tooltip", "topleft", "topleft");
617 Aardvark.viewSourceTimer = null; 616 Aardvark.viewSourceTimer = null;
618 }, 500, Ci.nsITimer.TYPE_ONE_SHOT); 617 }, 500, Ci.nsITimer.TYPE_ONE_SHOT);
619 return true; 618 return true;
620 }, 619 },
621 620
622 viewSourceWindow: function(elem) 621 viewSourceWindow: function(elem)
623 { 622 {
624 if (!elem) 623 if (!elem)
625 return false; 624 return false;
626 625
627 var range = elem.ownerDocument.createRange(); 626 var range = elem.ownerDocument.createRange();
628 range.selectNodeContents(elem); 627 range.selectNodeContents(elem);
629 var selection = {rangeCount: 1, getRangeAt: function() {return range}}; 628 var selection = {rangeCount: 1, getRangeAt: function() {return range}};
630 629
631 this.window.openDialog("chrome://global/content/viewPartialSource.xul", "_bl ank", "scrollbars,resizable,chrome,dialog=no", 630 this.window.openDialog("chrome://global/content/viewPartialSource.xul", "_bl ank", "scrollbars,resizable,chrome,dialog=no",
632 null, null, selection, "selection"); 631 null, null, selection, "selection");
633 return true; 632 return true;
634 }, 633 },
635 634
636 getOuterHtmlFormatted: function(node, container) 635 getOuterHtmlFormatted: function(node, container)
637 { 636 {
638 var type = null; 637 var type = null;
639 switch (node.nodeType) 638 switch (node.nodeType)
640 { 639 {
641 case node.ELEMENT_NODE: 640 case node.ELEMENT_NODE:
642 var box = this.window.document.createElement("vbox"); 641 var box = this.window.document.createElement("vbox");
643 box.className = "elementBox"; 642 box.className = "elementBox";
644 643
645 var startTag = this.window.document.createElement("hbox"); 644 var startTag = this.window.document.createElement("hbox");
646 startTag.className = "elementStartTag"; 645 startTag.className = "elementStartTag";
647 if (!node.firstElementChild) 646 if (!node.firstElementChild)
648 startTag.className += " elementEndTag"; 647 startTag.className += " elementEndTag";
649 648
650 this.appendDescription(startTag, "<", null); 649 this.appendDescription(startTag, "<", null);
651 this.appendDescription(startTag, node.tagName, "tagName"); 650 this.appendDescription(startTag, node.tagName, "tagName");
652 651
653 for (var i = 0; i < node.attributes.length; i++) 652 for (var i = 0; i < node.attributes.length; i++)
654 { 653 {
655 var attr = node.attributes[i]; 654 var attr = node.attributes[i];
656 this.appendDescription(startTag, attr.name, "attrName"); 655 this.appendDescription(startTag, attr.name, "attrName");
657 if (attr.value != "") 656 if (attr.value != "")
658 { 657 {
659 this.appendDescription(startTag, "=", null); 658 this.appendDescription(startTag, "=", null);
660 this.appendDescription(startTag, '"' + attr.value.replace(/"/, "&quo t;") + '"', "attrValue"); 659 this.appendDescription(startTag, '"' + attr.value.replace(/"/, "&quo t;") + '"', "attrValue");
661 } 660 }
662 } 661 }
663 662
664 this.appendDescription(startTag, node.firstElementChild ? ">" : " />", n ull); 663 this.appendDescription(startTag, node.firstElementChild ? ">" : " />", n ull);
665 box.appendChild(startTag); 664 box.appendChild(startTag);
666 665
667 if (node.firstElementChild) 666 if (node.firstElementChild)
668 { 667 {
669 for (var child = node.firstElementChild; child; child = child.nextElem entSibling) 668 for (var child = node.firstElementChild; child; child = child.nextElem entSibling)
670 this.getOuterHtmlFormatted(child, box); 669 this.getOuterHtmlFormatted(child, box);
671 670
672 var endTag = this.window.document.createElement("hbox"); 671 var endTag = this.window.document.createElement("hbox");
673 endTag.className = "elementEndTag"; 672 endTag.className = "elementEndTag";
674 this.appendDescription(endTag, "<", null); 673 this.appendDescription(endTag, "<", null);
675 this.appendDescription(endTag, "/" + node.tagName, "tagName"); 674 this.appendDescription(endTag, "/" + node.tagName, "tagName");
676 this.appendDescription(endTag, ">", null); 675 this.appendDescription(endTag, ">", null);
677 box.appendChild(endTag); 676 box.appendChild(endTag);
678 } 677 }
679 container.appendChild(box); 678 container.appendChild(box);
680 return; 679 return;
681 680
682 case node.TEXT_NODE: 681 case node.TEXT_NODE:
683 type = "text"; 682 type = "text";
684 break; 683 break;
685 case node.CDATA_SECTION_NODE: 684 case node.CDATA_SECTION_NODE:
686 type = "cdata"; 685 type = "cdata";
687 break; 686 break;
688 case node.COMMENT_NODE: 687 case node.COMMENT_NODE:
689 type = "comment"; 688 type = "comment";
690 break; 689 break;
691 default: 690 default:
692 return; 691 return;
693 } 692 }
694 693
695 var text = node.nodeValue.replace(/\r/g, '').replace(/^\s+/, '').replace(/\s +$/, ''); 694 var text = node.nodeValue.replace(/\r/g, '').replace(/^\s+/, '').replace(/\s +$/, '');
696 if (text == "") 695 if (text == "")
697 return; 696 return;
698 697
699 if (type != "cdata") 698 if (type != "cdata")
700 { 699 {
701 text = text.replace(/&/g, "&amp;") 700 text = text.replace(/&/g, "&amp;")
702 .replace(/</g, "&lt;") 701 .replace(/</g, "&lt;")
703 .replace(/>/g, "&gt;"); 702 .replace(/>/g, "&gt;");
704 } 703 }
705 text = text.replace(/\t/g, " "); 704 text = text.replace(/\t/g, " ");
706 if (type == "cdata") 705 if (type == "cdata")
707 text = "<![CDATA[" + text + "]]>"; 706 text = "<![CDATA[" + text + "]]>";
708 else if (type == "comment") 707 else if (type == "comment")
709 text = "<!--" + text + "-->"; 708 text = "<!--" + text + "-->";
710 709
711 var lines = text.split("\n"); 710 var lines = text.split("\n");
712 for (var i = 0; i < lines.length; i++) 711 for (var i = 0; i < lines.length; i++)
713 this.appendDescription(container, lines[i].replace(/^\s+/, '').replace(/\s +$/, ''), type); 712 this.appendDescription(container, lines[i].replace(/^\s+/, '').replace(/\s +$/, ''), type);
714 }, 713 },
715 714
716 showMenu: function() 715 showMenu: function()
717 { 716 {
718 var helpBox = E("ehh-helpbox"); 717 var helpBox = E("ehh-helpbox");
719 if (helpBox.state == "open") 718 if (helpBox.state == "open")
720 { 719 {
721 helpBox.hidePopup(); 720 helpBox.hidePopup();
722 return true; 721 return true;
723 } 722 }
724 723
725 // Show help box 724 // Show help box
726 helpBox.showPopup(this.browser, -1, -1, "tooltip", "topleft", "topleft"); 725 helpBox.showPopup(this.browser, -1, -1, "tooltip", "topleft", "topleft");
727 return true; 726 return true;
728 } 727 }
729 } 728 }
730 729
731 // Makes sure event handlers like Aardvark.onKeyPress always have the correct 730 // Makes sure event handlers like Aardvark.onKeyPress always have the correct
732 // this pointer set. 731 // this pointer set.
733 for each (let method in ["onMouseClick", "onMouseScroll", "onKeyPress", "onPageH ide", "onMouseMove", "onAfterPaint", "quit"]) 732 for each (let method in ["onMouseClick", "onMouseScroll", "onKeyPress", "onPageH ide", "onMouseMove", "onAfterPaint", "quit"])
734 Aardvark[method] = Aardvark[method].bind(Aardvark); 733 Aardvark[method] = Aardvark[method].bind(Aardvark);
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld