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

Delta Between Two Patch Sets: lib/child/selection.js

Issue 29363476: Issue 2879 - Move element selection into the content process (Closed) Base URL: https://hg.adblockplus.org/elemhidehelper
Left Patch Set: Created Nov. 17, 2016, 1:17 p.m.
Right 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « lib/child/nodeInfo.js ('k') | lib/child/utils.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
saroyanm 2016/11/23 17:44:39 I thought that this code belongs to Aardvark ? Wha
Wladimir Palant 2016/11/24 14:02:01 Yes, E10S is the reason for this whole change. Any
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 "use strict"; 7 "use strict";
8 8
9 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); 9 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
10 10
11 let messageManager = require("messageManager"); 11 let messageManager = require("messageManager");
12 let { 12 let {
13 createElement, getWindowSize, getParentElement, getElementPosition 13 createElement, getWindowSize, getParentElement, getElementPosition
14 } = require("./utils"); 14 } = require("./utils");
15 15
16 /**
17 * @typedef State
18 * @type {Object}
19 * @property {Window} window
20 * The top-level window that we are selecting in.
21 * @property {Element} boxElement
22 * The element marking the current selection.
23 * @property {Element} anchorElement
24 * The element that received the last mouse event.
25 * @property {Element} selectedElement
26 * The element currently selected (usually anchorElement or a parent element
27 * of it).
28 * @property {boolean} isUserSelected
29 * Will be true if the user narrowed down the selection to a specific element
30 * using wider/narrower commands.
31 * @property {Element} lockedAnchor
32 * When selection is locked, this property will be updated by mouse events
33 * instead of anchorElement.
34 * @property {number} prevSelectionUpdate
35 * Time of previous selection update, used for rate limiting.
36 * @property {Object} prevPos
37 * Position and size of selected element during previous selection update.
38 */
39
40 /**
41 * Current selection state. This object will be empty if no selection is
42 * currently in progress.
43 *
44 * @type {State}
45 */
16 let state = exports.state = {}; 46 let state = exports.state = {};
Wladimir Palant 2016/11/17 13:54:48 Original code was storing the selection state as p
saroyanm 2016/11/23 17:44:39 We are setting the properties of state in other fu
Wladimir Palant 2016/11/24 14:02:02 Setting them here doesn't make sense - the definit
17 47
18 messageManager.addMessageListener("ElemHideHelper:StartSelection", startSelectio n); 48 messageManager.addMessageListener("ElemHideHelper:StartSelection", startSelectio n);
19 49
20 onShutdown.add(() => 50 onShutdown.add(() =>
21 { 51 {
22 messageManager.removeMessageListener("ElemHideHelper:StartSelection", startSel ection); 52 messageManager.removeMessageListener("ElemHideHelper:StartSelection", startSel ection);
23 53
24 stopSelection(); 54 stopSelection();
25 }); 55 });
26 56
27 function startSelection(message) 57 function startSelection(message)
28 { 58 {
29 stopSelection(); 59 stopSelection();
30 60
31 let outerWindowID = message.data; 61 let outerWindowID = message.data;
32 let wnd = Services.wm.getOuterWindowWithId(outerWindowID); 62 let wnd = Services.wm.getOuterWindowWithId(outerWindowID);
33 if (!wnd || !canSelect(wnd)) 63 if (!wnd || !canSelect(wnd))
34 return; 64 return;
35 65
36 state.window = wnd; 66 state.window = wnd;
37 state.id = outerWindowID;
38 67
39 wnd.addEventListener("click", onMouseClick, true); 68 wnd.addEventListener("click", onMouseClick, true);
40 wnd.addEventListener("wheel", onMouseScroll, true); 69 wnd.addEventListener("wheel", onMouseScroll, true);
saroyanm 2016/11/23 17:44:39 It's a deprecated event: https://developer.mozilla
Wladimir Palant 2016/11/24 14:02:02 That page is about the mousewheel event, not wheel
41 wnd.addEventListener("mousemove", onMouseMove, true); 70 wnd.addEventListener("mousemove", onMouseMove, true);
42 wnd.addEventListener("pagehide", onPageHide, true); 71 wnd.addEventListener("pagehide", onPageHide, true);
43 72
44 wnd.focus(); 73 wnd.focus();
45 74
46 let doc = wnd.document; 75 let doc = wnd.document;
47 let {elementMarkerClass} = require("info"); 76 let {elementMarkerClass} = require("info");
48 state.boxElement = createElement(doc, "div", {"class": elementMarkerClass}, [ 77 state.boxElement = createElement(doc, "div", {"class": elementMarkerClass}, [
49 createElement(doc, "div", {"class": "ehh-border"}), 78 createElement(doc, "div", {"class": "ehh-border"}),
50 createElement(doc, "div", {"class": "ehh-label"}, [ 79 createElement(doc, "div", {"class": "ehh-label"}, [
(...skipping 25 matching lines...) Expand all
76 105
77 for (let key of Object.keys(state)) 106 for (let key of Object.keys(state))
78 delete state[key]; 107 delete state[key];
79 108
80 messageManager.sendAsyncMessage("ElemHideHelper:SelectionStopped"); 109 messageManager.sendAsyncMessage("ElemHideHelper:SelectionStopped");
81 } 110 }
82 exports.stopSelection = stopSelection; 111 exports.stopSelection = stopSelection;
83 112
84 function canSelect(wnd) 113 function canSelect(wnd)
85 { 114 {
86 let acceptlocalfiles; 115 let acceptLocalFiles;
saroyanm 2016/11/23 17:44:39 Nit: camelCase is missing
Wladimir Palant 2016/11/24 14:02:02 Done.
87 try 116 try
88 { 117 {
89 acceptlocalfiles = Services.prefs.getBoolPref("extensions.elemhidehelper.acc eptlocalfiles"); 118 let pref = "extensions.elemhidehelper.acceptlocalfiles";
saroyanm 2016/11/23 17:44:39 Nit: exceeding 80 chars.
Wladimir Palant 2016/11/24 14:02:01 Done.
119 acceptLocalFiles = Services.prefs.getBoolPref(pref);
90 } 120 }
91 catch (e) 121 catch (e)
92 { 122 {
93 acceptlocalfiles = false; 123 acceptLocalFiles = false;
94 } 124 }
95 125
96 if (!acceptlocalfiles) 126 if (!acceptLocalFiles)
97 { 127 {
98 let localSchemes; 128 let localSchemes;
99 try 129 try
100 { 130 {
101 localSchemes = new Set( 131 localSchemes = new Set(
102 Services.prefs.getCharPref("extensions.adblockplus.whitelistschemes") 132 Services.prefs.getCharPref("extensions.adblockplus.whitelistschemes")
103 .split(/\s+/) 133 .split(/\s+/)
104 ); 134 );
Wladimir Palant 2016/11/17 13:54:48 This changes the original logic which was simply h
105 } 135 }
106 catch (e) 136 catch (e)
107 { 137 {
108 localSchemes = new Set(); 138 localSchemes = new Set();
109 } 139 }
110 140
111 if (localSchemes.has(wnd.location.protocol.replace(/:$/, ""))) 141 if (localSchemes.has(wnd.location.protocol.replace(/:$/, "")))
112 return false; 142 return false;
113 } 143 }
114 144
115 return true; 145 return true;
116 } 146 }
117 147
118 function getElementLabel(elem) 148 function getElementLabel(elem)
119 { 149 {
120 let tagName = elem.localName; 150 let tagName = elem.localName;
saroyanm 2016/11/23 17:44:39 localName is a deprecated property: https://develo
Wladimir Palant 2016/11/24 14:02:02 That would have been surprising - the docs say tha
121 let addition = ""; 151 let addition = "";
122 if (elem.id != "") 152 if (elem.id != "")
123 addition += ", id: " + elem.id; 153 addition += ", id: " + elem.id;
124 if (elem.className != "") 154 if (elem.className != "")
125 addition += ", class: " + elem.className; 155 addition += ", class: " + elem.className;
126 if (elem.style.cssText != "") 156 if (elem.style.cssText != "")
127 addition += ", style: " + elem.style.cssText; 157 addition += ", style: " + elem.style.cssText;
saroyanm 2016/11/23 17:44:39 Weak suggestion: What about mentioning that it's n
Wladimir Palant 2016/11/24 14:02:02 Hasn't lead to any confusion so far, we can just a
128 158
129 return [tagName, addition]; 159 return [tagName, addition];
130 } 160 }
131 161
132 function setAnchorElement(anchor) 162 function setAnchorElement(anchor)
saroyanm 2016/11/23 17:44:39 What is the anchor element ? I assume it's not rel
Wladimir Palant 2016/11/24 14:02:01 Nope. I've documented the state properties now, sh
133 { 163 {
134 state.anchorElement = anchor; 164 state.anchorElement = anchor;
135 165
136 let newSelection = anchor; 166 let newSelection = anchor;
137 if (state.isUserSelected) 167 if (state.isUserSelected)
138 { 168 {
139 // User chose an element via wider/narrower commands, keep the selection if 169 // User chose an element via wider/narrower commands, keep the selection if
140 // our new anchor is still a child of that element 170 // our new anchor is still a child of that element
141 let e = newSelection; 171 let e = newSelection;
142 while (e && e != state.selectedElement) 172 while (e && e != state.selectedElement)
(...skipping 16 matching lines...) Expand all
159 189
160 let border = state.boxElement.querySelector(".ehh-border"); 190 let border = state.boxElement.querySelector(".ehh-border");
161 let label = state.boxElement.querySelector(".ehh-label"); 191 let label = state.boxElement.querySelector(".ehh-label");
162 let labelTag = state.boxElement.querySelector(".ehh-labelTag"); 192 let labelTag = state.boxElement.querySelector(".ehh-labelTag");
163 let labelAddition = state.boxElement.querySelector(".ehh-labelAddition"); 193 let labelAddition = state.boxElement.querySelector(".ehh-labelAddition");
164 194
165 let doc = state.window.document; 195 let doc = state.window.document;
166 let [wndWidth, wndHeight] = getWindowSize(state.window); 196 let [wndWidth, wndHeight] = getWindowSize(state.window);
167 197
168 let pos = getElementPosition(elem); 198 let pos = getElementPosition(elem);
169 state.boxElement.style.left = Math.min(pos.left - 1, wndWidth - 2) + "px"; 199 state.boxElement.style.left = Math.min(pos.left - 1, wndWidth - 2) + "px";
saroyanm 2016/11/23 17:44:38 Is this approach even working with RTL websites ?
Wladimir Palant 2016/11/24 14:02:01 Well, it works with RTL websites. Our UI is always
saroyanm 2016/11/25 16:18:13 Here you go: #4665
170 state.boxElement.style.top = Math.min(pos.top - 1, wndHeight - 2) + "px"; 200 state.boxElement.style.top = Math.min(pos.top - 1, wndHeight - 2) + "px";
171 border.style.width = Math.max(pos.right - pos.left - 2, 0) + "px"; 201 border.style.width = Math.max(pos.right - pos.left - 2, 0) + "px";
172 border.style.height = Math.max(pos.bottom - pos.top - 2, 0) + "px"; 202 border.style.height = Math.max(pos.bottom - pos.top - 2, 0) + "px";
173 203
174 [labelTag.textContent, labelAddition.textContent] = getElementLabel(elem); 204 [labelTag.textContent, labelAddition.textContent] = getElementLabel(elem);
175 205
176 // If there is not enough space to show the label move it up a little 206 // If there is not enough space to show the label move it up a little
177 if (pos.bottom < wndHeight - 25) 207 if (pos.bottom < wndHeight - 25)
178 label.className = "ehh-label"; 208 label.className = "ehh-label";
179 else 209 else
(...skipping 26 matching lines...) Expand all
206 236
207 require("./commands").select(); 237 require("./commands").select();
208 event.preventDefault(); 238 event.preventDefault();
209 } 239 }
210 240
211 function onMouseScroll(event) 241 function onMouseScroll(event)
212 { 242 {
213 if (!event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) 243 if (!event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
214 return; 244 return;
215 245
216 let delta = event.deltaY || event.deltaX; 246 let delta = event.deltaY || event.deltaX;
Wladimir Palant 2016/11/17 13:54:48 This was dead code originally, using DOMMouseScrol
saroyanm 2016/11/23 17:44:38 Acknowledged.
217 if (!delta) 247 if (!delta)
218 return; 248 return;
219 249
220 let commands = require("./commands"); 250 let commands = require("./commands");
saroyanm 2016/11/23 17:44:38 Detail: we already loading the module in onMouseCl
Wladimir Palant 2016/11/24 14:02:01 That would create a circular reference.
221 if (delta > 0) 251 if (delta > 0)
222 commands.wider(); 252 commands.wider();
223 else 253 else
224 commands.narrower(); 254 commands.narrower();
225 event.preventDefault(); 255 event.preventDefault();
226 } 256 }
227 257
228 function onMouseMove(event) 258 function onMouseMove(event)
229 { 259 {
230 hideSelection(); 260 hideSelection();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 selectElement(state.selectedElement); 292 selectElement(state.selectedElement);
263 } 293 }
264 } 294 }
265 } 295 }
266 296
267 function onPageHide(event) 297 function onPageHide(event)
268 { 298 {
269 stopSelection(); 299 stopSelection();
270 } 300 }
271 301
272 function onAfterPaint(event) 302 function onAfterPaint(event)
Wladimir Palant 2016/11/17 13:54:48 This code path is untested, I'm not sure whether i
saroyanm 2016/11/23 17:44:39 We do have "onMouseScroll" function, I thought it
Wladimir Palant 2016/11/24 14:02:02 Given that the purpose of this function is selecti
273 { 303 {
274 // Don't update position too often 304 // Don't update position too often
275 if (state.selectedElement && Date.now() - state.prevSelectionUpdate > 20) 305 if (state.selectedElement && Date.now() - state.prevSelectionUpdate > 20)
276 { 306 {
277 let pos = getElementPosition(state.selectedElement); 307 let pos = getElementPosition(state.selectedElement);
278 if (!state.prevPos || state.prevPos.left != pos.left || 308 if (!state.prevPos || state.prevPos.left != pos.left ||
279 state.prevPos.right != pos.right || state.prevPos.top != pos.top || 309 state.prevPos.right != pos.right || state.prevPos.top != pos.top ||
280 state.prevPos.bottom != pos.bottom) 310 state.prevPos.bottom != pos.bottom)
281 { 311 {
282 selectElement(state.selectedElement); 312 selectElement(state.selectedElement);
283 } 313 }
284 } 314 }
285 } 315 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld