Changeset 143723 in webkit


Ignore:
Timestamp:
Feb 22, 2013 5:44:06 AM (11 years ago)
Author:
keishi@webkit.org
Message:

Add scroll view for new calendar picker
https://bugs.webkit.org/show_bug.cgi?id=110137

Reviewed by Kent Tamura.

Adding a scroll view class as part of the new calendar picker (Bug 109439).

No new tests. Code not yet used.

  • Resources/pagepopups/calendarPicker.js:

(View):
(View.prototype.offsetRelativeTo): Returns the offset position of this view relative to the given ancestor element.
(View.prototype.attachTo): Attaches view to a node or view.
(View.prototype.bindCallbackMethods): Binds all methods starting with "on" to this.
(ScrollView): A custom scroll view that can contain extremely long content. CSS values have a limit. This can go beyond that.
(ScrollView.prototype.setWidth): Sets the view width.
(ScrollView.prototype.width):
(ScrollView.prototype.setHeight):Sets the view height.
(ScrollView.prototype.height):
(ScrollView.prototype.onScrollAnimatorStep): Callback for scroll animator step.
(ScrollView.prototype.scrollTo): Scrolls to a certain offset.
(ScrollView.prototype.scrollBy): Scrolls by a certain amount.
(ScrollView.prototype.contentOffset): Current content offset.
(ScrollView.prototype.onMouseWheel): Scroll with the mouse wheel.
(ScrollView.prototype.setContentOffset): Sets the content offset.
(ScrollView.prototype.contentPositionForContentOffset): Returns where the content element should be positioned.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r143721 r143723  
     12013-02-22  Keishi Hattori  <keishi@webkit.org>
     2
     3        Add scroll view for new calendar picker
     4        https://bugs.webkit.org/show_bug.cgi?id=110137
     5
     6        Reviewed by Kent Tamura.
     7
     8        Adding a scroll view class as part of the new calendar picker (Bug 109439).
     9
     10        No new tests. Code not yet used.
     11
     12        * Resources/pagepopups/calendarPicker.js:
     13        (View):
     14        (View.prototype.offsetRelativeTo): Returns the offset position of this view relative to the given ancestor element.
     15        (View.prototype.attachTo): Attaches view to a node or view.
     16        (View.prototype.bindCallbackMethods): Binds all methods starting with "on" to this.
     17        (ScrollView): A custom scroll view that can contain extremely long content. CSS values have a limit. This can go beyond that.
     18        (ScrollView.prototype.setWidth): Sets the view width.
     19        (ScrollView.prototype.width):
     20        (ScrollView.prototype.setHeight):Sets the view height.
     21        (ScrollView.prototype.height):
     22        (ScrollView.prototype.onScrollAnimatorStep): Callback for scroll animator step.
     23        (ScrollView.prototype.scrollTo): Scrolls to a certain offset.
     24        (ScrollView.prototype.scrollBy): Scrolls by a certain amount.
     25        (ScrollView.prototype.contentOffset): Current content offset.
     26        (ScrollView.prototype.onMouseWheel): Scroll with the mouse wheel.
     27        (ScrollView.prototype.setContentOffset): Sets the content offset.
     28        (ScrollView.prototype.contentPositionForContentOffset): Returns where the content element should be positioned.
     29
    1302013-02-22  Alexander Pavlov  <apavlov@chromium.org>
    231
  • trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js

    r143598 r143723  
    890890    this.step(this);
    891891    this._lastStepTime = now;
     892};
     893
     894/**
     895 * @constructor
     896 * @extends EventEmitter
     897 * @param {?Element} element
     898 * View adds itself as a property on the element so we can access it from Event.target.
     899 */
     900function View(element) {
     901    EventEmitter.call(this);
     902    /**
     903     * @type {Element}
     904     * @const
     905     */
     906    this.element = element || createElement("div");
     907    this.element.$view = this;
     908    this.bindCallbackMethods();
     909}
     910
     911View.prototype = Object.create(EventEmitter.prototype);
     912
     913/**
     914 * @param {!Element} ancestorElement
     915 * @return {?Object}
     916 */
     917View.prototype.offsetRelativeTo = function(ancestorElement) {
     918    var x = 0;
     919    var y = 0;
     920    var element = this.element;
     921    while (element) {
     922        x += element.offsetLeft  || 0;
     923        y += element.offsetTop || 0;
     924        element = element.offsetParent;
     925        if (element === ancestorElement)
     926            return {x: x, y: y};
     927    }
     928    return null;
     929};
     930
     931/**
     932 * @param {!View|Node} parent
     933 * @param {?View|Node=} before
     934 */
     935View.prototype.attachTo = function(parent, before) {
     936    if (parent instanceof View)
     937        return this.attachTo(parent.element, before);
     938    if (typeof before === "undefined")
     939        before = null;
     940    if (before instanceof View)
     941        before = before.element;
     942    parent.insertBefore(this.element, before);
     943};
     944
     945View.prototype.bindCallbackMethods = function() {
     946    for (var methodName in this) {
     947        if (!/^on[A-Z]/.test(methodName))
     948            continue;
     949        if (this.hasOwnProperty(methodName))
     950            continue;
     951        var method = this[methodName];
     952        if (!(method instanceof Function))
     953            continue;
     954        this[methodName] = method.bind(this);
     955    }
     956};
     957
     958/**
     959 * @constructor
     960 * @extends View
     961 */
     962function ScrollView() {
     963    View.call(this, createElement("div", ScrollView.ClassNameScrollView));
     964    /**
     965     * @type {Element}
     966     * @const
     967     */
     968    this.contentElement = createElement("div", ScrollView.ClassNameScrollViewContent);
     969    this.element.appendChild(this.contentElement);
     970    /**
     971     * @type {number}
     972     */
     973    this.minimumContentOffset = -Infinity;
     974    /**
     975     * @type {number}
     976     */
     977    this.maximumContentOffset = Infinity;
     978    /**
     979     * @type {number}
     980     * @protected
     981     */
     982    this._contentOffset = 0;
     983    /**
     984     * @type {number}
     985     * @protected
     986     */
     987    this._width = 0;
     988    /**
     989     * @type {number}
     990     * @protected
     991     */
     992    this._height = 0;
     993    /**
     994     * @type {Animator}
     995     * @protected
     996     */
     997    this._scrollAnimator = new Animator();
     998    this._scrollAnimator.step = this.onScrollAnimatorStep;
     999
     1000    /**
     1001     * @type {?Object}
     1002     */
     1003    this.delegate = null;
     1004
     1005    this.element.addEventListener("mousewheel", this.onMouseWheel, false);
     1006
     1007    /**
     1008     * The content offset is partitioned so the it can go beyond the CSS limit
     1009     * of 33554433px.
     1010     * @type {number}
     1011     * @protected
     1012     */
     1013    this._partitionNumber = 0;
     1014}
     1015
     1016ScrollView.prototype = Object.create(View.prototype);
     1017
     1018ScrollView.PartitionHeight = 100000;
     1019ScrollView.ClassNameScrollView = "scroll-view";
     1020ScrollView.ClassNameScrollViewContent = "scroll-view-content";
     1021
     1022/**
     1023 * @param {!number} width
     1024 */
     1025ScrollView.prototype.setWidth = function(width) {
     1026    console.assert(isFinite(width));
     1027    if (this._width === width)
     1028        return;
     1029    this._width = width;
     1030    this.element.style.width = this._width + "px";
     1031};
     1032
     1033/**
     1034 * @return {!number}
     1035 */
     1036ScrollView.prototype.width = function() {
     1037    return this._width;
     1038};
     1039
     1040/**
     1041 * @param {!number} height
     1042 */
     1043ScrollView.prototype.setHeight = function(height) {
     1044    console.assert(isFinite(height));
     1045    if (this._height === height)
     1046        return;
     1047    this._height = height;
     1048    this.element.style.height = height + "px";
     1049    if (this.delegate)
     1050        this.delegate.scrollViewDidChangeHeight(this);
     1051};
     1052
     1053/**
     1054 * @return {!number}
     1055 */
     1056ScrollView.prototype.height = function() {
     1057    return this._height;
     1058};
     1059
     1060/**
     1061 * @param {!Animator} animator
     1062 */
     1063ScrollView.prototype.onScrollAnimatorStep = function(animator) {
     1064    this.setContentOffset(animator.currentValue);
     1065};
     1066
     1067/**
     1068 * @param {!number} offset
     1069 * @param {?boolean} animate
     1070 */
     1071ScrollView.prototype.scrollTo = function(offset, animate) {
     1072    console.assert(isFinite(offset));
     1073    if (!animate) {
     1074        this.setContentOffset(offset);
     1075        return;
     1076    }
     1077    this._scrollAnimator.setFrom(this._contentOffset);
     1078    this._scrollAnimator.setTo(offset);
     1079    this._scrollAnimator.duration = 300;
     1080    this._scrollAnimator.start();
     1081};
     1082
     1083/**
     1084 * @param {!number} offset
     1085 * @param {?boolean} animate
     1086 */
     1087ScrollView.prototype.scrollBy = function(offset, animate) {
     1088    this.scrollTo(this._contentOffset + offset, animate);
     1089};
     1090
     1091/**
     1092 * @return {!number}
     1093 */
     1094ScrollView.prototype.contentOffset = function() {
     1095    return this._contentOffset;
     1096};
     1097
     1098/**
     1099 * @param {?Event} event
     1100 */
     1101ScrollView.prototype.onMouseWheel = function(event) {
     1102    this.setContentOffset(this._contentOffset - event.wheelDelta / 30);
     1103    event.stopPropagation();
     1104    event.preventDefault();
     1105};
     1106
     1107
     1108/**
     1109 * @param {!number} value
     1110 */
     1111ScrollView.prototype.setContentOffset = function(value) {
     1112    console.assert(isFinite(value));
     1113    value = Math.min(this.maximumContentOffset - this._height, Math.max(this.minimumContentOffset, Math.floor(value)));
     1114    if (this._contentOffset === value)
     1115        return;
     1116    var newPartitionNumber = Math.floor(value / ScrollView.PartitionHeight);   
     1117    var partitionChanged = this._partitionNumber !== newPartitionNumber;
     1118    this._partitionNumber = newPartitionNumber;
     1119    this._contentOffset = value;
     1120    this.contentElement.style.webkitTransform = "translate(0, " + (-this.contentPositionForContentOffset(this._contentOffset)) + "px)";
     1121    if (this.delegate) {
     1122        this.delegate.scrollViewDidChangeContentOffset(this);
     1123        if (partitionChanged)
     1124            this.delegate.scrollViewDidChangePartition(this);
     1125    }
     1126};
     1127
     1128/**
     1129 * @param {!number} offset
     1130 */
     1131ScrollView.prototype.contentPositionForContentOffset = function(offset) {
     1132    return offset - this._partitionNumber * ScrollView.PartitionHeight;
    8921133};
    8931134
Note: See TracChangeset for help on using the changeset viewer.