@jinntec/fore 3.3.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +98 -70
  2. package/dist/fore-dev.js +5593 -6832
  3. package/dist/fore.js +5602 -4887
  4. package/index.js +5 -10
  5. package/package.json +7 -7
  6. package/resources/fore.css +33 -0
  7. package/src/DependencyNotifyingDomFacade.js +90 -21
  8. package/src/DependentXPathQueries.js +15 -2
  9. package/src/ForeElementMixin.js +110 -16
  10. package/src/UndoManager.js +267 -0
  11. package/src/actions/abstract-action.js +71 -30
  12. package/src/actions/fx-action.js +5 -0
  13. package/src/actions/fx-append.js +3 -3
  14. package/src/actions/fx-commit-history.js +26 -0
  15. package/src/actions/fx-hide.js +1 -1
  16. package/src/actions/fx-insert.js +25 -22
  17. package/src/actions/fx-load.js +5 -5
  18. package/src/actions/fx-redo.js +58 -0
  19. package/src/actions/fx-refresh.js +2 -2
  20. package/src/actions/fx-reload.js +1 -1
  21. package/src/actions/fx-replace.js +1 -1
  22. package/src/actions/fx-send.js +27 -5
  23. package/src/actions/fx-setattribute.js +11 -7
  24. package/src/actions/fx-undo.js +58 -0
  25. package/src/createNodes.js +314 -0
  26. package/src/fore.js +53 -18
  27. package/src/functions/fx-functionlib.js +10 -10
  28. package/src/fx-bind.js +30 -18
  29. package/src/fx-fore.js +222 -200
  30. package/src/fx-instance.js +18 -1
  31. package/src/fx-model.js +236 -69
  32. package/src/fx-submission.js +37 -29
  33. package/src/fx-var.js +49 -13
  34. package/src/getInScopeContext.js +1 -1
  35. package/src/json/JSONDomFacade.js +1 -1
  36. package/src/json/JSONLens.js +2 -2
  37. package/src/ui/UIElement.js +18 -8
  38. package/src/ui/abstract-control.js +45 -3
  39. package/src/ui/fx-alert.js +4 -0
  40. package/src/ui/fx-case.js +1 -1
  41. package/src/ui/fx-container.js +3 -0
  42. package/src/ui/fx-control-menu.js +79 -11
  43. package/src/ui/fx-control.js +130 -41
  44. package/src/ui/fx-dialog.js +5 -0
  45. package/src/ui/fx-items.js +6 -6
  46. package/src/ui/fx-output.js +37 -1
  47. package/src/ui/fx-repeat.js +1065 -103
  48. package/src/ui/fx-repeatitem.js +4 -1
  49. package/src/ui/fx-switch.js +116 -3
  50. package/src/ui/fx-trigger.js +9 -4
  51. package/src/ui/fx-upload.js +10 -4
  52. package/src/ui/repeat-base.js +20 -12
  53. package/src/withDraggability.js +10 -1
  54. package/src/xpath-evaluation.js +30 -18
  55. package/src/xpath-path.js +122 -0
  56. package/src/xpath-util.js +11 -126
  57. package/src/actions/StringTpl.js +0 -17
  58. package/src/extract-predicate-deps.js +0 -57
  59. package/src/extractPredicateDependencies.js +0 -36
  60. package/src/json/lensFromNode.js +0 -5
  61. package/src/json-util.js +0 -27
  62. package/src/tools/adi.js +0 -1111
  63. package/src/tools/deprecation.md +0 -1
  64. package/src/tools/fx-action-log.js +0 -745
  65. package/src/tools/fx-devtools.js +0 -444
  66. package/src/tools/fx-dom-inspector.js +0 -610
  67. package/src/tools/fx-json-instance.js +0 -444
  68. package/src/tools/fx-log-item.js +0 -128
  69. package/src/tools/fx-log-settings.js +0 -533
  70. package/src/tools/fx-minimap.js +0 -203
  71. package/src/tools/helpers.js +0 -132
  72. package/src/ui/TemplateExpression.js +0 -12
  73. package/src/ui/fx-dom-inspector.js +0 -1255
@@ -1,1255 +0,0 @@
1
- import AbstractControl from './abstract-control.js';
2
-
3
- export class FxDomInspector extends HTMLElement {
4
- constructor() {
5
- super();
6
- this.attachShadow({ mode: 'open' });
7
- this.delegatedEvents = [];
8
- }
9
-
10
- connectedCallback() {
11
- this.render();
12
- }
13
-
14
- render(){
15
- const style = `
16
- :host {
17
- display:block;
18
- }
19
- `;
20
-
21
- const html = `
22
- <slot></slot>
23
- `;
24
-
25
- this.shadowRoot.innerHTML = `
26
- <style>
27
- ${style}
28
- </style>
29
- ${html}
30
- `;
31
- }
32
-
33
- // Node types shim -- creates Node type constants if necessary
34
- nodeTypesShim() {
35
- if (!window.Node) {
36
- return {
37
- ELEMENT_NODE : 1,
38
- ATTRIBUTE_NODE : 2,
39
- TEXT_NODE : 3,
40
- CDATA_SECTION_NODE : 4,
41
- ENTITY_REFERENCE_NODE : 5,
42
- ENTITY_NODE : 6,
43
- PROCESSING_INSTRUCTION_NODE : 7,
44
- COMMENT_NODE : 8,
45
- DOCUMENT_NODE : 9,
46
- DOCUMENT_TYPE_NODE : 10,
47
- DOCUMENT_FRAGMENT_NODE : 11,
48
- NOTATION_NODE : 12
49
- };
50
- }
51
- }
52
-
53
- addEvent(elem, evt, fn, capture) {
54
- if (typeof elem !== 'object') {
55
- throw "addEvent: Expected argument elem of type object, " + typeof elem + " given.";
56
- }
57
-
58
- if (window.addEventListener) {
59
- if (!capture) {
60
- capture = false;
61
- }
62
-
63
- elem.addEventListener(evt, fn, capture);
64
- } else {
65
- elem.attachEvent('on' + evt, fn);
66
- }
67
- }
68
-
69
- // Simple cross-browser event handler that enables simple event delegation.
70
- // Note that the selector must be a string and no nesting is supported.
71
- // Selector is expected to be in one of formats listed below and works for all children
72
- // in the particular element.
73
- // Store parameter enables storing the reference to custom event handler.
74
- // Exclude parameter will exclude the particular element and all of its children, this works
75
- // only for id selectors.
76
- // Selector formats: tag name ("div"), class name (".my-class"), id ("#my-id") and any ("*").
77
-
78
- addEventDelegate(elem, evt, fn, capture, selector, store, exclude) {
79
- // custom event handler is registered
80
- var handler = function(e) {
81
- // check if target corresponds to the selector
82
- var target = e ? e.target : window.event.srcElement,
83
- sel = selector.substr(1),
84
- delegate = false;
85
-
86
- if (exclude) {
87
- var node = target;
88
-
89
- while (node !== document) {
90
- if (node.id === exclude) {
91
- return;
92
- }
93
-
94
- node = node.parentNode;
95
- }
96
- }
97
-
98
- // should the event be delegated?
99
- if (selector.indexOf('#') === 0) { // ID
100
- delegate = target.id === sel;
101
- } else if (selector.indexOf('.') === 0) { // class
102
- delegate = target.className.indexOf(sel) !== -1;
103
- } else if (selector === '*') { // any
104
- delegate = true;
105
- } else { // tag name
106
- delegate = target.nodeName.toLowerCase() === selector;
107
- }
108
-
109
- // delegate the event handling
110
- if (delegate) {
111
- fn.call(this, e);
112
- }
113
- };
114
- // save the reference
115
- if (store) {
116
- delegatedEvents.push({
117
- 'handle' : handler,
118
- 'elem' : elem,
119
- 'fn' : fn,
120
- 'evt': evt
121
- });
122
- }
123
-
124
- // add custom event
125
- addEvent(elem, evt, handler, capture);
126
- }
127
-
128
- // Simple cross-browser event removing
129
- removeEvent(elem, evt, fn, wasDelegated) {
130
- if (typeof elem !== 'object') {
131
- throw "addEvent: Expected argument elem of type object, " + typeof elem + " given.";
132
- }
133
-
134
- // try to find stored delegated event
135
- var stored = null;
136
- if (wasDelegated) {
137
- for (var i = 0, len = delegatedEvents.length; i < len; ++i) {
138
- stored = delegatedEvents[i];
139
- if (stored.elem === elem && stored.evt === evt && stored.fn === fn) {
140
- fn = stored.handle;
141
- delegatedEvents.splice(i, 1);
142
- break;
143
- }
144
- }
145
- }
146
-
147
- if (window.addEventListener) {
148
- elem.removeEventListener(evt, fn, false);
149
- } else {
150
- elem.dettachEvent('on' + evt, fn);
151
- }
152
- }
153
- // Stops event propagation and also prevents the default behavior.
154
- pauseEvent(e){
155
- if(e.stopPropagation) {
156
- e.stopPropagation();
157
- }
158
-
159
- if(e.preventDefault) {
160
- e.preventDefault();
161
- }
162
-
163
- e.cancelBubble = true;
164
- e.returnValue = false;
165
-
166
- return false;
167
- }
168
-
169
- // Create element wrapper -- allows to set attributes using the config object.
170
- newElement(elem, attrs) {
171
- var el = document.createElement(elem);
172
-
173
- attrs = attrs || {};
174
- for (var attr in attrs) {
175
- // work only with direct (non-inherited) properties
176
- if (attrs.hasOwnProperty(attr)) {
177
- el.setAttribute(attr, attrs[attr]);
178
- }
179
- }
180
-
181
- return el;
182
- }
183
-
184
- // Function adds a class to the element, only if the class does not already exist.
185
- // Cls parameter may be either a string or an array listing multiple classes.
186
- // Implementation uses modern element.classList API if available, dummy shim provided for older
187
- // browsers.
188
- addClass(elem, cls) {
189
- if (typeof elem !== 'object') {
190
- throw "addClass: Expected argument elem of type object, " + typeof elem + " given.";
191
- }
192
-
193
- // normalize to array
194
- if (typeof cls === 'string') {
195
- cls = [cls];
196
- }
197
-
198
- // iterate over classes and add new if necessary
199
- for (var i = 0, len = cls.length; i < len; ++i) {
200
- if (supported('classList')) {
201
- elem.classList.add(cls[i]);
202
- } else {
203
- // prevents the match when new class is only a substring of another class name
204
- if (!new RegExp('(?:^|\\s)' + cls[i] + '(?:\\s|$)').test(elem.className)) {
205
- elem.className += ' ' + cls[i];
206
- }
207
- }
208
- }
209
- }
210
-
211
- // Function removes a class from the element, only if the class exists.
212
- // Cls parameter may be either a string or an array listing multiple classes.
213
- // Implementation uses modern element.classList API if available, dummy shim provided for older
214
- // browsers.
215
- removeClass(elem, cls) {
216
- if (typeof elem !== 'object') {
217
- throw "removeClass: Expected argument elem of type object, " + typeof elem + " given.";
218
- }
219
-
220
- // normalize to array
221
- if (typeof cls === 'string') {
222
- cls = [cls];
223
- }
224
-
225
- // iterate over classes and remove if necessary
226
- for (var i = 0, len = cls.length; i < len; ++i) {
227
- if (supported('classList')) {
228
- elem.classList.remove(cls[i]);
229
- } else {
230
- // removes the class if it exists
231
- var newClassName = elem.className.replace(new RegExp('(?:^|\\s)' + cls[i] + '(?:\\s|$)', 'g'), ' ');
232
- elem.className = newClassName.replace(/^\s+|\s+$/g, '');
233
- }
234
- }
235
- }
236
-
237
- // Functions checks whether the feature is supported.
238
- supported(key) {
239
- switch (key) {
240
- case 'localStorage':
241
- try {
242
- return 'localStorage' in window && !!window.localStorage;
243
- } catch (e) {
244
- return false;
245
- }
246
-
247
- break;
248
- case 'classList':
249
- return 'classList' in document.createElement('a');
250
-
251
- default:
252
- throw "supported: Unknown or unsupported key.";
253
- }
254
- }
255
-
256
- // AcID DOM Inspector definition (using module pattern).
257
- var ADI = (function() {
258
- // private methods and variables
259
- var Node = window.Node || nodeTypesShim(),
260
- uiView = null,
261
- menuView = null,
262
- domView = null,
263
- attrView = null,
264
- pathView = null,
265
- optsView = null,
266
- activeElement = null,
267
- vertResizing = false,
268
- horizResizing = false,
269
- pathScrolling = null,
270
- elemLookup = false,
271
- styleBackup = '',
272
- xPos = 0,
273
- options = {
274
- align: 'right', // NOTE: left is not supported in this version
275
- width: 500,
276
- minWidth: 260,
277
- split: 50,
278
- minSplit: 30,
279
- visible: true,
280
- saving: false,
281
- transparent: true,
282
- omitEmptyText: true,
283
- makeVisible: true,
284
- foldText: true,
285
- nodeTypes: [1, 3, 8, 9]
286
- };
287
-
288
- // Returns selected element or null
289
- function getSelected() {
290
- if (!activeElement) {
291
- return null;
292
- }
293
-
294
- var elem = document,
295
- path = JSON.parse(activeElement.getAttribute('data-js-path'));
296
-
297
- if (path[0] !== "") {
298
- for (var i = 0, len = path.length; i < len; ++i) {
299
- elem = elem.childNodes[path[i]];
300
- }
301
- }
302
-
303
- return elem;
304
- }
305
-
306
- // Loads user defined options stored in HTML5 storage (if available)
307
- function loadOptions() {
308
- var userOptions = {};
309
-
310
- if (supported('localStorage')) {
311
- userOptions = JSON.parse(localStorage.getItem('ADI.options')) || {};
312
- }
313
-
314
- // merge with defaults
315
- for (var opt in userOptions) {
316
- options[opt] = userOptions[opt];
317
- }
318
- }
319
-
320
- // Saves user defined options into the HTML5 storage (if available)
321
- function saveOptions() {
322
- if (supported('localStorage') && options.saving) {
323
- localStorage.setItem('ADI.options', JSON.stringify(options));
324
- }
325
- }
326
-
327
- // Resets user defined options and removes them from the HTML5 storage
328
- function resetOptions() {
329
- if (supported('localStorage')) {
330
- localStorage.removeItem('ADI.options');
331
- }
332
- }
333
-
334
- // Returns CSS and JS paths to the element
335
- // Result is an object with two variables (cssPath, jsPath) where cssPath is a string
336
- // which holds the css path starting from the HTML element, and jsPath is an array which
337
- // contains indexes for childNodes arrays (starting at document object).
338
- //
339
- // Inspired by the selector function from Rochester Oliveira's jQuery plugin
340
- // http://rockingcode.com/tutorial/element-dom-tree-jquery-plugin-firebug-like-functionality/
341
- function getElemPaths(elem) {
342
- if (typeof elem !== 'object') {
343
- throw "getElemPaths: Expected argument elem of type object, " + typeof elem + " given.";
344
- }
345
-
346
- var css = "",
347
- js = "",
348
- parent = "",
349
- i, len;
350
-
351
- while (elem !== document) {
352
- parent = elem.parentNode;
353
-
354
- // javascript selector
355
- for (i = 0, len = parent.childNodes.length; i < len; ++i) {
356
- if (parent.childNodes[i] === elem) {
357
- js = i + "," + js;
358
- break;
359
- }
360
- }
361
-
362
- // CSS selector
363
- var cssTmp = elem.nodeName;
364
-
365
- if (elem.id) {
366
- cssTmp += '#' + elem.id;
367
- }
368
-
369
- if (elem.className) {
370
- // use classList if available
371
- var classList = elem.classList || elem.className.split(' ');
372
-
373
- for (i = 0, len = classList.length; i < len; ++i) {
374
- cssTmp += '.' + classList[i];
375
- }
376
- }
377
-
378
- css = cssTmp + ' ' + css;
379
- elem = elem.parentNode;
380
- }
381
-
382
- js = js.slice(0, -1).split(',');
383
-
384
- return {
385
- cssPath: css.toLowerCase(),
386
- jsPath: js
387
- };
388
- }
389
-
390
- // Checks if a node has some child nodes and if at least on of them is of a supported type
391
- function hasRequiredNodes(node) {
392
- if (typeof node !== 'object') {
393
- throw "hasRequiredNodes: Expected argument node of type object, " + typeof node + " given.";
394
- }
395
-
396
- if (node.hasChildNodes()) {
397
- for (var i = 0, len = node.childNodes.length; i < len; i++) {
398
- if (options.nodeTypes.indexOf(node.childNodes[i].nodeType) !== -1) {
399
- return true;
400
- }
401
- }
402
- }
403
-
404
- return false;
405
- }
406
-
407
- // Checks whether the text node is not empty or contains only the EOL
408
- function isEmptyTextNode(node) {
409
- if (typeof node !== 'object') {
410
- throw "isEmptyTextNode: Expected argument node of type object, " + typeof node + " given.";
411
- }
412
-
413
- return (/^\s*$/).test(node.textContent);
414
- }
415
-
416
- // Checks whether the node or its children contains only text information
417
- function containsOnlyText(node, checkChildren) {
418
- if (typeof node !== 'object') {
419
- throw "containsOnlyText: Expected argument node of type object, " + typeof node + " given.";
420
- }
421
-
422
- checkChildren = checkChildren || false;
423
-
424
- var result = false,
425
- nodeTmp = null;
426
-
427
- // does the node contain only text nodes?
428
- if (checkChildren) {
429
- for (var i = 0, len = node.childNodes.length; i < len; ++i) {
430
- nodeTmp = node.childNodes[i];
431
- result = nodeTmp.nodeType === Node.TEXT_NODE
432
- || nodeTmp.nodeType === Node.COMMENT_NODE
433
- || nodeTmp.nodeType === Node.CDATA_SECTION_NODE;
434
-
435
- if (!result) {
436
- break;
437
- }
438
- }
439
- } else {
440
- // check the node type if it doesn't have any children
441
- result = node.nodeType === Node.TEXT_NODE
442
- || node.nodeType === Node.COMMENT_NODE
443
- || node.nodeType === Node.CDATA_SECTION_NODE;
444
- }
445
-
446
- return result;
447
- }
448
-
449
- // Creates a starting markup for a new DOM tree view node
450
- function newTreeNode(node) {
451
- if (typeof node !== 'object') {
452
- throw "newTreeNode: Expected argument node of type object, " + typeof node + " given.";
453
- }
454
-
455
- var withChildren = hasRequiredNodes(node),
456
- omit = false,
457
- elem = newElement('li', {
458
- class: (withChildren ? 'adi-node' : '')
459
- });
460
-
461
- // do not show ADI DOM nodes in the DOM view
462
- if (node === uiView) {
463
- return null;
464
- }
465
-
466
- // generate UI for elements with children
467
- if (withChildren) {
468
- elem.appendChild(newElement('span', { class: 'adi-trigger' }));
469
- }
470
-
471
- // we can omit empty text nodes if allowed in options
472
- if (options.omitEmptyText && node.nodeType === Node.TEXT_NODE) {
473
- omit = isEmptyTextNode(node);
474
- }
475
-
476
- if (!omit) {
477
- var path = getElemPaths(node),
478
- tagStart = newElement('span', {
479
- 'data-css-path' : path.cssPath,
480
- 'data-js-path' : JSON.stringify(path.jsPath)
481
- }),
482
- tagEnd = null;
483
-
484
- if (containsOnlyText(node)) {
485
-
486
- if (node.nodeType === Node.COMMENT_NODE) {
487
- addClass(tagStart, 'adi-comment-node');
488
- if (typeof tagStart.innerText === 'string') {
489
- tagStart.innerText = '<!-- ' + node.textContent + ' -->';
490
- } else {
491
- tagStart.textContent = '<!-- ' + node.textContent + ' -->';
492
- }
493
- } else {
494
- addClass(tagStart, 'adi-text-node');
495
- tagStart.textContent = node.textContent;
496
- }
497
- } else {
498
- addClass(tagStart, 'adi-normal-node');
499
- if (node.nodeType !== Node.DOCUMENT_NODE) {
500
- // tagStart.textContent = '<' + node.nodeName.toLowerCase() + '>';
501
-
502
- if(node.nodeName === 'FX-BIND'){
503
- tagStart.textContent = `<${node.nodeName.toLowerCase()} ref="${node.getAttribute('ref')}">`;
504
- }else if(node.nodeName === 'FX-INSTANCE'){
505
- tagStart.textContent = `<${node.nodeName.toLowerCase()} id="${node.id}">`;
506
- }else if(node.nodeName === 'FX-CONTROL'){
507
- tagStart.textContent = `<${node.nodeName.toLowerCase()} ref="${node.getAttribute('ref')}">`;
508
- }else if(node.nodeName === 'FX-SEND'){
509
- tagStart.textContent = `<${node.nodeName.toLowerCase()} submission="${node.getAttribute('submission')}">`;
510
- }else{
511
- tagStart.textContent = `<${node.nodeName.toLowerCase()}>`;
512
- }
513
-
514
- if (withChildren) {
515
- tagEnd = newElement('span');
516
- addClass(tagEnd, 'adi-end-node');
517
- tagEnd.textContent = '</' + node.nodeName.toLowerCase() + '>';
518
- }
519
- } else {
520
- tagStart.textContent = node.nodeName.toLowerCase();
521
- }
522
- }
523
-
524
- elem.appendChild(tagStart);
525
- /*
526
- const icon = document.createElement('span');
527
- icon.textContent = 'x';
528
- icon.classList.add(('icon'))
529
- const icon2 = document.createElement('span');
530
- icon2.textContent = '<-';
531
- icon2.classList.add(('icon'))
532
- elem.appendChild(icon);
533
- elem.appendChild(icon2);
534
- */
535
- if(node.nodeName.startsWith('FX-')){
536
- tagStart.classList.add('fore-node');
537
- }
538
-
539
- if (tagEnd) {
540
- elem.appendChild(tagEnd);
541
-
542
- if(node.nodeName.startsWith('FX-')){
543
- tagEnd.classList.add('fore-node');
544
- }
545
- }
546
-
547
- return elem;
548
- } else {
549
- return null;
550
- }
551
- }
552
-
553
- // Renders the DOM Tree view
554
- function drawDOM(root, elem, isRoot) {
555
- if (typeof root !== 'object') {
556
- throw "drawDOM: Expected argument root of type object, " + typeof root + " given.";
557
- }
558
-
559
- var newNode = null,
560
- isOpen = true;
561
-
562
- if (isRoot && options.nodeTypes.indexOf(root.nodeType) !== -1) {
563
- elem.innerHTML = '';
564
- newNode = newTreeNode(root);
565
-
566
- if (hasRequiredNodes(root)) {
567
- newNode.appendChild(newElement('ul', { 'data-open' : true }));
568
- addClass(newNode.querySelector('.adi-trigger'), 'opened');
569
- }
570
-
571
- elem.appendChild(newNode);
572
- elem = elem.querySelector('ul');
573
- }
574
-
575
- // recursive DOM traversal
576
- for (var i = 0, len = root.childNodes.length; i < len; ++i) {
577
- var node = root.childNodes[i],
578
- withChildren = hasRequiredNodes(node);
579
-
580
- if (options.nodeTypes.indexOf(node.nodeType) !== -1) {
581
- newNode = newTreeNode(node);
582
-
583
- if (newNode) {
584
- if (withChildren) {
585
- if (options.foldText) {
586
- isOpen = containsOnlyText(node, true) ? false : true;
587
- } else {
588
- isOpen = true;
589
- }
590
-
591
- if (node.nodeType === Node.DOCUMENT_NODE) {
592
- newNode.appendChild(newElement('ul', { 'data-open' : isOpen }));
593
- } else {
594
- newNode.insertBefore(newElement('ul', { 'data-open' : isOpen }), newNode.lastChild);
595
- }
596
-
597
- addClass(newNode.querySelector('.adi-trigger'), isOpen ? 'opened' : 'closed');
598
- }
599
-
600
- elem.appendChild(newNode);
601
-
602
- if (withChildren) {
603
- drawDOM(node, newNode.querySelector('ul'), false);
604
- }
605
- }
606
- }
607
- }
608
- }
609
-
610
- // Show/hide the options view
611
- function toggleOptions() {
612
- if (optsView.className.indexOf('adi-hidden') !== -1) {
613
- removeClass(optsView, 'adi-hidden');
614
- } else {
615
- addClass(optsView, 'adi-hidden');
616
- pathView.textContent = '';
617
- attrView.querySelector('.adi-content').innerHTML = '';
618
- refreshUI();
619
- drawDOM(document, domView.querySelector('.adi-tree-view'), true);
620
- if (options.saving) {
621
- saveOptions();
622
- } else {
623
- resetOptions();
624
- }
625
- }
626
- }
627
-
628
- // Helper function for options view
629
- function drawOptionRow(optionCode, optionText) {
630
- var row = newElement('span', { class: 'adi-opt' });
631
- row.innerHTML = '<label><input type="checkbox" data-opt="' + optionCode + '">' + optionText + '</label>';
632
-
633
- return row;
634
- }
635
-
636
- // Renders the options panel
637
- function drawOptions() {
638
- var ui = newElement('div', { id: 'adi-opts-view', class: 'adi-hidden' }),
639
- head1 = newElement('span', { class: 'adi-opt-heading' }),
640
- head2 = newElement('span', { class: 'adi-opt-heading' }),
641
- close = newElement('span', { class: 'adi-opt-close' });
642
-
643
- head1.textContent = 'General options';
644
- head2.textContent = 'Observed nodes';
645
-
646
- ui.appendChild(head1);
647
- ui.appendChild(drawOptionRow('saving', 'Enable saving of settings'));
648
- ui.appendChild(drawOptionRow('makeVisible', 'Scroll to the active element in DOM View'));
649
- ui.appendChild(drawOptionRow('omitEmptyText', 'Hide empty text nodes'));
650
- ui.appendChild(drawOptionRow('foldText', 'Fold the text nodes'));
651
- ui.appendChild(drawOptionRow('transparent', 'Enable transparent background'));
652
- ui.appendChild(head2);
653
- ui.appendChild(drawOptionRow('nodeTypes-3', 'Text node'));
654
- ui.appendChild(drawOptionRow('nodeTypes-8', 'Comment node'));
655
- // ui.appendChild(drawOptionRow('nodeTypes-1', 'Element node'));
656
- // ui.appendChild(drawOptionRow('nodeTypes-9', 'Document node'));
657
- ui.appendChild(close);
658
-
659
- return ui;
660
- }
661
-
662
- // Renders the UI
663
- function drawUI() {
664
- var wrapper = newElement('div', {
665
- id: 'adi-wrapper',
666
- class: options.transparent ? 'transparent' : ''
667
- }),
668
- domViewWrap = newElement('div', { id: 'adi-dom-view' }),
669
- domViewContent = newElement('div', { class: 'adi-content' }),
670
- attrViewWrap = newElement('div', { id: 'adi-attr-view' }),
671
- attrViewContent = newElement('div', { class: 'adi-content' }),
672
- horizSplit = newElement('div', { id: 'adi-horiz-split' }),
673
- vertSplit = newElement('div', { id: 'adi-vert-split' }),
674
- domTree = newElement('ul', { class: 'adi-tree-view' }),
675
- domPathWrap = newElement('div', { class: 'adi-path-wrap' }),
676
- domPath = newElement('div', { class: 'adi-path' }),
677
- domPathScrollLeft = newElement('span', { class: 'adi-path-left' }),
678
- domPathScrollRight = newElement('span', { class: 'adi-path-right' }),
679
- naviWrap = newElement('div', { id: 'adi-panel' }),
680
- naviButtons = newElement('div', { class: 'adi-menu-wrap' }),
681
- naviConfig = newElement('a', { class: 'adi-menu-config', title: 'Settings' }),
682
- naviLookup = newElement('a', { class: 'adi-menu-lookup', title: 'Lookup tool' }),
683
- optionsView = drawOptions();
684
-
685
-
686
- // put UI together
687
- domViewContent.appendChild(domTree);
688
- domViewWrap.appendChild(domViewContent);
689
- attrViewWrap.appendChild(attrViewContent);
690
- domPathWrap.appendChild(domPath);
691
- domPathWrap.appendChild(domPathScrollLeft);
692
- domPathWrap.appendChild(domPathScrollRight);
693
- naviButtons.appendChild(naviLookup);
694
- naviButtons.appendChild(naviConfig);
695
- naviWrap.appendChild(domPathWrap);
696
- naviWrap.appendChild(naviButtons);
697
- wrapper.appendChild(naviWrap);
698
- wrapper.appendChild(optionsView);
699
- wrapper.appendChild(domViewWrap);
700
- wrapper.appendChild(horizSplit);
701
- wrapper.appendChild(attrViewWrap);
702
- // wrapper.appendChild(naviWrap);
703
- wrapper.appendChild(vertSplit);
704
-
705
- // cache UI object and append to the DOM
706
-
707
- // #### here it attaches to the body
708
- document.getElementsByTagName('body')[0].appendChild(wrapper);
709
- // document.querySelector('#inspector').appendChild(wrapper);
710
-
711
- uiView = wrapper;
712
- menuView = naviWrap;
713
- domView = uiView.querySelector('#adi-dom-view');
714
- attrView = uiView.querySelector('#adi-attr-view');
715
-
716
- const adiPanel = attrView.querySelector('.adi-content');
717
- adiPanel.setAttribute('id','detailsView');
718
-
719
- pathView = domPath;
720
- optsView = optionsView;
721
- refreshUI(true);
722
- }
723
-
724
- // Refreshes the global UI
725
- function refreshUI(refreshOpts) {
726
- if (uiView === null) {
727
- return false;
728
- }
729
-
730
- // load options if requested (e.g. before the first UI refresh)
731
- if (refreshOpts) {
732
- loadOptions();
733
- }
734
-
735
- // Options view refresh
736
- if (refreshOpts) {
737
- optsView.querySelector('[data-opt="transparent"]').checked = options.transparent;
738
- optsView.querySelector('[data-opt="saving"]').checked = options.saving;
739
- optsView.querySelector('[data-opt="omitEmptyText"]').checked = options.omitEmptyText;
740
- optsView.querySelector('[data-opt="makeVisible"]').checked = options.makeVisible;
741
- optsView.querySelector('[data-opt="foldText"]').checked = options.foldText;
742
- optsView.querySelector('[data-opt="nodeTypes-3"]').checked = options.nodeTypes.indexOf(3) !== -1;
743
- optsView.querySelector('[data-opt="nodeTypes-8"]').checked = options.nodeTypes.indexOf(8) !== -1;
744
- // optsView.querySelector('[data-opt="nodeTypes-1"]').checked = options.nodeTypes.indexOf(1) !== -1;
745
- // optsView.querySelector('[data-opt="nodeTypes-9"]').checked = options.nodeTypes.indexOf(9) !== -1;
746
- }
747
-
748
- // UI appearance refresh
749
- uiView.className = options.transparent ? 'transparent' : '';
750
- uiView.style.display = options.visible ? 'block' : 'none';
751
- uiView.style.width = options.width + 'px';
752
- menuView.style.width = options.width + 'px';
753
- domView.style.height = options.split + '%';
754
- attrView.style.height = (100 - options.split) + '%';
755
- domView.querySelector('.adi-content').style.height = domView.clientHeight + 'px';
756
- attrView.querySelector('.adi-content').style.height = (attrView.clientHeight - menuView.clientHeight) + 'px';
757
- addClass(uiView, options.align);
758
- }
759
-
760
- // UI visibility toggle handler
761
- function toggleVisibilityUI() {
762
- if (uiView === null) {
763
- return false;
764
- }
765
-
766
- uiView.style.display = options.visible ? 'none' : 'block';
767
- options.visible = !options.visible;
768
- saveOptions();
769
- }
770
-
771
- // Helper function for attributes view
772
- function drawAttrRow(attrName, attrValue) {
773
- var row = newElement('span', { class: 'adi-attr' });
774
- switch (attrName.toLowerCase()) {
775
- case 'defaultaction':
776
- row.innerHTML = '<label>' + attrName + ': <select data-attr="' + attrName + '" value="' + attrValue + '"><option>perform</option><option>cancel</option></label>';
777
- break;
778
- case 'delay':
779
- row.innerHTML = '<label>' + attrName + ': <input type="number" data-attr="' + attrName + '" value="' + attrValue + '"></label>';
780
- break;
781
- default:
782
- row.innerHTML = '<label>' + attrName + ': <input type="text" data-attr="' + attrName + '" value="' + attrValue + '"></label>';
783
- }
784
- return row;
785
- }
786
-
787
- // Renders the attribute view
788
- function drawAttrs(elem) {
789
-
790
- //todo: hook element-def.json in here
791
- if(elem.nodeName.startsWith('FX-')){
792
- console.log('got a fore element')
793
- }
794
-
795
- if (typeof elem !== 'object') {
796
- throw "drawAttrs: Expected argument elem of type object, " + typeof elem + " given.";
797
- }
798
-
799
- var content = attrView.querySelector('.adi-content'),
800
- attrsMain = {
801
- 'id': '',
802
- 'class': '',
803
- 'style': ''
804
- },
805
- attrsOther = {},
806
- keys = [],
807
- attr, i, len;
808
-
809
- // prepare attributes
810
- content.innerHTML = '';
811
- for (i = 0, len = elem.attributes.length; i < len; ++i) {
812
- attr = elem.attributes[i];
813
-
814
- switch (attr.nodeName.toLowerCase()) {
815
- case 'id':
816
- attrsMain['id'] = attr.nodeValue;
817
- break;
818
- case 'class':
819
- attrsMain['class'] = attr.nodeValue;
820
- break;
821
- case 'style':
822
- attrsMain['style'] = styleBackup;
823
- break;
824
- default:
825
- attrsOther[attr.nodeName.toLowerCase()] = attr.nodeValue;
826
- }
827
- }
828
-
829
- if(elem.nodeName.startsWith('FX-')){
830
- switch (elem.nodeName) {
831
- case 'FX-BIND':
832
- attrsOther['calculate'] = attrsOther['calculate'] || '';
833
- attrsOther['constraint'] = attrsOther['constraint'] || '';
834
- attrsOther['readonly'] = attrsOther['readonly'] || '';
835
- attrsOther['relevant'] = attrsOther['relevant'] || '';
836
- attrsOther['required'] = attrsOther['required'] || '';
837
- break;
838
- case 'FX-MESSAGE':
839
- case 'FX-SEND':
840
- case 'FX-ACTION':
841
- attrsOther['defaultaction'] = attrsOther['defaultaction'] || '';
842
- attrsOther['delay'] = attrsOther['delay'] || '';
843
- attrsOther['event'] = attrsOther['event'] || '';
844
- attrsOther['handler'] = attrsOther['handler'] || '';
845
- attrsOther['if'] = attrsOther['if'] || '';
846
- attrsOther['phase'] = attrsOther['phase'] || '';
847
- attrsOther['propagate'] = attrsOther['propagate'] || '';
848
- attrsOther['target'] = attrsOther['target'] || '';
849
- attrsOther['while'] = attrsOther['while'] || '';
850
- break;
851
- default:
852
- attrsOther[attr.nodeName.toLowerCase()] = attr.nodeValue;
853
- }
854
- }
855
-
856
- // sort attributes
857
- for (var key in attrsOther) {
858
- keys.push(key);
859
- }
860
- keys.sort();
861
-
862
- // render the content
863
- content.appendChild(drawAttrRow('id', attrsMain['id']));
864
- content.appendChild(drawAttrRow('class', attrsMain['class']));
865
- content.appendChild(drawAttrRow('style', attrsMain['style']));
866
- content.appendChild(newElement('hr'));
867
-
868
- for (i = 0, len = keys.length; i < len; ++i) {
869
- content.appendChild(drawAttrRow(keys[i], attrsOther[keys[i]]));
870
- }
871
- }
872
-
873
- // Handles attribute changes
874
- function changeAttribute(e) {
875
- var target = e ? e.target : window.event.srcElement,
876
- attr = target.getAttribute('data-attr'),
877
- val = target.value,
878
- elem = getSelected();
879
-
880
- // remove attribute if the new value is empty
881
- if (val === '') {
882
- elem.removeAttribute(attr);
883
- } else {
884
- elem.setAttribute(attr, val);
885
- }
886
- }
887
-
888
- // Handles option changes
889
- function changeOption(e) {
890
- var target = e ? e.target : window.event.srcElement,
891
- data = target.getAttribute('data-opt'),
892
- val = target.checked;
893
-
894
- if (data.indexOf('nodeTypes') !== -1) {
895
- var type = parseInt(data.match(/\d+/)[0]);
896
-
897
- if (val) {
898
- options.nodeTypes.push(type);
899
- } else {
900
- options.nodeTypes.splice(options.nodeTypes.indexOf(type), 1);
901
- }
902
- } else {
903
- options[data] = val;
904
- }
905
- }
906
-
907
- // Key events processing
908
- function processKey(e) {
909
- e = e || window.event;
910
- var code = e.keyCode || e.which;
911
-
912
- switch (code) {
913
- case 272: // ctrl + alt + d
914
- toggleVisibilityUI();
915
- break;
916
- }
917
- }
918
-
919
- // Vertical splitter resize handler
920
- function verticalResize(e) {
921
- if (!vertResizing) {
922
- return;
923
- }
924
-
925
- e = e || window.event;
926
- document.documentElement.style.cursor = 'e-resize';
927
- var nWidth = options.width + xPos - e.clientX;
928
-
929
- if (nWidth >= options.minWidth) {
930
- options.width = nWidth;
931
- xPos = e.clientX;
932
- refreshUI();
933
- saveOptions();
934
- }
935
-
936
- checkPathOverflow();
937
- }
938
-
939
- // Horizontal splitter resize handler
940
- function horizontalResize(e) {
941
- if (!horizResizing) {
942
- return;
943
- }
944
-
945
- e = e || window.event;
946
- document.documentElement.style.cursor = 'n-resize';
947
- var nSplit = Math.floor(e.clientY / uiView.clientHeight * 100);
948
-
949
- if (nSplit >= options.minSplit && nSplit <= 100 - options.minSplit) {
950
- options.split = nSplit;
951
- refreshUI();
952
- saveOptions();
953
- }
954
- }
955
-
956
- // Dom view folding handler
957
- function handleFolding(e) {
958
- var target = e ? e.target : window.event.srcElement,
959
- ul = target.parentNode.querySelector('ul');
960
-
961
- if (ul.getAttribute('data-open') === "true") {
962
- removeClass(target, 'opened');
963
- addClass(target, 'closed');
964
- ul.setAttribute('data-open', "false");
965
- } else {
966
- removeClass(target, 'closed');
967
- addClass(target, 'opened');
968
- ul.setAttribute('data-open', "true");
969
- }
970
- }
971
-
972
- // Handles active element selection
973
- function handleActive(e) {
974
-
975
-
976
- var target = e ? e.target : window.event.srcElement,
977
- active = domView.querySelector('.adi-active-node');
978
-
979
- if (active) {
980
- removeClass(active, 'adi-active-node');
981
- }
982
-
983
- // clicked on normal-node or end-node?
984
- if (target.className === 'adi-end-node') {
985
- target = target.parentNode.querySelector('.adi-normal-node');
986
- }
987
-
988
- activeElement = target;
989
- addClass(target, 'adi-active-node');
990
- pathView.textContent = target.getAttribute('data-css-path');
991
-
992
- this.dispatchEvent(
993
- new CustomEvent('handle-active', {
994
- composed: true,
995
- bubbles: true,
996
- detail: { active: activeElement, selected: getSelected()},
997
- }),
998
- );
999
-
1000
-
1001
- // make it visible (scroll)
1002
- if (options.makeVisible) {
1003
- var wrap = domView.querySelector('.adi-content');
1004
- if (target.offsetTop >= wrap.clientHeight || target.offsetTop <= wrap.scrollTop) {
1005
- wrap.scrollTop = target.offsetTop - (Math.floor(wrap.clientHeight / 2));
1006
- }
1007
- }
1008
-
1009
- checkPathOverflow();
1010
- drawAttrs(getSelected());
1011
- const fore = document.createElement('fx-fore');
1012
- fore.setAttribute('src','inspector/inspector.html');
1013
- // const detailsView = document.getElementById('detailsView');
1014
- // detailsView.appendChild(fore);
1015
- }
1016
-
1017
- // Checks if pathView is overflowing or not
1018
- function checkPathOverflow() {
1019
- if (pathView.scrollWidth > pathView.clientWidth) {
1020
- addClass(pathView.parentNode, 'adi-overflowing');
1021
- } else {
1022
- removeClass(pathView.parentNode, 'adi-overflowing');
1023
- }
1024
- }
1025
-
1026
- // Handles scroll behavior for overflowing pathView
1027
- function scrollPathView(e) {
1028
- var target = e ? e.target : window.event.srcElement,
1029
- maxScroll = pathView.scrollWidth - pathView.clientWidth,
1030
- scroll = pathView.scrollLeft,
1031
- change = 5;
1032
-
1033
- if (target.className === "adi-path-right") {
1034
- pathView.scrollLeft = (scroll <= maxScroll - change) ? scroll + change : maxScroll;
1035
- } else {
1036
- pathView.scrollLeft = (scroll - change >= 0) ? scroll - change : 0;
1037
- }
1038
-
1039
- if (!pathScrolling) {
1040
- pathScrolling = setInterval(scrollPathView, 20, e);
1041
- }
1042
- }
1043
-
1044
- // Highlights an element on page
1045
- function highlightElement(e) {
1046
- var target = e ? e.target : window.event.srcElement,
1047
- node = document,
1048
- path;
1049
-
1050
- if (target.className === 'adi-end-node') {
1051
- target = target.parentNode.querySelector('.adi-normal-node');
1052
- }
1053
-
1054
- path = JSON.parse(target.getAttribute('data-js-path'));
1055
-
1056
- // find the element
1057
- for (var i = 0, len = path.length; i < len; ++i) {
1058
- node = node.childNodes[path[i]];
1059
- }
1060
-
1061
- if (node) {
1062
- if (e.type === 'mouseover') {
1063
- styleBackup = node.getAttribute('style') || '';
1064
- node.setAttribute('style', 'outline: 1px dashed red; ' + styleBackup);
1065
- } else {
1066
- if (styleBackup === '') {
1067
- node.removeAttribute('style');
1068
- } else {
1069
- node.setAttribute('style', styleBackup);
1070
- }
1071
- }
1072
- }
1073
- }
1074
-
1075
- // Handles element lookup on page
1076
- function handleLookup(e) {
1077
- var target = e ? e.target : window.event.srcElement;
1078
-
1079
- if (target.className.indexOf('adi-menu-lookup') !== -1) {
1080
- // enable/disable interactive lookup
1081
- if (elemLookup) {
1082
- removeClass(target, 'adi-active');
1083
- elemLookup = false;
1084
- removeEvent(document.body, 'mouseover', handleLookup, true);
1085
- removeEvent(document.body, 'mouseout', handleLookup, true);
1086
- removeEvent(document.body, 'click', handleLookup, true);
1087
- } else {
1088
- addClass(target, 'adi-active');
1089
- elemLookup = true;
1090
- addEventDelegate(document.body, 'mouseover', handleLookup, false, '*', true, 'adi-wrapper');
1091
- addEventDelegate(document.body, 'mouseout', handleLookup, false, '*', true, 'adi-wrapper');
1092
- addEventDelegate(document.body, 'click', handleLookup, false, '*', true, 'adi-wrapper');
1093
- }
1094
- } else {
1095
- // handle lookup events
1096
- if (e.type === 'mouseover') {
1097
- styleBackup = target.getAttribute('style') || '';
1098
- target.setAttribute('style', 'outline: 1px dashed red; ' + styleBackup);
1099
- } else if (e.type === 'mouseout') {
1100
- target.setAttribute('style', styleBackup);
1101
- } else {
1102
- elemLookup = false;
1103
- removeClass(menuView.querySelector('.adi-menu-lookup'), 'adi-active');
1104
- target.setAttribute('style', styleBackup);
1105
- removeEvent(document.body, 'mouseover', handleLookup, true);
1106
- removeEvent(document.body, 'mouseout', handleLookup, true);
1107
- removeEvent(document.body, 'click', handleLookup, true);
1108
- pauseEvent(e);
1109
-
1110
- // find corresponding node in the DOM view
1111
- var path = getElemPaths(target),
1112
- active = domView.querySelector('[data-js-path=\'' + JSON.stringify(path.jsPath) + '\']');
1113
-
1114
- // activate it
1115
- if (active) {
1116
- active.click();
1117
- }
1118
-
1119
- // open the whole path in DOM view
1120
- var node = active.parentNode,
1121
- tmp;
1122
-
1123
- if (node.querySelector('ul')) {
1124
- node.querySelector('ul').setAttribute('data-open', 'true');
1125
- }
1126
- while(node !== domView.querySelector('.adi-content')) {
1127
- if (node.className.indexOf('adi-node') !== -1) {
1128
- tmp = node.querySelector('.adi-trigger');
1129
- removeClass(tmp, 'closed');
1130
- addClass(tmp, 'opened');
1131
-
1132
- node = node.parentNode; // ul node
1133
- node.setAttribute('data-open', 'true');
1134
- }
1135
-
1136
- node = node.parentNode;
1137
- }
1138
-
1139
- // make it visible (scroll)
1140
- if (options.makeVisible) {
1141
- var wrap = domView.querySelector('.adi-content');
1142
- if (active.offsetTop >= wrap.clientHeight || active.offsetTop <= wrap.scrollTop) {
1143
- wrap.scrollTop = active.offsetTop - (Math.floor(wrap.clientHeight / 2));
1144
- }
1145
- }
1146
- }
1147
- }
1148
- }
1149
-
1150
- // Event registration
1151
- function registerEvents() {
1152
- var vertSplit = document.getElementById('adi-vert-split'),
1153
- horizSplit = document.getElementById('adi-horiz-split');
1154
-
1155
- // events for splitters
1156
- addEvent(vertSplit, 'mousedown', function(e) {
1157
- e = e || window.event;
1158
- pauseEvent(e);
1159
- vertResizing = true;
1160
- xPos = e.clientX;
1161
- }, false);
1162
-
1163
- addEvent(horizSplit, 'mousedown', function(e) {
1164
- e = e || window.event;
1165
- pauseEvent(e);
1166
- horizResizing = true;
1167
- }, false);
1168
-
1169
- addEvent(document, 'mouseup', function() {
1170
- document.documentElement.style.cursor = 'default';
1171
- vertResizing = false;
1172
- horizResizing = false;
1173
- }, false);
1174
-
1175
- addEvent(document, 'mousemove', verticalResize, false);
1176
- addEvent(document, 'mousemove', horizontalResize, false);
1177
-
1178
- // window resize
1179
- addEvent(window, 'resize', refreshUI, false);
1180
-
1181
- // keypress events
1182
- addEvent(document, 'keypress', processKey, false);
1183
-
1184
- // dom tree view folding
1185
- addEventDelegate(domView, 'click', handleFolding, false, '.adi-trigger');
1186
-
1187
- // active element
1188
- addEventDelegate(domView, 'click', handleActive, false, '.adi-normal-node');
1189
- addEventDelegate(domView, 'click', handleActive, false, '.adi-end-node');
1190
-
1191
- // path view scrolling
1192
- addEventDelegate(pathView.parentNode, 'mousedown', scrollPathView, false, '.adi-path-left');
1193
- addEventDelegate(pathView.parentNode, 'mousedown', scrollPathView, false, '.adi-path-right');
1194
- addEventDelegate(pathView.parentNode, 'mouseup', function() {
1195
- clearInterval(pathScrolling);
1196
- pathScrolling = false;
1197
- }, false, '.adi-path-left');
1198
- addEventDelegate(pathView.parentNode, 'mouseup', function() {
1199
- clearInterval(pathScrolling);
1200
- pathScrolling = false;
1201
- }, false, '.adi-path-right');
1202
-
1203
- // matching tag highlighting
1204
- addEventDelegate(domView, 'mouseover', function(e) {
1205
- var target = e ? e.target : window.event.srcElement;
1206
- addClass(target.parentNode.querySelector('.adi-normal-node'), 'hover');
1207
- }, false, '.adi-end-node');
1208
- addEventDelegate(domView, 'mouseout', function(e) {
1209
- var target = e ? e.target : window.event.srcElement;
1210
- removeClass(target.parentNode.querySelector('.adi-normal-node'), 'hover');
1211
- }, false, '.adi-end-node');
1212
-
1213
- // page element highlighting
1214
- addEventDelegate(domView, 'mouseover', highlightElement, false, '.adi-end-node');
1215
- addEventDelegate(domView, 'mouseover', highlightElement, false, '.adi-normal-node');
1216
- addEventDelegate(domView, 'mouseout', highlightElement, false, '.adi-end-node');
1217
- addEventDelegate(domView, 'mouseout', highlightElement, false, '.adi-normal-node');
1218
-
1219
- // element lookup
1220
- addEvent(menuView.querySelector('.adi-menu-lookup'), 'click', handleLookup, false);
1221
-
1222
- // options events
1223
- addEventDelegate(optsView, 'change', changeOption, false, 'input');
1224
- addEventDelegate(optsView, 'click', toggleOptions, false, '.adi-opt-close');
1225
- addEvent(menuView.querySelector('.adi-menu-config'), 'click', toggleOptions, false);
1226
-
1227
- // attributes events
1228
- addEventDelegate(attrView, 'change', changeAttribute, false, 'input');
1229
- }
1230
-
1231
- drawUI();
1232
- registerEvents();
1233
- drawDOM(document, domView.querySelector('.adi-tree-view'), true);
1234
-
1235
- return {
1236
- // TODO: public methods and variables (this will be visible to the global scope)
1237
- getSelectedElement: getSelected,
1238
- toggle: toggleVisibilityUI
1239
- };
1240
- })();
1241
-
1242
-
1243
- appInit() {
1244
- // make public API visible to the global scope
1245
- window.ADI = ADI;
1246
-
1247
- }
1248
-
1249
- // Launch the app when the DOM is ready and all assets are loaded
1250
- addEvent(window, 'load', appInit, false);
1251
-
1252
- }
1253
- if (!customElements.get('fx-dom-inspector')) {
1254
- customElements.define('fx-dom-inspector', FxDomInspector);
1255
- }