Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(859)

Side by Side Diff: chrome/browser/resources/ntp/apps.js

Issue 7291004: Wire up notifications to the New Tab page. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 var MAX_APPS_PER_ROW = []; 5 var MAX_APPS_PER_ROW = [];
6 MAX_APPS_PER_ROW[LayoutMode.SMALL] = 4; 6 MAX_APPS_PER_ROW[LayoutMode.SMALL] = 4;
7 MAX_APPS_PER_ROW[LayoutMode.NORMAL] = 6; 7 MAX_APPS_PER_ROW[LayoutMode.NORMAL] = 6;
8 8
9 function getAppsCallback(data) { 9 function getAppsCallback(data) {
10 logEvent('received apps'); 10 logEvent('received apps');
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 function appsPrefChangeCallback(data) { 143 function appsPrefChangeCallback(data) {
144 // Currently the only pref that is watched is the launch type. 144 // Currently the only pref that is watched is the launch type.
145 data.apps.forEach(function(app) { 145 data.apps.forEach(function(app) {
146 var appLink = document.querySelector('.app a[app-id=' + app['id'] + ']'); 146 var appLink = document.querySelector('.app a[app-id=' + app['id'] + ']');
147 if (appLink) 147 if (appLink)
148 appLink.setAttribute('launch-type', app['launch_type']); 148 appLink.setAttribute('launch-type', app['launch_type']);
149 }); 149 });
150 } 150 }
151 151
152 function appNotificationChanged(id, lastNotification) { 152 function appNotificationChanged(id, lastNotification) {
153 // TODO(asargent/finnur) use this when we hook up notifications into the NTP. 153 // TODO(asargent/finnur): Don't update all apps at once, do it in a more
154 // fine grained way.
155 chrome.send('getApps');
154 } 156 }
155 157
156 // Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE histogram. 158 // Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE histogram.
157 // This should only be invoked from the AppLauncherHandler. 159 // This should only be invoked from the AppLauncherHandler.
158 function launchAppAfterEnable(appId) { 160 function launchAppAfterEnable(appId) {
159 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]); 161 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]);
160 } 162 }
161 163
164 // Shows the notification bubble for a given app (the one clicked on).
165 function showNotificationBubble(event) {
166 var item = findAncestorByClass(event.target, 'app-anchor');
167 var title = item.getAttribute('notification-title');
168 var message = item.getAttribute('notification-message');
169 var link = item.getAttribute('notification-link');
170 var link_message = item.getAttribute('notification-link-message');
171
172 if (!title || !message)
173 return;
174
175 // Set the content to the right text.
176 $('app-notification-title').textContent = title;
177 $('app-notification-message').textContent = message;
178 $('app-notification-link').href = link;
179 $('app-notification-link').textContent = link_message;
180
181 var target = event.target;
182 while (target.parentElement && target.tagName != "A") {
183 target = target.parentElement;
184 }
185
186 // Move the bubble to the right location.
187 var bubble = $('app-notification-bubble');
188 var x = target.parentElement.offsetLeft +
189 target.parentElement.offsetWidth - 20;
190 var y = target.parentElement.offsetTop + 20;
191 bubble.style.left = x + "px";
192 bubble.style.top = y + "px";
193
194 // Move the arrow and shadow to the right location.
195 var arrow = $('arrow-contents');
196 var border = $('arrow-border');
197 var shadow = $('arrow-shadow');
198 y += 26;
199 x -= arrow.style.width + 23;
200 arrow.style.left = x + "px";
201 arrow.style.top = y + "px";
202 x -= 1;
203 border.style.left = x + "px";
204 border.style.top = y + "px";
205 x -= 1;
206 shadow.style.left = x + "px";
207 shadow.style.top = y + "px";
208
209 // Animate the bubble into view.
210 bubble.classList.add("notification-bubble-opened");
211 bubble.classList.remove("notification-bubble-closed");
212 arrow.classList.add("notification-bubble-opened");
213 arrow.classList.remove("notification-bubble-closed");
214 border.classList.add("notification-bubble-opened");
215 border.classList.remove("notification-bubble-closed");
216 shadow.classList.add("notification-bubble-opened");
217 shadow.classList.remove("notification-bubble-closed");
218
219 bubble.focus();
220 }
221
222 // Hide the notification bubble.
223 function hideNotificationBubble(event) {
224 // This will fade the bubble out of existence.
225 $('app-notification-bubble').classList.add("notification-bubble-closed");
226 $('app-notification-bubble').classList.remove("notification-bubble-opened");
227 $('arrow-border').classList.add("notification-bubble-closed");
228 $('arrow-border').classList.remove("notification-bubble-opened");
229 $('arrow-shadow').classList.add("notification-bubble-closed");
230 $('arrow-shadow').classList.remove("notification-bubble-opened");
231 $('arrow-contents').classList.add("notification-bubble-closed");
232 $('arrow-contents').classList.remove("notification-bubble-opened");
233 }
234
162 var apps = (function() { 235 var apps = (function() {
163 236
164 function createElement(app) { 237 function createElement(app) {
165 var div = document.createElement('div'); 238 var div = document.createElement('div');
166 div.className = 'app'; 239 div.className = 'app';
167 240
168 var a = div.appendChild(document.createElement('a')); 241 var a = div.appendChild(document.createElement('a'));
242 a.className = 'app-anchor';
169 a.setAttribute('app-id', app['id']); 243 a.setAttribute('app-id', app['id']);
170 a.setAttribute('launch-type', app['launch_type']); 244 a.setAttribute('launch-type', app['launch_type']);
245 if (typeof(app['notification']) != "undefined") {
246 a.setAttribute('notification-title', app['notification']['title']);
247 a.setAttribute('notification-message', app['notification']['body']);
248 if (typeof(app['notification']['linkUrl']) != "undefined" &&
249 typeof(app['notification']['linkText']) != "undefined") {
250 a.setAttribute('notification-link', app['notification']['linkUrl']);
251 a.setAttribute('notification-link-message',
252 app['notification']['linkText']);
253 }
254 }
171 a.draggable = false; 255 a.draggable = false;
172 a.xtitle = a.textContent = app['name'];
173 a.href = app['launch_url']; 256 a.href = app['launch_url'];
174 257
258 var span = a.appendChild(document.createElement('span'));
259 span.textContent = app['name'];
260
261 span = a.appendChild(document.createElement('span'));
262 span.className = "app_notification";
263 span.textContent =
264 typeof(app['notification']) != "undefined" &&
265 typeof(app['notification']['title']) != "undefined" ?
266 app['notification']['title'] : "";
267 span.onclick = handleClick;
268
269 $("app-notification-close").onclick = hideNotificationBubble;
270 $("app-notification-bubble").setAttribute("tabIndex", 0);
271 $("app-notification-bubble").onblur = hideNotificationBubble;
272
175 return div; 273 return div;
176 } 274 }
177 275
178 /** 276 /**
179 * Launches an application. 277 * Launches an application.
180 * @param {string} appId Application to launch. 278 * @param {string} appId Application to launch.
181 * @param {MouseEvent} opt_mouseEvent Mouse event from the click that 279 * @param {MouseEvent} opt_mouseEvent Mouse event from the click that
182 * triggered the launch, used to detect modifier keys that change 280 * triggered the launch, used to detect modifier keys that change
183 * the tab's disposition. 281 * the tab's disposition.
184 */ 282 */
(...skipping 27 matching lines...) Expand all
212 return APP_LAUNCH.NTP_APPS_COLLAPSED; 310 return APP_LAUNCH.NTP_APPS_COLLAPSED;
213 else 311 else
214 return APP_LAUNCH.NTP_APPS_MAXIMIZED; 312 return APP_LAUNCH.NTP_APPS_MAXIMIZED;
215 } 313 }
216 314
217 /** 315 /**
218 * @this {!HTMLAnchorElement} 316 * @this {!HTMLAnchorElement}
219 */ 317 */
220 function handleClick(e) { 318 function handleClick(e) {
221 var appId = e.currentTarget.getAttribute('app-id'); 319 var appId = e.currentTarget.getAttribute('app-id');
320 if (appId == null) {
321 showNotificationBubble(e);
322 e.stopPropagation();
323 return false;
324 }
325
222 if (!appDragAndDrop.isDragging()) 326 if (!appDragAndDrop.isDragging())
223 launchApp(appId, e); 327 launchApp(appId, e);
224 return false; 328 return false;
225 } 329 }
226 330
227 // Keep in sync with LaunchType in extension_prefs.h 331 // Keep in sync with LaunchType in extension_prefs.h
228 var LaunchType = { 332 var LaunchType = {
229 LAUNCH_PINNED: 0, 333 LAUNCH_PINNED: 0,
230 LAUNCH_REGULAR: 1, 334 LAUNCH_REGULAR: 1,
231 LAUNCH_FULLSCREEN: 2, 335 LAUNCH_FULLSCREEN: 2,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 418
315 document.addEventListener('canExecute', function(e) { 419 document.addEventListener('canExecute', function(e) {
316 switch (e.command.id) { 420 switch (e.command.id) {
317 case 'apps-options-command': 421 case 'apps-options-command':
318 e.canExecute = currentApp && currentApp['options_url']; 422 e.canExecute = currentApp && currentApp['options_url'];
319 break; 423 break;
320 case 'apps-launch-command': 424 case 'apps-launch-command':
321 e.canExecute = true; 425 e.canExecute = true;
322 break; 426 break;
323 case 'apps-uninstall-command': 427 case 'apps-uninstall-command':
324 e.canExecute = !currentApp['can_uninstall']; 428 e.canExecute = currentApp && !currentApp['can_uninstall'];
325 break; 429 break;
326 } 430 }
327 }); 431 });
328 432
329 // Moves the element at position |from| in array |arr| to position |to|. 433 // Moves the element at position |from| in array |arr| to position |to|.
330 function arrayMove(arr, from, to) { 434 function arrayMove(arr, from, to) {
331 var element = arr.splice(from, 1); 435 var element = arr.splice(from, 1);
332 arr.splice(to, 0, element[0]); 436 arr.splice(to, 0, element[0]);
333 } 437 }
334 438
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 return; 781 return;
678 } 782 }
679 }, 783 },
680 784
681 showImages: function() { 785 showImages: function() {
682 $('apps-content').classList.add('visible'); 786 $('apps-content').classList.add('visible');
683 clearTimeout(this.imageTimer); 787 clearTimeout(this.imageTimer);
684 }, 788 },
685 789
686 createElement: function(app) { 790 createElement: function(app) {
791 var container = document.createElement('div');
687 var div = createElement(app); 792 var div = createElement(app);
793 container.appendChild(div);
688 var a = div.firstChild; 794 var a = div.firstChild;
689 795
690 a.onclick = handleClick; 796 a.onclick = handleClick;
691 a.ping = getAppPingUrl( 797 a.ping = getAppPingUrl(
692 'PING_BY_ID', this.showPromo, 'NTP_APPS_MAXIMIZED'); 798 'PING_BY_ID', this.showPromo, 'NTP_APPS_MAXIMIZED');
693 a.style.backgroundImage = url(app['icon_big']); 799 a.style.backgroundImage = url(app['icon_big']);
694 if (app.isNew) { 800 if (app.isNew) {
695 div.setAttribute('new', 'new'); 801 div.setAttribute('new', 'new');
696 // Delay changing the attribute a bit to let the page settle down a bit. 802 // Delay changing the attribute a bit to let the page settle down a bit.
697 setTimeout(function() { 803 setTimeout(function() {
(...skipping 14 matching lines...) Expand all
712 img.src = app['icon_big']; 818 img.src = app['icon_big'];
713 819
714 // User cannot change launch options or uninstall component extension. 820 // User cannot change launch options or uninstall component extension.
715 if (!app['is_component']) { 821 if (!app['is_component']) {
716 var settingsButton = div.appendChild(new cr.ui.ContextMenuButton); 822 var settingsButton = div.appendChild(new cr.ui.ContextMenuButton);
717 settingsButton.className = 'app-settings'; 823 settingsButton.className = 'app-settings';
718 settingsButton.title = localStrings.getString('appsettings'); 824 settingsButton.title = localStrings.getString('appsettings');
719 addContextMenu(div, app); 825 addContextMenu(div, app);
720 } 826 }
721 827
722 return div; 828 if (app.notifications && app.notifications.length > 0) {
829 // Create the notification div below the app icon that is used to
830 // trigger the hidden notification bubble to appear.
831 var notification = document.createElement('div')
832 container.appendChild(notification);
833 var title = document.createElement('span');
834 title.innerText = app.notifications[0].title;
835 notification.appendChild(title);
836 notification.appendChild(document.createElement('br'));
837
838 var body = document.createElement('span');
839 container.appendChild(body);
840 body.innerText = app.notifications[0].body;
841 notification.appendChild(body);
842 if (app.notifications[0].linkUrl) {
843 notification.appendChild(document.createElement('br'));
844 var link = document.createElement('a');
845 link.href = app.notifications[0].linkUrl;
846 link.innerText = app.notifications[0].linkText ?
847 app.notifications[0].linkText : "link";
848 notification.appendChild(link);
849 }
850 }
851
852 return container;
723 }, 853 },
724 854
725 createMiniviewElement: function(app) { 855 createMiniviewElement: function(app) {
726 var span = document.createElement('span'); 856 var span = document.createElement('span');
727 var a = span.appendChild(document.createElement('a')); 857 var a = span.appendChild(document.createElement('a'));
728 858
729 a.setAttribute('app-id', app['id']); 859 a.setAttribute('app-id', app['id']);
730 a.textContent = app['name']; 860 a.textContent = app['name'];
731 a.href = app['launch_url']; 861 a.href = app['launch_url'];
732 a.onclick = handleClick; 862 a.onclick = handleClick;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 a.href = localStrings.getString('web_store_url'); 915 a.href = localStrings.getString('web_store_url');
786 a.style.backgroundImage = url('chrome://theme/IDR_WEBSTORE_ICON_16'); 916 a.style.backgroundImage = url('chrome://theme/IDR_WEBSTORE_ICON_16');
787 a.className = 'item'; 917 a.className = 'item';
788 return a; 918 return a;
789 } 919 }
790 }; 920 };
791 })(); 921 })();
792 922
793 // Enable drag and drop reordering of the app launcher. 923 // Enable drag and drop reordering of the app launcher.
794 var appDragAndDrop = new DragAndDropController(apps); 924 var appDragAndDrop = new DragAndDropController(apps);
OLDNEW
« chrome/browser/resources/new_tab.html ('K') | « chrome/browser/resources/ntp/apps.css ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698