OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 cr.define('ntp', function() { | |
6 'use strict'; | |
7 | |
8 var Tile = ntp.Tile; | |
9 var TilePage = ntp.TilePage; | |
10 | |
11 /** | |
12 * Creates a new Thumbnail object for tiling. | |
13 * @param {Object=} opt_data The data representing the thumbnail. | |
14 * @constructor | |
15 * @extends {Tile} | |
16 * @extends {HTMLAnchorElement} | |
17 */ | |
18 function Thumbnail(opt_data) { | |
19 var el = cr.doc.createElement('a'); | |
20 el.__proto__ = Thumbnail.prototype; | |
21 el.initialize(); | |
22 | |
23 if (opt_data) | |
24 el.data = opt_data; | |
25 | |
26 return el; | |
27 } | |
28 | |
29 Thumbnail.prototype = Tile.subclass({ | |
30 __proto__: HTMLAnchorElement.prototype, | |
31 | |
32 /** | |
33 * Initializes a Thumbnail. | |
34 */ | |
35 initialize: function() { | |
36 Tile.prototype.initialize.apply(this, arguments); | |
37 this.classList.add('thumbnail'); | |
38 this.addEventListener('mouseover', this.handleMouseOver_); | |
39 }, | |
40 | |
41 /** | |
42 * Clears the DOM hierarchy for this node, setting it back to the default | |
43 * for a blank thumbnail. | |
44 */ | |
45 reset: function() { | |
46 this.innerHTML = | |
47 '<span class="thumbnail-wrapper">' + | |
48 '<span class="thumbnail-image thumbnail-card"></span>' + | |
49 '</span>' + | |
50 '<span class="title"></span>'; | |
51 | |
52 this.tabIndex = -1; | |
53 this.data_ = null; | |
54 this.title = ''; | |
55 }, | |
56 | |
57 /** | |
58 * Update the appearance of this tile according to |data|. | |
59 * @param {Object} data A dictionary of relevant data for the page. | |
60 */ | |
61 set data(data) { | |
62 Object.getOwnPropertyDescriptor(Tile.prototype, 'data').set.apply(this, | |
63 arguments); | |
64 | |
65 this.formatThumbnail_(data); | |
66 }, | |
67 | |
68 /** | |
69 * Formats this tile according to |data|. | |
70 * @param {Object} data A dictionary of relevant data for the page. | |
71 * @private | |
72 */ | |
73 formatThumbnail_: function(data) { | |
74 var title = this.querySelector('.title'); | |
75 title.textContent = data.title; | |
76 title.dir = data.direction; | |
77 | |
78 // Sets the tooltip. | |
79 this.title = data.title; | |
80 | |
81 var dataUrl = data.url; | |
82 // Allow an empty string href (e.g. for a multiple tab thumbnail). | |
83 this.href = typeof data.href != 'undefined' ? data.href : dataUrl; | |
84 | |
85 var thumbnailImage = this.querySelector('.thumbnail-image'); | |
86 | |
87 var banner = thumbnailImage.querySelector('.thumbnail-banner'); | |
88 if (banner) | |
89 thumbnailImage.removeChild(banner); | |
90 | |
91 var favicon = this.querySelector('.thumbnail-favicon') || | |
92 this.ownerDocument.createElement('div'); | |
93 favicon.className = 'thumbnail-favicon'; | |
94 favicon.style.backgroundImage = getFaviconImageSet(dataUrl); | |
95 this.appendChild(favicon); | |
96 | |
97 var self = this; | |
98 var image = new Image(); | |
99 | |
100 // If the thumbnail image fails to load, show an alternative presentation. | |
101 // TODO(jeremycho): Move to a separate function? | |
102 image.onerror = function() { | |
103 banner = thumbnailImage.querySelector('.thumbnail-banner') || | |
104 self.ownerDocument.createElement('div'); | |
105 banner.className = 'thumbnail-banner'; | |
106 | |
107 // For now, just strip leading http://www and trailing backslash. | |
108 // TODO(jeremycho): Consult with UX on URL truncation. | |
109 banner.textContent = dataUrl.replace(/^(http:\/\/)?(www\.)?|\/$/gi, ''); | |
110 thumbnailImage.appendChild(banner); | |
111 }; | |
112 | |
113 var thumbnailUrl = ntp.getThumbnailUrl(dataUrl); | |
114 thumbnailImage.style.backgroundImage = url(thumbnailUrl); | |
115 image.src = thumbnailUrl; | |
116 }, | |
117 | |
118 /** | |
119 * Returns true if this is a thumbnail or descendant thereof. Used to | |
120 * detect when the mouse has transitioned into this thumbnail from a | |
121 * strictly non-thumbnail element. | |
122 * @param {Object} element The element to test. | |
123 * @return {boolean} True if this is a thumbnail or a descendant thereof. | |
124 * @private | |
125 */ | |
126 isInThumbnail_: function(element) { | |
127 while (element) { | |
128 if (element == this) | |
129 return true; | |
130 element = element.parentNode; | |
131 } | |
132 return false; | |
133 }, | |
134 | |
135 /** | |
136 * Increment the hover count whenever the mouse enters a thumbnail. | |
137 * @param {Event} e The mouse over event. | |
138 * @private | |
139 */ | |
140 handleMouseOver_: function(e) { | |
141 if (this.isInThumbnail_(e.target) && | |
142 !this.isInThumbnail_(e.relatedTarget)) { | |
143 ntp.incrementHoveredThumbnailCount(); | |
144 } | |
145 }, | |
146 }); | |
147 | |
148 /** | |
149 * Creates a new ThumbnailPage object. | |
150 * @constructor | |
151 * @extends {TilePage} | |
152 */ | |
153 function ThumbnailPage() { | |
154 var el = new TilePage(); | |
155 el.__proto__ = ThumbnailPage.prototype; | |
156 | |
157 return el; | |
158 } | |
159 | |
160 ThumbnailPage.prototype = { | |
161 __proto__: TilePage.prototype, | |
162 | |
163 /** | |
164 * Initializes a ThumbnailPage. | |
165 */ | |
166 initialize: function() { | |
167 TilePage.prototype.initialize.apply(this, arguments); | |
168 | |
169 this.classList.add('thumbnail-page'); | |
170 }, | |
171 | |
172 /** @override */ | |
173 shouldAcceptDrag: function(e) { | |
174 return false; | |
175 }, | |
176 }; | |
177 | |
178 return { | |
179 Thumbnail: Thumbnail, | |
180 ThumbnailPage: ThumbnailPage, | |
181 }; | |
182 }); | |
OLD | NEW |