tor-browser

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

math-global-event-handlers.tentative.html (5810B)


      1 <!DOCTYPE html>
      2 <title>MathMLElement GlobalEventHandlers</title>
      3 <link rel="author" title="Brian Kardell" href="mailto:bkardell@igalia.com" />
      4 <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
      5 <link rel="help" href="https://html.spec.whatwg.org/multipage/#event-handler-idl-attributes"/>
      6 <link rel="help" href="https://html.spec.whatwg.org/multipage/#event-handler-content-attributes"/>
      7 <meta name="timeout" content="long">
      8 <script src="/resources/testharness.js"></script>
      9 <script src="/resources/testharnessreport.js"></script>
     10 <script src="/resources/WebIDLParser.js"></script>
     11 
     12 <script>
     13  "use strict";
     14 
     15  // The prefixed animation events are special; their event types are
     16  // camel-case.
     17  const prefixedAnimationAttributeToEventType = new Map([
     18    ["webkitanimationend", "webkitAnimationEnd"],
     19    ["webkitanimationiteration", "webkitAnimationIteration"],
     20    ["webkitanimationstart", "webkitAnimationStart"],
     21    ["webkittransitionend", "webkitTransitionEnd"],
     22  ]);
     23 
     24  // basic pattern lifted from /html/webappapis/scripting/events/event-handler-all-global-events.html
     25  promise_setup(async function() {
     26    const res = await fetch("/interfaces/html.idl");
     27    const htmlIDL = await res.text();
     28    // Parsing the whole IDL file is slow, so use a small regexp to extract only
     29    // the part that is relevant for this test.
     30    const parsedHTMLIDL = WebIDL2.parse(htmlIDL.
     31      match(/^interface mixin GlobalEventHandlers {[^{}]*};$/m)[0]);
     32    const globalEventHandlers = parsedHTMLIDL.find(
     33      idl => idl.name === "GlobalEventHandlers"
     34    );
     35 
     36    // onerror is too special
     37    const names = globalEventHandlers.members
     38      .map(member => member.name)
     39      .filter(name => name !== "onerror");
     40 
     41    for (const name of names) {
     42      const withoutOn = name.substring(2);
     43 
     44      promise_test(async () => {
     45        const location = MathMLElement.prototype;
     46        assert_true(
     47          location.hasOwnProperty(name),
     48          `${location.constructor.name} has an own property named "${name}"`
     49        );
     50 
     51        assert_false(
     52          name in Element.prototype,
     53          `Element.prototype must not contain a "${name}" property`
     54        );
     55      }, `${name}: must be on the appropriate locations for GlobalEventHandlers`);
     56 
     57      promise_test(async () => {
     58        const location = document.createElementNS(
     59          "http://www.w3.org/1998/Math/MathML",
     60          "math"
     61        );
     62 
     63        assert_equals(
     64          location[name],
     65          null,
     66          `The default value of the property is null for a ${
     67            location.constructor.name
     68          } instance`
     69        );
     70      }, `${name}: the default value must be null`);
     71 
     72      promise_test(async () => {
     73        const div = document.createElement("div");
     74        div.insertAdjacentHTML("beforeend", `<math ${name}="window.${name}Happened1 = true;"></math>`);
     75        const compiledHandler = div.firstElementChild[name];
     76        assert_equals(
     77          typeof compiledHandler,
     78          "function",
     79          `The ${name} property must be a function`
     80        );
     81        compiledHandler();
     82        assert_true(
     83          window[`${name}Happened1`],
     84          "Calling the handler must run the code"
     85        );
     86      }, `${name}: the content attribute must be compiled into a function as the corresponding property`);
     87 
     88      promise_test(async () => {
     89        const el = document.createElementNS(
     90          "http://www.w3.org/1998/Math/MathML",
     91          "math"
     92        );
     93        assert_equals(el[name], null, `The ${name} property must be null (no attribute)`);
     94 
     95        el.setAttribute(name, `window.${name}Happened2 = true;`);
     96        const compiledHandler = el[name];
     97        assert_equals(
     98          typeof compiledHandler,
     99          "function",
    100          `The ${name} property must be a function (set attribute)`
    101        );
    102        compiledHandler();
    103        assert_true(
    104          window[`${name}Happened2`],
    105          "Calling the handler must run the code (set attribute)"
    106        );
    107 
    108        window[`${name}Happened2`] = false;
    109        const clonedEl = el.cloneNode(true);
    110        const clonedCompiledHandler = clonedEl[name];
    111        assert_equals(
    112          typeof clonedCompiledHandler,
    113          "function",
    114          `The ${name} property must be a function (clone node)`
    115        );
    116        clonedCompiledHandler();
    117        assert_true(
    118          window[`${name}Happened2`],
    119          "Calling the handler must run the code (clone node)"
    120        );
    121 
    122        el.setAttribute(name, `window.${name}Happened3 = true;`);
    123        const newCompiledHandler = el[name];
    124        assert_equals(
    125          typeof newCompiledHandler,
    126          "function",
    127          `The ${name} property must be a function (modify attribute)`
    128        );
    129        newCompiledHandler();
    130        assert_true(
    131          window[`${name}Happened3`],
    132          "Calling the handler must run the code (modify attribute)"
    133        );
    134 
    135        el.removeAttribute(name);
    136        assert_equals(el[name], null, `The ${name} property must be null (remove attribute)`);
    137      }, `${name}: dynamic changes on the attribute`);
    138 
    139      promise_test(async () => {
    140        const element = document.createElementNS(
    141          "http://www.w3.org/1998/Math/MathML",
    142          "math"
    143        );
    144        let target = undefined;
    145        element[name] = (e) => { target = e.currentTarget; }
    146        let eventType = withoutOn;
    147        if (prefixedAnimationAttributeToEventType.has(eventType)) {
    148          eventType = prefixedAnimationAttributeToEventType.get(eventType);
    149        }
    150        element.dispatchEvent(new Event(eventType));
    151        assert_equals(target, element, "The event must be fired at the <math> element");
    152      }, `${name}: dispatching an Event at a <math> element must trigger element.${name}`);
    153    }
    154  });
    155 </script>