| 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 | 6 |
| 7 /////////////////////////////////////////////////////////////////////////////// | 7 /////////////////////////////////////////////////////////////////////////////// |
| 8 // Globals: | 8 // Globals: |
| 9 /** @const */ var RESULTS_PER_PAGE = 150; | 9 /** @const */ var RESULTS_PER_PAGE = 150; |
| 10 | 10 |
| 11 // Amount of time between pageviews that we consider a 'break' in browsing, | 11 // Amount of time between pageviews that we consider a 'break' in browsing, |
| 12 // measured in milliseconds. | 12 // measured in milliseconds. |
| 13 /** @const */ var BROWSING_GAP_TIME = 15 * 60 * 1000; | 13 /** @const */ var BROWSING_GAP_TIME = 15 * 60 * 1000; |
| 14 | 14 |
| 15 // TODO(glen): Get rid of these global references, replace with a controller | 15 // TODO(glen): Get rid of these global references, replace with a controller |
| 16 // or just make the classes own more of the page. | 16 // or just make the classes own more of the page. |
| 17 var historyModel; | 17 var historyModel; |
| 18 var historyView; | 18 var historyView; |
| 19 var pageState; | 19 var pageState; |
| 20 var selectionAnchor = -1; | 20 var selectionAnchor = -1; |
| 21 var activeVisit = null; | 21 var activeVisit = null; |
| 22 | 22 |
| 23 /** @const */ var Command = cr.ui.Command; | 23 /** @const */ var Command = cr.ui.Command; |
| 24 /** @const */ var Menu = cr.ui.Menu; | 24 /** @const */ var Menu = cr.ui.Menu; |
| 25 /** @const */ var MenuButton = cr.ui.MenuButton; | 25 /** @const */ var MenuButton = cr.ui.MenuButton; |
| 26 | 26 |
| 27 /** | 27 /** |
| 28 * Enum that shows whether a manual exception is set in managed mode for a | 28 * Enum that shows the filtering behavior for a host or URL to a managed user. |
| 29 * host or URL. | 29 * Must behave like the FilteringBehavior enum from managed_mode_url_filter.h. |
| 30 * Must behave like the ManualBehavior enum from managed_user_service.h. | |
| 31 * @enum {number} | 30 * @enum {number} |
| 32 */ | 31 */ |
| 33 ManagedModeManualBehavior = { | 32 ManagedModeFilteringBehavior = { |
| 34 NONE: 0, | 33 ALLOW: 0, |
| 35 ALLOW: 1, | 34 WARN: 1, |
| 36 BLOCK: 2 | 35 BLOCK: 2 |
| 37 }; | 36 }; |
| 38 | 37 |
| 39 MenuButton.createDropDownArrows(); | 38 MenuButton.createDropDownArrows(); |
| 40 | 39 |
| 41 /** | 40 /** |
| 42 * Returns true if the mobile (non-desktop) version is being shown. | 41 * Returns true if the mobile (non-desktop) version is being shown. |
| 43 * @return {boolean} true if the mobile version is being shown. | 42 * @return {boolean} true if the mobile version is being shown. |
| 44 */ | 43 */ |
| 45 function isMobileVersion() { | 44 function isMobileVersion() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 // two items easily. | 78 // two items easily. |
| 80 | 79 |
| 81 this.date = new Date(result.time); | 80 this.date = new Date(result.time); |
| 82 | 81 |
| 83 // See comment in BrowsingHistoryHandler::QueryComplete - we won't always | 82 // See comment in BrowsingHistoryHandler::QueryComplete - we won't always |
| 84 // get all of these. | 83 // get all of these. |
| 85 this.dateRelativeDay = result.dateRelativeDay || ''; | 84 this.dateRelativeDay = result.dateRelativeDay || ''; |
| 86 this.dateTimeOfDay = result.dateTimeOfDay || ''; | 85 this.dateTimeOfDay = result.dateTimeOfDay || ''; |
| 87 this.dateShort = result.dateShort || ''; | 86 this.dateShort = result.dateShort || ''; |
| 88 | 87 |
| 89 // These values represent indicators shown to users in managed mode. | 88 // Shows the filtering behavior for that host (only used for managed users). |
| 90 // |*manualBehavior| shows whether the user has manually added an exception | 89 // A value of |ManagedModeFilteringBehavior.ALLOW| is not displayed so it is |
| 91 // for that URL or host while |*inContentPack| shows whether that URL or host | 90 // used as the default value. |
| 92 // is in a content pack or not. | 91 this.hostFilteringBehavior = ManagedModeFilteringBehavior.ALLOW; |
| 93 this.urlManualBehavior = result.urlManualBehavior || | 92 if (typeof result.hostFilteringBehavior != 'undefined') |
| 94 ManagedModeManualBehavior.NONE; | 93 this.hostFilteringBehavior = result.hostFilteringBehavior; |
| 95 this.hostManualBehavior = result.hostManualBehavior || | 94 |
| 96 ManagedModeManualBehavior.NONE; | |
| 97 this.urlInContentPack = result.urlInContentPack || false; | |
| 98 this.hostInContentPack = result.hostInContentPack || false; | |
| 99 this.blockedVisit = result.blockedVisit || false; | 95 this.blockedVisit = result.blockedVisit || false; |
| 100 | 96 |
| 101 // Whether this is the continuation of a previous day. | 97 // Whether this is the continuation of a previous day. |
| 102 this.continued = continued; | 98 this.continued = continued; |
| 103 | 99 |
| 104 this.allTimestamps = result.allTimestamps; | 100 this.allTimestamps = result.allTimestamps; |
| 105 } | 101 } |
| 106 | 102 |
| 107 // Visit, public: ------------------------------------------------------------- | 103 // Visit, public: ------------------------------------------------------------- |
| 108 | 104 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 bookmarkSection.classList.add('starred'); | 157 bookmarkSection.classList.add('starred'); |
| 162 bookmarkSection.addEventListener('click', function f(e) { | 158 bookmarkSection.addEventListener('click', function f(e) { |
| 163 bookmarkSection.classList.remove('starred'); | 159 bookmarkSection.classList.remove('starred'); |
| 164 chrome.send('removeBookmark', [self.url_]); | 160 chrome.send('removeBookmark', [self.url_]); |
| 165 bookmarkSection.removeEventListener('click', f); | 161 bookmarkSection.removeEventListener('click', f); |
| 166 e.preventDefault(); | 162 e.preventDefault(); |
| 167 }); | 163 }); |
| 168 } | 164 } |
| 169 entryBox.appendChild(bookmarkSection); | 165 entryBox.appendChild(bookmarkSection); |
| 170 | 166 |
| 171 var titleAndDomainWrapper = entryBox.appendChild( | 167 var visitEntryWrapper = entryBox.appendChild(document.createElement('div')); |
| 172 createElementWithClassName('div', 'title-and-domain')); | 168 if (addTitleFavicon || this.blockedVisit) |
| 169 visitEntryWrapper.classList.add('visit-entry'); |
| 173 if (this.blockedVisit) { | 170 if (this.blockedVisit) { |
| 174 titleAndDomainWrapper.classList.add('blocked-indicator'); | 171 visitEntryWrapper.classList.add('blocked-indicator'); |
| 175 titleAndDomainWrapper.appendChild(this.getVisitAttemptDOM_()); | 172 visitEntryWrapper.appendChild(this.getVisitAttemptDOM_()); |
| 176 } else { | 173 } else { |
| 177 titleAndDomainWrapper.appendChild(this.getTitleDOM_()); | 174 visitEntryWrapper.appendChild(this.getTitleDOM_()); |
| 178 if (addTitleFavicon) | 175 if (addTitleFavicon) |
| 179 this.addFaviconToElement_(titleAndDomainWrapper); | 176 this.addFaviconToElement_(visitEntryWrapper); |
| 177 visitEntryWrapper.appendChild(domain); |
| 180 } | 178 } |
| 181 titleAndDomainWrapper.appendChild(domain); | |
| 182 | 179 |
| 183 if (isMobileVersion()) { | 180 if (isMobileVersion()) { |
| 184 var removeButton = createElementWithClassName('button', 'remove-entry'); | 181 var removeButton = createElementWithClassName('button', 'remove-entry'); |
| 185 removeButton.classList.add('custom-appearance'); | 182 removeButton.classList.add('custom-appearance'); |
| 186 removeButton.addEventListener('click', function(e) { | 183 removeButton.addEventListener('click', function(e) { |
| 187 self.removeFromHistory(); | 184 self.removeFromHistory(); |
| 188 e.stopPropagation(); | 185 e.stopPropagation(); |
| 189 e.preventDefault(); | 186 e.preventDefault(); |
| 190 }); | 187 }); |
| 191 entryBox.appendChild(removeButton); | 188 entryBox.appendChild(removeButton); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 214 this.classList.add('contains-focus'); | 211 this.classList.add('contains-focus'); |
| 215 }, true); | 212 }, true); |
| 216 entryBox.addEventListener('blur', function() { | 213 entryBox.addEventListener('blur', function() { |
| 217 this.classList.remove('contains-focus'); | 214 this.classList.remove('contains-focus'); |
| 218 }, true); | 215 }, true); |
| 219 | 216 |
| 220 var entryBoxContainer = | 217 var entryBoxContainer = |
| 221 createElementWithClassName('div', 'entry-box-container'); | 218 createElementWithClassName('div', 'entry-box-container'); |
| 222 node.appendChild(entryBoxContainer); | 219 node.appendChild(entryBoxContainer); |
| 223 entryBoxContainer.appendChild(entryBox); | 220 entryBoxContainer.appendChild(entryBox); |
| 224 if (!isSearchResult && this.model_.isManagedProfile && | |
| 225 this.model_.getGroupByDomain()) { | |
| 226 entryBoxContainer.appendChild( | |
| 227 getManagedStatusDOM(this.urlManualBehavior, this.urlInContentPack)); | |
| 228 } | |
| 229 | 221 |
| 230 if (isSearchResult) { | 222 if (isSearchResult) { |
| 231 time.appendChild(document.createTextNode(this.dateShort)); | 223 time.appendChild(document.createTextNode(this.dateShort)); |
| 232 var snippet = createElementWithClassName('div', 'snippet'); | 224 var snippet = createElementWithClassName('div', 'snippet'); |
| 233 this.addHighlightedText_(snippet, | 225 this.addHighlightedText_(snippet, |
| 234 this.snippet_, | 226 this.snippet_, |
| 235 this.model_.getSearchText()); | 227 this.model_.getSearchText()); |
| 236 node.appendChild(snippet); | 228 node.appendChild(snippet); |
| 237 } else if (useMonthDate) { | 229 } else if (useMonthDate) { |
| 238 // Show the day instead of the time. | 230 // Show the day instead of the time. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 }; | 319 }; |
| 328 | 320 |
| 329 /** | 321 /** |
| 330 * Returns the DOM element containing the text for a blocked visit attempt. | 322 * Returns the DOM element containing the text for a blocked visit attempt. |
| 331 * @return {Element} DOM representation of the visit attempt. | 323 * @return {Element} DOM representation of the visit attempt. |
| 332 * @private | 324 * @private |
| 333 */ | 325 */ |
| 334 Visit.prototype.getVisitAttemptDOM_ = function() { | 326 Visit.prototype.getVisitAttemptDOM_ = function() { |
| 335 var node = createElementWithClassName('div', 'title'); | 327 var node = createElementWithClassName('div', 'title'); |
| 336 node.innerHTML = loadTimeData.getStringF('blockedVisitText', | 328 node.innerHTML = loadTimeData.getStringF('blockedVisitText', |
| 337 this.url_, this.id_); | 329 this.url_, |
| 330 this.id_, |
| 331 this.getDomainFromURL_(this.url_)); |
| 338 return node; | 332 return node; |
| 339 }; | 333 }; |
| 340 | 334 |
| 341 /** | 335 /** |
| 342 * Set the favicon for an element. | 336 * Set the favicon for an element. |
| 343 * @param {Element} el The DOM element to which to add the icon. | 337 * @param {Element} el The DOM element to which to add the icon. |
| 344 * @private | 338 * @private |
| 345 */ | 339 */ |
| 346 Visit.prototype.addFaviconToElement_ = function(el) { | 340 Visit.prototype.addFaviconToElement_ = function(el) { |
| 347 var url = isMobileVersion() ? | 341 var url = isMobileVersion() ? |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 */ | 567 */ |
| 574 HistoryModel.prototype.clearModel_ = function() { | 568 HistoryModel.prototype.clearModel_ = function() { |
| 575 this.inFlight_ = false; // Whether a query is inflight. | 569 this.inFlight_ = false; // Whether a query is inflight. |
| 576 this.searchText_ = ''; | 570 this.searchText_ = ''; |
| 577 // Whether this user is a managed user. | 571 // Whether this user is a managed user. |
| 578 this.isManagedProfile = loadTimeData.getBoolean('isManagedProfile'); | 572 this.isManagedProfile = loadTimeData.getBoolean('isManagedProfile'); |
| 579 this.deletingHistoryAllowed = loadTimeData.getBoolean('allowDeletingHistory'); | 573 this.deletingHistoryAllowed = loadTimeData.getBoolean('allowDeletingHistory'); |
| 580 | 574 |
| 581 // Only create checkboxes for editing entries if they can be used either to | 575 // Only create checkboxes for editing entries if they can be used either to |
| 582 // delete an entry or to block/allow it. | 576 // delete an entry or to block/allow it. |
| 583 this.editingEntriesAllowed = this.deletingHistoryAllowed || | 577 this.editingEntriesAllowed = this.deletingHistoryAllowed; |
| 584 this.isManagedProfile; | |
| 585 | 578 |
| 586 // Flag to show that the results are grouped by domain or not. | 579 // Flag to show that the results are grouped by domain or not. |
| 587 this.groupByDomain_ = false; | 580 this.groupByDomain_ = false; |
| 588 // Group domains by default for managed users. | |
| 589 if (this.isManagedProfile) | |
| 590 this.groupByDomain_ = true; | |
| 591 | 581 |
| 592 this.visits_ = []; // Date-sorted list of visits (most recent first). | 582 this.visits_ = []; // Date-sorted list of visits (most recent first). |
| 593 this.nextVisitId_ = 0; | 583 this.nextVisitId_ = 0; |
| 594 selectionAnchor = -1; | 584 selectionAnchor = -1; |
| 595 | 585 |
| 596 // The page that the view wants to see - we only fetch slightly past this | 586 // The page that the view wants to see - we only fetch slightly past this |
| 597 // point. If the view requests a page that we don't have data for, we try | 587 // point. If the view requests a page that we don't have data for, we try |
| 598 // to fetch it and call back when we're done. | 588 // to fetch it and call back when we're done. |
| 599 this.requestedPage_ = 0; | 589 this.requestedPage_ = 0; |
| 600 | 590 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 $('newest-button').addEventListener('click', function() { | 716 $('newest-button').addEventListener('click', function() { |
| 727 self.setPage(0); | 717 self.setPage(0); |
| 728 }); | 718 }); |
| 729 $('newer-button').addEventListener('click', function() { | 719 $('newer-button').addEventListener('click', function() { |
| 730 self.setPage(self.pageIndex_ - 1); | 720 self.setPage(self.pageIndex_ - 1); |
| 731 }); | 721 }); |
| 732 $('older-button').addEventListener('click', function() { | 722 $('older-button').addEventListener('click', function() { |
| 733 self.setPage(self.pageIndex_ + 1); | 723 self.setPage(self.pageIndex_ + 1); |
| 734 }); | 724 }); |
| 735 | 725 |
| 726 var handleRangeChange = function(e) { |
| 727 // Update the results and save the last state. |
| 728 self.setRangeInDays(parseInt(e.target.value, 10)); |
| 729 }; |
| 730 |
| 736 // Add handlers for the range options. | 731 // Add handlers for the range options. |
| 737 $('timeframe-filter').addEventListener('change', function(e) { | 732 $('timeframe-filter-all').addEventListener('change', handleRangeChange); |
| 738 self.setRangeInDays(parseInt(e.target.value, 10)); | 733 $('timeframe-filter-week').addEventListener('change', handleRangeChange); |
| 739 }); | 734 $('timeframe-filter-month').addEventListener('change', handleRangeChange); |
| 740 | |
| 741 $('group-by-domain').addEventListener('click', function(e) { | |
| 742 self.setGroupByDomain($('group-by-domain').checked); | |
| 743 }); | |
| 744 | 735 |
| 745 $('range-previous').addEventListener('click', function(e) { | 736 $('range-previous').addEventListener('click', function(e) { |
| 746 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) | 737 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) |
| 747 self.setPage(self.pageIndex_ + 1); | 738 self.setPage(self.pageIndex_ + 1); |
| 748 else | 739 else |
| 749 self.setOffset(self.getOffset() + 1); | 740 self.setOffset(self.getOffset() + 1); |
| 750 }); | 741 }); |
| 751 $('range-next').addEventListener('click', function(e) { | 742 $('range-next').addEventListener('click', function(e) { |
| 752 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) | 743 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) |
| 753 self.setPage(self.pageIndex_ - 1); | 744 self.setPage(self.pageIndex_ - 1); |
| 754 else | 745 else |
| 755 self.setOffset(self.getOffset() - 1); | 746 self.setOffset(self.getOffset() - 1); |
| 756 }); | 747 }); |
| 757 $('range-today').addEventListener('click', function(e) { | 748 $('range-today').addEventListener('click', function(e) { |
| 758 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) | 749 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) |
| 759 self.setPage(0); | 750 self.setPage(0); |
| 760 else | 751 else |
| 761 self.setOffset(0); | 752 self.setOffset(0); |
| 762 }); | 753 }); |
| 763 } | 754 } |
| 764 | 755 |
| 765 // HistoryView, public: ------------------------------------------------------- | 756 // HistoryView, public: ------------------------------------------------------- |
| 766 /** | 757 /** |
| 767 * Do a search on a specific term. | 758 * Do a search on a specific term. |
| 768 * @param {string} term The string to search for. | 759 * @param {string} term The string to search for. |
| 769 */ | 760 */ |
| 770 HistoryView.prototype.setSearch = function(term) { | 761 HistoryView.prototype.setSearch = function(term) { |
| 771 window.scrollTo(0, 0); | 762 window.scrollTo(0, 0); |
| 772 this.setPageState(term, 0, this.model_.getGroupByDomain(), | 763 this.setPageState(term, 0, this.getRangeInDays(), this.getOffset()); |
| 773 this.getRangeInDays(), this.getOffset()); | |
| 774 }; | 764 }; |
| 775 | 765 |
| 776 /** | 766 /** |
| 777 * Enable or disable results as being grouped by domain. | |
| 778 * @param {boolean} groupedByDomain Whether to group by domain or not. | |
| 779 */ | |
| 780 HistoryView.prototype.setGroupByDomain = function(groupedByDomain) { | |
| 781 // Group by domain is not currently supported for search results, so reset | |
| 782 // the search term if there was one. | |
| 783 this.setPageState('', this.pageIndex_, groupedByDomain, this.getRangeInDays(), | |
| 784 this.getOffset()); | |
| 785 }; | |
| 786 | |
| 787 /** | |
| 788 * Reload the current view. | 767 * Reload the current view. |
| 789 */ | 768 */ |
| 790 HistoryView.prototype.reload = function() { | 769 HistoryView.prototype.reload = function() { |
| 791 this.model_.reload(); | 770 this.model_.reload(); |
| 792 this.updateSelectionEditButtons(); | 771 this.updateSelectionEditButtons(); |
| 793 this.updateRangeButtons_(); | 772 this.updateRangeButtons_(); |
| 794 }; | 773 }; |
| 795 | 774 |
| 796 /** | 775 /** |
| 797 * Sets all the parameters for the history page and then reloads the view to | 776 * Sets all the parameters for the history page and then reloads the view to |
| 798 * update the results. | 777 * update the results. |
| 799 * @param {string} searchText The search string to set. | 778 * @param {string} searchText The search string to set. |
| 800 * @param {number} page The page to be viewed. | 779 * @param {number} page The page to be viewed. |
| 801 * @param {boolean} groupByDomain Whether the results are grouped or not. | |
| 802 * @param {HistoryModel.Range} range The range to view or search over. | 780 * @param {HistoryModel.Range} range The range to view or search over. |
| 803 * @param {number} offset Set the begining of the query to the specific offset. | 781 * @param {number} offset Set the begining of the query to the specific offset. |
| 804 */ | 782 */ |
| 805 HistoryView.prototype.setPageState = function(searchText, page, groupByDomain, | 783 HistoryView.prototype.setPageState = function(searchText, page, range, offset) { |
| 806 range, offset) { | |
| 807 this.clear_(); | 784 this.clear_(); |
| 808 this.model_.searchText_ = searchText; | 785 this.model_.searchText_ = searchText; |
| 809 this.pageIndex_ = page; | 786 this.pageIndex_ = page; |
| 810 this.model_.requestedPage_ = page; | 787 this.model_.requestedPage_ = page; |
| 811 this.model_.groupByDomain_ = groupByDomain; | |
| 812 this.model_.rangeInDays_ = range; | 788 this.model_.rangeInDays_ = range; |
| 789 this.model_.groupByDomain_ = false; |
| 790 if (range != HistoryModel.Range.ALL_TIME) |
| 791 this.model_.groupByDomain_ = true; |
| 813 this.model_.offset_ = offset; | 792 this.model_.offset_ = offset; |
| 814 this.reload(); | 793 this.reload(); |
| 815 pageState.setUIState(this.model_.getSearchText(), | 794 pageState.setUIState(this.model_.getSearchText(), |
| 816 this.pageIndex_, | 795 this.pageIndex_, |
| 817 this.model_.getGroupByDomain(), | |
| 818 this.getRangeInDays(), | 796 this.getRangeInDays(), |
| 819 this.getOffset()); | 797 this.getOffset()); |
| 820 }; | 798 }; |
| 821 | 799 |
| 822 /** | 800 /** |
| 823 * Switch to a specified page. | 801 * Switch to a specified page. |
| 824 * @param {number} page The page we wish to view. | 802 * @param {number} page The page we wish to view. |
| 825 */ | 803 */ |
| 826 HistoryView.prototype.setPage = function(page) { | 804 HistoryView.prototype.setPage = function(page) { |
| 827 // TODO(sergiu): Move this function to setPageState as well and see why one | 805 // TODO(sergiu): Move this function to setPageState as well and see why one |
| 828 // of the tests fails when using setPageState. | 806 // of the tests fails when using setPageState. |
| 829 this.clear_(); | 807 this.clear_(); |
| 830 this.pageIndex_ = parseInt(page, 10); | 808 this.pageIndex_ = parseInt(page, 10); |
| 831 window.scrollTo(0, 0); | 809 window.scrollTo(0, 0); |
| 832 this.model_.requestPage(page); | 810 this.model_.requestPage(page); |
| 833 pageState.setUIState(this.model_.getSearchText(), | 811 pageState.setUIState(this.model_.getSearchText(), |
| 834 this.pageIndex_, | 812 this.pageIndex_, |
| 835 this.model_.getGroupByDomain(), | |
| 836 this.getRangeInDays(), | 813 this.getRangeInDays(), |
| 837 this.getOffset()); | 814 this.getOffset()); |
| 838 }; | 815 }; |
| 839 | 816 |
| 840 /** | 817 /** |
| 841 * @return {number} The page number being viewed. | 818 * @return {number} The page number being viewed. |
| 842 */ | 819 */ |
| 843 HistoryView.prototype.getPage = function() { | 820 HistoryView.prototype.getPage = function() { |
| 844 return this.pageIndex_; | 821 return this.pageIndex_; |
| 845 }; | 822 }; |
| 846 | 823 |
| 847 /** | 824 /** |
| 848 * Set the current range for grouped results. | 825 * Set the current range for grouped results. |
| 849 * @param {string} range The number of days to which the range should be set. | 826 * @param {string} range The number of days to which the range should be set. |
| 850 */ | 827 */ |
| 851 HistoryView.prototype.setRangeInDays = function(range) { | 828 HistoryView.prototype.setRangeInDays = function(range) { |
| 852 // Set the range, offset and reset the page. | 829 // Set the range, offset and reset the page. |
| 853 this.setPageState(this.model_.getSearchText(), 0, | 830 this.setPageState(this.model_.getSearchText(), 0, range, 0); |
| 854 this.model_.getGroupByDomain(), range, 0); | |
| 855 }; | 831 }; |
| 856 | 832 |
| 857 /** | 833 /** |
| 858 * Get the current range in days. | 834 * Get the current range in days. |
| 859 * @return {number} Current range in days from the model. | 835 * @return {number} Current range in days from the model. |
| 860 */ | 836 */ |
| 861 HistoryView.prototype.getRangeInDays = function() { | 837 HistoryView.prototype.getRangeInDays = function() { |
| 862 return this.model_.rangeInDays; | 838 return this.model_.rangeInDays; |
| 863 }; | 839 }; |
| 864 | 840 |
| 865 /** | 841 /** |
| 866 * Set the current offset for grouped results. | 842 * Set the current offset for grouped results. |
| 867 * @param {number} offset Offset to set. | 843 * @param {number} offset Offset to set. |
| 868 */ | 844 */ |
| 869 HistoryView.prototype.setOffset = function(offset) { | 845 HistoryView.prototype.setOffset = function(offset) { |
| 870 // If there is another query already in flight wait for that to complete. | 846 // If there is another query already in flight wait for that to complete. |
| 871 if (this.model_.inFlight_) | 847 if (this.model_.inFlight_) |
| 872 return; | 848 return; |
| 873 this.setPageState(this.model_.getSearchText(), | 849 this.setPageState(this.model_.getSearchText(), |
| 874 this.pageIndex_, | 850 this.pageIndex_, |
| 875 this.model_.getGroupByDomain(), | |
| 876 this.getRangeInDays(), | 851 this.getRangeInDays(), |
| 877 offset); | 852 offset); |
| 878 }; | 853 }; |
| 879 | 854 |
| 880 /** | 855 /** |
| 881 * Get the current offset. | 856 * Get the current offset. |
| 882 * @return {number} Current offset from the model. | 857 * @return {number} Current offset from the model. |
| 883 */ | 858 */ |
| 884 HistoryView.prototype.getOffset = function() { | 859 HistoryView.prototype.getOffset = function() { |
| 885 return this.model_.offset; | 860 return this.model_.offset; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 | 1001 |
| 1027 numberOfVisits.textContent = loadTimeData.getStringF('numberVisits', | 1002 numberOfVisits.textContent = loadTimeData.getStringF('numberVisits', |
| 1028 domainVisits.length); | 1003 domainVisits.length); |
| 1029 siteDomain.appendChild(numberOfVisits); | 1004 siteDomain.appendChild(numberOfVisits); |
| 1030 | 1005 |
| 1031 domainVisits[0].addFaviconToElement_(siteDomain); | 1006 domainVisits[0].addFaviconToElement_(siteDomain); |
| 1032 | 1007 |
| 1033 siteDomainWrapper.addEventListener('click', toggleHandler); | 1008 siteDomainWrapper.addEventListener('click', toggleHandler); |
| 1034 | 1009 |
| 1035 if (this.model_.isManagedProfile) { | 1010 if (this.model_.isManagedProfile) { |
| 1036 // Visit attempts don't make sense for domains so set the last parameter to | 1011 siteDomainWrapper.appendChild( |
| 1037 // false. | 1012 getManagedStatusDOM(domainVisits[0].hostFilteringBehavior)); |
| 1038 siteDomainWrapper.appendChild(getManagedStatusDOM( | |
| 1039 domainVisits[0].hostManualBehavior, domainVisits[0].hostInContentPack)); | |
| 1040 } | 1013 } |
| 1041 | 1014 |
| 1042 siteResults.appendChild(siteDomainWrapper); | 1015 siteResults.appendChild(siteDomainWrapper); |
| 1043 var resultsList = siteResults.appendChild( | 1016 var resultsList = siteResults.appendChild( |
| 1044 createElementWithClassName('ol', 'site-results')); | 1017 createElementWithClassName('ol', 'site-results')); |
| 1045 | 1018 |
| 1046 // Collapse until it gets toggled. | 1019 // Collapse until it gets toggled. |
| 1047 resultsList.style.height = 0; | 1020 resultsList.style.height = 0; |
| 1048 | 1021 |
| 1049 // Add the results for each of the domain. | 1022 // Add the results for each of the domain. |
| 1050 var isMonthGroupedResult = this.getRangeInDays() == HistoryModel.Range.MONTH; | 1023 var isMonthGroupedResult = this.getRangeInDays() == HistoryModel.Range.MONTH; |
| 1051 for (var j = 0, visit; visit = domainVisits[j]; j++) { | 1024 for (var j = 0, visit; visit = domainVisits[j]; j++) { |
| 1052 resultsList.appendChild(visit.getResultDOM({ | 1025 resultsList.appendChild(visit.getResultDOM({ |
| 1053 useMonthDate: isMonthGroupedResult | 1026 useMonthDate: isMonthGroupedResult |
| 1054 })); | 1027 })); |
| 1055 this.setVisitRendered_(visit); | 1028 this.setVisitRendered_(visit); |
| 1056 } | 1029 } |
| 1057 }; | 1030 }; |
| 1058 | 1031 |
| 1059 /** | 1032 /** |
| 1060 * Enables or disables the time range buttons. | 1033 * Enables or disables the time range buttons. |
| 1061 * @private | 1034 * @private |
| 1062 */ | 1035 */ |
| 1063 HistoryView.prototype.updateRangeButtons_ = function() { | 1036 HistoryView.prototype.updateRangeButtons_ = function() { |
| 1064 // Update the range button to the current value. | |
| 1065 $('timeframe-filter').value = this.getRangeInDays(); | |
| 1066 | |
| 1067 // The enabled state for the previous, today and next buttons. | 1037 // The enabled state for the previous, today and next buttons. |
| 1068 var previousState = false; | 1038 var previousState = false; |
| 1069 var todayState = false; | 1039 var todayState = false; |
| 1070 var nextState = false; | 1040 var nextState = false; |
| 1071 var usePage = (this.getRangeInDays() == HistoryModel.Range.ALL_TIME); | 1041 var usePage = (this.getRangeInDays() == HistoryModel.Range.ALL_TIME); |
| 1072 | 1042 |
| 1073 // Use pagination for most recent visits, offset otherwise. | 1043 // Use pagination for most recent visits, offset otherwise. |
| 1074 // TODO(sergiu): Maybe send just one variable in the future. | 1044 // TODO(sergiu): Maybe send just one variable in the future. |
| 1075 if (usePage) { | 1045 if (usePage) { |
| 1076 if (this.getPage() != 0) { | 1046 if (this.getPage() != 0) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 * @param {Array} visits Visits returned by the query. | 1094 * @param {Array} visits Visits returned by the query. |
| 1125 * @param {Element} parentElement Element to which to add the results to. | 1095 * @param {Element} parentElement Element to which to add the results to. |
| 1126 * @private | 1096 * @private |
| 1127 */ | 1097 */ |
| 1128 HistoryView.prototype.addMonthResults_ = function(visits, parentElement) { | 1098 HistoryView.prototype.addMonthResults_ = function(visits, parentElement) { |
| 1129 if (visits.length == 0) | 1099 if (visits.length == 0) |
| 1130 return; | 1100 return; |
| 1131 | 1101 |
| 1132 var monthResults = parentElement.appendChild( | 1102 var monthResults = parentElement.appendChild( |
| 1133 createElementWithClassName('ol', 'month-results')); | 1103 createElementWithClassName('ol', 'month-results')); |
| 1104 // Don't add checkboxes if entries can not be edited. |
| 1105 if (!this.model_.editingEntriesAllowed) |
| 1106 monthResults.classList.add('no-checkboxes'); |
| 1107 |
| 1134 this.groupVisitsByDomain_(visits, monthResults); | 1108 this.groupVisitsByDomain_(visits, monthResults); |
| 1135 }; | 1109 }; |
| 1136 | 1110 |
| 1137 /** | 1111 /** |
| 1138 * Adds the results for a certain day. This includes a title with the day of | 1112 * Adds the results for a certain day. This includes a title with the day of |
| 1139 * the results and the results themselves, grouped or not. | 1113 * the results and the results themselves, grouped or not. |
| 1140 * @param {Array} visits Visits returned by the query. | 1114 * @param {Array} visits Visits returned by the query. |
| 1141 * @param {Element} parentElement Element to which to add the results to. | 1115 * @param {Element} parentElement Element to which to add the results to. |
| 1142 * @private | 1116 * @private |
| 1143 */ | 1117 */ |
| 1144 HistoryView.prototype.addDayResults_ = function(visits, parentElement) { | 1118 HistoryView.prototype.addDayResults_ = function(visits, parentElement) { |
| 1145 if (visits.length == 0) | 1119 if (visits.length == 0) |
| 1146 return; | 1120 return; |
| 1147 | 1121 |
| 1148 var firstVisit = visits[0]; | 1122 var firstVisit = visits[0]; |
| 1149 var day = parentElement.appendChild(createElementWithClassName('h3', 'day')); | 1123 var day = parentElement.appendChild(createElementWithClassName('h3', 'day')); |
| 1150 day.appendChild(document.createTextNode(firstVisit.dateRelativeDay)); | 1124 day.appendChild(document.createTextNode(firstVisit.dateRelativeDay)); |
| 1151 if (firstVisit.continued) { | 1125 if (firstVisit.continued) { |
| 1152 day.appendChild(document.createTextNode(' ' + | 1126 day.appendChild(document.createTextNode(' ' + |
| 1153 loadTimeData.getString('cont'))); | 1127 loadTimeData.getString('cont'))); |
| 1154 } | 1128 } |
| 1155 var dayResults = parentElement.appendChild( | 1129 var dayResults = parentElement.appendChild( |
| 1156 createElementWithClassName('ol', 'day-results')); | 1130 createElementWithClassName('ol', 'day-results')); |
| 1157 | 1131 |
| 1132 // Don't add checkboxes if entries can not be edited. |
| 1133 if (!this.model_.editingEntriesAllowed) |
| 1134 dayResults.classList.add('no-checkboxes'); |
| 1135 |
| 1158 if (this.model_.getGroupByDomain()) { | 1136 if (this.model_.getGroupByDomain()) { |
| 1159 this.groupVisitsByDomain_(visits, dayResults); | 1137 this.groupVisitsByDomain_(visits, dayResults); |
| 1160 } else { | 1138 } else { |
| 1161 var lastTime; | 1139 var lastTime; |
| 1162 | 1140 |
| 1163 for (var i = 0, visit; visit = visits[i]; i++) { | 1141 for (var i = 0, visit; visit = visits[i]; i++) { |
| 1164 // If enough time has passed between visits, indicate a gap in browsing. | 1142 // If enough time has passed between visits, indicate a gap in browsing. |
| 1165 var thisTime = visit.date.getTime(); | 1143 var thisTime = visit.date.getTime(); |
| 1166 if (lastTime && lastTime - thisTime > BROWSING_GAP_TIME) | 1144 if (lastTime && lastTime - thisTime > BROWSING_GAP_TIME) |
| 1167 dayResults.appendChild(createElementWithClassName('li', 'gap')); | 1145 dayResults.appendChild(createElementWithClassName('li', 'gap')); |
| 1168 | 1146 |
| 1169 // Insert the visit into the DOM. | 1147 // Insert the visit into the DOM. |
| 1170 dayResults.appendChild(visit.getResultDOM({ addTitleFavicon: true })); | 1148 dayResults.appendChild(visit.getResultDOM({ addTitleFavicon: true })); |
| 1171 this.setVisitRendered_(visit); | 1149 this.setVisitRendered_(visit); |
| 1172 | 1150 |
| 1173 lastTime = thisTime; | 1151 lastTime = thisTime; |
| 1174 } | 1152 } |
| 1175 } | 1153 } |
| 1176 }; | 1154 }; |
| 1177 | 1155 |
| 1178 /** | 1156 /** |
| 1157 * Adds the text that shows the current interval, used for week and month |
| 1158 * results. |
| 1159 * @param {Element} resultsFragment The element to which the interval will be |
| 1160 * added to. |
| 1161 * @private |
| 1162 */ |
| 1163 HistoryView.prototype.addTimeframeInterval_ = function(resultsFragment) { |
| 1164 if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME) |
| 1165 return; |
| 1166 |
| 1167 // If this is a time range result add some text that shows what is the |
| 1168 // time range for the results the user is viewing. |
| 1169 var timeFrame = resultsFragment.appendChild( |
| 1170 createElementWithClassName('h2', 'timeframe')); |
| 1171 // TODO(sergiu): Figure the best way to show this for the first day of |
| 1172 // the month. |
| 1173 timeFrame.appendChild(document.createTextNode(loadTimeData.getStringF( |
| 1174 'historyInterval', |
| 1175 this.model_.queryStartTime, |
| 1176 this.model_.queryEndTime))); |
| 1177 }; |
| 1178 |
| 1179 /** |
| 1179 * Update the page with results. | 1180 * Update the page with results. |
| 1180 * @param {boolean} doneLoading Whether the current request is complete. | 1181 * @param {boolean} doneLoading Whether the current request is complete. |
| 1181 * @private | 1182 * @private |
| 1182 */ | 1183 */ |
| 1183 HistoryView.prototype.displayResults_ = function(doneLoading) { | 1184 HistoryView.prototype.displayResults_ = function(doneLoading) { |
| 1184 // Either show a page of results received for the all time results or all the | 1185 // Either show a page of results received for the all time results or all the |
| 1185 // received results for the weekly and monthly view. | 1186 // received results for the weekly and monthly view. |
| 1186 var results = this.model_.visits_; | 1187 var results = this.model_.visits_; |
| 1187 if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME) { | 1188 if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME) { |
| 1188 var rangeStart = this.pageIndex_ * RESULTS_PER_PAGE; | 1189 var rangeStart = this.pageIndex_ * RESULTS_PER_PAGE; |
| 1189 var rangeEnd = rangeStart + RESULTS_PER_PAGE; | 1190 var rangeEnd = rangeStart + RESULTS_PER_PAGE; |
| 1190 results = this.model_.getNumberedRange(rangeStart, rangeEnd); | 1191 results = this.model_.getNumberedRange(rangeStart, rangeEnd); |
| 1191 } | 1192 } |
| 1192 var searchText = this.model_.getSearchText(); | 1193 var searchText = this.model_.getSearchText(); |
| 1193 var groupByDomain = this.model_.getGroupByDomain(); | 1194 var groupByDomain = this.model_.getGroupByDomain(); |
| 1194 | 1195 |
| 1195 if (searchText) { | 1196 if (searchText) { |
| 1196 // Add a header for the search results, if there isn't already one. | 1197 // Add a header for the search results, if there isn't already one. |
| 1197 if (!this.resultDiv_.querySelector('h3')) { | 1198 if (!this.resultDiv_.querySelector('h3')) { |
| 1198 var header = document.createElement('h3'); | 1199 var header = document.createElement('h3'); |
| 1199 header.textContent = loadTimeData.getStringF('searchResultsFor', | 1200 header.textContent = loadTimeData.getStringF('searchResultsFor', |
| 1200 searchText); | 1201 searchText); |
| 1201 this.resultDiv_.appendChild(header); | 1202 this.resultDiv_.appendChild(header); |
| 1202 } | 1203 } |
| 1203 | 1204 |
| 1205 this.addTimeframeInterval_(this.resultDiv_); |
| 1206 |
| 1204 var searchResults = createElementWithClassName('ol', 'search-results'); | 1207 var searchResults = createElementWithClassName('ol', 'search-results'); |
| 1208 |
| 1209 // Don't add checkboxes if entries can not be edited. |
| 1210 if (!this.model_.editingEntriesAllowed) |
| 1211 searchResults.classList.add('no-checkboxes'); |
| 1212 |
| 1205 if (results.length == 0 && doneLoading) { | 1213 if (results.length == 0 && doneLoading) { |
| 1206 var noSearchResults = searchResults.appendChild( | 1214 var noSearchResults = searchResults.appendChild( |
| 1207 createElementWithClassName('div', 'no-results-message')); | 1215 createElementWithClassName('div', 'no-results-message')); |
| 1208 noSearchResults.textContent = loadTimeData.getString('noSearchResults'); | 1216 noSearchResults.textContent = loadTimeData.getString('noSearchResults'); |
| 1209 } else { | 1217 } else { |
| 1210 for (var i = 0, visit; visit = results[i]; i++) { | 1218 for (var i = 0, visit; visit = results[i]; i++) { |
| 1211 if (!visit.isRendered) { | 1219 if (!visit.isRendered) { |
| 1212 searchResults.appendChild(visit.getResultDOM({ | 1220 searchResults.appendChild(visit.getResultDOM({ |
| 1213 isSearchResult: true, | 1221 isSearchResult: true, |
| 1214 addTitleFavicon: true | 1222 addTitleFavicon: true |
| 1215 })); | 1223 })); |
| 1216 this.setVisitRendered_(visit); | 1224 this.setVisitRendered_(visit); |
| 1217 } | 1225 } |
| 1218 } | 1226 } |
| 1219 } | 1227 } |
| 1220 this.resultDiv_.appendChild(searchResults); | 1228 this.resultDiv_.appendChild(searchResults); |
| 1221 } else { | 1229 } else { |
| 1222 var resultsFragment = document.createDocumentFragment(); | 1230 var resultsFragment = document.createDocumentFragment(); |
| 1223 | 1231 |
| 1224 if (this.getRangeInDays() == HistoryModel.Range.WEEK || | 1232 this.addTimeframeInterval_(resultsFragment); |
| 1225 this.getRangeInDays() == HistoryModel.Range.MONTH) { | |
| 1226 // If this is a time range result add some text that shows what is the | |
| 1227 // time range for the results the user is viewing. | |
| 1228 var timeFrame = resultsFragment.appendChild( | |
| 1229 createElementWithClassName('h2', 'timeframe')); | |
| 1230 // TODO(sergiu): Figure the best way to show this for the first day of | |
| 1231 // the month. | |
| 1232 timeFrame.appendChild(document.createTextNode(loadTimeData.getStringF( | |
| 1233 'historyInterval', | |
| 1234 this.model_.queryStartTime, | |
| 1235 this.model_.queryEndTime))); | |
| 1236 } | |
| 1237 | 1233 |
| 1238 if (results.length == 0 && doneLoading) { | 1234 if (results.length == 0 && doneLoading) { |
| 1239 var noResults = resultsFragment.appendChild( | 1235 var noResults = resultsFragment.appendChild( |
| 1240 createElementWithClassName('div', 'no-results-message')); | 1236 createElementWithClassName('div', 'no-results-message')); |
| 1241 noResults.textContent = loadTimeData.getString('noResults'); | 1237 noResults.textContent = loadTimeData.getString('noResults'); |
| 1242 this.resultDiv_.appendChild(resultsFragment); | 1238 this.resultDiv_.appendChild(resultsFragment); |
| 1243 this.updateNavBar_(); | 1239 this.updateNavBar_(); |
| 1244 return; | 1240 return; |
| 1245 } | 1241 } |
| 1246 | 1242 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1270 } | 1266 } |
| 1271 this.updateNavBar_(); | 1267 this.updateNavBar_(); |
| 1272 }; | 1268 }; |
| 1273 | 1269 |
| 1274 /** | 1270 /** |
| 1275 * Update the visibility of the page navigation buttons. | 1271 * Update the visibility of the page navigation buttons. |
| 1276 * @private | 1272 * @private |
| 1277 */ | 1273 */ |
| 1278 HistoryView.prototype.updateNavBar_ = function() { | 1274 HistoryView.prototype.updateNavBar_ = function() { |
| 1279 this.updateRangeButtons_(); | 1275 this.updateRangeButtons_(); |
| 1280 $('newest-button').hidden = this.pageIndex_ == 0; | 1276 if (!loadTimeData.getBoolean('isManagedProfile')) { |
| 1281 $('newer-button').hidden = this.pageIndex_ == 0; | 1277 // Managed users have the control bar on top, don't show it on the bottom |
| 1282 $('older-button').hidden = | 1278 // as well. |
| 1283 this.model_.rangeInDays_ != HistoryModel.Range.ALL_TIME || | 1279 $('newest-button').hidden = this.pageIndex_ == 0; |
| 1284 !this.model_.hasMoreResults(); | 1280 $('newer-button').hidden = this.pageIndex_ == 0; |
| 1281 $('older-button').hidden = |
| 1282 this.model_.rangeInDays_ != HistoryModel.Range.ALL_TIME || |
| 1283 !this.model_.hasMoreResults(); |
| 1284 } |
| 1285 }; | 1285 }; |
| 1286 | 1286 |
| 1287 /** | 1287 /** |
| 1288 * Updates the visibility of the 'Clear browsing data' button. | 1288 * Updates the visibility of the 'Clear browsing data' button. |
| 1289 * Only used on mobile platforms. | 1289 * Only used on mobile platforms. |
| 1290 * @private | 1290 * @private |
| 1291 */ | 1291 */ |
| 1292 HistoryView.prototype.updateClearBrowsingDataButton_ = function() { | 1292 HistoryView.prototype.updateClearBrowsingDataButton_ = function() { |
| 1293 // Ideally, we should hide the 'Clear browsing data' button whenever the | 1293 // Ideally, we should hide the 'Clear browsing data' button whenever the |
| 1294 // soft keyboard is visible. This is not possible, so instead, hide the | 1294 // soft keyboard is visible. This is not possible, so instead, hide the |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1315 this.view = view; | 1315 this.view = view; |
| 1316 | 1316 |
| 1317 if (typeof this.checker_ != 'undefined' && this.checker_) { | 1317 if (typeof this.checker_ != 'undefined' && this.checker_) { |
| 1318 clearInterval(this.checker_); | 1318 clearInterval(this.checker_); |
| 1319 } | 1319 } |
| 1320 | 1320 |
| 1321 // TODO(glen): Replace this with a bound method so we don't need | 1321 // TODO(glen): Replace this with a bound method so we don't need |
| 1322 // public model and view. | 1322 // public model and view. |
| 1323 this.checker_ = window.setInterval(function(stateObj) { | 1323 this.checker_ = window.setInterval(function(stateObj) { |
| 1324 var hashData = stateObj.getHashData(); | 1324 var hashData = stateObj.getHashData(); |
| 1325 var isGroupedByDomain = hashData.grouped == 'true'; | |
| 1326 var page = parseInt(hashData.page, 10); | 1325 var page = parseInt(hashData.page, 10); |
| 1327 var range = parseInt(hashData.range, 10); | 1326 var range = parseInt(hashData.range, 10); |
| 1328 var offset = parseInt(hashData.offset, 10); | 1327 var offset = parseInt(hashData.offset, 10); |
| 1329 if (hashData.q != stateObj.model.getSearchText() || | 1328 if (hashData.q != stateObj.model.getSearchText() || |
| 1330 page != stateObj.view.getPage() || | 1329 page != stateObj.view.getPage() || |
| 1331 isGroupedByDomain != stateObj.view.model_.getGroupByDomain() || | |
| 1332 range != stateObj.model.rangeInDays || | 1330 range != stateObj.model.rangeInDays || |
| 1333 offset != stateObj.model.offset) { | 1331 offset != stateObj.model.offset) { |
| 1334 stateObj.view.setPageState(hashData.q, page, isGroupedByDomain, | 1332 stateObj.view.setPageState(hashData.q, page, range, offset); |
| 1335 range, offset); | |
| 1336 } | 1333 } |
| 1337 }, 50, this); | 1334 }, 50, this); |
| 1338 } | 1335 } |
| 1339 | 1336 |
| 1340 /** | 1337 /** |
| 1341 * Holds the singleton instance. | 1338 * Holds the singleton instance. |
| 1342 */ | 1339 */ |
| 1343 PageState.instance = null; | 1340 PageState.instance = null; |
| 1344 | 1341 |
| 1345 /** | 1342 /** |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1367 | 1364 |
| 1368 return result; | 1365 return result; |
| 1369 }; | 1366 }; |
| 1370 | 1367 |
| 1371 /** | 1368 /** |
| 1372 * Set the hash to a specified state, this will create an entry in the | 1369 * Set the hash to a specified state, this will create an entry in the |
| 1373 * session history so the back button cycles through hash states, which | 1370 * session history so the back button cycles through hash states, which |
| 1374 * are then picked up by our listener. | 1371 * are then picked up by our listener. |
| 1375 * @param {string} term The current search string. | 1372 * @param {string} term The current search string. |
| 1376 * @param {number} page The page currently being viewed. | 1373 * @param {number} page The page currently being viewed. |
| 1377 * @param {boolean} grouped Whether the results are grouped or not. | |
| 1378 * @param {HistoryModel.Range} range The range to view or search over. | 1374 * @param {HistoryModel.Range} range The range to view or search over. |
| 1379 * @param {number} offset Set the begining of the query to the specific offset. | 1375 * @param {number} offset Set the begining of the query to the specific offset. |
| 1380 */ | 1376 */ |
| 1381 PageState.prototype.setUIState = function(term, page, grouped, range, offset) { | 1377 PageState.prototype.setUIState = function(term, page, range, offset) { |
| 1382 // Make sure the form looks pretty. | 1378 // Make sure the form looks pretty. |
| 1383 $('search-field').value = term; | 1379 $('search-field').value = term; |
| 1384 $('group-by-domain').checked = grouped; | |
| 1385 var hash = this.getHashData(); | 1380 var hash = this.getHashData(); |
| 1386 if (hash.q != term || hash.page != page || hash.grouped != grouped || | 1381 if (hash.q != term || hash.page != page || hash.range != range || |
| 1387 hash.range != range || hash.offset != offset) { | 1382 hash.offset != offset) { |
| 1388 window.location.hash = PageState.getHashString( | 1383 window.location.hash = PageState.getHashString(term, page, range, offset); |
| 1389 term, page, grouped, range, offset); | |
| 1390 } | 1384 } |
| 1391 }; | 1385 }; |
| 1392 | 1386 |
| 1393 /** | 1387 /** |
| 1394 * Static method to get the hash string for a specified state | 1388 * Static method to get the hash string for a specified state |
| 1395 * @param {string} term The current search string. | 1389 * @param {string} term The current search string. |
| 1396 * @param {number} page The page currently being viewed. | 1390 * @param {number} page The page currently being viewed. |
| 1397 * @param {boolean} grouped Whether the results are grouped or not. | |
| 1398 * @param {HistoryModel.Range} range The range to view or search over. | 1391 * @param {HistoryModel.Range} range The range to view or search over. |
| 1399 * @param {number} offset Set the begining of the query to the specific offset. | 1392 * @param {number} offset Set the begining of the query to the specific offset. |
| 1400 * @return {string} The string to be used in a hash. | 1393 * @return {string} The string to be used in a hash. |
| 1401 */ | 1394 */ |
| 1402 PageState.getHashString = function(term, page, grouped, range, offset) { | 1395 PageState.getHashString = function(term, page, range, offset) { |
| 1403 // Omit elements that are empty. | 1396 // Omit elements that are empty. |
| 1404 var newHash = []; | 1397 var newHash = []; |
| 1405 | 1398 |
| 1406 if (term) | 1399 if (term) |
| 1407 newHash.push('q=' + encodeURIComponent(term)); | 1400 newHash.push('q=' + encodeURIComponent(term)); |
| 1408 | 1401 |
| 1409 if (page) | 1402 if (page) |
| 1410 newHash.push('page=' + page); | 1403 newHash.push('page=' + page); |
| 1411 | 1404 |
| 1412 if (grouped) | |
| 1413 newHash.push('grouped=' + grouped); | |
| 1414 | |
| 1415 if (range) | 1405 if (range) |
| 1416 newHash.push('range=' + range); | 1406 newHash.push('range=' + range); |
| 1417 | 1407 |
| 1418 if (offset) | 1408 if (offset) |
| 1419 newHash.push('offset=' + offset); | 1409 newHash.push('offset=' + offset); |
| 1420 | 1410 |
| 1421 return newHash.join('&'); | 1411 return newHash.join('&'); |
| 1422 }; | 1412 }; |
| 1423 | 1413 |
| 1424 /////////////////////////////////////////////////////////////////////////////// | 1414 /////////////////////////////////////////////////////////////////////////////// |
| 1425 // Document Functions: | 1415 // Document Functions: |
| 1426 /** | 1416 /** |
| 1427 * Window onload handler, sets up the page. | 1417 * Window onload handler, sets up the page. |
| 1428 */ | 1418 */ |
| 1429 function load() { | 1419 function load() { |
| 1430 uber.onContentFrameLoaded(); | 1420 uber.onContentFrameLoaded(); |
| 1431 | 1421 |
| 1432 var searchField = $('search-field'); | 1422 var searchField = $('search-field'); |
| 1433 | 1423 |
| 1434 historyModel = new HistoryModel(); | 1424 historyModel = new HistoryModel(); |
| 1435 historyView = new HistoryView(historyModel); | 1425 historyView = new HistoryView(historyModel); |
| 1436 pageState = new PageState(historyModel, historyView); | 1426 pageState = new PageState(historyModel, historyView); |
| 1437 | 1427 |
| 1438 // Create default view. | 1428 // Create default view. |
| 1439 var hashData = pageState.getHashData(); | 1429 var hashData = pageState.getHashData(); |
| 1440 var grouped = (hashData.grouped == 'true') || historyModel.getGroupByDomain(); | 1430 var grouped = (hashData.grouped == 'true') || historyModel.getGroupByDomain(); |
| 1441 var page = parseInt(hashData.page, 10) || historyView.getPage(); | 1431 var page = parseInt(hashData.page, 10) || historyView.getPage(); |
| 1442 var range = parseInt(hashData.range, 10) || historyView.getRangeInDays(); | 1432 var range = parseInt(hashData.range, 10) || historyView.getRangeInDays(); |
| 1443 var offset = parseInt(hashData.offset, 10) || historyView.getOffset(); | 1433 var offset = parseInt(hashData.offset, 10) || historyView.getOffset(); |
| 1444 historyView.setPageState(hashData.q, page, grouped, range, offset); | 1434 historyView.setPageState(hashData.q, page, range, offset); |
| 1445 | 1435 |
| 1446 if ($('overlay')) | 1436 if ($('overlay')) |
| 1447 cr.ui.overlay.setupOverlay($('overlay')); | 1437 cr.ui.overlay.setupOverlay($('overlay')); |
| 1448 | 1438 |
| 1449 var doSearch = function(e) { | 1439 var doSearch = function(e) { |
| 1450 // Disable the group by domain control when a search is active. | |
| 1451 $('group-by-domain').disabled = (searchField.value != ''); | |
| 1452 historyView.setSearch(searchField.value); | 1440 historyView.setSearch(searchField.value); |
| 1453 | 1441 |
| 1454 if (isMobileVersion()) | 1442 if (isMobileVersion()) |
| 1455 searchField.blur(); // Dismiss the keyboard. | 1443 searchField.blur(); // Dismiss the keyboard. |
| 1456 }; | 1444 }; |
| 1457 | 1445 |
| 1458 var mayRemoveVisits = loadTimeData.getBoolean('allowDeletingHistory'); | 1446 var mayRemoveVisits = loadTimeData.getBoolean('allowDeletingHistory'); |
| 1459 $('remove-visit').disabled = !mayRemoveVisits; | 1447 $('remove-visit').disabled = !mayRemoveVisits; |
| 1460 | 1448 |
| 1461 if (mayRemoveVisits) { | 1449 if (mayRemoveVisits) { |
| 1462 $('remove-visit').addEventListener('activate', function(e) { | 1450 $('remove-visit').addEventListener('activate', function(e) { |
| 1463 activeVisit.removeFromHistory(); | 1451 activeVisit.removeFromHistory(); |
| 1464 activeVisit = null; | 1452 activeVisit = null; |
| 1465 }); | 1453 }); |
| 1466 } | 1454 } |
| 1467 | 1455 |
| 1468 searchField.addEventListener('search', doSearch); | 1456 searchField.addEventListener('search', doSearch); |
| 1469 $('search-button').addEventListener('click', doSearch); | 1457 $('search-button').addEventListener('click', doSearch); |
| 1470 | 1458 |
| 1471 $('more-from-site').addEventListener('activate', function(e) { | 1459 $('more-from-site').addEventListener('activate', function(e) { |
| 1472 activeVisit.showMoreFromSite_(); | 1460 activeVisit.showMoreFromSite_(); |
| 1473 activeVisit = null; | 1461 activeVisit = null; |
| 1474 }); | 1462 }); |
| 1475 | 1463 |
| 1476 // Only show the controls if the command line switch is activated. | 1464 // Only show the controls if the command line switch is activated. |
| 1477 if (loadTimeData.getBoolean('groupByDomain') || | 1465 if (loadTimeData.getBoolean('groupByDomain') || |
| 1478 loadTimeData.getBoolean('isManagedProfile')) { | 1466 loadTimeData.getBoolean('isManagedProfile')) { |
| 1467 // Hide the top container which has the "Clear browsing data" and "Remove |
| 1468 // selected entries" buttons since they're unavailable in managed mode |
| 1469 $('top-container').hidden = true; |
| 1470 $('history-page').classList.add('big-topbar-page'); |
| 1479 $('filter-controls').hidden = false; | 1471 $('filter-controls').hidden = false; |
| 1480 } | 1472 } |
| 1481 | 1473 |
| 1482 var title = loadTimeData.getString('title'); | 1474 var title = loadTimeData.getString('title'); |
| 1483 uber.invokeMethodOnParent('setTitle', {title: title}); | 1475 uber.invokeMethodOnParent('setTitle', {title: title}); |
| 1484 | 1476 |
| 1485 // Adjust the position of the notification bar when the window size changes. | 1477 // Adjust the position of the notification bar when the window size changes. |
| 1486 window.addEventListener('resize', | 1478 window.addEventListener('resize', |
| 1487 historyView.positionNotificationBar.bind(historyView)); | 1479 historyView.positionNotificationBar.bind(historyView)); |
| 1488 | 1480 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1508 } else { | 1500 } else { |
| 1509 window.addEventListener('message', function(e) { | 1501 window.addEventListener('message', function(e) { |
| 1510 if (e.data.method == 'frameSelected') | 1502 if (e.data.method == 'frameSelected') |
| 1511 searchField.focus(); | 1503 searchField.focus(); |
| 1512 }); | 1504 }); |
| 1513 searchField.focus(); | 1505 searchField.focus(); |
| 1514 } | 1506 } |
| 1515 } | 1507 } |
| 1516 | 1508 |
| 1517 /** | 1509 /** |
| 1518 * Updates the whitelist status labels of a host/URL entry to the current | 1510 * Updates the managed filter status labels of a host/URL entry to the current |
| 1519 * value. | 1511 * value. |
| 1520 * @param {Element} statusElement The div which contains the status labels. | 1512 * @param {Element} statusElement The div which contains the status labels. |
| 1521 * @param {Object} newStatus A dictionary with two entries: | 1513 * @param {ManagedModeFilteringBehavior} newStatus The filter status of the |
| 1522 * - |inContentPack|: whether the current domain/URL is allowed by a | 1514 * current domain/URL. |
| 1523 * content pack. | |
| 1524 * - |manualBehavior|: The manual status of the current domain/URL. | |
| 1525 */ | 1515 */ |
| 1526 function updateHostStatus(statusElement, newStatus) { | 1516 function updateHostStatus(statusElement, newStatus) { |
| 1527 var inContentPackDiv = statusElement.querySelector('.in-content-pack'); | 1517 var filteringBehaviorDiv = |
| 1528 inContentPackDiv.className = 'in-content-pack'; | 1518 statusElement.querySelector('.filtering-behavior'); |
| 1529 | 1519 // Reset to the base class first, then add modifier classes if needed. |
| 1530 if (newStatus['inContentPack']) { | 1520 filteringBehaviorDiv.className = 'filtering-behavior'; |
| 1531 if (newStatus['manualBehavior'] != ManagedModeManualBehavior.NONE) | 1521 if (newStatus == ManagedModeFilteringBehavior.BLOCK) { |
| 1532 inContentPackDiv.classList.add('in-content-pack-passive'); | 1522 filteringBehaviorDiv.textContent = |
| 1533 else | 1523 loadTimeData.getString('filterBlocked'); |
| 1534 inContentPackDiv.classList.add('in-content-pack-active'); | 1524 filteringBehaviorDiv.classList.add('filter-blocked'); |
| 1535 } | 1525 } else { |
| 1536 | 1526 filteringBehaviorDiv.textContent = ''; |
| 1537 if ('manualBehavior' in newStatus) { | |
| 1538 var manualBehaviorDiv = statusElement.querySelector('.manual-behavior'); | |
| 1539 // Reset to the base class first, then add modifier classes if needed. | |
| 1540 manualBehaviorDiv.className = 'manual-behavior'; | |
| 1541 switch (newStatus['manualBehavior']) { | |
| 1542 case ManagedModeManualBehavior.NONE: | |
| 1543 manualBehaviorDiv.textContent = ''; | |
| 1544 break; | |
| 1545 case ManagedModeManualBehavior.ALLOW: | |
| 1546 manualBehaviorDiv.textContent = loadTimeData.getString('filterAllowed'); | |
| 1547 manualBehaviorDiv.classList.add('filter-allowed'); | |
| 1548 break; | |
| 1549 case ManagedModeManualBehavior.BLOCK: | |
| 1550 manualBehaviorDiv.textContent = loadTimeData.getString('filterBlocked'); | |
| 1551 manualBehaviorDiv.classList.add('filter-blocked'); | |
| 1552 break; | |
| 1553 } | |
| 1554 } | 1527 } |
| 1555 } | 1528 } |
| 1556 | 1529 |
| 1557 /** | 1530 /** |
| 1558 * Click handler for the 'Clear browsing data' dialog. | 1531 * Click handler for the 'Clear browsing data' dialog. |
| 1559 * @param {Event} e The click event. | 1532 * @param {Event} e The click event. |
| 1560 */ | 1533 */ |
| 1561 function openClearBrowsingData(e) { | 1534 function openClearBrowsingData(e) { |
| 1562 chrome.send('clearBrowsingData'); | 1535 chrome.send('clearBrowsingData'); |
| 1563 } | 1536 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1783 innerArrow.classList.add('expand'); | 1756 innerArrow.classList.add('expand'); |
| 1784 } else { | 1757 } else { |
| 1785 innerResultList.style.height = 0; | 1758 innerResultList.style.height = 0; |
| 1786 innerArrow.classList.remove('expand'); | 1759 innerArrow.classList.remove('expand'); |
| 1787 innerArrow.classList.add('collapse'); | 1760 innerArrow.classList.add('collapse'); |
| 1788 } | 1761 } |
| 1789 } | 1762 } |
| 1790 | 1763 |
| 1791 /** | 1764 /** |
| 1792 * Builds the DOM elements to show the managed status of a domain/URL. | 1765 * Builds the DOM elements to show the managed status of a domain/URL. |
| 1793 * @param {ManagedModeManualBehavior} manualBehavior The manual behavior for | 1766 * @param {ManagedModeFilteringBehavior} filteringBehavior The filter behavior |
| 1794 * this item. | 1767 * for this item. |
| 1795 * @param {boolean} inContentPack Whether this element is in a content pack or | |
| 1796 * not. | |
| 1797 * @return {Element} Returns the DOM elements which show the status. | 1768 * @return {Element} Returns the DOM elements which show the status. |
| 1798 */ | 1769 */ |
| 1799 function getManagedStatusDOM(manualBehavior, inContentPack) { | 1770 function getManagedStatusDOM(filteringBehavior) { |
| 1800 var filterStatusDiv = createElementWithClassName('div', 'filter-status'); | 1771 var filterStatusDiv = createElementWithClassName('div', 'filter-status'); |
| 1801 var inContentPackDiv = createElementWithClassName('div', 'in-content-pack'); | 1772 var filteringBehaviorDiv = |
| 1802 inContentPackDiv.textContent = loadTimeData.getString('inContentPack'); | 1773 createElementWithClassName('div', 'filtering-behavior'); |
| 1803 var manualBehaviorDiv = createElementWithClassName('div', 'manual-behavior'); | 1774 filterStatusDiv.appendChild(filteringBehaviorDiv); |
| 1804 filterStatusDiv.appendChild(inContentPackDiv); | |
| 1805 filterStatusDiv.appendChild(manualBehaviorDiv); | |
| 1806 | 1775 |
| 1807 updateHostStatus(filterStatusDiv, { | 1776 updateHostStatus(filterStatusDiv, filteringBehavior); |
| 1808 'inContentPack' : inContentPack, | |
| 1809 'manualBehavior' : manualBehavior | |
| 1810 }); | |
| 1811 return filterStatusDiv; | 1777 return filterStatusDiv; |
| 1812 } | 1778 } |
| 1813 | 1779 |
| 1814 | 1780 |
| 1815 /////////////////////////////////////////////////////////////////////////////// | 1781 /////////////////////////////////////////////////////////////////////////////// |
| 1816 // Chrome callbacks: | 1782 // Chrome callbacks: |
| 1817 | 1783 |
| 1818 /** | 1784 /** |
| 1819 * Our history system calls this function with results from searches. | 1785 * Our history system calls this function with results from searches. |
| 1820 * @param {Object} info An object containing information about the query. | 1786 * @param {Object} info An object containing information about the query. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1849 historyView.reload(); | 1815 historyView.reload(); |
| 1850 } | 1816 } |
| 1851 | 1817 |
| 1852 // Add handlers to HTML elements. | 1818 // Add handlers to HTML elements. |
| 1853 document.addEventListener('DOMContentLoaded', load); | 1819 document.addEventListener('DOMContentLoaded', load); |
| 1854 | 1820 |
| 1855 // This event lets us enable and disable menu items before the menu is shown. | 1821 // This event lets us enable and disable menu items before the menu is shown. |
| 1856 document.addEventListener('canExecute', function(e) { | 1822 document.addEventListener('canExecute', function(e) { |
| 1857 e.canExecute = true; | 1823 e.canExecute = true; |
| 1858 }); | 1824 }); |
| OLD | NEW |