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

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

Issue 6825052: Update the web store promo to be clearer and configurable at run-time. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix URL. Created 9 years, 8 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');
11 11
12 // In the case of prefchange-triggered updates, we don't receive this flag. 12 // In the case of prefchange-triggered updates, we don't receive this flag.
13 // Just leave it set as it was before in that case. 13 // Just leave it set as it was before in that case.
14 if ('showPromo' in data) 14 if ('showPromo' in data)
15 apps.showPromo = data.showPromo; 15 apps.showPromo = data.showPromo;
16 16
17 var appsSection = $('apps'); 17 var appsSection = $('apps');
18 var appsSectionContent = $('apps-content'); 18 var appsSectionContent = $('apps-content');
19 var appsMiniview = appsSection.getElementsByClassName('miniview')[0]; 19 var appsMiniview = appsSection.getElementsByClassName('miniview')[0];
20 var appsPromo = $('apps-promo'); 20 var appsPromo = $('apps-promo');
21 var appsPromoLink = $('apps-promo-link');
21 var appsPromoPing = APP_LAUNCH_URL.PING_WEBSTORE + '+' + apps.showPromo; 22 var appsPromoPing = APP_LAUNCH_URL.PING_WEBSTORE + '+' + apps.showPromo;
22 var webStoreEntry, webStoreMiniEntry; 23 var webStoreEntry, webStoreMiniEntry;
23 24
24 // Hide menu options that are not supported on the OS or windowing system. 25 // Hide menu options that are not supported on the OS or windowing system.
25 26
26 // The "Launch as Window" menu option. 27 // The "Launch as Window" menu option.
27 $('apps-launch-type-window-menu-item').hidden = data.disableAppWindowLaunch; 28 $('apps-launch-type-window-menu-item').hidden = data.disableAppWindowLaunch;
28 29
29 // The "Create App Shortcut" menu option. 30 // The "Create App Shortcut" menu option.
30 $('apps-create-shortcut-command-menu-item').hidden = 31 $('apps-create-shortcut-command-menu-item').hidden =
(...skipping 10 matching lines...) Expand all
41 return a.app_launch_index - b.app_launch_index; 42 return a.app_launch_index - b.app_launch_index;
42 }); 43 });
43 44
44 // Determines if the web store link should be detached and place in the 45 // Determines if the web store link should be detached and place in the
45 // top right of the screen. 46 // top right of the screen.
46 apps.detachWebstoreEntry = 47 apps.detachWebstoreEntry =
47 !apps.showPromo && data.apps.length >= MAX_APPS_PER_ROW[layoutMode]; 48 !apps.showPromo && data.apps.length >= MAX_APPS_PER_ROW[layoutMode];
48 49
49 markNewApps(data.apps); 50 markNewApps(data.apps);
50 apps.data = data.apps; 51 apps.data = data.apps;
51 if (!apps.detachWebstoreEntry)
52 apps.data.push('web-store-entry');
53 52
54 clearClosedMenu(apps.menu); 53 clearClosedMenu(apps.menu);
55 54
56 // We wait for the app icons to load before displaying them, but never wait 55 // We wait for the app icons to load before displaying them, but never wait
57 // longer than 200ms. 56 // longer than 200ms.
58 apps.loadedImages = 0; 57 apps.loadedImages = 0;
59 apps.imageTimer = setTimeout(apps.showImages.bind(apps), 200); 58 apps.imageTimer = setTimeout(apps.showImages.bind(apps), 200);
60 59
61 data.apps.forEach(function(app) { 60 data.apps.forEach(function(app) {
62 appsSectionContent.appendChild(apps.createElement(app)); 61 appsSectionContent.appendChild(apps.createElement(app));
63 }); 62 });
64 63
65 webStoreEntry = apps.createWebStoreElement(); 64 if (data.showPromo) {
66 webStoreEntry.querySelector('a').setAttribute('ping', appsPromoPing); 65 // Add the promo content...
67 appsSectionContent.appendChild(webStoreEntry); 66 $('apps-promo-heading').textContent = data.promoHeader;
67 appsPromoLink.href = data.promoLink;
68 appsPromoLink.textContent = data.promoButton;
69 appsPromoLink.setAttribute('ping', appsPromoPing);
arv (Not doing code reviews) 2011/04/13 17:17:59 I added the ping dom binding 2 weeks ago. Can you
jstritar 2011/04/13 19:52:27 Done.
70 $('apps-promo-hide').textContent = data.promoExpire;
71
72 // ... then display the promo.
73 document.documentElement.classList.add('apps-promo-visible');
74 } else {
75 document.documentElement.classList.remove('apps-promo-visible');
76 }
77
78 // Only show the web store entry if there are apps installed, since the promo
79 // is sufficient otherwise.
80 if (data.apps.length > 0) {
81 webStoreEntry = apps.createWebStoreElement();
82 webStoreEntry.querySelector('a').setAttribute('ping', appsPromoPing);
83 appsSectionContent.appendChild(webStoreEntry);
84 if (apps.detachWebstoreEntry) {
85 webStoreEntry.classList.add('loner');
86 } else {
87 webStoreEntry.classList.remove('loner');
88 apps.data.push('web-store-entry');
89 }
90 }
68 91
69 data.apps.slice(0, MAX_MINIVIEW_ITEMS).forEach(function(app) { 92 data.apps.slice(0, MAX_MINIVIEW_ITEMS).forEach(function(app) {
70 appsMiniview.appendChild(apps.createMiniviewElement(app)); 93 appsMiniview.appendChild(apps.createMiniviewElement(app));
71 addClosedMenuEntryWithLink(apps.menu, apps.createClosedMenuElement(app)); 94 addClosedMenuEntryWithLink(apps.menu, apps.createClosedMenuElement(app));
72 }); 95 });
73 if (data.apps.length < MAX_MINIVIEW_ITEMS) { 96 if (data.apps.length < MAX_MINIVIEW_ITEMS) {
74 webStoreMiniEntry = apps.createWebStoreMiniElement(); 97 webStoreMiniEntry = apps.createWebStoreMiniElement();
75 webStoreEntry.querySelector('a').setAttribute('ping', appsPromoPing); 98 webStoreMiniEntry.querySelector('a').setAttribute('ping', appsPromoPing);
76 appsMiniview.appendChild(webStoreMiniEntry); 99 appsMiniview.appendChild(webStoreMiniEntry);
77 addClosedMenuEntryWithLink(apps.menu, 100 addClosedMenuEntryWithLink(apps.menu,
78 apps.createWebStoreClosedMenuElement()); 101 apps.createWebStoreClosedMenuElement());
79 } 102 }
80 103
81 if (!data.showLauncher) 104 if (!data.showLauncher)
82 hideSection(Section.APPS); 105 hideSection(Section.APPS);
83 else 106 else
84 appsSection.classList.remove('disabled'); 107 appsSection.classList.remove('disabled');
85 108
86 addClosedMenuFooter(apps.menu, 'apps', MENU_APPS, Section.APPS); 109 addClosedMenuFooter(apps.menu, 'apps', MENU_APPS, Section.APPS);
87 110
88 apps.loaded = true; 111 apps.loaded = true;
89 if (apps.showPromo)
90 document.documentElement.classList.add('apps-promo-visible');
91 else
92 document.documentElement.classList.remove('apps-promo-visible');
93 112
94 var appsPromoLink = $('apps-promo-link'); 113 var appsPromoLink = $('apps-promo-link');
95 if (appsPromoLink) 114 if (appsPromoLink)
96 appsPromoLink.setAttribute('ping', appsPromoPing); 115 appsPromoLink.setAttribute('ping', appsPromoPing);
97 maybeDoneLoading(); 116 maybeDoneLoading();
98 117
99 // Disable the animations when the app launcher is being (re)initailized. 118 // Disable the animations when the app launcher is being (re)initailized.
100 apps.layout({disableAnimations:true}); 119 apps.layout({disableAnimations:true});
101 120
102 if (apps.detachWebstoreEntry)
103 webStoreEntry.classList.add('loner');
104 else
105 webStoreEntry.classList.remove('loner');
106
107 if (isDoneLoading()) { 121 if (isDoneLoading()) {
108 updateMiniviewClipping(appsMiniview); 122 updateMiniviewClipping(appsMiniview);
109 layoutSections(); 123 layoutSections();
110 } 124 }
111 } 125 }
112 126
113 function markNewApps(data) { 127 function markNewApps(data) {
114 var oldData = apps.data; 128 var oldData = apps.data;
115 data.forEach(function(app) { 129 data.forEach(function(app) {
116 if (hashParams['app-id'] == app['id']) { 130 if (hashParams['app-id'] == app['id']) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 if (opt_mouseEvent) { 182 if (opt_mouseEvent) {
169 // Launch came from a click - add details of the click 183 // Launch came from a click - add details of the click
170 // Otherwise it came from a 'command' event from elsewhere in the UI. 184 // Otherwise it came from a 'command' event from elsewhere in the UI.
171 args.push(opt_mouseEvent.altKey, opt_mouseEvent.ctrlKey, 185 args.push(opt_mouseEvent.altKey, opt_mouseEvent.ctrlKey,
172 opt_mouseEvent.metaKey, opt_mouseEvent.shiftKey, 186 opt_mouseEvent.metaKey, opt_mouseEvent.shiftKey,
173 opt_mouseEvent.button); 187 opt_mouseEvent.button);
174 } 188 }
175 chrome.send('launchApp', args); 189 chrome.send('launchApp', args);
176 } 190 }
177 191
192 function isAppSectionMaximized() {
193 return (getAppLaunchType() == APP_LAUNCH.NTP_APPS_MAXIMIZED) &&
arv (Not doing code reviews) 2011/04/13 17:17:59 useless parentheses
jstritar 2011/04/13 19:52:27 Done.
194 !$('apps').classList.contains('disabled');
195 }
196
178 function isAppsMenu(node) { 197 function isAppsMenu(node) {
179 return node.id == 'apps-menu'; 198 return node.id == 'apps-menu';
180 } 199 }
181 200
182 function getAppLaunchType() { 201 function getAppLaunchType() {
183 // We determine if the apps section is maximized, collapsed or in menu mode 202 // We determine if the apps section is maximized, collapsed or in menu mode
184 // based on the class of the apps section. 203 // based on the class of the apps section.
185 if ($('apps').classList.contains('menu')) 204 if ($('apps').classList.contains('menu'))
186 return APP_LAUNCH.NTP_APPS_MENU; 205 return APP_LAUNCH.NTP_APPS_MENU;
187 else if ($('apps').classList.contains('collapsed')) 206 else if ($('apps').classList.contains('collapsed'))
(...skipping 21 matching lines...) Expand all
209 }; 228 };
210 229
211 // Keep in sync with LaunchContainer in extension_constants.h 230 // Keep in sync with LaunchContainer in extension_constants.h
212 var LaunchContainer = { 231 var LaunchContainer = {
213 LAUNCH_WINDOW: 0, 232 LAUNCH_WINDOW: 0,
214 LAUNCH_PANEL: 1, 233 LAUNCH_PANEL: 1,
215 LAUNCH_TAB: 2 234 LAUNCH_TAB: 2
216 }; 235 };
217 236
218 var currentApp; 237 var currentApp;
238 var promoHasBeenSeen = false;
219 239
220 function addContextMenu(el, app) { 240 function addContextMenu(el, app) {
221 el.addEventListener('contextmenu', cr.ui.contextMenuHandler); 241 el.addEventListener('contextmenu', cr.ui.contextMenuHandler);
222 el.addEventListener('keydown', cr.ui.contextMenuHandler); 242 el.addEventListener('keydown', cr.ui.contextMenuHandler);
223 el.addEventListener('keyup', cr.ui.contextMenuHandler); 243 el.addEventListener('keyup', cr.ui.contextMenuHandler);
224 244
225 Object.defineProperty(el, 'contextMenu', { 245 Object.defineProperty(el, 'contextMenu', {
226 get: function() { 246 get: function() {
227 currentApp = app; 247 currentApp = app;
228 248
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 360
341 visible_: true, 361 visible_: true,
342 get visible() { 362 get visible() {
343 return this.visible_; 363 return this.visible_;
344 }, 364 },
345 set visible(visible) { 365 set visible(visible) {
346 this.visible_ = visible; 366 this.visible_ = visible;
347 this.invalidate_(); 367 this.invalidate_();
348 }, 368 },
349 369
370 maybePingPromoSeen_: function() {
371 if (promoHasBeenSeen) return;
arv (Not doing code reviews) 2011/04/13 17:17:59 if (...) return;
jstritar 2011/04/13 19:52:27 Done.
372 if (!this.showPromo || !isAppSectionMaximized()) return;
arv (Not doing code reviews) 2011/04/13 17:17:59 merge if statements?
jstritar 2011/04/13 19:52:27 Done.
373
374 promoHasBeenSeen = true;
375 chrome.send('promoSeen', []);
376 },
377
350 // DragAndDropDelegate 378 // DragAndDropDelegate
351 379
352 dragContainer: $('apps-content'), 380 dragContainer: $('apps-content'),
353 transitionsDuration: 200, 381 transitionsDuration: 200,
354 382
355 get dragItem() { return this.dragItem_; }, 383 get dragItem() { return this.dragItem_; },
356 set dragItem(dragItem) { 384 set dragItem(dragItem) {
357 if (this.dragItem_ != dragItem) { 385 if (this.dragItem_ != dragItem) {
358 this.dragItem_ = dragItem; 386 this.dragItem_ = dragItem;
359 this.invalidate_(); 387 this.invalidate_();
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 // We need to re-enable animations asynchronously, so that the 585 // We need to re-enable animations asynchronously, so that the
558 // animations are still disabled for this layout update. 586 // animations are still disabled for this layout update.
559 setTimeout(function() { 587 setTimeout(function() {
560 container.setAttribute('launcher-animations', true); 588 container.setAttribute('launcher-animations', true);
561 }, 0); 589 }, 0);
562 } 590 }
563 } 591 }
564 }, 592 },
565 593
566 layoutImpl_: function() { 594 layoutImpl_: function() {
567 var apps = this.data; 595 var apps = this.data || [];
568 var rects = this.getLayoutRects_(apps.length); 596 var rects = this.getLayoutRects_(apps.length);
569 var appsContent = this.dragContainer; 597 var appsContent = this.dragContainer;
570 598
599 // Ping the PROMO_SEEN histogram only when the promo is maximized, and
600 // maximum once per NTP load.
601 this.maybePingPromoSeen_();
602
571 if (!this.visible) 603 if (!this.visible)
572 return; 604 return;
573 605
574 for (var i = 0; i < apps.length; i++) { 606 for (var i = 0; i < apps.length; i++) {
575 var app = appsContent.querySelector('[app-id='+apps[i]+']').parentNode; 607 var app = appsContent.querySelector('[app-id='+apps[i]+']').parentNode;
576 608
577 // If the node is being dragged, don't try to place it in the grid. 609 // If the node is being dragged, don't try to place it in the grid.
578 if (app == this.dragItem) 610 if (app == this.dragItem)
579 continue; 611 continue;
580 612
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 a.href = localStrings.getString('web_store_url'); 772 a.href = localStrings.getString('web_store_url');
741 a.style.backgroundImage = url('chrome://theme/IDR_PRODUCT_LOGO_16'); 773 a.style.backgroundImage = url('chrome://theme/IDR_PRODUCT_LOGO_16');
742 a.className = 'item'; 774 a.className = 'item';
743 return a; 775 return a;
744 } 776 }
745 }; 777 };
746 })(); 778 })();
747 779
748 // Enable drag and drop reordering of the app launcher. 780 // Enable drag and drop reordering of the app launcher.
749 var appDragAndDrop = new DragAndDropController(apps); 781 var appDragAndDrop = new DragAndDropController(apps);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698