524 lines
25 KiB
JavaScript
524 lines
25 KiB
JavaScript
|
/**
|
||
|
* @license
|
||
|
* Copyright 2016 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, __values } from "tslib";
|
||
|
import { MDCFoundation } from '@material/base/foundation';
|
||
|
import { cssClasses, numbers, strings } from './constants';
|
||
|
import { getNormalizedEventCoords } from './util';
|
||
|
// Activation events registered on the root element of each instance for activation
|
||
|
var ACTIVATION_EVENT_TYPES = [
|
||
|
'touchstart', 'pointerdown', 'mousedown', 'keydown',
|
||
|
];
|
||
|
// Deactivation events registered on documentElement when a pointer-related down event occurs
|
||
|
var POINTER_DEACTIVATION_EVENT_TYPES = [
|
||
|
'touchend', 'pointerup', 'mouseup', 'contextmenu',
|
||
|
];
|
||
|
// simultaneous nested activations
|
||
|
var activatedTargets = [];
|
||
|
var MDCRippleFoundation = /** @class */ (function (_super) {
|
||
|
__extends(MDCRippleFoundation, _super);
|
||
|
function MDCRippleFoundation(adapter) {
|
||
|
var _this = _super.call(this, __assign(__assign({}, MDCRippleFoundation.defaultAdapter), adapter)) || this;
|
||
|
_this.activationAnimationHasEnded = false;
|
||
|
_this.activationTimer = 0;
|
||
|
_this.fgDeactivationRemovalTimer = 0;
|
||
|
_this.fgScale = '0';
|
||
|
_this.frame = { width: 0, height: 0 };
|
||
|
_this.initialSize = 0;
|
||
|
_this.layoutFrame = 0;
|
||
|
_this.maxRadius = 0;
|
||
|
_this.unboundedCoords = { left: 0, top: 0 };
|
||
|
_this.activationState = _this.defaultActivationState();
|
||
|
_this.activationTimerCallback = function () {
|
||
|
_this.activationAnimationHasEnded = true;
|
||
|
_this.runDeactivationUXLogicIfReady();
|
||
|
};
|
||
|
_this.activateHandler = function (e) {
|
||
|
_this.activateImpl(e);
|
||
|
};
|
||
|
_this.deactivateHandler = function () {
|
||
|
_this.deactivateImpl();
|
||
|
};
|
||
|
_this.focusHandler = function () {
|
||
|
_this.handleFocus();
|
||
|
};
|
||
|
_this.blurHandler = function () {
|
||
|
_this.handleBlur();
|
||
|
};
|
||
|
_this.resizeHandler = function () {
|
||
|
_this.layout();
|
||
|
};
|
||
|
return _this;
|
||
|
}
|
||
|
Object.defineProperty(MDCRippleFoundation, "cssClasses", {
|
||
|
get: function () {
|
||
|
return cssClasses;
|
||
|
},
|
||
|
enumerable: false,
|
||
|
configurable: true
|
||
|
});
|
||
|
Object.defineProperty(MDCRippleFoundation, "strings", {
|
||
|
get: function () {
|
||
|
return strings;
|
||
|
},
|
||
|
enumerable: false,
|
||
|
configurable: true
|
||
|
});
|
||
|
Object.defineProperty(MDCRippleFoundation, "numbers", {
|
||
|
get: function () {
|
||
|
return numbers;
|
||
|
},
|
||
|
enumerable: false,
|
||
|
configurable: true
|
||
|
});
|
||
|
Object.defineProperty(MDCRippleFoundation, "defaultAdapter", {
|
||
|
get: function () {
|
||
|
return {
|
||
|
addClass: function () { return undefined; },
|
||
|
browserSupportsCssVars: function () { return true; },
|
||
|
computeBoundingRect: function () {
|
||
|
return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 });
|
||
|
},
|
||
|
containsEventTarget: function () { return true; },
|
||
|
deregisterDocumentInteractionHandler: function () { return undefined; },
|
||
|
deregisterInteractionHandler: function () { return undefined; },
|
||
|
deregisterResizeHandler: function () { return undefined; },
|
||
|
getWindowPageOffset: function () { return ({ x: 0, y: 0 }); },
|
||
|
isSurfaceActive: function () { return true; },
|
||
|
isSurfaceDisabled: function () { return true; },
|
||
|
isUnbounded: function () { return true; },
|
||
|
registerDocumentInteractionHandler: function () { return undefined; },
|
||
|
registerInteractionHandler: function () { return undefined; },
|
||
|
registerResizeHandler: function () { return undefined; },
|
||
|
removeClass: function () { return undefined; },
|
||
|
updateCssVariable: function () { return undefined; },
|
||
|
};
|
||
|
},
|
||
|
enumerable: false,
|
||
|
configurable: true
|
||
|
});
|
||
|
MDCRippleFoundation.prototype.init = function () {
|
||
|
var _this = this;
|
||
|
var supportsPressRipple = this.supportsPressRipple();
|
||
|
this.registerRootHandlers(supportsPressRipple);
|
||
|
if (supportsPressRipple) {
|
||
|
var _a = MDCRippleFoundation.cssClasses, ROOT_1 = _a.ROOT, UNBOUNDED_1 = _a.UNBOUNDED;
|
||
|
requestAnimationFrame(function () {
|
||
|
_this.adapter.addClass(ROOT_1);
|
||
|
if (_this.adapter.isUnbounded()) {
|
||
|
_this.adapter.addClass(UNBOUNDED_1);
|
||
|
// Unbounded ripples need layout logic applied immediately to set coordinates for both shade and ripple
|
||
|
_this.layoutInternal();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.destroy = function () {
|
||
|
var _this = this;
|
||
|
if (this.supportsPressRipple()) {
|
||
|
if (this.activationTimer) {
|
||
|
clearTimeout(this.activationTimer);
|
||
|
this.activationTimer = 0;
|
||
|
this.adapter.removeClass(MDCRippleFoundation.cssClasses.FG_ACTIVATION);
|
||
|
}
|
||
|
if (this.fgDeactivationRemovalTimer) {
|
||
|
clearTimeout(this.fgDeactivationRemovalTimer);
|
||
|
this.fgDeactivationRemovalTimer = 0;
|
||
|
this.adapter.removeClass(MDCRippleFoundation.cssClasses.FG_DEACTIVATION);
|
||
|
}
|
||
|
var _a = MDCRippleFoundation.cssClasses, ROOT_2 = _a.ROOT, UNBOUNDED_2 = _a.UNBOUNDED;
|
||
|
requestAnimationFrame(function () {
|
||
|
_this.adapter.removeClass(ROOT_2);
|
||
|
_this.adapter.removeClass(UNBOUNDED_2);
|
||
|
_this.removeCssVars();
|
||
|
});
|
||
|
}
|
||
|
this.deregisterRootHandlers();
|
||
|
this.deregisterDeactivationHandlers();
|
||
|
};
|
||
|
/**
|
||
|
* @param evt Optional event containing position information.
|
||
|
*/
|
||
|
MDCRippleFoundation.prototype.activate = function (evt) {
|
||
|
this.activateImpl(evt);
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.deactivate = function () {
|
||
|
this.deactivateImpl();
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.layout = function () {
|
||
|
var _this = this;
|
||
|
if (this.layoutFrame) {
|
||
|
cancelAnimationFrame(this.layoutFrame);
|
||
|
}
|
||
|
this.layoutFrame = requestAnimationFrame(function () {
|
||
|
_this.layoutInternal();
|
||
|
_this.layoutFrame = 0;
|
||
|
});
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.setUnbounded = function (unbounded) {
|
||
|
var UNBOUNDED = MDCRippleFoundation.cssClasses.UNBOUNDED;
|
||
|
if (unbounded) {
|
||
|
this.adapter.addClass(UNBOUNDED);
|
||
|
}
|
||
|
else {
|
||
|
this.adapter.removeClass(UNBOUNDED);
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.handleFocus = function () {
|
||
|
var _this = this;
|
||
|
requestAnimationFrame(function () { return _this.adapter.addClass(MDCRippleFoundation.cssClasses.BG_FOCUSED); });
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.handleBlur = function () {
|
||
|
var _this = this;
|
||
|
requestAnimationFrame(function () { return _this.adapter.removeClass(MDCRippleFoundation.cssClasses.BG_FOCUSED); });
|
||
|
};
|
||
|
/**
|
||
|
* We compute this property so that we are not querying information about the client
|
||
|
* until the point in time where the foundation requests it. This prevents scenarios where
|
||
|
* client-side feature-detection may happen too early, such as when components are rendered on the server
|
||
|
* and then initialized at mount time on the client.
|
||
|
*/
|
||
|
MDCRippleFoundation.prototype.supportsPressRipple = function () {
|
||
|
return this.adapter.browserSupportsCssVars();
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.defaultActivationState = function () {
|
||
|
return {
|
||
|
activationEvent: undefined,
|
||
|
hasDeactivationUXRun: false,
|
||
|
isActivated: false,
|
||
|
isProgrammatic: false,
|
||
|
wasActivatedByPointer: false,
|
||
|
wasElementMadeActive: false,
|
||
|
};
|
||
|
};
|
||
|
/**
|
||
|
* supportsPressRipple Passed from init to save a redundant function call
|
||
|
*/
|
||
|
MDCRippleFoundation.prototype.registerRootHandlers = function (supportsPressRipple) {
|
||
|
var e_1, _a;
|
||
|
if (supportsPressRipple) {
|
||
|
try {
|
||
|
for (var ACTIVATION_EVENT_TYPES_1 = __values(ACTIVATION_EVENT_TYPES), ACTIVATION_EVENT_TYPES_1_1 = ACTIVATION_EVENT_TYPES_1.next(); !ACTIVATION_EVENT_TYPES_1_1.done; ACTIVATION_EVENT_TYPES_1_1 = ACTIVATION_EVENT_TYPES_1.next()) {
|
||
|
var evtType = ACTIVATION_EVENT_TYPES_1_1.value;
|
||
|
this.adapter.registerInteractionHandler(evtType, this.activateHandler);
|
||
|
}
|
||
|
}
|
||
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||
|
finally {
|
||
|
try {
|
||
|
if (ACTIVATION_EVENT_TYPES_1_1 && !ACTIVATION_EVENT_TYPES_1_1.done && (_a = ACTIVATION_EVENT_TYPES_1.return)) _a.call(ACTIVATION_EVENT_TYPES_1);
|
||
|
}
|
||
|
finally { if (e_1) throw e_1.error; }
|
||
|
}
|
||
|
if (this.adapter.isUnbounded()) {
|
||
|
this.adapter.registerResizeHandler(this.resizeHandler);
|
||
|
}
|
||
|
}
|
||
|
this.adapter.registerInteractionHandler('focus', this.focusHandler);
|
||
|
this.adapter.registerInteractionHandler('blur', this.blurHandler);
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.registerDeactivationHandlers = function (evt) {
|
||
|
var e_2, _a;
|
||
|
if (evt.type === 'keydown') {
|
||
|
this.adapter.registerInteractionHandler('keyup', this.deactivateHandler);
|
||
|
}
|
||
|
else {
|
||
|
try {
|
||
|
for (var POINTER_DEACTIVATION_EVENT_TYPES_1 = __values(POINTER_DEACTIVATION_EVENT_TYPES), POINTER_DEACTIVATION_EVENT_TYPES_1_1 = POINTER_DEACTIVATION_EVENT_TYPES_1.next(); !POINTER_DEACTIVATION_EVENT_TYPES_1_1.done; POINTER_DEACTIVATION_EVENT_TYPES_1_1 = POINTER_DEACTIVATION_EVENT_TYPES_1.next()) {
|
||
|
var evtType = POINTER_DEACTIVATION_EVENT_TYPES_1_1.value;
|
||
|
this.adapter.registerDocumentInteractionHandler(evtType, this.deactivateHandler);
|
||
|
}
|
||
|
}
|
||
|
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
||
|
finally {
|
||
|
try {
|
||
|
if (POINTER_DEACTIVATION_EVENT_TYPES_1_1 && !POINTER_DEACTIVATION_EVENT_TYPES_1_1.done && (_a = POINTER_DEACTIVATION_EVENT_TYPES_1.return)) _a.call(POINTER_DEACTIVATION_EVENT_TYPES_1);
|
||
|
}
|
||
|
finally { if (e_2) throw e_2.error; }
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.deregisterRootHandlers = function () {
|
||
|
var e_3, _a;
|
||
|
try {
|
||
|
for (var ACTIVATION_EVENT_TYPES_2 = __values(ACTIVATION_EVENT_TYPES), ACTIVATION_EVENT_TYPES_2_1 = ACTIVATION_EVENT_TYPES_2.next(); !ACTIVATION_EVENT_TYPES_2_1.done; ACTIVATION_EVENT_TYPES_2_1 = ACTIVATION_EVENT_TYPES_2.next()) {
|
||
|
var evtType = ACTIVATION_EVENT_TYPES_2_1.value;
|
||
|
this.adapter.deregisterInteractionHandler(evtType, this.activateHandler);
|
||
|
}
|
||
|
}
|
||
|
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
||
|
finally {
|
||
|
try {
|
||
|
if (ACTIVATION_EVENT_TYPES_2_1 && !ACTIVATION_EVENT_TYPES_2_1.done && (_a = ACTIVATION_EVENT_TYPES_2.return)) _a.call(ACTIVATION_EVENT_TYPES_2);
|
||
|
}
|
||
|
finally { if (e_3) throw e_3.error; }
|
||
|
}
|
||
|
this.adapter.deregisterInteractionHandler('focus', this.focusHandler);
|
||
|
this.adapter.deregisterInteractionHandler('blur', this.blurHandler);
|
||
|
if (this.adapter.isUnbounded()) {
|
||
|
this.adapter.deregisterResizeHandler(this.resizeHandler);
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.deregisterDeactivationHandlers = function () {
|
||
|
var e_4, _a;
|
||
|
this.adapter.deregisterInteractionHandler('keyup', this.deactivateHandler);
|
||
|
try {
|
||
|
for (var POINTER_DEACTIVATION_EVENT_TYPES_2 = __values(POINTER_DEACTIVATION_EVENT_TYPES), POINTER_DEACTIVATION_EVENT_TYPES_2_1 = POINTER_DEACTIVATION_EVENT_TYPES_2.next(); !POINTER_DEACTIVATION_EVENT_TYPES_2_1.done; POINTER_DEACTIVATION_EVENT_TYPES_2_1 = POINTER_DEACTIVATION_EVENT_TYPES_2.next()) {
|
||
|
var evtType = POINTER_DEACTIVATION_EVENT_TYPES_2_1.value;
|
||
|
this.adapter.deregisterDocumentInteractionHandler(evtType, this.deactivateHandler);
|
||
|
}
|
||
|
}
|
||
|
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
||
|
finally {
|
||
|
try {
|
||
|
if (POINTER_DEACTIVATION_EVENT_TYPES_2_1 && !POINTER_DEACTIVATION_EVENT_TYPES_2_1.done && (_a = POINTER_DEACTIVATION_EVENT_TYPES_2.return)) _a.call(POINTER_DEACTIVATION_EVENT_TYPES_2);
|
||
|
}
|
||
|
finally { if (e_4) throw e_4.error; }
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.removeCssVars = function () {
|
||
|
var _this = this;
|
||
|
var rippleStrings = MDCRippleFoundation.strings;
|
||
|
var keys = Object.keys(rippleStrings);
|
||
|
keys.forEach(function (key) {
|
||
|
if (key.indexOf('VAR_') === 0) {
|
||
|
_this.adapter.updateCssVariable(rippleStrings[key], null);
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.activateImpl = function (evt) {
|
||
|
var _this = this;
|
||
|
if (this.adapter.isSurfaceDisabled()) {
|
||
|
return;
|
||
|
}
|
||
|
var activationState = this.activationState;
|
||
|
if (activationState.isActivated) {
|
||
|
return;
|
||
|
}
|
||
|
// Avoid reacting to follow-on events fired by touch device after an already-processed user interaction
|
||
|
var previousActivationEvent = this.previousActivationEvent;
|
||
|
var isSameInteraction = previousActivationEvent && evt !== undefined && previousActivationEvent.type !== evt.type;
|
||
|
if (isSameInteraction) {
|
||
|
return;
|
||
|
}
|
||
|
activationState.isActivated = true;
|
||
|
activationState.isProgrammatic = evt === undefined;
|
||
|
activationState.activationEvent = evt;
|
||
|
activationState.wasActivatedByPointer = activationState.isProgrammatic ? false : evt !== undefined && (evt.type === 'mousedown' || evt.type === 'touchstart' || evt.type === 'pointerdown');
|
||
|
var hasActivatedChild = evt !== undefined &&
|
||
|
activatedTargets.length > 0 &&
|
||
|
activatedTargets.some(function (target) { return _this.adapter.containsEventTarget(target); });
|
||
|
if (hasActivatedChild) {
|
||
|
// Immediately reset activation state, while preserving logic that prevents touch follow-on events
|
||
|
this.resetActivationState();
|
||
|
return;
|
||
|
}
|
||
|
if (evt !== undefined) {
|
||
|
activatedTargets.push(evt.target);
|
||
|
this.registerDeactivationHandlers(evt);
|
||
|
}
|
||
|
activationState.wasElementMadeActive = this.checkElementMadeActive(evt);
|
||
|
if (activationState.wasElementMadeActive) {
|
||
|
this.animateActivation();
|
||
|
}
|
||
|
requestAnimationFrame(function () {
|
||
|
// Reset array on next frame after the current event has had a chance to bubble to prevent ancestor ripples
|
||
|
activatedTargets = [];
|
||
|
if (!activationState.wasElementMadeActive
|
||
|
&& evt !== undefined
|
||
|
&& (evt.key === ' ' || evt.keyCode === 32)) {
|
||
|
// If space was pressed, try again within an rAF call to detect :active, because different UAs report
|
||
|
// active states inconsistently when they're called within event handling code:
|
||
|
// - https://bugs.chromium.org/p/chromium/issues/detail?id=635971
|
||
|
// - https://bugzilla.mozilla.org/show_bug.cgi?id=1293741
|
||
|
// We try first outside rAF to support Edge, which does not exhibit this problem, but will crash if a CSS
|
||
|
// variable is set within a rAF callback for a submit button interaction (#2241).
|
||
|
activationState.wasElementMadeActive = _this.checkElementMadeActive(evt);
|
||
|
if (activationState.wasElementMadeActive) {
|
||
|
_this.animateActivation();
|
||
|
}
|
||
|
}
|
||
|
if (!activationState.wasElementMadeActive) {
|
||
|
// Reset activation state immediately if element was not made active.
|
||
|
_this.activationState = _this.defaultActivationState();
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.checkElementMadeActive = function (evt) {
|
||
|
return (evt !== undefined && evt.type === 'keydown') ?
|
||
|
this.adapter.isSurfaceActive() :
|
||
|
true;
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.animateActivation = function () {
|
||
|
var _this = this;
|
||
|
var _a = MDCRippleFoundation.strings, VAR_FG_TRANSLATE_START = _a.VAR_FG_TRANSLATE_START, VAR_FG_TRANSLATE_END = _a.VAR_FG_TRANSLATE_END;
|
||
|
var _b = MDCRippleFoundation.cssClasses, FG_DEACTIVATION = _b.FG_DEACTIVATION, FG_ACTIVATION = _b.FG_ACTIVATION;
|
||
|
var DEACTIVATION_TIMEOUT_MS = MDCRippleFoundation.numbers.DEACTIVATION_TIMEOUT_MS;
|
||
|
this.layoutInternal();
|
||
|
var translateStart = '';
|
||
|
var translateEnd = '';
|
||
|
if (!this.adapter.isUnbounded()) {
|
||
|
var _c = this.getFgTranslationCoordinates(), startPoint = _c.startPoint, endPoint = _c.endPoint;
|
||
|
translateStart = startPoint.x + "px, " + startPoint.y + "px";
|
||
|
translateEnd = endPoint.x + "px, " + endPoint.y + "px";
|
||
|
}
|
||
|
this.adapter.updateCssVariable(VAR_FG_TRANSLATE_START, translateStart);
|
||
|
this.adapter.updateCssVariable(VAR_FG_TRANSLATE_END, translateEnd);
|
||
|
// Cancel any ongoing activation/deactivation animations
|
||
|
clearTimeout(this.activationTimer);
|
||
|
clearTimeout(this.fgDeactivationRemovalTimer);
|
||
|
this.rmBoundedActivationClasses();
|
||
|
this.adapter.removeClass(FG_DEACTIVATION);
|
||
|
// Force layout in order to re-trigger the animation.
|
||
|
this.adapter.computeBoundingRect();
|
||
|
this.adapter.addClass(FG_ACTIVATION);
|
||
|
this.activationTimer = setTimeout(function () {
|
||
|
_this.activationTimerCallback();
|
||
|
}, DEACTIVATION_TIMEOUT_MS);
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.getFgTranslationCoordinates = function () {
|
||
|
var _a = this.activationState, activationEvent = _a.activationEvent, wasActivatedByPointer = _a.wasActivatedByPointer;
|
||
|
var startPoint;
|
||
|
if (wasActivatedByPointer) {
|
||
|
startPoint = getNormalizedEventCoords(activationEvent, this.adapter.getWindowPageOffset(), this.adapter.computeBoundingRect());
|
||
|
}
|
||
|
else {
|
||
|
startPoint = {
|
||
|
x: this.frame.width / 2,
|
||
|
y: this.frame.height / 2,
|
||
|
};
|
||
|
}
|
||
|
// Center the element around the start point.
|
||
|
startPoint = {
|
||
|
x: startPoint.x - (this.initialSize / 2),
|
||
|
y: startPoint.y - (this.initialSize / 2),
|
||
|
};
|
||
|
var endPoint = {
|
||
|
x: (this.frame.width / 2) - (this.initialSize / 2),
|
||
|
y: (this.frame.height / 2) - (this.initialSize / 2),
|
||
|
};
|
||
|
return { startPoint: startPoint, endPoint: endPoint };
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.runDeactivationUXLogicIfReady = function () {
|
||
|
var _this = this;
|
||
|
// This method is called both when a pointing device is released, and when the activation animation ends.
|
||
|
// The deactivation animation should only run after both of those occur.
|
||
|
var FG_DEACTIVATION = MDCRippleFoundation.cssClasses.FG_DEACTIVATION;
|
||
|
var _a = this.activationState, hasDeactivationUXRun = _a.hasDeactivationUXRun, isActivated = _a.isActivated;
|
||
|
var activationHasEnded = hasDeactivationUXRun || !isActivated;
|
||
|
if (activationHasEnded && this.activationAnimationHasEnded) {
|
||
|
this.rmBoundedActivationClasses();
|
||
|
this.adapter.addClass(FG_DEACTIVATION);
|
||
|
this.fgDeactivationRemovalTimer = setTimeout(function () {
|
||
|
_this.adapter.removeClass(FG_DEACTIVATION);
|
||
|
}, numbers.FG_DEACTIVATION_MS);
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.rmBoundedActivationClasses = function () {
|
||
|
var FG_ACTIVATION = MDCRippleFoundation.cssClasses.FG_ACTIVATION;
|
||
|
this.adapter.removeClass(FG_ACTIVATION);
|
||
|
this.activationAnimationHasEnded = false;
|
||
|
this.adapter.computeBoundingRect();
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.resetActivationState = function () {
|
||
|
var _this = this;
|
||
|
this.previousActivationEvent = this.activationState.activationEvent;
|
||
|
this.activationState = this.defaultActivationState();
|
||
|
// Touch devices may fire additional events for the same interaction within a short time.
|
||
|
// Store the previous event until it's safe to assume that subsequent events are for new interactions.
|
||
|
setTimeout(function () { return _this.previousActivationEvent = undefined; }, MDCRippleFoundation.numbers.TAP_DELAY_MS);
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.deactivateImpl = function () {
|
||
|
var _this = this;
|
||
|
var activationState = this.activationState;
|
||
|
// This can happen in scenarios such as when you have a keyup event that blurs the element.
|
||
|
if (!activationState.isActivated) {
|
||
|
return;
|
||
|
}
|
||
|
var state = __assign({}, activationState);
|
||
|
if (activationState.isProgrammatic) {
|
||
|
requestAnimationFrame(function () {
|
||
|
_this.animateDeactivation(state);
|
||
|
});
|
||
|
this.resetActivationState();
|
||
|
}
|
||
|
else {
|
||
|
this.deregisterDeactivationHandlers();
|
||
|
requestAnimationFrame(function () {
|
||
|
_this.activationState.hasDeactivationUXRun = true;
|
||
|
_this.animateDeactivation(state);
|
||
|
_this.resetActivationState();
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.animateDeactivation = function (_a) {
|
||
|
var wasActivatedByPointer = _a.wasActivatedByPointer, wasElementMadeActive = _a.wasElementMadeActive;
|
||
|
if (wasActivatedByPointer || wasElementMadeActive) {
|
||
|
this.runDeactivationUXLogicIfReady();
|
||
|
}
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.layoutInternal = function () {
|
||
|
var _this = this;
|
||
|
this.frame = this.adapter.computeBoundingRect();
|
||
|
var maxDim = Math.max(this.frame.height, this.frame.width);
|
||
|
// Surface diameter is treated differently for unbounded vs. bounded ripples.
|
||
|
// Unbounded ripple diameter is calculated smaller since the surface is expected to already be padded appropriately
|
||
|
// to extend the hitbox, and the ripple is expected to meet the edges of the padded hitbox (which is typically
|
||
|
// square). Bounded ripples, on the other hand, are fully expected to expand beyond the surface's longest diameter
|
||
|
// (calculated based on the diagonal plus a constant padding), and are clipped at the surface's border via
|
||
|
// `overflow: hidden`.
|
||
|
var getBoundedRadius = function () {
|
||
|
var hypotenuse = Math.sqrt(Math.pow(_this.frame.width, 2) + Math.pow(_this.frame.height, 2));
|
||
|
return hypotenuse + MDCRippleFoundation.numbers.PADDING;
|
||
|
};
|
||
|
this.maxRadius = this.adapter.isUnbounded() ? maxDim : getBoundedRadius();
|
||
|
// Ripple is sized as a fraction of the largest dimension of the surface, then scales up using a CSS scale transform
|
||
|
var initialSize = Math.floor(maxDim * MDCRippleFoundation.numbers.INITIAL_ORIGIN_SCALE);
|
||
|
// Unbounded ripple size should always be even number to equally center align.
|
||
|
if (this.adapter.isUnbounded() && initialSize % 2 !== 0) {
|
||
|
this.initialSize = initialSize - 1;
|
||
|
}
|
||
|
else {
|
||
|
this.initialSize = initialSize;
|
||
|
}
|
||
|
this.fgScale = "" + this.maxRadius / this.initialSize;
|
||
|
this.updateLayoutCssVars();
|
||
|
};
|
||
|
MDCRippleFoundation.prototype.updateLayoutCssVars = function () {
|
||
|
var _a = MDCRippleFoundation.strings, VAR_FG_SIZE = _a.VAR_FG_SIZE, VAR_LEFT = _a.VAR_LEFT, VAR_TOP = _a.VAR_TOP, VAR_FG_SCALE = _a.VAR_FG_SCALE;
|
||
|
this.adapter.updateCssVariable(VAR_FG_SIZE, this.initialSize + "px");
|
||
|
this.adapter.updateCssVariable(VAR_FG_SCALE, this.fgScale);
|
||
|
if (this.adapter.isUnbounded()) {
|
||
|
this.unboundedCoords = {
|
||
|
left: Math.round((this.frame.width / 2) - (this.initialSize / 2)),
|
||
|
top: Math.round((this.frame.height / 2) - (this.initialSize / 2)),
|
||
|
};
|
||
|
this.adapter.updateCssVariable(VAR_LEFT, this.unboundedCoords.left + "px");
|
||
|
this.adapter.updateCssVariable(VAR_TOP, this.unboundedCoords.top + "px");
|
||
|
}
|
||
|
};
|
||
|
return MDCRippleFoundation;
|
||
|
}(MDCFoundation));
|
||
|
export { MDCRippleFoundation };
|
||
|
// tslint:disable-next-line:no-default-export Needed for backward compatibility with MDC Web v0.44.0 and earlier.
|
||
|
export default MDCRippleFoundation;
|
||
|
//# sourceMappingURL=foundation.js.map
|