<!DOCTYPE html>
<html>
<head>
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
  // Like assert_array_equals, but disregard element order.
  function assert_array_same(actual, expected) {
    assert_array_equals(actual.sort(), expected.sort());
  }

  // Element names:
  const elems_valid = [
    "p", "template", "span", "custom-elements", "potato",

    // Arguments will be stringified, so anything that stringifies to a valid
    // name is also valid. (E.g. null => "null")
    null, undefined, 123
  ];
  const elems_invalid = [
    "", [], ["*"], ["p"]
  ];

  // Attribute names:
  const attrs_valid = [
    "href", "span",
  ];
  const attrs_invalid = [
  ];

  const all_elems = elems_valid.concat(elems_invalid);
  const all_attrs = attrs_valid.concat(attrs_invalid);
  for (const item of ["allowElements", "dropElements", "blockElements"]) {
    test(t => {
      const sanitizer = new Sanitizer({[item]: all_elems});
      assert_array_same(sanitizer.getConfiguration()[item],
                          elems_valid.map(x => "" + x));
    }, `Element names in config item: ${item}`);
  }
  for (const item of ["allowAttributes", "dropAttributes"]) {
    test(t => {
      const sanitizer = new Sanitizer(
          {[item]: Object.fromEntries(all_attrs.map(x => [x, ["*"]]))});
      assert_array_same(Object.keys(sanitizer.getConfiguration()[item]),
                        attrs_valid.map(x => "" + x));
    }, `Attribute names in config item: ${item}`);
  }

  // Quick sanity tests for namespaced elements.
  // Each test case is a duo or triplet:
  // - a Sanitizer config string for an element.
  // - an HTML probe string.
  // - the expected result. (If different from the probe.)
  const SVG_NS = "http://www.w3.org/2000/svg";
  const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
  [
    [ "p", "<p>Hello</p>" ],
    [ "svg", "<svg>Hello</svg>", "Hello" ],
    [ { name: "svg", namespace: SVG_NS }, "<svg>Hello</svg>" ],
    [ "math", "<math>Hello</math>", "Hello" ],
    [ { name: "math", namespace: SVG_NS }, "<math>Hello</math>", "Hello" ],
    [ { name: "math", namespace: MATHML_NS }, "<math>Hello</math>" ],
  ].forEach(([elem, probe, expected], index) => {
    test(t => {
      const sanitizer = new Sanitizer({allowElements: [elem],
        // TODO(https://github.com/WICG/sanitizer-api/issues/167)
        allowUnknownMarkup: true});
      const template = document.createElement("template");
      template.setHTML(probe, {sanitizer});
      assert_equals(template.innerHTML, expected ?? probe);
    }, `Namespaced elements #${index}: allowElements: [${JSON.stringify(elem)}]`);
  });

  // Same for attributes:
  const XLINK_NS = "http://www.w3.org/1999/xlink";
  [
    [ { name: "style", elements: "*" }, "<p style=\"bla\"></p>" ],
    [ { name: "href", elements: "*" }, "<p href=\"bla\"></p>" ],
    [ { name: "xlink:href", elements: "*" }, "<p xlink:href=\"bla\"></p>" ],
    [ { name: "href", namespace: XLINK_NS, elements: "*" }, "<p xlink:href=\"bla\"></p>", "<p></p>" ],
    [ { name: "href", namespace: XLINK_NS, elements: "*" }, "<p href='bla'></p>", "<p></p>" ],
    [ { name: "href", elements: "*" }, "<p xlink:href='bla'></p>", "<p></p>" ],
  ].forEach(([attr, probe, expected], index) => {
    test(t => {
      const sanitizer = new Sanitizer({allowAttributes: [attr],
        // TODO(https://github.com/WICG/sanitizer-api/issues/167)
        allowUnknownMarkup: true});
      const template = document.createElement("template");
      template.setHTML(probe, {sanitizer});
      assert_equals(template.innerHTML, expected ?? probe);
    }, `Namespaced attributes #${index}: allowAttributes: [${JSON.stringify(attr)}]`);
  });

  // Test for namespaced attribute inside namespace element
  test(t => {
    const probe = `<svg><a xlink:href="bla"></a></svg>`;

    const sanitizer = new Sanitizer({
      allowAttributes: [{ name: "href", namespace: XLINK_NS, elements: "*" }],
      allowElements: [{ name: "svg", namespace: SVG_NS }, { name: "a", namespace: SVG_NS }],
      // TODO(https://github.com/WICG/sanitizer-api/issues/167)
      allowUnknownMarkup: true});
    const template = document.createElement("template");
    template.setHTML(probe, {sanitizer});
    assert_equals(template.innerHTML, probe);
  }, "Namespaced attribute xlink:href inside SVG tree");

  // Most element and attribute names are lower-cased, but "foreign content"
  // like SVG and MathML have some mixed-cased names.
  [
    [ "feBlend", "<feBlend></feBlend>" ],
    [ "feColorMatrix", "<feColorMatrix></feColorMatrix>" ],
    [ "textPath", "<textPath></textPath>" ],
  ].forEach(([elem, probe], index) => {
    const sanitize = (elem, probe) => {
      const sanitizer = new Sanitizer({allowElements: [
          { name: "svg", namespace: SVG_NS },
          { name: elem, namespace: SVG_NS }
        ],
        // TODO(https://github.com/WICG/sanitizer-api/issues/167)
        allowUnknownMarkup: true});
      const template = document.createElement("template");
      template.setHTML(`<svg>${probe}</svg>`, {sanitizer});
      return template.content.firstElementChild.innerHTML;
    };
    test(t => {
      assert_equals(sanitize(elem, probe), probe);
    }, `Mixed-case element names #${index}: "svg:${elem}"`);
    test(t => {
      // Lowercase element names should be normalized to mixed-case.
      assert_equals(sanitize(elem.toLowerCase(), probe), probe);
    }, `Lower-case element names #${index}: "svg:${elem.toLowerCase()}"`);
    test(t => {
      assert_not_equals(sanitize(elem.toUpperCase(), probe), probe);
    }, `Upper-case element names #${index}: "svg:${elem.toUpperCase()}"`);
    test(t => {
      const elems = ["svg:" + elem];
      assert_array_equals(
        new Sanitizer({allowElements: elems}).getConfiguration().allowElements,
        elems);
    }, `Mixed case element names #${index}: "${elem}" is preserved in config.`);
  });
</script>
</body>
</html>
