| Index: third_party/polymer/components/web-animations-js/src/group-constructors.js
|
| diff --git a/third_party/polymer/components/web-animations-js/src/group-constructors.js b/third_party/polymer/components/web-animations-js/src/group-constructors.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e5c0a102b07b636997f943c10eb985329814f07b
|
| --- /dev/null
|
| +++ b/third_party/polymer/components/web-animations-js/src/group-constructors.js
|
| @@ -0,0 +1,204 @@
|
| +// Copyright 2014 Google Inc. All rights reserved.
|
| +//
|
| +// Licensed under the Apache License, Version 2.0 (the "License");
|
| +// you may not use this file except in compliance with the License.
|
| +// You may obtain a copy of the License at
|
| +//
|
| +// http://www.apache.org/licenses/LICENSE-2.0
|
| +//
|
| +// Unless required by applicable law or agreed to in writing, software
|
| +// distributed under the License is distributed on an "AS IS" BASIS,
|
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| +// See the License for the specific language governing permissions and
|
| +// limitations under the License.
|
| +
|
| +(function(shared, scope, testing) {
|
| +
|
| + function groupChildDuration(node) {
|
| + return node._timing.delay + node.activeDuration + node._timing.endDelay;
|
| + }
|
| +
|
| + function constructor(children, timingInput, id) {
|
| + this._id = id;
|
| + this._parent = null;
|
| + this.children = children || [];
|
| + this._reparent(this.children);
|
| + timingInput = shared.numericTimingToObject(timingInput);
|
| + this._timingInput = shared.cloneTimingInput(timingInput);
|
| + this._timing = shared.normalizeTimingInput(timingInput, true);
|
| + this.timing = shared.makeTiming(timingInput, true, this);
|
| + this.timing._effect = this;
|
| +
|
| + if (this._timing.duration === 'auto') {
|
| + this._timing.duration = this.activeDuration;
|
| + }
|
| + }
|
| +
|
| + window.SequenceEffect = function() {
|
| + constructor.apply(this, arguments);
|
| + };
|
| +
|
| + window.GroupEffect = function() {
|
| + constructor.apply(this, arguments);
|
| + };
|
| +
|
| + constructor.prototype = {
|
| + _isAncestor: function(effect) {
|
| + var a = this;
|
| + while (a !== null) {
|
| + if (a == effect)
|
| + return true;
|
| + a = a._parent;
|
| + }
|
| + return false;
|
| + },
|
| + _rebuild: function() {
|
| + // Re-calculate durations for ancestors with specified duration 'auto'.
|
| + var node = this;
|
| + while (node) {
|
| + if (node.timing.duration === 'auto') {
|
| + node._timing.duration = node.activeDuration;
|
| + }
|
| + node = node._parent;
|
| + }
|
| + if (this._animation) {
|
| + this._animation._rebuildUnderlyingAnimation();
|
| + }
|
| + },
|
| + _reparent: function(newChildren) {
|
| + scope.removeMulti(newChildren);
|
| + for (var i = 0; i < newChildren.length; i++) {
|
| + newChildren[i]._parent = this;
|
| + }
|
| + },
|
| + _putChild: function(args, isAppend) {
|
| + var message = isAppend ? 'Cannot append an ancestor or self' : 'Cannot prepend an ancestor or self';
|
| + for (var i = 0; i < args.length; i++) {
|
| + if (this._isAncestor(args[i])) {
|
| + throw {
|
| + type: DOMException.HIERARCHY_REQUEST_ERR,
|
| + name: 'HierarchyRequestError',
|
| + message: message
|
| + };
|
| + }
|
| + }
|
| + var oldParents = [];
|
| + for (var i = 0; i < args.length; i++) {
|
| + isAppend ? this.children.push(args[i]) : this.children.unshift(args[i]);
|
| + }
|
| + this._reparent(args);
|
| + this._rebuild();
|
| + },
|
| + append: function() {
|
| + this._putChild(arguments, true);
|
| + },
|
| + prepend: function() {
|
| + this._putChild(arguments, false);
|
| + },
|
| + get parent() {
|
| + return this._parent;
|
| + },
|
| + get firstChild() {
|
| + return this.children.length ? this.children[0] : null;
|
| + },
|
| + get lastChild() {
|
| + return this.children.length ? this.children[this.children.length - 1] : null;
|
| + },
|
| + clone: function() {
|
| + var clonedTiming = shared.cloneTimingInput(this._timingInput);
|
| + var clonedChildren = [];
|
| + for (var i = 0; i < this.children.length; i++) {
|
| + clonedChildren.push(this.children[i].clone());
|
| + }
|
| + return (this instanceof GroupEffect) ?
|
| + new GroupEffect(clonedChildren, clonedTiming) :
|
| + new SequenceEffect(clonedChildren, clonedTiming);
|
| + },
|
| + remove: function() {
|
| + scope.removeMulti([this]);
|
| + }
|
| + };
|
| +
|
| + window.SequenceEffect.prototype = Object.create(constructor.prototype);
|
| + Object.defineProperty(
|
| + window.SequenceEffect.prototype,
|
| + 'activeDuration',
|
| + {
|
| + get: function() {
|
| + var total = 0;
|
| + this.children.forEach(function(child) {
|
| + total += groupChildDuration(child);
|
| + });
|
| + return Math.max(total, 0);
|
| + }
|
| + });
|
| +
|
| + window.GroupEffect.prototype = Object.create(constructor.prototype);
|
| + Object.defineProperty(
|
| + window.GroupEffect.prototype,
|
| + 'activeDuration',
|
| + {
|
| + get: function() {
|
| + var max = 0;
|
| + this.children.forEach(function(child) {
|
| + max = Math.max(max, groupChildDuration(child));
|
| + });
|
| + return max;
|
| + }
|
| + });
|
| +
|
| + scope.newUnderlyingAnimationForGroup = function(group) {
|
| + var underlyingAnimation;
|
| + var timing = null;
|
| + var ticker = function(tf) {
|
| + var animation = underlyingAnimation._wrapper;
|
| + if (!animation) {
|
| + return;
|
| + }
|
| + if (animation.playState == 'pending') {
|
| + return;
|
| + }
|
| + if (!animation.effect) {
|
| + return;
|
| + }
|
| + if (tf == null) {
|
| + animation._removeChildAnimations();
|
| + return;
|
| + }
|
| +
|
| + // If the group has a negative playback rate and is not fill backwards/both, then it should go
|
| + // out of effect when it reaches the start of its active interval (tf == 0). If it is fill
|
| + // backwards/both then it should stay in effect. calculateIterationProgress will return 0 in the
|
| + // backwards-filling case, and null otherwise.
|
| + if (tf == 0 && animation.playbackRate < 0) {
|
| + if (!timing) {
|
| + timing = shared.normalizeTimingInput(animation.effect.timing);
|
| + }
|
| + tf = shared.calculateIterationProgress(shared.calculateActiveDuration(timing), -1, timing);
|
| + if (isNaN(tf) || tf == null) {
|
| + animation._forEachChild(function(child) {
|
| + child.currentTime = -1;
|
| + });
|
| + animation._removeChildAnimations();
|
| + return;
|
| + }
|
| + }
|
| + };
|
| +
|
| + var underlyingEffect = new KeyframeEffect(null, [], group._timing, group._id);
|
| + underlyingEffect.onsample = ticker;
|
| + underlyingAnimation = scope.timeline._play(underlyingEffect);
|
| + return underlyingAnimation;
|
| + };
|
| +
|
| + scope.bindAnimationForGroup = function(animation) {
|
| + animation._animation._wrapper = animation;
|
| + animation._isGroup = true;
|
| + scope.awaitStartTime(animation);
|
| + animation._constructChildAnimations();
|
| + animation._setExternalAnimation(animation);
|
| + };
|
| +
|
| + scope.groupChildDuration = groupChildDuration;
|
| +
|
| +})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);
|
|
|