Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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); |
| OLD | NEW |