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

Side by Side Diff: lib/notificationHelper.js

Issue 6063199216467968: Issue 2642 - Moved notifications code to separate module (Closed)
Patch Set: Fixed typo in comment Created June 5, 2015, 2:06 p.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 | « background.js ('k') | metadata.common » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
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/>.
16 */
17
18 /** @module notificationHelper */
19
20 let {startIconAnimation, stopIconAnimation} = require("icon");
21 let {Utils} = require("utils");
22 let {Notification: NotificationStorage} = require("notification");
23 let {stringifyURL} = require("url");
24 let {initAntiAdblockNotification} = require("antiadblockInit");
25
26 let activeNotification = null;
27
28 // Chrome on Linux does not fully support chrome.notifications until version 35
29 // https://code.google.com/p/chromium/issues/detail?id=291485
30 let canUseChromeNotifications = (function()
31 {
32 let info = require("info");
33 if (info.platform == "chromium" && "notifications" in chrome)
34 {
35 if (navigator.platform.indexOf("Linux") == -1)
36 return true;
37 if (Services.vc.compare(info.applicationVersion, "35") >= 0)
38 return true;
39 }
40 return false;
41 })();
42
43 function prepareNotificationIconAndPopup()
44 {
45 let animateIcon = (activeNotification.type != "question");
46 activeNotification.onClicked = function()
47 {
48 if (animateIcon)
49 stopIconAnimation();
50 notificationClosed();
51 };
52 if (animateIcon)
53 startIconAnimation(activeNotification.type);
54 }
55
56 function openNotificationLinks()
57 {
58 if (activeNotification.links)
59 {
60 activeNotification.links.forEach(function(link)
61 {
62 ext.windows.getLastFocused(function(win)
63 {
64 win.openTab(Utils.getDocLink(link));
65 });
66 });
67 }
68 }
69
70 function notificationButtonClick(buttonIndex)
71 {
72 if (activeNotification.type == "question")
73 {
74 NotificationStorage.triggerQuestionListeners(activeNotification.id, buttonIn dex == 0);
75 NotificationStorage.markAsShown(activeNotification.id);
76 activeNotification.onClicked();
77 }
78 else if (activeNotification.links && activeNotification.links[buttonIndex])
79 {
80 ext.windows.getLastFocused(function(win)
81 {
82 win.openTab(Utils.getDocLink(activeNotification.links[buttonIndex]));
83 });
84 }
85 }
86
87 function notificationClosed()
88 {
89 activeNotification = null;
90 }
91
92 function imgToBase64(url, callback)
93 {
94 let canvas = document.createElement("canvas"),
95 ctx = canvas.getContext("2d"),
96 img = new Image;
97 img.src = url;
98 img.onload = function()
99 {
100 canvas.height = img.height;
101 canvas.width = img.width;
102 ctx.drawImage(img, 0, 0);
103 callback(canvas.toDataURL("image/png"));
104 canvas = null;
105 };
106 }
107
108 function initChromeNotifications()
109 {
110 // Chrome hides notifications in notification center when clicked so we need t o clear them
111 function clearActiveNotification(notificationId)
112 {
113 if (activeNotification && activeNotification.type != "question" && !("links" in activeNotification))
114 return;
115
116 chrome.notifications.clear(notificationId, function(wasCleared)
117 {
118 if (wasCleared)
119 notificationClosed();
120 });
121 }
122
123 chrome.notifications.onButtonClicked.addListener(function(notificationId, butt onIndex)
124 {
125 notificationButtonClick(buttonIndex);
126 clearActiveNotification(notificationId);
127 });
128 chrome.notifications.onClicked.addListener(clearActiveNotification);
129 chrome.notifications.onClosed.addListener(notificationClosed);
130 }
131
132 /**
133 * Initializes the notification system.
134 */
135 exports.initNotifications = function()
136 {
137 if (canUseChromeNotifications)
138 initChromeNotifications();
139 initAntiAdblockNotification();
140 };
141
142 let showNextNotification =
143 /**
144 * Shows the next notification from the queue if any.
145 *
146 * @param {URL} [url] URL to match notifications to
147 */
148 exports.showNextNotification = function(url)
149 {
150 let notification = NotificationStorage.getNextToShow(url && stringifyURL(url)) ;
151 if (!notification || activeNotification && activeNotification.id == notificati on.id)
152 return;
153
154 activeNotification = notification;
155 if (activeNotification.type == "critical" || activeNotification.type == "quest ion")
156 {
157 let texts = NotificationStorage.getLocalizedTexts(notification);
158 let title = texts.title || "";
159 let message = texts.message ? texts.message.replace(/<\/?(a|strong)>/g, "") : "";
160 let iconUrl = ext.getURL("icons/detailed/abp-128.png");
161 let hasLinks = activeNotification.links && activeNotification.links.length > 0;
162
163 if (canUseChromeNotifications)
164 {
165 let opts = {
166 type: "basic",
167 title: title,
168 message: message,
169 buttons: [],
170 priority: 2 // We use the highest priority to prevent the notification f rom closing automatically
171 };
172 if (activeNotification.type == "question")
173 {
174 opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt on_yes")});
175 opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt on_no")});
176 }
177 else
178 {
179 let regex = /<a>(.*?)<\/a>/g;
180 let plainMessage = texts.message || "";
181 let match;
182 while (match = regex.exec(plainMessage))
183 opts.buttons.push({title: match[1]});
184 }
185
186 imgToBase64(iconUrl, function(iconData)
187 {
188 opts["iconUrl"] = iconData;
189 chrome.notifications.create("", opts, function() {});
190 });
191 }
192 else if ("Notification" in window && activeNotification.type != "question")
193 {
194 if (hasLinks)
195 message += " " + ext.i18n.getMessage("notification_without_buttons");
196
197 imgToBase64(iconUrl, function(iconData)
198 {
199 let notification = new Notification(
200 title,
201 {
202 lang: Utils.appLocale,
203 dir: ext.i18n.getMessage("@@bidi_dir"),
204 body: message,
205 icon: iconData
206 }
207 );
208
209 notification.addEventListener("click", openNotificationLinks);
210 notification.addEventListener("close", notificationClosed);
211 });
212 }
213 else
214 {
215 let message = title + "\n" + message;
216 if (hasLinks)
217 message += "\n\n" + ext.i18n.getMessage("notification_with_buttons");
218
219 let approved = confirm(message);
220 if (activeNotification.type == "question")
221 notificationButtonClick(approved ? 0 : 1);
222 else if (approved)
223 openNotificationLinks();
224 }
225 }
226 prepareNotificationIconAndPopup();
227 };
228
229 setTimeout(showNextNotification, 3 * 60 * 1000);
OLDNEW
« no previous file with comments | « background.js ('k') | metadata.common » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld