| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 cr.define('ntp4', function() { | 5 cr.define('ntp4', function() { |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * Creates a new Tileobject. Tiles wrap content on a TilePage, providing | 9 * Creates a new Tileobject. Tiles wrap content on a TilePage, providing |
| 10 * some styling and drag functionality. | 10 * some styling and drag functionality. |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 this.onDragLeaveDot_.bind(this)); | 327 this.onDragLeaveDot_.bind(this)); |
| 328 }, | 328 }, |
| 329 get navigationDot() { | 329 get navigationDot() { |
| 330 return this.navigationDot_; | 330 return this.navigationDot_; |
| 331 }, | 331 }, |
| 332 | 332 |
| 333 /** | 333 /** |
| 334 * @protected | 334 * @protected |
| 335 */ | 335 */ |
| 336 appendTile: function(tileElement) { | 336 appendTile: function(tileElement) { |
| 337 this.addTileAt(tileElement, this.tileElements_.length); |
| 338 }, |
| 339 |
| 340 /** |
| 341 * Adds the given element to the tile grid. |
| 342 * @param {Node} tileElement The tile object/node to insert. |
| 343 * @param {number} index The location in the tile grid to insert it at. |
| 344 * @protected |
| 345 */ |
| 346 addTileAt: function(tileElement, index) { |
| 347 var wrapperDiv = new Tile(tileElement); |
| 348 if (index == this.tileElements_.length) { |
| 349 this.tileGrid_.appendChild(wrapperDiv); |
| 350 } else { |
| 351 this.tileGrid_.insertBefore(wrapperDiv, |
| 352 this.tileElements_[index]); |
| 353 } |
| 337 this.calculateLayoutValues_(); | 354 this.calculateLayoutValues_(); |
| 338 | 355 |
| 339 var wrapperDiv = new Tile(tileElement); | 356 this.positionTile_(index); |
| 340 this.tileGrid_.appendChild(wrapperDiv); | |
| 341 | |
| 342 this.positionTile_(this.tileElements_.length - 1); | |
| 343 this.classList.remove('animating-tile-page'); | 357 this.classList.remove('animating-tile-page'); |
| 344 }, | 358 }, |
| 345 | 359 |
| 346 /** | 360 /** |
| 347 * Controls whether this page will accept drags that originate from outside | 361 * Controls whether this page will accept drags that originate from outside |
| 348 * the page. | 362 * the page. |
| 349 * @return {boolean} True if this page accepts drags from outside sources. | 363 * @return {boolean} True if this page accepts drags from outside sources. |
| 350 */ | 364 */ |
| 351 acceptOutsideDrags: function() { | 365 acceptOutsideDrags: function() { |
| 352 return true; | 366 return true; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 heightForWidth: function(width) { | 569 heightForWidth: function(width) { |
| 556 return width; | 570 return width; |
| 557 }, | 571 }, |
| 558 | 572 |
| 559 /** Dragging **/ | 573 /** Dragging **/ |
| 560 | 574 |
| 561 /** | 575 /** |
| 562 * The number of un-paired dragenter events that have fired on |this|. This | 576 * The number of un-paired dragenter events that have fired on |this|. This |
| 563 * is incremented by |onDragEnter_| and decremented by |onDragLeave_|. This | 577 * is incremented by |onDragEnter_| and decremented by |onDragLeave_|. This |
| 564 * is necessary because dragging over child widgets will fire additional | 578 * is necessary because dragging over child widgets will fire additional |
| 565 * enter and leave events on |this|. | 579 * enter and leave events on |this|. A non-zero value does not necessarily |
| 580 * indicate that |isCurrentDragTarget_| is true. |
| 566 * @type {number} | 581 * @type {number} |
| 567 * @private | 582 * @private |
| 568 */ | 583 */ |
| 569 dragEnters_: 0, | 584 dragEnters_: 0, |
| 570 | 585 |
| 571 /** | 586 /** |
| 587 * Whether the tile page is currently being dragged over with data it can |
| 588 * accept. |
| 589 * @type {boolean} |
| 590 * @private |
| 591 */ |
| 592 isCurrentDragTarget_: false, |
| 593 |
| 594 /** |
| 572 * Handler for dragenter events fired on |tileGrid_|. | 595 * Handler for dragenter events fired on |tileGrid_|. |
| 573 * @param {Event} e A MouseEvent for the drag. | 596 * @param {Event} e A MouseEvent for the drag. |
| 574 * @private | 597 * @private |
| 575 */ | 598 */ |
| 576 onDragEnter_: function(e) { | 599 onDragEnter_: function(e) { |
| 577 if (++this.dragEnters_ > 1) | 600 if (++this.dragEnters_ > 1) |
| 578 return; | 601 return; |
| 602 this.doDragEnter_(e); |
| 603 }, |
| 579 | 604 |
| 580 // TODO(estade): for now we only allow tile drags. | 605 /** |
| 581 if (!TilePage.currentlyDraggingTile) | 606 * Thunk for dragover events fired on |tileGrid_|. |
| 607 * @param {Event} e A MouseEvent for the drag. |
| 608 * @private |
| 609 */ |
| 610 onDragOver_: function(e) { |
| 611 if (!this.isCurrentDragTarget_) |
| 582 return; | 612 return; |
| 613 this.doDragOver_(e); |
| 614 }, |
| 615 |
| 616 /** |
| 617 * Thunk for drop events fired on |tileGrid_|. |
| 618 * @param {Event} e A MouseEvent for the drag. |
| 619 * @private |
| 620 */ |
| 621 onDrop_: function(e) { |
| 622 this.dragEnters_ = 0; |
| 623 if (!this.isCurrentDragTarget_) |
| 624 return; |
| 625 this.doDrop_(e); |
| 626 }, |
| 627 |
| 628 /** |
| 629 * Thunk for dragleave events fired on |tileGrid_|. |
| 630 * @param {Event} e A MouseEvent for the drag. |
| 631 * @private |
| 632 */ |
| 633 onDragLeave_: function(e) { |
| 634 if (--this.dragEnters_ > 0) |
| 635 return; |
| 636 |
| 637 this.isCurrentDragTarget_ = false; |
| 638 this.cleanUpDrag_(); |
| 639 }, |
| 640 |
| 641 /** |
| 642 * Performs all actions necessary when a drag enters the tile page. |
| 643 * @param {Event} e A mouseover event for the drag enter. |
| 644 * @private |
| 645 */ |
| 646 doDragEnter_: function(e) { |
| 647 if (!this.shouldAcceptDrag(TilePage.currentlyDraggingTile, |
| 648 e.dataTransfer)) { |
| 649 return; |
| 650 } |
| 651 |
| 652 this.isCurrentDragTarget_ = true; |
| 583 | 653 |
| 584 // Applies the mask so doppleganger tiles disappear into the fog. | 654 // Applies the mask so doppleganger tiles disappear into the fog. |
| 585 this.updateMask_(); | 655 this.updateMask_(); |
| 586 | 656 |
| 587 this.classList.add('animating-tile-page'); | 657 this.classList.add('animating-tile-page'); |
| 588 this.withinPageDrag_ = this.contains(TilePage.currentlyDraggingTile); | 658 this.withinPageDrag_ = this.contains(TilePage.currentlyDraggingTile); |
| 589 this.dragItemIndex_ = this.withinPageDrag_ ? | 659 this.dragItemIndex_ = this.withinPageDrag_ ? |
| 590 TilePage.currentlyDraggingTile.index : this.tileElements_.length; | 660 TilePage.currentlyDraggingTile.index : this.tileElements_.length; |
| 591 this.currentDropIndex_ = this.dragItemIndex_; | 661 this.currentDropIndex_ = this.dragItemIndex_; |
| 592 }, | 662 }, |
| 593 | 663 |
| 594 /** | 664 /** |
| 595 * Handler for dragover events fired on |tileGrid_|. | 665 * Performs all actions necessary when the user moves the cursor during |
| 596 * @param {Event} e A MouseEvent for the drag. | 666 * a drag over the tile page. |
| 667 * @param {Event} e A mouseover event for the drag over. |
| 597 * @private | 668 * @private |
| 598 */ | 669 */ |
| 599 onDragOver_: function(e) { | 670 doDragOver_: function(e) { |
| 600 e.dataTransfer.dropEffect = 'move'; | 671 e.preventDefault(); |
| 601 var draggedTile = TilePage.currentlyDraggingTile; | |
| 602 if (!draggedTile) | |
| 603 return; | |
| 604 | 672 |
| 605 e.preventDefault(); | 673 if (TilePage.currentlyDraggingTile) |
| 674 e.dataTransfer.dropEffect = 'move'; |
| 675 else |
| 676 e.dataTransfer.dropEffect = 'copy'; |
| 606 | 677 |
| 607 var newDragIndex = this.getWouldBeIndexForPoint_(e.clientX, e.clientY); | 678 var newDragIndex = this.getWouldBeIndexForPoint_(e.clientX, e.clientY); |
| 608 if (newDragIndex < 0 || newDragIndex >= this.tileElements_.length) | 679 if (newDragIndex < 0 || newDragIndex >= this.tileElements_.length) |
| 609 newDragIndex = this.dragItemIndex_; | 680 newDragIndex = this.dragItemIndex_; |
| 610 this.updateDropIndicator_(newDragIndex); | 681 this.updateDropIndicator_(newDragIndex); |
| 611 }, | 682 }, |
| 612 | 683 |
| 613 /** | 684 /** |
| 614 * Handler for drop events fired on |tileGrid_|. | 685 * Performs all actions necessary when the user completes a drop. |
| 615 * @param {Event} e A MouseEvent for the drag. | 686 * @param {Event} e A mouseover event for the drag drop. |
| 616 * @private | 687 * @private |
| 617 */ | 688 */ |
| 618 onDrop_: function(e) { | 689 doDrop_: function(e) { |
| 619 this.dragEnters_ = 0; | |
| 620 e.stopPropagation(); | 690 e.stopPropagation(); |
| 691 this.isCurrentDragTarget_ = false; |
| 621 | 692 |
| 622 var index = this.currentDropIndex_; | 693 var index = this.currentDropIndex_; |
| 623 if ((index == this.dragItemIndex_) && this.withinPageDrag_) | 694 if ((index == this.dragItemIndex_) && this.withinPageDrag_) |
| 624 return; | 695 return; |
| 625 | 696 |
| 626 var adjustment = index > this.dragItemIndex_ ? 1 : 0; | 697 var adjustedIndex = this.currentDropIndex_ + |
| 627 this.tileGrid_.insertBefore( | 698 (index > this.dragItemIndex_ ? 1 : 0); |
| 628 TilePage.currentlyDraggingTile, | 699 if (TilePage.currentlyDraggingTile) { |
| 629 this.tileElements_[this.currentDropIndex_ + adjustment]); | 700 this.tileGrid_.insertBefore( |
| 701 TilePage.currentlyDraggingTile, |
| 702 this.tileElements_[adjustedIndex]); |
| 703 } else { |
| 704 this.addOutsideData(e.dataTransfer, adjustedIndex); |
| 705 } |
| 706 |
| 707 this.classList.remove('animating-tile-page'); |
| 630 this.cleanUpDrag_(); | 708 this.cleanUpDrag_(); |
| 631 }, | 709 }, |
| 632 | 710 |
| 633 /** | |
| 634 * Handler for dragleave events fired on |tileGrid_|. | |
| 635 * @param {Event} e A MouseEvent for the drag. | |
| 636 * @private | |
| 637 */ | |
| 638 onDragLeave_: function(e) { | |
| 639 if (--this.dragEnters_ > 0) | |
| 640 return; | |
| 641 | |
| 642 this.cleanUpDrag_(); | |
| 643 }, | |
| 644 | |
| 645 /** | 711 /** |
| 646 * Makes sure all the tiles are in the right place after a drag is over. | 712 * Makes sure all the tiles are in the right place after a drag is over. |
| 647 * @private | 713 * @private |
| 648 */ | 714 */ |
| 649 cleanUpDrag_: function() { | 715 cleanUpDrag_: function() { |
| 650 this.classList.remove('animating-tile-page'); | |
| 651 for (var i = 0; i < this.tileElements_.length; i++) { | 716 for (var i = 0; i < this.tileElements_.length; i++) { |
| 652 // The current drag tile will be positioned in its dragend handler. | 717 // The current drag tile will be positioned in its dragend handler. |
| 653 if (this.tileElements_[i] == this.currentlyDraggingTile) | 718 if (this.tileElements_[i] == this.currentlyDraggingTile) |
| 654 continue; | 719 continue; |
| 655 this.positionTile_(i); | 720 this.positionTile_(i); |
| 656 } | 721 } |
| 657 | 722 |
| 658 // Remove the drag mask. | 723 // Remove the drag mask. |
| 659 this.updateMask_(); | 724 this.updateMask_(); |
| 660 }, | 725 }, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 679 var adjustment = i <= newDragIndex ? -1 : 0; | 744 var adjustment = i <= newDragIndex ? -1 : 0; |
| 680 else | 745 else |
| 681 var adjustment = i >= newDragIndex ? 1 : 0; | 746 var adjustment = i >= newDragIndex ? 1 : 0; |
| 682 | 747 |
| 683 this.positionTile_(i, adjustment); | 748 this.positionTile_(i, adjustment); |
| 684 } | 749 } |
| 685 this.currentDropIndex_ = newDragIndex; | 750 this.currentDropIndex_ = newDragIndex; |
| 686 }, | 751 }, |
| 687 | 752 |
| 688 /** | 753 /** |
| 689 * This is equivalent to dragEnters_, but for drags over the navigation | 754 * These are equivalent to dragEnters_ and isCurrentDragTarget_, but for |
| 690 * dot. | 755 * drags over the navigation dot. |
| 756 * TODO(estade): thunkify the event handlers in the same manner as the |
| 757 * tile grid drag handlers. |
| 691 */ | 758 */ |
| 692 dotDragEnters_: 0, | 759 dotDragEnters_: 0, |
| 760 dotIsCurrentDragTarget_: false, |
| 693 | 761 |
| 694 /** | 762 /** |
| 695 * A drag has entered the navigation dot. If the user hovers long enough, | 763 * A drag has entered the navigation dot. If the user hovers long enough, |
| 696 * we will navigate to the relevant page. | 764 * we will navigate to the relevant page. |
| 697 * @param {Event} e The MouseOver event for the drag. | 765 * @param {Event} e The MouseOver event for the drag. |
| 698 */ | 766 */ |
| 699 onDragEnterDot_: function(e) { | 767 onDragEnterDot_: function(e) { |
| 700 if (++this.dotDragEnters_ > 1) | 768 if (++this.dotDragEnters_ > 1) |
| 701 return; | 769 return; |
| 702 | 770 |
| 703 if (!TilePage.currentlyDraggingTile) | 771 if (!this.shouldAcceptDrag(TilePage.currentlyDraggingTile, |
| 772 e.dataTransfer)) { |
| 704 return; | 773 return; |
| 705 if (!this.acceptOutsideDrags()) | 774 } |
| 706 return; | 775 |
| 776 this.dotIsCurrentDragTarget_ = true; |
| 707 | 777 |
| 708 var self = this; | 778 var self = this; |
| 709 function navPageClearTimeout() { | 779 function navPageClearTimeout() { |
| 710 self.navigationDot.showPage(); | 780 self.navigationDot.showPage(); |
| 711 self.dotNavTimeout = null; | 781 self.dotNavTimeout = null; |
| 712 } | 782 } |
| 713 this.dotNavTimeout = window.setTimeout(navPageClearTimeout, 500); | 783 this.dotNavTimeout = window.setTimeout(navPageClearTimeout, 500); |
| 714 }, | 784 }, |
| 715 | 785 |
| 716 /** | 786 /** |
| 717 * The drag has left the navigation dot. | 787 * The drag has left the navigation dot. |
| 718 * @param {Event} e The MouseOver event for the drag. | 788 * @param {Event} e The MouseOver event for the drag. |
| 719 */ | 789 */ |
| 720 onDragLeaveDot_: function(e) { | 790 onDragLeaveDot_: function(e) { |
| 721 if (--this.dotDragEnters_ > 0) | 791 if (--this.dotDragEnters_ > 0) |
| 722 return; | 792 return; |
| 723 | 793 |
| 794 if (!this.dotIsCurrentDragTarget_) |
| 795 return; |
| 796 this.dotIsCurrentDragTarget_ = false; |
| 797 |
| 724 if (this.dotNavTimeout) { | 798 if (this.dotNavTimeout) { |
| 725 window.clearTimeout(this.dotNavTimeout); | 799 window.clearTimeout(this.dotNavTimeout); |
| 726 this.dotNavTimeout = null; | 800 this.dotNavTimeout = null; |
| 727 } | 801 } |
| 728 }, | 802 }, |
| 803 |
| 804 /** |
| 805 * Checks if a page can accept a drag with the given data. |
| 806 * @param {Object} tile The drag tile, if any. |
| 807 * @param {Object} dataTransfer The dataTransfer object, if the drag object |
| 808 * is not a tile (e.g. it is a link). |
| 809 * @return {boolean} True if this page can handle the drag. |
| 810 */ |
| 811 shouldAcceptDrag: function(tile, dataTransfer) { |
| 812 return false; |
| 813 }, |
| 814 |
| 815 /** |
| 816 * Called to accept a drag drop. |
| 817 * @param {Object} dataTransfer The data transfer object that holds the drop |
| 818 * data. |
| 819 * @param {number} index The tile index at which the drop occurred. |
| 820 */ |
| 821 addOutsideData: function(dataTransfer, index) { |
| 822 // This should not get called unless there is a non-default |
| 823 // implementation. |
| 824 assert(false); |
| 825 }, |
| 729 }; | 826 }; |
| 730 | 827 |
| 731 return { | 828 return { |
| 732 TilePage: TilePage, | 829 TilePage: TilePage, |
| 733 }; | 830 }; |
| 734 }); | 831 }); |
| OLD | NEW |