| 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 |