File: /var/www/vhost/disk-apps/pwa.sports-crowd.com/node_modules/@material/tab-scroller/foundation.js
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import { __assign, __extends, __read } from "tslib";
import { MDCFoundation } from '@material/base/foundation';
import { cssClasses, strings } from './constants';
import { MDCTabScrollerRTLDefault } from './rtl-default-scroller';
import { MDCTabScrollerRTLNegative } from './rtl-negative-scroller';
import { MDCTabScrollerRTLReverse } from './rtl-reverse-scroller';
/** MDC Tab Scroller Foundation */
var MDCTabScrollerFoundation = /** @class */ (function (_super) {
__extends(MDCTabScrollerFoundation, _super);
function MDCTabScrollerFoundation(adapter) {
var _this = _super.call(this, __assign(__assign({}, MDCTabScrollerFoundation.defaultAdapter), adapter)) || this;
/**
* Controls whether we should handle the transitionend and interaction events
* during the animation.
*/
_this.isAnimating = false;
return _this;
}
Object.defineProperty(MDCTabScrollerFoundation, "cssClasses", {
get: function () {
return cssClasses;
},
enumerable: false,
configurable: true
});
Object.defineProperty(MDCTabScrollerFoundation, "strings", {
get: function () {
return strings;
},
enumerable: false,
configurable: true
});
Object.defineProperty(MDCTabScrollerFoundation, "defaultAdapter", {
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
eventTargetMatchesSelector: function () { return false; },
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
addScrollAreaClass: function () { return undefined; },
setScrollAreaStyleProperty: function () { return undefined; },
setScrollContentStyleProperty: function () { return undefined; },
getScrollContentStyleValue: function () { return ''; },
setScrollAreaScrollLeft: function () { return undefined; },
getScrollAreaScrollLeft: function () { return 0; },
getScrollContentOffsetWidth: function () { return 0; },
getScrollAreaOffsetWidth: function () { return 0; },
computeScrollAreaClientRect: function () {
return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 });
},
computeScrollContentClientRect: function () {
return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 });
},
computeHorizontalScrollbarHeight: function () { return 0; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: false,
configurable: true
});
MDCTabScrollerFoundation.prototype.init = function () {
// Compute horizontal scrollbar height on scroller with overflow initially
// hidden, then update overflow to scroll and immediately adjust bottom
// margin to avoid the scrollbar initially appearing before JS runs.
var horizontalScrollbarHeight = this.adapter.computeHorizontalScrollbarHeight();
this.adapter.setScrollAreaStyleProperty('margin-bottom', -horizontalScrollbarHeight + 'px');
this.adapter.addScrollAreaClass(MDCTabScrollerFoundation.cssClasses.SCROLL_AREA_SCROLL);
};
/**
* Computes the current visual scroll position
*/
MDCTabScrollerFoundation.prototype.getScrollPosition = function () {
if (this.isRTL()) {
return this.computeCurrentScrollPositionRTL();
}
var currentTranslateX = this.calculateCurrentTranslateX();
var scrollLeft = this.adapter.getScrollAreaScrollLeft();
return scrollLeft - currentTranslateX;
};
/**
* Handles interaction events that occur during transition
*/
MDCTabScrollerFoundation.prototype.handleInteraction = function () {
// Early exit if we aren't animating
if (!this.isAnimating) {
return;
}
// Prevent other event listeners from handling this event
this.stopScrollAnimation();
};
/**
* Handles the transitionend event
*/
MDCTabScrollerFoundation.prototype.handleTransitionEnd = function (evt) {
// Early exit if we aren't animating or the event was triggered by a
// different element.
var evtTarget = evt.target;
if (!this.isAnimating ||
!this.adapter.eventTargetMatchesSelector(evtTarget, MDCTabScrollerFoundation.strings.CONTENT_SELECTOR)) {
return;
}
this.isAnimating = false;
this.adapter.removeClass(MDCTabScrollerFoundation.cssClasses.ANIMATING);
};
/**
* Increment the scroll value by the scrollXIncrement using animation.
* @param scrollXIncrement The value by which to increment the scroll position
*/
MDCTabScrollerFoundation.prototype.incrementScroll = function (scrollXIncrement) {
// Early exit for non-operational increment values
if (scrollXIncrement === 0) {
return;
}
this.animate(this.getIncrementScrollOperation(scrollXIncrement));
};
/**
* Increment the scroll value by the scrollXIncrement without animation.
* @param scrollXIncrement The value by which to increment the scroll position
*/
MDCTabScrollerFoundation.prototype.incrementScrollImmediate = function (scrollXIncrement) {
// Early exit for non-operational increment values
if (scrollXIncrement === 0) {
return;
}
var operation = this.getIncrementScrollOperation(scrollXIncrement);
if (operation.scrollDelta === 0) {
return;
}
this.stopScrollAnimation();
this.adapter.setScrollAreaScrollLeft(operation.finalScrollPosition);
};
/**
* Scrolls to the given scrollX value
*/
MDCTabScrollerFoundation.prototype.scrollTo = function (scrollX) {
if (this.isRTL()) {
this.scrollToImplRTL(scrollX);
return;
}
this.scrollToImpl(scrollX);
};
/**
* @return Browser-specific {@link MDCTabScrollerRTL} instance.
*/
MDCTabScrollerFoundation.prototype.getRTLScroller = function () {
if (!this.rtlScrollerInstance) {
this.rtlScrollerInstance = this.rtlScrollerFactory();
}
return this.rtlScrollerInstance;
};
/**
* @return translateX value from a CSS matrix transform function string.
*/
MDCTabScrollerFoundation.prototype.calculateCurrentTranslateX = function () {
var transformValue = this.adapter.getScrollContentStyleValue('transform');
// Early exit if no transform is present
if (transformValue === 'none') {
return 0;
}
// The transform value comes back as a matrix transformation in the form
// of `matrix(a, b, c, d, tx, ty)`. We only care about tx (translateX) so
// we're going to grab all the parenthesized values, strip out tx, and
// parse it.
var match = /\((.+?)\)/.exec(transformValue);
if (!match) {
return 0;
}
var matrixParams = match[1];
// tslint:disable-next-line:ban-ts-suppressions "Unused vars" should be a linter warning, not a compiler error.
// @ts-ignore These unused variables should retain their semantic names for
// clarity.
var _a = __read(matrixParams.split(','), 6), a = _a[0], b = _a[1], c = _a[2], d = _a[3], tx = _a[4], ty = _a[5];
return parseFloat(tx); // tslint:disable-line:ban
};
/**
* Calculates a safe scroll value that is > 0 and < the max scroll value
* @param scrollX The distance to scroll
*/
MDCTabScrollerFoundation.prototype.clampScrollValue = function (scrollX) {
var edges = this.calculateScrollEdges();
return Math.min(Math.max(edges.left, scrollX), edges.right);
};
MDCTabScrollerFoundation.prototype.computeCurrentScrollPositionRTL = function () {
var translateX = this.calculateCurrentTranslateX();
return this.getRTLScroller().getScrollPositionRTL(translateX);
};
MDCTabScrollerFoundation.prototype.calculateScrollEdges = function () {
var contentWidth = this.adapter.getScrollContentOffsetWidth();
var rootWidth = this.adapter.getScrollAreaOffsetWidth();
return {
left: 0,
right: contentWidth - rootWidth,
};
};
/**
* Internal scroll method
* @param scrollX The new scroll position
*/
MDCTabScrollerFoundation.prototype.scrollToImpl = function (scrollX) {
var currentScrollX = this.getScrollPosition();
var safeScrollX = this.clampScrollValue(scrollX);
var scrollDelta = safeScrollX - currentScrollX;
this.animate({
finalScrollPosition: safeScrollX,
scrollDelta: scrollDelta,
});
};
/**
* Internal RTL scroll method
* @param scrollX The new scroll position
*/
MDCTabScrollerFoundation.prototype.scrollToImplRTL = function (scrollX) {
var animation = this.getRTLScroller().scrollToRTL(scrollX);
this.animate(animation);
};
/**
* Internal method to compute the increment scroll operation values.
* @param scrollX The desired scroll position increment
* @return MDCTabScrollerAnimation with the sanitized values for performing
* the scroll operation.
*/
MDCTabScrollerFoundation.prototype.getIncrementScrollOperation = function (scrollX) {
if (this.isRTL()) {
return this.getRTLScroller().incrementScrollRTL(scrollX);
}
var currentScrollX = this.getScrollPosition();
var targetScrollX = scrollX + currentScrollX;
var safeScrollX = this.clampScrollValue(targetScrollX);
var scrollDelta = safeScrollX - currentScrollX;
return {
finalScrollPosition: safeScrollX,
scrollDelta: scrollDelta,
};
};
/**
* Animates the tab scrolling
* @param animation The animation to apply
*/
MDCTabScrollerFoundation.prototype.animate = function (animation) {
var _this = this;
// Early exit if translateX is 0, which means there's no animation to
// perform
if (animation.scrollDelta === 0) {
return;
}
this.stopScrollAnimation();
// This animation uses the FLIP approach.
// Read more here: https://aerotwist.com/blog/flip-your-animations/
this.adapter.setScrollAreaScrollLeft(animation.finalScrollPosition);
this.adapter.setScrollContentStyleProperty('transform', "translateX(" + animation.scrollDelta + "px)");
// Force repaint
this.adapter.computeScrollAreaClientRect();
requestAnimationFrame(function () {
_this.adapter.addClass(MDCTabScrollerFoundation.cssClasses.ANIMATING);
_this.adapter.setScrollContentStyleProperty('transform', 'none');
});
this.isAnimating = true;
};
/**
* Stops scroll animation
*/
MDCTabScrollerFoundation.prototype.stopScrollAnimation = function () {
this.isAnimating = false;
var currentScrollPosition = this.getAnimatingScrollPosition();
this.adapter.removeClass(MDCTabScrollerFoundation.cssClasses.ANIMATING);
this.adapter.setScrollContentStyleProperty('transform', 'translateX(0px)');
this.adapter.setScrollAreaScrollLeft(currentScrollPosition);
};
/**
* Gets the current scroll position during animation
*/
MDCTabScrollerFoundation.prototype.getAnimatingScrollPosition = function () {
var currentTranslateX = this.calculateCurrentTranslateX();
var scrollLeft = this.adapter.getScrollAreaScrollLeft();
if (this.isRTL()) {
return this.getRTLScroller().getAnimatingScrollPosition(scrollLeft, currentTranslateX);
}
return scrollLeft - currentTranslateX;
};
/**
* Determines the RTL Scroller to use
*/
MDCTabScrollerFoundation.prototype.rtlScrollerFactory = function () {
// Browsers have three different implementations of scrollLeft in RTL mode,
// dependent on the browser. The behavior is based off the max LTR
// scrollLeft value and 0.
//
// * Default scrolling in RTL *
// - Left-most value: 0
// - Right-most value: Max LTR scrollLeft value
//
// * Negative scrolling in RTL *
// - Left-most value: Negated max LTR scrollLeft value
// - Right-most value: 0
//
// * Reverse scrolling in RTL *
// - Left-most value: Max LTR scrollLeft value
// - Right-most value: 0
//
// We use those principles below to determine which RTL scrollLeft
// behavior is implemented in the current browser.
var initialScrollLeft = this.adapter.getScrollAreaScrollLeft();
this.adapter.setScrollAreaScrollLeft(initialScrollLeft - 1);
var newScrollLeft = this.adapter.getScrollAreaScrollLeft();
// If the newScrollLeft value is negative,then we know that the browser has
// implemented negative RTL scrolling, since all other implementations have
// only positive values.
if (newScrollLeft < 0) {
// Undo the scrollLeft test check
this.adapter.setScrollAreaScrollLeft(initialScrollLeft);
return new MDCTabScrollerRTLNegative(this.adapter);
}
var rootClientRect = this.adapter.computeScrollAreaClientRect();
var contentClientRect = this.adapter.computeScrollContentClientRect();
var rightEdgeDelta = Math.round(contentClientRect.right - rootClientRect.right);
// Undo the scrollLeft test check
this.adapter.setScrollAreaScrollLeft(initialScrollLeft);
// By calculating the clientRect of the root element and the clientRect of
// the content element, we can determine how much the scroll value changed
// when we performed the scrollLeft subtraction above.
if (rightEdgeDelta === newScrollLeft) {
return new MDCTabScrollerRTLReverse(this.adapter);
}
return new MDCTabScrollerRTLDefault(this.adapter);
};
MDCTabScrollerFoundation.prototype.isRTL = function () {
return this.adapter.getScrollContentStyleValue('direction') === 'rtl';
};
return MDCTabScrollerFoundation;
}(MDCFoundation));
export { MDCTabScrollerFoundation };
// tslint:disable-next-line:no-default-export Needed for backward compatibility with MDC Web v0.44.0 and earlier.
export default MDCTabScrollerFoundation;
//# sourceMappingURL=foundation.js.map