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

Side by Side Diff: chrome/content/ui/firstRun.js

Issue 10585038: First-run page (revisited) (Closed)
Patch Set: Implemented behavior of remaining buttons on Chrome; Added changelog and data corruption warning Created May 24, 2013, 10:09 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
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2013 Eyeo GmbH 3 * Copyright (C) 2006-2013 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 function init() 18 "use strict";
19
20 (function()
19 { 21 {
20 generateLinkText(E("changeDescription")); 22 var shade;
21 23 var scrollTimer;
22 for each (let subscription in FilterStorage.subscriptions) 24
23 { 25 // Determine platform
24 if (subscription instanceof DownloadableSubscription && subscription.url != Prefs.subscriptions_exceptionsurl && !subscription.disabled) 26 var userAgent = "";
25 { 27 if (navigator.userAgent.indexOf("Gecko/") > -1)
26 E("listName").textContent = subscription.title; 28 userAgent = "firefox";
27 29 else if (navigator.userAgent.indexOf("Chrome/") > -1)
28 let link = E("listHomepage"); 30 userAgent = "chrome";
29 link.setAttribute("href", subscription.homepage); 31
30 link.setAttribute("title", subscription.homepage); 32 if (userAgent !== "")
31 33 document.documentElement.className = userAgent;
Wladimir Palant 2013/05/27 11:02:00 Please never do user agent detection, use feature
Thomas Greiner 2013/05/27 13:03:16 I wanted to but the problem is that Firefox' utils
Wladimir Palant 2013/05/27 14:10:37 Feel free to replace let by var everywhere in util
Thomas Greiner 2013/05/27 16:39:15 Done.
32 E("listNameContainer").removeAttribute("hidden"); 34
33 E("listNone").setAttribute("hidden", "true"); 35 // Load subscriptions for features
34 break; 36 var featureSubscriptions = {};
35 } 37 (function()
36 } 38 {
37 39 var request = new XMLHttpRequest();
38 if (FilterStorage.subscriptions.some(function(s) s.url == Prefs.subscriptions_ exceptionsurl)) 40 request.open("GET", "featureSubscriptions.xml", false);
39 E("acceptableAds").removeAttribute("hidden"); 41 request.send();
40 } 42 var subscriptions = request.responseXML.getElementsByTagName("subscription") ;
41 43 for (var i = 0, len = subscriptions.length; i < len; i++)
42 function generateLinkText(element) 44 {
43 { 45 var subscription = subscriptions[i];
44 let template = element.getAttribute("_textTemplate"); 46 featureSubscriptions[subscription.getAttribute("feature")] = {
45 47 "url": subscription.getAttribute("url"),
46 let [, beforeLink, linkText, afterLink] = /(.*)\[link\](.*)\[\/link\](.*)/.exe c(template) || [null, "", template, ""]; 48 "title": subscription.getAttribute("title")
47 while (element.firstChild && element.firstChild.nodeType != Node.ELEMENT_NODE) 49 };
48 element.removeChild(element.firstChild); 50 }
49 while (element.lastChild && element.lastChild.nodeType != Node.ELEMENT_NODE) 51 })();
50 element.removeChild(element.lastChild); 52
Wladimir Palant 2013/05/27 11:02:00 How about hardcoding the value of featureSubscript
Thomas Greiner 2013/05/27 13:03:16 Done.
51 if (!element.firstChild) 53 // Determine scripts to load
52 return; 54 var scripts = [];
53 55 if (userAgent == "chrome")
54 element.firstChild.textContent = linkText; 56 {
55 element.insertBefore(document.createTextNode(beforeLink), element.firstChild); 57 var backgroundPage = chrome.extension.getBackgroundPage();
56 element.appendChild(document.createTextNode(afterLink)); 58 var require = backgroundPage.require;
57 } 59 }
58 60 else if (userAgent == "firefox")
59 function openFilters() 61 {
60 { 62 scripts.push("utils.js");
61 if (Utils.isFennec) 63 }
62 { 64 scripts.push("i18n.js");
Wladimir Palant 2013/05/27 11:02:00 This shouldn't be necessary. As I said above, just
Thomas Greiner 2013/05/27 16:39:15 Done.
63 let topWnd = window.QueryInterface(Ci.nsIInterfaceRequestor) 65
64 .getInterface(Ci.nsIWebNavigation) 66 function loadScripts()
65 .QueryInterface(Ci.nsIDocShellTreeItem) 67 {
66 .rootTreeItem 68 var scriptName = scripts.shift();
67 .QueryInterface(Ci.nsIInterfaceRequestor) 69 var script = document.createElement("script");
68 .getInterface(Ci.nsIDOMWindow); 70 script.type = (userAgent == "firefox") ? "application/x-javascript;version=1 .7" : "text/javascript";
69 if (topWnd.wrappedJSObject) 71 script.addEventListener("load", (scripts.length == 0) ? onScriptsLoaded : lo adScripts, false);
70 topWnd = topWnd.wrappedJSObject; 72 script.src = scriptName;
71 73 document.head.appendChild(script);
72 // window.close() closes the entire window (bug 642604), make sure to close 74 }
73 // only a single tab instead. 75
74 if ("BrowserUI" in topWnd) 76 function onScriptsLoaded()
75 { 77 {
76 topWnd.BrowserUI.showPanel("addons-container"); 78 var isFirstRun = (userAgent == "chrome" && backgroundPage.isFirstRun)
77 function showOptions() 79 || (userAgent == "firefox" && !UI.firstRunDone);
Wladimir Palant 2013/05/27 11:02:00 I think we can safely drop the update scenario now
Thomas Greiner 2013/05/27 13:03:16 Done.
78 { 80
79 if (!topWnd.ExtensionsView.getElementForAddon(Utils.addonID)) 81 if (userAgent == "chrome")
80 Utils.runAsync(showOptions); 82 {
81 else 83 window.Synchronizer = require("synchronizer").Synchronizer;
82 topWnd.ExtensionsView.showOptions(Utils.addonID); 84 window.Utils = require("utils").Utils;
83 } 85 window.Prefs = require("prefs").Prefs;
84 showOptions(); 86 window.FilterStorage = require("filterStorage").FilterStorage;
85 } 87 window.FilterNotifier = require("filterNotifier").FilterNotifier;
86 } 88
87 else 89 var subscriptionClasses = require("subscriptionClasses");
88 UI.openFiltersDialog(); 90 window.Subscription = subscriptionClasses.Subscription;
89 } 91 window.DownloadableSubscription = subscriptionClasses.DownloadableSubscrip tion;
92 window.Filter = require("filterClasses").Filter;
Wladimir Palant 2013/05/27 11:02:00 This should be in the Chrome variant of utils.js.
Thomas Greiner 2013/05/27 16:39:15 Done.
93 }
94
95 // Set up page title
96 var titleId = isFirstRun ? "firstRun_title_install" : "firstRun_title_update ";
97 var pageTitle = i18n.getMessage(titleId);
98 document.title = document.getElementById("title-main").textContent = pageTit le;
99
100 // Only show changelog link on the update page
101 if (isFirstRun)
102 document.getElementById("title-changelog").style.display = "none";
Wladimir Palant 2013/05/27 11:02:00 See above, the update case is irrelevant by now an
Thomas Greiner 2013/05/27 13:03:16 Done.
103
104 // Show warning if data corruption was detected
105 // TODO: check in Firefox
Thomas Greiner 2013/05/24 10:19:12 ignore the TODO here :)
106 if (userAgent == "chrome" && backgroundPage.seenDataCorruption)
Wladimir Palant 2013/05/27 11:02:00 Please change that into (typeof backgroundPage !=
Thomas Greiner 2013/05/27 13:03:16 Done.
107 {
108 document.getElementById("dataCorruptionWarning").removeAttribute("hidden") ;
109 setLinks("dataCorruptionWarning", getDocLink("knownIssuesChrome_filterstor age"));
110 }
111
112 // Set up URLs
113 var versionId;
114 var platformId;
115 if (userAgent == "firefox")
116 {
117 versionId = Utils.addonVersion.match(/^[0-9\.]+/)[0].replace(/\./g, "");
118 platformId = "firefox";
119 }
120 else if (userAgent == "chrome")
121 {
122 versionId = chrome.app.getDetails().version.split(".").slice(0, 2).join("" );
123 platformId = "google-chrome";
124 }
125 setLinks("title-changelog", "https://adblockplus.org/releases/adblock-plus-" + versionId + "-for-" + platformId + "-released");
126 setLinks("acceptableAdsExplanation", getDocLink("acceptable_ads_criteria"), openFilters);
127
128 shade = document.getElementById("shade");
129 shade.addEventListener("mouseover", scrollPage, false);
130 shade.addEventListener("mouseout", stopScroll, false);
131
132 // Set up typo feature
133 if (userAgent == "firefox")
Wladimir Palant 2013/05/27 11:02:00 Please don't assume that only Firefox has the typo
Thomas Greiner 2013/05/27 13:03:16 Done.
134 {
135 var typoSettings = document.createElement("script");
136 typoSettings.type = "application/x-javascript;version=1.7";
137 typoSettings.src = "typoSettings.js";
138 document.head.appendChild(typoSettings);
139
140 var toggleTypo = document.getElementById("toggle-typo");
141 updateToggleButton("typo", Prefs.correctTypos);
142 Prefs.addListener(function(name)
143 {
144 if (name == "correctTypos")
145 updateToggleButton("typo", Prefs.correctTypos);
146 });
147 toggleTypo.addEventListener("click", function(event)
148 {
149 TypoActions.setEnabled(!Prefs.correctTypos);
150 }, false);
151 }
152
153 // Set up feature buttons linked to subscriptions
154 setToggleSubscriptionButton("malware");
155 setToggleSubscriptionButton("social");
156 setToggleSubscriptionButton("tracking");
Wladimir Palant 2013/05/27 11:02:00 How about: featureSubscriptions.forEach(setToggle
Thomas Greiner 2013/05/27 13:03:16 Done.
157
158 window.addEventListener("resize", onWindowResize, false);
159 document.addEventListener("scroll", onScroll, false);
160
161 onWindowResize();
162
163 initSocialLinks(null);
164 }
165
166 function onScroll()
167 {
168 var currentHeight = document.documentElement.scrollTop + document.body.scrol lTop + document.documentElement.clientHeight;
169 shade.style.opacity = (document.documentElement.scrollHeight == currentHeigh t) ? "0.0" : "0.5";
170 }
171
172 function onWindowResize()
173 {
174 onScroll();
175 }
176
177 function getSubscription(featureSubscription)
178 {
179 var subscriptions = FilterStorage.subscriptions;
180 for (var i = 0, len = subscriptions.length; i < len; i++)
181 {
182 var subscription = subscriptions[i];
183 if (subscription.url == featureSubscription.url && subscription instanceof DownloadableSubscription)
184 return subscription;
185 }
186
187 return null;
188 }
189
190 function isSubscriptionEnabled(featureSubscription)
191 {
192 var subscription = getSubscription(featureSubscription);
193 return subscription != null && !subscription.disabled;
Wladimir Palant 2013/05/27 11:02:00 FilterStorage keeps a lookup table for listed subs
Thomas Greiner 2013/05/27 13:03:16 Done.
194 }
195
196 function setToggleSubscriptionButton(feature)
197 {
198 var featureSubscription = featureSubscriptions[feature];
199
200 var element = document.getElementById("toggle-" + feature);
201 updateToggleButton(feature, isSubscriptionEnabled(featureSubscription));
202 FilterNotifier.addListener(function(action)
203 {
204 if (/^(filter|subscription)\.(added|removed|disabled)$/.test(action))
205 updateToggleButton(feature, isSubscriptionEnabled(featureSubscription));
Wladimir Palant 2013/05/27 11:02:00 How about adding a single listener that will updat
Thomas Greiner 2013/05/27 13:03:16 Not removing the listeners was a clear oversight,
Thomas Greiner 2013/05/27 16:39:15 Readded with unload.
206 });
207 element.addEventListener("click", function(event)
208 {
209 var subscription = getSubscription(featureSubscription);
210 if (subscription == null)
211 {
212 subscription = Subscription.fromURL(featureSubscription.url);
213 subscription.disabled = false;
214 subscription.title = featureSubscription.title;
215 subscription.homepage = featureSubscription.homepage;
216 FilterStorage.addSubscription(subscription);
217 if (subscription instanceof DownloadableSubscription && !subscription.la stDownload)
218 Synchronizer.execute(subscription);
219 }
220 else if (!subscription.disabled)
221 FilterStorage.removeSubscription(subscription);
222 else
223 subscription.disabled = false;
Wladimir Palant 2013/05/27 11:02:00 The logic should be simpler here, either it's curr
Thomas Greiner 2013/05/27 13:03:16 Done.
224 }, false);
225 }
226
227 function scrollPage()
228 {
229 if (scrollTimer)
230 stopScroll();
231
232 scrollTimer = setInterval(function()
233 {
234 window.scrollBy(0, 5);
235 }, 20);
236 }
237
238 function stopScroll()
239 {
240 clearTimeout(scrollTimer);
241 scrollTimer = null;
242 }
243
244 function openSharePopup(url)
245 {
246 var iframe = document.getElementById("share-popup");
247 var glassPane = document.getElementById("glass-pane");
248 var popupMessageReceived = false;
249
250 var popupMessageListener = function(event)
251 {
252 var originFilter = Filter.fromText("||adblockplus.org^");
253 if (!originFilter.matches(event.origin, "OTHER", null, null))
254 return;
255
256 var width = event.data.width;
257 var height = event.data.height;
258 iframe.width = width;
259 iframe.height = height;
260 iframe.style.marginTop = -height/2 + "px";
261 iframe.style.marginLeft = -width/2 + "px";
262 popupMessageReceived = true;
263 window.removeEventListener("message", popupMessageListener);
264 };
265 // Firefox requires last parameter to be true to be triggered by unprivilege d pages
266 window.addEventListener("message", popupMessageListener, false, true);
267
268 var popupLoadListener = function()
269 {
270 if (popupMessageReceived)
271 {
272 iframe.className = "visible";
273
274 var popupCloseListener = function()
275 {
276 iframe.className = glassPane.className = "";
277 document.removeEventListener("click", popupCloseListener);
278 };
279 document.addEventListener("click", popupCloseListener, false);
280 }
281 else
282 {
283 glassPane.className = "";
284 window.removeEventListener("message", popupMessageListener);
285 }
286
287 iframe.removeEventListener("load", popupLoadListener);
288 };
289 iframe.addEventListener("load", popupLoadListener, false);
290
291 iframe.src = url;
292 glassPane.className = "visible";
293 }
294
295 function initSocialLinks(variant)
296 {
297 var networks = ["twitter", "facebook", "gplus"];
298 networks.forEach(function(network)
299 {
300 var link = document.getElementById("share-" + network);
301 link.addEventListener("click", function(e)
302 {
303 e.preventDefault();
304 openSharePopup(getDocLink("share-" + network) + "&variant=" + variant);
305 }, false);
306 });
307 }
308
309 function setLinks(id)
310 {
311 var element = document.getElementById(id);
312 if (!element)
313 return;
314
315 var links = element.getElementsByTagName("a");
316 for (var i = 0; i < links.length; i++)
317 {
318 if (typeof arguments[i + 1] == "string")
319 {
320 links[i].href = arguments[i + 1];
321 links[i].setAttribute("target", "_blank");
322 }
323 else if (typeof arguments[i + 1] == "function")
324 {
325 links[i].href = "javascript:void(0);";
326 links[i].addEventListener("click", arguments[i + 1], false);
327 }
328 }
329 }
330
331 function getDocLink(page, anchor)
332 {
333 return Prefs.documentation_link
334 .replace(/%LINK%/g, page)
335 .replace(/%LANG%/g, Utils.appLocale) + (anchor ? "#" + anchor : "");
336 }
Wladimir Palant 2013/05/27 11:02:00 The anchor parameter is unnecessary. This is dupl
337
338 function openFilters()
339 {
340 if (userAgent == "firefox")
341 UI.openFiltersDialog();
342 else if (userAgent == "chrome")
343 {
344 backgroundPage.openOptions();
Wladimir Palant 2013/05/27 11:02:00 Again, please don't go by user agents here: if (t
Thomas Greiner 2013/05/27 13:03:16 Done.
345 }
346 }
347
348 function updateToggleButton(feature, isEnabled)
349 {
350 var button = document.getElementById("toggle-" + feature);
351 button.className = isEnabled ? "disable" : "enable";
352 button.textContent = i18n.getMessage(isEnabled ? "firstRun_action_disable" : "firstRun_action_enable");
353 }
354
355 document.addEventListener("DOMContentLoaded", loadScripts, false);
356 })();
OLDNEW

Powered by Google App Engine
This is Rietveld