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 |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 * @constructor | 315 * @constructor |
316 */ | 316 */ |
317 function HistoryModel() { | 317 function HistoryModel() { |
318 this.clearModel_(); | 318 this.clearModel_(); |
319 } | 319 } |
320 | 320 |
321 // HistoryModel, Public: ------------------------------------------------------ | 321 // HistoryModel, Public: ------------------------------------------------------ |
322 | 322 |
323 /** @enum {number} */ | 323 /** @enum {number} */ |
324 HistoryModel.Range = { | 324 HistoryModel.Range = { |
325 ALLTIME: 0, | 325 ALL_TIME: 0, |
326 WEEK: 1, | 326 WEEK: 1, |
327 MONTH: 2 | 327 MONTH: 2 |
328 }; | 328 }; |
329 | 329 |
330 /** | 330 /** |
331 * Sets our current view that is called when the history model changes. | 331 * Sets our current view that is called when the history model changes. |
332 * @param {HistoryView} view The view to set our current view to. | 332 * @param {HistoryView} view The view to set our current view to. |
333 */ | 333 */ |
334 HistoryModel.prototype.setView = function(view) { | 334 HistoryModel.prototype.setView = function(view) { |
335 this.view_ = view; | 335 this.view_ = view; |
(...skipping 20 matching lines...) Expand all Loading... |
356 }; | 356 }; |
357 | 357 |
358 /** | 358 /** |
359 * Reload our model with the current parameters. | 359 * Reload our model with the current parameters. |
360 */ | 360 */ |
361 HistoryModel.prototype.reload = function() { | 361 HistoryModel.prototype.reload = function() { |
362 // Save user-visible state, clear the model, and restore the state. | 362 // Save user-visible state, clear the model, and restore the state. |
363 var search = this.searchText_; | 363 var search = this.searchText_; |
364 var page = this.requestedPage_; | 364 var page = this.requestedPage_; |
365 var range = this.rangeInDays_; | 365 var range = this.rangeInDays_; |
| 366 var offset = this.offset_; |
366 var groupByDomain = this.groupByDomain_; | 367 var groupByDomain = this.groupByDomain_; |
367 | 368 |
368 this.clearModel_(); | 369 this.clearModel_(); |
369 this.searchText_ = search; | 370 this.searchText_ = search; |
370 this.requestedPage_ = page; | 371 this.requestedPage_ = page; |
371 this.rangeInDays_ = range; | 372 this.rangeInDays_ = range; |
| 373 this.offset_ = offset; |
372 this.groupByDomain_ = groupByDomain; | 374 this.groupByDomain_ = groupByDomain; |
373 this.queryHistory_(); | 375 this.queryHistory_(); |
374 }; | 376 }; |
375 | 377 |
376 /** | 378 /** |
377 * @return {string} The current search text. | 379 * @return {string} The current search text. |
378 */ | 380 */ |
379 HistoryModel.prototype.getSearchText = function() { | 381 HistoryModel.prototype.getSearchText = function() { |
380 return this.searchText_; | 382 return this.searchText_; |
381 }; | 383 }; |
(...skipping 90 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.nextVisitId_ = 0; | 513 this.nextVisitId_ = 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 |
503 // The range of history to view or search over. | 521 // The range of history to view or search over. |
504 this.rangeInDays_ = HistoryModel.Range.ALLTIME; | 522 this.rangeInDays_ = HistoryModel.Range.ALL_TIME; |
| 523 |
| 524 // Skip |offset_| * weeks/months from the begining. |
| 525 this.offset_ = 0; |
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; |
513 | 534 |
514 // A map of URLs of visits on the same day as the last known visit. | 535 // A map of URLs of visits on the same day as the last known visit. |
(...skipping 11 matching lines...) Expand all Loading... |
526 * we're ready to show something. This only applies to the daily time-based | 547 * we're ready to show something. This only applies to the daily time-based |
527 * view. | 548 * view. |
528 * @private | 549 * @private |
529 */ | 550 */ |
530 HistoryModel.prototype.updateSearch_ = function() { | 551 HistoryModel.prototype.updateSearch_ = function() { |
531 var doneLoading = this.isQueryFinished_ || | 552 var doneLoading = this.isQueryFinished_ || |
532 this.canFillPage_(this.requestedPage_); | 553 this.canFillPage_(this.requestedPage_); |
533 | 554 |
534 // Try to fetch more results if more results can arrive and the page is not | 555 // Try to fetch more results if more results can arrive and the page is not |
535 // full. | 556 // full. |
536 if (this.rangeInDays_ == HistoryModel.Range.ALLTIME && | 557 if (this.rangeInDays_ == HistoryModel.Range.ALL_TIME && |
537 !doneLoading && !this.inFlight_) { | 558 !doneLoading && !this.inFlight_) { |
538 this.queryHistory_(); | 559 this.queryHistory_(); |
539 } | 560 } |
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 var max_results = | 571 var max_results = |
551 (this.rangeInDays_ == HistoryModel.Range.ALLTIME) ? RESULTS_PER_PAGE : 0; | 572 (this.rangeInDays_ == HistoryModel.Range.ALL_TIME) ? RESULTS_PER_PAGE : 0; |
552 | 573 |
553 $('loading-spinner').hidden = false; | 574 $('loading-spinner').hidden = false; |
554 this.inFlight_ = true; | 575 this.inFlight_ = true; |
555 chrome.send('queryHistory', | 576 chrome.send('queryHistory', |
556 [this.searchText_, this.rangeInDays_, this.queryCursor_, max_results]); | 577 [this.searchText_, this.offset_, this.rangeInDays_, this.queryCursor_, |
| 578 max_results]); |
557 }; | 579 }; |
558 | 580 |
559 /** | 581 /** |
560 * Check to see if we have data for the given page. | 582 * Check to see if we have data for the given page. |
561 * @param {number} page The page number. | 583 * @param {number} page The page number. |
562 * @return {boolean} Whether we have any data for the given page. | 584 * @return {boolean} Whether we have any data for the given page. |
563 * @private | 585 * @private |
564 */ | 586 */ |
565 HistoryModel.prototype.haveDataForPage_ = function(page) { | 587 HistoryModel.prototype.haveDataForPage_ = function(page) { |
566 return (page * RESULTS_PER_PAGE < this.getSize()); | 588 return (page * RESULTS_PER_PAGE < this.getSize()); |
567 }; | 589 }; |
568 | 590 |
569 /** | 591 /** |
570 * Check to see if we have data to fill the given page. | 592 * Check to see if we have data to fill the given page. |
571 * @param {number} page The page number. | 593 * @param {number} page The page number. |
572 * @return {boolean} Whether we have data to fill the page. | 594 * @return {boolean} Whether we have data to fill the page. |
573 * @private | 595 * @private |
574 */ | 596 */ |
575 HistoryModel.prototype.canFillPage_ = function(page) { | 597 HistoryModel.prototype.canFillPage_ = function(page) { |
576 return ((page + 1) * RESULTS_PER_PAGE <= this.getSize()); | 598 return ((page + 1) * RESULTS_PER_PAGE <= this.getSize()); |
577 }; | 599 }; |
578 | 600 |
579 /** | 601 /** |
580 * Enables or disables grouping by domain. | 602 * Enables or disables grouping by domain. |
581 * @param {boolean} groupByDomain New groupByDomain_ value. | 603 * @param {boolean} groupByDomain New groupByDomain_ value. |
582 */ | 604 */ |
583 HistoryModel.prototype.setGroupByDomain = function(groupByDomain) { | 605 HistoryModel.prototype.setGroupByDomain = function(groupByDomain) { |
584 this.groupByDomain_ = groupByDomain; | 606 this.groupByDomain_ = groupByDomain; |
| 607 this.offset_ = 0; |
585 }; | 608 }; |
586 | 609 |
587 /** | 610 /** |
588 * Gets whether we are grouped by domain. | 611 * Gets whether we are grouped by domain. |
589 * @return {boolean} Whether the results are grouped by domain. | 612 * @return {boolean} Whether the results are grouped by domain. |
590 */ | 613 */ |
591 HistoryModel.prototype.getGroupByDomain = function() { | 614 HistoryModel.prototype.getGroupByDomain = function() { |
592 return this.groupByDomain_; | 615 return this.groupByDomain_; |
593 }; | 616 }; |
594 | 617 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 }); | 655 }); |
633 | 656 |
634 // Add handlers for the range options. | 657 // Add handlers for the range options. |
635 $('timeframe-filter').addEventListener('change', function(e) { | 658 $('timeframe-filter').addEventListener('change', function(e) { |
636 self.setRangeInDays(parseInt(e.target.value, 10)); | 659 self.setRangeInDays(parseInt(e.target.value, 10)); |
637 }); | 660 }); |
638 | 661 |
639 $('display-filter-sites').addEventListener('click', function(e) { | 662 $('display-filter-sites').addEventListener('click', function(e) { |
640 self.setGroupByDomain($('display-filter-sites').checked); | 663 self.setGroupByDomain($('display-filter-sites').checked); |
641 }); | 664 }); |
| 665 |
| 666 $('range-previous').addEventListener('click', function(e) { |
| 667 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) |
| 668 self.setPage(self.pageIndex_ + 1); |
| 669 else |
| 670 self.setOffset(self.getOffset() + 1); |
| 671 }); |
| 672 $('range-next').addEventListener('click', function(e) { |
| 673 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) |
| 674 self.setPage(self.pageIndex_ - 1); |
| 675 else |
| 676 self.setOffset(self.getOffset() - 1); |
| 677 }); |
| 678 $('range-today').addEventListener('click', function(e) { |
| 679 if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME) |
| 680 self.setPage(0); |
| 681 else |
| 682 self.setOffset(0); |
| 683 }); |
642 } | 684 } |
643 | 685 |
644 // HistoryView, public: ------------------------------------------------------- | 686 // HistoryView, public: ------------------------------------------------------- |
645 /** | 687 /** |
646 * Do a search and optionally view a certain page. | 688 * Do a search and optionally view a certain page. |
647 * @param {string} term The string to search for. | 689 * @param {string} term The string to search for. |
648 * @param {number} opt_page The page we wish to view, only use this for | 690 * @param {number} opt_page The page we wish to view, only use this for |
649 * setting up initial views, as this triggers a search. | 691 * setting up initial views, as this triggers a search. |
650 */ | 692 */ |
651 HistoryView.prototype.setSearch = function(term, opt_page) { | 693 HistoryView.prototype.setSearch = function(term, opt_page) { |
652 this.pageIndex_ = parseInt(opt_page || 0, 10); | 694 this.pageIndex_ = parseInt(opt_page || 0, 10); |
653 window.scrollTo(0, 0); | 695 window.scrollTo(0, 0); |
654 this.model_.setSearchText(term, this.pageIndex_); | 696 this.model_.setSearchText(term, this.pageIndex_); |
655 pageState.setUIState(term, this.pageIndex_, this.model_.getGroupByDomain(), | 697 pageState.setUIState(term, this.pageIndex_, this.model_.getGroupByDomain(), |
656 this.getRangeInDays()); | 698 this.getRangeInDays(), this.getOffset()); |
657 }; | 699 }; |
658 | 700 |
659 /** | 701 /** |
660 * Enable or disable results as being grouped by domain. | 702 * Enable or disable results as being grouped by domain. |
661 * @param {boolean} groupedByDomain Whether to group by domain or not. | 703 * @param {boolean} groupedByDomain Whether to group by domain or not. |
662 */ | 704 */ |
663 HistoryView.prototype.setGroupByDomain = function(groupedByDomain) { | 705 HistoryView.prototype.setGroupByDomain = function(groupedByDomain) { |
664 // Group by domain is not currently supported for search results, so reset | 706 // Group by domain is not currently supported for search results, so reset |
665 // the search term if there was one. | 707 // the search term if there was one. |
666 this.model_.clearSearchText(); | 708 this.model_.clearSearchText(); |
667 this.model_.setGroupByDomain(groupedByDomain); | 709 this.model_.setGroupByDomain(groupedByDomain); |
668 this.model_.reload(); | 710 this.model_.reload(); |
669 pageState.setUIState(this.model_.getSearchText(), | 711 pageState.setUIState(this.model_.getSearchText(), |
670 this.pageIndex_, | 712 this.pageIndex_, |
671 this.model_.getGroupByDomain(), | 713 this.model_.getGroupByDomain(), |
672 this.getRangeInDays()); | 714 this.getRangeInDays(), |
| 715 this.getOffset()); |
673 }; | 716 }; |
674 | 717 |
675 /** | 718 /** |
676 * Reload the current view. | 719 * Reload the current view. |
677 */ | 720 */ |
678 HistoryView.prototype.reload = function() { | 721 HistoryView.prototype.reload = function() { |
679 this.model_.reload(); | 722 this.model_.reload(); |
680 this.updateRemoveButton(); | 723 this.updateRemoveButton(); |
681 }; | 724 }; |
682 | 725 |
683 /** | 726 /** |
684 * Switch to a specified page. | 727 * Switch to a specified page. |
685 * @param {number} page The page we wish to view. | 728 * @param {number} page The page we wish to view. |
686 */ | 729 */ |
687 HistoryView.prototype.setPage = function(page) { | 730 HistoryView.prototype.setPage = function(page) { |
688 this.clear_(); | 731 this.clear_(); |
689 this.pageIndex_ = parseInt(page, 10); | 732 this.pageIndex_ = parseInt(page, 10); |
690 window.scrollTo(0, 0); | 733 window.scrollTo(0, 0); |
691 this.model_.requestPage(page); | 734 this.model_.requestPage(page); |
692 pageState.setUIState(this.model_.getSearchText(), | 735 pageState.setUIState(this.model_.getSearchText(), |
693 this.pageIndex_, | 736 this.pageIndex_, |
694 this.model_.getGroupByDomain(), | 737 this.model_.getGroupByDomain(), |
695 this.getRangeInDays()); | 738 this.getRangeInDays(), |
| 739 this.getOffset()); |
696 }; | 740 }; |
697 | 741 |
698 /** | 742 /** |
699 * @return {number} The page number being viewed. | 743 * @return {number} The page number being viewed. |
700 */ | 744 */ |
701 HistoryView.prototype.getPage = function() { | 745 HistoryView.prototype.getPage = function() { |
702 return this.pageIndex_; | 746 return this.pageIndex_; |
703 }; | 747 }; |
704 | 748 |
705 /** | 749 /** |
706 * Set the current range for grouped results. | 750 * Set the current range for grouped results. |
707 * @param {string} range The number of days to which the range should be set. | 751 * @param {string} range The number of days to which the range should be set. |
708 */ | 752 */ |
709 HistoryView.prototype.setRangeInDays = function(range) { | 753 HistoryView.prototype.setRangeInDays = function(range) { |
710 // Set the range and reset the page | 754 // Set the range, offset and reset the page |
711 this.model_.rangeInDays = range; | 755 this.model_.rangeInDays = range; |
| 756 this.model_.offset = 0; |
712 this.pageIndex_ = 0; | 757 this.pageIndex_ = 0; |
713 this.model_.reload(); | 758 this.model_.reload(); |
714 pageState.setUIState(this.model_.getSearchText(), this.pageIndex_, | 759 pageState.setUIState(this.model_.getSearchText(), this.pageIndex_, |
715 this.model_.getGroupByDomain(), range); | 760 this.model_.getGroupByDomain(), range, this.getOffset()); |
716 }; | 761 }; |
717 | 762 |
718 /** | 763 /** |
719 * Get the current range in days. | 764 * Get the current range in days. |
720 * @return {number} Current range in days from the model. | 765 * @return {number} Current range in days from the model. |
721 */ | 766 */ |
722 HistoryView.prototype.getRangeInDays = function() { | 767 HistoryView.prototype.getRangeInDays = function() { |
723 return this.model_.rangeInDays; | 768 return this.model_.rangeInDays; |
724 }; | 769 }; |
725 | 770 |
726 /** | 771 /** |
| 772 * Set the current offset for grouped results. |
| 773 * @param {number} offset Offset to set. |
| 774 */ |
| 775 HistoryView.prototype.setOffset = function(offset) { |
| 776 // If there is another query already in flight wait for that to complete. |
| 777 if (this.model_.inFlight_) |
| 778 return; |
| 779 this.model_.offset = offset; |
| 780 this.model_.reload(); |
| 781 pageState.setUIState(this.model_.getSearchText(), |
| 782 this.pageIndex_, |
| 783 this.model_.getGroupByDomain(), |
| 784 this.getRangeInDays(), |
| 785 this.getOffset()); |
| 786 }; |
| 787 |
| 788 /** |
| 789 * Get the current offset. |
| 790 * @return {number} Current offset from the model. |
| 791 */ |
| 792 HistoryView.prototype.getOffset = function() { |
| 793 return this.model_.offset; |
| 794 }; |
| 795 |
| 796 /** |
727 * Callback for the history model to let it know that it has data ready for us | 797 * Callback for the history model to let it know that it has data ready for us |
728 * to view. | 798 * to view. |
729 */ | 799 */ |
730 HistoryView.prototype.onModelReady = function() { | 800 HistoryView.prototype.onModelReady = function() { |
731 this.displayResults_(); | 801 this.displayResults_(); |
732 this.updateNavBar_(); | 802 this.updateNavBar_(); |
733 }; | 803 }; |
734 | 804 |
735 /** | 805 /** |
736 * Enables or disables the 'Remove selected items' button as appropriate. | 806 * 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; | 877 var isMonthGroupedResult = this.getRangeInDays() == HistoryModel.Range.MONTH; |
808 for (var j = 0, visit; visit = domainVisits[j]; j++) { | 878 for (var j = 0, visit; visit = domainVisits[j]; j++) { |
809 resultsList.appendChild(visit.getResultDOM({ | 879 resultsList.appendChild(visit.getResultDOM({ |
810 useMonthDate: isMonthGroupedResult | 880 useMonthDate: isMonthGroupedResult |
811 })); | 881 })); |
812 this.setVisitRendered_(visit); | 882 this.setVisitRendered_(visit); |
813 } | 883 } |
814 }; | 884 }; |
815 | 885 |
816 /** | 886 /** |
| 887 * Enables or disables the time range buttons. |
| 888 * @private |
| 889 */ |
| 890 HistoryView.prototype.updateRangeButtons_ = function() { |
| 891 // The enabled state for the previous, today and next buttons. |
| 892 var previousState = false; |
| 893 var todayState = false; |
| 894 var nextState = false; |
| 895 var usePage = (this.getRangeInDays() == HistoryModel.Range.ALL_TIME); |
| 896 |
| 897 // Use pagination for most recent visits, offset otherwise. |
| 898 // TODO(sergiu): Maybe send just one variable in the future. |
| 899 if (usePage) { |
| 900 if (this.getPage() != 0) { |
| 901 nextState = true; |
| 902 todayState = true; |
| 903 } |
| 904 previousState = this.model_.hasMoreResults(); |
| 905 } else { |
| 906 if (this.getOffset() != 0) { |
| 907 nextState = true; |
| 908 todayState = true; |
| 909 } |
| 910 previousState = !this.model_.isQueryFinished_; |
| 911 } |
| 912 |
| 913 $('range-previous').disabled = !previousState; |
| 914 $('range-today').disabled = !todayState; |
| 915 $('range-next').disabled = !nextState; |
| 916 }; |
| 917 |
| 918 /** |
817 * Groups visits by domain, sorting them by the number of visits. | 919 * Groups visits by domain, sorting them by the number of visits. |
818 * @param {Array} visits Visits received from the query results. | 920 * @param {Array} visits Visits received from the query results. |
819 * @param {Element} results Object where the results are added to. | 921 * @param {Element} results Object where the results are added to. |
820 * @private | 922 * @private |
821 */ | 923 */ |
822 HistoryView.prototype.groupVisitsByDomain_ = function(visits, results) { | 924 HistoryView.prototype.groupVisitsByDomain_ = function(visits, results) { |
823 var visitsByDomain = {}; | 925 var visitsByDomain = {}; |
824 var domains = []; | 926 var domains = []; |
825 | 927 |
826 // Group the visits into a dictionary and generate a list of domains. | 928 // Group the visits into a dictionary and generate a list of domains. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 }; | 1001 }; |
900 | 1002 |
901 /** | 1003 /** |
902 * Update the page with results. | 1004 * Update the page with results. |
903 * @private | 1005 * @private |
904 */ | 1006 */ |
905 HistoryView.prototype.displayResults_ = function() { | 1007 HistoryView.prototype.displayResults_ = function() { |
906 // Either show a page of results received for the all time results or all the | 1008 // Either show a page of results received for the all time results or all the |
907 // received results for the weekly and monthly view. | 1009 // received results for the weekly and monthly view. |
908 var results = this.model_.visits_; | 1010 var results = this.model_.visits_; |
909 if (this.getRangeInDays() == HistoryModel.Range.ALLTIME) { | 1011 if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME) { |
910 var rangeStart = this.pageIndex_ * RESULTS_PER_PAGE; | 1012 var rangeStart = this.pageIndex_ * RESULTS_PER_PAGE; |
911 var rangeEnd = rangeStart + RESULTS_PER_PAGE; | 1013 var rangeEnd = rangeStart + RESULTS_PER_PAGE; |
912 results = this.model_.getNumberedRange(rangeStart, rangeEnd); | 1014 results = this.model_.getNumberedRange(rangeStart, rangeEnd); |
913 } | 1015 } |
914 var searchText = this.model_.getSearchText(); | 1016 var searchText = this.model_.getSearchText(); |
915 var groupByDomain = this.model_.getGroupByDomain(); | 1017 var groupByDomain = this.model_.getGroupByDomain(); |
916 | 1018 |
917 if (searchText) { | 1019 if (searchText) { |
918 // Add a header for the search results, if there isn't already one. | 1020 // Add a header for the search results, if there isn't already one. |
919 if (!this.resultDiv_.querySelector('h3')) { | 1021 if (!this.resultDiv_.querySelector('h3')) { |
(...skipping 16 matching lines...) Expand all Loading... |
936 addTitleFavicon: true | 1038 addTitleFavicon: true |
937 })); | 1039 })); |
938 this.setVisitRendered_(visit); | 1040 this.setVisitRendered_(visit); |
939 } | 1041 } |
940 } | 1042 } |
941 } | 1043 } |
942 this.resultDiv_.appendChild(searchResults); | 1044 this.resultDiv_.appendChild(searchResults); |
943 } else { | 1045 } else { |
944 var resultsFragment = document.createDocumentFragment(); | 1046 var resultsFragment = document.createDocumentFragment(); |
945 | 1047 |
946 if (this.getRangeInDays() != HistoryModel.Range.ALLTIME) { | 1048 if (this.getRangeInDays() != HistoryModel.Range.ALL_TIME) { |
947 // If this is a time range result add some text that shows what is the | 1049 // If this is a time range result add some text that shows what is the |
948 // time range for the results the user is viewing. | 1050 // time range for the results the user is viewing. |
949 var timeFrame = resultsFragment.appendChild( | 1051 var timeFrame = resultsFragment.appendChild( |
950 createElementWithClassName('h2', 'timeframe')); | 1052 createElementWithClassName('h2', 'timeframe')); |
951 // TODO(sergiu): Figure the best way to show this for the first day of | 1053 // TODO(sergiu): Figure the best way to show this for the first day of |
952 // the month. | 1054 // the month. |
953 timeFrame.appendChild(document.createTextNode(loadTimeData.getStringF( | 1055 timeFrame.appendChild(document.createTextNode(loadTimeData.getStringF( |
954 'historyinterval', | 1056 'historyinterval', |
955 this.model_.queryStartTime, | 1057 this.model_.queryStartTime, |
956 this.model_.queryEndTime))); | 1058 this.model_.queryEndTime))); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 this.resultDiv_.appendChild(resultsFragment); | 1092 this.resultDiv_.appendChild(resultsFragment); |
991 } | 1093 } |
992 this.updateNavBar_(); | 1094 this.updateNavBar_(); |
993 }; | 1095 }; |
994 | 1096 |
995 /** | 1097 /** |
996 * Update the visibility of the page navigation buttons. | 1098 * Update the visibility of the page navigation buttons. |
997 * @private | 1099 * @private |
998 */ | 1100 */ |
999 HistoryView.prototype.updateNavBar_ = function() { | 1101 HistoryView.prototype.updateNavBar_ = function() { |
| 1102 this.updateRangeButtons_(); |
1000 $('newest-button').hidden = this.pageIndex_ == 0; | 1103 $('newest-button').hidden = this.pageIndex_ == 0; |
1001 $('newer-button').hidden = this.pageIndex_ == 0; | 1104 $('newer-button').hidden = this.pageIndex_ == 0; |
1002 $('older-button').hidden = | 1105 $('older-button').hidden = |
1003 this.model_.rangeInDays_ != HistoryModel.Range.ALLTIME || | 1106 this.model_.rangeInDays_ != HistoryModel.Range.ALL_TIME || |
1004 !this.model_.hasMoreResults(); | 1107 !this.model_.hasMoreResults(); |
1005 }; | 1108 }; |
1006 | 1109 |
1007 /////////////////////////////////////////////////////////////////////////////// | 1110 /////////////////////////////////////////////////////////////////////////////// |
1008 // State object: | 1111 // State object: |
1009 /** | 1112 /** |
1010 * An 'AJAX-history' implementation. | 1113 * An 'AJAX-history' implementation. |
1011 * @param {HistoryModel} model The model we're representing. | 1114 * @param {HistoryModel} model The model we're representing. |
1012 * @param {HistoryView} view The view we're representing. | 1115 * @param {HistoryView} view The view we're representing. |
1013 * @constructor | 1116 * @constructor |
(...skipping 17 matching lines...) Expand all Loading... |
1031 var hashData = state_obj.getHashData(); | 1134 var hashData = state_obj.getHashData(); |
1032 var isGroupedByDomain = (hashData.g == 'true'); | 1135 var isGroupedByDomain = (hashData.g == 'true'); |
1033 if (hashData.q != state_obj.model.getSearchText()) { | 1136 if (hashData.q != state_obj.model.getSearchText()) { |
1034 state_obj.view.setSearch(hashData.q, parseInt(hashData.p, 10)); | 1137 state_obj.view.setSearch(hashData.q, parseInt(hashData.p, 10)); |
1035 } else if (parseInt(hashData.p, 10) != state_obj.view.getPage()) { | 1138 } else if (parseInt(hashData.p, 10) != state_obj.view.getPage()) { |
1036 state_obj.view.setPage(hashData.p); | 1139 state_obj.view.setPage(hashData.p); |
1037 } else if (isGroupedByDomain != state_obj.view.model_.getGroupByDomain()) { | 1140 } else if (isGroupedByDomain != state_obj.view.model_.getGroupByDomain()) { |
1038 state_obj.view.setGroupByDomain(isGroupedByDomain); | 1141 state_obj.view.setGroupByDomain(isGroupedByDomain); |
1039 } else if (parseInt(hashData.r, 10) != state_obj.model.rangeInDays) { | 1142 } else if (parseInt(hashData.r, 10) != state_obj.model.rangeInDays) { |
1040 state_obj.view.setRangeInDays(parseInt(hashData.r, 10)); | 1143 state_obj.view.setRangeInDays(parseInt(hashData.r, 10)); |
| 1144 } else if (parseInt(hashData.o, 10) != state_obj.model.offset) { |
| 1145 state_obj.view.setOffset(parseInt(hashData.o, 10)); |
1041 } | 1146 } |
1042 }), 50, this); | 1147 }), 50, this); |
1043 } | 1148 } |
1044 | 1149 |
1045 /** | 1150 /** |
1046 * Holds the singleton instance. | 1151 * Holds the singleton instance. |
1047 */ | 1152 */ |
1048 PageState.instance = null; | 1153 PageState.instance = null; |
1049 | 1154 |
1050 /** | 1155 /** |
1051 * @return {Object} An object containing parameters from our window hash. | 1156 * @return {Object} An object containing parameters from our window hash. |
1052 */ | 1157 */ |
1053 PageState.prototype.getHashData = function() { | 1158 PageState.prototype.getHashData = function() { |
1054 var result = { | 1159 var result = { |
1055 e: 0, | 1160 e: 0, |
1056 q: '', | 1161 q: '', |
1057 p: 0, | 1162 p: 0, |
1058 g: false, | 1163 g: false, |
1059 r: 0 | 1164 r: 0, |
| 1165 o: 0 |
1060 }; | 1166 }; |
1061 | 1167 |
1062 if (!window.location.hash) | 1168 if (!window.location.hash) |
1063 return result; | 1169 return result; |
1064 | 1170 |
1065 var hashSplit = window.location.hash.substr(1).split('&'); | 1171 var hashSplit = window.location.hash.substr(1).split('&'); |
1066 for (var i = 0; i < hashSplit.length; i++) { | 1172 for (var i = 0; i < hashSplit.length; i++) { |
1067 var pair = hashSplit[i].split('='); | 1173 var pair = hashSplit[i].split('='); |
1068 if (pair.length > 1) { | 1174 if (pair.length > 1) { |
1069 result[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); | 1175 result[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); |
1070 } | 1176 } |
1071 } | 1177 } |
1072 | 1178 |
1073 return result; | 1179 return result; |
1074 }; | 1180 }; |
1075 | 1181 |
1076 /** | 1182 /** |
1077 * Set the hash to a specified state, this will create an entry in the | 1183 * Set the hash to a specified state, this will create an entry in the |
1078 * session history so the back button cycles through hash states, which | 1184 * session history so the back button cycles through hash states, which |
1079 * are then picked up by our listener. | 1185 * are then picked up by our listener. |
1080 * @param {string} term The current search string. | 1186 * @param {string} term The current search string. |
1081 * @param {number} page The page currently being viewed. | 1187 * @param {number} page The page currently being viewed. |
1082 * @param {boolean} grouped Whether the results are grouped or not. | 1188 * @param {boolean} grouped Whether the results are grouped or not. |
1083 * @param {HistoryModel.Range} range The range to view or search over. | 1189 * @param {HistoryModel.Range} range The range to view or search over. |
| 1190 * @param {number} offset Set the begining of the query to the specific offset. |
1084 */ | 1191 */ |
1085 PageState.prototype.setUIState = function(term, page, grouped, range) { | 1192 PageState.prototype.setUIState = function(term, page, grouped, range, offset) { |
1086 // Make sure the form looks pretty. | 1193 // Make sure the form looks pretty. |
1087 $('search-field').value = term; | 1194 $('search-field').value = term; |
1088 $('display-filter-sites').checked = grouped; | 1195 $('display-filter-sites').checked = grouped; |
1089 var hash = this.getHashData(); | 1196 var hash = this.getHashData(); |
1090 if (hash.q != term || hash.p != page || hash.g != grouped || | 1197 if (hash.q != term || hash.p != page || hash.g != grouped || |
1091 hash.r != range) { | 1198 hash.r != range || hash.o != offset) { |
1092 window.location.hash = PageState.getHashString( | 1199 window.location.hash = PageState.getHashString( |
1093 term, page, grouped, range); | 1200 term, page, grouped, range, offset); |
1094 } | 1201 } |
1095 }; | 1202 }; |
1096 | 1203 |
1097 /** | 1204 /** |
1098 * Static method to get the hash string for a specified state | 1205 * Static method to get the hash string for a specified state |
1099 * @param {string} term The current search string. | 1206 * @param {string} term The current search string. |
1100 * @param {number} page The page currently being viewed. | 1207 * @param {number} page The page currently being viewed. |
1101 * @param {boolean} grouped Whether the results are grouped or not. | 1208 * @param {boolean} grouped Whether the results are grouped or not. |
1102 * @param {HistoryModel.Range} range The range to view or search over. | 1209 * @param {HistoryModel.Range} range The range to view or search over. |
| 1210 * @param {number} offset Set the begining of the query to the specific offset. |
1103 * @return {string} The string to be used in a hash. | 1211 * @return {string} The string to be used in a hash. |
1104 */ | 1212 */ |
1105 PageState.getHashString = function(term, page, grouped, range) { | 1213 PageState.getHashString = function(term, page, grouped, range, offset) { |
1106 // Omit elements that are empty. | 1214 // Omit elements that are empty. |
1107 var newHash = []; | 1215 var newHash = []; |
1108 | 1216 |
1109 if (term) | 1217 if (term) |
1110 newHash.push('q=' + encodeURIComponent(term)); | 1218 newHash.push('q=' + encodeURIComponent(term)); |
1111 | 1219 |
1112 if (page) | 1220 if (page) |
1113 newHash.push('p=' + page); | 1221 newHash.push('p=' + page); |
1114 | 1222 |
1115 if (grouped) | 1223 if (grouped) |
1116 newHash.push('g=' + grouped); | 1224 newHash.push('g=' + grouped); |
1117 | 1225 |
1118 if (range) | 1226 if (range) |
1119 newHash.push('r=' + range); | 1227 newHash.push('r=' + range); |
1120 | 1228 |
| 1229 if (offset) |
| 1230 newHash.push('o=' + offset); |
| 1231 |
1121 return newHash.join('&'); | 1232 return newHash.join('&'); |
1122 }; | 1233 }; |
1123 | 1234 |
1124 /////////////////////////////////////////////////////////////////////////////// | 1235 /////////////////////////////////////////////////////////////////////////////// |
1125 // Document Functions: | 1236 // Document Functions: |
1126 /** | 1237 /** |
1127 * Window onload handler, sets up the page. | 1238 * Window onload handler, sets up the page. |
1128 */ | 1239 */ |
1129 function load() { | 1240 function load() { |
1130 uber.onContentFrameLoaded(); | 1241 uber.onContentFrameLoaded(); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1423 historyView.reload(); | 1534 historyView.reload(); |
1424 } | 1535 } |
1425 | 1536 |
1426 // Add handlers to HTML elements. | 1537 // Add handlers to HTML elements. |
1427 document.addEventListener('DOMContentLoaded', load); | 1538 document.addEventListener('DOMContentLoaded', load); |
1428 | 1539 |
1429 // This event lets us enable and disable menu items before the menu is shown. | 1540 // This event lets us enable and disable menu items before the menu is shown. |
1430 document.addEventListener('canExecute', function(e) { | 1541 document.addEventListener('canExecute', function(e) { |
1431 e.canExecute = true; | 1542 e.canExecute = true; |
1432 }); | 1543 }); |
OLD | NEW |