move dependencies to npm

This commit is contained in:
Tim Lancina
2015-08-07 16:50:15 -05:00
parent ef5f50883a
commit baef69f75b
220 changed files with 0 additions and 121242 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
System.config({ "paths": { "ionic/*": "ionic/*" } });

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,100 +0,0 @@
# 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.
#! /bin/bash
set -x
set -e
# Make sure /dev/shm has correct permissions.
ls -l /dev/shm
sudo chmod 1777 /dev/shm
ls -l /dev/shm
uname -a
cat /etc/lsb-release
npm install
npm install -g grunt-cli
sudo apt-get update --fix-missing
# Install python-imaging from the environment rather then build it.
# If the below fails, pip will build it via the requirements.txt
# sudo apt-get install python-imaging
# VIRTUAL_ENV_site_packages=$(echo $VIRTUAL_ENV/lib/*/site-packages)
# VIRTUAL_ENV_python_version=$(echo $VIRTUAL_ENV_site_packages | sed -e's@.*/\(.*\)/site-packages@\1@')
# ln -s /usr/lib/$VIRTUAL_ENV_python_version/dist-packages/PIL.pth $VIRTUAL_ENV_site_packages/PIL.pth
# ln -s /usr/lib/$VIRTUAL_ENV_python_version/dist-packages/PIL $VIRTUAL_ENV_site_packages/PIL
export VERSION=$(echo $BROWSER | sed -e's/[^-]*-//')
export BROWSER=$(echo $BROWSER | sed -e's/-.*//')
echo BROWSER=$BROWSER
echo VERSION=$VERSION
sudo ln -sf $(which true) $(which xdg-desktop-menu)
case $BROWSER in
Android)
sudo apt-get install -qq --force-yes \
libc6:i386 libgcc1:i386 gcc-4.6-base:i386 libstdc++5:i386 \
libstdc++6:i386 lib32z1 libreadline6-dev:i386 \
libncurses5-dev:i386
bash tools/android/setup.sh
;;
Chrome)
echo "Getting $VERSION of $BROWSER"
export CHROME=google-chrome-${VERSION}_current_amd64.deb
wget https://dl.google.com/linux/direct/$CHROME
sudo dpkg --install $CHROME || sudo apt-get -f install
which google-chrome
ls -l `which google-chrome`
if [ -f /opt/google/chrome/chrome-sandbox ]; then
export CHROME_SANDBOX=/opt/google/chrome/chrome-sandbox
else
export CHROME_SANDBOX=$(ls /opt/google/chrome*/chrome-sandbox)
fi
# Download a custom chrome-sandbox which works inside OpenVC containers (used on travis).
sudo rm -f $CHROME_SANDBOX
sudo wget https://googledrive.com/host/0B5VlNZ_Rvdw6NTJoZDBSVy1ZdkE -O $CHROME_SANDBOX
sudo chown root:root $CHROME_SANDBOX; sudo chmod 4755 $CHROME_SANDBOX
sudo md5sum $CHROME_SANDBOX
google-chrome --version
;;
Firefox)
sudo rm -f /usr/local/bin/firefox
case $VERSION in
beta)
yes "\n" | sudo add-apt-repository -y ppa:mozillateam/firefox-next
;;
aurora)
yes "\n" | sudo add-apt-repository -y ppa:ubuntu-mozilla-daily/firefox-aurora
;;
esac
sudo apt-get update --fix-missing
sudo apt-get install firefox
which firefox
ls -l `which firefox`
firefox --version
;;
esac
# R=tools/python/requirements.txt
# pip install -r $R --use-mirrors || pip install -r $R

View File

@ -1,11 +0,0 @@
language: node_js
node_js:
- "0.10"
install:
- BROWSER="Firefox-aurora" ./.travis-setup.sh
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start

View File

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@ -1,293 +0,0 @@
// 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.
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-gjslint');
grunt.loadNpmTasks('grunt-checkrepo');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-saucelabs');
grunt.loadNpmTasks('grunt-git-status');
grunt.loadNpmTasks('grunt-template');
var targetConfig = require('./target-config.js');
var sourceMap = require('source-map');
var config = {
uglify: {},
template: {},
wrap: {},
sourceMapConcat: {},
};
function concat(sources, target, defines) {
config.uglify[target] = {
options: {
sourceMap: true,
sourceMapName: target + '.map',
wrap: false,
compress: {
global_defs: defines,
dead_code: false
},
mangle: false
},
nonull: true,
dest: target,
src: sources
};
return 'uglify:' + target;
}
function compress(source, target, defines) {
var name = concat([source], target, defines);
var record = config.uglify[target];
record.options.sourceMapIn = source + '.map';
record.options.banner = grunt.file.read('templates/boilerplate');
record.options.wrap = true;
record.options.compress.dead_code = true;
record.options.mangle = { eval: true };
return name;
}
function genTarget(target) {
var config = targetConfig[target];
var newGens = [
generateFromTemplate('templates/web-animations.js', {target: target}, target + '.dev.js'),
generateFromTemplate('templates/web-animations.html', {src: config.src}, target + '.dev.html'),
generateFromTemplate('templates/runner.html', {target: target}, 'test/runner-' + target + '.html')];
return newGens;
}
function generateFromTemplate(source, data, target) {
var targetSpec = {};
targetSpec[target] = [source];
config.template[target] = {
options: {
data: data
},
files: targetSpec
}
return 'template:' + target;
}
function guard(source, target) {
config.wrap[target] = {
source: source,
preamble: '(function() {\n' +
' if (document.documentElement.animate) {\n' +
' var player = document.documentElement.animate([], 0);\n' +
' var load = true;\n' +
' if (player) {\n' +
' load = false;\n' +
' "play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState".split("|").forEach(function(t) {\n' +
' if (player[t] === undefined) {\n' +
' load = true;\n' +
' }\n' +
' });\n' +
' }\n' +
' if (!load) { return; }' +
' }\n',
postamble: '})();'
};
return 'wrap:' + target;
}
function concatWithMaps(sources, target) {
config.sourceMapConcat[target] = {
sources: sources
}
return 'sourceMapConcat:' + target;
};
var concatDefines = {
WEB_ANIMATIONS_TESTING: false
};
function buildWebAnimations1(target) {
var config = targetConfig[target];
return genTarget(target).concat([
concat(config.scopeSrc.concat(config.sharedSrc).concat(config.webAnimations1Src), 'inter-raw-' + target + '.js', concatDefines),
guard('inter-raw-' + target + '.js', 'inter-' + target + '.js'),
compress('inter-' + target + '.js', target + '.min.js', concatDefines)
]);
}
function buildWebAnimationsNext(target) {
var config = targetConfig[target];
return genTarget(target).concat([
concat(config.scopeSrc.concat(config.sharedSrc), 'inter-' + target + '-preamble.js', concatDefines),
concat(config.webAnimations1Src, 'inter-component-' + target + 'web-animations-1.js', concatDefines),
guard('inter-component-' + target + 'web-animations-1.js', 'inter-guarded-' + target + '-web-animations-1.js'),
concat(config.webAnimationsNextSrc, 'inter-component-' + target + '.js', concatDefines),
concatWithMaps(['inter-' + target + '-preamble.js', 'inter-guarded-' + target + '-web-animations-1.js', 'inter-component-' + target + '.js'],
'inter-' + target + '.js'),
compress('inter-' + target + '.js', target + '.min.js', concatDefines)
]);
}
grunt.registerTask('web-animations', buildWebAnimations1('web-animations'));
grunt.registerTask('web-animations-next', buildWebAnimationsNext('web-animations-next'));
grunt.registerTask('web-animations-next-lite', buildWebAnimationsNext('web-animations-next-lite'));
var testTargets = {'web-animations': {}, 'web-animations-next': {}};
grunt.initConfig({
uglify: config.uglify,
template: config.template,
wrap: config.wrap,
sourceMapConcat: config.sourceMapConcat,
checkrepo: {
all: {
clean: true,
},
},
'git-status': {
all: {
},
},
gjslint: {
options: {
flags: [
'--nojsdoc',
'--strict',
'--disable 7,121,110', // 7: Wrong blank line count
// 121: Illegal comma at end of object literal
// 110: Line too long
],
reporter: {
name: 'console'
}
},
all: {
src: [
'src/*.js',
'test/*.js',
'test/js/*.js',
],
}
},
test: testTargets,
sauce: testTargets,
});
grunt.task.registerMultiTask('test', 'Run <target> tests under Karma', function() {
var done = this.async();
var karmaConfig = require('karma/lib/config').parseConfig(require('path').resolve('test/karma-config.js'), {});
var config = targetConfig[this.target];
karmaConfig.files = ['test/runner.js'].concat(config.src, config.test);
var karmaServer = require('karma').server;
karmaServer.start(karmaConfig, function(exitCode) {
done(exitCode === 0);
});
});
grunt.task.registerMultiTask('sauce', 'Run <target> tests under Karma on Saucelabs', function() {
var done = this.async();
var karmaConfig = require('karma/lib/config').parseConfig(require('path').resolve('test/karma-config-ci.js'), {});
var config = targetConfig[this.target];
karmaConfig.files = ['test/runner.js'].concat(config.src, config.test);
karmaConfig.sauceLabs.testName = 'web-animation-next ' + this.target + ' Unit tests';
var karmaServer = require('karma').server;
karmaServer.start(karmaConfig, function(exitCode) {
done(exitCode === 0);
});
});
grunt.task.registerMultiTask('sourceMapConcat', 'concat source files and produce combined source map',
function() {
var sources = this.data.sources.map(grunt.file.read);
var sourceMaps = this.data.sources.map(function(f) { return grunt.file.read(f + '.map'); });
var out = "";
var outMapGenerator = new sourceMap.SourceMapGenerator({file: this.target});
var lineDelta = 0;
for (var i = 0; i < sources.length; i++) {
out += sources[i];
new sourceMap.SourceMapConsumer(sourceMaps[i]).eachMapping(function(mapping) {
outMapGenerator.addMapping({
generated: {line: mapping.generatedLine + lineDelta, column: mapping.generatedColumn},
original: {line: mapping.originalLine, column: mapping.originalColumn},
source: mapping.source, name: mapping.name});
});
var sourceLines = sources[i].split('\n');
lineDelta += sourceLines.length;
if (sources[i][sources[i].length - 1] !== '\n') {
out += '\n';
}
}
grunt.file.write(this.target, out);
grunt.file.write(this.target + '.map', outMapGenerator.toString());
});
grunt.task.registerMultiTask('wrap', 'Wrap <target> source file and update source map',
function() {
var inFile = grunt.file.read(this.data.source);
var inMap = grunt.file.read(this.data.source + '.map');
var inLines = inFile.split('\n');
var i = 0;
// Discover copyright header
while (inLines[i].length < 2 || inLines[i].substring(0, 2) == '//') {
i++;
}
// Fix mapping footer
var postamble = this.data.postamble;
if (inLines[inLines.length - 1].substring(0, 21) == '//# sourceMappingURL=') {
postamble += '\n//# sourceMappingURL=' + this.target + '.map';
}
if (i > 0) {
var banner = inLines.slice(0, i).join('\n') + '\n';
} else {
var banner = '';
}
var source = inLines.slice(i, inLines.length - 1).join('\n');
grunt.file.write(this.target, banner + this.data.preamble + source + postamble);
var preLines = this.data.preamble.split('\n');
var lineDelta = preLines.length;
if (this.data.preamble[this.data.preamble.length - 1] == '\n') {
var charDelta = 0;
} else {
var charDelta = preLines[lineDelta - 1].length;
lineDelta -= 1;
}
var inMapConsumer = new sourceMap.SourceMapConsumer(inMap);
var outMapGenerator = new sourceMap.SourceMapGenerator({file: this.target});
inMapConsumer.eachMapping(function(mapping) {
if (mapping.generatedLine == i + 1) {
mapping.generatedColumn += charDelta;
}
mapping.generatedLine += lineDelta;
outMapGenerator.addMapping(
{generated: {line: mapping.generatedLine, column: mapping.generatedColumn},
original: {line: mapping.originalLine, column: mapping.originalColumn},
source: mapping.source, name: mapping.name});
});
grunt.file.write(this.target + '.map', outMapGenerator.toString());
});
grunt.task.registerTask('clean', 'Remove files generated by grunt', function() {
grunt.file.expand('web-animations*').concat(grunt.file.expand('test/runner-*.html')).concat(grunt.file.expand('inter-*')).forEach(function(file) {
grunt.file.delete(file);
grunt.log.writeln('File ' + file + ' removed');
});
});
grunt.task.registerTask('default', ['web-animations', 'web-animations-next', 'web-animations-next-lite', 'gjslint']);
};

View File

@ -1,108 +0,0 @@
### 2.0.0 - *April 5 2015*
* Improve behavior of group Animation playback rate.
* Rename Animation to KeyframeEffect.
* Rename AnimationSequence to SequenceEffect.
* Rename AnimationGroup to GroupEffect.
* Rename AnimationPlayer to Animation.
* Remove KeyframeEffect.effect and add KeyframeEffect.getFrames.
* Rename Animation.source to Animation.effect.
* Rename Timeline.getAnimationPlayers to Timeline.getAnimations.
* Rename Element.getAnimationPlayers to Element.getAnimations.
### 1.0.7 - *March 10 2015*
* Improve performance of constructing groups and sequences.
* Remove support for animating zoom.
* Add bower file.
### 1.0.6 - *February 5 2015*
* Implement playbackRate setter for group players.
* Fix pausing a group player before its first tick.
* Fix cancelling a group player before its first tick.
* Fix excess CPU use on idle pages where custom effects and groups were used.
* Suppress AnimationTiming.playbackRate deprecation warning for cases where AnimationTiming.playbackRate == 1.
### 1.0.5 - *January 6 2015*
* Fix loading the polyfill in an SVG document
* Fix a problem where groups didn't take effect in their first frame
* Don't rely on performance.now
### 1.0.4 - *December 8 2014*
* Fix a critical bug where deprecation logic wasn't being loaded
when `web-animations-next` and `web-animations-next-lite` were
executed on top of a native `element.animate`.
### 1.0.3 - *December 4 2014*
* Fix a critical bug on iOS 7 and Safari <= 6. Due to limitations,
inline style patching is not supported on these platforms.
### 1.0.2 - *November 28 2014*
* Deprecated `AnimationTiming.playbackRate`.
For example, this is no longer supported:
var player = element.animate(
keyframes,
{duration: 1000, playbackRate: 2});
Use `AnimationPlayer.playbackRate` instead:
var player = element.animate(
keyframes,
{duration: 1000});
player.playbackRate = 2;
If you have any feedback on this change, please start a discussion
on the public-fx mailing list:
http://lists.w3.org/Archives/Public/public-fx/
Or file an issue against the specification on GitHub:
https://github.com/w3c/web-animations/issues/new
### 1.0.1 - *November 26 2014*
* Players should be constructed in idle state
* `play()` and `reverse()` should not force a start times
* Add `requestAnimationFrame` ids and `cancelAnimationFrame`
### 1.0.0 — *November 21 2014*
The web-animations-js hackers are pleased to announce the release of
a new codebase for the Web Animations Polyfill:
https://github.com/web-animations/web-animations-js
The previous polyfill has been moved to:
https://github.com/web-animations/web-animations-js-legacy
The new codebase is focused on code-size -- our smallest target is
now only 33kb or 11kb after gzip.
We've implemented native fallback. If the target browser provides
Web Animations features natively, the Polyfill will use them.
We now provide three different build targets:
`web-animations.min.js` - Tracks the Web Animations features that
are supported natively in browsers. Today that means Element.animate
and Playback Control in Chrome. If youre not sure what features you
will need, start with this.
`web-animations-next.min.js` - All of web-animations.min.js plus
features that are still undergoing discussion or have yet to be
implemented natively.
`web-animations-next-lite.min.js` - A cut down version of
web-animations-next, removes several lesser used property handlers
and some of the larger and less used features such as matrix
interpolation/decomposition.
Not all features of the previous polyfill have been ported to the
new codebase; most notably mutation of Animations and Groups and
Additive Animations are not yet supported. These features are still
important and will be implemented in the coming weeks.

View File

@ -1,161 +0,0 @@
Quick Start
-----------
To provide native Chrome Web Animation features (`Element.animate` and Playback
Control) in other browsers, use `web-animations.min.js`. To explore all of the
proposed Web Animations API, use `web-animations-next.min.js`.
What is Web Animations?
-----------------------
Web Animations is a new JavaScript API for driving animated content on the web.
By unifying the animation features of SVG and CSS, Web Animations unlocks
features previously only usable declaratively, and exposes powerful,
high-performance animation capabilities to developers.
For more details see the
[W3C specification](http://w3c.github.io/web-animations/).
What is the polyfill?
---------------------
The polyfill is a JavaScript implementation of the Web Animations API. It works
on modern versions of all major browsers. For more details about browser
support see <https://www.polymer-project.org/resources/compatibility.html>.
Getting Started
---------------
Here's a simple example of an animation that scales and changes the opacity of
a `<div>` over 0.5 seconds. The animation alternates producing a pulsing
effect.
<script src="web-animations.min.js"></script>
<div class="pulse" style="width:150px;">Hello world!</div>
<script>
var elem = document.querySelector('.pulse');
var animation = elem.animate([
{opacity: 0.5, transform: "scale(0.5)"},
{opacity: 1.0, transform: "scale(1)"}
], {
direction: 'alternate',
duration: 500,
iterations: Infinity
});
</script>
Web Animations supports off-main-thread animations, and also allows procedural
generation of animations and fine-grained control of animation playback. See
<http://web-animations.github.io> for ideas and inspiration!
Native Fallback
---------------
When the polyfill runs on a browser that implements `Element.animate` and
`Animation` Playback Control it will detect and use the underlying native
features.
Different Build Targets
-----------------------
### web-animations.min.js
Tracks the Web Animations features that are supported natively in browsers.
Today that means Element.animate and Playback Control in Chrome. If youre not
sure what features you will need, start with this.
### web-animations-next.min.js
Contains all of web-animations.min.js plus features that are still undergoing
discussion or have yet to be implemented natively.
### web-animations-next-lite.min.js
A cut down version of web-animations-next, it removes several lesser used
property handlers and some of the larger and less used features such as matrix
interpolation/decomposition.
### Build Target Comparison
| | web-animations | web-animations-next | web-animations-next-lite |
|------------------------|:--------------:|:-------------------:|:------------------------:|
|Size (gzipped) | 12.5kb | 14kb | 10.5kb |
|Element.animate | ✔ | ✔ | ✔ |
|Timing input (easings, duration, fillMode, etc.) for animation effects| ✔ | ✔ | ✔ |
|Playback control | ✔ | ✔ | ✔ |
|Support for animating lengths, transforms and opacity| ✔ | ✔ | ✔ |
|Support for animating other CSS properties| ✔ | ✔ | 🚫 |
|Matrix fallback for transform animations | ✔ | ✔ | 🚫 |
|KeyframeEffect constructor | 🚫 | ✔ | ✔ |
|Simple GroupEffects & SequenceEffects | 🚫 | ✔ | ✔ |
|Custom Effects | 🚫 | ✔ | ✔ |
|Timing input (easings, duration, fillMode, etc.) for groups</div>| 🚫 | 🚫\* | 🚫 |
|Additive animation | 🚫 | 🚫\* | 🚫 |
|Motion path | 🚫\* | 🚫\* | 🚫 |
|Modifiable keyframe effect timing| 🚫 | 🚫\* | 🚫\* |
|Modifiable group timing | 🚫 | 🚫\* | 🚫\* |
|Usable inline style\*\* | ✔ | ✔ | 🚫 |
\* support is planned for these features.
\*\* see inline style caveat below.
Caveats
-------
Some things wont ever be faithful to the native implementation due to browser
and CSS API limitations. These include:
### Inline Style
Inline style modification is the mechanism used by the polyfill to animate
properties. Both web-animations and web-animations-next incorporate a module
that emulates a vanilla inline style object, so that style modification from
JavaScript can still work in the presence of animations. However, to keep the
size of web-animations-next-lite as small as possible, the style emulation
module is not included. When using this version of the polyfill, JavaScript
inline style modification will be overwritten by animations.
Due to browser constraints inline style modification is not supported on iOS 7
or Safari 6 (or earlier versions).
### Prefix handling
The polyfill will automatically detect the correctly prefixed name to use when
writing animated properties back to the platform. Where possible, the polyfill
will only accept unprefixed versions of experimental features. For example:
var effect = new KeyframeEffect(elem, {"transform": "translate(100px, 100px)"}, 2000);
will work in all browsers that implement a conforming version of transform, but
var effect = new KeyframeEffect(elem, {"-webkit-transform": "translate(100px, 100px)"}, 2000);
will not work anywhere.
API and Specification Feedback
------------------------------
File an issue on GitHub: <https://github.com/w3c/web-animations/issues/new>.
Alternatively, send an email to <public-fx@w3.org> with subject line
“[web-animations] … message topic …”
([archives](http://lists.w3.org/Archives/Public/public-fx/)).
Polyfill Issues
---------------
Report any issues with this implementation on GitHub:
<https://github.com/web-animations/web-animations-next/issues/new>.
Breaking changes
----------------
When we make a potentially breaking change to the polyfill's API
surface (like a rename) we will, where possible, continue supporting the
old version, deprecated, for three months, and ensure that there are
console warnings to indicate that a change is pending. After three
months, the old version of the API surface (e.g. the old version of a
function name) will be removed. *If you see deprecation warnings you
can't avoid it by not updating*.
We also announce anything that isn't a bug fix on
[web-animations-changes@googlegroups.com](https://groups.google.com/forum/#!forum/web-animations-changes).

View File

@ -1,31 +0,0 @@
{
"name": "web-animations-js",
"description": "JavaScript implementation of the Web Animations API",
"homepage": "https://github.com/web-animations/web-animations-js",
"main": "web-animations.min.js",
"moduleType": [
"globals"
],
"keywords": [
"animations",
"polyfill"
],
"license": "Apache-2.0",
"ignore": [
"**/.*",
"node_modules",
"templates",
"test",
"src",
"Gruntfile.js",
"package.json",
"target-config.js",
"target-loader.js",
"web-animations.dev.html",
"web-animations.dev.js",
"web-animations-next.dev.html",
"web-animations-next.dev.js",
"web-animations-next-lite.dev.html",
"web-animations-next-lite.dev.js"
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,33 +0,0 @@
{
"name": "web-animations-js",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/web-animations/web-animations-js.git"
},
"devDependencies": {
"mocha": "1.21.4",
"chai": "^1.9.1",
"grunt": "~0.4.5",
"grunt-contrib-uglify": "^0.4.0",
"grunt-gjslint": "^0.1.4",
"grunt-karma": "^0.8.2",
"karma": "^0.12.14",
"karma-mocha": "^0.1.3",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "~0.1.4",
"karma-firefox-launcher": "~0.1.3",
"karma-ie-launcher": "~0.1.5",
"karma-safari-launcher": "~0.1.1",
"karma-sauce-launcher": "~0.2.3",
"grunt-checkrepo": "~0.1.0",
"grunt-saucelabs": "~4.0.2",
"grunt-checkrepo": "~0.1.0",
"grunt-git-status": "~1.0.0",
"grunt-template": "~0.2.3",
"source-map": "~0.1.40"
},
"scripts": {
"test": "grunt test gjslint git-status checkrepo"
}
}

View File

@ -1,218 +0,0 @@
// 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(scope, testing) {
var sequenceNumber = 0;
var AnimationEvent = function(target, currentTime, timelineTime) {
this.target = target;
this.currentTime = currentTime;
this.timelineTime = timelineTime;
this.type = 'finish';
this.bubbles = false;
this.cancelable = false;
this.currentTarget = target;
this.defaultPrevented = false;
this.eventPhase = Event.AT_TARGET;
this.timeStamp = Date.now();
};
scope.Animation = function(effect) {
this._sequenceNumber = sequenceNumber++;
this._currentTime = 0;
this._startTime = null;
this.paused = false;
this._playbackRate = 1;
this._inTimeline = true;
this._finishedFlag = false;
this.onfinish = null;
this._finishHandlers = [];
this._effect = effect;
this._inEffect = this._effect._update(0);
this._idle = true;
this._currentTimePending = false;
};
scope.Animation.prototype = {
_ensureAlive: function() {
// If an animation is playing backwards and is not fill backwards/both
// then it should go out of effect when it reaches the start of its
// active interval (currentTime == 0).
if (this.playbackRate < 0 && this.currentTime === 0) {
this._inEffect = this._effect._update(-1);
} else {
this._inEffect = this._effect._update(this.currentTime);
}
if (!this._inTimeline && (this._inEffect || !this._finishedFlag)) {
this._inTimeline = true;
scope.timeline._animations.push(this);
}
},
_tickCurrentTime: function(newTime, ignoreLimit) {
if (newTime != this._currentTime) {
this._currentTime = newTime;
if (this.finished && !ignoreLimit)
this._currentTime = this._playbackRate > 0 ? this._totalDuration : 0;
this._ensureAlive();
}
},
get currentTime() {
if (this._idle || this._currentTimePending)
return null;
return this._currentTime;
},
set currentTime(newTime) {
newTime = +newTime;
if (isNaN(newTime))
return;
scope.restart();
if (!this.paused && this._startTime != null) {
this._startTime = this._timeline.currentTime - newTime / this._playbackRate;
}
this._currentTimePending = false;
if (this._currentTime == newTime)
return;
this._tickCurrentTime(newTime, true);
scope.invalidateEffects();
},
get startTime() {
return this._startTime;
},
set startTime(newTime) {
newTime = +newTime;
if (isNaN(newTime))
return;
if (this.paused || this._idle)
return;
this._startTime = newTime;
this._tickCurrentTime((this._timeline.currentTime - this._startTime) * this.playbackRate);
scope.invalidateEffects();
},
get playbackRate() {
return this._playbackRate;
},
set playbackRate(value) {
if (value == this._playbackRate) {
return;
}
var oldCurrentTime = this.currentTime;
this._playbackRate = value;
this._startTime = null;
if (this.playState != 'paused' && this.playState != 'idle') {
this.play();
}
if (oldCurrentTime != null) {
this.currentTime = oldCurrentTime;
}
},
get finished() {
return !this._idle && (this._playbackRate > 0 && this._currentTime >= this._totalDuration ||
this._playbackRate < 0 && this._currentTime <= 0);
},
get _totalDuration() { return this._effect._totalDuration; },
get playState() {
if (this._idle)
return 'idle';
if ((this._startTime == null && !this.paused && this.playbackRate != 0) || this._currentTimePending)
return 'pending';
if (this.paused)
return 'paused';
if (this.finished)
return 'finished';
return 'running';
},
play: function() {
this.paused = false;
if (this.finished || this._idle) {
this._currentTime = this._playbackRate > 0 ? 0 : this._totalDuration;
this._startTime = null;
scope.invalidateEffects();
}
this._finishedFlag = false;
scope.restart();
this._idle = false;
this._ensureAlive();
},
pause: function() {
if (!this.finished && !this.paused && !this._idle) {
this._currentTimePending = true;
}
this._startTime = null;
this.paused = true;
},
finish: function() {
if (this._idle)
return;
this.currentTime = this._playbackRate > 0 ? this._totalDuration : 0;
this._startTime = this._totalDuration - this.currentTime;
this._currentTimePending = false;
},
cancel: function() {
this._inEffect = false;
this._idle = true;
this.currentTime = 0;
this._startTime = null;
},
reverse: function() {
this.playbackRate *= -1;
this.play();
},
addEventListener: function(type, handler) {
if (typeof handler == 'function' && type == 'finish')
this._finishHandlers.push(handler);
},
removeEventListener: function(type, handler) {
if (type != 'finish')
return;
var index = this._finishHandlers.indexOf(handler);
if (index >= 0)
this._finishHandlers.splice(index, 1);
},
_fireEvents: function(baseTime) {
var finished = this.finished;
if ((finished || this._idle) && !this._finishedFlag) {
var event = new AnimationEvent(this, this._currentTime, baseTime);
var handlers = this._finishHandlers.concat(this.onfinish ? [this.onfinish] : []);
// setTimeout(function() {
// handlers.forEach(function(handler) {
// handler.call(event.target, event);
// });
// }, 0);
handlers.forEach(function(handler) {
handler.call(event.target, event);
});
}
this._finishedFlag = finished;
},
_tick: function(timelineTime) {
if (!this._idle && !this.paused) {
if (this._startTime == null)
this.startTime = timelineTime - this._currentTime / this.playbackRate;
else if (!this.finished)
this._tickCurrentTime((timelineTime - this._startTime) * this.playbackRate);
}
this._currentTimePending = false;
this._fireEvents(timelineTime);
return !this._idle && (this._inEffect || !this._finishedFlag);
},
};
if (WEB_ANIMATIONS_TESTING) {
testing.webAnimations1Animation = scope.Animation;
}
})(webAnimations1, webAnimationsTesting);

View File

@ -1,191 +0,0 @@
// 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(scope, testing) {
var styleAttributes = {
cssText: 1,
length: 1,
parentRule: 1,
};
var styleMethods = {
getPropertyCSSValue: 1,
getPropertyPriority: 1,
getPropertyValue: 1,
item: 1,
removeProperty: 1,
setProperty: 1,
};
var styleMutatingMethods = {
removeProperty: 1,
setProperty: 1,
};
function configureProperty(object, property, descriptor) {
descriptor.enumerable = true;
descriptor.configurable = true;
Object.defineProperty(object, property, descriptor);
}
function AnimatedCSSStyleDeclaration(element) {
WEB_ANIMATIONS_TESTING && console.assert(!(element.style instanceof AnimatedCSSStyleDeclaration),
'Element must not already have an animated style attached.');
// Stores the inline style of the element on its behalf while the
// polyfill uses the element's inline style to simulate web animations.
// This is needed to fake regular inline style CSSOM access on the element.
this._surrogateStyle = document.createElementNS('http://www.w3.org/1999/xhtml', 'div').style;
this._style = element.style;
this._length = 0;
this._isAnimatedProperty = {};
// Copy the inline style contents over to the surrogate.
for (var i = 0; i < this._style.length; i++) {
var property = this._style[i];
this._surrogateStyle[property] = this._style[property];
}
this._updateIndices();
}
AnimatedCSSStyleDeclaration.prototype = {
get cssText() {
return this._surrogateStyle.cssText;
},
set cssText(text) {
var isAffectedProperty = {};
for (var i = 0; i < this._surrogateStyle.length; i++) {
isAffectedProperty[this._surrogateStyle[i]] = true;
}
this._surrogateStyle.cssText = text;
this._updateIndices();
for (var i = 0; i < this._surrogateStyle.length; i++) {
isAffectedProperty[this._surrogateStyle[i]] = true;
}
for (var property in isAffectedProperty) {
if (!this._isAnimatedProperty[property]) {
this._style.setProperty(property, this._surrogateStyle.getPropertyValue(property));
}
}
},
get length() {
return this._surrogateStyle.length;
},
get parentRule() {
return this._style.parentRule;
},
// Mirror the indexed getters and setters of the surrogate style.
_updateIndices: function() {
while (this._length < this._surrogateStyle.length) {
Object.defineProperty(this, this._length, {
configurable: true,
enumerable: false,
get: (function(index) {
return function() { return this._surrogateStyle[index]; };
})(this._length)
});
this._length++;
}
while (this._length > this._surrogateStyle.length) {
this._length--;
Object.defineProperty(this, this._length, {
configurable: true,
enumerable: false,
value: undefined
});
}
},
_set: function(property, value) {
this._style[property] = value;
this._isAnimatedProperty[property] = true;
},
_clear: function(property) {
this._style[property] = this._surrogateStyle[property];
delete this._isAnimatedProperty[property];
},
};
// Wrap the style methods.
for (var method in styleMethods) {
AnimatedCSSStyleDeclaration.prototype[method] = (function(method, modifiesStyle) {
return function() {
var result = this._surrogateStyle[method].apply(this._surrogateStyle, arguments);
if (modifiesStyle) {
if (!this._isAnimatedProperty[arguments[0]])
this._style[method].apply(this._style, arguments);
this._updateIndices();
}
return result;
}
})(method, method in styleMutatingMethods);
}
// Wrap the style.cssProperty getters and setters.
for (var property in document.documentElement.style) {
if (property in styleAttributes || property in styleMethods) {
continue;
}
(function(property) {
configureProperty(AnimatedCSSStyleDeclaration.prototype, property, {
get: function() {
return this._surrogateStyle[property];
},
set: function(value) {
this._surrogateStyle[property] = value;
this._updateIndices();
if (!this._isAnimatedProperty[property])
this._style[property] = value;
}
});
})(property);
}
function ensureStyleIsPatched(element) {
if (element._webAnimationsPatchedStyle)
return;
var animatedStyle = new AnimatedCSSStyleDeclaration(element);
try {
configureProperty(element, 'style', { get: function() { return animatedStyle; } });
} catch (_) {
// iOS and older versions of Safari (pre v7) do not support overriding an element's
// style object. Animations will clobber any inline styles as a result.
element.style._set = function(property, value) {
element.style[property] = value;
};
element.style._clear = function(property) {
element.style[property] = '';
};
}
// We must keep a handle on the patched style to prevent it from getting GC'd.
element._webAnimationsPatchedStyle = element.style;
}
scope.apply = function(element, property, value) {
ensureStyleIsPatched(element);
element.style._set(scope.propertyName(property), value);
};
scope.clear = function(element, property) {
if (element._webAnimationsPatchedStyle) {
element.style._clear(scope.propertyName(property));
}
};
if (WEB_ANIMATIONS_TESTING)
testing.ensureStyleIsPatched = ensureStyleIsPatched;
})(webAnimations1, webAnimationsTesting);

View File

@ -1,25 +0,0 @@
// 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(scope, testing) {
scope.apply = function(element, property, value) {
element.style[scope.propertyName(property)] = value;
};
scope.clear = function(element, property) {
element.style[scope.propertyName(property)] = '';
};
})(webAnimations1, webAnimationsTesting);

View File

@ -1,57 +0,0 @@
// 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(scope, testing) {
function consumeLengthPercentOrAuto(string) {
return scope.consumeLengthOrPercent(string) || scope.consumeToken(/^auto/, string);
}
function parseBox(string) {
var result = scope.consumeList([
scope.ignore(scope.consumeToken.bind(null, /^rect/)),
scope.ignore(scope.consumeToken.bind(null, /^\(/)),
scope.consumeRepeated.bind(null, consumeLengthPercentOrAuto, /^,/),
scope.ignore(scope.consumeToken.bind(null, /^\)/)),
], string);
if (result && result[0].length == 4) {
return result[0];
}
}
function mergeComponent(left, right) {
if (left == 'auto' || right == 'auto') {
return [true, false, function(t) {
var result = t ? left : right;
if (result == 'auto') {
return 'auto';
}
// FIXME: There's probably a better way to turn a dimension back into a string.
var merged = scope.mergeDimensions(result, result);
return merged[2](merged[0]);
}];
}
return scope.mergeDimensions(left, right);
}
function wrap(result) {
return 'rect(' + result + ')';
}
var mergeBoxes = scope.mergeWrappedNestedRepeated.bind(null, wrap, mergeComponent, ', ');
scope.parseBox = parseBox;
scope.mergeBoxes = mergeBoxes;
scope.addPropertiesHandler(parseBox, mergeBoxes, ['clip']);
})(webAnimations1, webAnimationsTesting);

View File

@ -1,62 +0,0 @@
// 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(scope, testing) {
var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
canvas.width = canvas.height = 1;
var context = canvas.getContext('2d');
function parseColor(string) {
string = string.trim();
// The context ignores invalid colors
context.fillStyle = '#000';
context.fillStyle = string;
var contextSerializedFillStyle = context.fillStyle;
context.fillStyle = '#fff';
context.fillStyle = string;
if (contextSerializedFillStyle != context.fillStyle)
return;
context.fillRect(0, 0, 1, 1);
var pixelColor = context.getImageData(0, 0, 1, 1).data;
context.clearRect(0, 0, 1, 1);
var alpha = pixelColor[3] / 255;
return [pixelColor[0] * alpha, pixelColor[1] * alpha, pixelColor[2] * alpha, alpha];
}
function mergeColors(left, right) {
return [left, right, function(x) {
function clamp(v) {
return Math.max(0, Math.min(255, v));
}
if (x[3]) {
for (var i = 0; i < 3; i++)
x[i] = Math.round(clamp(x[i] / x[3]));
}
x[3] = scope.numberToString(scope.clamp(0, 1, x[3]));
return 'rgba(' + x.join(',') + ')';
}];
}
scope.addPropertiesHandler(parseColor, mergeColors,
['background-color', 'border-bottom-color', 'border-left-color', 'border-right-color',
'border-top-color', 'color', 'outline-color', 'text-decoration-color']);
scope.consumeColor = scope.consumeParenthesised.bind(null, parseColor);
scope.mergeColors = mergeColors;
if (WEB_ANIMATIONS_TESTING) {
testing.parseColor = parseColor;
}
})(webAnimations1, webAnimationsTesting);

View File

@ -1,43 +0,0 @@
// 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) {
var silenced = {};
shared.isDeprecated = function(feature, date, advice, plural) {
var auxVerb = plural ? 'are' : 'is';
var today = new Date();
var expiry = new Date(date);
expiry.setMonth(expiry.getMonth() + 3); // 3 months grace period
if (today < expiry) {
if (!(feature in silenced)) {
console.warn('Web Animations: ' + feature + ' ' + auxVerb + ' deprecated and will stop working on ' + expiry.toDateString() + '. ' + advice);
}
silenced[feature] = true;
return false;
} else {
return true;
}
};
shared.deprecated = function(feature, date, advice, plural) {
var auxVerb = plural ? 'are' : 'is';
if (shared.isDeprecated(feature, date, advice, plural)) {
throw new Error(feature + ' ' + auxVerb + ' no longer supported. ' + advice);
}
};
})(webAnimationsShared);

View File

@ -1,16 +0,0 @@
// 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.
var WEB_ANIMATIONS_TESTING = false;
var webAnimationsTesting = null;

View File

@ -1,167 +0,0 @@
// 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(scope, testing) {
function parseDimension(unitRegExp, string) {
string = string.trim().toLowerCase();
if (string == '0' && 'px'.search(unitRegExp) >= 0)
return {px: 0};
// If we have parenthesis, we're a calc and need to start with 'calc'.
if (!/^[^(]*$|^calc/.test(string))
return;
string = string.replace(/calc\(/g, '(');
// We tag units by prefixing them with 'U' (note that we are already
// lowercase) to prevent problems with types which are substrings of
// each other (although prefixes may be problematic!)
var matchedUnits = {};
string = string.replace(unitRegExp, function(match) {
matchedUnits[match] = null;
return 'U' + match;
});
var taggedUnitRegExp = 'U(' + unitRegExp.source + ')';
// Validating input is simply applying as many reductions as we can.
var typeCheck = string.replace(/[-+]?(\d*\.)?\d+/g, 'N')
.replace(new RegExp('N' + taggedUnitRegExp, 'g'), 'D')
.replace(/\s[+-]\s/g, 'O')
.replace(/\s/g, '');
var reductions = [/N\*(D)/g, /(N|D)[*/]N/g, /(N|D)O\1/g, /\((N|D)\)/g];
var i = 0;
while (i < reductions.length) {
if (reductions[i].test(typeCheck)) {
typeCheck = typeCheck.replace(reductions[i], '$1');
i = 0;
} else {
i++;
}
}
if (typeCheck != 'D')
return;
for (var unit in matchedUnits) {
var result = eval(string.replace(new RegExp('U' + unit, 'g'), '').replace(new RegExp(taggedUnitRegExp, 'g'), '*0'));
if (!isFinite(result))
return;
matchedUnits[unit] = result;
}
return matchedUnits;
}
function mergeDimensionsNonNegative(left, right) {
return mergeDimensions(left, right, true);
}
function mergeDimensions(left, right, nonNegative) {
var units = [], unit;
for (unit in left)
units.push(unit);
for (unit in right) {
if (units.indexOf(unit) < 0)
units.push(unit);
}
left = units.map(function(unit) { return left[unit] || 0; });
right = units.map(function(unit) { return right[unit] || 0; });
return [left, right, function(values) {
var result = values.map(function(value, i) {
if (values.length == 1 && nonNegative) {
value = Math.max(value, 0);
}
// Scientific notation (e.g. 1e2) is not yet widely supported by browser vendors.
return scope.numberToString(value) + units[i];
}).join(' + ');
return values.length > 1 ? 'calc(' + result + ')' : result;
}];
}
var lengthUnits = 'px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc';
var parseLength = parseDimension.bind(null, new RegExp(lengthUnits, 'g'));
var parseLengthOrPercent = parseDimension.bind(null, new RegExp(lengthUnits + '|%', 'g'));
var parseAngle = parseDimension.bind(null, /deg|rad|grad|turn/g);
scope.parseLength = parseLength;
scope.parseLengthOrPercent = parseLengthOrPercent;
scope.consumeLengthOrPercent = scope.consumeParenthesised.bind(null, parseLengthOrPercent);
scope.parseAngle = parseAngle;
scope.mergeDimensions = mergeDimensions;
var consumeLength = scope.consumeParenthesised.bind(null, parseLength);
var consumeSizePair = scope.consumeRepeated.bind(undefined, consumeLength, /^/);
var consumeSizePairList = scope.consumeRepeated.bind(undefined, consumeSizePair, /^,/);
scope.consumeSizePairList = consumeSizePairList;
var parseSizePairList = function(input) {
var result = consumeSizePairList(input);
if (result && result[1] == '') {
return result[0];
}
};
var mergeNonNegativeSizePair = scope.mergeNestedRepeated.bind(undefined, mergeDimensionsNonNegative, ' ');
var mergeNonNegativeSizePairList = scope.mergeNestedRepeated.bind(undefined, mergeNonNegativeSizePair, ',');
scope.mergeNonNegativeSizePair = mergeNonNegativeSizePair;
scope.addPropertiesHandler(parseSizePairList, mergeNonNegativeSizePairList, [
'background-size'
]);
scope.addPropertiesHandler(parseLengthOrPercent, mergeDimensionsNonNegative, [
'border-bottom-width',
'border-image-width',
'border-left-width',
'border-right-width',
'border-top-width',
'flex-basis',
'font-size',
'height',
'line-height',
'max-height',
'max-width',
'outline-width',
'width',
]);
scope.addPropertiesHandler(parseLengthOrPercent, mergeDimensions, [
'border-bottom-left-radius',
'border-bottom-right-radius',
'border-top-left-radius',
'border-top-right-radius',
'bottom',
'left',
'letter-spacing',
'margin-bottom',
'margin-left',
'margin-right',
'margin-top',
'min-height',
'min-width',
'outline-offset',
'padding-bottom',
'padding-left',
'padding-right',
'padding-top',
'perspective',
'right',
'shape-margin',
'text-indent',
'top',
'vertical-align',
'word-spacing',
]);
})(webAnimations1, webAnimationsTesting);

View File

@ -1,87 +0,0 @@
// 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) {
var nullTarget = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
var sequenceNumber = 0;
scope.bindAnimationForCustomEffect = function(animation) {
var target = animation.effect.target;
var effectFunction = animation.effect._normalizedKeyframes;
var timing = animation.effect.timing;
var last = null;
timing = shared.normalizeTimingInput(timing);
var callback = function() {
var t = callback._animation ? callback._animation.currentTime : null;
if (t !== null) {
t = shared.calculateTimeFraction(shared.calculateActiveDuration(timing), t, timing);
if (isNaN(t))
t = null;
}
// FIXME: There are actually more conditions under which the effectFunction
// should be called.
if (t !== last)
effectFunction(t, target, animation.effect);
last = t;
};
callback._animation = animation;
callback._registered = false;
callback._sequenceNumber = sequenceNumber++;
animation._callback = callback;
register(callback);
};
var callbacks = [];
var ticking = false;
function register(callback) {
if (callback._registered)
return;
callback._registered = true;
callbacks.push(callback);
if (!ticking) {
ticking = true;
requestAnimationFrame(tick);
}
}
function tick(t) {
var updating = callbacks;
callbacks = [];
updating.sort(function(left, right) {
return left._sequenceNumber - right._sequenceNumber;
});
updating = updating.filter(function(callback) {
callback();
var playState = callback._animation ? callback._animation.playState : 'idle';
if (playState != 'running' && playState != 'pending')
callback._registered = false;
return callback._registered;
});
callbacks.push.apply(callbacks, updating);
if (callbacks.length) {
ticking = true;
requestAnimationFrame(tick);
} else {
ticking = false;
}
}
scope.Animation.prototype._register = function() {
if (this._callback)
register(this._callback);
};
})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);

View File

@ -1,19 +0,0 @@
// 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(scope) {
window.Element.prototype.animate = function(effectInput, timingInput) {
return scope.timeline._play(scope.KeyframeEffect(this, effectInput, timingInput));
};
})(webAnimations1);

View File

@ -1,42 +0,0 @@
// 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(scope) {
function parse(string) {
var out = Number(string);
if (isNaN(out) || out < 100 || out > 900 || out % 100 !== 0) {
return;
}
return out;
}
function toCss(value) {
value = Math.round(value / 100) * 100;
value = scope.clamp(100, 900, value);
if (value === 400) {
return 'normal';
}
if (value === 700) {
return 'bold';
}
return String(value);
}
function merge(left, right) {
return [left, right, toCss];
}
scope.addPropertiesHandler(parse, merge, ['font-weight']);
})(webAnimations1);

View File

@ -1,124 +0,0 @@
// 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) {
this.children = children || [];
this._timing = shared.normalizeTimingInput(timingInput, true);
this.timing = shared.makeTiming(timingInput, true);
if (this._timing.duration === 'auto')
this._timing.duration = this.activeDuration;
}
window.SequenceEffect = function() {
constructor.apply(this, arguments);
};
window.GroupEffect = function() {
constructor.apply(this, arguments);
};
window.SequenceEffect.prototype = {
get activeDuration() {
var total = 0;
this.children.forEach(function(child) {
total += groupChildDuration(child);
});
return Math.max(total, 0);
}
};
window.GroupEffect.prototype = {
get activeDuration() {
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.playState == 'pending')
return;
if (!animation.effect)
return;
if (tf == null) {
animation._removeChildren();
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. calculateTimeFraction 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.calculateTimeFraction(shared.calculateActiveDuration(timing), -1, timing);
if (isNaN(tf) || tf == null) {
animation._forEachChild(function(child) {
child.currentTime = -1;
});
animation._removeChildren();
return;
}
}
};
underlyingAnimation = scope.timeline.play(new scope.KeyframeEffect(null, ticker, group._timing));
return underlyingAnimation;
};
scope.bindAnimationForGroup = function(animation) {
animation._animation._wrapper = animation;
animation._isGroup = true;
scope.awaitStartTime(animation);
animation._constructChildren();
animation._setExternalAnimation(animation);
};
scope.groupChildDuration = groupChildDuration;
// Alias GroupEffect & SequenceEffect to AnimationGroup & AnimationSequence respectively, to
// support old constructors (Animation*) for a deprecation period. Should be removed after 23 June
// 2015.
window.AnimationSequence = function() {
shared.deprecated('window.AnimationSequence', '2015-03-23', 'Use window.SequenceEffect instead.');
window.SequenceEffect.apply(this, arguments);
};
window.AnimationSequence.prototype = Object.create(window.SequenceEffect.prototype);
window.AnimationSequence.prototype.constructor = window.AnimationSequence;
window.AnimationGroup = function() {
shared.deprecated('window.AnimationGroup', '2015-03-23', 'Use window.GroupEffect instead.');
window.GroupEffect.apply(this, arguments);
};
window.AnimationGroup.prototype = Object.create(window.GroupEffect.prototype);
window.AnimationGroup.prototype.constructor = window.AnimationGroup;
})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);

View File

@ -1,177 +0,0 @@
// 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(scope) {
// consume* functions return a 2 value array of [parsed-data, '' or not-yet consumed input]
// Regex should be anchored with /^
function consumeToken(regex, string) {
var result = regex.exec(string);
if (result) {
result = regex.ignoreCase ? result[0].toLowerCase() : result[0];
return [result, string.substr(result.length)];
}
}
function consumeTrimmed(consumer, string) {
string = string.replace(/^\s*/, '');
var result = consumer(string);
if (result) {
return [result[0], result[1].replace(/^\s*/, '')];
}
}
function consumeRepeated(consumer, separator, string) {
consumer = consumeTrimmed.bind(null, consumer);
var list = [];
while (true) {
var result = consumer(string);
if (!result) {
return [list, string];
}
list.push(result[0]);
string = result[1];
result = consumeToken(separator, string);
if (!result || result[1] == '') {
return [list, string];
}
string = result[1];
}
}
// Consumes a token or expression with balanced parentheses
function consumeParenthesised(parser, string) {
var nesting = 0;
for (var n = 0; n < string.length; n++) {
if (/\s|,/.test(string[n]) && nesting == 0) {
break;
} else if (string[n] == '(') {
nesting++;
} else if (string[n] == ')') {
nesting--;
if (nesting == 0)
n++;
if (nesting <= 0)
break;
}
}
var parsed = parser(string.substr(0, n));
return parsed == undefined ? undefined : [parsed, string.substr(n)];
}
function lcm(a, b) {
var c = a;
var d = b;
while (c && d)
c > d ? c %= d : d %= c;
c = (a * b) / (c + d);
return c;
}
function ignore(value) {
return function(input) {
var result = value(input);
if (result)
result[0] = undefined;
return result;
}
}
function optional(value, defaultValue) {
return function(input) {
var result = value(input);
if (result)
return result;
return [defaultValue, input];
}
}
function consumeList(list, input) {
var output = [];
for (var i = 0; i < list.length; i++) {
var result = scope.consumeTrimmed(list[i], input);
if (!result || result[0] == '')
return;
if (result[0] !== undefined)
output.push(result[0]);
input = result[1];
}
if (input == '') {
return output;
}
}
function mergeWrappedNestedRepeated(wrap, nestedMerge, separator, left, right) {
var matchingLeft = [];
var matchingRight = [];
var reconsititution = [];
var length = lcm(left.length, right.length);
for (var i = 0; i < length; i++) {
var thing = nestedMerge(left[i % left.length], right[i % right.length]);
if (!thing) {
return;
}
matchingLeft.push(thing[0]);
matchingRight.push(thing[1]);
reconsititution.push(thing[2]);
}
return [matchingLeft, matchingRight, function(positions) {
var result = positions.map(function(position, i) {
return reconsititution[i](position);
}).join(separator);
return wrap ? wrap(result) : result;
}];
}
function mergeList(left, right, list) {
var lefts = [];
var rights = [];
var functions = [];
var j = 0;
for (var i = 0; i < list.length; i++) {
if (typeof list[i] == 'function') {
var result = list[i](left[j], right[j++]);
lefts.push(result[0]);
rights.push(result[1]);
functions.push(result[2]);
} else {
(function(pos) {
lefts.push(false);
rights.push(false);
functions.push(function() { return list[pos]; });
})(i);
}
}
return [lefts, rights, function(results) {
var result = '';
for (var i = 0; i < results.length; i++) {
result += functions[i](results[i]);
}
return result;
}];
}
scope.consumeToken = consumeToken;
scope.consumeTrimmed = consumeTrimmed;
scope.consumeRepeated = consumeRepeated;
scope.consumeParenthesised = consumeParenthesised;
scope.ignore = ignore;
scope.optional = optional;
scope.consumeList = consumeList;
scope.mergeNestedRepeated = mergeWrappedNestedRepeated.bind(null, null);
scope.mergeWrappedNestedRepeated = mergeWrappedNestedRepeated;
scope.mergeList = mergeList;
})(webAnimations1);

View File

@ -1,49 +0,0 @@
// 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(scope, testing) {
function interpolate(from, to, f) {
if ((typeof from == 'number') && (typeof to == 'number')) {
return from * (1 - f) + to * f;
}
if ((typeof from == 'boolean') && (typeof to == 'boolean')) {
return f < 0.5 ? from : to;
}
WEB_ANIMATIONS_TESTING && console.assert(
Array.isArray(from) && Array.isArray(to),
'If interpolation arguments are not numbers or bools they must be arrays');
if (from.length == to.length) {
var r = [];
for (var i = 0; i < from.length; i++) {
r.push(interpolate(from[i], to[i], f));
}
return r;
}
throw 'Mismatched interpolation arguments ' + from + ':' + to;
}
scope.Interpolation = function(from, to, convertToString) {
return function(f) {
return convertToString(interpolate(from, to, f));
}
};
if (WEB_ANIMATIONS_TESTING) {
testing.interpolate = interpolate;
}
})(webAnimations1, webAnimationsTesting);

View File

@ -1,137 +0,0 @@
// 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) {
// FIXME: Make this shareable and rename to SharedKeyframeList.
function KeyframeList(effectInput) {
this._frames = shared.normalizeKeyframes(effectInput);
}
// FIXME: This constructor is also used for custom effects. This won't be the case once custom
// effects are change to callbacks.
scope.KeyframeEffect = function(target, effectInput, timingInput) {
this.target = target;
// TODO: Store a clone, not the same instance.
this._timingInput = timingInput;
this._timing = shared.normalizeTimingInput(timingInput);
// TODO: Make modifications to timing update the underlying animation
this.timing = shared.makeTiming(timingInput);
// TODO: Make this a live object - will need to separate normalization of keyframes into a
// shared module.
// FIXME: This is a bit weird. Custom effects will soon be implemented as
// callbacks, and effectInput will no longer be allowed to be a function.
if (typeof effectInput == 'function')
this._normalizedKeyframes = effectInput;
else
this._normalizedKeyframes = new KeyframeList(effectInput);
this._keyframes = effectInput;
this.activeDuration = shared.calculateActiveDuration(this._timing);
return this;
};
scope.KeyframeEffect.prototype = {
getFrames: function() {
// FIXME: Once custom effects are switched over to callbacks we can
// always return this._normalizedKeyframes._frames here.
if (typeof this._normalizedKeyframes == 'function')
return this._normalizedKeyframes;
return this._normalizedKeyframes._frames;
},
get effect() {
shared.deprecated('KeyframeEffect.effect', '2015-03-23', 'Use KeyframeEffect.getFrames() instead.');
return this._normalizedKeyframes;
}
};
var originalElementAnimate = Element.prototype.animate;
Element.prototype.animate = function(effectInput, timing) {
return scope.timeline.play(new scope.KeyframeEffect(this, effectInput, timing));
};
var nullTarget = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
scope.newUnderlyingAnimationForKeyframeEffect = function(keyframeEffect) {
var target = keyframeEffect.target || nullTarget;
var keyframes = keyframeEffect._keyframes;
if (typeof keyframes == 'function') {
keyframes = [];
}
return originalElementAnimate.apply(target, [keyframes, keyframeEffect._timingInput]);
};
scope.bindAnimationForKeyframeEffect = function(animation) {
if (animation.effect && typeof animation.effect._normalizedKeyframes == 'function') {
scope.bindAnimationForCustomEffect(animation);
}
};
var pendingGroups = [];
scope.awaitStartTime = function(groupAnimation) {
if (groupAnimation.startTime !== null || !groupAnimation._isGroup)
return;
if (pendingGroups.length == 0) {
requestAnimationFrame(updatePendingGroups);
}
pendingGroups.push(groupAnimation);
};
function updatePendingGroups() {
var updated = false;
while (pendingGroups.length) {
pendingGroups.shift()._updateChildren();
updated = true;
}
return updated;
}
var originalGetComputedStyle = window.getComputedStyle;
Object.defineProperty(window, 'getComputedStyle', {
configurable: true,
enumerable: true,
value: function() {
var result = originalGetComputedStyle.apply(this, arguments);
if (updatePendingGroups())
result = originalGetComputedStyle.apply(this, arguments);
return result;
},
});
window.KeyframeEffect = scope.KeyframeEffect;
window.Element.prototype.getAnimations = function() {
return document.timeline.getAnimations().filter(function(animation) {
return animation.effect !== null && animation.effect.target == this;
}.bind(this));
};
window.Element.prototype.getAnimationPlayers = function() {
shared.deprecated('Element.getAnimationPlayers', '2015-03-23', 'Use Element.getAnimations instead.');
return this.getAnimations();
};
// Alias KeyframeEffect to Animation, to support old constructor (Animation) for a deprecation
// period. Should be removed after 23 June 2015.
//
// This is only on window and not on scope, because the constructor that was called
// webAnimationsNext.Player - now called webAnimationsNext.Animation - is already on the scope.
//
// FIXME: Add this to scope & expose the other scope.Animation (nee scope.Player). I.e. both this
// function and the constructor in web-animations-next-animation should be scope.Animation and
// window.Animation until 23 June 2015.
window.Animation = function() {
shared.deprecated('window.Animation', '2015-03-23', 'Use window.KeyframeEffect instead.');
window.KeyframeEffect.apply(this, arguments);
};
window.Animation.prototype = Object.create(window.KeyframeEffect.prototype);
window.Animation.prototype.constructor = window.Animation;
}(webAnimationsShared, webAnimationsNext, webAnimationsTesting));

View File

@ -1,80 +0,0 @@
// 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 EffectTime(timing) {
var timeFraction = 0;
var activeDuration = shared.calculateActiveDuration(timing);
var effectTime = function(localTime) {
return shared.calculateTimeFraction(activeDuration, localTime, timing);
};
effectTime._totalDuration = timing.delay + activeDuration + timing.endDelay;
effectTime._isCurrent = function(localTime) {
var phase = shared.calculatePhase(activeDuration, localTime, timing);
return phase === PhaseActive || phase === PhaseBefore;
};
return effectTime;
}
scope.KeyframeEffect = function(target, effectInput, timingInput) {
var effectTime = EffectTime(shared.normalizeTimingInput(timingInput));
var interpolations = scope.convertEffectInput(effectInput);
var timeFraction;
var keyframeEffect = function() {
WEB_ANIMATIONS_TESTING && console.assert(typeof timeFraction !== 'undefined');
interpolations(target, timeFraction);
};
// Returns whether the keyframeEffect is in effect or not after the timing update.
keyframeEffect._update = function(localTime) {
timeFraction = effectTime(localTime);
return timeFraction !== null;
};
keyframeEffect._clear = function() {
interpolations(target, null);
};
keyframeEffect._hasSameTarget = function(otherTarget) {
return target === otherTarget;
};
keyframeEffect._isCurrent = effectTime._isCurrent;
keyframeEffect._totalDuration = effectTime._totalDuration;
return keyframeEffect;
};
scope.NullEffect = function(clear) {
var nullEffect = function() {
if (clear) {
clear();
clear = null;
}
};
nullEffect._update = function() {
return null;
};
nullEffect._totalDuration = 0;
nullEffect._isCurrent = function() {
return false;
};
nullEffect._hasSameTarget = function() {
return false;
};
return nullEffect;
};
if (WEB_ANIMATIONS_TESTING) {
testing.webAnimations1KeyframeEffect = scope.KeyframeEffect;
testing.effectTime = EffectTime;
}
})(webAnimationsShared, webAnimations1, webAnimationsTesting);

View File

@ -1,110 +0,0 @@
// 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) {
scope.convertEffectInput = function(effectInput) {
var keyframes = shared.normalizeKeyframes(effectInput);
var propertySpecificKeyframeGroups = makePropertySpecificKeyframeGroups(keyframes);
var interpolations = makeInterpolations(propertySpecificKeyframeGroups);
return function(target, fraction) {
if (fraction != null) {
interpolations.filter(function(interpolation) {
return (fraction <= 0 && interpolation.startTime == 0) ||
(fraction >= 1 && interpolation.endTime == 1) ||
(fraction >= interpolation.startTime && fraction <= interpolation.endTime);
}).forEach(function(interpolation) {
var offsetFraction = fraction - interpolation.startTime;
var localDuration = interpolation.endTime - interpolation.startTime;
var scaledLocalTime = localDuration == 0 ? 0 : interpolation.easing(offsetFraction / localDuration);
scope.apply(target, interpolation.property, interpolation.interpolation(scaledLocalTime));
});
} else {
for (var property in propertySpecificKeyframeGroups)
if (property != 'offset' && property != 'easing' && property != 'composite')
scope.clear(target, property);
}
};
};
function makePropertySpecificKeyframeGroups(keyframes) {
var propertySpecificKeyframeGroups = {};
for (var i = 0; i < keyframes.length; i++) {
for (var member in keyframes[i]) {
if (member != 'offset' && member != 'easing' && member != 'composite') {
var propertySpecificKeyframe = {
offset: keyframes[i].offset,
easing: keyframes[i].easing,
value: keyframes[i][member]
};
propertySpecificKeyframeGroups[member] = propertySpecificKeyframeGroups[member] || [];
propertySpecificKeyframeGroups[member].push(propertySpecificKeyframe);
}
}
}
for (var groupName in propertySpecificKeyframeGroups) {
var group = propertySpecificKeyframeGroups[groupName];
if (group[0].offset != 0 || group[group.length - 1].offset != 1) {
throw {
type: DOMException.NOT_SUPPORTED_ERR,
name: 'NotSupportedError',
message: 'Partial keyframes are not supported'
};
}
}
return propertySpecificKeyframeGroups;
}
function makeInterpolations(propertySpecificKeyframeGroups) {
var interpolations = [];
for (var groupName in propertySpecificKeyframeGroups) {
var group = propertySpecificKeyframeGroups[groupName];
for (var i = 0; i < group.length - 1; i++) {
var startTime = group[i].offset;
var endTime = group[i + 1].offset;
var startValue = group[i].value;
var endValue = group[i + 1].value;
if (startTime == endTime) {
if (endTime == 1) {
startValue = endValue;
} else {
endValue = startValue;
}
}
interpolations.push({
startTime: startTime,
endTime: endTime,
easing: group[i].easing,
property: groupName,
interpolation: scope.propertyInterpolation(groupName, startValue, endValue)
});
}
}
interpolations.sort(function(leftInterpolation, rightInterpolation) {
return leftInterpolation.startTime - rightInterpolation.startTime;
});
return interpolations;
}
if (WEB_ANIMATIONS_TESTING) {
testing.makePropertySpecificKeyframeGroups = makePropertySpecificKeyframeGroups;
testing.makeInterpolations = makeInterpolations;
}
})(webAnimationsShared, webAnimations1, webAnimationsTesting);

View File

@ -1,452 +0,0 @@
// 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(scope, testing) {
var decomposeMatrix = (function() {
function determinant(m) {
return m[0][0] * m[1][1] * m[2][2] +
m[1][0] * m[2][1] * m[0][2] +
m[2][0] * m[0][1] * m[1][2] -
m[0][2] * m[1][1] * m[2][0] -
m[1][2] * m[2][1] * m[0][0] -
m[2][2] * m[0][1] * m[1][0];
}
// from Wikipedia:
//
// [A B]^-1 = [A^-1 + A^-1B(D - CA^-1B)^-1CA^-1 -A^-1B(D - CA^-1B)^-1]
// [C D] [-(D - CA^-1B)^-1CA^-1 (D - CA^-1B)^-1 ]
//
// Therefore
//
// [A [0]]^-1 = [A^-1 [0]]
// [C 1 ] [ -CA^-1 1 ]
function inverse(m) {
var iDet = 1 / determinant(m);
var a = m[0][0], b = m[0][1], c = m[0][2];
var d = m[1][0], e = m[1][1], f = m[1][2];
var g = m[2][0], h = m[2][1], k = m[2][2];
var Ainv = [
[(e * k - f * h) * iDet, (c * h - b * k) * iDet,
(b * f - c * e) * iDet, 0],
[(f * g - d * k) * iDet, (a * k - c * g) * iDet,
(c * d - a * f) * iDet, 0],
[(d * h - e * g) * iDet, (g * b - a * h) * iDet,
(a * e - b * d) * iDet, 0]
];
var lastRow = [];
for (var i = 0; i < 3; i++) {
var val = 0;
for (var j = 0; j < 3; j++) {
val += m[3][j] * Ainv[j][i];
}
lastRow.push(val);
}
lastRow.push(1);
Ainv.push(lastRow);
return Ainv;
}
function transposeMatrix4(m) {
return [[m[0][0], m[1][0], m[2][0], m[3][0]],
[m[0][1], m[1][1], m[2][1], m[3][1]],
[m[0][2], m[1][2], m[2][2], m[3][2]],
[m[0][3], m[1][3], m[2][3], m[3][3]]];
}
function multVecMatrix(v, m) {
var result = [];
for (var i = 0; i < 4; i++) {
var val = 0;
for (var j = 0; j < 4; j++) {
val += v[j] * m[j][i];
}
result.push(val);
}
return result;
}
function normalize(v) {
var len = length(v);
return [v[0] / len, v[1] / len, v[2] / len];
}
function length(v) {
return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
function combine(v1, v2, v1s, v2s) {
return [v1s * v1[0] + v2s * v2[0], v1s * v1[1] + v2s * v2[1],
v1s * v1[2] + v2s * v2[2]];
}
function cross(v1, v2) {
return [v1[1] * v2[2] - v1[2] * v2[1],
v1[2] * v2[0] - v1[0] * v2[2],
v1[0] * v2[1] - v1[1] * v2[0]];
}
// TODO: Implement 2D matrix decomposition.
// http://dev.w3.org/csswg/css-transforms/#decomposing-a-2d-matrix
function decomposeMatrix(matrix) {
var m3d = [
matrix.slice(0, 4),
matrix.slice(4, 8),
matrix.slice(8, 12),
matrix.slice(12, 16)
];
// skip normalization step as m3d[3][3] should always be 1
if (m3d[3][3] !== 1) {
return null;
}
var perspectiveMatrix = [];
for (var i = 0; i < 4; i++) {
perspectiveMatrix.push(m3d[i].slice());
}
for (var i = 0; i < 3; i++) {
perspectiveMatrix[i][3] = 0;
}
if (determinant(perspectiveMatrix) === 0) {
return false;
}
var rhs = [];
var perspective;
if (m3d[0][3] || m3d[1][3] || m3d[2][3]) {
rhs.push(m3d[0][3]);
rhs.push(m3d[1][3]);
rhs.push(m3d[2][3]);
rhs.push(m3d[3][3]);
var inversePerspectiveMatrix = inverse(perspectiveMatrix);
var transposedInversePerspectiveMatrix =
transposeMatrix4(inversePerspectiveMatrix);
perspective = multVecMatrix(rhs, transposedInversePerspectiveMatrix);
} else {
perspective = [0, 0, 0, 1];
}
var translate = m3d[3].slice(0, 3);
var row = [];
row.push(m3d[0].slice(0, 3));
var scale = [];
scale.push(length(row[0]));
row[0] = normalize(row[0]);
var skew = [];
row.push(m3d[1].slice(0, 3));
skew.push(dot(row[0], row[1]));
row[1] = combine(row[1], row[0], 1.0, -skew[0]);
scale.push(length(row[1]));
row[1] = normalize(row[1]);
skew[0] /= scale[1];
row.push(m3d[2].slice(0, 3));
skew.push(dot(row[0], row[2]));
row[2] = combine(row[2], row[0], 1.0, -skew[1]);
skew.push(dot(row[1], row[2]));
row[2] = combine(row[2], row[1], 1.0, -skew[2]);
scale.push(length(row[2]));
row[2] = normalize(row[2]);
skew[1] /= scale[2];
skew[2] /= scale[2];
var pdum3 = cross(row[1], row[2]);
if (dot(row[0], pdum3) < 0) {
for (var i = 0; i < 3; i++) {
scale[i] *= -1;
row[i][0] *= -1;
row[i][1] *= -1;
row[i][2] *= -1;
}
}
var t = row[0][0] + row[1][1] + row[2][2] + 1;
var s;
var quaternion;
if (t > 1e-4) {
s = 0.5 / Math.sqrt(t);
quaternion = [
(row[2][1] - row[1][2]) * s,
(row[0][2] - row[2][0]) * s,
(row[1][0] - row[0][1]) * s,
0.25 / s
];
} else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) {
s = Math.sqrt(1 + row[0][0] - row[1][1] - row[2][2]) * 2.0;
quaternion = [
0.25 * s,
(row[0][1] + row[1][0]) / s,
(row[0][2] + row[2][0]) / s,
(row[2][1] - row[1][2]) / s
];
} else if (row[1][1] > row[2][2]) {
s = Math.sqrt(1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0;
quaternion = [
(row[0][1] + row[1][0]) / s,
0.25 * s,
(row[1][2] + row[2][1]) / s,
(row[0][2] - row[2][0]) / s
];
} else {
s = Math.sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0;
quaternion = [
(row[0][2] + row[2][0]) / s,
(row[1][2] + row[2][1]) / s,
0.25 * s,
(row[1][0] - row[0][1]) / s
];
}
return [translate, scale, skew, quaternion, perspective];
}
return decomposeMatrix;
})();
function dot(v1, v2) {
var result = 0;
for (var i = 0; i < v1.length; i++) {
result += v1[i] * v2[i];
}
return result;
}
function multiplyMatrices(a, b) {
return [
a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3],
a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3],
a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3],
a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3],
a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7],
a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7],
a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7],
a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7],
a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11],
a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11],
a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11],
a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11],
a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15],
a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15],
a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15],
a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]
];
}
// TODO: This can probably be made smaller.
function convertItemToMatrix(item) {
switch (item.t) {
// TODO: Handle units other than rads and degs.
case 'rotatex':
var rads = item.d[0].rad || 0;
var degs = item.d[0].deg || 0;
var angle = (degs * Math.PI / 180) + rads;
return [1, 0, 0, 0,
0, Math.cos(angle), Math.sin(angle), 0,
0, -Math.sin(angle), Math.cos(angle), 0,
0, 0, 0, 1];
case 'rotatey':
var rads = item.d[0].rad || 0;
var degs = item.d[0].deg || 0;
var angle = (degs * Math.PI / 180) + rads;
return [Math.cos(angle), 0, -Math.sin(angle), 0,
0, 1, 0, 0,
Math.sin(angle), 0, Math.cos(angle), 0,
0, 0, 0, 1];
case 'rotate':
case 'rotatez':
var rads = item.d[0].rad || 0;
var degs = item.d[0].deg || 0;
var angle = (degs * Math.PI / 180) + rads;
return [Math.cos(angle), Math.sin(angle), 0, 0,
-Math.sin(angle), Math.cos(angle), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
case 'rotate3d':
var x = item.d[0];
var y = item.d[1];
var z = item.d[2];
var rads = item.d[3].rad || 0;
var degs = item.d[3].deg || 0;
var angle = (degs * Math.PI / 180) + rads;
var sqrLength = x * x + y * y + z * z;
if (sqrLength === 0) {
x = 1;
y = 0;
z = 0;
} else if (sqrLength !== 1) {
var length = Math.sqrt(sqrLength);
x /= length;
y /= length;
z /= length;
}
var s = Math.sin(angle / 2);
var sc = s * Math.cos(angle / 2);
var sq = s * s;
return [
1 - 2 * (y * y + z * z) * sq,
2 * (x * y * sq + z * sc),
2 * (x * z * sq - y * sc),
0,
2 * (x * y * sq - z * sc),
1 - 2 * (x * x + z * z) * sq,
2 * (y * z * sq + x * sc),
0,
2 * (x * z * sq + y * sc),
2 * (y * z * sq - x * sc),
1 - 2 * (x * x + y * y) * sq,
0,
0, 0, 0, 1
];
case 'scale':
return [item.d[0], 0, 0, 0,
0, item.d[1], 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
case 'scalex':
return [item.d[0], 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
case 'scaley':
return [1, 0, 0, 0,
0, item.d[0], 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
case 'scalez':
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, item.d[0], 0,
0, 0, 0, 1];
case 'scale3d':
return [item.d[0], 0, 0, 0,
0, item.d[1], 0, 0,
0, 0, item.d[2], 0,
0, 0, 0, 1];
// FIXME: Skew behaves differently in Blink, FireFox and here. Need to work out why.
case 'skew':
var xDegs = item.d[0].deg || 0;
var xRads = item.d[0].rad || 0;
var yDegs = item.d[1].deg || 0;
var yRads = item.d[1].rad || 0;
var xAngle = (xDegs * Math.PI / 180) + xRads;
var yAngle = (yDegs * Math.PI / 180) + yRads;
return [1, Math.tan(yAngle), 0, 0,
Math.tan(xAngle), 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
case 'skewx':
var rads = item.d[0].rad || 0;
var degs = item.d[0].deg || 0;
var angle = (degs * Math.PI / 180) + rads;
return [1, 0, 0, 0,
Math.tan(angle), 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
case 'skewy':
var rads = item.d[0].rad || 0;
var degs = item.d[0].deg || 0;
var angle = (degs * Math.PI / 180) + rads;
return [1, Math.tan(angle), 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
// TODO: Work out what to do with non-px values.
case 'translate':
var x = item.d[0].px || 0;
var y = item.d[1].px || 0;
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, 0, 1];
case 'translatex':
var x = item.d[0].px || 0;
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, 0, 0, 1];
case 'translatey':
var y = item.d[0].px || 0;
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, y, 0, 1];
case 'translatez':
var z = item.d[0].px || 0;
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, z, 1];
case 'translate3d':
var x = item.d[0].px || 0;
var y = item.d[1].px || 0;
var z = item.d[2].px || 0;
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1];
case 'perspective':
var p = item.d[0].px ? (-1 / item.d[0].px) : 0;
return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, p,
0, 0, 0, 1];
case 'matrix':
return [item.d[0], item.d[1], 0, 0,
item.d[2], item.d[3], 0, 0,
0, 0, 1, 0,
item.d[4], item.d[5], 0, 1];
case 'matrix3d':
return item.d;
default:
WEB_ANIMATIONS_TESTING && console.assert(false, 'Transform item type ' + item.t +
' conversion to matrix not yet implemented.');
}
}
function convertToMatrix(transformList) {
if (transformList.length === 0) {
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
}
return transformList.map(convertItemToMatrix).reduce(multiplyMatrices);
}
function makeMatrixDecomposition(transformList) {
return [decomposeMatrix(convertToMatrix(transformList))];
}
scope.dot = dot;
scope.makeMatrixDecomposition = makeMatrixDecomposition;
})(webAnimations1, webAnimationsTesting);

View File

@ -1,130 +0,0 @@
// 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(scope, testing) {
var composeMatrix = (function() {
function multiply(a, b) {
var result = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
for (var k = 0; k < 4; k++) {
result[i][j] += b[i][k] * a[k][j];
}
}
}
return result;
}
function is2D(m) {
return (
m[0][2] == 0 &&
m[0][3] == 0 &&
m[1][2] == 0 &&
m[1][3] == 0 &&
m[2][0] == 0 &&
m[2][1] == 0 &&
m[2][2] == 1 &&
m[2][3] == 0 &&
m[3][2] == 0 &&
m[3][3] == 1);
}
function composeMatrix(translate, scale, skew, quat, perspective) {
var matrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
for (var i = 0; i < 4; i++) {
matrix[i][3] = perspective[i];
}
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
matrix[3][i] += translate[j] * matrix[j][i];
}
}
var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
var rotMatrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
rotMatrix[0][0] = 1 - 2 * (y * y + z * z);
rotMatrix[0][1] = 2 * (x * y - z * w);
rotMatrix[0][2] = 2 * (x * z + y * w);
rotMatrix[1][0] = 2 * (x * y + z * w);
rotMatrix[1][1] = 1 - 2 * (x * x + z * z);
rotMatrix[1][2] = 2 * (y * z - x * w);
rotMatrix[2][0] = 2 * (x * z - y * w);
rotMatrix[2][1] = 2 * (y * z + x * w);
rotMatrix[2][2] = 1 - 2 * (x * x + y * y);
matrix = multiply(matrix, rotMatrix);
var temp = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
if (skew[2]) {
temp[2][1] = skew[2];
matrix = multiply(matrix, temp);
}
if (skew[1]) {
temp[2][1] = 0;
temp[2][0] = skew[0];
matrix = multiply(matrix, temp);
}
if (skew[0]) {
temp[2][0] = 0;
temp[1][0] = skew[0];
matrix = multiply(matrix, temp);
}
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
matrix[i][j] *= scale[i];
}
}
if (is2D(matrix)) {
return [matrix[0][0], matrix[0][1], matrix[1][0], matrix[1][1], matrix[3][0], matrix[3][1]];
}
return matrix[0].concat(matrix[1], matrix[2], matrix[3]);
}
return composeMatrix;
})();
function clamp(x, min, max) {
return Math.max(Math.min(x, max), min);
};
function quat(fromQ, toQ, f) {
var product = scope.dot(fromQ, toQ);
product = clamp(product, -1.0, 1.0);
var quat = [];
if (product === 1.0) {
quat = fromQ;
} else {
var theta = Math.acos(product);
var w = Math.sin(f * theta) * 1 / Math.sqrt(1 - product * product);
for (var i = 0; i < 4; i++) {
quat.push(fromQ[i] * (Math.cos(f * theta) - product * w) +
toQ[i] * w);
}
}
return quat;
}
scope.composeMatrix = composeMatrix;
scope.quat = quat;
})(webAnimations1, webAnimationsTesting);

View File

@ -1,259 +0,0 @@
// 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, testing) {
var shorthandToLonghand = {
background: [
'backgroundImage',
'backgroundPosition',
'backgroundSize',
'backgroundRepeat',
'backgroundAttachment',
'backgroundOrigin',
'backgroundClip',
'backgroundColor'
],
border: [
'borderTopColor',
'borderTopStyle',
'borderTopWidth',
'borderRightColor',
'borderRightStyle',
'borderRightWidth',
'borderBottomColor',
'borderBottomStyle',
'borderBottomWidth',
'borderLeftColor',
'borderLeftStyle',
'borderLeftWidth'
],
borderBottom: [
'borderBottomWidth',
'borderBottomStyle',
'borderBottomColor'
],
borderColor: [
'borderTopColor',
'borderRightColor',
'borderBottomColor',
'borderLeftColor'
],
borderLeft: [
'borderLeftWidth',
'borderLeftStyle',
'borderLeftColor'
],
borderRadius: [
'borderTopLeftRadius',
'borderTopRightRadius',
'borderBottomRightRadius',
'borderBottomLeftRadius'
],
borderRight: [
'borderRightWidth',
'borderRightStyle',
'borderRightColor'
],
borderTop: [
'borderTopWidth',
'borderTopStyle',
'borderTopColor'
],
borderWidth: [
'borderTopWidth',
'borderRightWidth',
'borderBottomWidth',
'borderLeftWidth'
],
flex: [
'flexGrow',
'flexShrink',
'flexBasis'
],
font: [
'fontFamily',
'fontSize',
'fontStyle',
'fontVariant',
'fontWeight',
'lineHeight'
],
margin: [
'marginTop',
'marginRight',
'marginBottom',
'marginLeft'
],
outline: [
'outlineColor',
'outlineStyle',
'outlineWidth'
],
padding: [
'paddingTop',
'paddingRight',
'paddingBottom',
'paddingLeft'
]
};
var shorthandExpanderElem = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
var borderWidthAliases = {
thin: '1px',
medium: '3px',
thick: '5px'
};
var aliases = {
borderBottomWidth: borderWidthAliases,
borderLeftWidth: borderWidthAliases,
borderRightWidth: borderWidthAliases,
borderTopWidth: borderWidthAliases,
fontSize: {
'xx-small': '60%',
'x-small': '75%',
'small': '89%',
'medium': '100%',
'large': '120%',
'x-large': '150%',
'xx-large': '200%'
},
fontWeight: {
normal: '400',
bold: '700'
},
outlineWidth: borderWidthAliases,
textShadow: {
none: '0px 0px 0px transparent'
},
boxShadow: {
none: '0px 0px 0px 0px transparent'
}
};
function antiAlias(property, value) {
if (property in aliases) {
return aliases[property][value] || value;
}
return value;
}
// This delegates parsing shorthand value syntax to the browser.
function expandShorthandAndAntiAlias(property, value, result) {
var longProperties = shorthandToLonghand[property];
if (longProperties) {
shorthandExpanderElem.style[property] = value;
for (var i in longProperties) {
var longProperty = longProperties[i];
var longhandValue = shorthandExpanderElem.style[longProperty];
result[longProperty] = antiAlias(longProperty, longhandValue);
}
} else {
result[property] = antiAlias(property, value);
}
};
function normalizeKeyframes(effectInput) {
if (!Array.isArray(effectInput) && effectInput !== null)
throw new TypeError('Keyframes must be null or an array of keyframes');
if (effectInput == null)
return [];
var keyframes = effectInput.map(function(originalKeyframe) {
var keyframe = {};
for (var member in originalKeyframe) {
var memberValue = originalKeyframe[member];
if (member == 'offset') {
if (memberValue != null) {
memberValue = Number(memberValue);
if (!isFinite(memberValue))
throw new TypeError('keyframe offsets must be numbers.');
}
} else if (member == 'composite') {
throw {
type: DOMException.NOT_SUPPORTED_ERR,
name: 'NotSupportedError',
message: 'add compositing is not supported'
};
} else if (member == 'easing') {
memberValue = shared.toTimingFunction(memberValue);
} else {
memberValue = '' + memberValue;
}
expandShorthandAndAntiAlias(member, memberValue, keyframe);
}
if (keyframe.offset == undefined)
keyframe.offset = null;
if (keyframe.easing == undefined)
keyframe.easing = shared.toTimingFunction('linear');
return keyframe;
});
var everyFrameHasOffset = true;
var looselySortedByOffset = true;
var previousOffset = -Infinity;
for (var i = 0; i < keyframes.length; i++) {
var offset = keyframes[i].offset;
if (offset != null) {
if (offset < previousOffset) {
throw {
code: DOMException.INVALID_MODIFICATION_ERR,
name: 'InvalidModificationError',
message: 'Keyframes are not loosely sorted by offset. Sort or specify offsets.'
};
}
previousOffset = offset;
} else {
everyFrameHasOffset = false;
}
}
keyframes = keyframes.filter(function(keyframe) {
return keyframe.offset >= 0 && keyframe.offset <= 1;
});
function spaceKeyframes() {
var length = keyframes.length;
if (keyframes[length - 1].offset == null)
keyframes[length - 1].offset = 1;
if (length > 1 && keyframes[0].offset == null)
keyframes[0].offset = 0;
var previousIndex = 0;
var previousOffset = keyframes[0].offset;
for (var i = 1; i < length; i++) {
var offset = keyframes[i].offset;
if (offset != null) {
for (var j = 1; j < i - previousIndex; j++)
keyframes[previousIndex + j].offset = previousOffset + (offset - previousOffset) * j / (i - previousIndex);
previousIndex = i;
previousOffset = offset;
}
}
}
if (!everyFrameHasOffset)
spaceKeyframes();
return keyframes;
}
shared.normalizeKeyframes = normalizeKeyframes;
if (WEB_ANIMATIONS_TESTING) {
testing.normalizeKeyframes = normalizeKeyframes;
}
})(webAnimationsShared, webAnimationsTesting);

View File

@ -1,70 +0,0 @@
// 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(scope, testing) {
function numberToString(x) {
return x.toFixed(3).replace('.000', '');
}
function clamp(min, max, x) {
return Math.min(max, Math.max(min, x));
}
function parseNumber(string) {
if (/^\s*[-+]?(\d*\.)?\d+\s*$/.test(string))
return Number(string);
}
function mergeNumbers(left, right) {
return [left, right, numberToString];
}
// FIXME: This should probably go in it's own handler.
function mergeFlex(left, right) {
if (left == 0)
return;
return clampedMergeNumbers(0, Infinity)(left, right);
}
function mergePositiveIntegers(left, right) {
return [left, right, function(x) {
return Math.round(clamp(1, Infinity, x));
}];
}
function clampedMergeNumbers(min, max) {
return function(left, right) {
return [left, right, function(x) {
return numberToString(clamp(min, max, x));
}];
};
}
function round(left, right) {
return [left, right, Math.round];
}
scope.clamp = clamp;
scope.addPropertiesHandler(parseNumber, clampedMergeNumbers(0, Infinity), ['border-image-width', 'line-height']);
scope.addPropertiesHandler(parseNumber, clampedMergeNumbers(0, 1), ['opacity', 'shape-image-threshold']);
scope.addPropertiesHandler(parseNumber, mergeFlex, ['flex-grow', 'flex-shrink']);
scope.addPropertiesHandler(parseNumber, mergePositiveIntegers, ['orphans', 'widows']);
scope.addPropertiesHandler(parseNumber, round, ['z-index']);
scope.parseNumber = parseNumber;
scope.mergeNumbers = mergeNumbers;
scope.numberToString = numberToString;
})(webAnimations1, webAnimationsTesting);

View File

@ -1,117 +0,0 @@
// 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(scope) {
function negateDimension(dimension) {
var result = {};
for (var k in dimension) {
result[k] = -dimension[k];
}
return result;
}
function consumeOffset(string) {
return scope.consumeToken(/^(left|center|right|top|bottom)\b/i, string) || scope.consumeLengthOrPercent(string);
}
var offsetMap = {
left: {'%': 0},
center: {'%': 50},
right: {'%': 100},
top: {'%': 0},
bottom: {'%': 100},
};
function parseOrigin(slots, string) {
var result = scope.consumeRepeated(consumeOffset, /^/, string);
if (!result || result[1] != '') return;
var tokens = result[0];
tokens[0] = tokens[0] || 'center';
tokens[1] = tokens[1] || 'center';
if (slots == 3) {
tokens[2] = tokens[2] || {px: 0};
}
if (tokens.length != slots) {
return;
}
// Reorder so that the horizontal axis comes first.
if (/top|bottom/.test(tokens[0]) || /left|right/.test(tokens[1])) {
var tmp = tokens[0];
tokens[0] = tokens[1];
tokens[1] = tmp;
}
// Invalid if not horizontal then vertical.
if (!/left|right|center|Object/.test(tokens[0]))
return;
if (!/top|bottom|center|Object/.test(tokens[1]))
return;
return tokens.map(function(position) {
return typeof position == 'object' ? position : offsetMap[position];
});
}
var mergeOffsetList = scope.mergeNestedRepeated.bind(null, scope.mergeDimensions, ' ');
scope.addPropertiesHandler(parseOrigin.bind(null, 3), mergeOffsetList, ['transform-origin']);
scope.addPropertiesHandler(parseOrigin.bind(null, 2), mergeOffsetList, ['perspective-origin']);
function consumePosition(string) {
var result = scope.consumeRepeated(consumeOffset, /^/, string);
if (!result) {
return;
}
var tokens = result[0];
var out = [{'%': 50}, {'%': 50}];
var pos = 0;
var bottomOrRight = false;
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
if (typeof token == 'string') {
bottomOrRight = /bottom|right/.test(token);
pos = {left: 0, right: 0, center: pos, top: 1, bottom: 1}[token];
out[pos] = offsetMap[token];
if (token == 'center') {
// Center doesn't accept a length offset.
pos++;
}
} else {
if (bottomOrRight) {
// If bottom or right we need to subtract the length from 100%
token = negateDimension(token);
token['%'] = (token['%'] || 0) + 100;
}
out[pos] = token;
pos++;
bottomOrRight = false;
}
}
return [out, result[1]];
}
function parsePositionList(string) {
var result = scope.consumeRepeated(consumePosition, /^,/, string);
if (result && result[1] == '') {
return result[0];
}
}
scope.consumePosition = consumePosition;
scope.mergeOffsetList = mergeOffsetList;
var mergePositionList = scope.mergeNestedRepeated.bind(null, mergeOffsetList, ', ');
scope.addPropertiesHandler(parsePositionList, mergePositionList, ['background-position', 'object-position']);
})(webAnimations1);

View File

@ -1,62 +0,0 @@
// 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(scope, testing) {
var propertyHandlers = {};
function addPropertyHandler(parser, merger, property) {
propertyHandlers[property] = propertyHandlers[property] || [];
propertyHandlers[property].push([parser, merger]);
}
function addPropertiesHandler(parser, merger, properties) {
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
WEB_ANIMATIONS_TESTING && console.assert(property.toLowerCase() === property);
addPropertyHandler(parser, merger, property);
if (/-/.test(property)) {
// Add camel cased variant.
addPropertyHandler(parser, merger, property.replace(/-(.)/g, function(_, c) {
return c.toUpperCase();
}));
}
}
}
scope.addPropertiesHandler = addPropertiesHandler;
function propertyInterpolation(property, left, right) {
var handlers = left == right ? [] : propertyHandlers[property];
for (var i = 0; handlers && i < handlers.length; i++) {
var parsedLeft = handlers[i][0](left);
var parsedRight = handlers[i][0](right);
if (parsedLeft !== undefined && parsedRight !== undefined) {
var interpolationArgs = handlers[i][1](parsedLeft, parsedRight);
if (interpolationArgs) {
var interp = scope.Interpolation.apply(null, interpolationArgs);
return function(t) {
if (t == 0) return left;
if (t == 1) return right;
return interp(t);
};
}
}
}
return scope.Interpolation(false, true, function(bool) {
return bool ? right : left;
});
}
scope.propertyInterpolation = propertyInterpolation;
})(webAnimations1, webAnimationsTesting);

View File

@ -1,35 +0,0 @@
// 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(scope, testing) {
var aliased = {};
function alias(name, aliases) {
aliases.concat([name]).forEach(function(candidate) {
if (candidate in document.documentElement.style) {
aliased[name] = candidate;
}
});
}
alias('transform', ['webkitTransform', 'msTransform']);
alias('transformOrigin', ['webkitTransformOrigin']);
alias('perspective', ['webkitPerspective']);
alias('perspectiveOrigin', ['webkitPerspectiveOrigin']);
scope.propertyName = function(property) {
return aliased[property] || property;
};
})(webAnimations1, webAnimationsTesting);

View File

@ -1,20 +0,0 @@
// 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.
var webAnimationsShared = {};
var webAnimations1 = {};
var webAnimationsNext = {};
if (!WEB_ANIMATIONS_TESTING)
var webAnimationsTesting = null;

View File

@ -1,108 +0,0 @@
// 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(scope) {
function consumeShadow(string) {
var shadow = {
inset: false,
lengths: [],
color: null,
};
function consumePart(string) {
var result = scope.consumeToken(/^inset/i, string);
if (result) {
shadow.inset = true;
return result;
}
var result = scope.consumeLengthOrPercent(string);
if (result) {
shadow.lengths.push(result[0]);
return result;
}
var result = scope.consumeColor(string);
if (result) {
shadow.color = result[0];
return result;
}
}
var result = scope.consumeRepeated(consumePart, /^/, string);
if (result && result[0].length) {
return [shadow, result[1]];
}
}
function parseShadowList(string) {
var result = scope.consumeRepeated(consumeShadow, /^,/, string);
if (result && result[1] == '') {
return result[0];
}
}
function mergeShadow(left, right) {
while (left.lengths.length < Math.max(left.lengths.length, right.lengths.length))
left.lengths.push({px: 0});
while (right.lengths.length < Math.max(left.lengths.length, right.lengths.length))
right.lengths.push({px: 0});
if (left.inset != right.inset || !!left.color != !!right.color) {
return;
}
var lengthReconstitution = [];
var colorReconstitution;
var matchingLeft = [[], 0];
var matchingRight = [[], 0];
for (var i = 0; i < left.lengths.length; i++) {
var mergedDimensions = scope.mergeDimensions(left.lengths[i], right.lengths[i], i == 2);
matchingLeft[0].push(mergedDimensions[0]);
matchingRight[0].push(mergedDimensions[1]);
lengthReconstitution.push(mergedDimensions[2]);
}
if (left.color && right.color) {
var mergedColor = scope.mergeColors(left.color, right.color);
matchingLeft[1] = mergedColor[0];
matchingRight[1] = mergedColor[1];
colorReconstitution = mergedColor[2];
}
return [matchingLeft, matchingRight, function(value) {
var result = left.inset ? 'inset ' : ' ';
for (var i = 0; i < lengthReconstitution.length; i++) {
result += lengthReconstitution[i](value[0][i]) + ' ';
}
if (colorReconstitution) {
result += colorReconstitution(value[1]);
}
return result;
}];
}
function mergeNestedRepeatedShadow(nestedMerge, separator, left, right) {
var leftCopy = [];
var rightCopy = [];
function defaultShadow(inset) {
return {inset: inset, color: [0, 0, 0, 0], lengths: [{px: 0}, {px: 0}, {px: 0}, {px: 0}]};
}
for (var i = 0; i < left.length || i < right.length; i++) {
var l = left[i] || defaultShadow(right[i].inset);
var r = right[i] || defaultShadow(left[i].inset);
leftCopy.push(l);
rightCopy.push(r);
}
return scope.mergeNestedRepeated(nestedMerge, separator, leftCopy, rightCopy);
}
var mergeShadowList = mergeNestedRepeatedShadow.bind(null, mergeShadow, ', ');
scope.addPropertiesHandler(parseShadowList, mergeShadowList, ['box-shadow', 'text-shadow']);
})(webAnimations1);

View File

@ -1,85 +0,0 @@
// 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(scope) {
var consumeLengthOrPercent = scope.consumeParenthesised.bind(null, scope.parseLengthOrPercent);
var consumeLengthOrPercentPair = scope.consumeRepeated.bind(undefined, consumeLengthOrPercent, /^/);
var mergeSizePair = scope.mergeNestedRepeated.bind(undefined, scope.mergeDimensions, ' ');
var mergeSizePairList = scope.mergeNestedRepeated.bind(undefined, mergeSizePair, ',');
function parseShape(input) {
var circle = scope.consumeToken(/^circle/, input);
if (circle && circle[0]) {
return ['circle'].concat(scope.consumeList([
scope.ignore(scope.consumeToken.bind(undefined, /^\(/)),
consumeLengthOrPercent,
scope.ignore(scope.consumeToken.bind(undefined, /^at/)),
scope.consumePosition,
scope.ignore(scope.consumeToken.bind(undefined, /^\)/))
], circle[1]));
}
var ellipse = scope.consumeToken(/^ellipse/, input);
if (ellipse && ellipse[0]) {
return ['ellipse'].concat(scope.consumeList([
scope.ignore(scope.consumeToken.bind(undefined, /^\(/)),
consumeLengthOrPercentPair,
scope.ignore(scope.consumeToken.bind(undefined, /^at/)),
scope.consumePosition,
scope.ignore(scope.consumeToken.bind(undefined, /^\)/))
], ellipse[1]));
}
var polygon = scope.consumeToken(/^polygon/, input);
if (polygon && polygon[0]) {
return ['polygon'].concat(scope.consumeList([
scope.ignore(scope.consumeToken.bind(undefined, /^\(/)),
scope.optional(scope.consumeToken.bind(undefined, /^nonzero\s*,|^evenodd\s*,/), 'nonzero,'),
scope.consumeSizePairList,
scope.ignore(scope.consumeToken.bind(undefined, /^\)/))
], polygon[1]));
}
}
function mergeShapes(left, right) {
if (left[0] !== right[0])
return;
if (left[0] == 'circle') {
return scope.mergeList(left.slice(1), right.slice(1), [
'circle(',
scope.mergeDimensions,
' at ',
scope.mergeOffsetList,
')']);
}
if (left[0] == 'ellipse') {
return scope.mergeList(left.slice(1), right.slice(1), [
'ellipse(',
scope.mergeNonNegativeSizePair,
' at ',
scope.mergeOffsetList,
')']);
}
if (left[0] == 'polygon' && left[1] == right[1]) {
return scope.mergeList(left.slice(2), right.slice(2), [
'polygon(',
left[1],
mergeSizePairList,
')']);
}
}
scope.addPropertiesHandler(parseShape, mergeShapes, ['shape-outside']);
})(webAnimations1);

View File

@ -1,149 +0,0 @@
// 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) {
var originalRequestAnimationFrame = window.requestAnimationFrame;
var rafCallbacks = [];
var rafId = 0;
window.requestAnimationFrame = function(f) {
var id = rafId++;
if (rafCallbacks.length == 0 && !WEB_ANIMATIONS_TESTING) {
originalRequestAnimationFrame(processRafCallbacks);
}
rafCallbacks.push([id, f]);
return id;
};
window.cancelAnimationFrame = function(id) {
rafCallbacks.forEach(function(entry) {
if (entry[0] == id) {
entry[1] = function() {};
}
});
};
function processRafCallbacks(t) {
var processing = rafCallbacks;
rafCallbacks = [];
tick(t);
processing.forEach(function(entry) { entry[1](t); });
if (needsRetick)
tick(t);
applyPendingEffects();
}
function compareAnimations(leftAnimation, rightAnimation) {
return leftAnimation._sequenceNumber - rightAnimation._sequenceNumber;
}
function InternalTimeline() {
this._animations = [];
// Android 4.3 browser has window.performance, but not window.performance.now
this.currentTime = window.performance && performance.now ? performance.now() : 0;
};
InternalTimeline.prototype = {
_play: function(effect) {
effect._timing = shared.normalizeTimingInput(effect.timing);
var animation = new scope.Animation(effect);
animation._idle = false;
animation._timeline = this;
this._animations.push(animation);
scope.restart();
scope.invalidateEffects();
return animation;
}
};
var ticking = false;
var hasRestartedThisFrame = false;
scope.restart = function() {
if (!ticking) {
ticking = true;
requestAnimationFrame(function() {});
hasRestartedThisFrame = true;
}
return hasRestartedThisFrame;
};
var needsRetick = false;
scope.invalidateEffects = function() {
needsRetick = true;
};
var pendingEffects = [];
function applyPendingEffects() {
pendingEffects.forEach(function(f) { f(); });
pendingEffects.length = 0;
}
var originalGetComputedStyle = window.getComputedStyle;
Object.defineProperty(window, 'getComputedStyle', {
configurable: true,
enumerable: true,
value: function() {
if (needsRetick) tick(timeline.currentTime);
applyPendingEffects();
return originalGetComputedStyle.apply(this, arguments);
},
});
function tick(t) {
hasRestartedThisFrame = false;
var timeline = scope.timeline;
timeline.currentTime = t;
timeline._animations.sort(compareAnimations);
ticking = false;
var updatingAnimations = timeline._animations;
timeline._animations = [];
var newPendingClears = [];
var newPendingEffects = [];
updatingAnimations = updatingAnimations.filter(function(animation) {
animation._inTimeline = animation._tick(t);
if (!animation._inEffect)
newPendingClears.push(animation._effect);
else
newPendingEffects.push(animation._effect);
if (!animation.finished && !animation.paused && !animation._idle)
ticking = true;
return animation._inTimeline;
});
// FIXME: Should remove dupliactes from pendingEffects.
pendingEffects.push.apply(pendingEffects, newPendingClears);
pendingEffects.push.apply(pendingEffects, newPendingEffects);
timeline._animations.push.apply(timeline._animations, updatingAnimations);
needsRetick = false;
if (ticking)
requestAnimationFrame(function() {});
};
if (WEB_ANIMATIONS_TESTING) {
testing.tick = processRafCallbacks;
testing.isTicking = function() { return ticking; };
testing.setTicking = function(newVal) { ticking = newVal; };
}
var timeline = new InternalTimeline();
scope.timeline = timeline;
})(webAnimationsShared, webAnimations1, webAnimationsTesting);

View File

@ -1,86 +0,0 @@
// 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) {
scope.AnimationTimeline = function() {
this._animations = [];
this.currentTime = undefined;
};
scope.AnimationTimeline.prototype = {
// FIXME: This needs to return the wrapped animations in Web Animations Next
// TODO: Does this need to be sorted?
// TODO: Do we need to consider needsRetick?
getAnimations: function() {
this._discardAnimations();
return this._animations.slice();
},
getAnimationPlayers: function() {
shared.deprecated('AnimationTimeline.getAnimationPlayers', '2015-03-23', 'Use AnimationTimeline.getAnimations instead.');
return this.getAnimations();
},
_discardAnimations: function() {
this._animations = this._animations.filter(function(animation) {
return animation.playState != 'finished' && animation.playState != 'idle';
});
},
play: function(effect) {
var animation = new scope.Animation(effect);
this._animations.push(animation);
scope.restartWebAnimationsNextTick();
// Use animation._animation.play() here, NOT animation.play().
//
// Timeline.play calls new scope.Animation(effect) which (indirectly) calls Timeline.play on
// effect's children, and Animation.play is also recursive. We only need to call play on each
// animation in the tree once.
animation._animation.play();
return animation;
},
};
var ticking = false;
scope.restartWebAnimationsNextTick = function() {
if (!ticking) {
ticking = true;
requestAnimationFrame(webAnimationsNextTick);
}
};
function webAnimationsNextTick(t) {
var timeline = window.document.timeline;
timeline.currentTime = t;
timeline._discardAnimations();
if (timeline._animations.length == 0)
ticking = false;
else
requestAnimationFrame(webAnimationsNextTick);
}
var timeline = new scope.AnimationTimeline();
scope.timeline = timeline;
try {
Object.defineProperty(window.document, 'timeline', {
configurable: true,
get: function() { return timeline; }
});
} catch (e) { }
try {
window.document.timeline = timeline;
} catch (e) { }
})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);

View File

@ -1,242 +0,0 @@
// 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, testing) {
var fills = 'backwards|forwards|both|none'.split('|');
var directions = 'reverse|alternate|alternate-reverse'.split('|');
function makeTiming(timingInput, forGroup) {
var timing = {
delay: 0,
endDelay: 0,
fill: forGroup ? 'both' : 'none',
iterationStart: 0,
iterations: 1,
duration: forGroup ? 'auto' : 0,
playbackRate: 1,
direction: 'normal',
easing: 'linear',
};
if (typeof timingInput == 'number' && !isNaN(timingInput)) {
timing.duration = timingInput;
} else if (timingInput !== undefined) {
Object.getOwnPropertyNames(timingInput).forEach(function(property) {
if (timingInput[property] != 'auto') {
if (typeof timing[property] == 'number' || property == 'duration') {
if (typeof timingInput[property] != 'number' || isNaN(timingInput[property])) {
return;
}
}
if ((property == 'fill') && (fills.indexOf(timingInput[property]) == -1)) {
return;
}
if ((property == 'direction') && (directions.indexOf(timingInput[property]) == -1)) {
return;
}
if (property == 'playbackRate' && timingInput[property] !== 1 && shared.isDeprecated('AnimationEffectTiming.playbackRate', '2014-11-28', 'Use Animation.playbackRate instead.')) {
return;
}
timing[property] = timingInput[property];
}
});
}
return timing;
}
function normalizeTimingInput(timingInput, forGroup) {
var timing = makeTiming(timingInput, forGroup);
timing.easing = toTimingFunction(timing.easing);
return timing;
}
function cubic(a, b, c, d) {
if (a < 0 || a > 1 || c < 0 || c > 1) {
return linear;
}
return function(x) {
var start = 0, end = 1;
while (1) {
var mid = (start + end) / 2;
function f(a, b, m) { return 3 * a * (1 - m) * (1 - m) * m + 3 * b * (1 - m) * m * m + m * m * m};
var xEst = f(a, c, mid);
if (Math.abs(x - xEst) < 0.001) {
return f(b, d, mid);
}
if (xEst < x) {
start = mid;
} else {
end = mid;
}
}
}
}
var Start = 1;
var Middle = 0.5;
var End = 0;
function step(count, pos) {
return function(x) {
if (x >= 1) {
return 1;
}
var stepSize = 1 / count;
x += pos * stepSize;
return x - x % stepSize;
}
}
var presets = {
'ease': cubic(0.25, 0.1, 0.25, 1),
'ease-in': cubic(0.42, 0, 1, 1),
'ease-out': cubic(0, 0, 0.58, 1),
'ease-in-out': cubic(0.42, 0, 0.58, 1),
'step-start': step(1, Start),
'step-middle': step(1, Middle),
'step-end': step(1, End)
};
var numberString = '\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*';
var cubicBezierRe = new RegExp('cubic-bezier\\(' + numberString + ',' + numberString + ',' + numberString + ',' + numberString + '\\)');
var stepRe = /steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/;
var linear = function(x) { return x; };
function toTimingFunction(easing) {
var cubicData = cubicBezierRe.exec(easing);
if (cubicData) {
return cubic.apply(this, cubicData.slice(1).map(Number));
}
var stepData = stepRe.exec(easing);
if (stepData) {
return step(Number(stepData[1]), {'start': Start, 'middle': Middle, 'end': End}[stepData[2]]);
}
var preset = presets[easing];
if (preset) {
return preset;
}
return linear;
};
function calculateActiveDuration(timing) {
return Math.abs(repeatedDuration(timing) / timing.playbackRate);
}
function repeatedDuration(timing) {
return timing.duration * timing.iterations;
}
var PhaseNone = 0;
var PhaseBefore = 1;
var PhaseAfter = 2;
var PhaseActive = 3;
function calculatePhase(activeDuration, localTime, timing) {
if (localTime == null) {
return PhaseNone;
}
if (localTime < timing.delay) {
return PhaseBefore;
}
if (localTime >= timing.delay + activeDuration) {
return PhaseAfter;
}
return PhaseActive;
}
function calculateActiveTime(activeDuration, fillMode, localTime, phase, delay) {
switch (phase) {
case PhaseBefore:
if (fillMode == 'backwards' || fillMode == 'both')
return 0;
return null;
case PhaseActive:
return localTime - delay;
case PhaseAfter:
if (fillMode == 'forwards' || fillMode == 'both')
return activeDuration;
return null;
case PhaseNone:
return null;
}
}
function calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing) {
return (timing.playbackRate < 0 ? activeTime - activeDuration : activeTime) * timing.playbackRate + startOffset;
}
function calculateIterationTime(iterationDuration, repeatedDuration, scaledActiveTime, startOffset, timing) {
if (scaledActiveTime === Infinity || scaledActiveTime === -Infinity || (scaledActiveTime - startOffset == repeatedDuration && timing.iterations && ((timing.iterations + timing.iterationStart) % 1 == 0))) {
return iterationDuration;
}
return scaledActiveTime % iterationDuration;
}
function calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, timing) {
if (scaledActiveTime === 0) {
return 0;
}
if (iterationTime == iterationDuration) {
return timing.iterationStart + timing.iterations - 1;
}
return Math.floor(scaledActiveTime / iterationDuration);
}
function calculateTransformedTime(currentIteration, iterationDuration, iterationTime, timing) {
var currentIterationIsOdd = currentIteration % 2 >= 1;
var currentDirectionIsForwards = timing.direction == 'normal' || timing.direction == (currentIterationIsOdd ? 'alternate-reverse' : 'alternate');
var directedTime = currentDirectionIsForwards ? iterationTime : iterationDuration - iterationTime;
var timeFraction = directedTime / iterationDuration;
return iterationDuration * timing.easing(timeFraction);
}
function calculateTimeFraction(activeDuration, localTime, timing) {
var phase = calculatePhase(activeDuration, localTime, timing);
var activeTime = calculateActiveTime(activeDuration, timing.fill, localTime, phase, timing.delay);
if (activeTime === null)
return null;
if (activeDuration === 0)
return phase === PhaseBefore ? 0 : 1;
var startOffset = timing.iterationStart * timing.duration;
var scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing);
var iterationTime = calculateIterationTime(timing.duration, repeatedDuration(timing), scaledActiveTime, startOffset, timing);
var currentIteration = calculateCurrentIteration(timing.duration, iterationTime, scaledActiveTime, timing);
return calculateTransformedTime(currentIteration, timing.duration, iterationTime, timing) / timing.duration;
}
shared.makeTiming = makeTiming;
shared.normalizeTimingInput = normalizeTimingInput;
shared.calculateActiveDuration = calculateActiveDuration;
shared.calculateTimeFraction = calculateTimeFraction;
shared.calculatePhase = calculatePhase;
shared.toTimingFunction = toTimingFunction;
if (WEB_ANIMATIONS_TESTING) {
testing.normalizeTimingInput = normalizeTimingInput;
testing.toTimingFunction = toTimingFunction;
testing.calculateActiveDuration = calculateActiveDuration;
testing.calculatePhase = calculatePhase;
testing.PhaseNone = PhaseNone;
testing.PhaseBefore = PhaseBefore;
testing.PhaseActive = PhaseActive;
testing.PhaseAfter = PhaseAfter;
testing.calculateActiveTime = calculateActiveTime;
testing.calculateScaledActiveTime = calculateScaledActiveTime;
testing.calculateIterationTime = calculateIterationTime;
testing.calculateCurrentIteration = calculateCurrentIteration;
testing.calculateTransformedTime = calculateTransformedTime;
}
})(webAnimationsShared, webAnimationsTesting);

View File

@ -1,262 +0,0 @@
// 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(scope, testing) {
// This returns a function for converting transform functions to equivalent
// primitive functions, which will take an array of values from the
// derivative type and fill in the blanks (underscores) with them.
var _ = null;
function cast(pattern) {
return function(contents) {
var i = 0;
return pattern.map(function(x) { return x === _ ? contents[i++] : x; });
}
}
function id(x) { return x; }
var Opx = {px: 0};
var Odeg = {deg: 0};
// type: [argTypes, convertTo3D, convertTo2D]
// In the argument types string, lowercase characters represent optional arguments
var transformFunctions = {
matrix: ['NNNNNN', [_, _, 0, 0, _, _, 0, 0, 0, 0, 1, 0, _, _, 0, 1], id],
matrix3d: ['NNNNNNNNNNNNNNNN', id],
rotate: ['A'],
rotatex: ['A'],
rotatey: ['A'],
rotatez: ['A'],
rotate3d: ['NNNA'],
perspective: ['L'],
scale: ['Nn', cast([_, _, 1]), id],
scalex: ['N', cast([_, 1, 1]), cast([_, 1])],
scaley: ['N', cast([1, _, 1]), cast([1, _])],
scalez: ['N', cast([1, 1, _])],
scale3d: ['NNN', id],
skew: ['Aa', null, id],
skewx: ['A', null, cast([_, Odeg])],
skewy: ['A', null, cast([Odeg, _])],
translate: ['Tt', cast([_, _, Opx]), id],
translatex: ['T', cast([_, Opx, Opx]), cast([_, Opx])],
translatey: ['T', cast([Opx, _, Opx]), cast([Opx, _])],
translatez: ['L', cast([Opx, Opx, _])],
translate3d: ['TTL', id],
};
function parseTransform(string) {
string = string.toLowerCase().trim();
if (string == 'none')
return [];
// FIXME: Using a RegExp means calcs won't work here
var transformRegExp = /\s*(\w+)\(([^)]*)\)/g;
var result = [];
var match;
var prevLastIndex = 0;
while (match = transformRegExp.exec(string)) {
if (match.index != prevLastIndex)
return;
prevLastIndex = match.index + match[0].length;
var functionName = match[1];
var functionData = transformFunctions[functionName];
if (!functionData)
return;
var args = match[2].split(',');
var argTypes = functionData[0];
if (argTypes.length < args.length)
return;
var parsedArgs = [];
for (var i = 0; i < argTypes.length; i++) {
var arg = args[i];
var type = argTypes[i];
var parsedArg;
if (!arg)
parsedArg = ({a: Odeg,
n: parsedArgs[0],
t: Opx})[type];
else
parsedArg = ({A: function(s) { return s.trim() == '0' ? Odeg : scope.parseAngle(s); },
N: scope.parseNumber,
T: scope.parseLengthOrPercent,
L: scope.parseLength})[type.toUpperCase()](arg);
if (parsedArg === undefined)
return;
parsedArgs.push(parsedArg);
}
result.push({t: functionName, d: parsedArgs});
if (transformRegExp.lastIndex == string.length)
return result;
}
};
function numberToLongString(x) {
return x.toFixed(6).replace('.000000', '');
}
function mergeMatrices(left, right) {
if (left.decompositionPair !== right) {
left.decompositionPair = right;
var leftArgs = scope.makeMatrixDecomposition(left);
}
if (right.decompositionPair !== left) {
right.decompositionPair = left;
var rightArgs = scope.makeMatrixDecomposition(right);
}
if (leftArgs[0] == null || rightArgs[0] == null)
return [[false], [true], function(x) { return x ? right[0].d : left[0].d; }];
leftArgs[0].push(0);
rightArgs[0].push(1);
return [
leftArgs,
rightArgs,
function(list) {
var quat = scope.quat(leftArgs[0][3], rightArgs[0][3], list[5]);
var mat = scope.composeMatrix(list[0], list[1], list[2], quat, list[4]);
var stringifiedArgs = mat.map(numberToLongString).join(',');
return stringifiedArgs;
}
];
}
function typeTo2D(type) {
return type.replace(/[xy]/, '');
}
function typeTo3D(type) {
return type.replace(/(x|y|z|3d)?$/, '3d');
}
function mergeTransforms(left, right) {
var matrixModulesLoaded = scope.makeMatrixDecomposition && true;
var flipResults = false;
if (!left.length || !right.length) {
if (!left.length) {
flipResults = true;
left = right;
right = [];
}
for (var i = 0; i < left.length; i++) {
var type = left[i].t;
var args = left[i].d;
var defaultValue = type.substr(0, 5) == 'scale' ? 1 : 0;
right.push({t: type, d: args.map(function(arg) {
if (typeof arg == 'number')
return defaultValue;
var result = {};
for (var unit in arg)
result[unit] = defaultValue;
return result;
})});
}
}
var isMatrixOrPerspective = function(lt, rt) {
return ((lt == 'perspective') && (rt == 'perspective')) ||
((lt == 'matrix' || lt == 'matrix3d') && (rt == 'matrix' || rt == 'matrix3d'));
};
var leftResult = [];
var rightResult = [];
var types = [];
if (left.length != right.length) {
if (!matrixModulesLoaded)
return;
var merged = mergeMatrices(left, right);
leftResult = [merged[0]];
rightResult = [merged[1]];
types = [['matrix', [merged[2]]]];
} else {
for (var i = 0; i < left.length; i++) {
var leftType = left[i].t;
var rightType = right[i].t;
var leftArgs = left[i].d;
var rightArgs = right[i].d;
var leftFunctionData = transformFunctions[leftType];
var rightFunctionData = transformFunctions[rightType];
var type;
if (isMatrixOrPerspective(leftType, rightType)) {
if (!matrixModulesLoaded)
return;
var merged = mergeMatrices([left[i]], [right[i]]);
leftResult.push(merged[0]);
rightResult.push(merged[1]);
types.push(['matrix', [merged[2]]]);
continue;
} else if (leftType == rightType) {
type = leftType;
} else if (leftFunctionData[2] && rightFunctionData[2] && typeTo2D(leftType) == typeTo2D(rightType)) {
type = typeTo2D(leftType);
leftArgs = leftFunctionData[2](leftArgs);
rightArgs = rightFunctionData[2](rightArgs);
} else if (leftFunctionData[1] && rightFunctionData[1] && typeTo3D(leftType) == typeTo3D(rightType)) {
type = typeTo3D(leftType);
leftArgs = leftFunctionData[1](leftArgs);
rightArgs = rightFunctionData[1](rightArgs);
} else {
if (!matrixModulesLoaded)
return;
var merged = mergeMatrices(left, right);
leftResult = [merged[0]];
rightResult = [merged[1]];
types = [['matrix', [merged[2]]]];
break;
}
var leftArgsCopy = [];
var rightArgsCopy = [];
var stringConversions = [];
for (var j = 0; j < leftArgs.length; j++) {
var merge = typeof leftArgs[j] == 'number' ? scope.mergeNumbers : scope.mergeDimensions;
var merged = merge(leftArgs[j], rightArgs[j]);
leftArgsCopy[j] = merged[0];
rightArgsCopy[j] = merged[1];
stringConversions.push(merged[2]);
}
leftResult.push(leftArgsCopy);
rightResult.push(rightArgsCopy);
types.push([type, stringConversions]);
}
}
if (flipResults) {
var tmp = leftResult;
leftResult = rightResult;
rightResult = tmp;
}
return [leftResult, rightResult, function(list) {
return list.map(function(args, i) {
var stringifiedArgs = args.map(function(arg, j) {
return types[i][1][j](arg);
}).join(',');
if (types[i][0] == 'matrix' && stringifiedArgs.split(',').length == 16)
types[i][0] = 'matrix3d';
return types[i][0] + '(' + stringifiedArgs + ')';
}).join(' ');
}];
}
scope.addPropertiesHandler(parseTransform, mergeTransforms, ['transform']);
if (WEB_ANIMATIONS_TESTING)
testing.parseTransform = parseTransform;
})(webAnimations1, webAnimationsTesting);

View File

@ -1,29 +0,0 @@
// 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(scope, testing) {
function merge(left, right) {
if (left != 'visible' && right != 'visible') return;
return [0, 1, function(x) {
if (x <= 0) return left;
if (x >= 1) return right;
return 'visible';
}];
}
scope.addPropertiesHandler(String, merge, ['visibility']);
})(webAnimations1);

View File

@ -1,235 +0,0 @@
// 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) {
scope.Animation = function(effect) {
this.effect = effect;
if (effect) {
// FIXME: detach existing animation.
effect.animation = this;
}
this._isGroup = false;
this._animation = null;
this._childAnimations = [];
this._callback = null;
this._rebuildUnderlyingAnimation();
// Animations are constructed in the idle state.
this._animation.cancel();
};
// TODO: add an effect getter/setter
scope.Animation.prototype = {
_rebuildUnderlyingAnimation: function() {
if (this._animation) {
this._animation.cancel();
this._animation = null;
}
if (!this.effect || this.effect instanceof window.KeyframeEffect) {
this._animation = scope.newUnderlyingAnimationForKeyframeEffect(this.effect);
scope.bindAnimationForKeyframeEffect(this);
}
if (this.effect instanceof window.SequenceEffect || this.effect instanceof window.GroupEffect) {
this._animation = scope.newUnderlyingAnimationForGroup(this.effect);
scope.bindAnimationForGroup(this);
}
// FIXME: move existing currentTime/startTime/playState to new animation
},
_updateChildren: function() {
if (!this.effect || this.playState == 'idle')
return;
var offset = this.effect._timing.delay;
this._childAnimations.forEach(function(childAnimation) {
this._arrangeChildren(childAnimation, offset);
if (this.effect instanceof window.SequenceEffect)
offset += scope.groupChildDuration(childAnimation.effect);
}.bind(this));
},
_setExternalAnimation: function(animation) {
if (!this.effect || !this._isGroup)
return;
for (var i = 0; i < this.effect.children.length; i++) {
this.effect.children[i].animation = animation;
this._childAnimations[i]._setExternalAnimation(animation);
}
},
_constructChildren: function() {
if (!this.effect || !this._isGroup)
return;
var offset = this.effect._timing.delay;
this.effect.children.forEach(function(child) {
var childAnimation = window.document.timeline.play(child);
this._childAnimations.push(childAnimation);
childAnimation.playbackRate = this.playbackRate;
if (this.paused)
childAnimation.pause();
child.animation = this.effect.animation;
this._arrangeChildren(childAnimation, offset);
if (this.effect instanceof window.SequenceEffect)
offset += scope.groupChildDuration(child);
}.bind(this));
},
_arrangeChildren: function(childAnimation, offset) {
if (this.startTime === null) {
childAnimation.currentTime = this.currentTime - offset / this.playbackRate;
childAnimation._startTime = null;
} else if (childAnimation.startTime !== this.startTime + offset / this.playbackRate) {
childAnimation.startTime = this.startTime + offset / this.playbackRate;
}
},
get paused() {
return this._animation.paused;
},
get playState() {
return this._animation.playState;
},
get onfinish() {
return this._onfinish;
},
set onfinish(v) {
if (typeof v == 'function') {
this._onfinish = v;
this._animation.onfinish = (function(e) {
e.target = this;
v.call(this, e);
}).bind(this);
} else {
this._animation.onfinish = v;
this.onfinish = this._animation.onfinish;
}
},
get currentTime() {
return this._animation.currentTime;
},
set currentTime(v) {
this._animation.currentTime = v;
this._register();
this._forEachChild(function(child, offset) {
child.currentTime = v - offset;
});
},
get startTime() {
return this._animation.startTime;
},
set startTime(v) {
this._animation.startTime = v;
this._register();
this._forEachChild(function(child, offset) {
child.startTime = v + offset;
});
},
get playbackRate() {
return this._animation.playbackRate;
},
set playbackRate(value) {
var oldCurrentTime = this.currentTime;
this._animation.playbackRate = value;
this._forEachChild(function(childAnimation) {
childAnimation.playbackRate = value;
});
if (this.playState != 'paused' && this.playState != 'idle') {
this.play();
}
if (oldCurrentTime !== null) {
this.currentTime = oldCurrentTime;
}
},
get finished() {
return this._animation.finished;
},
get source() {
shared.deprecated('Animation.source', '2015-03-23', 'Use Animation.effect instead.');
return this.effect;
},
play: function() {
this._animation.play();
this._register();
scope.awaitStartTime(this);
this._forEachChild(function(child) {
var time = child.currentTime;
child.play();
child.currentTime = time;
});
},
pause: function() {
this._animation.pause();
this._register();
this._forEachChild(function(child) {
child.pause();
});
},
finish: function() {
this._animation.finish();
this._register();
// TODO: child animations??
},
cancel: function() {
this._animation.cancel();
this._register();
this._removeChildren();
},
reverse: function() {
var oldCurrentTime = this.currentTime;
this._animation.reverse();
this._forEachChild(function(childAnimation) {
childAnimation.reverse();
});
if (oldCurrentTime !== null) {
this.currentTime = oldCurrentTime;
}
},
addEventListener: function(type, handler) {
var wrapped = handler;
if (typeof handler == 'function') {
wrapped = (function(e) {
e.target = this;
handler.call(this, e);
}).bind(this);
handler._wrapper = wrapped;
}
this._animation.addEventListener(type, wrapped);
},
removeEventListener: function(type, handler) {
this._animation.removeEventListener(type, (handler && handler._wrapper) || handler);
},
_removeChildren: function() {
while (this._childAnimations.length)
this._childAnimations.pop().cancel();
},
_forEachChild: function(f) {
var offset = 0;
if (this.effect.children && this._childAnimations.length < this.effect.children.length)
this._constructChildren();
this._childAnimations.forEach(function(child) {
f.call(this, child, offset);
if (this.effect instanceof window.SequenceEffect)
offset += child.effect.activeDuration;
}.bind(this));
if (this._animation.playState == 'pending')
return;
var timing = this.effect._timing;
var t = this._animation.currentTime;
if (t !== null)
t = shared.calculateTimeFraction(shared.calculateActiveDuration(timing), t, timing);
if (t == null || isNaN(t))
this._removeChildren();
},
};
})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);

View File

@ -1,136 +0,0 @@
// 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() {
var scopeSrc = [
'src/scope.js'];
var webAnimations1Src = [
'src/keyframe-interpolations.js',
'src/property-interpolation.js',
'src/keyframe-effect.js',
'src/apply-preserving-inline-style.js',
'src/element-animatable.js',
'src/interpolation.js',
'src/matrix-interpolation.js',
'src/animation.js',
'src/tick.js',
'src/matrix-decomposition.js',
'src/handler-utils.js',
'src/shadow-handler.js',
'src/number-handler.js',
'src/visibility-handler.js',
'src/color-handler.js',
'src/dimension-handler.js',
'src/box-handler.js',
'src/transform-handler.js',
'src/font-weight-handler.js',
'src/position-handler.js',
'src/shape-handler.js',
'src/property-names.js',
];
var liteWebAnimations1Src = [
'src/keyframe-interpolations.js',
'src/property-interpolation.js',
'src/keyframe-effect.js',
'src/apply.js',
'src/element-animatable.js',
'src/interpolation.js',
'src/animation.js',
'src/tick.js',
'src/handler-utils.js',
'src/shadow-handler.js',
'src/number-handler.js',
'src/visibility-handler.js',
'src/color-handler.js',
'src/dimension-handler.js',
'src/box-handler.js',
'src/transform-handler.js',
'src/property-names.js',
];
var sharedSrc = [
'src/timing-utilities.js',
'src/normalize-keyframes.js',
'src/deprecation.js',
];
var webAnimationsNextSrc = [
'src/timeline.js',
'src/web-animations-next-animation.js',
'src/keyframe-effect-constructor.js',
'src/effect-callback.js',
'src/group-constructors.js'];
var webAnimations1Test = [
'test/js/animation-finish-event.js',
'test/js/animation.js',
'test/js/apply-preserving-inline-style.js',
'test/js/box-handler.js',
'test/js/color-handler.js',
'test/js/dimension-handler.js',
'test/js/interpolation.js',
'test/js/keyframes.js',
'test/js/matrix-interpolation.js',
'test/js/number-handler.js',
'test/js/property-interpolation.js',
'test/js/tick.js',
'test/js/timing-utilities.js',
'test/js/timing.js',
'test/js/transform-handler.js'];
var webAnimationsNextTest = webAnimations1Test.concat(
'test/js/effect-callback.js',
'test/js/group-animation-finish-event.js',
'test/js/group-animation.js',
'test/js/group-constructors.js',
'test/js/keyframe-effect-constructor.js',
'test/js/timeline.js');
// This object specifies the source and test files for different Web Animation build targets.
var targetConfig = {
'web-animations': {
scopeSrc: scopeSrc,
sharedSrc: sharedSrc,
webAnimations1Src: webAnimations1Src,
webAnimationsNextSrc: [],
src: scopeSrc.concat(sharedSrc).concat(webAnimations1Src),
test: webAnimations1Test,
},
'web-animations-next': {
scopeSrc: scopeSrc,
sharedSrc: sharedSrc,
webAnimations1Src: webAnimations1Src,
webAnimationsNextSrc: webAnimationsNextSrc,
src: scopeSrc.concat(sharedSrc).concat(webAnimations1Src).concat(webAnimationsNextSrc),
test: webAnimationsNextTest,
},
'web-animations-next-lite': {
scopeSrc: scopeSrc,
sharedSrc: sharedSrc,
webAnimations1Src: liteWebAnimations1Src,
webAnimationsNextSrc: webAnimationsNextSrc,
src: scopeSrc.concat(sharedSrc).concat(liteWebAnimations1Src).concat(webAnimationsNextSrc),
test: [],
},
};
if (typeof module != 'undefined')
module.exports = targetConfig;
else
window.webAnimationsTargetConfig = targetConfig;
})();

View File

@ -1,27 +0,0 @@
// 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() {
var target = webAnimationsTargetConfig.defaultTarget;
if (typeof webAnimationsSourceTarget != 'undefined')
target = webAnimationsSourceTarget;
// Native implementation detection.
var scripts = document.getElementsByTagName('script');
var location = scripts[scripts.length - 1].src.replace(/[^\/]+$/, '');
webAnimationsTargetConfig[target].src.forEach(function(sourceFile) {
document.write('<script src="' + location + sourceFile + '"></script>');
});
})();

View File

@ -1,13 +0,0 @@
// 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.

View File

@ -1,26 +0,0 @@
<!--
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.
-->
<!DOCTYPE html>
<meta charset="UTF-8">
<link rel="stylesheet" href="../node_modules/mocha/mocha.css">
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../target-config.js"></script>
<script src="runner.js"></script>
<script>
loadWebAnimationsBuildTarget('<%= target %>');
</script>
<div id="mocha"></div>

View File

@ -1,18 +0,0 @@
<!--
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.
-->
<script src="src/dev.js"></script>
<% _.forEach(src, function(src) { %><script src="<%= src %>"></script>
<% }); %>

View File

@ -1,21 +0,0 @@
// 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.
var webAnimationsSourceTarget = '<%= target %>';
var WEB_ANIMATIONS_TESTING = false;
(function() {
var scripts = document.getElementsByTagName('script');
var location = scripts[scripts.length - 1].src.replace(/[^\/]+$/, '');
document.write('<script src="' + location + 'target-config.js"></script>');
document.write('<script src="' + location + 'target-loader.js"></script>');
})();

View File

@ -1,56 +0,0 @@
<!DOCTYPE html>
<script src="testharness/testharness.js"></script>
<script src="testharness/testharnessreport.js"></script>
<script src="resources/keyframes-test.js"></script>
<script>
test(function() {
assertAnimationStyles([
{opacity: '0.25', left: '25px', offset: 0},
{opacity: '0.75', left: '75px'},
], {
0.5: {opacity: '0.5', left: '50px'},
});
assertAnimationStyles([
{opacity: '0.25', left: '25px'},
{opacity: '0.75', left: '75px', offset: 1},
], {
0.5: {opacity: '0.5', left: '50px'},
});
},
'element.animate() with 2 keyframes and 1 offset specified',
{
help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
assert: [
'element.animate() should start an animation when two keyframes',
'are provided with matching properties and one offset is specified.',
],
author: 'Alan Cutter',
});
test(function() {
assertAnimationStyles([
{opacity: '0.25', left: '25px', offset: 0},
{opacity: '0.75', left: '75px', offset: 1},
], {
0.5: {opacity: '0.5', left: '50px'},
});
assert_throws('InvalidModificationError', function() {
assertAnimationStyles([
{opacity: '0.75', left: '75px', offset: 1},
{opacity: '0.25', left: '25px', offset: 0},
], {
0.5: {opacity: '0.5', left: '50px'},
});
});
},
'element.animate() with 2 keyframes and 2 offsets specified',
{
help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
assert: [
'element.animate() should start an animation when two keyframes',
'are provided with matching properties and both offsets specified.',
],
author: 'Alan Cutter',
});
</script>

View File

@ -1,147 +0,0 @@
<!DOCTYPE html>
<script src="testharness/testharness.js"></script>
<script src="testharness/testharnessreport.js"></script>
<script src="resources/keyframes-test.js"></script>
<script>
var keyframeA = {opacity: '0.5', left: '50px'};
var keyframeB = {opacity: '0', left: '0px'};
var keyframeC = {opacity: '0.75', left: '75px'};
var keyframeBExpectations = {
0: {opacity: '0.5', left: '50px'},
0.25: {opacity: '0.25', left: '25px'},
0.5: {opacity: '0', left: '0px'}, // Corresponds to keyframeB (offset unspecified).
0.75: {opacity: '0.375', left: '37.5px'},
1: {opacity: '0.75', left: '75px'},
};
var offsetKeyframeA = {opacity: keyframeA.opacity, left: keyframeA.left, offset: 0};
var offsetKeyframeB = {opacity: keyframeB.opacity, left: keyframeB.left, offset: 0.25};
var offsetKeyframeC = {opacity: keyframeC.opacity, left: keyframeC.left, offset: 1};
var offsetKeyframeBExpectations = {
0: {opacity: '0.5', left: '50px'},
0.125: {opacity: '0.25', left: '25px'},
0.25: {opacity: '0', left: '0px'}, // Corresponds to offsetKeyframeB (offset 0.25).
0.5: {opacity: '0.25', left: '25px'},
0.75: {opacity: '0.5', left: '50px'},
1: {opacity: '0.75', left: '75px'},
};
test(function() {
assertAnimationStyles([
offsetKeyframeA,
keyframeB,
keyframeC,
], keyframeBExpectations, 'with first offset specified');
assertAnimationStyles([
keyframeA,
offsetKeyframeB,
keyframeC,
], offsetKeyframeBExpectations, 'with second offset specified');
assertAnimationStyles([
keyframeA,
keyframeB,
offsetKeyframeC,
], keyframeBExpectations, 'with third offset specified');
},
'element.animate() with 3 keyframes and 1 offset specified',
{
help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
assert: [
'element.animate() should start an animation when three keyframes',
'are provided with matching properties and one offset specified.',
'The keyframes must maintain their ordering and get distributed',
'correctly.',
],
author: 'Alan Cutter',
});
test(function() {
assertAnimationStyles([
keyframeA,
offsetKeyframeB,
offsetKeyframeC,
], offsetKeyframeBExpectations, 'with first offset unspecified');
assertAnimationStyles([
offsetKeyframeA,
keyframeB,
offsetKeyframeC,
], keyframeBExpectations, 'with second offset unspecified');
assertAnimationStyles([
offsetKeyframeA,
offsetKeyframeB,
keyframeC,
], offsetKeyframeBExpectations, 'with third offset unspecified');
},
'element.animate() with 3 keyframes and 2 offsets specified',
{
help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
assert: [
'element.animate() should start an animation when three keyframes',
'are provided with matching properties and two offsets specified.',
'The keyframes must maintain their ordering and get distributed',
'correctly.',
],
author: 'Alan Cutter',
});
test(function() {
assertAnimationStyles([
offsetKeyframeA,
offsetKeyframeB,
offsetKeyframeC,
], offsetKeyframeBExpectations, 'with ordered offsets');
assert_throws('InvalidModificationError', function() {
assertAnimationStyles([
offsetKeyframeA,
offsetKeyframeC,
offsetKeyframeB,
], offsetKeyframeBExpectations, 'with unordered offsets (1)');
});
assert_throws('InvalidModificationError', function() {
assertAnimationStyles([
offsetKeyframeB,
offsetKeyframeA,
offsetKeyframeC,
], offsetKeyframeBExpectations, 'with unordered offsets (2)');
});
assert_throws('InvalidModificationError', function() {
assertAnimationStyles([
offsetKeyframeB,
offsetKeyframeC,
offsetKeyframeA,
], offsetKeyframeBExpectations, 'with unordered offsets (3)');
});
assert_throws('InvalidModificationError', function() {
assertAnimationStyles([
offsetKeyframeC,
offsetKeyframeA,
offsetKeyframeB,
], offsetKeyframeBExpectations, 'with unordered offsets (4)');
});
assert_throws('InvalidModificationError', function() {
assertAnimationStyles([
offsetKeyframeC,
offsetKeyframeB,
offsetKeyframeA,
], offsetKeyframeBExpectations, 'with unordered offsets (5)');
});
},
'element.animate() with 3 keyframes and 3 offsets specified',
{
help: 'http://dev.w3.org/fxtf/web-animations/#keyframe-animation-effects',
assert: [
'element.animate() should start an animation when three keyframes',
'are provided with matching properties and all offsets specified.',
'The keyframes must maintain their ordering and get distributed',
'correctly.',
],
author: 'Alan Cutter',
});
</script>

View File

@ -1,33 +0,0 @@
<!doctype html>
<title>Web Animations API: Add Keyframe tests</title>
<script src="testharness/testharness.js"></script>
<script src="testharness/testharnessreport.js"></script>
<div id='log'></div>
<div id='div'></div>
<script>
test(function() {
assert_throws({name: 'NotSupportedError'}, function() {
div.animate([{height: '100px', composite: 'add'}, {height: '200px', composite: 'add'}], 1);
}, 'Add animations should cause an exception.');
},
'Add animation tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-unaccumulated-animation-value-of-a-keyframe-animation-effect',
assert: 'Only keyframes without add compositing considered',
author: 'Shane Stephens'
});
test(function() {
assert_throws({name: 'NotSupportedError'}, function() {
div.animate([{height: '100px'}, {height: '200px', composite: 'add'}], 1);
}, 'Animations with add keyframes should cause an exception.');
},
'Hybrid animation tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-unaccumulated-animation-value-of-a-keyframe-animation-effect',
assert: 'Only keyframes without add compositing are considered',
author: 'Shane Stephens'
});
</script>

View File

@ -1,95 +0,0 @@
<!DOCTYPE html>
<script src="testharness/testharness.js"></script>
<script src="testharness/testharnessreport.js"></script>
<script src="resources/keyframes-test.js"></script>
<script>
test(function() {
assertAnimationStyles([
{opacity: '0', left: '0px', easing: 'steps(2, start)'},
{opacity: '0.25', left: '25px'},
{opacity: '0.75', left: '75px'},
], {
0: {opacity: '0.125', left: '12.5px'},
0.125: {opacity: '0.125', left: '12.5px'},
0.25: {opacity: '0.25', left: '25px'},
0.375: {opacity: '0.25', left: '25px'},
0.5: {opacity: '0.25', left: '25px'},
0.625: {opacity: '0.375', left: '37.5px'},
0.75: {opacity: '0.5', left: '50px'},
0.875: {opacity: '0.625', left: '62.5px'},
1: {opacity: '0.75', left: '75px'},
}, 'with easing on first keyframe');
assertAnimationStyles([
{opacity: '0', left: '0px'},
{opacity: '0.5', left: '50px', easing: 'steps(2, start)'},
{opacity: '0.75', left: '75px'},
], {
0: {opacity: '0', left: '0px'},
0.125: {opacity: '0.125', left: '12.5px'},
0.25: {opacity: '0.25', left: '25px'},
0.375: {opacity: '0.375', left: '37.5px'},
0.5: {opacity: '0.625', left: '62.5px'},
0.625: {opacity: '0.625', left: '62.5px'},
0.75: {opacity: '0.75', left: '75px'},
0.875: {opacity: '0.75', left: '75px'},
1: {opacity: '0.75', left: '75px'},
}, 'with easing on second keyframe');
},
'element.animate() with eased keyframe',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-keyframe-dictionary',
assert: [
'element.animate() should start an animation when keyframes are specified with timing functions',
'for their easing property. The animation should use the given timing function between consecutive',
'keyframe offsets.',
],
author: 'Alan Cutter',
});
test(function() {
assertAnimationStyles([
{opacity: '0', offset: 0, easing: 'steps(2, start)'},
{left: '0px', offset: 0},
{opacity: '0.5', left: '50px'},
], {
0: {opacity: '0.25', left: '0px'},
0.25: {opacity: '0.25', left: '12.5px'},
0.5: {opacity: '0.5', left: '25px'},
0.75: {opacity: '0.5', left: '37.5px'},
1: {opacity: '0.5', left: '50px'},
});
},
'element.animate() with eased keyframe on single property',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-keyframe-dictionary',
assert: [
'element.animate() should start an animation when keyframes are specified with timing functions',
'for their easing property. The animation should use the given timing function only on the properties',
'specified in the same keyframe.',
],
author: 'Alan Cutter',
});
test(function() {
assertAnimationStyles([
{opacity: '0', left: '0px'},
{opacity: '0.5', left: '50px', easing: 'steps(2, start)'},
], {
0: {opacity: '0', left: '0px'},
0.25: {opacity: '0.125', left: '12.5px'},
0.5: {opacity: '0.25', left: '25px'},
0.75: {opacity: '0.375', left: '37.5px'},
1: {opacity: '0.5', left: '50px'},
});
},
'element.animate() with easing on last keyframe',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-keyframe-dictionary',
assert: [
'element.animate() should start an animation when keyframes are specified with timing functions',
'for their easing property. Easing on the last keyframes should have no effect on the animation.',
],
author: 'Alan Cutter',
});
</script>

View File

@ -1,90 +0,0 @@
<!DOCTYPE html>
<script src="testharness/testharness.js"></script>
<script src="testharness/testharnessreport.js"></script>
<div id='container'>
<div id='element'></div>
</div>
<script>
var container = document.getElementById('container');
var element = document.getElementById('element');
test(function() {
assert_equals(document.timeline.getAnimations().length, 0);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 0);
var animation = element.animate([], 1000);
assert_equals(document.timeline.getAnimations().length, 1);
assert_equals(document.timeline.getAnimations()[0], animation);
var animation2 = container.animate([], 1000);
assert_equals(document.timeline.getAnimations().length, 2);
assert_equals(document.timeline.getAnimations()[0], animation);
assert_equals(document.timeline.getAnimations()[1], animation2);
animation.finish();
assert_equals(document.timeline.getAnimations().length, 1);
assert_equals(document.timeline.getAnimations()[0], animation2);
animation2.finish();
assert_equals(document.timeline.getAnimations().length, 0);
}, 'Timeline getAnimations()');
test(function() {
assert_equals(document.timeline.getAnimations().length, 0);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 0);
var animation = element.animate([], 1000);
assert_equals(document.timeline.getAnimations().length, 1);
assert_equals(document.timeline.getAnimations()[0], animation);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 1);
assert_equals(element.getAnimations()[0], animation);
var animation2 = container.animate([], 1000);
assert_equals(document.timeline.getAnimations().length, 2);
assert_equals(document.timeline.getAnimations()[0], animation);
assert_equals(document.timeline.getAnimations()[1], animation2);
assert_equals(container.getAnimations().length, 1);
assert_equals(container.getAnimations()[0], animation2);
assert_equals(element.getAnimations().length, 1);
assert_equals(element.getAnimations()[0], animation);
animation.finish();
assert_equals(document.timeline.getAnimations().length, 1);
assert_equals(document.timeline.getAnimations()[0], animation2);
assert_equals(container.getAnimations().length, 1);
assert_equals(container.getAnimations()[0], animation2);
assert_equals(element.getAnimations().length, 0);
animation2.finish();
assert_equals(document.timeline.getAnimations().length, 0);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 0);
}, 'Animatable getAnimations()');
test(function() {
assert_equals(document.timeline.getAnimations().length, 0);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 0);
var animation = element.animate([], {duration: 1000, delay: 500});
assert_equals(document.timeline.getAnimations().length, 1);
assert_equals(document.timeline.getAnimations()[0], animation);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 1);
assert_equals(element.getAnimations()[0], animation);
animation.finish();
assert_equals(document.timeline.getAnimations().length, 0);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 0);
}, 'getAnimations() with delays');
</script>

View File

@ -1,40 +0,0 @@
<!DOCTYPE html>
<script src="testharness/testharness.js"></script>
<script src="testharness/testharnessreport.js"></script>
<style>
@keyframes test {
from { opacity: 0; }
to { opacity: 1; }
}
.cssAnimation {
animation: test 2s;
}
</style>
<div id='container'>
<div id='element'></div>
</div>
<script>
async_test(function(t) {
assert_equals(document.timeline.getAnimations().length, 0);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 0);
element.className = 'cssAnimation';
onload = function () {
t.step(function() {
var animations = document.timeline.getAnimations();
assert_equals(animations.length, 1);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 1);
animations[0].finish();
assert_equals(document.timeline.getAnimations().length, 0);
assert_equals(container.getAnimations().length, 0);
assert_equals(element.getAnimations().length, 0);
t.done();
});
}
}, 'getAnimations() with cssanimations');
</script>

View File

@ -1,39 +0,0 @@
<!doctype html>
<title>Web Animations API: Insufficient Keyframe tests</title>
<script src="testharness/testharness.js"></script>
<script src="testharness/testharnessreport.js"></script>
<div id='log'></div>
<div id='div'></div>
<script>
test(function() {
assert_throws({name: 'NotSupportedError'}, function() {
div.animate([{width: '100px'}], 1);
}, 'A keyframe list with a single keyframe should cause an exception.');
},
'single keyframe tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-unaccumulated-animation-value-of-a-keyframe-animation-effect',
assert: 'Only keyframes with matched start and end properties are considered',
author: 'Shane Stephens'
});
test(function() {
assert_throws({name: 'NotSupportedError'}, function() {
div.animate([{height: '100px'}, {width: '100px'}], 1);
}, 'Mismatched start and end keyframes should cause an exception.');
try {
div.animate([{width: '100px'}, {height: '200px', offset: 0}, {width: '100px', offset: 1}, {height: '100px'}], 1);
} catch (e) {
assert_unreached("multiple start and end keyframes should be considered");
}
},
'multiple keyframe tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-unaccumulated-animation-value-of-a-keyframe-animation-effect',
assert: 'Only keyframes with matched start and end properties are considered',
author: 'Shane Stephens'
});
</script>

View File

@ -1,46 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 60px;
height: 60px;
display: inline-block;
border: 2px solid black;
margin-right: 2px;
}
.replica {
background-color: green;
margin-right: 15px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
assertInterpolation({
property: 'background-color',
from: 'white',
to: 'orange'
}, [
{at: -0.3, is: 'white'},
{at: 0, is: 'white'},
{at: 0.3, is: 'rgb(255, 228, 179)'},
{at: 0.6, is: 'rgb(255, 201, 102)'},
{at: 1, is: 'orange'},
{at: 1.5, is: 'rgb(255, 120, 0)'},
]);
assertInterpolation({
property: 'background-color',
from: 'initial',
to: 'transparent'
}, [
{at: -0.3, is: 'transparent'},
{at: 0, is: 'transparent'},
{at: 0.3, is: 'transparent'},
{at: 0.6, is: 'transparent'},
{at: 1, is: 'transparent'},
{at: 1.5, is: 'transparent'},
]);
</script>
</body>

View File

@ -1,143 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 100px;
height: 100px;
display: inline-block;
border: 10px solid black;
background-repeat: no-repeat;
}
.replica {
border-color: green;
margin-right: 2px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
// Image to image
var from = 'url(../resources/blue-100.png)';
var to = 'url(../resources/green-100.png)';
assertInterpolation({
property: 'background-image',
from: from,
to: to,
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Image to gradient
from = 'url(../resources/blue-100.png)';
to = 'linear-gradient(45deg, blue, orange)';
assertInterpolation({
property: 'background-image',
from: from,
to: to,
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Gradient to gradient
from = 'linear-gradient(-45deg, red, yellow)';
to = 'linear-gradient(45deg, blue, orange)';
assertInterpolation({
property: 'background-image',
from: from,
to: to,
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Keyword to image
from = 'none';
to = 'url(../resources/green-100.png)';
assertInterpolation({
property: 'background-image',
from: from,
to: to,
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: from},
{at: 0.6, is: to},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Multiple to multiple
var fromA = 'url(../resources/stripes-100.png)';
var fromB = 'linear-gradient(-45deg, blue, transparent)';
var toA = 'url(../resources/blue-100.png)';
var toB = 'url(../resources/stripes-100.png)';
from = fromA + ', ' + fromB;
to = toA + ', ' + toB;
assertInterpolation({
property: 'background-image',
from: from,
to: to,
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + fromA + ', ' + toA + ', 0.3), -webkit-cross-fade(' + fromB + ', ' + toB + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + fromA + ', ' + toA + ', 0.6), -webkit-cross-fade(' + fromB + ', ' + toB + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Single to multiple
from = 'url(../resources/blue-100.png)';
var toA = 'url(../resources/stripes-100.png)';
var toB = 'url(../resources/green-100.png)';
to = toA + ', ' + toB;
assertInterpolation({
property: 'background-image',
from: from,
to: to,
}, [
// The interpolation of different numbers of background-images looks a bit strange here.
// Animating background-image is not specified to be possible however we do it for backwards compatibility.
// With this in mind we kept the implementation simple at the expense of this corner case because there is
// no official specification to support.
{at: -0.3, is: from + ', ' + from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + from + ', ' + toA + ', 0.3), -webkit-cross-fade(' + from + ', ' + toB + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + from + ', ' + toA + ', 0.6), -webkit-cross-fade(' + from + ', ' + toB + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Multiple mismatched types
from = 'url(../resources/blue-100.png), none';
to = 'url(../resources/stripes-100.png), url(../resources/green-100.png)';
assertInterpolation({
property: 'background-image',
from: from,
to: to,
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: from},
{at: 0.6, is: to},
{at: 1, is: to},
{at: 1.5, is: to},
]);
</script>
</body>

View File

@ -1,69 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 120px;
height: 120px;
display: inline-block;
border: 2px solid black;
background-repeat: no-repeat;
background-image: radial-gradient(20px circle at 20px 20px, red 18px, transparent),
radial-gradient(20px circle at 20px 20px, yellow 18px, transparent),
radial-gradient(20px circle at 20px 20px, lime 18px, transparent),
radial-gradient(20px circle at 20px 20px, blue 18px, transparent);
}
.replica {
margin-right: 10px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
// Test equal number of position values as background images.
assertInterpolation({
property: 'background-position',
from: '0px 0px, 0px 0px, 0px 0px, 0px 0px',
to: '80px 80px, 80px 80px, 80px 80px, 80px 80px',
}, [
{at: -0.25, is: '-20px -20px, -20px -20px, -20px -20px, -20px -20px'},
{at: 0, is: ' 0px 0px, 0px 0px, 0px 0px, 0px 0px'},
{at: 0.25, is: ' 20px 20px, 20px 20px, 20px 20px, 20px 20px'},
{at: 0.5, is: ' 40px 40px, 40px 40px, 40px 40px, 40px 40px'},
{at: 0.75, is: ' 60px 60px, 60px 60px, 60px 60px, 60px 60px'},
{at: 1, is: ' 80px 80px, 80px 80px, 80px 80px, 80px 80px'},
{at: 1.25, is: '100px 100px, 100px 100px, 100px 100px, 100px 100px'},
]);
// Test single position value repeated over background images.
assertInterpolation({
property: 'background-position',
from: 'top 0px left 0px',
to: 'left 80px top 80px',
}, [
{at: -0.25, is: '-20px -20px, -20px -20px, -20px -20px, -20px -20px'},
{at: 0, is: ' top 0px left 0px, 0px 0px, 0px 0px, 0px 0px'},
{at: 0.25, is: ' 20px 20px, 20px 20px, 20px 20px, 20px 20px'},
{at: 0.5, is: ' 40px 40px, 40px 40px, 40px 40px, 40px 40px'},
{at: 0.75, is: ' 60px 60px, 60px 60px, 60px 60px, 60px 60px'},
{at: 1, is: ' left 80px top 80px, 80px 80px, 80px 80px, 80px 80px'},
{at: 1.25, is: '100px 100px, 100px 100px, 100px 100px, 100px 100px'},
]);
// Test mismatched numbers of position values.
assertInterpolation({
property: 'background-position',
from: '0px 0px, 80px 0px',
to: '40px 40px, 80px 80px, 0px 80px',
}, [
{at: -0.25, is: '-10px -10px, 80px -20px, 0px -20px, 90px -10px'},
{at: 0, is: ' 0px 0px, 80px 0px, 0px 0px, 80px 0px'},
{at: 0.25, is: ' 10px 10px, 80px 20px, 0px 20px, 70px 10px'},
{at: 0.5, is: ' 20px 20px, 80px 40px, 0px 40px, 60px 20px'},
{at: 0.75, is: ' 30px 30px, 80px 60px, 0px 60px, 50px 30px'},
{at: 1, is: ' 40px 40px, 80px 80px, 0px 80px, 40px 40px'},
{at: 1.25, is: ' 50px 50px, 80px 100px, 0px 100px, 30px 50px'},
]);
</script>
</body>

View File

@ -1,142 +0,0 @@
<!doctype html>
<meta charset="utf-8">
<style>
.target {
border: 3px solid skyblue;
width: 100px;
height: 100px;
background-image: linear-gradient(to right, coral, coral);
background-size: 20px 20px;
background-repeat: no-repeat;
display: inline-block;
}
.replica {
margin-right: 10px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
// left-top
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'left 20px top 20px',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: 'calc(37.5% + 5px) calc(37.5% + 5px)'},
{at: 0.50, is: 'calc(25% + 10px) calc(25% + 10px)'},
{at: 0.75, is: 'calc(12.5% + 15px) calc(12.5% + 15px)'},
{at: 1, is: 'left 20px top 20px'},
]);
// center-top
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'center top 20px',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: '50% calc(37.5% + 5px)'},
{at: 0.50, is: '50% calc(25% + 10px)'},
{at: 0.75, is: '50% calc(12.5% + 15px)'},
{at: 1, is: 'center top 20px'},
]);
// right-top
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'right 20px top 20px',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: 'calc(37.5% + ((100% - 20px) * 0.25)) calc(37.5% + 5px)'},
{at: 0.50, is: 'calc(25% + ((100% - 20px) * 0.5)) calc(25% + 10px)'},
{at: 0.75, is: 'calc(12.5% + ((100% - 20px) * 0.75)) calc(12.5% + 15px)'},
{at: 1, is: 'right 20px top 20px'},
]);
// left-center
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'left 20px center',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: 'calc(37.5% + 5px) 50%'},
{at: 0.50, is: 'calc(25% + 10px) 50%'},
{at: 0.75, is: 'calc(12.5% + 15px) 50%'},
{at: 1, is: 'left 20px center'},
]);
// center-center
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'center center',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: '50% 50%'},
{at: 0.50, is: '50% 50%'},
{at: 0.75, is: '50% 50%'},
{at: 1, is: 'center center'}
]);
// right-center
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'right 20px center',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: 'calc(37.5% + ((100% - 20px) * 0.25)) 50%'},
{at: 0.50, is: 'calc(25% + ((100% - 20px) * 0.5)) 50%'},
{at: 0.75, is: 'calc(12.5% + ((100% - 20px) * 0.75)) 50%'},
{at: 1, is: 'right 20px center'},
]);
// left-bottom
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'left 20px bottom 20px',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: 'calc(37.5% + 5px) calc(37.5% + ((100% - 20px) * 0.25))'},
{at: 0.50, is: 'calc(25% + 10px) calc(25% + ((100% - 20px) * 0.5))'},
{at: 0.75, is: 'calc(12.5% + 15px) calc(12.5% + ((100% - 20px) * 0.75))'},
{at: 1, is: 'left 20px bottom 20px'},
]);
// center-bottom
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'center bottom 20px',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: '50% calc(37.5% + ((100% - 20px) * 0.25))'},
{at: 0.50, is: '50% calc(25% + ((100% - 20px) * 0.5))'},
{at: 0.75, is: '50% calc(12.5% + ((100% - 20px) * 0.75))'},
{at: 1, is: 'center bottom 20px'},
]);
// right-bottom
assertInterpolation({
property: 'background-position',
from: 'center center',
to: 'right 20px bottom 20px',
}, [
{at: 0, is: 'center center'},
{at: 0.25, is: 'calc(37.5% + ((100% - 20px) * 0.25)) calc(37.5% + ((100% - 20px) * 0.25))'},
{at: 0.50, is: 'calc(25% + ((100% - 20px) * 0.5)) calc(25% + ((100% - 20px) * 0.5))'},
{at: 0.75, is: 'calc(12.5% + ((100% - 20px) * 0.75)) calc(12.5% + ((100% - 20px) * 0.75))'},
{at: 1, is: 'right 20px bottom 20px'},
]);
</script>
</body>

View File

@ -1,101 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 80px;
height: 100px;
display: inline-block;
border: 10px solid black;
background-repeat: no-repeat;
background-image: url(../resources/stripes-100.png),
url(../resources/stripes-100.png),
url(../resources/blue-100.png),
url(../resources/green-100.png);
background-position: left top, right top, left bottom, right bottom;
}
.replica {
margin-right: 10px;
border-color: green;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
// Matched keywords in size value list.
assertInterpolation({
property: 'background-size',
from: '0px 0px, 0px 0px, contain, cover',
to: '40px 40px, 40px 40px, contain, cover',
}, [
{at: -0.25, is: ' 0px 0px, 0px 0px, contain, cover'},
{at: 0, is: ' 0px 0px, 0px 0px, contain, cover'},
{at: 0.25, is: ' 0px 0px, 0px 0px, contain, cover'},
{at: 0.5, is: '40px 40px, 40px 40px, contain, cover'},
{at: 0.75, is: '40px 40px, 40px 40px, contain, cover'},
{at: 1, is: '40px 40px, 40px 40px, contain, cover'},
{at: 1.25, is: '40px 40px, 40px 40px, contain, cover'},
]);
// Mismatched keywords in size value list.
assertInterpolation({
property: 'background-size',
from: '0px 0px, 0px 0px, contain, cover',
to: '40px 40px, 40px 40px, cover, contain',
}, [
{at: -0.25, is: ' 0px 0px, 0px 0px, contain, cover'},
{at: 0, is: ' 0px 0px, 0px 0px, contain, cover'},
{at: 0.25, is: ' 0px 0px, 0px 0px, contain, cover'},
{at: 0.5, is: '40px 40px, 40px 40px, cover, contain'},
{at: 0.75, is: '40px 40px, 40px 40px, cover, contain'},
{at: 1, is: '40px 40px, 40px 40px, cover, contain'},
{at: 1.25, is: '40px 40px, 40px 40px, cover, contain'},
]);
// Equal number of size values as background images.
assertInterpolation({
property: 'background-size',
from: '0px 0px, 0px 0px, 0px 0px, 0px 0px',
to: '20px 20px, 40px 40px, 60px 60px, 100px 100px',
}, [
{at: -0.25, is: ' 0px 0px, 0px 0px, 0px 0px, 0px 0px'},
{at: 0, is: ' 0px 0px, 0px 0px, 0px 0px, 0px 0px'},
{at: 0.25, is: ' 5px 5px, 10px 10px, 15px 15px, 25px 25px'},
{at: 0.5, is: '10px 10px, 20px 20px, 30px 30px, 50px 50px'},
{at: 0.75, is: '15px 15px, 30px 30px, 45px 45px, 75px 75px'},
{at: 1, is: '20px 20px, 40px 40px, 60px 60px, 100px 100px'},
{at: 1.25, is: '25px 25px, 50px 50px, 75px 75px, 125px 125px'},
]);
// Single size value repeated over background images.
assertInterpolation({
property: 'background-size',
from: '0px 0px',
to: '80px 80px',
}, [
{at: -0.25, is: ' 0px 0px, 0px 0px, 0px 0px, 0px 0px'},
{at: 0, is: ' 0px 0px, 0px 0px, 0px 0px, 0px 0px'},
{at: 0.25, is: ' 20px 20px, 20px 20px, 20px 20px, 20px 20px'},
{at: 0.5, is: ' 40px 40px, 40px 40px, 40px 40px, 40px 40px'},
{at: 0.75, is: ' 60px 60px, 60px 60px, 60px 60px, 60px 60px'},
{at: 1, is: ' 80px 80px, 80px 80px, 80px 80px, 80px 80px'},
{at: 1.25, is: '100px 100px, 100px 100px, 100px 100px, 100px 100px'},
]);
// Mismatched numbers of size values.
assertInterpolation({
property: 'background-size',
from: '0px 0px, 80px 0px',
to: '40px 40px, 80px 80px, 0px 80px',
}, [
{at: -0.25, is: ' 0px 0px, 80px 0px, 0px 0px, 90px 0px'},
{at: 0, is: ' 0px 0px, 80px 0px, 0px 0px, 80px 0px'},
{at: 0.25, is: '10px 10px, 80px 20px, 0px 20px, 70px 10px'},
{at: 0.5, is: '20px 20px, 80px 40px, 0px 40px, 60px 20px'},
{at: 0.75, is: '30px 30px, 80px 60px, 0px 60px, 50px 30px'},
{at: 1, is: '40px 40px, 80px 80px, 0px 80px, 40px 40px'},
{at: 1.25, is: '50px 50px, 80px 100px, 0px 100px, 30px 50px'},
]);
</script>
</body>

View File

@ -1,34 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 50px;
height: 50px;
background-color: black;
display: inline-block;
border: 12px solid white;
}
.replica {
background-color: green;
margin-right: 2px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
assertInterpolation({
property: 'border-color',
from: 'white',
to: 'orange'
}, [
{at: -0.3, is: 'white'},
{at: 0, is: 'white'},
{at: 0.3, is: 'rgb(255, 228, 179)'},
{at: 0.6, is: 'rgb(255, 201, 102)'},
{at: 1, is: 'orange'},
{at: 1.5, is: 'rgb(255, 120, 0)'},
]);
</script>
</body>

View File

@ -1,65 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 50px;
height: 50px;
background-color: black;
display: inline-block;
border: 25px;
margin-right: 50px;
border-image-slice: 30%;
background-clip: content-box;
border-image-source: linear-gradient(45deg, pink, blue, white, black, green);
}
.replica {
background-color: green;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
assertInterpolation({
property: 'border-image-outset',
from: '0px',
to: '5px',
}, [
{at: -0.3, is: '0px'}, // CSS border-image-outset can't be negative.
{at: 0, is: '0px'},
{at: 0.1, is: '0.5px'},
{at: 0.2, is: '1px'},
{at: 0.3, is: '1.5px'},
{at: 0.4, is: '2px'},
{at: 0.5, is: '2.5px'},
{at: 0.6, is: '3px'},
{at: 0.7, is: '3.5px'},
{at: 0.8, is: '4px'},
{at: 0.9, is: '4.5px'},
{at: 1, is: '5px'},
{at: 1.5, is: '7.5px'},
{at: 10, is: '50px'}
]);
assertInterpolation({
property: 'border-image-outset',
from: '0',
to: '5',
}, [
{at: -0.3, is: '0'}, // CSS border-image-outset can't be negative.
{at: 0, is: '0'},
{at: 0.1, is: '0.5'},
{at: 0.2, is: '1'},
{at: 0.3, is: '1.5'},
{at: 0.4, is: '2'},
{at: 0.5, is: '2.5'},
{at: 0.6, is: '3'},
{at: 0.7, is: '3.5'},
{at: 0.8, is: '4'},
{at: 0.9, is: '4.5'},
{at: 1, is: '5'},
{at: 1.5, is: '7.5'},
{at: 10, is: '50'}
]);
</script>
</body>

View File

@ -1,43 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 50px;
height: 50px;
background-color: black;
display: inline-block;
border: 25px;
border-image-source: linear-gradient(45deg, red, blue, green);
}
.replica {
background-color: green;
margin-right: 2px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
assertInterpolation({
property: 'border-image-slice',
from: '0%',
to: '50%',
}, [
{at: -0.3, is: '0%'}, // CSS border-image-slice can't be negative.
{at: 0, is: '0%'},
{at: 0.1, is: '5%'},
{at: 0.2, is: '10%'},
{at: 0.3, is: '15%'},
{at: 0.4, is: '20%'},
{at: 0.5, is: '25%'},
{at: 0.6, is: '30%'},
{at: 0.7, is: '35%'},
{at: 0.8, is: '40%'},
{at: 0.9, is: '45%'},
{at: 1, is: '50%'},
{at: 1.5, is: '75%'},
{at: 10, is: '500%'}
]);
</script>
</body>

View File

@ -1,83 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 50px;
height: 50px;
background-color: black;
display: inline-block;
border: 25px;
}
.replica {
background-color: green;
margin-right: 2px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
// None to image
var from = 'none';
var to = 'url(../resources/stripes-100.png)';
assertInterpolation({
property: 'border-image-source',
from: from,
to: to
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: from},
{at: 0.6, is: to},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Image to image
from = 'url(../resources/green-100.png)';
to = 'url(../resources/stripes-100.png)';
assertInterpolation({
property: 'border-image-source',
from: from,
to: to
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Image to gradient
to = 'linear-gradient(45deg, blue, orange)';
assertInterpolation({
property: 'border-image-source',
from: from,
to: to
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
// Gradient to gradient
from = 'linear-gradient(-45deg, red, yellow)';
assertInterpolation({
property: 'border-image-source',
from: from,
to: to
}, [
{at: -0.3, is: from},
{at: 0, is: from},
{at: 0.3, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.3)'},
{at: 0.6, is: '-webkit-cross-fade(' + from + ', ' + to + ', 0.6)'},
{at: 1, is: to},
{at: 1.5, is: to},
]);
</script>
</body>

View File

@ -1,154 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 100px;
height: 100px;
background-color: black;
display: inline-block;
border: 10px;
border-image-source: linear-gradient(45deg, red, blue, green);
}
.replica {
background-color: green;
margin-right: 2px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
assertInterpolation({
property: 'border-image-width',
from: '0px',
to: '20px'
}, [
{at: -0.3, is: '0px'}, // CSS border-image-width can't be negative.
{at: 0, is: '0px'},
{at: 0.3, is: '6px'},
{at: 0.6, is: '12px'},
{at: 1, is: '20px'},
{at: 1.5, is: '30px'},
{at: 5, is: '100px'},
{at: 10, is: '200px'}
]);
assertInterpolation({
property: 'border-image-width',
from: '0%',
to: '20%'
}, [
{at: -0.3, is: '0%'}, // CSS border-image-width can't be negative.
{at: 0, is: '0%'},
{at: 0.3, is: '6%'},
{at: 0.6, is: '12%'},
{at: 1, is: '20%'},
{at: 1.5, is: '30%'},
{at: 5, is: '100%'},
{at: 10, is: '200%'}
]);
assertInterpolation({
property: 'border-image-width',
from: '0',
to: '20'
}, [
{at: -0.3, is: '0'}, // CSS border-image-width can't be negative.
{at: 0, is: '0'},
{at: 0.3, is: '6'},
{at: 0.6, is: '12'},
{at: 1, is: '20'},
{at: 1.5, is: '30'},
{at: 5, is: '100'},
{at: 10, is: '200'}
]);
assertInterpolation({
property: 'border-image-width',
from: '10px 20% 30 40px',
to: '80px 70% 60 50px'
}, [
{at: -0.3, is: '0px 5% 21 37px'}, // CSS border-image-width can't be negative.
{at: 0, is: '10px 20% 30 40px'},
{at: 0.3, is: '31px 35% 39 43px'},
{at: 0.6, is: '52px 50% 48 46px'},
{at: 1, is: '80px 70% 60 50px'},
{at: 1.5, is: '115px 95% 75 55px'},
{at: 5, is: '360px 270% 180 90px'},
{at: 10, is: '710px 520% 330 140px'}
]);
assertInterpolation({
property: 'border-image-width',
from: '10%',
to: '20px'
}, [
// Percentages are relative to the size of the border image area, which is 120px.
{at: -0.3, is: 'calc(13% + -6px)'}, // Should be parsed as 16px - 6px = 10px
{at: 0, is: '10%'}, // Should be parsed as 12px
{at: 0.3, is: 'calc(7% + 6px)'}, // Should be parsed as 8px + 6px = 14px
{at: 0.6, is: 'calc(4% + 12px)'}, // Should be parsed as 5px + 12px = 17px
{at: 1, is: '20px'},
{at: 1.5, is: 'calc(-5% + 30px)'}, // Should be parsed as -6px + 30px = 24px
]);
assertInterpolation({
property: 'border-image-width',
from: '10px',
to: '20%'
}, [
// Percentages are relative to the size of the border image area, which is 120px.
{at: -0.3, is: 'calc(13px + -6%)'}, // Should be parsed as 13px - 7px = 6px
{at: 0, is: '10px'},
{at: 0.3, is: 'calc(7px + 6%)'}, // Should be parsed as 7px + 7px = 14px
{at: 0.6, is: 'calc(4px + 12%)'}, // Should be parsed as 4px + 14px = 18px
{at: 1, is: '20%'}, // Should be parsed as 24px
{at: 1.5, is: 'calc(-5px + 30%)'}, // Should be parsed as -5px + 36px = 31px
]);
assertInterpolation({
property: 'border-image-width',
from: '10px',
to: '20'
}, [
{at: -0.3, is: '10px'},
{at: 0, is: '10px'},
{at: 0.3, is: '10px'},
{at: 0.6, is: '20'},
{at: 1, is: '20'},
{at: 1.5, is: '20'},
]);
assertInterpolation({
property: 'border-image-width',
from: '10',
to: '20px'
}, [
{at: -0.3, is: '10'},
{at: 0, is: '10'},
{at: 0.3, is: '10'},
{at: 0.6, is: '20px'},
{at: 1, is: '20px'},
{at: 1.5, is: '20px'},
]);
assertInterpolation({
property: 'border-image-width',
from: '10%',
to: '20'
}, [
{at: -0.3, is: '10%'},
{at: 0, is: '10%'},
{at: 0.3, is: '10%'},
{at: 0.6, is: '20'},
{at: 1, is: '20'},
{at: 1.5, is: '20'},
]);
assertInterpolation({
property: 'border-image-width',
from: '10',
to: '20%'
}, [
{at: -0.3, is: '10'},
{at: 0, is: '10'},
{at: 0.3, is: '10'},
{at: 0.6, is: '20%'},
{at: 1, is: '20%'},
{at: 1.5, is: '20%'},
]);
</script>
</body>

View File

@ -1,48 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 80px;
height: 80px;
display: inline-block;
background-color: black;
margin-right: 5px;
}
.replica {
background-color: green;
margin-right: 15px;
}
</style>
<body>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
assertInterpolation({
property: 'border-radius',
from: '10px',
to: '50px'
}, [
{at: -0.3, is: '0px'}, // CSS border-radius can't be negative.
{at: 0, is: '10px'},
{at: 0.3, is: '22px'},
{at: 0.6, is: '34px'},
{at: 1, is: '50px'},
{at: 1.5, is: '70px'},
]);
assertInterpolation({
property: 'border-radius',
from: '10px',
to: '100%'
}, [
// These expectations are expected to fail on the current animation engine
// with different (but equivalent) calc expressions.
{at: -0.3, is: 'calc(13px + -30%)'},
{at: 0, is: '10px'},
{at: 0.3, is: 'calc(7px + 30%)'},
{at: 0.6, is: 'calc(4px + 60%)'},
{at: 1, is: '100%'},
{at: 1.5, is: 'calc(-5px + 150%)'},
]);
</script>
</body>

View File

@ -1,74 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<style>
.target {
width: 50px;
height: 50px;
background-color: black;
display: inline-block;
margin: 18px;
border-collapse: separate;
}
.target td {
background-color: white;
border: 1px solid orange;
width: 10px;
height: 10px;
}
.replica {
background-color: green;
}
</style>
<body>
<template id="target-template">
<table>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</template>
<script src="../testharness/testharness.js"></script>
<script src="../testharness/testharnessreport.js"></script>
<script src="resources/interpolation-test.js"></script>
<script>
assertInterpolation({
property: 'border-spacing',
from: '0px',
to: '10px'
}, [
{at: -0.3, is: '0px 0px'}, // Can't be negative.
{at: 0, is: '0px 0px'},
{at: 0.3, is: '3px 3px'},
{at: 0.6, is: '6px 6px'},
{at: 1, is: '10px 10px'},
{at: 1.5, is: '15px 15px'}
]);
assertInterpolation({
property: '-webkit-border-horizontal-spacing',
from: '0px',
to: '10px'
}, [
{at: -0.3, is: '0px'}, // Can't be negative.
{at: 0, is: '0px'},
{at: 0.3, is: '3px'},
{at: 0.6, is: '6px'},
{at: 1, is: '10px'},
{at: 1.5, is: '15px'}
]);
assertInterpolation({
property: '-webkit-border-vertical-spacing',
from: '0px',
to: '10px'
}, [
{at: -0.3, is: '0px'}, // Can't be negative.
{at: 0, is: '0px'},
{at: 0.3, is: '3px'},
{at: 0.6, is: '6px'},
{at: 1, is: '10px'},
{at: 1.5, is: '15px'}
]);
</script>
</body>

Some files were not shown because too many files have changed in this diff Show More