 Chromium Code Reviews
 Chromium Code Reviews Issue 11886104:
  History: Add range navigation control for grouped visits  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 11886104:
  History: Add range navigation control for grouped visits  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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 /** @const */ var RESULTS_MAX_LIMIT = 2000; | 10 /** @const */ var RESULTS_MAX_LIMIT = 2000; | 
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 }; | 351 }; | 
| 352 | 352 | 
| 353 /** | 353 /** | 
| 354 * Reload our model with the current parameters. | 354 * Reload our model with the current parameters. | 
| 355 */ | 355 */ | 
| 356 HistoryModel.prototype.reload = function() { | 356 HistoryModel.prototype.reload = function() { | 
| 357 // Save user-visible state, clear the model, and restore the state. | 357 // Save user-visible state, clear the model, and restore the state. | 
| 358 var search = this.searchText_; | 358 var search = this.searchText_; | 
| 359 var page = this.requestedPage_; | 359 var page = this.requestedPage_; | 
| 360 var range = this.rangeInDays_; | 360 var range = this.rangeInDays_; | 
| 361 var offset = this.offset_; | |
| 361 var groupByDomain = this.groupByDomain_; | 362 var groupByDomain = this.groupByDomain_; | 
| 362 | 363 | 
| 363 this.clearModel_(); | 364 this.clearModel_(); | 
| 364 this.searchText_ = search; | 365 this.searchText_ = search; | 
| 365 this.requestedPage_ = page; | 366 this.requestedPage_ = page; | 
| 366 this.rangeInDays_ = range; | 367 this.rangeInDays_ = range; | 
| 368 this.offset_ = offset; | |
| 367 this.groupByDomain_ = groupByDomain; | 369 this.groupByDomain_ = groupByDomain; | 
| 368 this.queryHistory_(); | 370 this.queryHistory_(); | 
| 369 }; | 371 }; | 
| 370 | 372 | 
| 371 /** | 373 /** | 
| 372 * @return {string} The current search text. | 374 * @return {string} The current search text. | 
| 373 */ | 375 */ | 
| 374 HistoryModel.prototype.getSearchText = function() { | 376 HistoryModel.prototype.getSearchText = function() { | 
| 375 return this.searchText_; | 377 return this.searchText_; | 
| 376 }; | 378 }; | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 // Getter and setter for HistoryModel.rangeInDays_. | 474 // Getter and setter for HistoryModel.rangeInDays_. | 
| 473 Object.defineProperty(HistoryModel.prototype, 'rangeInDays', { | 475 Object.defineProperty(HistoryModel.prototype, 'rangeInDays', { | 
| 474 get: function() { | 476 get: function() { | 
| 475 return this.rangeInDays_; | 477 return this.rangeInDays_; | 
| 476 }, | 478 }, | 
| 477 set: function(range) { | 479 set: function(range) { | 
| 478 this.rangeInDays_ = range; | 480 this.rangeInDays_ = range; | 
| 479 } | 481 } | 
| 480 }); | 482 }); | 
| 481 | 483 | 
| 484 /** | |
| 485 * Getter and setter for HistoryModel.offset_. The offset moves the current | |
| 486 * query 'window' |range| days behind. As such for range set to WEEK an offset | |
| 487 * of 0 refers to the last 7 days, an offset of 1 refers to the 7 day period | |
| 488 * that ended 7 days ago, etc. For MONTH an offset of 0 refers to the current | |
| 489 * calendar month, 1 to the previous one, etc. | |
| 490 */ | |
| 491 Object.defineProperty(HistoryModel.prototype, 'offset', { | |
| 492 get: function() { | |
| 493 return this.offset_; | |
| 494 }, | |
| 495 set: function(offset) { | |
| 496 this.offset_ = offset; | |
| 497 } | |
| 498 }); | |
| 499 | |
| 482 // HistoryModel, Private: ----------------------------------------------------- | 500 // HistoryModel, Private: ----------------------------------------------------- | 
| 483 | 501 | 
| 484 /** | 502 /** | 
| 485 * Clear the history model. | 503 * Clear the history model. | 
| 486 * @private | 504 * @private | 
| 487 */ | 505 */ | 
| 488 HistoryModel.prototype.clearModel_ = function() { | 506 HistoryModel.prototype.clearModel_ = function() { | 
| 489 this.inFlight_ = false; // Whether a query is inflight. | 507 this.inFlight_ = false; // Whether a query is inflight. | 
| 490 this.searchText_ = ''; | 508 this.searchText_ = ''; | 
| 491 // Flag to show that the results are grouped by domain or not. | 509 // Flag to show that the results are grouped by domain or not. | 
| 492 this.groupByDomain_ = false; | 510 this.groupByDomain_ = false; | 
| 493 | 511 | 
| 494 this.visits_ = []; // Date-sorted list of visits (most recent first). | 512 this.visits_ = []; // Date-sorted list of visits (most recent first). | 
| 495 this.last_id_ = 0; | 513 this.last_id_ = 0; | 
| 496 selectionAnchor = -1; | 514 selectionAnchor = -1; | 
| 497 | 515 | 
| 498 // The page that the view wants to see - we only fetch slightly past this | 516 // The page that the view wants to see - we only fetch slightly past this | 
| 499 // point. If the view requests a page that we don't have data for, we try | 517 // point. If the view requests a page that we don't have data for, we try | 
| 500 // to fetch it and call back when we're done. | 518 // to fetch it and call back when we're done. | 
| 501 this.requestedPage_ = 0; | 519 this.requestedPage_ = 0; | 
| 502 | 520 | 
| 521 // Skip |offset_| * weeks/months from the begining. | |
| 522 this.offset_ = 0; | |
| 523 | |
| 503 // The range of history to view or search over, WEEK by default. | 524 // The range of history to view or search over, WEEK by default. | 
| 504 this.rangeInDays_ = HistoryModel.Range.RECENT; | 525 this.rangeInDays_ = HistoryModel.Range.RECENT; | 
| 505 | 526 | 
| 506 // Keeps track of whether or not there are more results available than are | 527 // Keeps track of whether or not there are more results available than are | 
| 507 // currently held in |this.visits_|. | 528 // currently held in |this.visits_|. | 
| 508 this.isQueryFinished_ = false; | 529 this.isQueryFinished_ = false; | 
| 509 | 530 | 
| 510 // An opaque value that is returned with the query results. This is used to | 531 // An opaque value that is returned with the query results. This is used to | 
| 511 // fetch the next page of results for a query. | 532 // fetch the next page of results for a query. | 
| 512 this.queryCursor_ = null; | 533 this.queryCursor_ = null; | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 540 | 561 | 
| 541 // Show the result or a message if no results were returned. | 562 // Show the result or a message if no results were returned. | 
| 542 this.view_.onModelReady(); | 563 this.view_.onModelReady(); | 
| 543 }; | 564 }; | 
| 544 | 565 | 
| 545 /** | 566 /** | 
| 546 * Query for history, either for a search or time-based browsing. | 567 * Query for history, either for a search or time-based browsing. | 
| 547 * @private | 568 * @private | 
| 548 */ | 569 */ | 
| 549 HistoryModel.prototype.queryHistory_ = function() { | 570 HistoryModel.prototype.queryHistory_ = function() { | 
| 550 // Set the range to the values from the interface. | 571 // Set the range and offset to the values from the interface. | 
| 572 var offset = this.offset_; | |
| 551 var range = this.rangeInDays_; | 573 var range = this.rangeInDays_; | 
| 552 | 574 | 
| 553 $('loading-spinner').hidden = false; | 575 $('loading-spinner').hidden = false; | 
| 554 this.inFlight_ = true; | 576 this.inFlight_ = true; | 
| 555 chrome.send('queryHistory', | 577 chrome.send('queryHistory', | 
| 556 [this.searchText_, range, this.queryCursor_, this.getMaxResults()]); | 578 [this.searchText_, offset, range, this.queryCursor_, | 
| 579 this.getMaxResults()]); | |
| 557 }; | 580 }; | 
| 558 | 581 | 
| 559 /** | 582 /** | 
| 560 * Check to see if we have data for the given page. | 583 * Check to see if we have data for the given page. | 
| 561 * @param {number} page The page number. | 584 * @param {number} page The page number. | 
| 562 * @return {boolean} Whether we have any data for the given page. | 585 * @return {boolean} Whether we have any data for the given page. | 
| 563 * @private | 586 * @private | 
| 564 */ | 587 */ | 
| 565 HistoryModel.prototype.haveDataForPage_ = function(page) { | 588 HistoryModel.prototype.haveDataForPage_ = function(page) { | 
| 566 return (page * this.getMaxResults() < this.getSize()); | 589 return (page * this.getMaxResults() < this.getSize()); | 
| 567 }; | 590 }; | 
| 568 | 591 | 
| 569 /** | 592 /** | 
| 570 * Check to see if we have data to fill the given page. | 593 * Check to see if we have data to fill the given page. | 
| 571 * @param {number} page The page number. | 594 * @param {number} page The page number. | 
| 572 * @return {boolean} Whether we have data to fill the page. | 595 * @return {boolean} Whether we have data to fill the page. | 
| 573 * @private | 596 * @private | 
| 574 */ | 597 */ | 
| 575 HistoryModel.prototype.canFillPage_ = function(page) { | 598 HistoryModel.prototype.canFillPage_ = function(page) { | 
| 576 return ((page + 1) * this.getMaxResults() <= this.getSize()); | 599 return ((page + 1) * this.getMaxResults() <= this.getSize()); | 
| 577 }; | 600 }; | 
| 578 | 601 | 
| 579 /** | 602 /** | 
| 580 * Enables or disables grouping by domain. | 603 * Enables or disables grouping by domain. | 
| 581 * @param {boolean} groupByDomain New groupByDomain_ value. | 604 * @param {boolean} groupByDomain New groupByDomain_ value. | 
| 582 */ | 605 */ | 
| 583 HistoryModel.prototype.setGroupByDomain = function(groupByDomain) { | 606 HistoryModel.prototype.setGroupByDomain = function(groupByDomain) { | 
| 584 this.groupByDomain_ = groupByDomain; | 607 this.groupByDomain_ = groupByDomain; | 
| 608 this.offset_ = 0; | |
| 585 }; | 609 }; | 
| 586 | 610 | 
| 587 /** | 611 /** | 
| 588 * Gets whether we are grouped by domain. | 612 * Gets whether we are grouped by domain. | 
| 589 * @return {boolean} Whether the results are grouped by domain. | 613 * @return {boolean} Whether the results are grouped by domain. | 
| 590 */ | 614 */ | 
| 591 HistoryModel.prototype.getGroupByDomain = function() { | 615 HistoryModel.prototype.getGroupByDomain = function() { | 
| 592 return this.groupByDomain_; | 616 return this.groupByDomain_; | 
| 593 }; | 617 }; | 
| 594 | 618 | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 632 }); | 656 }); | 
| 633 | 657 | 
| 634 // Add handlers for the range options. | 658 // Add handlers for the range options. | 
| 635 $('timeframe-filter').addEventListener('change', function(e) { | 659 $('timeframe-filter').addEventListener('change', function(e) { | 
| 636 self.setRangeInDays(parseInt(e.target.value, 10)); | 660 self.setRangeInDays(parseInt(e.target.value, 10)); | 
| 637 }); | 661 }); | 
| 638 | 662 | 
| 639 $('display-filter-sites').addEventListener('click', function(e) { | 663 $('display-filter-sites').addEventListener('click', function(e) { | 
| 640 self.setGroupByDomain($('display-filter-sites').checked); | 664 self.setGroupByDomain($('display-filter-sites').checked); | 
| 641 }); | 665 }); | 
| 666 | |
| 667 $('range-previous').addEventListener('click', function(e) { | |
| 668 self.setOffset(self.getOffset() + 1); | |
| 669 }); | |
| 670 $('range-next').addEventListener('click', function(e) { | |
| 671 self.setOffset(self.getOffset() - 1); | |
| 672 }); | |
| 673 $('range-today').addEventListener('click', function(e) { | |
| 674 self.setOffset(0); | |
| 675 }); | |
| 642 } | 676 } | 
| 643 | 677 | 
| 644 // HistoryView, public: ------------------------------------------------------- | 678 // HistoryView, public: ------------------------------------------------------- | 
| 645 /** | 679 /** | 
| 646 * Do a search and optionally view a certain page. | 680 * Do a search and optionally view a certain page. | 
| 647 * @param {string} term The string to search for. | 681 * @param {string} term The string to search for. | 
| 648 * @param {number} opt_page The page we wish to view, only use this for | 682 * @param {number} opt_page The page we wish to view, only use this for | 
| 649 * setting up initial views, as this triggers a search. | 683 * setting up initial views, as this triggers a search. | 
| 650 */ | 684 */ | 
| 651 HistoryView.prototype.setSearch = function(term, opt_page) { | 685 HistoryView.prototype.setSearch = function(term, opt_page) { | 
| 652 this.pageIndex_ = parseInt(opt_page || 0, 10); | 686 this.pageIndex_ = parseInt(opt_page || 0, 10); | 
| 653 window.scrollTo(0, 0); | 687 window.scrollTo(0, 0); | 
| 654 this.model_.setSearchText(term, this.pageIndex_); | 688 this.model_.setSearchText(term, this.pageIndex_); | 
| 655 pageState.setUIState(term, this.pageIndex_, this.model_.getGroupByDomain(), | 689 pageState.setUIState(term, this.pageIndex_, this.model_.getGroupByDomain(), | 
| 656 this.getRangeInDays()); | 690 this.getRangeInDays(), this.getOffset()); | 
| 657 }; | 691 }; | 
| 658 | 692 | 
| 659 /** | 693 /** | 
| 660 * Enable or disable results as being grouped by domain. | 694 * Enable or disable results as being grouped by domain. | 
| 661 * @param {boolean} groupedByDomain Whether to group by domain or not. | 695 * @param {boolean} groupedByDomain Whether to group by domain or not. | 
| 662 */ | 696 */ | 
| 663 HistoryView.prototype.setGroupByDomain = function(groupedByDomain) { | 697 HistoryView.prototype.setGroupByDomain = function(groupedByDomain) { | 
| 664 // Group by domain is not currently supported for search results, so reset | 698 // Group by domain is not currently supported for search results, so reset | 
| 665 // the search term if there was one. | 699 // the search term if there was one. | 
| 666 this.model_.clearSearchText(); | 700 this.model_.clearSearchText(); | 
| 667 this.model_.setGroupByDomain(groupedByDomain); | 701 this.model_.setGroupByDomain(groupedByDomain); | 
| 668 this.model_.reload(); | 702 this.model_.reload(); | 
| 669 pageState.setUIState(this.model_.getSearchText(), | 703 pageState.setUIState(this.model_.getSearchText(), | 
| 670 this.pageIndex_, | 704 this.pageIndex_, | 
| 671 this.model_.getGroupByDomain(), | 705 this.model_.getGroupByDomain(), | 
| 672 this.getRangeInDays()); | 706 this.getRangeInDays(), | 
| 707 this.getOffset()); | |
| 673 }; | 708 }; | 
| 674 | 709 | 
| 675 /** | 710 /** | 
| 676 * Reload the current view. | 711 * Reload the current view. | 
| 677 */ | 712 */ | 
| 678 HistoryView.prototype.reload = function() { | 713 HistoryView.prototype.reload = function() { | 
| 679 this.model_.reload(); | 714 this.model_.reload(); | 
| 680 this.updateRemoveButton(); | 715 this.updateRemoveButton(); | 
| 681 }; | 716 }; | 
| 682 | 717 | 
| 683 /** | 718 /** | 
| 684 * Switch to a specified page. | 719 * Switch to a specified page. | 
| 685 * @param {number} page The page we wish to view. | 720 * @param {number} page The page we wish to view. | 
| 686 */ | 721 */ | 
| 687 HistoryView.prototype.setPage = function(page) { | 722 HistoryView.prototype.setPage = function(page) { | 
| 688 this.clear_(); | 723 this.clear_(); | 
| 689 this.pageIndex_ = parseInt(page, 10); | 724 this.pageIndex_ = parseInt(page, 10); | 
| 690 window.scrollTo(0, 0); | 725 window.scrollTo(0, 0); | 
| 691 this.model_.requestPage(page); | 726 this.model_.requestPage(page); | 
| 692 pageState.setUIState(this.model_.getSearchText(), | 727 pageState.setUIState(this.model_.getSearchText(), | 
| 693 this.pageIndex_, | 728 this.pageIndex_, | 
| 694 this.model_.getGroupByDomain(), | 729 this.model_.getGroupByDomain(), | 
| 695 this.getRangeInDays()); | 730 this.getRangeInDays(), | 
| 731 this.getOffset()); | |
| 696 }; | 732 }; | 
| 697 | 733 | 
| 698 /** | 734 /** | 
| 699 * @return {number} The page number being viewed. | 735 * @return {number} The page number being viewed. | 
| 700 */ | 736 */ | 
| 701 HistoryView.prototype.getPage = function() { | 737 HistoryView.prototype.getPage = function() { | 
| 702 return this.pageIndex_; | 738 return this.pageIndex_; | 
| 703 }; | 739 }; | 
| 704 | 740 | 
| 705 /** | 741 /** | 
| 706 * Set the current range for grouped results. | 742 * Set the current range for grouped results. | 
| 707 * @param {string} range The number of days to which the range should be set. | 743 * @param {string} range The number of days to which the range should be set. | 
| 708 */ | 744 */ | 
| 709 HistoryView.prototype.setRangeInDays = function(range) { | 745 HistoryView.prototype.setRangeInDays = function(range) { | 
| 710 // Set the range and reset the page | 746 // Set the range offset and reset the page | 
| 711 this.model_.rangeInDays = range; | 747 this.model_.rangeInDays = range; | 
| 748 this.model_.offset = 0; | |
| 712 this.pageIndex_ = 0; | 749 this.pageIndex_ = 0; | 
| 713 this.model_.reload(); | 750 this.model_.reload(); | 
| 714 pageState.setUIState(this.model_.getSearchText(), this.pageIndex_, | 751 pageState.setUIState(this.model_.getSearchText(), this.pageIndex_, | 
| 715 this.model_.getGroupByDomain(), range); | 752 this.model_.getGroupByDomain(), range, this.getOffset()); | 
| 716 }; | 753 }; | 
| 717 | 754 | 
| 718 /** | 755 /** | 
| 719 * Get the current range in days. | 756 * Get the current range in days. | 
| 720 * @return {number} Current range in days from the model. | 757 * @return {number} Current range in days from the model. | 
| 721 */ | 758 */ | 
| 722 HistoryView.prototype.getRangeInDays = function() { | 759 HistoryView.prototype.getRangeInDays = function() { | 
| 723 return this.model_.rangeInDays; | 760 return this.model_.rangeInDays; | 
| 724 }; | 761 }; | 
| 725 | 762 | 
| 726 /** | 763 /** | 
| 764 * Set the current offset for grouped results. | |
| 765 * @param {number} offset Offset to set. | |
| 766 */ | |
| 767 HistoryView.prototype.setOffset = function(offset) { | |
| 768 window.scrollTo(0, 0); | |
| 
Patrick Dubroy
2013/01/30 23:25:33
I'm having deja vu...I swear I wrote this comment
 | |
| 769 this.model_.offset = offset; | |
| 770 this.model_.reload(); | |
| 771 pageState.setUIState(this.model_.getSearchText(), | |
| 772 this.pageIndex_, | |
| 773 this.model_.getGroupByDomain(), | |
| 774 this.getRangeInDays(), | |
| 775 this.getOffset()); | |
| 776 }; | |
| 777 | |
| 778 /** | |
| 779 * Get the current offset. | |
| 780 * @return {number} Current offset from the model. | |
| 781 */ | |
| 782 HistoryView.prototype.getOffset = function() { | |
| 783 return this.model_.offset; | |
| 784 }; | |
| 785 | |
| 786 /** | |
| 727 * Callback for the history model to let it know that it has data ready for us | 787 * Callback for the history model to let it know that it has data ready for us | 
| 728 * to view. | 788 * to view. | 
| 729 */ | 789 */ | 
| 730 HistoryView.prototype.onModelReady = function() { | 790 HistoryView.prototype.onModelReady = function() { | 
| 731 this.displayResults_(); | 791 this.displayResults_(); | 
| 732 this.updateNavBar_(); | 792 this.updateNavBar_(); | 
| 733 }; | 793 }; | 
| 734 | 794 | 
| 735 /** | 795 /** | 
| 736 * Enables or disables the 'Remove selected items' button as appropriate. | 796 * Enables or disables the 'Remove selected items' button as appropriate. | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 var isMonthGroupedResult = this.getRangeInDays() == HistoryModel.Range.MONTH; | 867 var isMonthGroupedResult = this.getRangeInDays() == HistoryModel.Range.MONTH; | 
| 808 for (var j = 0, visit; visit = domainVisits[j]; j++) { | 868 for (var j = 0, visit; visit = domainVisits[j]; j++) { | 
| 809 resultsList.appendChild(visit.getResultDOM({ | 869 resultsList.appendChild(visit.getResultDOM({ | 
| 810 useMonthDate: isMonthGroupedResult | 870 useMonthDate: isMonthGroupedResult | 
| 811 })); | 871 })); | 
| 812 this.setVisitRendered_(visit); | 872 this.setVisitRendered_(visit); | 
| 813 } | 873 } | 
| 814 }; | 874 }; | 
| 815 | 875 | 
| 816 /** | 876 /** | 
| 877 * Enables or disables the time range buttons. | |
| 878 * @private | |
| 879 */ | |
| 880 HistoryView.prototype.setRangeButtonsState_ = function() { | |
| 
Patrick Dubroy
2013/01/30 23:25:33
I think "updateRangeButtons_" would be a slightly
 | |
| 881 // The enabled state for the previous, today and next buttons. | |
| 882 var buttonsState = [false, false, false]; | |
| 
Patrick Dubroy
2013/01/30 23:25:33
What do you need this array for? Why can't you jus
 | |
| 883 var start = 0; | |
| 884 var enableButtons = (this.getRangeInDays() != HistoryModel.Range.RECENT); | |
| 885 var offset = this.getOffset(); | |
| 886 | |
| 887 // Set today button. | |
| 888 if (offset != start) { | |
| 889 buttonsState[2] = true; | |
| 890 buttonsState[1] = true; | |
| 891 } | |
| 892 | |
| 893 buttonsState[0] = !this.model_.isQueryFinished_; | |
| 894 | |
| 895 $('range-previous').disabled = !(enableButtons && buttonsState[0]); | |
| 896 $('range-today').disabled = !(enableButtons && buttonsState[1]); | |
| 897 $('range-next').disabled = !(enableButtons && buttonsState[2]); | |
| 898 }; | |
| 899 | |
| 900 /** | |
| 817 * Groups visits by domain, sorting them by the number of visits. | 901 * Groups visits by domain, sorting them by the number of visits. | 
| 818 * @param {Array} visits Visits received from the query results. | 902 * @param {Array} visits Visits received from the query results. | 
| 819 * @param {Element} results Object where the results are added to. | 903 * @param {Element} results Object where the results are added to. | 
| 820 * @private | 904 * @private | 
| 821 */ | 905 */ | 
| 822 HistoryView.prototype.groupVisitsByDomain_ = function(visits, results) { | 906 HistoryView.prototype.groupVisitsByDomain_ = function(visits, results) { | 
| 823 var visitsByDomain = {}; | 907 var visitsByDomain = {}; | 
| 824 var domains = []; | 908 var domains = []; | 
| 825 | 909 | 
| 826 // Group the visits into a dictionary and generate a list of domains. | 910 // Group the visits into a dictionary and generate a list of domains. | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 947 createElementWithClassName('h2', 'timeframe')); | 1031 createElementWithClassName('h2', 'timeframe')); | 
| 948 timeFrame.appendChild(document.createTextNode(loadTimeData.getStringF( | 1032 timeFrame.appendChild(document.createTextNode(loadTimeData.getStringF( | 
| 949 'historyinterval', | 1033 'historyinterval', | 
| 950 this.model_.queryStartTime, | 1034 this.model_.queryStartTime, | 
| 951 this.model_.queryEndTime))); | 1035 this.model_.queryEndTime))); | 
| 952 } | 1036 } | 
| 953 | 1037 | 
| 954 if (results.length == 0) { | 1038 if (results.length == 0) { | 
| 955 var noResults = document.createElement('div'); | 1039 var noResults = document.createElement('div'); | 
| 956 noResults.textContent = loadTimeData.getString('noresults'); | 1040 noResults.textContent = loadTimeData.getString('noresults'); | 
| 957 this.resultDiv_.appendChild(noResults); | 1041 resultsFragment.appendChild(noResults); | 
| 1042 this.resultDiv_.appendChild(resultsFragment); | |
| 958 this.updateNavBar_(); | 1043 this.updateNavBar_(); | 
| 959 return; | 1044 return; | 
| 960 } | 1045 } | 
| 961 | 1046 | 
| 962 if (this.getRangeInDays() == HistoryModel.Range.MONTH && | 1047 if (this.getRangeInDays() == HistoryModel.Range.MONTH && | 
| 963 groupByDomain) { | 1048 groupByDomain) { | 
| 964 // Group everything together in the month view. | 1049 // Group everything together in the month view. | 
| 965 this.addMonthResults_(results, resultsFragment); | 1050 this.addMonthResults_(results, resultsFragment); | 
| 966 } else { | 1051 } else { | 
| 967 var dayStart = 0; | 1052 var dayStart = 0; | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 984 this.resultDiv_.appendChild(resultsFragment); | 1069 this.resultDiv_.appendChild(resultsFragment); | 
| 985 } | 1070 } | 
| 986 this.updateNavBar_(); | 1071 this.updateNavBar_(); | 
| 987 }; | 1072 }; | 
| 988 | 1073 | 
| 989 /** | 1074 /** | 
| 990 * Update the visibility of the page navigation buttons. | 1075 * Update the visibility of the page navigation buttons. | 
| 991 * @private | 1076 * @private | 
| 992 */ | 1077 */ | 
| 993 HistoryView.prototype.updateNavBar_ = function() { | 1078 HistoryView.prototype.updateNavBar_ = function() { | 
| 1079 this.setRangeButtonsState_(); | |
| 994 $('newest-button').hidden = this.pageIndex_ == 0; | 1080 $('newest-button').hidden = this.pageIndex_ == 0; | 
| 995 $('newer-button').hidden = this.pageIndex_ == 0; | 1081 $('newer-button').hidden = this.pageIndex_ == 0; | 
| 996 $('older-button').hidden = | 1082 $('older-button').hidden = | 
| 997 this.model_.rangeInDays_ != HistoryModel.Range.RECENT || | 1083 this.model_.rangeInDays_ != HistoryModel.Range.RECENT || | 
| 998 !this.model_.hasMoreResults(); | 1084 !this.model_.hasMoreResults(); | 
| 999 }; | 1085 }; | 
| 1000 | 1086 | 
| 1001 /////////////////////////////////////////////////////////////////////////////// | 1087 /////////////////////////////////////////////////////////////////////////////// | 
| 1002 // State object: | 1088 // State object: | 
| 1003 /** | 1089 /** | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1025 var hashData = state_obj.getHashData(); | 1111 var hashData = state_obj.getHashData(); | 
| 1026 var isGroupedByDomain = (hashData.g == 'true'); | 1112 var isGroupedByDomain = (hashData.g == 'true'); | 
| 1027 if (hashData.q != state_obj.model.getSearchText()) { | 1113 if (hashData.q != state_obj.model.getSearchText()) { | 
| 1028 state_obj.view.setSearch(hashData.q, parseInt(hashData.p, 10)); | 1114 state_obj.view.setSearch(hashData.q, parseInt(hashData.p, 10)); | 
| 1029 } else if (parseInt(hashData.p, 10) != state_obj.view.getPage()) { | 1115 } else if (parseInt(hashData.p, 10) != state_obj.view.getPage()) { | 
| 1030 state_obj.view.setPage(hashData.p); | 1116 state_obj.view.setPage(hashData.p); | 
| 1031 } else if (isGroupedByDomain != state_obj.view.model_.getGroupByDomain()) { | 1117 } else if (isGroupedByDomain != state_obj.view.model_.getGroupByDomain()) { | 
| 1032 state_obj.view.setGroupByDomain(isGroupedByDomain); | 1118 state_obj.view.setGroupByDomain(isGroupedByDomain); | 
| 1033 } else if (parseInt(hashData.r, 10) != state_obj.model.rangeInDays) { | 1119 } else if (parseInt(hashData.r, 10) != state_obj.model.rangeInDays) { | 
| 1034 state_obj.view.setRangeInDays(parseInt(hashData.r, 10)); | 1120 state_obj.view.setRangeInDays(parseInt(hashData.r, 10)); | 
| 1121 } else if (parseInt(hashData.o, 10) != state_obj.model.offset) { | |
| 1122 state_obj.view.setOffset(parseInt(hashData.o, 10)); | |
| 1035 } | 1123 } | 
| 1036 }), 50, this); | 1124 }), 50, this); | 
| 1037 } | 1125 } | 
| 1038 | 1126 | 
| 1039 /** | 1127 /** | 
| 1040 * Holds the singleton instance. | 1128 * Holds the singleton instance. | 
| 1041 */ | 1129 */ | 
| 1042 PageState.instance = null; | 1130 PageState.instance = null; | 
| 1043 | 1131 | 
| 1044 /** | 1132 /** | 
| 1045 * @return {Object} An object containing parameters from our window hash. | 1133 * @return {Object} An object containing parameters from our window hash. | 
| 1046 */ | 1134 */ | 
| 1047 PageState.prototype.getHashData = function() { | 1135 PageState.prototype.getHashData = function() { | 
| 1048 var result = { | 1136 var result = { | 
| 1049 e: 0, | 1137 e: 0, | 
| 1050 q: '', | 1138 q: '', | 
| 1051 p: 0, | 1139 p: 0, | 
| 1052 g: false, | 1140 g: false, | 
| 1053 r: 0 | 1141 r: 0, | 
| 1142 o: 0 | |
| 1054 }; | 1143 }; | 
| 1055 | 1144 | 
| 1056 if (!window.location.hash) | 1145 if (!window.location.hash) | 
| 1057 return result; | 1146 return result; | 
| 1058 | 1147 | 
| 1059 var hashSplit = window.location.hash.substr(1).split('&'); | 1148 var hashSplit = window.location.hash.substr(1).split('&'); | 
| 1060 for (var i = 0; i < hashSplit.length; i++) { | 1149 for (var i = 0; i < hashSplit.length; i++) { | 
| 1061 var pair = hashSplit[i].split('='); | 1150 var pair = hashSplit[i].split('='); | 
| 1062 if (pair.length > 1) { | 1151 if (pair.length > 1) { | 
| 1063 result[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); | 1152 result[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); | 
| 1064 } | 1153 } | 
| 1065 } | 1154 } | 
| 1066 | 1155 | 
| 1067 return result; | 1156 return result; | 
| 1068 }; | 1157 }; | 
| 1069 | 1158 | 
| 1070 /** | 1159 /** | 
| 1071 * Set the hash to a specified state, this will create an entry in the | 1160 * Set the hash to a specified state, this will create an entry in the | 
| 1072 * session history so the back button cycles through hash states, which | 1161 * session history so the back button cycles through hash states, which | 
| 1073 * are then picked up by our listener. | 1162 * are then picked up by our listener. | 
| 1074 * @param {string} term The current search string. | 1163 * @param {string} term The current search string. | 
| 1075 * @param {number} page The page currently being viewed. | 1164 * @param {number} page The page currently being viewed. | 
| 1076 * @param {boolean} grouped Whether the results are grouped or not. | 1165 * @param {boolean} grouped Whether the results are grouped or not. | 
| 1077 * @param {number} range The range in days to view or search over. If 0, use | 1166 * @param {number} range The range in days to view or search over. If 0, use | 
| 1078 * the entire history. | 1167 * the entire history. | 
| 1168 * @param {number} offset Set the begining of the query to range * offset days. | |
| 1079 */ | 1169 */ | 
| 1080 PageState.prototype.setUIState = function(term, page, grouped, range) { | 1170 PageState.prototype.setUIState = function(term, page, grouped, range, offset) { | 
| 1081 // Make sure the form looks pretty. | 1171 // Make sure the form looks pretty. | 
| 1082 $('search-field').value = term; | 1172 $('search-field').value = term; | 
| 1083 if (grouped) | 1173 if (grouped) | 
| 1084 $('display-filter-sites').checked = true; | 1174 $('display-filter-sites').checked = true; | 
| 1085 else | 1175 else | 
| 1086 $('display-filter-sites').checked = false; | 1176 $('display-filter-sites').checked = false; | 
| 1087 var hash = this.getHashData(); | 1177 var hash = this.getHashData(); | 
| 1088 if (hash.q != term || hash.p != page || hash.g != grouped || | 1178 if (hash.q != term || hash.p != page || hash.g != grouped || | 
| 1089 hash.r != range) { | 1179 hash.r != range || hash.o != offset) { | 
| 1090 window.location.hash = PageState.getHashString( | 1180 window.location.hash = PageState.getHashString( | 
| 1091 term, page, grouped, range); | 1181 term, page, grouped, range, offset); | 
| 1092 } | 1182 } | 
| 1093 }; | 1183 }; | 
| 1094 | 1184 | 
| 1095 /** | 1185 /** | 
| 1096 * Static method to get the hash string for a specified state | 1186 * Static method to get the hash string for a specified state | 
| 1097 * @param {string} term The current search string. | 1187 * @param {string} term The current search string. | 
| 1098 * @param {number} page The page currently being viewed. | 1188 * @param {number} page The page currently being viewed. | 
| 1099 * @param {boolean} grouped Whether the results are grouped or not. | 1189 * @param {boolean} grouped Whether the results are grouped or not. | 
| 1100 * @param {number} range The range in days to view or search over. | 1190 * @param {number} range The range in days to view or search over. | 
| 1191 * @param {number} offset Set the begining of the query to range * offset days. | |
| 1101 * @return {string} The string to be used in a hash. | 1192 * @return {string} The string to be used in a hash. | 
| 1102 */ | 1193 */ | 
| 1103 PageState.getHashString = function(term, page, grouped, range) { | 1194 PageState.getHashString = function(term, page, grouped, range, offset) { | 
| 1104 // Omit elements that are empty. | 1195 // Omit elements that are empty. | 
| 1105 var newHash = []; | 1196 var newHash = []; | 
| 1106 | 1197 | 
| 1107 if (term) | 1198 if (term) | 
| 1108 newHash.push('q=' + encodeURIComponent(term)); | 1199 newHash.push('q=' + encodeURIComponent(term)); | 
| 1109 | 1200 | 
| 1110 if (page) | 1201 if (page) | 
| 1111 newHash.push('p=' + page); | 1202 newHash.push('p=' + page); | 
| 1112 | 1203 | 
| 1113 if (grouped) | 1204 if (grouped) | 
| 1114 newHash.push('g=' + grouped); | 1205 newHash.push('g=' + grouped); | 
| 1115 | 1206 | 
| 1116 if (range) | 1207 if (range) | 
| 1117 newHash.push('r=' + range); | 1208 newHash.push('r=' + range); | 
| 1118 | 1209 | 
| 1210 if (offset) | |
| 1211 newHash.push('o=' + offset); | |
| 1212 | |
| 1119 return newHash.join('&'); | 1213 return newHash.join('&'); | 
| 1120 }; | 1214 }; | 
| 1121 | 1215 | 
| 1122 /////////////////////////////////////////////////////////////////////////////// | 1216 /////////////////////////////////////////////////////////////////////////////// | 
| 1123 // Document Functions: | 1217 // Document Functions: | 
| 1124 /** | 1218 /** | 
| 1125 * Window onload handler, sets up the page. | 1219 * Window onload handler, sets up the page. | 
| 1126 */ | 1220 */ | 
| 1127 function load() { | 1221 function load() { | 
| 1128 uber.onContentFrameLoaded(); | 1222 uber.onContentFrameLoaded(); | 
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1421 historyView.reload(); | 1515 historyView.reload(); | 
| 1422 } | 1516 } | 
| 1423 | 1517 | 
| 1424 // Add handlers to HTML elements. | 1518 // Add handlers to HTML elements. | 
| 1425 document.addEventListener('DOMContentLoaded', load); | 1519 document.addEventListener('DOMContentLoaded', load); | 
| 1426 | 1520 | 
| 1427 // This event lets us enable and disable menu items before the menu is shown. | 1521 // This event lets us enable and disable menu items before the menu is shown. | 
| 1428 document.addEventListener('canExecute', function(e) { | 1522 document.addEventListener('canExecute', function(e) { | 
| 1429 e.canExecute = true; | 1523 e.canExecute = true; | 
| 1430 }); | 1524 }); | 
| OLD | NEW |