diff options
Diffstat (limited to 'layout/reftests/svg/smil/smil-grid.js')
-rw-r--r-- | layout/reftests/svg/smil/smil-grid.js | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/layout/reftests/svg/smil/smil-grid.js b/layout/reftests/svg/smil/smil-grid.js new file mode 100644 index 0000000000..0c8036ea27 --- /dev/null +++ b/layout/reftests/svg/smil/smil-grid.js @@ -0,0 +1,200 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Javascript library for dynamically generating a simple SVG/SMIL reftest + * with several copies of the same animation, each seeked to a different time. + */ + +// Global variables +const START_TIMES = [ "4.0s", "3.0s", "2.7s", + "2.25s", "2.01s", "1.5s", + "1.4s", "1.0s", "0.5s" ]; + +const X_POSNS = [ "20px", "70px", "120px", + "20px", "70px", "120px", + "20px", "70px", "120px" ]; + +const Y_POSNS = [ "20px", "20px", "20px", + "70px", "70px", "70px", + "120px", "120px", "120px" ]; + +const DURATION = "2s"; +const SNAPSHOT_TIME ="3"; +const SVGNS = "http://www.w3.org/2000/svg"; + +// Convenience wrapper using testAnimatedGrid to make 15pt-by-15pt rects +function testAnimatedRectGrid(animationTagName, animationAttrHashList) { + var targetTagName = "rect"; + var targetAttrHash = {"width" : "15px", + "height" : "15px" }; + testAnimatedGrid(targetTagName, targetAttrHash, + animationTagName, animationAttrHashList); +} + +// Convenience wrapper using testAnimatedGrid to make grid of text +function testAnimatedTextGrid(animationTagName, animationAttrHashList) { + var targetTagName = "text"; + var targetAttrHash = { }; + testAnimatedGrid(targetTagName, targetAttrHash, + animationTagName, animationAttrHashList); +} + +// Generates a visual grid of elements of type "targetTagName", with the +// attribute values given in targetAttrHash. Each generated element has +// exactly one child -- an animation element of type "animationTagName", with +// the attribute values given in animationAttrHash. +function testAnimatedGrid(targetTagName, targetAttrHash, + animationTagName, animationAttrHashList) { + // SANITY CHECK + const numElementsToMake = START_TIMES.length; + if (X_POSNS.length != numElementsToMake || + Y_POSNS.length != numElementsToMake) { + return; + } + + for (var i = 0; i < animationAttrHashList.length; i++) { + var animationAttrHash = animationAttrHashList[i]; + // Default to fill="freeze" so we can test the final value of the animation + if (!animationAttrHash["fill"]) { + animationAttrHash["fill"] = "freeze"; + } + } + + // Build the grid! + var svg = document.documentElement; + for (var i = 0; i < numElementsToMake; i++) { + // Build target & animation elements + var targetElem = buildElement(targetTagName, targetAttrHash); + for (var j = 0; j < animationAttrHashList.length; j++) { + var animationAttrHash = animationAttrHashList[j]; + var animElem = buildElement(animationTagName, animationAttrHash); + + // Customize them using global constant values + targetElem.setAttribute("x", X_POSNS[i]); + targetElem.setAttribute("y", Y_POSNS[i]); + animElem.setAttribute("begin", START_TIMES[i]); + animElem.setAttribute("dur", DURATION); + + // Append to target + targetElem.appendChild(animElem); + } + // Insert target into DOM + svg.appendChild(targetElem); + } + + // Take snapshot + setTimeAndSnapshot(SNAPSHOT_TIME, true); +} + +// Generates a visual grid of elements of type |graphicElemTagName|, with the +// attribute values given in |graphicElemAttrHash|. This is a variation of the +// above function. We use <defs> to include the reference elements because +// some animatable properties are only applicable to some specific elements +// (e.g. feFlood, stop), so then we apply an animation element of type +// |animationTagName|, with the attribute values given in |animationAttrHash|, +// to those specific elements. |defTagNameList| is an array of tag names. +// We will create elements hierarchically according to this array. The first tag +// in |defTagNameList| is the outer-most one in <defs>, and the last tag is the +// inner-most one and it is the target to which the animation element will be +// applied. We visualize the effect of our animation by referencing each +// animated subtree from some graphical element that we generate. The +// |graphicElemIdValueProperty| parameter provides the name of the CSS property +// that we should use to hook up this reference. +// +// e.g. if a caller passes a defTagNameList of [ "linearGradient", "stop" ], +// this function will generate the following subtree: +// <defs> +// <linearGradient id="elem0"> +// <stop> +// <animate ..../> +// </stop> +// </linearGradient> +// <linearGradient id="elem1"> +// <stop> +// <animate ..../> +// </stop> +// </linearGradient> +// +// <!--- more similar linearGradients here, up to START_TIMES.length --> +// </defs> +function testAnimatedGridWithDefs(graphicElemTagName, + graphicElemAttrHash, + graphicElemIdValuedProperty, + defTagNameList, + animationTagName, + animationAttrHashList) { + // SANITY CHECK + const numElementsToMake = START_TIMES.length; + if (X_POSNS.length != numElementsToMake || + Y_POSNS.length != numElementsToMake) { + return; + } + + if (defTagNameList.length == 0) { + return; + } + + for (var i = 0; i < animationAttrHashList.length; i++) { + var animationAttrHash = animationAttrHashList[i]; + // Default to fill="freeze" so we can test the final value of the animation + if (!animationAttrHash["fill"]) { + animationAttrHash["fill"] = "freeze"; + } + } + + var svg = document.documentElement; + + // Build defs element. + var defs = buildElement('defs'); + for (var i = 0; i < numElementsToMake; i++) { + // This will track the innermost element in our subtree: + var innerElement = defs; + + for (var defIdx = 0; defIdx < defTagNameList.length; ++defIdx) { + // Set an ID on the first level of nesting (on child of defs): + var attrs = defIdx == 0 ? { "id": "elem" + i } : {}; + + var newElem = buildElement(defTagNameList[defIdx], attrs); + innerElement.appendChild(newElem); + innerElement = newElem; + } + + for (var j = 0; j < animationAttrHashList.length; ++j) { + var animationAttrHash = animationAttrHashList[j]; + var animElem = buildElement(animationTagName, animationAttrHash); + animElem.setAttribute("begin", START_TIMES[i]); + animElem.setAttribute("dur", DURATION); + innerElement.appendChild(animElem); + } + } + svg.appendChild(defs); + + // Build the grid! + for (var i = 0; i < numElementsToMake; ++i) { + var graphicElem = buildElement(graphicElemTagName, graphicElemAttrHash); + graphicElem.setAttribute("x", X_POSNS[i]); + graphicElem.setAttribute("y", Y_POSNS[i]); + graphicElem.setAttribute("style", graphicElemIdValuedProperty + + ":url(#elem" + i + ")"); + svg.appendChild(graphicElem); + } + + // Take snapshot + setTimeAndSnapshot(SNAPSHOT_TIME, true); +} + +function buildElement(tagName, attrHash) { + var elem = document.createElementNS(SVGNS, tagName); + for (var attrName in attrHash) { + var attrValue = attrHash[attrName]; + elem.setAttribute(attrName, attrValue); + } + // If we're creating a text node, populate it with some text. + if (tagName == "text") { + elem.appendChild(document.createTextNode("abc")); + } + return elem; +} |