| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 cr.define('ntp', function() { | 5 cr.define('ntp', function() { |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 var APP_LAUNCH = { | 8 var APP_LAUNCH = { |
| 9 // The histogram buckets (keep in sync with extension_constants.h). | 9 // The histogram buckets (keep in sync with extension_constants.h). |
| 10 NTP_APPS_MAXIMIZED: 0, | 10 NTP_APPS_MAXIMIZED: 0, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 var self = this; | 58 var self = this; |
| 59 this.forAllLaunchTypes_(function(launchTypeButton, id) { | 59 this.forAllLaunchTypes_(function(launchTypeButton, id) { |
| 60 launchTypeButton.addEventListener('activate', | 60 launchTypeButton.addEventListener('activate', |
| 61 self.onLaunchTypeChanged_.bind(self)); | 61 self.onLaunchTypeChanged_.bind(self)); |
| 62 }); | 62 }); |
| 63 | 63 |
| 64 this.launchTypeMenuSeparator_ = cr.ui.MenuItem.createSeparator(); | 64 this.launchTypeMenuSeparator_ = cr.ui.MenuItem.createSeparator(); |
| 65 menu.appendChild(this.launchTypeMenuSeparator_); | 65 menu.appendChild(this.launchTypeMenuSeparator_); |
| 66 this.options_ = this.appendMenuItem_('appoptions'); | 66 this.options_ = this.appendMenuItem_('appoptions'); |
| 67 this.details_ = this.appendMenuItem_('appdetails'); | 67 this.details_ = this.appendMenuItem_('appdetails'); |
| 68 this.disableNotifications_ = | |
| 69 this.appendMenuItem_('appdisablenotifications'); | |
| 70 this.uninstall_ = this.appendMenuItem_('appuninstall'); | 68 this.uninstall_ = this.appendMenuItem_('appuninstall'); |
| 71 this.options_.addEventListener('activate', | 69 this.options_.addEventListener('activate', |
| 72 this.onShowOptions_.bind(this)); | 70 this.onShowOptions_.bind(this)); |
| 73 this.details_.addEventListener('activate', | 71 this.details_.addEventListener('activate', |
| 74 this.onShowDetails_.bind(this)); | 72 this.onShowDetails_.bind(this)); |
| 75 this.disableNotifications_.addEventListener( | |
| 76 'activate', this.onDisableNotifications_.bind(this)); | |
| 77 this.uninstall_.addEventListener('activate', | 73 this.uninstall_.addEventListener('activate', |
| 78 this.onUninstall_.bind(this)); | 74 this.onUninstall_.bind(this)); |
| 79 | 75 |
| 80 if (!cr.isChromeOS) { | 76 if (!cr.isChromeOS) { |
| 81 this.createShortcutSeparator_ = | 77 this.createShortcutSeparator_ = |
| 82 menu.appendChild(cr.ui.MenuItem.createSeparator()); | 78 menu.appendChild(cr.ui.MenuItem.createSeparator()); |
| 83 this.createShortcut_ = this.appendMenuItem_('appcreateshortcut'); | 79 this.createShortcut_ = this.appendMenuItem_('appcreateshortcut'); |
| 84 this.createShortcut_.addEventListener( | 80 this.createShortcut_.addEventListener( |
| 85 'activate', this.onCreateShortcut_.bind(this)); | 81 'activate', this.onCreateShortcut_.bind(this)); |
| 86 } | 82 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 launchTypeButton.checked = app.appData.launch_type == id; | 133 launchTypeButton.checked = app.appData.launch_type == id; |
| 138 launchTypeButton.hidden = app.appData.packagedApp; | 134 launchTypeButton.hidden = app.appData.packagedApp; |
| 139 }); | 135 }); |
| 140 | 136 |
| 141 this.launchTypeMenuSeparator_.hidden = app.appData.packagedApp; | 137 this.launchTypeMenuSeparator_.hidden = app.appData.packagedApp; |
| 142 | 138 |
| 143 this.options_.disabled = !app.appData.optionsUrl || !app.appData.enabled; | 139 this.options_.disabled = !app.appData.optionsUrl || !app.appData.enabled; |
| 144 this.details_.disabled = !app.appData.detailsUrl; | 140 this.details_.disabled = !app.appData.detailsUrl; |
| 145 this.uninstall_.disabled = !app.appData.mayDisable; | 141 this.uninstall_.disabled = !app.appData.mayDisable; |
| 146 | 142 |
| 147 this.disableNotifications_.hidden = true; | |
| 148 var notificationsDisabled = app.appData.notifications_disabled; | |
| 149 if (typeof notificationsDisabled != 'undefined') { | |
| 150 this.disableNotifications_.hidden = false; | |
| 151 this.disableNotifications_.checked = notificationsDisabled; | |
| 152 } | |
| 153 if (cr.isMac) { | 143 if (cr.isMac) { |
| 154 // On Windows and Linux, these should always be visible. On ChromeOS, | 144 // On Windows and Linux, these should always be visible. On ChromeOS, |
| 155 // they are never created. On Mac, shortcuts can only be created for | 145 // they are never created. On Mac, shortcuts can only be created for |
| 156 // new-style packaged apps, so hide the menu item. | 146 // new-style packaged apps, so hide the menu item. |
| 157 this.createShortcutSeparator_.hidden = this.createShortcut_.hidden = | 147 this.createShortcutSeparator_.hidden = this.createShortcut_.hidden = |
| 158 !app.appData.packagedApp; | 148 !app.appData.packagedApp; |
| 159 } | 149 } |
| 160 }, | 150 }, |
| 161 | 151 |
| 162 /** | 152 /** |
| (...skipping 17 matching lines...) Expand all Loading... |
| 180 }); | 170 }); |
| 181 }, | 171 }, |
| 182 onShowOptions_: function(e) { | 172 onShowOptions_: function(e) { |
| 183 window.location = this.app_.appData.optionsUrl; | 173 window.location = this.app_.appData.optionsUrl; |
| 184 }, | 174 }, |
| 185 onShowDetails_: function(e) { | 175 onShowDetails_: function(e) { |
| 186 var url = this.app_.appData.detailsUrl; | 176 var url = this.app_.appData.detailsUrl; |
| 187 url = appendParam(url, 'utm_source', 'chrome-ntp-launcher'); | 177 url = appendParam(url, 'utm_source', 'chrome-ntp-launcher'); |
| 188 window.location = url; | 178 window.location = url; |
| 189 }, | 179 }, |
| 190 onDisableNotifications_: function(e) { | |
| 191 var app = this.app_; | |
| 192 app.removeBubble(); | |
| 193 // Toggle the current disable setting. | |
| 194 var newSetting = !this.disableNotifications_.checked; | |
| 195 app.appData.notifications_disabled = newSetting; | |
| 196 chrome.send('setNotificationsDisabled', [app.appData.id, newSetting]); | |
| 197 }, | |
| 198 onUninstall_: function(e) { | 180 onUninstall_: function(e) { |
| 199 chrome.send('uninstallApp', [this.app_.appData.id]); | 181 chrome.send('uninstallApp', [this.app_.appData.id]); |
| 200 }, | 182 }, |
| 201 onCreateShortcut_: function(e) { | 183 onCreateShortcut_: function(e) { |
| 202 chrome.send('createAppShortcut', [this.app_.appData.id]); | 184 chrome.send('createAppShortcut', [this.app_.appData.id]); |
| 203 }, | 185 }, |
| 204 }; | 186 }; |
| 205 | 187 |
| 206 /** | 188 /** |
| 207 * Creates a new App object. | 189 * Creates a new App object. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 chrome.send('getAppIconDominantColor', [this.id]); | 234 chrome.send('getAppIconDominantColor', [this.id]); |
| 253 } else { | 235 } else { |
| 254 this.addLaunchClickTarget_(this.appImgContainer_); | 236 this.addLaunchClickTarget_(this.appImgContainer_); |
| 255 this.appImgContainer_.title = this.appData_.title; | 237 this.appImgContainer_.title = this.appData_.title; |
| 256 } | 238 } |
| 257 | 239 |
| 258 var appSpan = this.appContents_.querySelector('.title'); | 240 var appSpan = this.appContents_.querySelector('.title'); |
| 259 appSpan.textContent = appSpan.title = this.appData_.title; | 241 appSpan.textContent = appSpan.title = this.appData_.title; |
| 260 this.addLaunchClickTarget_(appSpan); | 242 this.addLaunchClickTarget_(appSpan); |
| 261 | 243 |
| 262 var notification = this.appData_.notification; | |
| 263 var hasNotification = typeof notification != 'undefined' && | |
| 264 typeof notification['title'] != 'undefined' && | |
| 265 typeof notification['body'] != 'undefined' && | |
| 266 !this.appData_.notifications_disabled; | |
| 267 if (hasNotification) | |
| 268 this.setupNotification_(notification); | |
| 269 | |
| 270 this.addEventListener('keydown', cr.ui.contextMenuHandler); | 244 this.addEventListener('keydown', cr.ui.contextMenuHandler); |
| 271 this.addEventListener('keyup', cr.ui.contextMenuHandler); | 245 this.addEventListener('keyup', cr.ui.contextMenuHandler); |
| 272 | 246 |
| 273 // This hack is here so that appContents.contextMenu will be the same as | 247 // This hack is here so that appContents.contextMenu will be the same as |
| 274 // this.contextMenu. | 248 // this.contextMenu. |
| 275 var self = this; | 249 var self = this; |
| 276 this.appContents_.__defineGetter__('contextMenu', function() { | 250 this.appContents_.__defineGetter__('contextMenu', function() { |
| 277 return self.contextMenu; | 251 return self.contextMenu; |
| 278 }); | 252 }); |
| 279 this.appContents_.addEventListener('contextmenu', | 253 this.appContents_.addEventListener('contextmenu', |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 if (this.appImgSrc_) { | 302 if (this.appImgSrc_) { |
| 329 this.appImg_.src = this.appImgSrc_; | 303 this.appImg_.src = this.appImgSrc_; |
| 330 this.appImg_.classList.remove('invisible'); | 304 this.appImg_.classList.remove('invisible'); |
| 331 this.appImgSrc_ = null; | 305 this.appImgSrc_ = null; |
| 332 } | 306 } |
| 333 | 307 |
| 334 this.classList.remove('icon-loading'); | 308 this.classList.remove('icon-loading'); |
| 335 }, | 309 }, |
| 336 | 310 |
| 337 /** | 311 /** |
| 338 * Creates a bubble node. | |
| 339 * @param {Object} notification The notification to show in the bubble. | |
| 340 * @param {boolean} full Whether we want the headline or just the content. | |
| 341 * @private | |
| 342 */ | |
| 343 createBubbleNode_: function(notification, full) { | |
| 344 if (!full) { | |
| 345 var titleItem = this.ownerDocument.createElement('span'); | |
| 346 titleItem.textContent = notification['title']; | |
| 347 return titleItem; | |
| 348 } else { | |
| 349 var container = this.ownerDocument.createElement('div'); | |
| 350 | |
| 351 var messageItem = this.ownerDocument.createElement('div'); | |
| 352 messageItem.textContent = notification['body']; | |
| 353 container.appendChild(messageItem); | |
| 354 | |
| 355 if (notification['linkUrl'] && notification['linkText']) { | |
| 356 var anchor = this.ownerDocument.createElement('a'); | |
| 357 anchor.href = notification['linkUrl']; | |
| 358 anchor.textContent = notification['linkText']; | |
| 359 container.appendChild(anchor); | |
| 360 } | |
| 361 | |
| 362 return container; | |
| 363 } | |
| 364 }, | |
| 365 | |
| 366 /** | |
| 367 * Sets up a notification for the app icon. | |
| 368 * @param {Object} notification The notification to show in the bubble. | |
| 369 * @private | |
| 370 */ | |
| 371 setupNotification_: function(notification) { | |
| 372 if (notification) { | |
| 373 var infoBubble; | |
| 374 if (!this.currentBubbleShowing_) { | |
| 375 // Create a new bubble. | |
| 376 infoBubble = new cr.ui.ExpandableBubble; | |
| 377 infoBubble.anchorNode = this; | |
| 378 infoBubble.appId = this.appData_.id; | |
| 379 infoBubble.handleCloseEvent = function() { | |
| 380 chrome.send('closeNotification', [this.appId]); | |
| 381 infoBubble.hide(); | |
| 382 }; | |
| 383 } else { | |
| 384 // Reuse the old bubble instead of popping up a new bubble over | |
| 385 // the old one. | |
| 386 infoBubble = this.currentBubbleShowing_; | |
| 387 infoBubble.collapseBubble_(); | |
| 388 } | |
| 389 infoBubble.contentTitle = this.createBubbleNode_(notification, false); | |
| 390 infoBubble.content = this.createBubbleNode_(notification, true); | |
| 391 infoBubble.show(); | |
| 392 infoBubble.resizeAndReposition(); | |
| 393 | |
| 394 this.currentBubbleShowing_ = infoBubble; | |
| 395 } | |
| 396 }, | |
| 397 | |
| 398 /** | |
| 399 * Removes the info bubble if there is one. | |
| 400 */ | |
| 401 removeBubble: function() { | |
| 402 if (this.currentBubbleShowing_) { | |
| 403 this.currentBubbleShowing_.hide(); | |
| 404 this.currentBubbleShowing_ = null; | |
| 405 } | |
| 406 }, | |
| 407 | |
| 408 /** | |
| 409 * Set the size and position of the app tile. | 312 * Set the size and position of the app tile. |
| 410 * @param {number} size The total size of |this|. | 313 * @param {number} size The total size of |this|. |
| 411 * @param {number} x The x-position. | 314 * @param {number} x The x-position. |
| 412 * @param {number} y The y-position. | 315 * @param {number} y The y-position. |
| 413 * animate. | 316 * animate. |
| 414 */ | 317 */ |
| 415 setBounds: function(size, x, y) { | 318 setBounds: function(size, x, y) { |
| 416 var imgSize = size * APP_IMG_SIZE_FRACTION; | 319 var imgSize = size * APP_IMG_SIZE_FRACTION; |
| 417 this.appImgContainer_.style.width = this.appImgContainer_.style.height = | 320 this.appImgContainer_.style.width = this.appImgContainer_.style.height = |
| 418 toCssPx(this.useSmallIcon_ ? 16 : imgSize); | 321 toCssPx(this.useSmallIcon_ ? 16 : imgSize); |
| 419 if (this.useSmallIcon_) { | 322 if (this.useSmallIcon_) { |
| 420 // 3/4 is the ratio of 96px to 128px (the used height and full height | 323 // 3/4 is the ratio of 96px to 128px (the used height and full height |
| 421 // of icons in apps). | 324 // of icons in apps). |
| 422 var iconSize = imgSize * 3 / 4; | 325 var iconSize = imgSize * 3 / 4; |
| 423 // The -2 is for the div border to improve the visual alignment for the | 326 // The -2 is for the div border to improve the visual alignment for the |
| 424 // icon div. | 327 // icon div. |
| 425 this.imgDiv_.style.width = this.imgDiv_.style.height = | 328 this.imgDiv_.style.width = this.imgDiv_.style.height = |
| 426 toCssPx(iconSize - 2); | 329 toCssPx(iconSize - 2); |
| 427 // Margins set to get the icon placement right and the text to line up. | 330 // Margins set to get the icon placement right and the text to line up. |
| 428 this.imgDiv_.style.marginTop = this.imgDiv_.style.marginBottom = | 331 this.imgDiv_.style.marginTop = this.imgDiv_.style.marginBottom = |
| 429 toCssPx((imgSize - iconSize) / 2); | 332 toCssPx((imgSize - iconSize) / 2); |
| 430 } | 333 } |
| 431 | 334 |
| 432 this.style.width = this.style.height = toCssPx(size); | 335 this.style.width = this.style.height = toCssPx(size); |
| 433 this.style.left = toCssPx(x); | 336 this.style.left = toCssPx(x); |
| 434 this.style.right = toCssPx(x); | 337 this.style.right = toCssPx(x); |
| 435 this.style.top = toCssPx(y); | 338 this.style.top = toCssPx(y); |
| 436 | |
| 437 if (this.currentBubbleShowing_) | |
| 438 this.currentBubbleShowing_.resizeAndReposition(); | |
| 439 }, | 339 }, |
| 440 | 340 |
| 441 /** | 341 /** |
| 442 * Invoked when an app is clicked. | 342 * Invoked when an app is clicked. |
| 443 * @param {Event} e The click event. | 343 * @param {Event} e The click event. |
| 444 * @private | 344 * @private |
| 445 */ | 345 */ |
| 446 onClick_: function(e) { | 346 onClick_: function(e) { |
| 447 var url = !this.appData_.is_webstore ? '' : | 347 var url = !this.appData_.is_webstore ? '' : |
| 448 appendParam(this.appData_.url, | 348 appendParam(this.appData_.url, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 * will cause the app icon to look active). | 407 * will cause the app icon to look active). |
| 508 * @param {HTMLElement} node The node that should be clickable. | 408 * @param {HTMLElement} node The node that should be clickable. |
| 509 */ | 409 */ |
| 510 addLaunchClickTarget_: function(node) { | 410 addLaunchClickTarget_: function(node) { |
| 511 node.classList.add('launch-click-target'); | 411 node.classList.add('launch-click-target'); |
| 512 node.addEventListener('click', this.onClick_.bind(this)); | 412 node.addEventListener('click', this.onClick_.bind(this)); |
| 513 }, | 413 }, |
| 514 | 414 |
| 515 /** | 415 /** |
| 516 * Handler for mousedown on the App. Adds a class that allows us to | 416 * Handler for mousedown on the App. Adds a class that allows us to |
| 517 * not display as :active for right clicks and clicks on app notifications | 417 * not display as :active for right clicks (specifically, don't pulse on |
| 518 * (specifically, don't pulse on these occasions). Also, we don't pulse | 418 * these occasions). Also, we don't pulse for clicks that aren't within the |
| 519 * for clicks that aren't within the clickable regions. | 419 * clickable regions. |
| 520 * @param {Event} e The mousedown event. | 420 * @param {Event} e The mousedown event. |
| 521 */ | 421 */ |
| 522 onMousedown_: function(e) { | 422 onMousedown_: function(e) { |
| 523 // If the current platform uses middle click to autoscroll and this | 423 // If the current platform uses middle click to autoscroll and this |
| 524 // mousedown isn't handled, onClick_() will never fire. crbug.com/142939 | 424 // mousedown isn't handled, onClick_() will never fire. crbug.com/142939 |
| 525 if (e.button == 1) | 425 if (e.button == 1) |
| 526 e.preventDefault(); | 426 e.preventDefault(); |
| 527 | 427 |
| 528 if (e.button == 2 || | 428 if (e.button == 2 || |
| 529 !findAncestorByClass(e.target, 'launch-click-target')) { | 429 !findAncestorByClass(e.target, 'launch-click-target')) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 canBeRemoved: function() { | 482 canBeRemoved: function() { |
| 583 return this.appData_.mayDisable; | 483 return this.appData_.mayDisable; |
| 584 }, | 484 }, |
| 585 | 485 |
| 586 /** | 486 /** |
| 587 * Uninstalls the app after it's been dropped on the trash. | 487 * Uninstalls the app after it's been dropped on the trash. |
| 588 */ | 488 */ |
| 589 removeFromChrome: function() { | 489 removeFromChrome: function() { |
| 590 chrome.send('uninstallApp', [this.appData_.id, true]); | 490 chrome.send('uninstallApp', [this.appData_.id, true]); |
| 591 this.tile.tilePage.removeTile(this.tile, true); | 491 this.tile.tilePage.removeTile(this.tile, true); |
| 592 if (this.currentBubbleShowing_) | |
| 593 currentBubbleShowing_.hide(); | |
| 594 }, | 492 }, |
| 595 | 493 |
| 596 /** | 494 /** |
| 597 * Called when a drag is starting on the tile. Updates dataTransfer with | 495 * Called when a drag is starting on the tile. Updates dataTransfer with |
| 598 * data for this tile. | 496 * data for this tile. |
| 599 */ | 497 */ |
| 600 setDragData: function(dataTransfer) { | 498 setDragData: function(dataTransfer) { |
| 601 dataTransfer.setData('Text', this.appData_.title); | 499 dataTransfer.setData('Text', this.appData_.title); |
| 602 dataTransfer.setData('URL', this.appData_.url); | 500 dataTransfer.setData('URL', this.appData_.url); |
| 603 }, | 501 }, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 return el; | 535 return el; |
| 638 } | 536 } |
| 639 | 537 |
| 640 AppsPage.prototype = { | 538 AppsPage.prototype = { |
| 641 __proto__: TilePage.prototype, | 539 __proto__: TilePage.prototype, |
| 642 | 540 |
| 643 initialize: function() { | 541 initialize: function() { |
| 644 this.classList.add('apps-page'); | 542 this.classList.add('apps-page'); |
| 645 | 543 |
| 646 this.addEventListener('cardselected', this.onCardSelected_); | 544 this.addEventListener('cardselected', this.onCardSelected_); |
| 647 // Add event listeners for two events, so we can temporarily suppress | |
| 648 // the app notification bubbles when the app card slides in and out of | |
| 649 // view. | |
| 650 this.addEventListener('carddeselected', this.onCardDeselected_); | |
| 651 this.addEventListener('cardSlider:card_change_ended', | |
| 652 this.onCardChangeEnded_); | |
| 653 | 545 |
| 654 this.addEventListener('tilePage:tile_added', this.onTileAdded_); | 546 this.addEventListener('tilePage:tile_added', this.onTileAdded_); |
| 655 | 547 |
| 656 this.content_.addEventListener('scroll', this.onScroll_.bind(this)); | 548 this.content_.addEventListener('scroll', this.onScroll_.bind(this)); |
| 657 }, | 549 }, |
| 658 | 550 |
| 659 /** | 551 /** |
| 660 * Highlight a newly installed app as it's added to the NTP. | 552 * Highlight a newly installed app as it's added to the NTP. |
| 661 * @param {Object} appData The data object that describes the app. | 553 * @param {Object} appData The data object that describes the app. |
| 662 */ | 554 */ |
| (...skipping 24 matching lines...) Expand all Loading... |
| 687 | 579 |
| 688 /** | 580 /** |
| 689 * Handler for 'cardselected' event, fired when |this| is selected. The | 581 * Handler for 'cardselected' event, fired when |this| is selected. The |
| 690 * first time this is called, we load all the app icons. | 582 * first time this is called, we load all the app icons. |
| 691 * @private | 583 * @private |
| 692 */ | 584 */ |
| 693 onCardSelected_: function(e) { | 585 onCardSelected_: function(e) { |
| 694 var apps = this.querySelectorAll('.app.icon-loading'); | 586 var apps = this.querySelectorAll('.app.icon-loading'); |
| 695 for (var i = 0; i < apps.length; i++) { | 587 for (var i = 0; i < apps.length; i++) { |
| 696 apps[i].loadIcon(); | 588 apps[i].loadIcon(); |
| 697 if (apps[i].currentBubbleShowing_) | |
| 698 apps[i].currentBubbleShowing_.suppressed = false; | |
| 699 } | 589 } |
| 700 }, | 590 }, |
| 701 | 591 |
| 702 /** | 592 /** |
| 703 * Handler for tile additions to this page. | 593 * Handler for tile additions to this page. |
| 704 * @param {Event} e The tilePage:tile_added event. | 594 * @param {Event} e The tilePage:tile_added event. |
| 705 */ | 595 */ |
| 706 onTileAdded_: function(e) { | 596 onTileAdded_: function(e) { |
| 707 assert(e.currentTarget == this); | 597 assert(e.currentTarget == this); |
| 708 assert(e.addedTile.firstChild instanceof App); | 598 assert(e.addedTile.firstChild instanceof App); |
| 709 if (this.classList.contains('selected-card')) | 599 if (this.classList.contains('selected-card')) |
| 710 e.addedTile.firstChild.loadIcon(); | 600 e.addedTile.firstChild.loadIcon(); |
| 711 }, | 601 }, |
| 712 | 602 |
| 713 /** | 603 /** |
| 714 * Handler for the when this.cardSlider ends change its card. If animated, | |
| 715 * this happens when the -webkit-transition is done, otherwise happens | |
| 716 * immediately (but after cardSlider:card_changed). | |
| 717 * @private | |
| 718 */ | |
| 719 onCardChangeEnded_: function(e) { | |
| 720 for (var i = 0; i < this.tileElements_.length; i++) { | |
| 721 var app = this.tileElements_[i].firstChild; | |
| 722 assert(app instanceof App); | |
| 723 if (app.currentBubbleShowing_) | |
| 724 app.currentBubbleShowing_.suppressed = false; | |
| 725 } | |
| 726 }, | |
| 727 | |
| 728 /** | |
| 729 * Handler for the 'carddeselected' event, fired when the user switches | |
| 730 * to another 'card' than the App 'card' on the NTP (|this| gets | |
| 731 * deselected). | |
| 732 * @private | |
| 733 */ | |
| 734 onCardDeselected_: function(e) { | |
| 735 for (var i = 0; i < this.tileElements_.length; i++) { | |
| 736 var app = this.tileElements_[i].firstChild; | |
| 737 assert(app instanceof App); | |
| 738 if (app.currentBubbleShowing_) | |
| 739 app.currentBubbleShowing_.suppressed = true; | |
| 740 } | |
| 741 }, | |
| 742 | |
| 743 /** | 604 /** |
| 744 * A handler for when the apps page is scrolled (then we need to reposition | 605 * A handler for when the apps page is scrolled (then we need to reposition |
| 745 * the bubbles. | 606 * the bubbles. |
| 746 * @private | 607 * @private |
| 747 */ | 608 */ |
| 748 onScroll_: function(e) { | 609 onScroll_: function(e) { |
| 749 if (!this.selected) | 610 if (!this.selected) |
| 750 return; | 611 return; |
| 751 for (var i = 0; i < this.tileElements_.length; i++) { | 612 for (var i = 0; i < this.tileElements_.length; i++) { |
| 752 var app = this.tileElements_[i].firstChild; | 613 var app = this.tileElements_[i].firstChild; |
| 753 assert(app instanceof App); | 614 assert(app instanceof App); |
| 754 if (app.currentBubbleShowing_) | |
| 755 app.currentBubbleShowing_.resizeAndReposition(); | |
| 756 } | |
| 757 }, | 615 }, |
| 758 | 616 |
| 759 /** @override */ | 617 /** @override */ |
| 760 doDragOver: function(e) { | 618 doDragOver: function(e) { |
| 761 // Only animatedly re-arrange if the user is currently dragging an app. | 619 // Only animatedly re-arrange if the user is currently dragging an app. |
| 762 var tile = ntp.getCurrentlyDraggingTile(); | 620 var tile = ntp.getCurrentlyDraggingTile(); |
| 763 if (tile && tile.querySelector('.app')) { | 621 if (tile && tile.querySelector('.app')) { |
| 764 TilePage.prototype.doDragOver.call(this, e); | 622 TilePage.prototype.doDragOver.call(this, e); |
| 765 } else { | 623 } else { |
| 766 e.preventDefault(); | 624 e.preventDefault(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 | 743 |
| 886 /** | 744 /** |
| 887 * Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE | 745 * Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE |
| 888 * histogram. This should only be invoked from the AppLauncherHandler. | 746 * histogram. This should only be invoked from the AppLauncherHandler. |
| 889 * @param {string} appID The ID of the app. | 747 * @param {string} appID The ID of the app. |
| 890 */ | 748 */ |
| 891 function launchAppAfterEnable(appId) { | 749 function launchAppAfterEnable(appId) { |
| 892 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]); | 750 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]); |
| 893 } | 751 } |
| 894 | 752 |
| 895 function appNotificationChanged(id, notification) { | |
| 896 var app = $(id); | |
| 897 // The app might have been uninstalled, or notifications might be disabled. | |
| 898 if (app && !app.appData.notifications_disabled) | |
| 899 app.setupNotification_(notification); | |
| 900 } | |
| 901 | |
| 902 return { | 753 return { |
| 903 APP_LAUNCH: APP_LAUNCH, | 754 APP_LAUNCH: APP_LAUNCH, |
| 904 appNotificationChanged: appNotificationChanged, | |
| 905 AppsPage: AppsPage, | 755 AppsPage: AppsPage, |
| 906 launchAppAfterEnable: launchAppAfterEnable, | 756 launchAppAfterEnable: launchAppAfterEnable, |
| 907 }; | 757 }; |
| 908 }); | 758 }); |
| OLD | NEW |