diff --git a/content/smil/test/Makefile.in b/content/smil/test/Makefile.in index 1b671277fb7..e54f1666cc4 100644 --- a/content/smil/test/Makefile.in +++ b/content/smil/test/Makefile.in @@ -45,13 +45,18 @@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _TEST_FILES = \ + db_smilAnimateMotion.js \ db_smilCSSFromBy.js \ db_smilCSSFromTo.js \ db_smilCSSPaced.js \ db_smilCSSPropertyList.js \ db_smilMappedAttrList.js \ + smilAnimateMotionValueLists.js \ smilTestUtils.js \ smilXHR_helper.svg \ + test_smilAnimateMotion.xhtml \ + test_smilAnimateMotionInvalidValues.xhtml \ + test_smilAnimateMotionOverrideRules.xhtml \ test_smilChangeAfterFrozen.xhtml \ test_smilContainerBinding.xhtml \ test_smilCrossContainer.xhtml \ diff --git a/content/smil/test/db_smilAnimateMotion.js b/content/smil/test/db_smilAnimateMotion.js new file mode 100644 index 00000000000..92a006d8bef --- /dev/null +++ b/content/smil/test/db_smilAnimateMotion.js @@ -0,0 +1,286 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 sts=2 et: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla SMIL Test Code. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Daniel Holbert (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* testcase data for */ + +// Fake motion 'attribute', to satisfy testing code that expects an attribute. +var gMotionAttr = new AdditiveAttribute(SMILUtil.getMotionFakeAttributeName(), + "XML", "rect"); + +// CTM-summary-definitions, for re-use by multiple testcase bundles below. +var _reusedCTMLists = { + pacedBasic: { ctm0: [100, 200, 0], + ctm1_6: [105, 205, 0], + ctm1_3: [110, 210, 0], + ctm2_3: [120, 220, 0], + ctm1: [130, 210, 0] + }, + pacedR60: { ctm0: [100, 200, Math.PI/3], + ctm1_6: [105, 205, Math.PI/3], + ctm1_3: [110, 210, Math.PI/3], + ctm2_3: [120, 220, Math.PI/3], + ctm1: [130, 210, Math.PI/3] + }, + pacedRAuto: { ctm0: [100, 200, Math.PI/4], + ctm1_6: [105, 205, Math.PI/4], + ctm1_3: [110, 210, Math.PI/4], + ctm2_3: [120, 220, Math.PI/4], + ctm1: [130, 210, -Math.PI/4] + }, + pacedRAutoReverse : { ctm0: [100, 200, 5*Math.PI/4], + ctm1_6: [105, 205, 5*Math.PI/4], + ctm1_3: [110, 210, 5*Math.PI/4], + ctm2_3: [120, 220, 5*Math.PI/4], + ctm1: [130, 210, 3*Math.PI/4] + }, + + discreteBasic : { ctm0: [100, 200, 0], + ctm1_6: [100, 200, 0], + ctm1_3: [120, 220, 0], + ctm2_3: [130, 210, 0], + ctm1: [130, 210, 0] + }, + discreteRAuto : { ctm0: [100, 200, Math.PI/4], + ctm1_6: [100, 200, Math.PI/4], + ctm1_3: [120, 220, Math.PI/4], + ctm2_3: [130, 210, -Math.PI/4], + ctm1: [130, 210, -Math.PI/4] + }, + justMoveBasic : { ctm0: [40, 80, 0], + ctm1_6: [40, 80, 0], + ctm1_3: [40, 80, 0], + ctm2_3: [40, 80, 0], + ctm1: [40, 80, 0] + }, + justMoveR60 : { ctm0: [40, 80, Math.PI/3], + ctm1_6: [40, 80, Math.PI/3], + ctm1_3: [40, 80, Math.PI/3], + ctm2_3: [40, 80, Math.PI/3], + ctm1: [40, 80, Math.PI/3] + }, + justMoveRAuto : { ctm0: [40, 80, Math.atan(2)], + ctm1_6: [40, 80, Math.atan(2)], + ctm1_3: [40, 80, Math.atan(2)], + ctm2_3: [40, 80, Math.atan(2)], + ctm1: [40, 80, Math.atan(2)] + }, + justMoveRAutoReverse : { ctm0: [40, 80, Math.PI + Math.atan(2)], + ctm1_6: [40, 80, Math.PI + Math.atan(2)], + ctm1_3: [40, 80, Math.PI + Math.atan(2)], + ctm2_3: [40, 80, Math.PI + Math.atan(2)], + ctm1: [40, 80, Math.PI + Math.atan(2)] + }, + nullMoveBasic : { ctm0: [0, 0, 0], + ctm1_6: [0, 0, 0], + ctm1_3: [0, 0, 0], + ctm2_3: [0, 0, 0], + ctm1: [0, 0, 0] + }, + nullMoveRAutoReverse : { ctm0: [0, 0, Math.PI], + ctm1_6: [0, 0, Math.PI], + ctm1_3: [0, 0, Math.PI], + ctm2_3: [0, 0, Math.PI], + ctm1: [0, 0, Math.PI] + }, +}; + +var gMotionBundles = +[ + // Bundle to test basic functionality (using default calcMode='paced') + new TestcaseBundle(gMotionAttr, [ + // Basic paced-mode (default) test, with values/mpath/path + new AnimMotionTestcase({ "values": "100, 200; 120, 220; 130, 210" }, + _reusedCTMLists.pacedBasic), + new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210" }, + _reusedCTMLists.pacedBasic), + new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210" }, + _reusedCTMLists.pacedBasic), + + // ..and now with rotate=constant value in degrees + new AnimMotionTestcase({ "values": "100,200; 120,220; 130, 210", + "rotate": "60" }, + _reusedCTMLists.pacedR60), + new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210", + "rotate": "60" }, + _reusedCTMLists.pacedR60), + new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210", + "rotate": "60" }, + _reusedCTMLists.pacedR60), + + // ..and now with rotate=constant value in radians + new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210", + "rotate": "1.0471975512rad" }, // pi/3 + _reusedCTMLists.pacedR60), + + // ..and now with rotate=auto + new AnimMotionTestcase({ "values": "100,200; 120,220; 130, 210", + "rotate": "auto" }, + _reusedCTMLists.pacedRAuto), + new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210", + "rotate": "auto" }, + _reusedCTMLists.pacedRAuto), + new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210", + "rotate": "auto" }, + _reusedCTMLists.pacedRAuto), + + // ..and now with rotate=auto-reverse + new AnimMotionTestcase({ "values": "100,200; 120,220; 130, 210", + "rotate": "auto-reverse" }, + _reusedCTMLists.pacedRAutoReverse), + new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210", + "rotate": "auto-reverse" }, + _reusedCTMLists.pacedRAutoReverse), + new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210", + "rotate": "auto-reverse" }, + _reusedCTMLists.pacedRAutoReverse), + + ]), + + // Bundle to test calcMode='discrete' + new TestcaseBundle(gMotionAttr, [ + new AnimMotionTestcase({ "values": "100, 200; 120, 220; 130, 210", + "calcMode": "discrete" }, + _reusedCTMLists.discreteBasic), + new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210", + "calcMode": "discrete" }, + _reusedCTMLists.discreteBasic), + new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210", + "calcMode": "discrete" }, + _reusedCTMLists.discreteBasic), + // ..and now with rotate=auto + new AnimMotionTestcase({ "values": "100, 200; 120, 220; 130, 210", + "calcMode": "discrete", + "rotate": "auto" }, + _reusedCTMLists.discreteRAuto), + new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210", + "calcMode": "discrete", + "rotate": "auto" }, + _reusedCTMLists.discreteRAuto), + new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210", + "calcMode": "discrete", + "rotate": "auto" }, + _reusedCTMLists.discreteRAuto), + ]), + + // Bundle to test relative units ('em') + new TestcaseBundle(gMotionAttr, [ + // First with unitless values from->by... + new AnimMotionTestcase({ "from": "10, 10", + "by": "30, 60" }, + { ctm0: [10, 10, 0], + ctm1_6: [15, 20, 0], + ctm1_3: [20, 30, 0], + ctm2_3: [30, 50, 0], + ctm1: [40, 70, 0] + }), + // ... then add 'em' units (with 1em=10px) on half the values + new AnimMotionTestcase({ "from": "1em, 10", + "by": "30, 6em" }, + { ctm0: [10, 10, 0], + ctm1_6: [15, 20, 0], + ctm1_3: [20, 30, 0], + ctm2_3: [30, 50, 0], + ctm1: [40, 70, 0] + }), + ]), + + // Bundle to test a path with just a "move" command and nothing else + new TestcaseBundle(gMotionAttr, [ + new AnimMotionTestcase({ "values": "40, 80" }, + _reusedCTMLists.justMoveBasic), + new AnimMotionTestcase({ "path": "M40 80" }, + _reusedCTMLists.justMoveBasic), + new AnimMotionTestcase({ "mpath": "m40 80" }, + _reusedCTMLists.justMoveBasic), + ]), + // ... and now with a fixed rotate-angle + new TestcaseBundle(gMotionAttr, [ + new AnimMotionTestcase({ "values": "40, 80", + "rotate": "60" }, + _reusedCTMLists.justMoveR60), + new AnimMotionTestcase({ "path": "M40 80", + "rotate": "60" }, + _reusedCTMLists.justMoveR60), + new AnimMotionTestcase({ "mpath": "m40 80", + "rotate": "60" }, + _reusedCTMLists.justMoveR60), + ]), + // ... and now with 'auto' (should use the move itself as + // our tangent angle, I think) + new TestcaseBundle(gMotionAttr, [ + new AnimMotionTestcase({ "values": "40, 80", + "rotate": "auto" }, + _reusedCTMLists.justMoveRAuto), + new AnimMotionTestcase({ "path": "M40 80", + "rotate": "auto" }, + _reusedCTMLists.justMoveRAuto), + new AnimMotionTestcase({ "mpath": "m40 80", + "rotate": "auto" }, + _reusedCTMLists.justMoveRAuto), + ]), + // ... and now with 'auto-reverse' + new TestcaseBundle(gMotionAttr, [ + new AnimMotionTestcase({ "values": "40, 80", + "rotate": "auto-reverse" }, + _reusedCTMLists.justMoveRAutoReverse), + new AnimMotionTestcase({ "path": "M40 80", + "rotate": "auto-reverse" }, + _reusedCTMLists.justMoveRAutoReverse), + new AnimMotionTestcase({ "mpath": "m40 80", + "rotate": "auto-reverse" }, + _reusedCTMLists.justMoveRAutoReverse), + ]), + // ... and now with a null move to make sure 'auto'/'auto-reverse' don't + // blow up + new TestcaseBundle(gMotionAttr, [ + new AnimMotionTestcase({ "values": "0, 0", + "rotate": "auto" }, + _reusedCTMLists.nullMoveBasic), + ]), + new TestcaseBundle(gMotionAttr, [ + new AnimMotionTestcase({ "values": "0, 0", + "rotate": "auto-reverse" }, + _reusedCTMLists.nullMoveRAutoReverse), + ]), +]; + +// XXXdholbert Add more tests: +// - keyPoints/keyTimes +// - paths with curves +// - Control path with from/by/to diff --git a/content/smil/test/smilAnimateMotionValueLists.js b/content/smil/test/smilAnimateMotionValueLists.js new file mode 100644 index 00000000000..3afeba7e86c --- /dev/null +++ b/content/smil/test/smilAnimateMotionValueLists.js @@ -0,0 +1,124 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 sts=2 et: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla SMIL Test Code. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Daniel Holbert (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Lists of valid & invalid values for the various attributes */ +const gValidValues = [ + "10 10", + " 10 10em ", + "1 2 ; 3,4", + "1,2;3,4", + "0 0", + "0,0", +]; + +const gInvalidValues = [ + "10 10;", // We treat semicolon-terminated value-lists as failure cases + "1 2 3", + "1 2 3 4", + "1,2;3,4 ,", + ",", ";", "a", "", " ", +]; + +const gInvalidValuesTodo = [ + "1,2;3,4,", + "1,,2", + ",1,2", +]; + +const gValidRotate = [ + "10", + "20.1", + "30.5deg", + "0.5rad", + "auto", + "auto-reverse" +]; + +const gInvalidRotate = [ + " 10 ", + " 10deg", + "10 deg", + "10deg ", + "10 rad ", + "aaa", + " 10.1 ", +]; + +const gValidToBy = [ + "0 0", + "1em,2", + "50.3em 0.2in" +]; + +const gInvalidToBy = [ + "0 0 0", + "0 0,0", + "0,0,0", + "1emm 2", + "1 2;", + " 1,2 ,", + "abc", + ",", + "" +]; + +const gInvalidToByTodo = [ + "1,,2", + "1,2,", + " 1,2", + "1 2 " +]; + +const gValidPath = [ + "m0 0 L30 30", + "M20,20L10 10", + "M20,20 L30, 30h20", + "m50 50", "M50 50", + "m0 0", "M0, 0" +]; + +const gInvalidPath = [ + "m0 0 L30,,30", + "M20 20em", + "M20in 20", + "h30", + "L50 50", + "abc", + "M10 10 L50 50 abc", +]; diff --git a/content/smil/test/smilTestUtils.js b/content/smil/test/smilTestUtils.js index baafd6e18a3..afd356251d5 100644 --- a/content/smil/test/smilTestUtils.js +++ b/content/smil/test/smilTestUtils.js @@ -39,6 +39,9 @@ // Note: Class syntax roughly based on: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Inheritance const SVG_NS = "http://www.w3.org/2000/svg"; +const XLINK_NS = "http://www.w3.org/1999/xlink"; + +const MPATH_TARGET_ID = "smilTestUtilsTestingPath"; function extend(child, supertype) { @@ -85,11 +88,16 @@ var SMILUtil = getAttributeValue: function(elem, attr) { + if (attr.attrName == SMILUtil.getMotionFakeAttributeName()) { + // Fake motion "attribute" -- "computed value" is the element's CTM + return elem.getCTM(); + } if (attr.attrType == "CSS") { return SMILUtil.getComputedStyleWrapper(elem, attr.attrName); - } else if (attr.attrType == "XML") { + } + if (attr.attrType == "XML") { // XXXdholbert This is appropriate for mapped attributes, but not - // for others. + // for other attributes. return SMILUtil.getComputedStyleWrapper(elem, attr.attrName); } }, @@ -168,7 +176,82 @@ var SMILUtil = child = child.nextSibling; } }, -} + + getMotionFakeAttributeName : function() { + return "_motion"; + }, +}; + + +var CTMUtil = +{ + CTM_COMPONENTS_ALL : ["a", "b", "c", "d", "e", "f"], + CTM_COMPONENTS_ROTATE : ["a", "b", "c", "d" ], + + // Function to generate a CTM Matrix from a "summary" + // (a 3-tuple containing [tX, tY, theta]) + generateCTM : function(aCtmSummary) + { + if (!aCtmSummary || aCtmSummary.length != 3) { + ok(false, "Unexpected CTM summary tuple length: " + aCtmSummary.length); + } + var tX = aCtmSummary[0]; + var tY = aCtmSummary[1]; + var theta = aCtmSummary[2]; + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); + var newCtm = { a : cosTheta, c: -sinTheta, e: tX, + b : sinTheta, d: cosTheta, f: tY }; + return newCtm; + }, + + /// Helper for isCtmEqual + isWithinDelta : function(aTestVal, aExpectedVal, aErrMsg, aIsTodo) { + var testFunc = aIsTodo ? todo : ok; + const delta = 0.000001; // allowing margin of error = 10^-6 + ok(aTestVal >= aExpectedVal - delta && + aTestVal <= aExpectedVal + delta, + aErrMsg + " | got: " + aTestVal + ", expected: " + aExpectedVal); + }, + + assertCTMEqual : function(aLeftCtm, aRightCtm, aComponentsToCheck, + aErrMsg, aIsTodo) { + var foundCTMDifference = false; + for (var j in aComponentsToCheck) { + var curComponent = aComponentsToCheck[j]; + if (!aIsTodo) { + CTMUtil.isWithinDelta(aLeftCtm[curComponent], aRightCtm[curComponent], + aErrMsg + " | component: " + curComponent, false); + } else if (aLeftCtm[curComponent] != aRightCtm[curComponent]) { + foundCTMDifference = true; + } + } + + if (aIsTodo) { + todo(!foundCTMDifference, aErrMsg + " | (currently marked todo)"); + } + }, + + assertCTMNotEqual : function(aLeftCtm, aRightCtm, aComponentsToCheck, + aErrMsg, aIsTodo) { + // CTM should not match initial one + var foundCTMDifference = false; + for (var j in aComponentsToCheck) { + var curComponent = aComponentsToCheck[j]; + if (aLeftCtm[curComponent] != aRightCtm[curComponent]) { + foundCTMDifference = true; + break; // We found a difference, as expected. Success! + } + } + + if (aIsTodo) { + todo(foundCTMDifference, aErrMsg + " | (currently marked todo)"); + } else { + ok(foundCTMDifference, aErrMsg); + } + }, +}; + // Wrapper for timing information function SMILTimingData(aBegin, aDur) @@ -685,6 +768,154 @@ AnimTestcasePaced.prototype = }; extend(AnimTestcasePaced, AnimTestcase); +/* + * A testcase for an animation. + * + * @param aAttrValueHash A hash-map mapping attribute names to values. + * Should include at least 'path', 'values', 'to' + * or 'by' to describe the motion path. + * @param aCtmMap A hash-map that contains summaries of the expected resulting + * CTM at various points during the animation. The CTM is + * summarized as a tuple of three numbers: [tX, tY, theta] + (indicating a translate(tX,tY) followed by a rotate(theta)) + * - ctm0: The CTM summary at the start of the animation + * - ctm1_6: The CTM summary at exactly 1/6 through animation + * - ctm1_3: The CTM summary at exactly 1/3 through animation + * - ctm2_3: The CTM summary at exactly 2/3 through animation + * - ctm1: The CTM summary at the animation endpoint + * + * NOTE: For paced-mode animation (the default for animateMotion), the math + * works out easiest if: + * (a) our motion path has 3 points: vA, vB, vC + * (b) dist(vB, vC) = 2 * dist(vA, vB) + * (See discussion in header comment for AnimTestcasePaced.) + * + * @param aSkipReason If this test-case is known to currently fail, this + * parameter should be a string explaining why. + * Otherwise, this value should be null (or omitted). + */ +function AnimMotionTestcase(aAttrValueHash, aCtmMap, aSkipReason) +{ + this.attrValueHash = aAttrValueHash; + this.ctmMap = aCtmMap; + this.skipReason = aSkipReason; + if (this.ctmMap && + (!this.ctmMap.ctm0 || + !this.ctmMap.ctm1_6 || + !this.ctmMap.ctm1_3 || + !this.ctmMap.ctm2_3 || + !this.ctmMap.ctm1)) { + ok(false, "This AnimMotionTestcase has an incomplete CTM map"); + } +} +AnimMotionTestcase.prototype = +{ + // Member variables + _animElementTagName : "animateMotion", + + // Implementations of inherited methods that we need to override: + // -------------------------------------------------------------- + setupAnimationElement : function(aAnimAttr, aTimeData, aIsFreeze) + { + var animElement = document.createElementNS(SVG_NS, + this._animElementTagName); + animElement.setAttribute("begin", aTimeData.getBeginTime()); + animElement.setAttribute("dur", aTimeData.getDur()); + if (aIsFreeze) { + animElement.setAttribute("fill", "freeze"); + } + for (var attrName in this.attrValueHash) { + if (attrName == "mpath") { + this.createPath(this.attrValueHash[attrName]); + this.createMpath(animElement); + } else { + animElement.setAttribute(attrName, this.attrValueHash[attrName]); + } + } + return animElement; + }, + + createPath : function(aPathDescription) + { + var path = document.createElementNS(SVG_NS, "path"); + path.setAttribute("d", aPathDescription); + path.setAttribute("id", MPATH_TARGET_ID); + return SMILUtil.getSVGRoot().appendChild(path); + }, + + createMpath : function(aAnimElement) + { + var mpath = document.createElementNS(SVG_NS, "mpath"); + mpath.setAttributeNS(XLINK_NS, "href", "#" + MPATH_TARGET_ID); + return aAnimElement.appendChild(mpath); + }, + + // Override inherited seekAndTest method since... + // (a) it expects a computedValMap and we have a computed-CTM map instead + // and (b) it expects we might have no effect (for non-animatable attrs) + buildSeekList : function(aAnimAttr, aBaseVal, aTimeData, aIsFreeze) + { + var seekList = new Array(); + var msgPrefix = "CTM mismatch "; + seekList.push([aTimeData.getBeginTime(), + CTMUtil.generateCTM(this.ctmMap.ctm0), + msgPrefix + "at start of animation"]); + seekList.push([aTimeData.getFractionalTime(1/6), + CTMUtil.generateCTM(this.ctmMap.ctm1_6), + msgPrefix + "1/6 of the way through animation."]); + seekList.push([aTimeData.getFractionalTime(1/3), + CTMUtil.generateCTM(this.ctmMap.ctm1_3), + msgPrefix + "1/3 of the way through animation."]); + seekList.push([aTimeData.getFractionalTime(2/3), + CTMUtil.generateCTM(this.ctmMap.ctm2_3), + msgPrefix + "2/3 of the way through animation."]); + + var finalMsg; + var expectedEndVal; + if (aIsFreeze) { + expectedEndVal = CTMUtil.generateCTM(this.ctmMap.ctm1); + finalMsg = aAnimAttr.attrName + + ": [freeze-mode] checking that final value is set "; + } else { + expectedEndVal = aBaseVal; + finalMsg = aAnimAttr.attrName + + ": [remove-mode] checking that animation is cleared "; + } + seekList.push([aTimeData.getEndTime(), + expectedEndVal, finalMsg + "at end of animation"]); + seekList.push([aTimeData.getEndTime() + aTimeData.getDur(), + expectedEndVal, finalMsg + "after end of animation"]); + return seekList; + }, + + // Override inherited seekAndTest method + // (Have to use assertCTMEqual() instead of is() for comparison, to check each + // component of the CTM and to allow for a small margin of error.) + seekAndTest : function(aSeekList, aTargetElem, aTargetAttr) + { + var svg = document.getElementById("svg"); + for (var i in aSeekList) { + var entry = aSeekList[i]; + SMILUtil.getSVGRoot().setCurrentTime(entry[0]); + CTMUtil.assertCTMEqual(aTargetElem.getCTM(), entry[1], + CTMUtil.CTM_COMPONENTS_ALL, entry[2], false); + } + }, + + // Override "runTest" method so we can remove any element that we + // created at the end of each test. + runTest : function(aTargetElem, aTargetAttr, aTimeData, aIsFreeze) + { + AnimTestcase.prototype.runTest.apply(this, + [aTargetElem, aTargetAttr, aTimeData, aIsFreeze]); + var pathElem = document.getElementById(MPATH_TARGET_ID); + if (pathElem) { + SMILUtil.getSVGRoot().removeChild(pathElem); + } + } +}; +extend(AnimMotionTestcase, AnimTestcase); + // MAIN METHOD function testBundleList(aBundleList, aTimingData) { diff --git a/content/smil/test/test_smilAnimateMotion.xhtml b/content/smil/test/test_smilAnimateMotion.xhtml new file mode 100644 index 00000000000..487c6248c18 --- /dev/null +++ b/content/smil/test/test_smilAnimateMotion.xhtml @@ -0,0 +1,58 @@ + + + + Test for animateMotion behavior + + + + + + + +Mozilla Bug 436418 +

+ +
+
+
+ + diff --git a/content/smil/test/test_smilAnimateMotionInvalidValues.xhtml b/content/smil/test/test_smilAnimateMotionInvalidValues.xhtml new file mode 100644 index 00000000000..bb2ce3aebb5 --- /dev/null +++ b/content/smil/test/test_smilAnimateMotionInvalidValues.xhtml @@ -0,0 +1,175 @@ + + + + Test for animateMotion acceptance of invalid values + + + + + + diff --git a/content/smil/test/test_smilAnimateMotionOverrideRules.xhtml b/content/smil/test/test_smilAnimateMotionOverrideRules.xhtml new file mode 100644 index 00000000000..8a5938f7fea --- /dev/null +++ b/content/smil/test/test_smilAnimateMotionOverrideRules.xhtml @@ -0,0 +1,222 @@ + + + + Test for overriding of path-defining attributes for animateMotion + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-by-1.svg b/layout/reftests/svg/smil/motion/animateMotion-by-1.svg new file mode 100644 index 00000000000..755cf4c1e5c --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-by-1.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-from-to-1.svg b/layout/reftests/svg/smil/motion/animateMotion-from-to-1.svg new file mode 100644 index 00000000000..e8aeed8ee26 --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-from-to-1.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-mpath-targetChange-1.svg b/layout/reftests/svg/smil/motion/animateMotion-mpath-targetChange-1.svg new file mode 100644 index 00000000000..b2a408ca626 --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-mpath-targetChange-1.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-rotate-1.svg b/layout/reftests/svg/smil/motion/animateMotion-rotate-1.svg new file mode 100644 index 00000000000..368ffbc50f9 --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-rotate-1.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-rotate-2.svg b/layout/reftests/svg/smil/motion/animateMotion-rotate-2.svg new file mode 100644 index 00000000000..da79360609b --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-rotate-2.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-values-linear-1-ref.svg b/layout/reftests/svg/smil/motion/animateMotion-values-linear-1-ref.svg new file mode 100644 index 00000000000..fbb06fcf132 --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-values-linear-1-ref.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-values-linear-1.svg b/layout/reftests/svg/smil/motion/animateMotion-values-linear-1.svg new file mode 100644 index 00000000000..6c4721cca0f --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-values-linear-1.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-values-paced-1-ref.svg b/layout/reftests/svg/smil/motion/animateMotion-values-paced-1-ref.svg new file mode 100644 index 00000000000..d933fb83818 --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-values-paced-1-ref.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-values-paced-1a.svg b/layout/reftests/svg/smil/motion/animateMotion-values-paced-1a.svg new file mode 100644 index 00000000000..737574cae5f --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-values-paced-1a.svg @@ -0,0 +1,14 @@ + + + + + + diff --git a/layout/reftests/svg/smil/motion/animateMotion-values-paced-1b.svg b/layout/reftests/svg/smil/motion/animateMotion-values-paced-1b.svg new file mode 100644 index 00000000000..9d72807d9e6 --- /dev/null +++ b/layout/reftests/svg/smil/motion/animateMotion-values-paced-1b.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/layout/reftests/svg/smil/motion/lime.svg b/layout/reftests/svg/smil/motion/lime.svg new file mode 100644 index 00000000000..b113287a3e2 --- /dev/null +++ b/layout/reftests/svg/smil/motion/lime.svg @@ -0,0 +1,8 @@ + + + Testcase reference file for generic pass condition + + diff --git a/layout/reftests/svg/smil/motion/reftest.list b/layout/reftests/svg/smil/motion/reftest.list new file mode 100644 index 00000000000..5b21dfe1f6e --- /dev/null +++ b/layout/reftests/svg/smil/motion/reftest.list @@ -0,0 +1,13 @@ +# Tests related to SVG Animation (using SMIL), focusing on the animateMotion +# element. + +== animateMotion-by-1.svg lime.svg +== animateMotion-from-to-1.svg lime.svg +== animateMotion-rotate-1.svg lime.svg +== animateMotion-rotate-2.svg lime.svg +== animateMotion-values-linear-1.svg animateMotion-values-linear-1-ref.svg +== animateMotion-values-paced-1a.svg animateMotion-values-paced-1-ref.svg +== animateMotion-values-paced-1b.svg animateMotion-values-paced-1-ref.svg + +# Tests involving sub-element +== animateMotion-mpath-targetChange-1.svg lime.svg