tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

smil-grid.js (7566B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
      2 /* vim: set ts=2 sw=2 sts=2 et: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* Javascript library for dynamically generating a simple SVG/SMIL reftest
      8 * with several copies of the same animation, each seeked to a different time.
      9 */
     10 
     11 // Global variables
     12 const START_TIMES = [ "4.0s",  "3.0s",  "2.7s",
     13                      "2.25s", "2.01s", "1.5s",
     14                      "1.4s",  "1.0s",  "0.5s" ];
     15 
     16 const X_POSNS = [ "20px",  "70px",  "120px",
     17                  "20px",  "70px",  "120px",
     18                  "20px",  "70px",  "120px" ];
     19 
     20 const Y_POSNS = [ "20px",  "20px",  "20px",
     21                  "70px",  "70px",  "70px",
     22                 "120px", "120px", "120px"  ];
     23 
     24 const DURATION = "2s";
     25 const SNAPSHOT_TIME ="3";
     26 const SVGNS = "http://www.w3.org/2000/svg";
     27 
     28 // Convenience wrapper using testAnimatedGrid to make 15pt-by-15pt rects
     29 function testAnimatedRectGrid(animationTagName, animationAttrHashList) {
     30  var targetTagName = "rect";
     31  var targetAttrHash = {"width"  : "15px",
     32                        "height" : "15px" };
     33  testAnimatedGrid(targetTagName,    targetAttrHash,
     34                   animationTagName, animationAttrHashList);
     35 }
     36 
     37 // Convenience wrapper using testAnimatedGrid to make grid of text
     38 function testAnimatedTextGrid(animationTagName, animationAttrHashList) {
     39  var targetTagName = "text";
     40  var targetAttrHash = { };
     41  testAnimatedGrid(targetTagName,    targetAttrHash,
     42                   animationTagName, animationAttrHashList);
     43 }
     44 
     45 // Generates a visual grid of elements of type "targetTagName", with the
     46 // attribute values given in targetAttrHash.  Each generated element has
     47 // exactly one child -- an animation element of type "animationTagName", with
     48 // the attribute values given in animationAttrHash.
     49 function testAnimatedGrid(targetTagName,    targetAttrHash,
     50                          animationTagName, animationAttrHashList) {
     51    // SANITY CHECK
     52  const numElementsToMake = START_TIMES.length;
     53  if (X_POSNS.length != numElementsToMake ||
     54      Y_POSNS.length != numElementsToMake) {
     55    return;
     56  }
     57 
     58  for (var i = 0; i < animationAttrHashList.length; i++) {
     59    var animationAttrHash = animationAttrHashList[i];
     60    // Default to fill="freeze" so we can test the final value of the animation
     61    if (!animationAttrHash["fill"]) {
     62      animationAttrHash["fill"] = "freeze";
     63    }
     64  }
     65 
     66  // Build the grid!
     67  var svg = document.documentElement;
     68  for (var i = 0; i < numElementsToMake; i++) {
     69    // Build target & animation elements
     70    var targetElem = buildElement(targetTagName, targetAttrHash);
     71    for (var j = 0; j < animationAttrHashList.length; j++) {
     72      var animationAttrHash = animationAttrHashList[j];
     73      var animElem = buildElement(animationTagName, animationAttrHash);
     74 
     75      // Customize them using global constant values
     76      targetElem.setAttribute("x", X_POSNS[i]);
     77      targetElem.setAttribute("y", Y_POSNS[i]);
     78      animElem.setAttribute("begin", START_TIMES[i]);
     79      animElem.setAttribute("dur", DURATION);
     80 
     81      // Append to target
     82      targetElem.appendChild(animElem);
     83    }
     84    // Insert target into DOM
     85    svg.appendChild(targetElem);
     86  }
     87 
     88  // Take snapshot
     89  setTimeAndSnapshot(SNAPSHOT_TIME, true);
     90 }
     91 
     92 // Generates a visual grid of elements of type |graphicElemTagName|, with the
     93 // attribute values given in |graphicElemAttrHash|. This is a variation of the
     94 // above function. We use <defs> to include the reference elements because
     95 // some animatable properties are only applicable to some specific elements
     96 // (e.g. feFlood, stop), so then we apply an animation element of type
     97 // |animationTagName|, with the attribute values given in |animationAttrHash|,
     98 // to those specific elements. |defTagNameList| is an array of tag names.
     99 // We will create elements hierarchically according to this array. The first tag
    100 // in |defTagNameList| is the outer-most one in <defs>, and the last tag is the
    101 // inner-most one and it is the target to which the animation element will be
    102 // applied. We visualize the effect of our animation by referencing each
    103 // animated subtree from some graphical element that we generate. The
    104 // |graphicElemIdValueProperty| parameter provides the name of the CSS property
    105 // that we should use to hook up this reference.
    106 //
    107 // e.g. if a caller passes a defTagNameList of [ "linearGradient", "stop" ],
    108 //      this function will generate the following subtree:
    109 // <defs>
    110 //   <linearGradient id="elem0">
    111 //     <stop>
    112 //       <animate ..../>
    113 //     </stop>
    114 //   </linearGradient>
    115 //   <linearGradient id="elem1">
    116 //     <stop>
    117 //       <animate ..../>
    118 //     </stop>
    119 //   </linearGradient>
    120 //
    121 //   <!--- more similar linearGradients here, up to START_TIMES.length -->
    122 // </defs>
    123 function testAnimatedGridWithDefs(graphicElemTagName,
    124                                  graphicElemAttrHash,
    125                                  graphicElemIdValuedProperty,
    126                                  defTagNameList,
    127                                  animationTagName,
    128                                  animationAttrHashList) {
    129  // SANITY CHECK
    130  const numElementsToMake = START_TIMES.length;
    131  if (X_POSNS.length != numElementsToMake ||
    132      Y_POSNS.length != numElementsToMake) {
    133    return;
    134  }
    135 
    136  if (defTagNameList.length == 0) {
    137    return;
    138  }
    139 
    140  for (var i = 0; i < animationAttrHashList.length; i++) {
    141    var animationAttrHash = animationAttrHashList[i];
    142    // Default to fill="freeze" so we can test the final value of the animation
    143    if (!animationAttrHash["fill"]) {
    144      animationAttrHash["fill"] = "freeze";
    145    }
    146  }
    147 
    148  var svg = document.documentElement;
    149 
    150  // Build defs element.
    151  var defs = buildElement('defs');
    152  for (var i = 0; i < numElementsToMake; i++) {
    153    // This will track the innermost element in our subtree:
    154    var innerElement = defs;
    155 
    156    for (var defIdx = 0; defIdx < defTagNameList.length; ++defIdx) {
    157      // Set an ID on the first level of nesting (on child of defs):
    158      var attrs = defIdx == 0 ? { "id": "elem" + i } : {};
    159 
    160      var newElem = buildElement(defTagNameList[defIdx], attrs);
    161      innerElement.appendChild(newElem);
    162      innerElement = newElem;
    163    }
    164 
    165    for (var j = 0; j < animationAttrHashList.length; ++j) {
    166      var animationAttrHash = animationAttrHashList[j];
    167      var animElem = buildElement(animationTagName, animationAttrHash);
    168      animElem.setAttribute("begin", START_TIMES[i]);
    169      animElem.setAttribute("dur", DURATION);
    170      innerElement.appendChild(animElem);
    171    }
    172  }
    173  svg.appendChild(defs);
    174 
    175  // Build the grid!
    176  for (var i = 0; i < numElementsToMake; ++i) {
    177    var graphicElem = buildElement(graphicElemTagName, graphicElemAttrHash);
    178    graphicElem.setAttribute("x", X_POSNS[i]);
    179    graphicElem.setAttribute("y", Y_POSNS[i]);
    180    graphicElem.setAttribute("style", graphicElemIdValuedProperty +
    181                                      ":url(#elem" + i + ")");
    182    svg.appendChild(graphicElem);
    183  }
    184 
    185  // Take snapshot
    186  setTimeAndSnapshot(SNAPSHOT_TIME, true);
    187 }
    188 
    189 function buildElement(tagName, attrHash) {
    190  var elem = document.createElementNS(SVGNS, tagName);
    191  for (var attrName in attrHash) {
    192    var attrValue = attrHash[attrName];
    193    elem.setAttribute(attrName, attrValue);
    194  }
    195  // If we're creating a text node, populate it with some text.
    196  if (tagName == "text") {
    197    elem.appendChild(document.createTextNode("abc"));
    198  }
    199  return elem;
    200 }