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 <include src="../uber/uber_utils.js"> | 5 <include src="../uber/uber_utils.js"> |
6 <include src="history_focus_manager.js"> | 6 <include src="history_focus_manager.js"> |
7 | 7 |
8 /////////////////////////////////////////////////////////////////////////////// | 8 /////////////////////////////////////////////////////////////////////////////// |
9 // Globals: | 9 // Globals: |
10 /** @const */ var RESULTS_PER_PAGE = 150; | 10 /** @const */ var RESULTS_PER_PAGE = 150; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 * visit before it. | 85 * visit before it. |
86 * @param {HistoryModel} model The model object this entry belongs to. | 86 * @param {HistoryModel} model The model object this entry belongs to. |
87 * @constructor | 87 * @constructor |
88 */ | 88 */ |
89 function Visit(result, continued, model) { | 89 function Visit(result, continued, model) { |
90 this.model_ = model; | 90 this.model_ = model; |
91 this.title_ = result.title; | 91 this.title_ = result.title; |
92 this.url_ = result.url; | 92 this.url_ = result.url; |
93 this.domain_ = result.domain; | 93 this.domain_ = result.domain; |
94 this.starred_ = result.starred; | 94 this.starred_ = result.starred; |
| 95 this.fallbackFaviconText_ = result.fallbackFaviconText; |
95 | 96 |
96 // These identify the name and type of the device on which this visit | 97 // These identify the name and type of the device on which this visit |
97 // occurred. They will be empty if the visit occurred on the current device. | 98 // occurred. They will be empty if the visit occurred on the current device. |
98 this.deviceName = result.deviceName; | 99 this.deviceName = result.deviceName; |
99 this.deviceType = result.deviceType; | 100 this.deviceType = result.deviceType; |
100 | 101 |
101 // The ID will be set according to when the visit was displayed, not | 102 // The ID will be set according to when the visit was displayed, not |
102 // received. Set to -1 to show that it has not been set yet. | 103 // received. Set to -1 to show that it has not been set yet. |
103 this.id_ = -1; | 104 this.id_ = -1; |
104 | 105 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 bookmarkSection.removeEventListener('click', f); | 213 bookmarkSection.removeEventListener('click', f); |
213 e.preventDefault(); | 214 e.preventDefault(); |
214 }.bind(this)); | 215 }.bind(this)); |
215 } | 216 } |
216 | 217 |
217 if (focusless) | 218 if (focusless) |
218 bookmarkSection.tabIndex = -1; | 219 bookmarkSection.tabIndex = -1; |
219 | 220 |
220 entryBox.appendChild(bookmarkSection); | 221 entryBox.appendChild(bookmarkSection); |
221 | 222 |
| 223 if (addTitleFavicon || this.blockedVisit) { |
| 224 var faviconSection = createElementWithClassName('div', 'favicon'); |
| 225 if (this.blockedVisit) |
| 226 faviconSection.classList.add('blocked-icon'); |
| 227 else |
| 228 this.loadFavicon_(faviconSection); |
| 229 entryBox.appendChild(faviconSection); |
| 230 } |
| 231 |
222 var visitEntryWrapper = /** @type {HTMLElement} */( | 232 var visitEntryWrapper = /** @type {HTMLElement} */( |
223 entryBox.appendChild(document.createElement('div'))); | 233 entryBox.appendChild(document.createElement('div'))); |
224 if (addTitleFavicon || this.blockedVisit) | 234 if (addTitleFavicon || this.blockedVisit) |
225 visitEntryWrapper.classList.add('visit-entry'); | 235 visitEntryWrapper.classList.add('visit-entry'); |
226 if (this.blockedVisit) { | 236 if (this.blockedVisit) { |
227 visitEntryWrapper.classList.add('blocked-indicator'); | 237 visitEntryWrapper.classList.add('blocked-indicator'); |
228 visitEntryWrapper.appendChild(this.getVisitAttemptDOM_()); | 238 visitEntryWrapper.appendChild(this.getVisitAttemptDOM_()); |
229 } else { | 239 } else { |
230 var title = visitEntryWrapper.appendChild( | 240 var title = visitEntryWrapper.appendChild( |
231 this.getTitleDOM_(isSearchResult)); | 241 this.getTitleDOM_(isSearchResult)); |
232 | 242 |
233 if (addTitleFavicon) | |
234 this.addFaviconToElement_(visitEntryWrapper); | |
235 | |
236 if (focusless) | 243 if (focusless) |
237 title.querySelector('a').tabIndex = -1; | 244 title.querySelector('a').tabIndex = -1; |
238 | 245 |
239 visitEntryWrapper.appendChild(domain); | 246 visitEntryWrapper.appendChild(domain); |
240 } | 247 } |
241 | 248 |
242 if (isMobileVersion()) { | 249 if (isMobileVersion()) { |
243 if (this.model_.editingEntriesAllowed) { | 250 if (this.model_.editingEntriesAllowed) { |
244 var removeButton = createElementWithClassName('button', 'remove-entry'); | 251 var removeButton = createElementWithClassName('button', 'remove-entry'); |
245 removeButton.setAttribute('aria-label', | 252 removeButton.setAttribute('aria-label', |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 Visit.prototype.getVisitAttemptDOM_ = function() { | 440 Visit.prototype.getVisitAttemptDOM_ = function() { |
434 var node = createElementWithClassName('div', 'title'); | 441 var node = createElementWithClassName('div', 'title'); |
435 node.innerHTML = loadTimeData.getStringF('blockedVisitText', | 442 node.innerHTML = loadTimeData.getStringF('blockedVisitText', |
436 this.url_, | 443 this.url_, |
437 this.id_, | 444 this.id_, |
438 this.domain_); | 445 this.domain_); |
439 return node; | 446 return node; |
440 }; | 447 }; |
441 | 448 |
442 /** | 449 /** |
443 * Set the favicon for an element. | 450 * Load the favicon for an element. |
444 * @param {Element} el The DOM element to which to add the icon. | 451 * @param {Element} faviconDiv The DOM element for which to load the icon. |
445 * @private | 452 * @private |
446 */ | 453 */ |
447 Visit.prototype.addFaviconToElement_ = function(el) { | 454 Visit.prototype.loadFavicon_ = function(faviconDiv) { |
448 var url = isMobileVersion() ? | 455 if (cr.isAndroid) { |
449 getFaviconImageSet(this.url_, 32, 'touch-icon') : | 456 // On Android, if a large icon is unavailable, an HTML/CSS fallback favicon |
450 getFaviconImageSet(this.url_); | 457 // is generated because Android does not yet support text drawing in native. |
451 el.style.backgroundImage = url; | 458 |
| 459 // Check whether a fallback favicon needs to be generated. |
| 460 var desiredPixelSize = 32 * window.devicePixelRatio; |
| 461 var img = new Image(); |
| 462 img.onload = this.onLargeFaviconLoadedAndroid_.bind(this, faviconDiv); |
| 463 img.src = 'chrome://large-icon/' + desiredPixelSize + '/' + this.url_; |
| 464 } else { |
| 465 faviconDiv.style.backgroundImage = getFaviconImageSet(this.url_); |
| 466 } |
452 }; | 467 }; |
453 | 468 |
454 /** | 469 /** |
| 470 * Called when the chrome://large-icon image has finished loading. |
| 471 * @param {Element} faviconDiv The DOM element to add the favicon to. |
| 472 * @param {Event} event The onload event. |
| 473 * @private |
| 474 */ |
| 475 Visit.prototype.onLargeFaviconLoadedAndroid_ = function(faviconDiv, event) { |
| 476 // The loaded image should either: |
| 477 // - Have the desired size. |
| 478 // OR |
| 479 // - Be 1x1 px with the background color for the fallback icon. |
| 480 var loadedImg = event.target; |
| 481 if (loadedImg.width == 1) { |
| 482 faviconDiv.classList.add('fallback-favicon'); |
| 483 faviconDiv.textContent = this.fallbackFaviconText_; |
| 484 } |
| 485 faviconDiv.style.backgroundImage = url(loadedImg.src); |
| 486 }; |
| 487 |
| 488 /** |
455 * Launch a search for more history entries from the same domain. | 489 * Launch a search for more history entries from the same domain. |
456 * @private | 490 * @private |
457 */ | 491 */ |
458 Visit.prototype.showMoreFromSite_ = function() { | 492 Visit.prototype.showMoreFromSite_ = function() { |
459 recordUmaAction('HistoryPage_EntryMenuShowMoreFromSite'); | 493 recordUmaAction('HistoryPage_EntryMenuShowMoreFromSite'); |
460 historyView.setSearch(this.domain_); | 494 historyView.setSearch(this.domain_); |
461 $('search-field').focus(); | 495 $('search-field').focus(); |
462 }; | 496 }; |
463 | 497 |
464 /** | 498 /** |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 | 1368 |
1335 siteDomainCheckbox.type = 'checkbox'; | 1369 siteDomainCheckbox.type = 'checkbox'; |
1336 siteDomainCheckbox.addEventListener('click', domainCheckboxClicked); | 1370 siteDomainCheckbox.addEventListener('click', domainCheckboxClicked); |
1337 siteDomainCheckbox.domain_ = domain; | 1371 siteDomainCheckbox.domain_ = domain; |
1338 siteDomainCheckbox.setAttribute('aria-label', domain); | 1372 siteDomainCheckbox.setAttribute('aria-label', domain); |
1339 siteDomainRow.appendChild(siteDomainCheckbox); | 1373 siteDomainRow.appendChild(siteDomainCheckbox); |
1340 } | 1374 } |
1341 | 1375 |
1342 var siteArrow = siteDomainRow.appendChild( | 1376 var siteArrow = siteDomainRow.appendChild( |
1343 createElementWithClassName('div', 'site-domain-arrow')); | 1377 createElementWithClassName('div', 'site-domain-arrow')); |
| 1378 var siteFavicon = siteDomainRow.appendChild( |
| 1379 createElementWithClassName('div', 'favicon')); |
1344 var siteDomain = siteDomainRow.appendChild( | 1380 var siteDomain = siteDomainRow.appendChild( |
1345 createElementWithClassName('div', 'site-domain')); | 1381 createElementWithClassName('div', 'site-domain')); |
1346 var siteDomainLink = siteDomain.appendChild(new ActionLink); | 1382 var siteDomainLink = siteDomain.appendChild(new ActionLink); |
1347 siteDomainLink.textContent = domain; | 1383 siteDomainLink.textContent = domain; |
1348 var numberOfVisits = createElementWithClassName('span', 'number-visits'); | 1384 var numberOfVisits = createElementWithClassName('span', 'number-visits'); |
1349 var domainElement = document.createElement('span'); | 1385 var domainElement = document.createElement('span'); |
1350 | 1386 |
1351 numberOfVisits.textContent = loadTimeData.getStringF('numberVisits', | 1387 numberOfVisits.textContent = loadTimeData.getStringF('numberVisits', |
1352 domainVisits.length); | 1388 domainVisits.length); |
1353 siteDomain.appendChild(numberOfVisits); | 1389 siteDomain.appendChild(numberOfVisits); |
1354 | 1390 |
1355 domainVisits[0].addFaviconToElement_(siteDomain); | 1391 domainVisits[0].loadFavicon_(siteFavicon); |
1356 | 1392 |
1357 siteDomainWrapper.addEventListener( | 1393 siteDomainWrapper.addEventListener( |
1358 'click', this.toggleGroupedVisits_.bind(this)); | 1394 'click', this.toggleGroupedVisits_.bind(this)); |
1359 | 1395 |
1360 if (this.model_.isSupervisedProfile) { | 1396 if (this.model_.isSupervisedProfile) { |
1361 siteDomainRow.appendChild( | 1397 siteDomainRow.appendChild( |
1362 getFilteringStatusDOM(domainVisits[0].hostFilteringBehavior)); | 1398 getFilteringStatusDOM(domainVisits[0].hostFilteringBehavior)); |
1363 } | 1399 } |
1364 | 1400 |
1365 siteResults.appendChild(siteDomainWrapper); | 1401 siteResults.appendChild(siteDomainWrapper); |
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2346 historyView.reload(); | 2382 historyView.reload(); |
2347 } | 2383 } |
2348 | 2384 |
2349 // Add handlers to HTML elements. | 2385 // Add handlers to HTML elements. |
2350 document.addEventListener('DOMContentLoaded', load); | 2386 document.addEventListener('DOMContentLoaded', load); |
2351 | 2387 |
2352 // This event lets us enable and disable menu items before the menu is shown. | 2388 // This event lets us enable and disable menu items before the menu is shown. |
2353 document.addEventListener('canExecute', function(e) { | 2389 document.addEventListener('canExecute', function(e) { |
2354 e.canExecute = true; | 2390 e.canExecute = true; |
2355 }); | 2391 }); |
OLD | NEW |