@jinntec/fore 3.3.2 → 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,444 +0,0 @@
1
- /**
2
- * A simple collapsible treeview for showing JSON data.
3
- *
4
- */
5
- class FxJsonInstance extends HTMLElement {
6
- // constructor(container, options = {}) {
7
- constructor() {
8
- super();
9
- const shadowRoot = this.attachShadow({ mode: 'open' });
10
- this.instanceElement = null;
11
- this.foreSelector = null;
12
- }
13
-
14
- connectedCallback() {
15
- this.container = this.querySelector('.json-path-picker-container');
16
- this.foreSelector = this.hasAttribute('fore') ? this.getAttribute('fore') : 'fx-fore'; // default to first one in doc
17
- this.render();
18
- }
19
-
20
- render() {
21
- const style = `
22
- @import '../../resources/fore.css';
23
-
24
- :host {
25
- display:block;
26
- font-size:0.8em;
27
- background:rgba(250, 250, 250, 0.9);
28
- }
29
- .container{
30
- margin-left:1em;
31
- }
32
- .header{
33
- margin-left:0;
34
- }
35
-
36
- ::slot[name='header']{
37
- margin-left:-1em;
38
- }
39
- /* Syntax highlighting for JSON objects */
40
- ul.json-dict, ol.json-array {
41
- list-style-type: none;
42
- margin: 0 0 0 1px;
43
- border-left: 1px dotted #ccc;
44
- padding-left: 2em;
45
- }
46
- .json-string {
47
- // color: #0B7500;
48
- }
49
- .json-literal {
50
- color: #1A01CC;
51
- font-weight: bold;
52
- }
53
-
54
- /* Toggle button */
55
- a.json-toggle {
56
- position: relative;
57
- color: inherit;
58
- text-decoration: none;
59
- }
60
- a.json-toggle:focus {
61
- outline: none;
62
- }
63
- a.json-toggle:before {
64
- content: "\\25BC"; /* down arrow */
65
- position: absolute;
66
- display: inline-block;
67
- width: 1em;
68
- left: -1.2em;
69
- font-size:0.8em;
70
- }
71
- a.json-toggle.collapsed:before {
72
- content: "\\25B6"; /* left arrow */
73
- }
74
-
75
- /* Collapsable placeholder links */
76
- a.json-placeholder {
77
- color: #aaa;
78
- padding: 0 1em;
79
- text-decoration: none;
80
- }
81
- a.json-placeholder:hover {
82
- text-decoration: underline;
83
- }
84
-
85
- /* Copy path icon */
86
- .pick-path {
87
- color: lightgray;
88
- cursor: pointer;
89
- margin-left: 3px;
90
- }
91
-
92
- .pick-path:hover {
93
- color: darkgray;
94
- }
95
-
96
- `;
97
-
98
- const instanceId = this.hasAttribute('instance') ? this.getAttribute('instance') : 'default';
99
- const fore = document.querySelector(this.foreSelector);
100
- if (!fore) {
101
- throw new Error(`this '${this.foreSelector}' does not match a fx-fore element`);
102
- }
103
-
104
- const html = `
105
- <div class="container"></div>
106
- `;
107
-
108
- this.shadowRoot.innerHTML = `
109
- <style>
110
- ${style}
111
- </style>
112
- <slot name="header">
113
- <header class="header">${instanceId}</header>
114
- </slot>
115
- <slot></slot>
116
- ${html}
117
- `;
118
-
119
- // fore.addEventListener('ready', e => {
120
-
121
- const instanceElement = document.querySelector(`#${instanceId}`);
122
- if (
123
- !instanceElement ||
124
- instanceElement.nodeName !== 'FX-INSTANCE' ||
125
- instanceElement.getAttribute('type') !== 'json'
126
- ) {
127
- throw new Error(
128
- `this '${instanceId}' does not match an fx-instance element or is not of type JSON`,
129
- );
130
- }
131
- const container = this.shadowRoot.querySelector('.container');
132
-
133
- const json = instanceElement.instanceData;
134
- let tree = this.json2html(json, { outputWithQuotes: true });
135
- if (this.isCollapsable(json)) tree = '<a href=\'#\' class="json-toggle"></a>'.concat(tree); // Insert HTML in target DOM element
136
-
137
- container.innerHTML = tree;
138
-
139
- const toggles = this.shadowRoot.querySelectorAll('.json-toggle');
140
- toggles.forEach(toggle => {
141
- toggle.addEventListener('click', this._handleToggleEvent.bind(this));
142
- });
143
- // container.addEventListener('click', (event) => this._handleToggleEvent);
144
- // });
145
- }
146
-
147
- disconnectedCallback() {}
148
-
149
- _isHidden(elem) {
150
- const width = elem.offsetWidth;
151
- const height = elem.offsetHeight;
152
- return (width === 0 && height === 0) || window.getComputedStyle(elem).display === 'none';
153
- }
154
-
155
- _handleToggleEvent(event) {
156
- // Change class
157
- // event.preventDefault();
158
- // event.stopPropagation();
159
-
160
- const elm = event.target;
161
- elm.classList.toggle('collapsed'); // Fetch every json-dict and json-array to toggle them
162
-
163
- const subTarget = this._siblings(elm, 'ul.json-dict, ol.json-array', el => {
164
- el.style.display = el.style.display === '' || el.style.display === 'block' ? 'none' : 'block';
165
- }); // ForEach subtarget, previous siblings return array so we parse it
166
-
167
- for (let i = 0; i < subTarget.length; i += 1) {
168
- if (!this._isHidden(subTarget[i])) {
169
- // Parse every siblings with '.json-placehoder' and remove them (previous add by else)
170
- this._siblings(subTarget[i], '.json-placeholder', el => el.parentNode.removeChild(el));
171
- } else {
172
- // count item in object / array
173
- const childs = subTarget[i].children;
174
- let count = 0;
175
-
176
- for (let j = 0; j < childs.length; j += 1) {
177
- if (childs[j].tagName === 'LI') {
178
- count += 1;
179
- }
180
- }
181
-
182
- const placeholder = count + (count > 1 ? ' items' : ' item'); // Append a placeholder
183
- subTarget[i].insertAdjacentHTML(
184
- 'afterend',
185
- '<a href class="json-placeholder">'.concat(placeholder, '</a>'),
186
- );
187
- }
188
- } // Prevent propagation
189
-
190
- event.stopPropagation();
191
- event.preventDefault();
192
- }
193
-
194
- _siblings(el, sel, callback) {
195
- const sibs = [];
196
-
197
- for (let i = 0; i < el.parentNode.children.length; i += 1) {
198
- const child = el.parentNode.children[i];
199
-
200
- if (child !== el && typeof sel === 'string' && child.matches(sel)) {
201
- sibs.push(child);
202
- }
203
- } // If a callback is passed, call it on each sibs
204
-
205
- if (callback && typeof callback === 'function') {
206
- for (let _i = 0; _i < sibs.length; _i += 1) {
207
- callback(sibs[_i]);
208
- }
209
- }
210
-
211
- return sibs;
212
- }
213
-
214
- json2html(json, options) {
215
- let html = '';
216
-
217
- if (typeof json === 'string') {
218
- // Escape tags
219
- const tmp = json
220
- .replace(/&/g, '&amp;')
221
- .replace(/</g, '&lt;')
222
- .replace(/>/g, '&gt;')
223
- .replace(/"/g, '&quot;');
224
-
225
- if (this.isUrl(tmp)) {
226
- html += '<a href="'.concat(tmp, '" class="json-string">').concat(tmp, '</a>');
227
- } else {
228
- html += '<span class="json-string">"'.concat(tmp, '"</span>');
229
- }
230
- } else if (typeof json === 'number') {
231
- html += '<span class="json-literal">'.concat(json, '</span>');
232
- } else if (typeof json === 'boolean') {
233
- html += '<span class="json-literal">'.concat(json, '</span>');
234
- } else if (json === null) {
235
- html += '<span class="json-literal">null</span>';
236
- } else if (json instanceof Array) {
237
- if (json.length > 0) {
238
- html += '[<ol class="json-array">';
239
-
240
- for (let i = 0; i < json.length; i += 1) {
241
- html += '<li data-key-type="array" data-key="'.concat(i, '">'); // Add toggle button if item is collapsable
242
-
243
- if (this.isCollapsable(json[i])) {
244
- html += '<a href="#" class="json-toggle"></a>';
245
- }
246
-
247
- html += this.json2html(json[i], options); // Add comma if item is not last
248
-
249
- if (i < json.length - 1) {
250
- html += ',';
251
- }
252
-
253
- html += '</li>';
254
- }
255
-
256
- html += '</ol>]';
257
- } else {
258
- html += '[]';
259
- }
260
- } else if (this._typeof(json) === 'object') {
261
- let keyCount = Object.keys(json).length;
262
-
263
- if (keyCount > 0) {
264
- html += '{<ul class="json-dict">';
265
-
266
- for (const key in json) {
267
- if (json.hasOwnProperty(key)) {
268
- html += '<li data-key-type="object" data-key="'.concat(key, '">');
269
- const keyRepr = options.outputWithQuotes
270
- ? '<span class="json-string">"'.concat(key, '"</span>')
271
- : key; // Add toggle button if item is collapsable
272
-
273
- if (this.isCollapsable(json[key])) {
274
- html += '<a href=\'#\' class="json-toggle">'.concat(keyRepr, '</a>');
275
- } else {
276
- html += keyRepr;
277
- }
278
-
279
- // ### keep the following comment for later - pick path is a good idea but needs to be adapted to XPath syntax
280
- // html += '<span class="pick-path" title="Pick path">&#10697;</span>';
281
- html += ': '.concat(this.json2html(json[key], options)); // Add comma if item is not last
282
-
283
- keyCount -= 1;
284
-
285
- if (keyCount > 0) {
286
- html += ',';
287
- }
288
-
289
- html += '</li>';
290
- }
291
- }
292
-
293
- html += '</ul>}';
294
- } else {
295
- html += '{}';
296
- }
297
- }
298
-
299
- return html;
300
- }
301
-
302
- isUrl(string) {
303
- const regexp =
304
- /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#:.?+=&%@!\-/]))?/;
305
- return regexp.test(string);
306
- }
307
-
308
- _typeof(obj) {
309
- if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
310
- this._typeof = function _typeof(obj) {
311
- return typeof obj;
312
- };
313
- } else {
314
- this._typeof = function _typeof(obj) {
315
- return obj &&
316
- typeof Symbol === 'function' &&
317
- obj.constructor === Symbol &&
318
- obj !== Symbol.prototype
319
- ? 'symbol'
320
- : typeof obj;
321
- };
322
- }
323
- return this._typeof(obj);
324
- }
325
-
326
- isCollapsable(arg) {
327
- return arg instanceof Object && Object.keys(arg).length > 0;
328
- }
329
-
330
- /*
331
- setup() {
332
- // Create shadow DOM
333
-
334
- // Add styles to shadow DOM
335
- const style = document.createElement('style');
336
- style.textContent = `
337
- /!* add your CSS styles here *!/
338
- `;
339
- shadowRoot.appendChild(style);
340
-
341
- // Move content to shadow DOM
342
- const container = this.container.cloneNode(true);
343
- shadowRoot.appendChild(container);
344
- this.container.remove();
345
- this.container = shadowRoot.querySelector('.json-path-picker-container');
346
- this.clearBtn = shadowRoot.querySelector('.json-path-picker-clear-btn');
347
- this.jsonTextarea = shadowRoot.querySelector('.json-path-picker-json');
348
- this.treeView = shadowRoot.querySelector('.json-path-picker-tree');
349
- this.resultView = shadowRoot.querySelector('.json-path-picker-result');
350
-
351
- const data = {
352
- "automobiles": [
353
- {
354
- "maker": "Nissan",
355
- "model": "Teana",
356
- "year": 2000
357
- },
358
- {
359
- "maker": "Honda",
360
- "model": "Jazz",
361
- "year": 2023
362
- },
363
- {
364
- "maker": "Honda",
365
- "model": "Civic",
366
- "year": 2007
367
- },
368
- {
369
- "maker": "Toyota",
370
- "model": "Yaris",
371
- "year": 2008
372
- },
373
- {
374
- "maker": "Honda",
375
- "model": "Accord",
376
- "year": 2011
377
- }
378
- ],
379
- "motorcycles": [{
380
- "maker": "Honda",
381
- "model": "ST1300",
382
- "year": 2012
383
- }]
384
- }
385
-
386
- this.updateTree(JSON.stringify(data));
387
-
388
- }
389
- */
390
-
391
- static get observedAttributes() {
392
- return ['data'];
393
- }
394
-
395
- attributeChangedCallback(name, oldValue, newValue) {
396
- if (name === 'data') {
397
- this.jsonTextarea.value = newValue;
398
- this.updateTree(newValue);
399
- }
400
- }
401
-
402
- updateTree(jsonString) {
403
- try {
404
- this.data = JSON.parse(jsonString);
405
- this.treeView.innerHTML = '';
406
- this.treeView.appendChild(this.createTreeView(this.data, ''));
407
- } catch (e) {
408
- console.error(e);
409
- alert('Invalid JSON');
410
- }
411
- }
412
-
413
- createTreeView(data, path) {
414
- const ul = document.createElement('ul');
415
- ul.classList.add('jp-ul');
416
- if (Array.isArray(data)) {
417
- data.forEach((item, index) => {
418
- const li = document.createElement('li');
419
- li.classList.add('jp-li');
420
- const newPath = `${path}[${index}]`;
421
- li.appendChild(this.createItemView(newPath, item));
422
- ul.appendChild(li);
423
- });
424
- } else if (typeof data === 'object' && data !== null) {
425
- Object.keys(data).forEach(key => {
426
- const li = document.createElement('li');
427
- li.classList.add('jp-li');
428
- const newPath = `${path}.${key}`;
429
- li.appendChild(this.createItemView(newPath, data[key]));
430
- ul.appendChild(li);
431
- });
432
- } else {
433
- const li = document.createElement('li');
434
- li.classList.add('jp-li');
435
- li.appendChild(this.createItemView(path, data));
436
- ul.appendChild(li);
437
- }
438
- return ul;
439
- }
440
- }
441
-
442
- if (!customElements.get('fx-json-instance')) {
443
- customElements.define('fx-json-instance', FxJsonInstance);
444
- }
@@ -1,128 +0,0 @@
1
- export class FxLogItem extends HTMLElement {
2
- constructor() {
3
- super();
4
- this.attachShadow({ mode: 'open' });
5
- this.eventName = '';
6
- this.shortName = '';
7
- this.shortInfo = '';
8
- this.shortPath = '';
9
- this.xpath = '';
10
- }
11
-
12
- connectedCallback() {
13
- const style = `
14
- :host {
15
- height: auto;
16
- font-size: 0.8em;
17
- font-weight: 400;
18
-
19
- }
20
-
21
- a,a:link,a:visited{
22
- color:black;
23
- }
24
- a{
25
- position:relative;
26
- }
27
- a[alt]:hover::after {
28
- content:attr(alt);
29
- position:absolute;
30
- left:0;
31
- top:1em;
32
- border.thin solid;
33
- padding:0.5em;
34
- background:white;
35
- z-index:1;
36
- min-width:5em;
37
- border:thin solid;
38
- white-space:nowrap;
39
- overflow-wrap:break-word;
40
- }
41
-
42
- .info{
43
- padding:0 0.5em;
44
- margin:0.1rem 0;
45
- background:white;
46
- position:relative;
47
- border:1px solid #ddd;
48
- border-radius:1em;
49
- box-shadow: 1px 1px 5px 0px rgba(79, 136, 183, 0.8);
50
- }
51
- :host(.action) .info{
52
- border-radius:0;
53
- border-color:steelblue;
54
- }
55
-
56
- .info label{
57
- grid-area:left;
58
- overflow: hidden;
59
- text-overflow: ellipsis;
60
- }
61
- .info a{
62
- grid-area:right;
63
- justify-self:end;
64
- }
65
- .info:hover{
66
- outline:3px solid lightblue;
67
- transition:height 0.4s;
68
- }
69
-
70
- summary{
71
- padding:1em;
72
- display:flex;
73
- flex-wrap:wrap;
74
- padding:0.5em 0;
75
- cursor:pointer;
76
- gap:0.25em;
77
- }
78
- /*
79
- .log-name{
80
- font-size:1.2em;
81
- }
82
- .log-name, .short-info{
83
- width:10em;
84
- }
85
- */
86
- .event-name{
87
- width:12em;
88
- text-align:right;
89
- }
90
- .short-info{
91
- flex:3;
92
- overflow:hidden;
93
- white-space:nowrap;
94
- text-overflow:ellipsis;
95
- }
96
- `;
97
-
98
- this.eventName = this.getAttribute('event-name');
99
- this.shortName = this.getAttribute('short-name');
100
- this.shortInfo = this.hasAttribute('short-info') ? this.getAttribute('short-info') : '';
101
- this.xpath = this.getAttribute('xpath');
102
-
103
- const cut = this.xpath.substring(this.xpath.indexOf('/fx-fore'), this.xpath.length);
104
- const xpathCut = `/${cut}`;
105
- const shortPath = xpathCut.replaceAll('fx-', '');
106
-
107
- const html = `
108
- <details class="info send">
109
- <summary>
110
- <span class="log-name"><a href="#" title="${shortPath}" data-path="${this.xpath}">${this.shortName}</a></span>
111
- <span class="short-info">${this.shortInfo}</span>
112
- <span class="event-name">${this.eventName}</span>
113
- </summary>
114
- <slot></slot>
115
- </details>
116
- `;
117
-
118
- this.shadowRoot.innerHTML = `
119
- <style>
120
- ${style}
121
- </style>
122
- ${html}
123
- `;
124
- }
125
- }
126
- if (!customElements.get('fx-log-item')) {
127
- customElements.define('fx-log-item', FxLogItem);
128
- }