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

Delta Between Two Patch Sets: options.js

Issue 6088024630755328: issue 1526 - Implement new options page design for Chrome/Opera/Safari (Closed)
Left Patch Set: Created Feb. 26, 2015, 11:50 a.m.
Right Patch Set: Comment about solution being temprorary is added to subscriptions.xml Created June 13, 2015, 12:59 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 | « options.html ('k') | skin/options.css » ('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-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 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 "use strict"; 18 "use strict";
19 19
20 (function() 20 (function()
21 { 21 {
22 var acceptableAdsUrl = null;
23 var subscriptionsMap = Object.create(null); 22 var subscriptionsMap = Object.create(null);
24 var recommendationsMap = Object.create(null); 23 var recommendationsMap = Object.create(null);
25 var filtersMap = Object.create(null); 24 var filtersMap = Object.create(null);
26 var collections = Object.create(null); 25 var collections = Object.create(null);
27 26
28 function Collection(details) 27 function Collection(details)
saroyanm 2015/02/26 12:18:33 We can rethink about the name of current Class in
Thomas Greiner 2015/03/05 11:36:03 I guess "Collection" should be fine (see Java's Co
Thomas Greiner 2015/03/05 11:36:03 Why "details"? It's an array of items and not a co
saroyanm 2015/03/06 11:54:32 I used details as I thought that it's corresponds
Thomas Greiner 2015/03/12 11:41:56 Makes sense, let's stick with "details" then.
29 { 28 {
30 this.details = details; 29 this.details = details;
31 } 30 this.items = [];
32 31 }
33 Collection.prototype = Object.create(Array.prototype); 32
34 Collection.prototype.addItems = function() 33 Collection.prototype.addItems = function()
Thomas Greiner 2015/03/05 11:36:03 I couldn't find a case where you add multiple item
saroyanm 2015/03/06 11:54:32 I actually were thinking that this could be useful
Thomas Greiner 2015/03/12 11:41:56 Ok, then let's leave it like it is for now (no nee
saroyanm 2015/03/12 14:03:22 Done.
35 { 34 {
36 var length = Array.prototype.push.apply(this, arguments); 35 var length = Array.prototype.push.apply(this.items, arguments);
37 if (length == 0) 36 if (length == 0)
38 return; 37 return;
39 38
40 this.sort(function(a, b) 39 this.items.sort(function(a, b)
41 { 40 {
42 var aValue = (a.title || a.url || a.text).toLowerCase(); 41 var aValue = (a.title || a.url || a.text).toLowerCase();
43 var bValue = (b.title || b.url || a.text).toLowerCase(); 42 var bValue = (b.title || b.url || a.text).toLowerCase();
44 if (aValue < bValue) 43 return aValue.localeCompare(bValue);
45 return -1;
46 if (aValue > bValue)
47 return 1;
48 return 0;
49 }); 44 });
50 45
51 for (var j = 0; j < this.details.length; j++) 46 for (var j = 0; j < this.details.length; j++)
52 { 47 {
53 var table = E(this.details[j].id); 48 var table = E(this.details[j].id);
54 var template = table.querySelector("template"); 49 var template = table.querySelector("template");
55 var listener = this.details[j].listener;
56 for (var i = 0; i < arguments.length; i++) 50 for (var i = 0; i < arguments.length; i++)
57 { 51 {
58 var object = arguments[i]; 52 var item = arguments[i];
59 var text = object.title || object.text; 53 var text = item.title || item.url || item.text;
Thomas Greiner 2015/03/05 11:36:03 A subscription might not have a title. In those ca
60 var access = object.url || object.text;
Thomas Greiner 2015/03/05 11:36:03 You're only using this variable once so no need to
saroyanm 2015/03/06 11:54:32 Done, but now I'm using access, to shorten the lin
Thomas Greiner 2015/03/12 11:41:56 That'd be ok but "index" is only used in that one
saroyanm 2015/03/12 14:03:22 This is already fixed in current patch: http://cod
61 var index = this.indexOf(object);
62 var listItem = document.createElement("li"); 54 var listItem = document.createElement("li");
63 listItem.appendChild(document.importNode(template.content, true)); 55 listItem.appendChild(document.importNode(template.content, true));
64 listItem.dataset.access = access; 56 listItem.dataset.access = item.url || item.text;
Thomas Greiner 2015/03/05 11:36:03 You need to normalize this string or otherwise `El
saroyanm 2015/03/06 11:54:32 while current query throw error: document.querySel
Thomas Greiner 2015/03/12 11:41:56 Should be fine. Alternatively, you could use `enc
65 listItem.querySelector(".display").textContent = text; 57 listItem.querySelector(".display").textContent = text;
66 if (text) 58 if (text)
67 listItem.dataset.search = text.toLowerCase(); 59 listItem.dataset.search = text.toLowerCase();
68 60
69 var control = listItem.querySelector(".control"); 61 var control = listItem.querySelector(".control");
70 if (control) 62 if (control)
71 { 63 {
72 control.addEventListener("click", listener, false); 64 control.addEventListener("click", this.details[j].onClick, false);
Thomas Greiner 2015/03/05 11:36:03 Just FYI: I'd still prefer a single global event l
73 control.checked = object.disabled == false; 65 control.checked = item.disabled == false;
74 } 66 }
75 67
76 var popular = listItem.querySelector(".popular"); 68 if (table.hasChildNodes())
77 if (popular) 69 table.insertBefore(listItem, table.childNodes[this.items.indexOf(item) ]);
78 popular.textContent = ext.i18n.getMessage("options_popular");
Thomas Greiner 2015/03/05 11:36:03 Setting that text right inside the template tag on
saroyanm 2015/03/06 11:54:32 Done.
79
80 if (table.hasChildNodes)
81 table.insertBefore(listItem, table.childNodes[index]);
82 else 70 else
83 table.appendChild(listItem); 71 table.appendChild(listItem);
84 } 72 }
85 } 73 }
86 return length; 74 return length;
87 }; 75 };
88 76
89 Collection.prototype.removeItem = function(obj) 77 Collection.prototype.removeItem = function(item)
Thomas Greiner 2015/03/05 11:36:03 The function is called "removeItem" but the item i
saroyanm 2015/03/06 11:54:32 Done.
90 { 78 {
91 var index = this.indexOf(obj); 79 var index = this.items.indexOf(item);
92 if (index == -1) 80 if (index == -1)
93 return; 81 return;
94 82
95 this.splice(index, 1); 83 this.items.splice(index, 1);
96 var access = obj.url || obj.text; 84 var access = (item.url || item.text).replace(/'/g, "\\'");
97 for (var i = 0; i < this.details.length; i++) 85 for (var i = 0; i < this.details.length; i++)
98 { 86 {
99 var table = E(this.details[i].id); 87 var table = E(this.details[i].id);
100 var element = table.querySelector("[data-access='"+access+"']"); 88 var element = table.querySelector("[data-access='" + access + "']");
101 element.parentElement.removeChild(element); 89 element.parentElement.removeChild(element);
102 } 90 }
103 }; 91 };
104 92
105 function toggleSubscription(e) 93 Collection.prototype.clearAll = function()
94 {
95 for (var i = 0; i < this.details.length; i++)
96 {
97 var table = E(this.details[i].id);
98 var template = table.querySelector("template");
99 table.innerHTML = "";
100 table.appendChild(template);
101 }
102 this.items.length = 0;
103 };
104
105 function onToggleSubscriptionClick(e)
106 { 106 {
107 e.preventDefault(); 107 e.preventDefault();
108 var isChecked = e.target.checked;
Thomas Greiner 2015/03/05 11:36:03 Again, this variable is only used once.
saroyanm 2015/03/06 11:54:32 Done.
109 var subscriptionUrl = e.target.parentNode.dataset.access; 108 var subscriptionUrl = e.target.parentNode.dataset.access;
110 if (!isChecked) 109 if (!e.target.checked)
111 removeSubscription(subscriptionUrl); 110 removeSubscription(subscriptionUrl);
112 else 111 else
113 addEnableSubscription(subscriptionUrl); 112 addEnableSubscription(subscriptionUrl);
114 } 113 }
115 114
116 function addLanguageSubscription(e) 115 function onAddLanguageSubscriptionClick(e)
117 { 116 {
118 e.preventDefault(); 117 e.preventDefault();
119 var url = this.parentNode.dataset.access; 118 var url = this.parentNode.dataset.access;
120 addEnableSubscription(url); 119 addEnableSubscription(url);
121 } 120 }
122 121
123 function triggerRemoveFilter() 122 function onRemoveFilterClick()
124 { 123 {
125 var filter = this.parentNode.dataset.access; 124 var filter = this.parentNode.dataset.access;
126 removeFilter(filter); 125 removeFilter(filter);
127 } 126 }
128 127
129 collections.popular = new Collection( 128 collections.popular = new Collection(
130 [ 129 [
131 { 130 {
132 id: "recommend-list-table", 131 id: "recommend-list-table",
133 listener: toggleSubscription 132 onClick: onToggleSubscriptionClick
Thomas Greiner 2015/03/05 11:36:03 I'd rename "listener" to "onClick". Otherwise it's
saroyanm 2015/03/06 11:54:32 Done.
134 } 133 }
135 ]); 134 ]);
136 collections.langs = new Collection( 135 collections.langs = new Collection(
137 [ 136 [
138 { 137 {
139 id: "blocking-languages-table", 138 id: "blocking-languages-table",
140 listener: toggleSubscription 139 onClick: onToggleSubscriptionClick
141 }, 140 },
142 { 141 {
143 id: "blocking-languages-modal-table" 142 id: "blocking-languages-dialog-table"
144 } 143 }
145 ]); 144 ]);
146 collections.allLangs = new Collection( 145 collections.allLangs = new Collection(
147 [ 146 [
148 { 147 {
149 id: "all-lang-table", 148 id: "all-lang-table",
150 listener: addLanguageSubscription 149 onClick: onAddLanguageSubscriptionClick
151 } 150 }
152 ]); 151 ]);
153 collections.acceptableAds = new Collection( 152 collections.acceptableAds = new Collection(
154 [ 153 [
155 { 154 {
156 id: "acceptableads-table", 155 id: "acceptableads-table",
157 listener: toggleSubscription 156 onClick: onToggleSubscriptionClick
158 } 157 }
159 ]); 158 ]);
160 collections.custom = new Collection( 159 collections.custom = new Collection(
161 [ 160 [
162 { 161 {
163 id: "custom-list-table", 162 id: "custom-list-table",
164 listener: toggleSubscription 163 onClick: onToggleSubscriptionClick
165 } 164 }
166 ]); 165 ]);
167 collections.whitelist = new Collection( 166 collections.whitelist = new Collection(
168 [ 167 [
169 { 168 {
170 id: "whitelisting-table", 169 id: "whitelisting-table",
171 listener: triggerRemoveFilter 170 onClick: onRemoveFilterClick
172 } 171 }
173 ]); 172 ]);
174 173
175 function updateSubscription(subscription) 174 function updateSubscription(subscription)
176 { 175 {
177 var subscriptionUrl = subscription.url; 176 var subscriptionUrl = subscription.url;
178 var knownSubscription = getKnownSubscription(subscriptionUrl); 177 var knownSubscription = subscriptionsMap[subscriptionUrl];
179 if (knownSubscription) 178 if (knownSubscription)
180 knownSubscription.disabled = subscription.disabled; 179 knownSubscription.disabled = subscription.disabled;
181 else 180 else
182 { 181 {
183 getAcceptableAdsURL(function(acceptableAdsUrl) 182 getAcceptableAdsURL(function(acceptableAdsUrl)
184 { 183 {
185 function onObjectChanged() 184 function onObjectChanged()
186 { 185 {
187 var access = subscriptionUrl || subscription.text; 186 var access = (subscriptionUrl || subscription.text).replace(/'/g, "\\' ");
188 var elements = document.querySelectorAll("[data-access='" + access + " ']"); 187 var elements = document.querySelectorAll("[data-access='" + access + " ']");
189 for (var i = 0; i < elements.length; i++) 188 for (var i = 0; i < elements.length; i++)
190 { 189 {
191 var element = elements[i]; 190 var element = elements[i];
192 var control = element.getElementsByClassName("control")[0]; 191 var control = element.querySelector(".control");
Thomas Greiner 2015/03/05 11:36:03 Usually, you use `element.querySelector(".control"
saroyanm 2015/03/06 11:54:32 Done.
193 if (control.localName == "input") 192 if (control.localName == "input")
194 control.checked = subscription.disabled == false; 193 control.checked = subscription.disabled == false;
195 if (isRecommendation(subscriptionUrl)) 194 if (subscriptionUrl in recommendationsMap)
196 { 195 {
197 var recommendation = getRecommendation(subscriptionUrl); 196 var recommendation = recommendationsMap[subscriptionUrl];
198 if (recommendation.isAdsType && subscription.disabled == false) 197 if (recommendation.isAdsType)
199 { 198 {
200 collections.allLangs.removeItem(subscription); 199 if (subscription.disabled == false)
201 collections.langs.addItems(subscription); 200 {
202 } 201 collections.allLangs.removeItem(subscription);
203 else 202 collections.langs.addItems(subscription);
204 { 203 }
205 collections.allLangs.addItems(subscription); 204 else
206 collections.langs.removeItem(subscription); 205 {
206 collections.allLangs.addItems(subscription);
207 collections.langs.removeItem(subscription);
208 }
207 } 209 }
208 } 210 }
209 } 211 }
210 } 212 }
211 213
212 if (!Object.observe) 214 if (!Object.observe)
213 { 215 {
216 // Currently only "disabled" property of subscription used for observa tion
217 // but with Advanced tab implementation we should also add more proper ties.
214 ["disabled"].forEach(function(property) 218 ["disabled"].forEach(function(property)
215 { 219 {
216 subscription["$"+property] = subscription[property]; 220 subscription["$" + property] = subscription[property];
Thomas Greiner 2015/03/05 11:36:03 By now I'd expect you to know that operators, like
saroyanm 2015/03/06 11:54:32 Done.
217 Object.defineProperty(subscription, property, 221 Object.defineProperty(subscription, property,
218 { 222 {
219 get: function() 223 get: function()
220 { 224 {
221 return this["$"+property]; 225 return this["$" + property];
222 }, 226 },
223 set: function(value) 227 set: function(value)
224 { 228 {
225 this["$"+property] = value; 229 this["$" + property] = value;
226 onObjectChanged(); 230 onObjectChanged();
227 } 231 }
228 }); 232 });
229 }); 233 });
230 } 234 }
231 else 235 else
232 { 236 {
233 Object.observe(subscription, function(changes) 237 Object.observe(subscription, onObjectChanged);
234 {
235 onObjectChanged();
236 });
237 } 238 }
238 239
239 var collection = null; 240 var collection = null;
240 if (isRecommendation(subscriptionUrl)) 241 if (subscriptionUrl in recommendationsMap)
241 { 242 {
242 var recommendation = getRecommendation(subscriptionUrl); 243 var recommendation = recommendationsMap[subscriptionUrl];
243 if (recommendation.isPopular) 244 if (recommendation.isPopular)
244 collection = collections.popular; 245 collection = collections.popular;
245 else if (recommendation.isAdsType && subscription.disabled == false) 246 else if (recommendation.isAdsType && subscription.disabled == false)
246 collection = collections.langs; 247 collection = collections.langs;
247 else 248 else
248 collection = collections.allLangs; 249 collection = collections.allLangs;
249 } 250 }
250 else if (subscriptionUrl == acceptableAdsUrl) 251 else if (subscriptionUrl == acceptableAdsUrl)
251 collection = collections.acceptableAds; 252 collection = collections.acceptableAds;
252 else 253 else
253 collection = collections.custom; 254 collection = collections.custom;
254 255
255 collection.addItems(subscription); 256 collection.addItems(subscription);
256 setKnownSubscription(subscriptionUrl, subscription); 257 subscriptionsMap[subscriptionUrl] = subscription;
257 }); 258 });
258 } 259 }
259 } 260 }
260 261
261 function updateFilter(filter) 262 function updateFilter(filter)
262 { 263 {
263 var knownFilter = getKnownFilter(filter.text);
264 var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/); 264 var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/);
265 if (match && !knownFilter) 265 if (match && !filtersMap[filter.text])
266 { 266 {
267 filter.title = match[1]; 267 filter.title = match[1];
268 collections.whitelist.addItems(filter); 268 collections.whitelist.addItems(filter);
269 setKnownFilter(filter.text, filter); 269 filtersMap[filter.text] = filter
270 } 270 }
271 else 271 else
272 { 272 {
273 // TODO: add `filters[i].text` to list of custom filters 273 // TODO: add `filters[i].text` to list of custom filters
274 } 274 }
275 } 275 }
276 276
277 function loadRecommendations() 277 function loadRecommendations()
278 { 278 {
279 var request = new XMLHttpRequest(); 279 var request = new XMLHttpRequest();
280 request.open("GET", "subscriptions.xml", false); 280 request.open("GET", "subscriptions.xml", false);
281 request.onload = function() 281 request.addEventListener("load", function()
282 { 282 {
283 var list = document.getElementById("subscriptionSelector"); 283 var list = document.getElementById("subscriptionSelector");
284 var docElem = request.responseXML.documentElement; 284 var docElem = request.responseXML.documentElement;
285 var elements = docElem.getElementsByTagName("subscription"); 285 var elements = docElem.getElementsByTagName("subscription");
286 for (var i = 0; i < elements.length; i++) 286 for (var i = 0; i < elements.length; i++)
287 { 287 {
288 var element = elements[i]; 288 var element = elements[i];
289 var subscription = Object.create(null); 289 var subscription = Object.create(null);
290 subscription.title = element.getAttribute("title"); 290 subscription.title = element.getAttribute("title");
291 subscription.url = element.getAttribute("url"); 291 subscription.url = element.getAttribute("url");
(...skipping 10 matching lines...) Expand all
302 var prefix = element.getAttribute("prefixes").replace(/,/g, "_"); 302 var prefix = element.getAttribute("prefixes").replace(/,/g, "_");
303 subscription.title = ext.i18n.getMessage("options_language_" + prefix) ; 303 subscription.title = ext.i18n.getMessage("options_language_" + prefix) ;
304 recommendation.isAdsType = true; 304 recommendation.isAdsType = true;
305 } 305 }
306 else 306 else
307 subscription.title = element.getAttribute("specialization"); 307 subscription.title = element.getAttribute("specialization");
308 308
309 if (element.getAttribute("popular")) 309 if (element.getAttribute("popular"))
310 recommendation.isPopular = true; 310 recommendation.isPopular = true;
311 311
312 setRecommendation(subscription.url, recommendation); 312 recommendationsMap[subscription.url] = recommendation;
313 updateSubscription(subscription); 313 updateSubscription(subscription);
314 } 314 }
315 }; 315 }, false);
316 request.send(null); 316 request.send(null);
317 } 317 }
318 318
319 function onDOMLoaded() 319 function onDOMLoaded()
320 { 320 {
321 var recommendationTemplate = document.querySelector("#recommend-list-table t emplate");
322 var popularText = ext.i18n.getMessage("options_popular");
323 recommendationTemplate.content.querySelector(".popular").textContent = popul arText;
324 var languagesTemplate = document.querySelector("#all-lang-table template");
325 var buttonText = ext.i18n.getMessage("options_button_add");
326 languagesTemplate.content.querySelector(".button-add span").textContent = bu ttonText;
327
321 updateShareLink(); 328 updateShareLink();
322 populateLists(); 329 populateLists();
323 330
324 var tabList = document.querySelectorAll("#main-navigation-tabs li"); 331 var tabList = document.querySelectorAll("#main-navigation-tabs li");
325 for (var i = 0; i < tabList.length; i++) 332 for (var i = 0; i < tabList.length; i++)
326 { 333 {
327 tabList[i].addEventListener("click", function(e) 334 tabList[i].addEventListener("click", function(e)
328 { 335 {
329 document.body.dataset.tab = e.currentTarget.dataset.show; 336 document.body.dataset.tab = e.currentTarget.dataset.show;
330 }, false); 337 }, false);
331 } 338 }
332 339
333 function searchLanguage() 340 function onFindLanguageKeyUp()
334 { 341 {
335 var searchStyle = E("search-style"); 342 var searchStyle = E("search-style");
336 if (!this.value) 343 if (!this.value)
337 searchStyle.innerHTML = ""; 344 searchStyle.innerHTML = "";
338 else 345 else
339 searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + this .value.toLowerCase() + "\"]) { display: none; }"; 346 searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + this .value.toLowerCase() + "\"]) { display: none; }";
340 } 347 }
341 348
342 // Update version number in navigation sidebar 349 // Update version number in navigation sidebar
343 ext.backgroundPage.sendMessage( 350 ext.backgroundPage.sendMessage(
344 { 351 {
345 method: "app.get", 352 method: "app.get",
346 what: "addonVersion" 353 what: "addonVersion"
347 }, 354 },
348 function(addonVersion) 355 function(addonVersion)
349 { 356 {
350 E("abp-version").textContent = addonVersion; 357 E("abp-version").textContent = addonVersion;
351 }); 358 });
352 359
353 var placeholderValue = ext.i18n.getMessage("options_modal_language_find"); 360 var placeholderValue = ext.i18n.getMessage("options_dialog_language_find");
354 E("find-language").setAttribute("placeholder", placeholderValue); 361 E("find-language").setAttribute("placeholder", placeholderValue);
355 E("add-blocking-list").addEventListener("click", function() 362 E("add-blocking-list").addEventListener("click", function()
356 { 363 {
357 openModal("customlist"); 364 openDialog("customlist");
358 }, false); 365 }, false);
359 E("add-website-language").addEventListener("click", function() 366 E("add-website-language").addEventListener("click", function()
360 { 367 {
361 openModal("language"); 368 openDialog("language");
362 }, false); 369 }, false);
363 E("modal-close").addEventListener("click", function() 370 E("dialog-close").addEventListener("click", function()
364 { 371 {
365 delete document.body.dataset.modal; 372 delete document.body.dataset.dialog;
366 }, false); 373 }, false);
367 E("edit-ownBlockingList-btn").addEventListener("click", editCustomFilters, f alse); 374 E("edit-ownBlockingList-button").addEventListener("click", editCustomFilters , false);
368 E("find-language").addEventListener("keyup", searchLanguage, false); 375 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false);
369 E("find-language").addEventListener("search", searchLanguage, false); 376 E("whitelisting").addEventListener("click", function(e)
Thomas Greiner 2015/03/05 11:36:03 Turns out that the "onsearch" event listener is We
saroyanm 2015/03/06 11:54:32 I'm using this event to listen for "X" button clic
Thomas Greiner 2015/03/12 11:41:56 Since that "X" is also not in the standard I'd sug
saroyanm 2015/03/12 14:03:22 Done.
370 E("whitelisting-add-icon").addEventListener("click", addWhitelistedDomain, f alse); 377 {
371 E("whitelisting-add-btn").addEventListener("click", addWhitelistedDomain, fa lse); 378 var id = e.target.id;
372 E("whitelisting-enter-icon").addEventListener("click", addWhitelistedDomain, false); 379 if (id == "whitelisting-add-icon" || id == "whitelisting-enter-icon")
380 addWhitelistedDomain();
381 else if (id == "whitelisting-cancel-button")
382 E("whitelisting-textbox").value = "";
383 }, false);
384 E("whitelisting-add-button").addEventListener("click", addWhitelistedDomain, false);
373 E("whitelisting-textbox").addEventListener("keypress", function(e) 385 E("whitelisting-textbox").addEventListener("keypress", function(e)
374 { 386 {
375 // keyCode value of 13 corresponds to "Enter" key 387 // e.keyCode has been deprecated so we attempt to use e.key
Thomas Greiner 2015/03/05 11:36:03 Please also explain why you need to check for both
saroyanm 2015/03/06 11:54:32 Done.
376 if (e.key && e.key == "Enter") 388 // keyCode "13" corresponds to "Enter"
377 addWhitelistedDomain(); 389 if ((e.key && e.key == "Enter") || (!e.key && e.keyCode == 13))
378 else if (!e.key && e.keyCode == 13)
379 addWhitelistedDomain(); 390 addWhitelistedDomain();
380 }, false); 391 }, false);
381 E("whitelisting-cancel-btn").addEventListener("click", function() 392 E("import-blockingList-button").addEventListener("click", function()
382 {
383 E("whitelisting-textbox").value = "";
384 }, false);
385 E("import-blockingList-btn").addEventListener("click", function()
386 { 393 {
387 var url = E("blockingList-textbox").value; 394 var url = E("blockingList-textbox").value;
388 addEnableSubscription(url); 395 addEnableSubscription(url);
389 delete document.body.dataset.modal; 396 delete document.body.dataset.dialog;
390 }, false); 397 }, false);
391 } 398 }
392 399
393 function openModal(name) 400 function openDialog(name)
394 { 401 {
395 document.body.dataset.modal = name; 402 document.body.dataset.dialog = name;
396 } 403 }
397 404
398 function populateLists() 405 function populateLists()
399 { 406 {
400 subscriptionsMap = Object.create(null); 407 subscriptionsMap = Object.create(null);
401 filtersMap = Object.create(null); 408 filtersMap = Object.create(null);
402 recommendationsMap = Object.create(null); 409 recommendationsMap = Object.create(null);
403 410
404 // Empty collections and lists 411 // Empty collections and lists
405 for (var property in collections) 412 for (var property in collections)
406 { 413 collections[property].clearAll();
407 var collection = collections[property];
408 collection.details.forEach(function(detail)
Thomas Greiner 2015/03/05 11:36:03 This property does not need to be exposed. It'd be
saroyanm 2015/03/06 11:54:32 Done.
409 {
410 var table = E(detail.id);
411 var template = table.querySelector("template");
412 table.innerHTML = "";
413 table.appendChild(template);
414 });
415 collection.length = 0;
416 }
417 414
418 ext.backgroundPage.sendMessage( 415 ext.backgroundPage.sendMessage(
419 { 416 {
420 type: "subscriptions.get", 417 type: "subscriptions.get",
421 special: true 418 special: true
422 }, 419 },
423 function(subscriptions) 420 function(subscriptions)
424 { 421 {
425 // Load filters 422 // Load filters
426 for (var i = 0; i < subscriptions.length; i++) 423 for (var i = 0; i < subscriptions.length; i++)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 type: "filters.add", 467 type: "filters.add",
471 text: "@@||" + domain.value.toLowerCase() + "^$document" 468 text: "@@||" + domain.value.toLowerCase() + "^$document"
472 }); 469 });
473 } 470 }
474 471
475 domain.value = ""; 472 domain.value = "";
476 } 473 }
477 474
478 function editCustomFilters() 475 function editCustomFilters()
479 { 476 {
480 477 //TODO: NYI
481 } 478 }
482 479
483 function getAcceptableAdsURL(callback) 480 function getAcceptableAdsURL(callback)
484 { 481 {
485 if (acceptableAdsUrl) 482 ext.backgroundPage.sendMessage(
Thomas Greiner 2015/03/05 11:36:03 This if-statement is not necessary and neither is
saroyanm 2015/03/06 11:54:32 Hmm :/ Totally missed your implementation, good po
486 callback(acceptableAdsUrl); 483 {
487 else 484 type: "prefs.get",
488 { 485 key: "subscriptions_exceptionsurl"
489 ext.backgroundPage.sendMessage( 486 },
490 { 487 function(value)
491 type: "prefs.get", 488 {
492 key: "subscriptions_exceptionsurl" 489 getAcceptableAdsURL = function(callback)
493 }, 490 {
494 function(value) 491 callback(value);
495 { 492 }
496 getAcceptableAdsURL = function(callback) 493 getAcceptableAdsURL(callback);
497 { 494 });
498 acceptableAdsUrl = value;
499 callback(value);
500 }
501 getAcceptableAdsURL(callback);
502 });
503 }
504 }
505
506 function getKnownSubscription(url)
Thomas Greiner 2015/03/05 11:36:03 The next few functions are all one-liners. There's
saroyanm 2015/03/06 11:54:32 Done.
507 {
508 return subscriptionsMap[url];
509 }
510
511 function setKnownSubscription(url, subscription)
512 {
513 subscriptionsMap[url] = subscription;
514 }
515
516 function getKnownFilter(text)
517 {
518 return filtersMap[text];
519 }
520
521 function setKnownFilter(text, filter)
522 {
523 filtersMap[text] = filter;
524 }
525
526 function getRecommendation(url)
527 {
528 return recommendationsMap[url];
529 }
530
531 function setRecommendation(url, recommendation)
532 {
533 recommendationsMap[url] = recommendation;
534 }
535
536 function isRecommendation(url)
537 {
538 return url in recommendationsMap;
539 } 495 }
540 496
541 function addEnableSubscription(url, title, homepage) 497 function addEnableSubscription(url, title, homepage)
542 { 498 {
543 var messageType = null; 499 var messageType = null;
544 var knownSubscription = getKnownSubscription(url); 500 var knownSubscription = subscriptionsMap[url];
545 if (knownSubscription && knownSubscription.disabled == true) 501 if (knownSubscription && knownSubscription.disabled == true)
546 messageType = "subscriptions.toggle" 502 messageType = "subscriptions.toggle"
547 else 503 else
548 messageType = "subscriptions.add" 504 messageType = "subscriptions.add"
549 505
550 var message = { 506 var message = {
551 type: messageType, 507 type: messageType,
552 url: url 508 url: url
553 }; 509 };
554 if (title) 510 if (title)
(...skipping 27 matching lines...) Expand all
582 switch (action) 538 switch (action)
583 { 539 {
584 case "added": 540 case "added":
585 updateFilter(filter); 541 updateFilter(filter);
586 updateShareLink(); 542 updateShareLink();
587 break; 543 break;
588 case "loaded": 544 case "loaded":
589 populateLists(); 545 populateLists();
590 break; 546 break;
591 case "removed": 547 case "removed":
592 var knownFilter = getKnownFilter(filter.text); 548 var knownFilter = filtersMap[filter.text];
593 collections.whitelist.removeItem(knownFilter); 549 collections.whitelist.removeItem(knownFilter);
550 delete filtersMap[filter.text];
594 updateShareLink(); 551 updateShareLink();
595 break; 552 break;
596 } 553 }
597 } 554 }
598 555
599 function onSubscriptionMessage(action, subscription) 556 function onSubscriptionMessage(action, subscription)
600 { 557 {
601 switch (action) 558 switch (action)
602 { 559 {
603 case "added": 560 case "added":
604 updateSubscription(subscription);
605 updateShareLink();
606 break;
607 case "disabled": 561 case "disabled":
608 updateSubscription(subscription); 562 updateSubscription(subscription);
609 updateShareLink(); 563 updateShareLink();
610 break; 564 break;
611 case "homepage": 565 case "homepage":
612 // TODO: NYI 566 // TODO: NYI
613 break; 567 break;
614 case "removed": 568 case "removed":
615 getAcceptableAdsURL(function(acceptableAdsUrl) 569 getAcceptableAdsURL(function(acceptableAdsUrl)
616 { 570 {
617 if (subscription.url == acceptableAdsUrl) 571 if (subscription.url == acceptableAdsUrl)
618 { 572 {
619 subscription.disabled = true; 573 subscription.disabled = true;
620 updateSubscription(subscription); 574 updateSubscription(subscription);
621 } 575 }
622 else 576 else
623 { 577 {
624 var knownSubscription = getKnownSubscription(subscription.url); 578 var knownSubscription = subscriptionsMap[subscription.url];
625 var subscriptionUrl = subscription.url; 579 if (subscription.url in recommendationsMap)
Thomas Greiner 2015/03/05 11:36:03 This variable is not necessary. It's only used onc
saroyanm 2015/03/06 11:54:32 Done.
626 if (isRecommendation(subscriptionUrl))
627 knownSubscription.disabled = true; 580 knownSubscription.disabled = true;
628 else 581 else
582 {
629 collections.custom.removeItem(knownSubscription); 583 collections.custom.removeItem(knownSubscription);
584 delete subscriptionsMap[subscription.url];
585 }
630 } 586 }
631 updateShareLink(); 587 updateShareLink();
632 }); 588 });
633 break; 589 break;
634 case "title": 590 case "title":
635 // TODO: NYI 591 // TODO: NYI
636 break; 592 break;
637 } 593 }
638 } 594 }
639 595
640 function showAddSubscriptionDialog(subscription) 596 function showAddSubscriptionDialog(subscription)
641 { 597 {
642 E("blockingList-textbox").value = subscription.url; 598 E("blockingList-textbox").value = subscription.url;
643 openModal("customlist"); 599 openDialog("customlist");
644 } 600 }
645 601
646 function updateShareLink() 602 function updateShareLink()
647 { 603 {
648 ext.backgroundPage.sendMessage( 604 ext.backgroundPage.sendMessage(
649 { 605 {
650 type: "filters.blocked", 606 type: "filters.blocked",
651 url: "https://platform.twitter.com/widgets/", 607 url: "https://platform.twitter.com/widgets/",
652 requestType: "SCRIPT", 608 requestType: "SCRIPT",
653 docDomain: "adblockplus.org", 609 docDomain: "adblockplus.org",
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 filter: ["added", "loaded", "removed"] 648 filter: ["added", "loaded", "removed"]
693 }); 649 });
694 ext.backgroundPage.sendMessage( 650 ext.backgroundPage.sendMessage(
695 { 651 {
696 type: "subscriptions.listen", 652 type: "subscriptions.listen",
697 filter: ["added", "disabled", "homepage", "removed", "title"] 653 filter: ["added", "disabled", "homepage", "removed", "title"]
698 }); 654 });
699 655
700 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); 656 window.addEventListener("DOMContentLoaded", onDOMLoaded, false);
701 })(); 657 })();
LEFTRIGHT

Powered by Google App Engine
This is Rietveld