How to use shadowRoot method in Webdriverio

Best JavaScript code snippet using webdriverio-monorepo

Run Webdriverio automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

rerender.js

Source: rerender.js Github

copy
1/**
2 * @license
3 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
4 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7 * Code distributed by Google as part of the polymer project is also
8 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 */
10
11suite('Shadow DOM rerender', function() {
12
13  var unsafeUnwrap = ShadowDOMPolyfill.unsafeUnwrap;
14  var unwrap = ShadowDOMPolyfill.unwrap;
15
16  function getVisualInnerHtml(el) {
17    el.offsetWidth;
18    return unwrap(el).innerHTML;
19  }
20
21  test('No <content> nor <shadow>', function() {
22    var host = document.createElement('div');
23    host.innerHTML = '<a></a>';
24    var a = host.firstChild;
25
26    var shadowRoot = host.createShadowRoot();
27    shadowRoot.textContent = 'text';
28    var textNode = shadowRoot.firstChild;
29
30    function testRender() {
31
32      assert.strictEqual(getVisualInnerHtml(host), 'text');
33
34      expectStructure(host, {
35        firstChild: a,
36        lastChild: a
37      });
38
39      expectStructure(a, {
40        parentNode: host
41      });
42
43      expectStructure(shadowRoot, {
44        firstChild: textNode,
45        lastChild: textNode
46      });
47
48      expectStructure(textNode, {
49        parentNode: shadowRoot
50      });
51    }
52
53    testRender();
54    testRender();
55  });
56
57  test('<content>', function() {
58    var host = document.createElement('div');
59    host.innerHTML = '<a></a>';
60    var a = host.firstChild;
61
62    var shadowRoot = host.createShadowRoot();
63    shadowRoot.innerHTML = '<content></content>';
64    var content = shadowRoot.firstChild;
65
66    function testRender() {
67      assert.strictEqual(getVisualInnerHtml(host), '<a></a>');
68
69      expectStructure(host, {
70        firstChild: a,
71        lastChild: a
72      });
73
74      expectStructure(a, {
75        parentNode: host
76      });
77
78      expectStructure(shadowRoot, {
79        firstChild: content,
80        lastChild: content
81      });
82
83      expectStructure(content, {
84        parentNode: shadowRoot
85      });
86    }
87
88    testRender();
89    testRender();
90  });
91
92  test('<content> with fallback', function() {
93    var host = document.createElement('div');
94    host.innerHTML = '<a></a>';
95    var a = host.firstChild;
96
97    var shadowRoot = host.createShadowRoot();
98    shadowRoot.innerHTML = '<content select="b">fallback</content>';
99    var content = shadowRoot.firstChild;
100    var fallback = content.firstChild;
101
102    function testRender() {
103      assert.strictEqual(getVisualInnerHtml(host), 'fallback');
104
105      expectStructure(host, {
106        firstChild: a,
107        lastChild: a
108      });
109
110      expectStructure(a, {
111        parentNode: host
112      });
113
114      expectStructure(shadowRoot, {
115        firstChild: content,
116        lastChild: content
117      });
118
119      expectStructure(content, {
120        parentNode: shadowRoot,
121        firstChild: fallback,
122        lastChild: fallback
123      });
124
125      expectStructure(fallback, {
126        parentNode: content
127      });
128    }
129
130    testRender();
131    testRender();
132  });
133
134  test('<shadow>', function() {
135    var host = document.createElement('div');
136    host.innerHTML = '<a></a>';
137    var a = host.firstChild;
138
139    var shadowRoot = host.createShadowRoot();
140    shadowRoot.innerHTML = '<shadow></shadow>';
141    var shadow = shadowRoot.firstChild;
142
143    function testRender() {
144      assert.strictEqual(getVisualInnerHtml(host), '<a></a>');
145
146      expectStructure(host, {
147        firstChild: a,
148        lastChild: a
149      });
150
151      expectStructure(a, {
152        parentNode: host
153      });
154
155      expectStructure(shadowRoot, {
156        firstChild: shadow,
157        lastChild: shadow
158      });
159
160      expectStructure(shadow, {
161        parentNode: shadowRoot
162      });
163    }
164
165    testRender();
166    testRender();
167  });
168
169  test('<shadow> fallback support has been removed', function() {
170    var host = document.createElement('div');
171    host.innerHTML = '<a></a>';
172    var a = host.firstChild;
173
174    var shadowRoot = host.createShadowRoot();
175    shadowRoot.innerHTML = '<shadow>fallback</shadow>';
176    var shadow = shadowRoot.firstChild;
177    var fallback = shadow.firstChild;
178
179    function testRender() {
180      assert.strictEqual(getVisualInnerHtml(host), '<a></a>');
181
182      expectStructure(host, {
183        firstChild: a,
184        lastChild: a
185      });
186
187      expectStructure(a, {
188        parentNode: host
189      });
190
191      expectStructure(shadowRoot, {
192        firstChild: shadow,
193        lastChild: shadow
194      });
195
196      expectStructure(shadow, {
197        parentNode: shadowRoot,
198        firstChild: fallback,
199        lastChild: fallback
200      });
201
202      expectStructure(fallback, {
203        parentNode: shadow
204      });
205    }
206
207    testRender();
208    testRender();
209  });
210
211  test('<shadow> with nested shadow roots', function() {
212    var host = document.createElement('div');
213    host.innerHTML = '<a></a>';
214    var a = host.firstChild;
215
216    var oldestShadowRoot = host.createShadowRoot();
217    oldestShadowRoot.textContent = 'text';
218    var textNode = oldestShadowRoot.firstChild;
219
220    var youngestShadowRoot = host.createShadowRoot();
221    youngestShadowRoot.innerHTML = '<shadow></shadow>';
222    var shadow = youngestShadowRoot.firstChild;
223
224    function testRender() {
225      assert.strictEqual(getVisualInnerHtml(host), 'text');
226
227      expectStructure(host, {
228        firstChild: a,
229        lastChild: a
230      });
231
232      expectStructure(a, {
233        parentNode: host
234      });
235
236      expectStructure(oldestShadowRoot, {
237        firstChild: textNode,
238        lastChild: textNode
239      });
240
241      expectStructure(textNode, {
242        parentNode: oldestShadowRoot
243      });
244
245      expectStructure(youngestShadowRoot, {
246        firstChild: shadow,
247        lastChild: shadow
248      });
249
250      expectStructure(shadow, {
251        parentNode: youngestShadowRoot
252      });
253    }
254
255    testRender();
256    testRender();
257  });
258
259  suite('Mutate logical DOM', function() {
260    test('removeAllChildNodes - mutate host', function() {
261      var host = document.createElement('div');
262      host.innerHTML = '<a>Hello</a>';
263
264      var shadowRoot = host.createShadowRoot();
265      shadowRoot.innerHTML = '<content>fallback</content>';
266
267      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
268
269      host.firstChild.textContent = '';
270
271      assert.strictEqual(getVisualInnerHtml(host), '<a></a>');
272
273      host.textContent = '';
274      assert.strictEqual(getVisualInnerHtml(host), 'fallback');
275    });
276
277    test('removeAllChildNodes - mutate shadow', function() {
278      var host = document.createElement('div');
279      host.innerHTML = '<a>Hello</a>';
280
281      var shadowRoot = host.createShadowRoot();
282      shadowRoot.innerHTML = '<content></content><b>after</b>';
283
284      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a><b>after</b>');
285
286      shadowRoot.lastChild.textContent = '';
287
288      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a><b></b>');
289
290      shadowRoot.textContent = '';
291      assert.strictEqual(getVisualInnerHtml(host), '');
292    });
293
294    test('removeAllChildNodes - mutate shadow fallback', function() {
295      var host = document.createElement('div');
296      host.innerHTML = '<a>Hello</a>';
297
298      var shadowRoot = host.createShadowRoot();
299      shadowRoot.innerHTML = '<content select="xxx"><b>fallback</b></content>';
300
301      assert.strictEqual(getVisualInnerHtml(host), '<b>fallback</b>');
302
303      shadowRoot.firstChild.firstChild.textContent = '';
304
305      assert.strictEqual(getVisualInnerHtml(host), '<b></b>');
306
307      shadowRoot.firstChild.textContent = '';
308
309      assert.strictEqual(getVisualInnerHtml(host), '');
310
311      shadowRoot.textContent = '';
312      assert.strictEqual(getVisualInnerHtml(host), '');
313    });
314
315    test('removeChild - mutate host', function() {
316      var host = document.createElement('div');
317      host.innerHTML = '<a>Hello</a>';
318
319      var shadowRoot = host.createShadowRoot();
320      shadowRoot.innerHTML = '<content>fallback</content>';
321
322      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
323
324      host.firstChild.removeChild(host.firstChild.firstChild);
325
326      assert.strictEqual(getVisualInnerHtml(host), '<a></a>');
327
328      host.removeChild(host.firstChild);
329      assert.strictEqual(getVisualInnerHtml(host), 'fallback');
330    });
331
332    test('removeChild - mutate host 2', function() {
333      var host = document.createElement('div');
334      host.innerHTML = '<a></a><b></b>';
335
336      var shadowRoot = host.createShadowRoot();
337      shadowRoot.innerHTML = '<content>fallback</content>';
338
339      assert.strictEqual(getVisualInnerHtml(host), '<a></a><b></b>');
340
341      host.removeChild(host.lastChild);
342
343      assert.strictEqual(getVisualInnerHtml(host), '<a></a>');
344
345      host.removeChild(host.firstChild);
346      assert.strictEqual(getVisualInnerHtml(host), 'fallback');
347    });
348
349    test('removeChild - mutate shadow', function() {
350      var host = document.createElement('div');
351      host.innerHTML = '<a>Hello</a>';
352
353      var shadowRoot = host.createShadowRoot();
354      shadowRoot.innerHTML = '<content></content><b>after</b>';
355
356      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a><b>after</b>');
357
358
359      shadowRoot.lastChild.removeChild(
360          shadowRoot.lastChild.firstChild);
361
362      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a><b></b>');
363
364      shadowRoot.removeChild(shadowRoot.lastChild);
365      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
366
367      shadowRoot.removeChild(shadowRoot.firstChild);
368      assert.strictEqual(getVisualInnerHtml(host), '');
369    });
370
371    test('setAttribute select', function() {
372      // TODO(arv): DOM bindings for select.
373      var host = document.createElement('div');
374      host.innerHTML = '<a>Hello</a><b>World</b>';
375
376      var shadowRoot = host.createShadowRoot();
377      shadowRoot.innerHTML = '<content select="b">fallback b</content>' +
378                             '<content select="a">fallback a</content>';
379
380      assert.strictEqual(getVisualInnerHtml(host), '<b>World</b><a>Hello</a>');
381
382      shadowRoot.firstChild.setAttribute('select', 'xxx');
383
384      assert.strictEqual(getVisualInnerHtml(host), 'fallback b<a>Hello</a>');
385
386      shadowRoot.firstChild.setAttribute('select', '');
387
388      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a><b>World</b>fallback a');
389    });
390
391    test('appendChild - mutate host', function() {
392      var host = document.createElement('div');
393      host.innerHTML = '<a>Hello</a>';
394
395      var shadowRoot = host.createShadowRoot();
396      shadowRoot.innerHTML = '<content></content>';
397
398      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
399
400      var b = document.createElement('b');
401
402      host.appendChild(b);
403
404      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a><b></b>');
405    });
406
407    test('appendChild - mutate shadow', function() {
408      var host = document.createElement('div');
409      host.innerHTML = '<a>Hello</a>';
410
411      var shadowRoot = host.createShadowRoot();
412      shadowRoot.innerHTML = '<content></content>';
413
414      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
415
416      var b = document.createElement('b');
417
418      shadowRoot.appendChild(b);
419
420      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a><b></b>');
421    });
422
423    test('insertBefore - mutate host', function() {
424      var host = document.createElement('div');
425      host.innerHTML = '<a>Hello</a>';
426      var a = host.firstChild;
427
428      var shadowRoot = host.createShadowRoot();
429      shadowRoot.innerHTML = '<content></content>';
430
431      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
432
433      var b = document.createElement('b');
434
435      host.insertBefore(b, a);
436
437      assert.strictEqual(getVisualInnerHtml(host), '<b></b><a>Hello</a>');
438    });
439
440    test('insertBefore - mutate shadow', function() {
441      var host = document.createElement('div');
442      host.innerHTML = '<a>Hello</a>';
443
444      var shadowRoot = host.createShadowRoot();
445      shadowRoot.innerHTML = '<content></content>';
446      var content = shadowRoot.firstChild;
447
448      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
449
450      var b = document.createElement('b');
451
452      shadowRoot.insertBefore(b, content);
453
454      assert.strictEqual(getVisualInnerHtml(host), '<b></b><a>Hello</a>');
455    });
456
457    test('replaceChild - mutate host', function() {
458      var host = document.createElement('div');
459      host.innerHTML = '<a>Hello</a>';
460      var a = host.firstChild;
461
462      var shadowRoot = host.createShadowRoot();
463      shadowRoot.innerHTML = '<content></content>';
464
465      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
466
467      var b = document.createElement('b');
468
469      host.replaceChild(b, a);
470
471      assert.strictEqual(getVisualInnerHtml(host), '<b></b>');
472    });
473
474    test('replaceChild - mutate shadow', function() {
475      var host = document.createElement('div');
476      host.innerHTML = '<a>Hello</a>';
477
478      var shadowRoot = host.createShadowRoot();
479      shadowRoot.innerHTML = '<content></content>';
480      var content = shadowRoot.firstChild;
481
482      assert.strictEqual(getVisualInnerHtml(host), '<a>Hello</a>');
483
484      var b = document.createElement('b');
485
486      shadowRoot.replaceChild(b, content);
487
488      assert.strictEqual(getVisualInnerHtml(host), '<b></b>');
489    });
490
491  });
492
493  test('Invalidation', function() {
494    var host = document.createElement('div');
495    host.innerHTML = '<a></a>';
496    var a = host.firstChild;
497
498    var sr = host.createShadowRoot();
499    sr.innerHTML = '<b></b><content></content><c></c>';
500    var b = sr.firstChild;
501    var content = b.nextSibling;
502    var c = sr.lastChild;
503
504    assert.equal(getVisualInnerHtml(host), '<b></b><a></a><c></c>');
505
506    a.textContent = 'x';
507
508    // Don't use getVisualInnerHtml but it does invalidation.
509    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b><a>x</a><c></c>');
510
511    host.appendChild(document.createTextNode('y'));
512    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b><a>x</a><c></c>y');  //dirty
513    host.offsetWidth;
514    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b><a>x</a>y<c></c>');
515
516    sr.appendChild(document.createTextNode('z'));
517    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b><a>x</a>y<c></c>');  //dirty
518    host.offsetWidth;
519    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b><a>x</a>y<c></c>z');
520
521    sr.insertBefore(document.createTextNode('w'), content);
522    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b><a>x</a>y<c></c>z');  // dirty
523    host.offsetWidth;
524    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b>w<a>x</a>y<c></c>z');
525
526    // This case does not need invalidation.
527    // We could make the check a bit more specific (check for nextSibling being
528    // null or a content/shadow).
529    sr.insertBefore(document.createTextNode('v'), c);
530    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b>w<a>x</a>yv<c></c>z');
531    host.offsetWidth;
532    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b>w<a>x</a>yv<c></c>z');
533
534    content.select = '*';
535    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b>w<a>x</a>yv<c></c>z');  // dirty
536    host.offsetWidth;
537    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b>w<a>x</a>v<c></c>z');
538
539    content.setAttribute('SelecT', 'no-match');
540    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b>w<a>x</a>v<c></c>z');  // dirty
541    host.offsetWidth;
542    assert.equal(unsafeUnwrap(host).innerHTML, '<b></b>wv<c></c>z');
543  });
544
545  test('minimal dom changes', function() {
546    var div = document.createElement('div');
547
548    // TODO(jmesserly): ideally we would intercept all of the visual DOM
549    // operations, but that isn't possible because they are captured in the code
550    // as originalInsertBefore/originalRemoveChild, so we only see the calls
551    // inside ShadowRenderer.
552
553    var originalInsertBefore = ShadowDOMPolyfill.originalInsertBefore;
554    var originalRemoveChild = ShadowDOMPolyfill.originalRemoveChild;
555
556    var insertBeforeCount = 0;
557    var removeChildCount = 0;
558
559    ShadowDOMPolyfill.originalInsertBefore = function(newChild, refChild) {
560      insertBeforeCount++;
561      return originalInsertBefore.call(this, newChild, refChild);
562    };
563
564    ShadowDOMPolyfill.originalRemoveChild = function(child) {
565      removeChildCount++;
566      return originalRemoveChild.call(this, child);
567    };
568
569    function reset() {
570      insertBeforeCount = 0;
571      removeChildCount = 0;
572    }
573
574    try {
575
576      var div = document.createElement('div');
577      var a = div.appendChild(document.createElement('a'));
578
579      var sr = div.createShadowRoot();
580      var content = sr.appendChild(document.createElement('content'));
581      var b = sr.appendChild(document.createElement('b'));
582
583      assert.equal(getVisualInnerHtml(div), '<a></a><b></b>');
584
585      assert.equal(insertBeforeCount, 1);
586      assert.equal(removeChildCount, 1);
587
588      reset();
589
590      // Invalidates but does not change the rendered tree.
591      content.select = '*';
592
593      assert.equal(getVisualInnerHtml(div), '<a></a><b></b>');
594      assert.equal(insertBeforeCount, 0);
595      assert.equal(removeChildCount, 0);
596
597      // Does not use our overridden appendChild
598      var c = div.appendChild(document.createElement('c'));
599      assert.equal(insertBeforeCount, 0);
600      assert.equal(removeChildCount, 0);
601
602      assert.equal(getVisualInnerHtml(div), '<a></a><c></c><b></b>');
603      assert.equal(insertBeforeCount, 1);
604      assert.equal(removeChildCount, 1);
605
606      content.select = 'c';
607      reset();
608      assert.equal(getVisualInnerHtml(div), '<c></c><b></b>');
609      assert.equal(insertBeforeCount, 0);
610      assert.equal(removeChildCount, 1);
611
612      content.select = '*';
613      reset();
614      assert.equal(getVisualInnerHtml(div), '<a></a><c></c><b></b>');
615      assert.equal(insertBeforeCount, 1);
616      assert.equal(removeChildCount, 0);
617
618      content.select = 'x';
619      reset();
620      assert.equal(getVisualInnerHtml(div), '<b></b>');
621      assert.equal(insertBeforeCount, 0);
622      assert.equal(removeChildCount, 2);
623
624      content.appendChild(document.createTextNode('fallback'));
625      reset();
626      assert.equal(getVisualInnerHtml(div), 'fallback<b></b>');
627      assert.equal(insertBeforeCount, 1);
628      assert.equal(removeChildCount, 1);  // moved from content
629
630      content.insertBefore(document.createTextNode('more '),
631                           content.firstChild);
632      reset();
633      assert.equal(getVisualInnerHtml(div), 'more fallback<b></b>');
634      assert.equal(insertBeforeCount, 0);  // already inserted before "fallback"
635      assert.equal(removeChildCount, 0);
636
637      content.select = '*';
638      reset();
639      assert.equal(getVisualInnerHtml(div), '<a></a><c></c><b></b>');
640      assert.equal(insertBeforeCount, 2);
641      assert.equal(removeChildCount, 2);
642
643
644    } finally {
645      ShadowDOMPolyfill.originalInsertBefore =  originalInsertBefore;
646      ShadowDOMPolyfill.originalRemoveChild = originalRemoveChild;
647    }
648  });
649});
650
Full Screen

custom-elements.js

Source: custom-elements.js Github

copy
1// Copyright (c) Microsoft Corporation. All rights reserved.
2
3var dialog = require('dialog'),
4    utils = require('utils');
5
6var uniqueIdSuffix = 0;
7var interactiveElementSelector = '* /deep/ input, * /deep/ select, * /deep/ button, * /deep/ textarea';
8
9function initialize(changePanelVisibilityCallback) {
10    registerCustomElement('cordova-panel', {
11        proto: {
12            cordovaCollapsed: {
13                set: function (value) {
14                    var icon = this.shadowRoot.querySelector('.cordova-collapse-icon');
15                    var content = this.shadowRoot.querySelector('.cordova-content');
16                    var isCurrentlyCollapsed = icon.classList.contains('cordova-collapsed');
17
18                    if (value && !isCurrentlyCollapsed) {
19                        collapsePanel(icon, content);
20                    } else if (!value && isCurrentlyCollapsed) {
21                        expandPanel(icon, content);
22                    }
23                }
24            },
25            enabled: {
26                set: function (value) {
27                    if (value) {
28                        if (this.elementEnabledState) {
29                            this.elementEnabledState.forEach(function (enabledState) {
30                                enabledState.element.disabled = enabledState.disabled;
31                            });
32                            delete this.elementEnabledState;
33                            this.shadowRoot.querySelector('.cordova-panel-inner').setAttribute('tabIndex', '0');
34                        }
35                    } else {
36                        this.elementEnabledState = [];
37                        Array.prototype.forEach.call(this.querySelectorAll(interactiveElementSelector), function (element) {
38                            this.elementEnabledState.push({element: element, disabled: element.disabled});
39                            element.disabled = true;
40                        }, this);
41                        this.shadowRoot.querySelector('.cordova-panel-inner').setAttribute('tabIndex', '');
42                    }
43                }
44            },
45            focus: {
46                value: function () {
47                    this.shadowRoot.querySelector('.cordova-panel-inner').focus();
48                }
49            }
50        },
51        initialize: function () {
52            var content = this.shadowRoot.querySelector('.cordova-content');
53            var panelId = this.getAttribute('id');
54            var collapseIcon = this.shadowRoot.querySelector('.cordova-collapse-icon');
55
56            this.shadowRoot.querySelector('.cordova-header .spoken-text span').textContent = this.getAttribute('caption');
57            this.shadowRoot.querySelector('.cordova-header .spoken-text span').setAttribute('title', this.getAttribute('caption'));
58            this.shadowRoot.querySelector('.cordova-header .spoken-text').setAttribute('aria-label', this.getAttribute('spoken-text') || this.getAttribute('caption'));
59
60            function expandCollapse() {
61                var collapsed = collapseIcon.classList.contains('cordova-collapsed');
62
63                if (collapsed) {
64                    expandPanel(collapseIcon, content);
65                } else {
66                    collapsePanel(collapseIcon, content);
67                }
68
69                if (changePanelVisibilityCallback && typeof changePanelVisibilityCallback === 'function') {
70                    changePanelVisibilityCallback(panelId, !collapsed);
71                }
72            }
73
74            this.shadowRoot.querySelector('.cordova-header').addEventListener('click', expandCollapse);
75            this.shadowRoot.querySelector('.cordova-panel-inner').addEventListener('keydown', function (e) {
76                if (e.target === this && e.keyCode === 32 && !isModifyKeyPressed(e)) {
77                    expandCollapse();
78                }
79            });
80        }
81    });
82
83    registerCustomElement('cordova-dialog', {
84        proto: {
85            show: {
86                value: function () {
87                    document.getElementById('popup-window').style.display = '';
88                    this.style.display = '';
89                    this.querySelector('.cordova-panel-inner').focus();
90                }
91            },
92            hide: {
93                value: function () {
94                    document.getElementById('popup-window').style.display = 'none';
95                    this.style.display = 'none';
96                }
97            }
98        },
99        initialize: function () {
100            this.shadowRoot.querySelector('.cordova-header .spoken-text span').textContent = this.getAttribute('caption');
101            this.shadowRoot.querySelector('.cordova-header .spoken-text span').setAttribute('title', this.getAttribute('caption'));
102            this.shadowRoot.querySelector('.cordova-header .spoken-text').setAttribute('aria-label', this.getAttribute('spoken-text') || this.getAttribute('caption'));
103
104            this.shadowRoot.querySelector('.cordova-close-icon').addEventListener('click', function () {
105                dialog.hideDialog();
106            });
107            this.addEventListener('keydown', function (e) {
108                if (e.keyCode === 27 && !isModifyKeyPressed(e)) {
109                    // Escape key pressed
110                    dialog.hideDialog();
111                }
112            });
113        }
114    });
115
116    registerCustomElement('cordova-item-list', {
117        proto: {
118            addItem: {
119                value: function (item) {
120                    this.appendChild(item);
121                    setClassWrapper(this.children);
122                }
123            },
124            removeItem: {
125                value: function (item) {
126                    this.removeChild(this.children[item]);
127                    setClassWrapper(this.children);
128                }
129            }
130        },
131        initialize: function () {
132            this.classList.add('cordova-group');
133        }
134    });
135
136    registerCustomElement('cordova-item', {
137        proto: {
138            focus: {
139                value: function () {
140                    this.shadowRoot.querySelector('.cordova-item-wrapper').focus();
141                }
142            }
143        },
144        initialize: function () {
145            this.classList.add('cordova-group');
146
147            this.addEventListener('mousedown', function () {
148                var that = this;
149                window.setTimeout(function () {
150                    if (document.activeElement !== that) {
151                        that.focus();
152                    }
153                }, 0);
154            });
155
156            var that = this;
157            this.shadowRoot.querySelector('.close-button').addEventListener('click', function () {
158                removeItem(that);
159            });
160
161            this.addEventListener('keydown', function (e) {
162                if (isModifyKeyPressed(e)) {
163                    return;
164                }
165
166                var list, childIndex;
167
168                switch (e.keyCode) {
169                    case 46:
170                        // Delete key
171                        removeItem(this, true);
172                        break;
173
174                    case 38:
175                        // Up arrow
176                        e.preventDefault();
177                        list = this.parentNode;
178                        childIndex = getItemIndex(this, list);
179                        if (childIndex > 0) {
180                            list.children[childIndex - 1].focus();
181                        }
182                        break;
183
184                    case 40:
185                        // Down arrow
186                        e.preventDefault();
187                        list = this.parentNode;
188                        childIndex = getItemIndex(this, list);
189                        if (childIndex < list.children.length - 1) {
190                            list.children[childIndex + 1].focus();
191                        }
192                        break;
193                }
194            });
195
196            function getItemIndex(item, list) {
197                return list && list.tagName === 'CORDOVA-ITEM-LIST' ? Array.prototype.indexOf.call(list.children, item) : -1;
198            }
199
200            function removeItem(item, setFocus) {
201                var list = item.parentNode;
202
203                // If we're within a list, calculate index in the list
204                var childIndex = getItemIndex(item, list);
205                if (childIndex > -1) {
206                    // Raise an event on ourselves
207                    var itemRemovedEvent = new CustomEvent('itemremoved', { detail: { itemIndex: childIndex }, bubbles: true });
208                    item.dispatchEvent(itemRemovedEvent);
209
210                    list.removeChild(item);
211                    setClassWrapper(list.children);
212
213                    if (setFocus) {
214                        var itemCount = list.children.length;
215                        if (itemCount > 0) {
216                            if (childIndex >= itemCount) {
217                                childIndex = itemCount - 1;
218                            }
219                            list.children[childIndex].focus();
220                        } else {
221                            // If no items left, set focus to containing panel if there is one
222                            var panel = findParent(list, 'cordova-panel');
223                            panel && panel.focus();
224                        }
225                    }
226                }
227            }
228        }
229    });
230
231    registerCustomElement('cordova-panel-row', {
232        initialize: function () {
233            this.classList.add('cordova-panel-row');
234            this.classList.add('cordova-group');
235        }
236    });
237
238    registerCustomElement('cordova-group', {
239        initialize: function () {
240            this.classList.add('cordova-group');
241        }
242    });
243
244    registerCustomElement('cordova-checkbox', {
245        proto: {
246            checked: {
247                get: function () {
248                    return this.shadowRoot.querySelector('input').checked;
249                },
250                set: function (value) {
251                    setValueSafely(this.shadowRoot.querySelector('input'), 'checked', value);
252                }
253            },
254            focus: {
255                value: function () {
256                    this.shadowRoot.querySelector('input').focus();
257                }
258            }
259        },
260        initialize: function () {
261            if (this.parentNode.tagName === 'CORDOVA-PANEL') {
262                this.classList.add('cordova-panel-row');
263                this.classList.add('cordova-group');
264            } else {
265                // Reverse the order of the checkbox and caption
266                this.shadowRoot.appendChild(this.shadowRoot.querySelector('label'));
267            }
268
269            if (this.hasAttribute('spoken')) {
270                this.shadowRoot.querySelector('label').setAttribute('aria-hidden', false);
271            }
272        },
273        mungeIds: 'cordova-checkbox-template-input'
274    });
275
276    registerCustomElement('cordova-radio', {
277        proto: {
278            checked: {
279                get: function () {
280                    return this.shadowRoot.querySelector('input').checked;
281                },
282                set: function (value) {
283                    setValueSafely(this.shadowRoot.querySelector('input'), 'checked', value);
284                }
285            },
286            focus: {
287                value: function () {
288                    this.shadowRoot.querySelector('input').focus();
289                }
290            }
291        },
292        initialize: function () {
293            var isChecked = this.getAttribute('checked');
294            if (isChecked && isChecked.toLowerCase() === 'true') {
295                this.shadowRoot.querySelector('input').checked = true;
296            }
297
298            var parentGroup = findParent(this, 'cordova-group');
299            if (parentGroup) {
300                var radioButton = this.shadowRoot.querySelector('input');
301                radioButton.setAttribute('name', parentGroup.id);
302            }
303        },
304        mungeIds: 'cordova-radio-template-input'
305    });
306
307    registerCustomElement('cordova-label', {
308        proto: {
309            value: {
310                set: function (value) {
311                    setValueSafely(this.shadowRoot.querySelector('label'), 'textContent', value);
312                },
313                get: function () {
314                    return this.shadowRoot.querySelector('label').textContent;
315                }
316            }
317        },
318        initialize: function () {
319            var label = this.shadowRoot.querySelector('label');
320            label.textContent = this.getAttribute('label');
321            label.setAttribute('for', this.getAttribute('for'));
322            this.setAttribute('for', '');
323
324            if (this.hasAttribute('spoken')) {
325                label.setAttribute('aria-hidden', 'false');
326            }
327        }
328    });
329
330    registerCustomElement('cordova-text-entry', {
331        proto: {
332            value: {
333                set: function (value) {
334                    setValueSafely(this.shadowRoot.querySelector('input'), 'value', value);
335                },
336
337                get: function () {
338                    return this.shadowRoot.querySelector('input').value;
339                }
340            },
341            disabled: {
342                set: function (value) {
343                    setValueSafely(this.shadowRoot.querySelector('input'), 'disabled', value);
344                }
345            },
346            focus: {
347                value: function () {
348                    this.shadowRoot.querySelector('input').focus();
349                }
350            }
351        },
352        initialize: function () {
353            this.shadowRoot.querySelector('label').textContent = this.getAttribute('label');
354            this.classList.add('cordova-panel-row');
355            this.classList.add('cordova-group');
356        },
357        eventTarget: 'input',
358        mungeIds: 'cordova-text-entry-template-input'
359    });
360
361    registerCustomElement('cordova-number-entry', {
362        proto: {
363            value: {
364                set: function (value) {
365                    if (utils.isNumber(value)) {
366                        this._internalValue = value;
367                    } else {
368                        value = this._internalValue;
369                    }
370
371                    setValueSafely(this.shadowRoot.querySelector('input'), 'value', value);
372                },
373
374                get: function () {
375                    return this.shadowRoot.querySelector('input').value;
376                }
377            },
378            disabled: {
379                set: function (value) {
380                    setValueSafely(this.shadowRoot.querySelector('input'), 'disabled', value);
381                }
382            },
383            focus: {
384                value: function () {
385                    this.shadowRoot.querySelector('input').focus();
386                }
387            }
388        },
389        initialize: function () {
390            var displayLabel = this.getAttribute('label');
391            this.shadowRoot.querySelector('label').textContent = displayLabel;
392            this.classList.add('cordova-panel-row');
393            this.classList.add('cordova-group');
394            this._internalValue = 0;
395
396            var input = this.shadowRoot.querySelector('input');
397            input.setAttribute('aria-label', this.getAttribute('spoken-text') || displayLabel);
398
399            var maxValue = this.getAttribute('max'),
400                minValue = this.getAttribute('min'),
401                value = this.getAttribute('value'),
402                step = this.getAttribute('step');
403
404            // initialize _internalValue with one of the available values,
405            // otherwise it remains 0
406            if (value !== null && utils.isNumber(value)) {
407                this._internalValue = value;
408            } else if (minValue !== null && utils.isNumber(minValue)) {
409                this._internalValue = minValue;
410            } else if (maxValue !== null && utils.isNumber(maxValue) && this._internalValue > parseFloat(maxValue)) {
411                this._internalValue = maxValue;
412            }
413
414            if (maxValue !== null) input.setAttribute('max', maxValue);
415            if (minValue !== null) input.setAttribute('min', minValue);
416            if (step !== null) input.setAttribute('step', step);
417            if (value !== null) input.setAttribute('value', value);
418
419            // verify and force the input value to be a valid number
420            input.addEventListener('input', function (event) {
421                var value = event.target.value;
422
423                if (utils.isNumber(value)) {
424                    this._internalValue = value;
425                } else {
426                    // the new value is not a number, set the value to the
427                    // latest number value
428                    input.value = this._internalValue;
429                    return false;
430                }
431            }.bind(this));
432        },
433        eventTarget: 'input',
434        mungeIds: 'cordova-number-entry-template-input'
435    });
436
437    registerCustomElement('cordova-labeled-value', {
438        proto: {
439            label: {
440                set: function (value) {
441                    setValueSafely(this.shadowRoot.querySelector('label'), 'textContent', value);
442                },
443
444                get: function () {
445                    return this.shadowRoot.querySelector('label').textContent;
446                }
447            },
448            value: {
449                set: function (value) {
450                    setValueSafely(this.shadowRoot.querySelector('span'), 'textContent', value);
451                    setValueSafely(this.shadowRoot.querySelector('span'), 'title', value);
452                },
453
454                get: function () {
455                    return this.shadowRoot.querySelector('span').textContent;
456                }
457            }
458        },
459        initialize: function () {
460            this.shadowRoot.querySelector('label').textContent = this.getAttribute('label');
461            this.shadowRoot.querySelector('span').textContent = this.getAttribute('value');
462            this.shadowRoot.querySelector('span').setAttribute('title', this.getAttribute('value'));
463            this.classList.add('cordova-panel-row');
464            this.classList.add('cordova-group');
465        }
466    });
467
468    registerCustomElement('cordova-button', {
469        proto: {
470            focus: {
471                value: function () {
472                    this.shadowRoot.querySelector('button').focus();
473                }
474            }
475        },
476        initialize: function () {
477            var readLabel = this.getAttribute('spoken-text');
478            if (readLabel) {
479                this.shadowRoot.querySelector('button').setAttribute('aria-label', readLabel);
480            }
481        },
482        eventTarget: 'button'
483    });
484
485    registerCustomElement('cordova-file', {
486        proto: {
487            input: {
488                get: function () {
489                    return this.shadowRoot.querySelector('input');
490                }
491            },
492            files: {
493                get: function () {
494                    return this.shadowRoot.querySelector('input').files;
495                }
496            },
497            accept: {
498                set: function (value) {
499                    setValueSafely(this.shadowRoot.querySelector('input'), 'accept', value);
500                }
501            }
502        },
503        eventTarget: 'input'
504    });
505
506    registerCustomElement('cordova-combo', {
507        proto: {
508            options: {
509                get: function () {
510                    return this.shadowRoot.querySelector('select').options;
511                }
512            },
513            selectedIndex: {
514                get: function () {
515                    return this.shadowRoot.querySelector('select').selectedIndex;
516                }
517            },
518            value: {
519                get: function () {
520                    return this.shadowRoot.querySelector('select').value;
521                },
522                set: function (value) {
523                    setValueSafely(this.shadowRoot.querySelector('select'), 'value', value);
524                }
525            },
526            appendChild: {
527                value: function (node) {
528                    this.shadowRoot.querySelector('select').appendChild(node);
529                }
530            },
531            focus: {
532                value: function () {
533                    this.shadowRoot.querySelector('select').focus();
534                }
535            }
536        },
537        initialize: function () {
538            this.classList.add('cordova-panel-row');
539            this.classList.add('cordova-group');
540            var select = this.shadowRoot.querySelector('select');
541
542            var name = this.getAttribute('name');
543            if (name) {
544                select.setAttribute('name', name);
545            }
546
547            var label = this.getAttribute('label');
548            if (label) {
549                this.shadowRoot.querySelector('label').textContent = label;
550            } else {
551                select.style.width = this.style.width || '100%';
552                select.style.minWidth = this.style.minWidth;
553            }
554            
555            var readLabel = this.getAttribute('spoken-text');
556            if (readLabel) {
557                select.setAttribute('aria-label', readLabel);
558            }
559
560            // Move option elements to be children of select element
561            var options = this.querySelectorAll('option');
562            Array.prototype.forEach.call(options, function (option) {
563                select.appendChild(option);
564            });
565        },
566        eventTarget: 'select',
567        mungeIds: 'cordova-combo-template-select'
568    });
569}
570
571/**
572 * @param name The name of the custom element (corresponds to tag in html files).
573 * @param opts - options for the creation of the element.
574 * @param opts.proto Properties to set on the prototype.
575 * @param opts.initialize Function to call when the custom element is initialized.
576 * @param opts.eventTarget Selector for object to redirect events to.
577 * @param opts.mungeIds An id or array of ids to 'munge' by pre-pending with custom element id or random value (to
578 *        ensure unique in document)
579 */
580function registerCustomElement(name, opts) {
581    var protoProperties = opts.proto;
582    var initializeCallback = opts.initialize;
583    var eventTargetSelector = opts.eventTarget;
584    var mungeIds = opts.mungeIds;
585
586    if (mungeIds && !Array.isArray(mungeIds)) {
587        mungeIds = [mungeIds];
588    }
589
590    var constructorName = name.split('-').map(function (bit) {
591        return bit.charAt(0).toUpperCase() + bit.substr(1);
592    }).join('');
593
594    var proto = Object.create(HTMLElement.prototype);
595    if (protoProperties) {
596        Object.defineProperties(proto, protoProperties);
597    }
598
599    function initialize() {
600        this.initialized = true;
601
602        var eventTarget = eventTargetSelector && this.shadowRoot.querySelector(eventTargetSelector);
603        if (eventTarget) {
604            // Make sure added events are redirected. Add more on<event> handlers here as we find they're needed
605            Object.defineProperties(this, {
606                addEventListener: {
607                    value: function (a, b, c) {
608                        eventTarget.addEventListener(a, b, c);
609                    }
610                },
611                click: {
612                    value: eventTarget.click
613                },
614                onclick: {
615                    get: function () {
616                        return eventTarget.onclick;
617                    },
618                    set: function (value) {
619                        eventTarget.onclick = value;
620                    }
621                },
622                onchange: {
623                    get: function () {
624                        return eventTarget.onchange;
625                    },
626                    set: function (value) {
627                        eventTarget.onchange = value;
628                    }
629                }
630            });
631        }
632
633        // We don't allow inline event handlers. Detect them and strip.
634        var atts = this.attributes;
635        Array.prototype.forEach.call(atts, function (att) {
636            if (att.name.indexOf('on') === 0) {
637                console.error('Unsupported inline event handlers detected: ' + name + '.' + att.name + '="' + att.value + '"');
638                this.removeAttribute(att.name);
639            }
640        }, this);
641
642
643        // Initialize if it is required
644        initializeCallback && initializeCallback.call(this);
645
646        // Apply attributes
647    }
648
649    proto.attachedCallback = function () {
650        if (!this.initialized) {
651            // If it hasn't already been initialized, do so now.
652            initialize.call(this);
653        }
654    };
655
656    proto.createdCallback = function () {
657        var t = document.getElementById(name + '-template');
658        var shadowRoot = this.createShadowRoot();
659        shadowRoot.appendChild(document.importNode(t.content, true));
660
661        if (mungeIds) {
662            mungeIds.forEach(function (idToMunge) {
663                var mungedId = idToMunge + '-' + uniqueIdSuffix++;
664                var target = shadowRoot.querySelector('#' + idToMunge);
665                if (target) {
666                    target.setAttribute('id', mungedId);
667                }
668
669                var forElement = shadowRoot.querySelector('[for=' + idToMunge + ']');
670                if (forElement) {
671                    forElement.setAttribute('for', mungedId);
672                }
673            });
674        }
675
676        if (initializeCallback && this.ownerDocument === document) {
677            // If it is being created in the main document, initialize immediately.
678            initialize.call(this);
679        }
680    };
681
682    window[constructorName] = document.registerElement(name, {
683        prototype: proto
684    });
685}
686
687function isModifyKeyPressed(e) {
688    return e.altKey || e.ctrlKey || e.shiftKey || e.metaKey;
689}
690
691function collapsePanel(iconElem, content) {
692    iconElem.classList.add('cordova-collapsed');
693    content.style.display = 'none';
694    content.style.height = '0';
695}
696
697function expandPanel(iconElem, content) {
698    iconElem.classList.remove('cordova-collapsed');
699    content.style.display = '';
700    content.style.height = '';
701}
702
703function findParent(element, tag) {
704    if (!Array.isArray(tag)) {
705        tag = [tag];
706    }
707
708    var parent = element.parentNode;
709    return parent && parent.tagName ? tag.indexOf(parent.tagName.toLowerCase()) > -1 ? parent : findParent(parent, tag) : null;
710}
711
712function setValueSafely(el, prop, value) {
713    // In IE, setting the property when the element hasn't yet been added to the document can fail (like an issue with
714    // the webcomponents polyfill), so do it after a setTimeout().
715    if (el.ownerDocument.contains(el)) {
716        el[prop] = value;
717    } else {
718        window.setTimeout(function () {
719            el[prop] = value;
720        }, 0);
721    }
722}
723
724function setClassWrapper(list) {
725    var length = list.length;
726    if (length == 1) {
727        list[0].shadowRoot.querySelector('.cordova-item-wrapper').className = 'cordova-item-wrapper cordova-item-first-child cordova-item-last-child';
728    } else if (length > 0) {
729        list[0].shadowRoot.querySelector('.cordova-item-wrapper').className = 'cordova-item-wrapper cordova-item-first-child';
730        for (var i = 1; i < length - 1; i++) {
731            list[i].shadowRoot.querySelector('.cordova-item-wrapper').className = 'cordova-item-wrapper';
732        } 
733        list[length - 1].shadowRoot.querySelector('.cordova-item-wrapper').className = 'cordova-item-wrapper cordova-item-last-child';   
734    }
735}
736
737module.exports = {
738    initialize: initialize
739};
740
741if (!Array.prototype.find) {
742    Array.prototype.find = function (predicate) {
743        if (this == null) {
744            throw new TypeError('Array.prototype.find called on null or undefined');
745        }
746        if (typeof predicate !== 'function') {
747            throw new TypeError('predicate must be a function');
748        }
749        var list = Object(this);
750        var length = list.length >>> 0;
751        var thisArg = arguments[1];
752        var value;
753
754        for (var i = 0; i < length; i++) {
755            value = list[i];
756            if (predicate.call(thisArg, value, i, list)) {
757                return value;
758            }
759        }
760        return undefined;
761    };
762}
763
Full Screen

calculator.js

Source: calculator.js Github

copy
1const template = document.createElement('template');
2template.innerHTML = `
3    <style>
4        @import "main.css"
5    </style>
6    <div class="calculatorForm"><h1>Calculator</h1></div>
7    <div class="main">
8        <form>
9            <div id="amount">
10                <h2 class="heading">Amount: </h2>
11                <input class="totalAmount" id="total-amount" type="text" name="total_amount" placeholder="How much do you have?"/>
12                <label id="errorText" hidden>Incorrect Format</label>
13            </div>
14            <button type="button" id="calculate">Calculate</button>
15            
16            <div id="resultsAmount" hidden>
17                <h2 class="resultsHeading">Results: </h2>
18                <input class="totalAmountResults" id="total-amount-results" type="text" name="total_amount" readonly/>
19                <label id="errorText" hidden>Incorrect Format</label>
20            </div>
21
22            <div id="hideMe">
23
24            </div>
25        </form>
26    </div>
27`;
28class SharesCalculator extends HTMLElement {
29    constructor(){
30        super();
31
32        this.attachShadow({mode:'open'});
33        this.shadowRoot.appendChild(template.content.cloneNode(true));
34        this.shadowRoot.querySelector('h1').innerText = this.getAttribute('name');
35    }
36    Calculate(totalAmount){
37        
38        var reg = new RegExp(/^[1-9]\d*(((,\d{3}){1})?(\.\d{0,2})?)$/);
39        if(totalAmount == ""){
40            this.shadowRoot.querySelector('#total-amount').classList.add('error');
41        }
42        else if(!reg.test(totalAmount)){
43            this.shadowRoot.querySelector('#errorText').classList.add('showMe');
44        }
45        else{
46
47            var currentSharePrice = 167241;
48            var results = parseFloat((totalAmount/currentSharePrice) * 100);
49            this.shadowRoot.querySelector('#total-amount-results').value = Math.round(results);
50            this.shadowRoot.querySelector('#errorText').classList.remove('showMe');
51            this.shadowRoot.querySelector('#total-amount').classList.remove('error');
52            this.shadowRoot.querySelector('#resultsAmount').classList.add('showMe');
53        }
54    }
55
56    RemoveRedBorder(totalAmount){
57
58        if(totalAmount != ""){
59            this.shadowRoot.querySelector('#total-amount').classList.remove('error');
60        }
61        else{
62            this.shadowRoot.querySelector('#errorText').classList.remove('showMe');
63            this.shadowRoot.querySelector('#total-amount').classList.add('error');
64        }
65        
66    }
67
68    connectedCallback(){
69        this.shadowRoot.querySelector('#calculate').addEventListener('click', () => this.Calculate(this.shadowRoot.querySelector('#total-amount').value));
70        this.shadowRoot.querySelector('#total-amount').addEventListener('change', () => this.RemoveRedBorder(this.shadowRoot.querySelector('#total-amount').value));
71    }
72    disconnectedCallback(){
73        this.shadowRoot.querySelector('#calculate').removeEventListener();
74    }
75}
76
77window.customElements.define('shares-calculator',SharesCalculator);
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Webdriverio on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)