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

Delta Between Two Patch Sets: mobile-options.js

Issue 29488575: Issue 5384 - Introduced dedicated mobile options page (Closed)
Left Patch Set: Encapsulated mobile-options.js script Created July 18, 2017, 5:38 p.m.
Right Patch Set: Added ID constants Created Aug. 28, 2017, 2:51 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 | « mobile-options.html ('k') | skin/fonts/Source-Sans-Pro/300.woff2 » ('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 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2017 eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 /* globals getDocLink */ 18 /* globals getDocLink */
19 19
20 "use strict"; 20 "use strict";
21 21
22 { 22 {
23 const {getMessage} = ext.i18n; 23 const {getMessage} = ext.i18n;
24 24
25 const dialogSubscribe = "subscribe";
26 const idAcceptableAds = "acceptableAds";
27 const idRecommended = "subscriptions-recommended";
25 let whitelistFilter = null; 28 let whitelistFilter = null;
26 let promisedAcceptableAdsUrl = getAcceptableAdsUrl(); 29 let promisedAcceptableAdsUrl = getAcceptableAdsUrl();
27 30
28 /* Utility functions */ 31 /* Utility functions */
29 32
30 function get(selector, origin) 33 function get(selector, origin)
31 { 34 {
32 return (origin || document).querySelector(selector); 35 return (origin || document).querySelector(selector);
33 } 36 }
34 37
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 { 87 {
85 return new Promise((resolve, reject) => 88 return new Promise((resolve, reject) =>
86 { 89 {
87 ext.backgroundPage.sendMessage( 90 ext.backgroundPage.sendMessage(
88 {type: "prefs.get", key: "subscriptions_exceptionsurl"}, 91 {type: "prefs.get", key: "subscriptions_exceptionsurl"},
89 resolve 92 resolve
90 ); 93 );
91 }); 94 });
92 } 95 }
93 96
94 function getRecommended() 97 function getRecommendedAds()
95 { 98 {
96 return fetch("subscriptions.xml") 99 return fetch("subscriptions.xml")
97 .then((resp) => resp.text()) 100 .then((response) => response.text())
98 .then((text) => 101 .then((text) =>
99 { 102 {
100 let doc = new DOMParser().parseFromString(text, "application/xml"); 103 let doc = new DOMParser().parseFromString(text, "application/xml");
101 let elements = Array.from(doc.getElementsByTagName("subscription")); 104 let elements = Array.from(doc.getElementsByTagName("subscription"));
102 105
103 return elements 106 return elements
104 .filter((element) => element.getAttribute("type") == "ads") 107 .filter((element) => element.getAttribute("type") == "ads")
105 .map((element) => 108 .map((element) =>
106 { 109 {
107 return { 110 return {
(...skipping 18 matching lines...) Expand all
126 129
127 function setSubscription({disabled, title, url}, shouldAdd) 130 function setSubscription({disabled, title, url}, shouldAdd)
128 { 131 {
129 if (disabled) 132 if (disabled)
130 return; 133 return;
131 134
132 promisedAcceptableAdsUrl.then((acceptableAdsUrl) => 135 promisedAcceptableAdsUrl.then((acceptableAdsUrl) =>
133 { 136 {
134 if (url == acceptableAdsUrl) 137 if (url == acceptableAdsUrl)
135 { 138 {
136 get("#acceptableAds").checked = true; 139 get(`#${idAcceptableAds}`).checked = true;
137 return; 140 return;
138 } 141 }
139 142
140 let listInstalled = get("#subscriptions-installed"); 143 let listInstalled = get("#subscriptions-installed");
141 let installed = get(`[data-url="${url}"]`, listInstalled); 144 let installed = get(`[data-url="${url}"]`, listInstalled);
142 145
143 if (installed) 146 if (installed)
144 { 147 {
145 let titleElement = get("span", installed); 148 let titleElement = get("span", installed);
146 titleElement.textContent = title || url; 149 titleElement.textContent = title || url;
147 } 150 }
148 else if (shouldAdd) 151 else if (shouldAdd)
149 { 152 {
150 let element = create(listInstalled, "li", null, {"data-url": url}); 153 let element = create(listInstalled, "li", null, {"data-url": url});
151 create(element, "span", title || url); 154 create(element, "span", title || url);
152 create(element, "button", null, {class: "remove"}, 155 create(element, "button", null, {class: "remove"},
153 () => uninstallSubscription(url) 156 () => uninstallSubscription(url)
154 ); 157 );
155 158
156 let recommended = get(`#subscriptions-recommended [data-url="${url}"]`); 159 let recommended = get(`#${idRecommended} [data-url="${url}"]`);
157 if (recommended) 160 if (recommended)
158 { 161 {
159 recommended.classList.add("installed"); 162 recommended.classList.add("installed");
160 } 163 }
161 } 164 }
162 }); 165 });
163 } 166 }
164 167
165 function removeSubscription(url) 168 function removeSubscription(url)
166 { 169 {
167 promisedAcceptableAdsUrl.then((acceptableAdsUrl) => 170 promisedAcceptableAdsUrl.then((acceptableAdsUrl) =>
168 { 171 {
169 if (url == acceptableAdsUrl) 172 if (url == acceptableAdsUrl)
170 { 173 {
171 get("#acceptable-ads").checked = false; 174 get(`#${idAcceptableAds}`).checked = false;
172 return; 175 return;
173 } 176 }
174 177
175 let installed = get(`#subscriptions-installed [data-url="${url}"]`); 178 let installed = get(`#subscriptions-installed [data-url="${url}"]`);
176 if (installed) 179 if (installed)
177 { 180 {
178 installed.parentNode.removeChild(installed); 181 installed.parentNode.removeChild(installed);
179 } 182 }
180 183
181 let recommended = get(`#subscriptions-recommended [data-url="${url}"]`); 184 let recommended = get(`#${idRecommended} [data-url="${url}"]`);
182 if (recommended) 185 if (recommended)
183 { 186 {
184 recommended.classList.remove("installed"); 187 recommended.classList.remove("installed");
185 } 188 }
186 }); 189 });
187 } 190 }
188 191
189 function setDialog(id, options) 192 function setDialog(id, options)
190 { 193 {
191 if (!id) 194 if (!id)
192 { 195 {
193 delete document.body.dataset.dialog; 196 delete document.body.dataset.dialog;
194 return; 197 return;
195 } 198 }
196 199
197 let fields = getAll(`#dialog-${id} input`); 200 let fields = getAll(`#dialog-${id} input`);
198 for (let field of fields) 201 for (let field of fields)
199 { 202 {
200 field.value = (options && field.name in options) ? options[field.name] : " "; 203 let {name} = field;
204 field.value = (options && name in options) ? options[name] : "";
201 } 205 }
202 setError(id, null); 206 setError(id, null);
203 207
204 document.body.dataset.dialog = id; 208 document.body.dataset.dialog = id;
205 } 209 }
206 210
207 function setError(dialogId, message) 211 function setError(dialogId, fieldName)
208 { 212 {
209 let dialog = get(`#dialog-${dialogId}`); 213 let dialog = get(`#dialog-${dialogId}`);
210 if (message) 214 if (fieldName)
211 { 215 {
212 dialog.dataset.error = message; 216 dialog.dataset.error = fieldName;
213 } 217 }
214 else 218 else
215 { 219 {
216 delete dialog.dataset.error; 220 delete dialog.dataset.error;
217 } 221 }
218 } 222 }
219 223
220 function populateLists() 224 function populateLists()
221 { 225 {
222 Promise.all([getInstalled(), getRecommended()]) 226 Promise.all([getInstalled(), getRecommendedAds()])
223 .then(([installed, recommended]) => 227 .then(([installed, recommended]) =>
224 { 228 {
225 let listRecommended = get("#subscriptions-recommended"); 229 let listRecommended = get(`#${idRecommended}`);
226 for (let {title, url} of recommended) 230 for (let {title, url} of recommended)
227 { 231 {
228 create(listRecommended, "li", title, {"data-url": url}, 232 create(listRecommended, "li", title, {"data-url": url},
229 (ev) => 233 (ev) =>
230 { 234 {
231 if (ev.target.classList.contains("installed")) 235 if (ev.target.classList.contains("installed"))
232 return; 236 return;
233 237
234 setDialog("subscribe", {title, url}); 238 setDialog(dialogSubscribe, {title, url});
235 } 239 }
236 ); 240 );
237 } 241 }
238 242
239 for (let subscription of installed) 243 for (let subscription of installed)
240 { 244 {
241 if (subscription.disabled) 245 if (subscription.disabled)
242 continue; 246 continue;
243 247
244 setSubscription(subscription, true); 248 setSubscription(subscription, true);
245 } 249 }
246 }) 250 })
247 .catch((err) => console.error(err)); 251 .catch((err) => console.error(err));
248 } 252 }
249 253
250 /* Listeners */ 254 /* Listeners */
251 255
252 function onChange(ev) 256 function onChange(ev)
253 { 257 {
254 if (ev.target.id != "acceptable-ads") 258 if (ev.target.id != idAcceptableAds)
255 return; 259 return;
256 260
257 promisedAcceptableAdsUrl.then((acceptableAdsUrl) => 261 promisedAcceptableAdsUrl.then((acceptableAdsUrl) =>
258 { 262 {
259 if (ev.target.checked) 263 if (ev.target.checked)
260 { 264 {
261 installSubscription(acceptableAdsUrl, null); 265 installSubscription(acceptableAdsUrl, null);
262 } 266 }
263 else 267 else
264 { 268 {
265 uninstallSubscription(acceptableAdsUrl); 269 uninstallSubscription(acceptableAdsUrl);
266 } 270 }
267 }); 271 });
268 } 272 }
269 document.addEventListener("change", onChange); 273 document.addEventListener("change", onChange);
274
275 function toggleWhitelistFilter(toggle)
276 {
277 if (whitelistFilter)
278 {
279 ext.backgroundPage.sendMessage(
280 {
281 type: (toggle.checked) ? "filters.remove" : "filters.add",
282 text: whitelistFilter
283 },
284 (errors) =>
285 {
286 if (errors.length < 1)
287 return;
288
289 console.error(errors);
290 toggle.checked = !toggle.checked;
291 }
292 );
293 }
294 else
295 {
296 console.error("Whitelist filter hasn't been initialized yet");
297 }
298 }
270 299
271 function onClick(ev) 300 function onClick(ev)
272 { 301 {
273 switch (ev.target.dataset.action) 302 switch (ev.target.dataset.action)
274 { 303 {
275 case "close-dialog": 304 case "close-dialog":
276 setDialog(null); 305 setDialog(null);
277 break; 306 break;
278 case "open-dialog": 307 case "open-dialog":
279 setDialog(ev.target.dataset.dialog); 308 setDialog(ev.target.dataset.dialog);
309 break;
310 case "toggle-enabled":
311 toggleWhitelistFilter(ev.target);
312 ev.preventDefault();
280 break; 313 break;
281 } 314 }
282 } 315 }
283 document.addEventListener("click", onClick); 316 document.addEventListener("click", onClick);
284 317
285 function onSubmit(ev) 318 function onSubmit(ev)
286 { 319 {
287 let fields = ev.target.elements; 320 let fields = ev.target.elements;
288 let title = fields.title.value; 321 let title = fields.title.value;
289 let url = fields.url.value; 322 let url = fields.url.value;
290 323
291 if (!title) 324 if (!title)
292 { 325 {
293 setError("subscribe", "title"); 326 setError(dialogSubscribe, "title");
294 } 327 }
295 else if (!url) 328 else if (!url)
296 { 329 {
297 setError("subscribe", "url"); 330 setError(dialogSubscribe, "url");
298 } 331 }
299 else 332 else
300 { 333 {
301 installSubscription(url, title); 334 installSubscription(url, title);
302 setDialog(null); 335 setDialog(null);
303 } 336 }
304 337
305 ev.preventDefault(); 338 ev.preventDefault();
306 } 339 }
307 document.addEventListener("submit", onSubmit); 340 document.addEventListener("submit", onSubmit);
308 341
309 function onToggleWhitelistFilter(ev)
310 {
311 let checkbox = ev.target;
312 ext.backgroundPage.sendMessage(
313 {
314 type: (checkbox.checked) ? "filters.remove" : "filters.add",
315 text: whitelistFilter
316 }, (errors) =>
317 {
318 if (errors.length < 1)
319 return;
320
321 console.error(errors);
322 checkbox.checked = !checkbox.checked;
323 }
324 );
325 ev.preventDefault();
326 }
327
328 function onMessage(msg) 342 function onMessage(msg)
329 { 343 {
330 switch (msg.type) 344 switch (msg.type)
331 { 345 {
332 case "app.respond": { 346 case "app.respond": {
333 switch (msg.action) 347 switch (msg.action)
334 { 348 {
335 case "addSubscription": 349 case "addSubscription":
336 let [subscription] = msg.args; 350 let [subscription] = msg.args;
337 setDialog("subscribe", { 351 setDialog(dialogSubscribe, {
338 title: subscription.title, 352 title: subscription.title,
339 url: subscription.url 353 url: subscription.url
340 }); 354 });
341 break; 355 break;
342 case "showPageOptions": 356 case "showPageOptions":
343 let [{host, whitelisted}] = msg.args; 357 let [{host, whitelisted}] = msg.args;
344 whitelistFilter = `@@||${host}^$document`; 358 whitelistFilter = `@@||${host}^$document`;
345 359
346 ext.i18n.setElementText( 360 ext.i18n.setElementText(
347 get("#enabled-label"), 361 get("#enabled-label"),
348 "mops_enabled_label", 362 "mops_enabled_label",
349 [host] 363 [host]
350 ); 364 );
351 365
352 let checkbox = get("#enabled"); 366 let toggle = get("#enabled");
353 checkbox.checked = !whitelisted; 367 toggle.checked = !whitelisted;
354 checkbox.addEventListener("click", onToggleWhitelistFilter);
355 368
356 get("#enabled-container").hidden = false; 369 get("#enabled-container").hidden = false;
357 break; 370 break;
358 } 371 }
359 break; 372 break;
360 } 373 }
361 case "filters.respond": { 374 case "filters.respond": {
362 let [filter] = msg.args; 375 let [filter] = msg.args;
363 if (!whitelistFilter || filter.text != whitelistFilter) 376 if (!whitelistFilter || filter.text != whitelistFilter)
364 break; 377 break;
(...skipping 15 matching lines...) Expand all
380 } 393 }
381 else 394 else
382 { 395 {
383 setSubscription(subscription, true); 396 setSubscription(subscription, true);
384 } 397 }
385 break; 398 break;
386 case "removed": 399 case "removed":
387 removeSubscription(subscription.url); 400 removeSubscription(subscription.url);
388 break; 401 break;
389 case "title": 402 case "title":
390 // We're also receiving these messages for subscriptions that are no t 403 // We're also receiving these messages for subscriptions that are
391 // installed so we shouldn't add those by accident 404 // not installed so we shouldn't add those by accident
392 setSubscription(subscription, false); 405 setSubscription(subscription, false);
393 break; 406 break;
394 } 407 }
395 break; 408 break;
396 } 409 }
397 } 410 }
398 } 411 }
399 ext.onMessage.addListener(onMessage); 412 ext.onMessage.addListener(onMessage);
400 413
401 ext.backgroundPage.sendMessage({ 414 ext.backgroundPage.sendMessage({
(...skipping 23 matching lines...) Expand all
425 get("#dialog-subscribe [name='title']").setAttribute( 438 get("#dialog-subscribe [name='title']").setAttribute(
426 "placeholder", 439 "placeholder",
427 getMessage("mops_subscribe_title") 440 getMessage("mops_subscribe_title")
428 ); 441 );
429 442
430 get("#dialog-subscribe [name='url']").setAttribute( 443 get("#dialog-subscribe [name='url']").setAttribute(
431 "placeholder", 444 "placeholder",
432 getMessage("mops_subscribe_url") 445 getMessage("mops_subscribe_url")
433 ); 446 );
434 } 447 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld