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 Thumbnail = ntp.Thumbnail; | |
9 var ThumbnailPage = ntp.ThumbnailPage; | |
10 | |
11 /** | |
12 * Creates a new Most Visited object for tiling. | |
13 * @param {Object=} opt_data The data representing the most visited page. | |
14 * @constructor | |
15 * @extends {Thumbnail} | |
16 * @extends {HTMLAnchorElement} | |
17 */ | |
18 function MostVisited(opt_data) { | |
19 var el = cr.doc.createElement('a'); | |
20 el.__proto__ = MostVisited.prototype; | |
21 el.initialize(); | |
22 | |
23 if (opt_data) | |
24 el.data = opt_data; | |
25 | |
26 return el; | |
27 } | |
28 | |
29 MostVisited.prototype = { | |
30 __proto__: Thumbnail.prototype, | |
31 | |
32 /** | |
33 * Initializes a MostVisited Thumbnail. | |
34 */ | |
35 initialize: function() { | |
36 Thumbnail.prototype.initialize.apply(this, arguments); | |
37 | |
38 this.addEventListener('click', this.handleClick_); | |
39 this.addEventListener('keydown', this.handleKeyDown_); | |
40 this.addEventListener('carddeselected', this.handleCardDeselected_); | |
41 this.addEventListener('cardselected', this.handleCardSelected_); | |
42 }, | |
43 | |
44 /** | |
45 * Clears the DOM hierarchy for this node, setting it back to the default | |
46 * for a blank thumbnail. | |
47 */ | |
48 reset: function() { | |
49 Thumbnail.prototype.reset.apply(this, arguments); | |
50 | |
51 var closeButton = cr.doc.createElement('div'); | |
52 closeButton.className = 'close-button'; | |
53 closeButton.title = loadTimeData.getString('removethumbnailtooltip'); | |
54 this.appendChild(closeButton); | |
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(Thumbnail.prototype, 'data').set.apply( | |
63 this, arguments); | |
64 | |
65 if (this.classList.contains('blacklisted') && data) { | |
66 // Animate appearance of new tile. | |
67 this.classList.add('new-tile-contents'); | |
68 } | |
69 this.classList.remove('blacklisted'); | |
70 }, | |
71 get data() { | |
72 return this.data_; | |
73 }, | |
74 | |
75 /** | |
76 * Handles a click on the tile. | |
77 * @param {Event} e The click event. | |
78 * @private | |
79 */ | |
80 handleClick_: function(e) { | |
81 if (e.target.classList.contains('close-button')) { | |
82 this.blacklist_(); | |
83 e.preventDefault(); | |
84 } else { | |
85 ntp.logTimeToClickAndHoverCount('MostVisited'); | |
86 // Records an app launch from the most visited page (Chrome will decide | |
87 // whether the url is an app). TODO(estade): this only works for clicks; | |
88 // other actions like "open in new tab" from the context menu won't be | |
89 // recorded. Can this be fixed? | |
90 chrome.send('recordAppLaunchByURL', | |
91 [encodeURIComponent(this.href), | |
92 ntp.APP_LAUNCH.NTP_MOST_VISITED]); | |
93 // Records the index of this tile. | |
94 chrome.send('metricsHandler:recordInHistogram', | |
95 ['NewTabPage.MostVisited', this.index, 8]); | |
96 chrome.send('mostVisitedAction', | |
97 [ntp.NtpFollowAction.CLICKED_TILE]); | |
98 } | |
99 }, | |
100 | |
101 /** | |
102 * Allow blacklisting most visited site using the keyboard. | |
103 * @private | |
104 */ | |
105 handleKeyDown_: function(e) { | |
106 if (!cr.isMac && e.keyCode == 46 || // Del | |
107 cr.isMac && e.metaKey && e.keyCode == 8) { // Cmd + Backspace | |
108 this.blacklist_(); | |
109 } | |
110 }, | |
111 | |
112 /** | |
113 * Permanently removes a page from Most Visited. | |
114 * @private | |
115 */ | |
116 blacklist_: function() { | |
117 this.tileCell.tilePage.setTileRepositioningState(this.index, true); | |
118 this.showUndoNotification_(); | |
119 chrome.send('blacklistURLFromMostVisited', [this.data_.url]); | |
120 this.classList.add('blacklisted'); | |
121 }, | |
122 | |
123 /** | |
124 * Shows the undo notification when blacklisting a most visited site. | |
125 * @private | |
126 */ | |
127 showUndoNotification_: function() { | |
128 var data = this.data_; | |
129 var tilePage = this.tileCell.tilePage; | |
130 var index = this.index; | |
131 var doUndo = function() { | |
132 tilePage.setTileRepositioningState(index, false); | |
133 chrome.send('removeURLsFromMostVisitedBlacklist', [data.url]); | |
134 }; | |
135 | |
136 var undo = { | |
137 action: doUndo, | |
138 text: loadTimeData.getString('undothumbnailremove'), | |
139 }; | |
140 | |
141 var undoAll = { | |
142 action: function() { | |
143 chrome.send('clearMostVisitedURLsBlacklist'); | |
144 }, | |
145 text: loadTimeData.getString('restoreThumbnailsShort'), | |
146 }; | |
147 | |
148 ntp.showNotification( | |
149 loadTimeData.getString('thumbnailremovednotification'), | |
150 [undo, undoAll]); | |
151 }, | |
152 | |
153 /** | |
154 * Returns whether this element can be 'removed' from chrome. | |
155 * @return {boolean} True, since most visited pages can always be | |
156 * blacklisted. | |
157 */ | |
158 canBeRemoved: function() { | |
159 return true; | |
160 }, | |
161 }; | |
162 | |
163 /** | |
164 * Creates a new MostVisitedPage object. | |
165 * @constructor | |
166 * @extends {ThumbnailPage} | |
167 */ | |
168 function MostVisitedPage() { | |
169 var el = new ThumbnailPage(); | |
170 el.__proto__ = MostVisitedPage.prototype; | |
171 el.initialize(); | |
172 | |
173 return el; | |
174 } | |
175 | |
176 MostVisitedPage.prototype = { | |
177 __proto__: ThumbnailPage.prototype, | |
178 | |
179 TileClass: MostVisited, | |
180 | |
181 /** | |
182 * Initializes a MostVisitedPage. | |
183 */ | |
184 initialize: function() { | |
185 ThumbnailPage.prototype.initialize.apply(this, arguments); | |
186 | |
187 this.classList.add('most-visited-page'); | |
188 }, | |
189 | |
190 /** | |
191 * Handles the 'card deselected' event (i.e. the user clicked to another | |
192 * pane). | |
193 * @private | |
194 * @param {Event} e The CardChanged event. | |
195 */ | |
196 handleCardDeselected_: function(e) { | |
197 if (!document.documentElement.classList.contains('starting-up')) { | |
198 chrome.send('mostVisitedAction', | |
199 [ntp.NtpFollowAction.CLICKED_OTHER_NTP_PANE]); | |
200 } | |
201 }, | |
202 | |
203 /** | |
204 * Handles the 'card selected' event (i.e. the user clicked to select the | |
205 * this page's pane). | |
206 * @private | |
207 * @param {Event} e The CardChanged event. | |
208 */ | |
209 handleCardSelected_: function(e) { | |
210 if (!document.documentElement.classList.contains('starting-up')) | |
211 chrome.send('mostVisitedSelected'); | |
212 }, | |
213 | |
214 /** @override */ | |
215 setDataList: function(dataList) { | |
216 var startTime = Date.now(); | |
217 ThumbnailPage.prototype.setDataList.apply(this, arguments); | |
218 this.updateGrid(); | |
219 logEvent('mostVisited.layout: ' + (Date.now() - startTime)); | |
220 }, | |
221 }; | |
222 | |
223 /** | |
224 * Executed once the NTP has loaded. Checks if the Most Visited pane is | |
225 * shown or not. If it is shown, the 'mostVisitedSelected' message is sent | |
226 * to the C++ code, to record the fact that the user has seen this pane. | |
227 */ | |
228 MostVisitedPage.onLoaded = function() { | |
229 if (ntp.getCardSlider() && | |
230 ntp.getCardSlider().currentCardValue && | |
231 ntp.getCardSlider().currentCardValue.classList | |
232 .contains('most-visited-page')) { | |
233 chrome.send('mostVisitedSelected'); | |
234 } | |
235 }; | |
236 | |
237 return { | |
238 MostVisitedPage: MostVisitedPage, | |
239 }; | |
240 }); | |
241 | |
242 document.addEventListener('ntpLoaded', ntp.MostVisitedPage.onLoaded); | |
OLD | NEW |