| 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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 * @param {Object} appData The data object that describes the app. | 238 * @param {Object} appData The data object that describes the app. |
| 239 */ | 239 */ |
| 240 initialize: function(appData) { | 240 initialize: function(appData) { |
| 241 this.appData = appData; | 241 this.appData = appData; |
| 242 assert(this.appData_.id, 'Got an app without an ID'); | 242 assert(this.appData_.id, 'Got an app without an ID'); |
| 243 this.id = this.appData_.id; | 243 this.id = this.appData_.id; |
| 244 this.setAttribute('role', 'menuitem'); | 244 this.setAttribute('role', 'menuitem'); |
| 245 | 245 |
| 246 this.className = 'app focusable'; | 246 this.className = 'app focusable'; |
| 247 | 247 |
| 248 if (!this.appData_.icon_big_exists && this.appData_.icon_small_exists) | 248 this.appContents_ = $('app-icon-template').cloneNode(true); |
| 249 this.useSmallIcon_ = true; | |
| 250 | |
| 251 this.appContents_ = this.useSmallIcon_ ? | |
| 252 $('app-small-icon-template').cloneNode(true) : | |
| 253 $('app-large-icon-template').cloneNode(true); | |
| 254 this.appContents_.id = ''; | 249 this.appContents_.id = ''; |
| 255 this.appendChild(this.appContents_); | 250 this.appendChild(this.appContents_); |
| 256 | 251 |
| 257 this.appImgContainer_ = /** @type {HTMLElement} */( | 252 this.appImgContainer_ = /** @type {HTMLElement} */( |
| 258 this.querySelector('.app-img-container')); | 253 this.querySelector('.app-img-container')); |
| 259 this.appImg_ = this.appImgContainer_.querySelector('img'); | 254 this.appImg_ = this.appImgContainer_.querySelector('img'); |
| 260 this.setIcon(); | 255 this.setIcon(); |
| 261 | 256 |
| 262 if (this.useSmallIcon_) { | 257 this.addLaunchClickTarget_(this.appImgContainer_); |
| 263 this.imgDiv_ = /** @type {HTMLElement} */( | 258 this.appImgContainer_.title = this.appData_.full_name; |
| 264 this.querySelector('.app-icon-div')); | |
| 265 this.addLaunchClickTarget_(this.imgDiv_); | |
| 266 this.imgDiv_.title = this.appData_.full_name; | |
| 267 chrome.send('getAppIconDominantColor', [this.id]); | |
| 268 } else { | |
| 269 this.addLaunchClickTarget_(this.appImgContainer_); | |
| 270 this.appImgContainer_.title = this.appData_.full_name; | |
| 271 } | |
| 272 | 259 |
| 273 // The app's full name is shown in the tooltip, whereas the short name | 260 // The app's full name is shown in the tooltip, whereas the short name |
| 274 // is used for the label. | 261 // is used for the label. |
| 275 var appSpan = /** @type {HTMLElement} */( | 262 var appSpan = /** @type {HTMLElement} */( |
| 276 this.appContents_.querySelector('.title')); | 263 this.appContents_.querySelector('.title')); |
| 277 appSpan.textContent = this.appData_.title; | 264 appSpan.textContent = this.appData_.title; |
| 278 appSpan.title = this.appData_.full_name; | 265 appSpan.title = this.appData_.full_name; |
| 279 this.addLaunchClickTarget_(appSpan); | 266 this.addLaunchClickTarget_(appSpan); |
| 280 | 267 |
| 281 this.addEventListener('keydown', cr.ui.contextMenuHandler); | 268 this.addEventListener('keydown', cr.ui.contextMenuHandler); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 292 this.appContents_.addEventListener('contextmenu', | 279 this.appContents_.addEventListener('contextmenu', |
| 293 cr.ui.contextMenuHandler); | 280 cr.ui.contextMenuHandler); |
| 294 } | 281 } |
| 295 | 282 |
| 296 this.addEventListener('mousedown', this.onMousedown_, true); | 283 this.addEventListener('mousedown', this.onMousedown_, true); |
| 297 this.addEventListener('keydown', this.onKeydown_); | 284 this.addEventListener('keydown', this.onKeydown_); |
| 298 this.addEventListener('blur', this.onBlur_); | 285 this.addEventListener('blur', this.onBlur_); |
| 299 }, | 286 }, |
| 300 | 287 |
| 301 /** | 288 /** |
| 302 * Sets the color of the favicon dominant color bar. | |
| 303 * @param {string} color The css-parsable value for the color. | |
| 304 */ | |
| 305 set stripeColor(color) { | |
| 306 this.querySelector('.color-stripe').style.backgroundColor = color; | |
| 307 }, | |
| 308 | |
| 309 /** | |
| 310 * Removes the app tile from the page. Should be called after the app has | 289 * Removes the app tile from the page. Should be called after the app has |
| 311 * been uninstalled. | 290 * been uninstalled. |
| 312 * | 291 * |
| 313 * TODO(dbeam): this method now conflicts with HTMLElement#remove(), which | 292 * TODO(dbeam): this method now conflicts with HTMLElement#remove(), which |
| 314 * is why the param is optional. Rename. | 293 * is why the param is optional. Rename. |
| 315 * | 294 * |
| 316 * @param {boolean=} opt_animate Whether the removal should be animated. | 295 * @param {boolean=} opt_animate Whether the removal should be animated. |
| 317 */ | 296 */ |
| 318 remove: function(opt_animate) { | 297 remove: function(opt_animate) { |
| 319 // Unset the ID immediately, because the app is already gone. But leave | 298 // Unset the ID immediately, because the app is already gone. But leave |
| 320 // the tile on the page as it animates out. | 299 // the tile on the page as it animates out. |
| 321 this.id = ''; | 300 this.id = ''; |
| 322 this.tile.doRemove(opt_animate); | 301 this.tile.doRemove(opt_animate); |
| 323 }, | 302 }, |
| 324 | 303 |
| 325 /** | 304 /** |
| 326 * Set the URL of the icon from |appData_|. This won't actually show the | 305 * Set the URL of the icon from |appData_|. This won't actually show the |
| 327 * icon until loadIcon() is called (for performance reasons; we don't want | 306 * icon until loadIcon() is called (for performance reasons; we don't want |
| 328 * to load icons until we have to). | 307 * to load icons until we have to). |
| 329 */ | 308 */ |
| 330 setIcon: function() { | 309 setIcon: function() { |
| 331 var src = this.useSmallIcon_ ? this.appData_.icon_small : | 310 var src = this.appData_.icon; |
| 332 this.appData_.icon_big; | |
| 333 if (!this.appData_.enabled || | 311 if (!this.appData_.enabled || |
| 334 (!this.appData_.offlineEnabled && !navigator.onLine)) { | 312 (!this.appData_.offlineEnabled && !navigator.onLine)) { |
| 335 src += '?grayscale=true'; | 313 src += '?grayscale=true'; |
| 336 } | 314 } |
| 337 | 315 |
| 338 this.appImgSrc_ = src; | 316 this.appImgSrc_ = src; |
| 339 this.classList.add('icon-loading'); | 317 this.classList.add('icon-loading'); |
| 340 }, | 318 }, |
| 341 | 319 |
| 342 /** | 320 /** |
| (...skipping 13 matching lines...) Expand all Loading... |
| 356 /** | 334 /** |
| 357 * Set the size and position of the app tile. | 335 * Set the size and position of the app tile. |
| 358 * @param {number} size The total size of |this|. | 336 * @param {number} size The total size of |this|. |
| 359 * @param {number} x The x-position. | 337 * @param {number} x The x-position. |
| 360 * @param {number} y The y-position. | 338 * @param {number} y The y-position. |
| 361 * animate. | 339 * animate. |
| 362 */ | 340 */ |
| 363 setBounds: function(size, x, y) { | 341 setBounds: function(size, x, y) { |
| 364 var imgSize = size * APP_IMG_SIZE_FRACTION; | 342 var imgSize = size * APP_IMG_SIZE_FRACTION; |
| 365 this.appImgContainer_.style.width = this.appImgContainer_.style.height = | 343 this.appImgContainer_.style.width = this.appImgContainer_.style.height = |
| 366 toCssPx(this.useSmallIcon_ ? 16 : imgSize); | 344 toCssPx(imgSize); |
| 367 if (this.useSmallIcon_) { | |
| 368 // 3/4 is the ratio of 96px to 128px (the used height and full height | |
| 369 // of icons in apps). | |
| 370 var iconSize = imgSize * 3 / 4; | |
| 371 // The -2 is for the div border to improve the visual alignment for the | |
| 372 // icon div. | |
| 373 this.imgDiv_.style.width = this.imgDiv_.style.height = | |
| 374 toCssPx(iconSize - 2); | |
| 375 // Margins set to get the icon placement right and the text to line up. | |
| 376 this.imgDiv_.style.marginTop = this.imgDiv_.style.marginBottom = | |
| 377 toCssPx((imgSize - iconSize) / 2); | |
| 378 } | |
| 379 | |
| 380 this.style.width = this.style.height = toCssPx(size); | 345 this.style.width = this.style.height = toCssPx(size); |
| 381 this.style.left = toCssPx(x); | 346 this.style.left = toCssPx(x); |
| 382 this.style.right = toCssPx(x); | 347 this.style.right = toCssPx(x); |
| 383 this.style.top = toCssPx(y); | 348 this.style.top = toCssPx(y); |
| 384 }, | 349 }, |
| 385 | 350 |
| 386 onBlur_: function(e) { | 351 onBlur_: function(e) { |
| 387 this.classList.remove('click-focus'); | 352 this.classList.remove('click-focus'); |
| 388 this.appContents_.classList.remove('suppress-active'); | 353 this.appContents_.classList.remove('suppress-active'); |
| 389 }, | 354 }, |
| 390 | 355 |
| 391 /** | 356 /** |
| 392 * Invoked when an app is clicked. | 357 * Invoked when an app is clicked. |
| 393 * @param {Event} e The click/auxclick event. | 358 * @param {Event} e The click/auxclick event. |
| 394 * @private | 359 * @private |
| 395 */ | 360 */ |
| 396 onClick_: function(e) { | 361 onClick_: function(e) { |
| 397 if (/** @type {MouseEvent} */(e).button > 1) return; | 362 if (/** @type {MouseEvent} */(e).button > 1) |
| 363 return; |
| 398 | 364 |
| 399 chrome.send('launchApp', | 365 chrome.send('launchApp', |
| 400 [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED, 'chrome-ntp-icon', | 366 [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED, 'chrome-ntp-icon', |
| 401 e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]); | 367 e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]); |
| 402 | 368 |
| 403 // Don't allow the click to trigger a link or anything | 369 // Don't allow the click to trigger a link or anything |
| 404 e.preventDefault(); | 370 e.preventDefault(); |
| 405 }, | 371 }, |
| 406 | 372 |
| 407 /** | 373 /** |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 replaceAppData: function(appData) { | 432 replaceAppData: function(appData) { |
| 467 this.appData_ = appData; | 433 this.appData_ = appData; |
| 468 this.setIcon(); | 434 this.setIcon(); |
| 469 this.loadIcon(); | 435 this.loadIcon(); |
| 470 }, | 436 }, |
| 471 | 437 |
| 472 /** | 438 /** |
| 473 * The data and preferences for this app. | 439 * The data and preferences for this app. |
| 474 * @type {Object} | 440 * @type {Object} |
| 475 */ | 441 */ |
| 476 set appData(data) { | 442 set appData(data) { this.appData_ = data; }, |
| 477 this.appData_ = data; | 443 get appData() { return this.appData_; }, |
| 478 }, | |
| 479 get appData() { | |
| 480 return this.appData_; | |
| 481 }, | |
| 482 | 444 |
| 483 get appId() { | 445 get appId() { return this.appData_.id; }, |
| 484 return this.appData_.id; | |
| 485 }, | |
| 486 | 446 |
| 487 /** | 447 /** |
| 488 * Returns a pointer to the context menu for this app. All apps share the | 448 * Returns a pointer to the context menu for this app. All apps share the |
| 489 * singleton AppContextMenu. This function is called by the | 449 * singleton AppContextMenu. This function is called by the |
| 490 * ContextMenuHandler in response to the 'contextmenu' event. | 450 * ContextMenuHandler in response to the 'contextmenu' event. |
| 491 * @type {cr.ui.Menu} | 451 * @type {cr.ui.Menu} |
| 492 */ | 452 */ |
| 493 get contextMenu() { | 453 get contextMenu() { |
| 494 var menu = AppContextMenu.getInstance(); | 454 var menu = AppContextMenu.getInstance(); |
| 495 menu.setupForApp(this); | 455 menu.setupForApp(this); |
| 496 return menu.menu; | 456 return menu.menu; |
| 497 }, | 457 }, |
| 498 | 458 |
| 499 /** | 459 /** |
| 500 * Returns whether this element can be 'removed' from chrome (i.e. whether | 460 * Returns whether this element can be 'removed' from chrome (i.e. whether |
| 501 * the user can drag it onto the trash and expect something to happen). | 461 * the user can drag it onto the trash and expect something to happen). |
| 502 * @return {boolean} True if the app can be uninstalled. | 462 * @return {boolean} True if the app can be uninstalled. |
| 503 */ | 463 */ |
| 504 canBeRemoved: function() { | 464 canBeRemoved: function() { return this.appData_.mayDisable; }, |
| 505 return this.appData_.mayDisable; | |
| 506 }, | |
| 507 | 465 |
| 508 /** | 466 /** |
| 509 * Uninstalls the app after it's been dropped on the trash. | 467 * Uninstalls the app after it's been dropped on the trash. |
| 510 */ | 468 */ |
| 511 removeFromChrome: function() { | 469 removeFromChrome: function() { |
| 512 chrome.send('uninstallApp', [this.appData_.id, true]); | 470 chrome.send('uninstallApp', [this.appData_.id, true]); |
| 513 this.tile.tilePage.removeTile(this.tile, true); | 471 this.tile.tilePage.removeTile(this.tile, true); |
| 514 }, | 472 }, |
| 515 | 473 |
| 516 /** | 474 /** |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]); | 727 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]); |
| 770 } | 728 } |
| 771 | 729 |
| 772 return { | 730 return { |
| 773 APP_LAUNCH: APP_LAUNCH, | 731 APP_LAUNCH: APP_LAUNCH, |
| 774 App: App, | 732 App: App, |
| 775 AppsPage: AppsPage, | 733 AppsPage: AppsPage, |
| 776 launchAppAfterEnable: launchAppAfterEnable, | 734 launchAppAfterEnable: launchAppAfterEnable, |
| 777 }; | 735 }; |
| 778 }); | 736 }); |
| OLD | NEW |