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 |