Skip to content
This repository has been archived by the owner on Jun 9, 2022. It is now read-only.

Support Closure Compiler with ADVANCED_OPTIMIZATIONS #1

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 77 additions & 32 deletions lib/ftscroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,12 @@
/*jslint nomen: true, vars: true, browser: true, node: true, es5: true, continue: true, white: true*/
/*globals FTScrollerOptions*/

var FTScroller, CubicBezier;

(function () {
'use strict';

// Global flag to determine if any scroll is currently active. This prevents
// issues when using multiple scrollers, particularly when they're nested.
var _ftscrollerMoving = false;
var _ftscrollerMoving = null;

// Determine whether pointer events or touch events can be used
var _trackPointerEvents = window.navigator.msPointerEnabled;
Expand Down Expand Up @@ -159,8 +157,11 @@ var FTScroller, CubicBezier;
* construct the scroller in, and any scrolling options.
* Note that app-wide options can also be set using a global FTScrollerOptions
* object.
*
* @constructor
* @expose
*/
FTScroller = function (domNode, options) {
self.FTScroller = function FTScroller(domNode, options) {
var key;
var destroy, setSnapSize, scrollTo, scrollBy, updateDimensions, addEventListener, removeEventListener, _startScroll, _updateScroll, _endScroll, _finalizeScroll, _interruptScroll, _flingScroll, _snapScroll, _getSnapPositionForPosition, _initializeDOM, _existingDOMValid, _domChanged, _updateDimensions, _updateScrollbarDimensions, _updateElementPosition, _updateSegments, _setAxisPosition, _scheduleAxisPosition, _fireEvent, _childFocused, _modifyDistanceBeyondBounds, _distancesBeyondBounds, _startAnimation, _scheduleRender, _cancelAnimation, _toggleEventHandlers, _onTouchStart, _onTouchMove, _onTouchEnd, _onMouseDown, _onMouseMove, _onMouseUp, _onPointerDown, _onPointerMove, _onPointerUp, _onPointerCancel, _onPointerCaptureEnd, _onClick, _onMouseScroll, _captureInput, _releaseInputCapture, _getBoundingRect;

Expand All @@ -173,89 +174,109 @@ var FTScroller, CubicBezier;
var _instanceOptions = {

// Whether to display scrollbars as appropriate
/** @expose */
scrollbars: true,

// Enable scrolling on the X axis if content is available
/** @expose */
scrollingX: true,

// Enable scrolling on the Y axis if content is available
/** @expose */
scrollingY: true,

// The initial movement required to trigger a scroll, in pixels; this is the point at which
// the scroll is exclusive to this particular FTScroller instance.
/** @expose */
scrollBoundary: 1,

// The initial movement required to trigger a visual indication that scrolling is occurring,
// in pixels. This is enforced to be less than or equal to the scrollBoundary, and is used to
// define when the scroller starts drawing changes in response to an input, even if the scroll
// is not treated as having begun/locked yet.
/** @expose */
scrollResponseBoundary: 1,

// Whether to always enable scrolling, even if the content of the scroller does not
// require the scroller to function. This makes the scroller behave more like an
// element set to "overflow: scroll", with bouncing always occurring if enabled.
/** @expose */
alwaysScroll: false,

// The content width to use when determining scroller dimensions. If this
// is false, the width will be detected based on the actual content.
/** @expose */
contentWidth: undefined,

// The content height to use when determining scroller dimensions. If this
// is false, the height will be detected based on the actual content.
/** @expose */
contentHeight: undefined,

// Enable snapping of content to 'pages' or a pixel grid
/** @expose */
snapping: false,

// Define the horizontal interval of the pixel grid; snapping must be enabled for this to
// take effect. If this is not defined, snapping will use intervals based on container size.
/** @expose */
snapSizeX: undefined,

// Define the vertical interval of the pixel grid; snapping must be enabled for this to
// take effect. If this is not defined, snapping will use intervals based on container size.
/** @expose */
snapSizeY: undefined,

// Control whether snapping should be fully paginated, only ever flicking to the next page
// and not beyond. Snapping needs to be enabled for this to take effect.
/** @expose */
paginatedSnap: false,

// Allow scroll bouncing and elasticity near the ends and grid
/** @expose */
bouncing: true,

// Automatically detects changes to the contained markup and
// updates its dimensions whenever the content changes. This is
// set to false if a contentWidth or contentHeight are supplied.
/** @expose */
updateOnChanges: true,

// Automatically catches changes to the window size and updates
// its dimensions.
/** @expose */
updateOnWindowResize: false,

// The alignment to use if the content is smaller than the container;
// this also applies to initial positioning of scrollable content.
// Valid alignments are -1 (top or left), 0 (center), and 1 (bottom or right).
/** @expose */
baseAlignments: { x: -1, y: -1 },

// Whether to use a window scroll flag, eg window.foo, to control whether
// to allow scrolling to start or now. If the window flag is set to true,
// this element will not start scrolling; this element will also toggle
// the variable while scrolling
/** @expose */
windowScrollingActiveFlag: undefined,

// Instead of always using translate3d for transforms, a mix of translate3d
// and translate with a hardware acceleration class used to trigger acceleration
// is used; this is to allow CSS inheritance to be used to allow dynamic
// disabling of backing layers on older platforms.
/** @expose */
hwAccelerationClass: 'ftscroller_hwaccelerated',

// While use of requestAnimationFrame is highly recommended on platforms
// which support it, it can result in the animation being a further half-frame
// behind the input method, increasing perceived lag slightly. To disable this,
// set this property to false.
/** @expose */
enableRequestAnimationFrameSupport: true,

// Set the maximum time (ms) that a fling can take to complete; if
// this is not set, flings will complete instantly
/** @expose */
maxFlingDuration: 1000
};

Expand Down Expand Up @@ -317,11 +338,11 @@ var FTScroller, CubicBezier;
var _kDecelerateBezier = new CubicBezier(0, 0.5, 0.5, 1);

// Allow certain events to be debounced
var _domChangeDebouncer = false;
var _scrollWheelEndDebouncer = false;
var _domChangeDebouncer = null;
var _scrollWheelEndDebouncer = null;

// Performance switches on browsers supporting requestAnimationFrame
var _animationFrameRequest = false;
var _animationFrameRequest = 0;
var _animationTargetPosition = { x: 0, y: 0 };
var _reqAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || false;
var _cancelAnimationFrame = window.cancelAnimationFrame || window.cancelRequestAnimationFrame || window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame || false;
Expand Down Expand Up @@ -400,7 +421,7 @@ var FTScroller, CubicBezier;
_cancelAnimation();
if (_domChangeDebouncer) {
window.clearTimeout(_domChangeDebouncer);
_domChangeDebouncer = false;
_domChangeDebouncer = null;
}
for (i = 0, l = _timeouts.length; i < l; i = i + 1) {
window.clearTimeout(_timeouts[i]);
Expand Down Expand Up @@ -430,7 +451,7 @@ var FTScroller, CubicBezier;

// If this is currently tracked as a scrolling instance, clear the flag
if (_ftscrollerMoving && _ftscrollerMoving === _self) {
_ftscrollerMoving = false;
_ftscrollerMoving = null;
if (_instanceOptions.windowScrollingActiveFlag) {
window[_instanceOptions.windowScrollingActiveFlag] = false;
}
Expand Down Expand Up @@ -644,6 +665,12 @@ var FTScroller, CubicBezier;

/**
* Continue a scroll as a result of an updated position
*
* @param {number} inputX
* @param {number} inputY
* @param {number} inputTime
* @param {MouseEvent} rawEvent
* @param {boolean} [scrollInterrupt]
*/
_updateScroll = function _updateScroll(inputX, inputY, inputTime, rawEvent, scrollInterrupt) {
var axis, otherScrollerActive;
Expand Down Expand Up @@ -791,6 +818,9 @@ var FTScroller, CubicBezier;
* Complete a scroll with a final event time if available (it may
* not be, depending on the input type); this may continue the scroll
* with a fling and/or bounceback depending on options.
*
* @param {number} inputTime
* @param {MouseEvent} [rawEvent]
*/
_endScroll = function _endScroll(inputTime, rawEvent) {
_inputIdentifier = false;
Expand Down Expand Up @@ -829,6 +859,8 @@ var FTScroller, CubicBezier;

/**
* Remove the scrolling class, cleaning up display.
*
* @param {boolean} [scrollCancelled]
*/
_finalizeScroll = function _finalizeScroll(scrollCancelled) {
var i, l, axis;
Expand Down Expand Up @@ -1158,6 +1190,8 @@ var FTScroller, CubicBezier;

/**
* Bounce back into bounds if necessary, or snap to a grid location.
*
* @param {boolean} [scrollCancelled]
*/
_snapScroll = function _snapScroll(scrollCancelled) {
var axis;
Expand Down Expand Up @@ -1384,6 +1418,9 @@ var FTScroller, CubicBezier;
}, 100);
};

/**
* @param {boolean} [ignoreSnapScroll]
*/
_updateDimensions = function _updateDimensions(ignoreSnapScroll) {
var axis;

Expand All @@ -1395,7 +1432,7 @@ var FTScroller, CubicBezier;

if (_domChangeDebouncer) {
window.clearTimeout(_domChangeDebouncer);
_domChangeDebouncer = false;
_domChangeDebouncer = null;
}
var containerWidth, containerHeight, startAlignments;

Expand Down Expand Up @@ -1424,7 +1461,7 @@ var FTScroller, CubicBezier;
var rawScrollHeight = options.contentHeight || _contentParentNode.offsetHeight;
var scrollWidth = rawScrollWidth;
var scrollHeight = rawScrollHeight;
var targetPosition = { x: false, y: false };
var targetPosition = { x: -1, y: -1 };

// Update snap grid
if (!_snapGridSize.userX) {
Expand Down Expand Up @@ -1488,11 +1525,11 @@ var FTScroller, CubicBezier;
}
}
}
if (_instanceOptions.scrollingX && targetPosition.x !== false) {
if (_instanceOptions.scrollingX && targetPosition.x !== -1) {
_setAxisPosition('x', targetPosition.x, 0);
_baseScrollPosition.x = targetPosition.x;
}
if (_instanceOptions.scrollingY && targetPosition.y !== false) {
if (_instanceOptions.scrollingY && targetPosition.y !== -1) {
_setAxisPosition('y', targetPosition.y, 0);
_baseScrollPosition.y = targetPosition.y;
}
Expand Down Expand Up @@ -1582,6 +1619,13 @@ var FTScroller, CubicBezier;
}
};

/**
* @param {string} axis
* @param {number} position
* @param {number} [animationDuration]
* @param {CubicBezier} [animationBezier]
* @param {number} [boundsCrossDelay]
*/
_setAxisPosition = function _setAxisPosition(axis, position, animationDuration, animationBezier, boundsCrossDelay) {
var transitionCSSString, newPositionAtExtremity = null;

Expand Down Expand Up @@ -1659,7 +1703,7 @@ var FTScroller, CubicBezier;
_eventListeners[eventName][i](eventObject);
} catch (error) {
if (window.console && window.console.error) {
window.console.error(error.message + ' (' + error.sourceURL + ', line ' + error.line + ')');
window.console.error(error.message + ' (' + error.sourceURL + ', line ' + error.lineNumber + ')');
}
}
}
Expand Down Expand Up @@ -1741,7 +1785,7 @@ var FTScroller, CubicBezier;
_startAnimation = function _startAnimation() {
if (_reqAnimationFrame) {
_cancelAnimation();
_animationFrameRequest = _reqAnimationFrame(_scheduleRender);
_animationFrameRequest = _reqAnimationFrame.call(window, _scheduleRender);
}
};

Expand All @@ -1755,7 +1799,7 @@ var FTScroller, CubicBezier;
var axis;

// Request the next update at once
_animationFrameRequest = _reqAnimationFrame(_scheduleRender);
_animationFrameRequest = _reqAnimationFrame.call(window, _scheduleRender);

// Perform the draw.
for (axis in _scrollableAxes) {
Expand All @@ -1769,12 +1813,12 @@ var FTScroller, CubicBezier;
* Stops the animation process.
*/
_cancelAnimation = function _cancelAnimation() {
if (_animationFrameRequest === false || !_cancelAnimationFrame) {
if (!_animationFrameRequest || !_cancelAnimationFrame) {
return;
}

_cancelAnimationFrame(_animationFrameRequest);
_animationFrameRequest = false;
_cancelAnimationFrame.call(window, _animationFrameRequest);
_animationFrameRequest = 0;
};

/**
Expand Down Expand Up @@ -2207,7 +2251,7 @@ var FTScroller, CubicBezier;
*/
FTScroller.prototype.getPrependedHTML = function (excludeXAxis, excludeYAxis, hwAccelerationClass) {
if (!hwAccelerationClass) {
if (typeof FTScrollerOptions === 'object' && FTScrollerOptions.hwAccelerationClass) {
if (typeof FTScrollerOptions === 'object' && /** @expose */ FTScrollerOptions.hwAccelerationClass) {
hwAccelerationClass = FTScrollerOptions.hwAccelerationClass;
} else {
hwAccelerationClass = 'ftscroller_hwaccelerated';
Expand Down Expand Up @@ -2257,37 +2301,38 @@ var FTScroller, CubicBezier;

return output;
};
}());


(function () {
'use strict';

/**
* Represents a two-dimensional cubic bezier curve with the starting
* point (0, 0) and the end point (1, 1). The two control points p1 and p2
* have x and y coordinates between 0 and 1.
*
* This type of bezier curves can be used as CSS transform timing functions.
*
* @constructor
* @param {number} [p1x]
* @param {number} [p1y]
* @param {number} [p2x]
* @param {number} [p2y]
*/
CubicBezier = function (p1x, p1y, p2x, p2y) {
function CubicBezier(p1x, p1y, p2x, p2y) {
if (!(p1x >= 0 && p1x <= 1)) {
throw new RangeError('"p1x" must be a number between 0 and 1. ' + 'Got ' + p1x + 'instead.');
throw new RangeError('"p1x" must be a number between 0 and 1. ' + 'Got ' + p1x + ' instead.');
}
if (!(p1y >= 0 && p1y <= 1)) {
throw new RangeError('"p1y" must be a number between 0 and 1. ' + 'Got ' + p1y + 'instead.');
throw new RangeError('"p1y" must be a number between 0 and 1. ' + 'Got ' + p1y + ' instead.');
}
if (!(p2x >= 0 && p2x <= 1)) {
throw new RangeError('"p2x" must be a number between 0 and 1. ' + 'Got ' + p2x + 'instead.');
throw new RangeError('"p2x" must be a number between 0 and 1. ' + 'Got ' + p2x + ' instead.');
}
if (!(p2y >= 0 && p2y <= 1)) {
throw new RangeError('"p2y" must be a number between 0 and 1. ' + 'Got ' + p2y + 'instead.');
throw new RangeError('"p2y" must be a number between 0 and 1. ' + 'Got ' + p2y + ' instead.');
}

// Control points
this._p1 = { x: p1x, y: p1y };
this._p2 = { x: p2x, y: p2y };
};
}

CubicBezier.prototype._getCoordinateForT = function (t, p1, p2) {
var c = 3 * p1,
Expand Down Expand Up @@ -2457,7 +2502,7 @@ var FTScroller, CubicBezier;
* t === 1 or t === 0 are the starting/ending points of the curve, so no
* division is needed.
*
* @returns {CubicBezier[]} Returns an array containing two bezier curves
* @returns {Array.<CubicBezier>} Returns an array containing two bezier curves
* to the left and the right of t.
*/
CubicBezier.prototype.divideAtT = function (t) {
Expand Down