<!DOCTYPE html>
<html>
  <head>
    <script src="../../resources/js-test.js"></script>
    <script src="resources/svgtags.js"></script>
  </head>
  <body>
    <div id="console"></div>
    <div id="container" style="position: fixed;"></div>

    <script>
      var svgNS = "http://www.w3.org/2000/svg";

      function createNode(tag, container) {
        var node = document.createElementNS(svgNS, tag);
        container.appendChild(node);
        return node;
      }

      function createValidNode(tag, container, createAncestors) {
        var realContainer = container;

        if (createAncestors && SvgTags[tag].needParent)
          realContainer = createValidNode(SvgTags[tag].needParent, container, true);

        var node = createNode(tag, realContainer);
        for (var attr in SvgTags[tag].needAttr)
          node.setAttribute(attr, SvgTags[tag].needAttr[attr]);

        var requiredChildren = SvgTags[tag].needChild || [];
        for (var childTag of requiredChildren)
          createValidNode(childTag, node, false);

        return node;
      }

      function expandClasses(tags) {
        var expandedTags = [];
        for (var tag of tags)
          Array.prototype.push.apply(expandedTags, SvgTagClasses[tag] || [tag]);
        return expandedTags;
      }

      function createsRenderer(parentTag, childTag) {
        var divContainer = document.getElementById('container');
        var svgContainer = createNode('svg', divContainer);
        var parentNode = createValidNode(parentTag, svgContainer, true);
        createValidNode(childTag, parentNode, false);

        var drt = internals.elementLayoutTreeAsText(divContainer);
        divContainer.removeChild(svgContainer);

        // Skip to the line after the LayoutSVGRoot.
        var skip = drt.indexOf('LayoutSVGRoot');
        skip = drt.indexOf('\n', skip) + 1;
        // Skip the line with the parent tag.
        skip = drt.indexOf('\n', skip) + 1;

        return drt.substr(skip).search(new RegExp('\\{' + childTag + '\\}|\\[' + childTag + '[\\] ]')) > 0;
      }

      function validateTag(tag, validChildren) {
        var expandedValidChildren = expandClasses(validChildren);
        var unexpectedValid = [];
        var unexpectedInvalid = [];

        for (var childTag in SvgTags) {
          // Only testing elements with renderers.
          if (SvgTags[childTag].noRenderer)
            continue;

          if (createsRenderer(tag, childTag)) {
            if (expandedValidChildren.indexOf(childTag) < 0)
              unexpectedValid.push(childTag);
          } else {
            if (expandedValidChildren.indexOf(childTag) >= 0)
              unexpectedInvalid.push(childTag);
          }
        }

        var msg = '<' + tag + '>: ';
        var passed = (unexpectedValid.length == 0 && unexpectedInvalid.length == 0);
        if (passed) {
          msg += '[' + validChildren + ']';
          testPassed(msg);
        } else {
          if (unexpectedValid.length > 0)
            msg += 'unexpected valid [' + unexpectedValid + '] ';
          if (unexpectedInvalid.length > 0)
            msg += 'unexpected invalid [' + unexpectedInvalid + ']';
          testFailed(msg);
        }
      }


      if (!window.testRunner || !window.internals)
        testFailed('this test requires DumpRenderTree.');

      description('This test validates renderer instantiation against the SVG content model.');

      validateTag('filter', [
        // http://dev.w3.org/fxtf/filters/#FilterElement
        'CLASS_DESCRIPTIVE', 'CLASS_FILTER_PRIMITIVE', 'animate', 'set'
      ]);
      validateTag('linearGradient', [
        // https://svgwg.org/svg2-draft/pservers.html#LinearGradientElement
        'CLASS_DESCRIPTIVE', 'CLASS_PAINT_SERVER', 'animate', 'animateTransform', 'script', 'set',
        'stop'
      ]);
      validateTag('g', [
        // https://svgwg.org/svg2-draft/struct.html#GElement
        'CLASS_ANIMATION', 'CLASS_DESCRIPTIVE', 'CLASS_PAINT_SERVER', 'CLASS_SHAPE',
        'CLASS_STRUCTURAL', 'a', 'clipPath', 'cursor', 'filter', 'foreignObject', 'image', 'marker',
        'mask', 'script', 'style', 'switch', 'text', 'view'
      ]);
      validateTag('radialGradient', [
        // https://svgwg.org/svg2-draft/pservers.html#RadialGradientElement
        'CLASS_DESCRIPTIVE', 'CLASS_PAINT_SERVER', 'animate', 'animateTransform', 'script', 'set',
        'stop'
      ]);
      validateTag('svg', [
        // https://svgwg.org/svg2-draft/struct.html#SVGElement
        'CLASS_ANIMATION', 'CLASS_DESCRIPTIVE', 'CLASS_PAINT_SERVER', 'CLASS_SHAPE',
        'CLASS_STRUCTURAL', 'a', 'clipPath', 'cursor', 'filter', 'foreignObject', 'image', 'marker',
        'mask', 'script', 'style', 'switch', 'text', 'view'
      ]);
    </script>
  </body>
</html>
