summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest/webcomponents/test_custom_element_when_defined.html
blob: 04cca315818444d948dcebe1e021eac359c68e1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1275839
-->
<head>
  <title>Test custom elements whenDefined function.</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1275839">Bug 1275839</a>
<iframe id="iframe"></iframe>
<script>

SimpleTest.waitForExplicitFinish();

const testWindow = iframe.contentDocument.defaultView;
const customElements = testWindow.customElements;
const expectSyntaxError = 'SyntaxError';

function testCustomElementsAvailable() {
  ok('customElements' in testWindow, '"window.customElements" exists');
  ok('define' in customElements, '"window.customElements.define" exists');
  ok('whenDefined' in customElements, '"window.customElements.get" exists');
}

function testCustomElementsPromiseEqually() {
  // 4. If map does not contain an entry with key name, create an entry in
  // map with key name and whose value is a new promise.
  let promiseElement1 = customElements.whenDefined('x-element1');
  let promiseElement2 = customElements.whenDefined('x-element2');

  ok(promiseElement1 instanceof testWindow.Promise &&
     promiseElement2 instanceof testWindow.Promise,
     "promiseElement1 and promiseElement2 should return promises.");

  // 5. Let promise be the value of the entry in map with key name.
  // 6. Return promise
  let sameAsPromiseElement1 = customElements.whenDefined('x-element1');

  ok(sameAsPromiseElement1 instanceof testWindow.Promise,
     "sameAsPromiseElement1 should return promise.");
  is(promiseElement1, sameAsPromiseElement1,
     "Same name should return same promise.");
  isnot(promiseElement1, promiseElement2,
        "whenDefined() returns different promises for different names.");
}

function testCustomElementsNameDefined() {
  let name = 'x-foo';
  let beforeDefinedPromise = customElements.whenDefined(name);

  customElements.define(name, class {});

  // 2. If this CustomElementRegistry contains an entry with name name,
  // then return a new promise resolved with undefined and abort these
  // steps.
  return beforeDefinedPromise.then(() => {
    let afterDefinedPromise = customElements.whenDefined(name);
    isnot(beforeDefinedPromise, afterDefinedPromise,
          "When name is defined, we should have a new promise.");

    let newPromise = customElements.whenDefined(name);
    isnot(afterDefinedPromise, newPromise,
          "Once name is defined, whenDefined() always returns a new promise.");
    return Promise.all([newPromise, afterDefinedPromise]);
  });
}

function testCustomElementsNameNotDefined() {
  let isResolved = false;
  customElements.whenDefined('x-name-not-defined').then(() => {
    isResolved = true;
  });

  return new Promise((aResolve, aReject) => {
    setTimeout(
      function() {
        ok(!isResolved, "Promise for not defined name should not be resolved.");
        aResolve();
      }, 0);
  });
}

function testCustomElementsInvalidName() {
  let invalidCustomElementNames = [
    undefined,
    null,
    '',
    '-',
    'a',
    'input',
    'mycustomelement',
    'A',
    'A-',
    '0-',
    'a-A',
    'a-Z',
    'A-a',
    'a-a\u00D7',
    'a-a\u3000',
    'a-a\uDB80\uDC00', // Surrogate pair U+F0000
    // name must not be any of the hyphen-containing element names.
    'annotation-xml',
    'color-profile',
    'font-face',
    'font-face-src',
    'font-face-uri',
    'font-face-format',
    'font-face-name',
    'missing-glyph',
  ];

  let promises = [];
  invalidCustomElementNames.forEach(name => {
    const expectSyntaxErrorPromise = customElements.whenDefined(name);

    promises.push(expectSyntaxErrorPromise.then(() => {
      ok(false, "CustomElements with invalid name should throw SyntaxError.");
    }, (ex) => {
      is(ex.name, expectSyntaxError,
         "CustomElements with invalid name should throw SyntaxError.");
    }));
  });

  return Promise.all(promises);
}

Promise.resolve()
 .then(() => testCustomElementsAvailable())
 .then(() => testCustomElementsPromiseEqually())
 .then(() => testCustomElementsNameDefined())
 .then(() => testCustomElementsNameNotDefined())
 .then(() => testCustomElementsInvalidName())
 .then(() => SimpleTest.finish());

</script>
</body>
</html>