@jinntec/fore 1.5.0 → 1.7.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.
- package/dist/fore-dev.js +2 -36
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +2 -30
- package/dist/fore.js.map +1 -1
- package/index.js +13 -0
- package/package.json +9 -5
- package/resources/fore.css +178 -92
- package/src/DependencyNotifyingDomFacade.js +1 -2
- package/src/ForeElementMixin.js +31 -5
- package/src/actions/abstract-action.js +379 -297
- package/src/actions/fx-action.js +0 -1
- package/src/actions/fx-append.js +1 -2
- package/src/actions/fx-confirm.js +12 -0
- package/src/actions/fx-copy.js +0 -1
- package/src/actions/fx-delete.js +31 -9
- package/src/actions/fx-dispatch.js +19 -5
- package/src/actions/fx-hide.js +19 -0
- package/src/actions/fx-insert.js +72 -8
- package/src/actions/fx-load.js +253 -0
- package/src/actions/fx-message.js +22 -7
- package/src/actions/fx-refresh.js +11 -1
- package/src/actions/fx-reload.js +12 -2
- package/src/actions/fx-replace.js +5 -4
- package/src/actions/fx-reset.js +48 -0
- package/src/actions/fx-return.js +0 -1
- package/src/actions/fx-send.js +40 -2
- package/src/actions/fx-setfocus.js +25 -7
- package/src/actions/fx-setvalue.js +32 -4
- package/src/actions/fx-show.js +14 -2
- package/src/actions/fx-toggle.js +0 -1
- package/src/actions/fx-toggleboolean.js +58 -0
- package/src/actions/fx-update.js +9 -0
- package/src/events.js +0 -1
- package/src/fore.js +118 -63
- package/src/functions/common-function.js +28 -0
- package/src/fx-bind.js +9 -7
- package/src/fx-fore.js +153 -55
- package/src/fx-instance.js +55 -17
- package/src/fx-model.js +31 -33
- package/src/fx-submission.js +50 -47
- package/src/getInScopeContext.js +8 -10
- package/src/lab/fore-component.js +90 -0
- package/src/lab/instance-inspector.js +56 -0
- package/src/lab/template.html +16 -0
- package/src/relevance.js +27 -1
- package/src/tools/adi.js +1056 -0
- package/src/tools/fx-action-log.js +662 -0
- package/src/tools/fx-devtools.js +444 -0
- package/src/tools/fx-dom-inspector.js +609 -0
- package/src/tools/fx-json-instance.js +435 -0
- package/src/tools/fx-log-item.js +133 -0
- package/src/tools/fx-log-settings.js +474 -0
- package/src/tools/fx-minimap.js +194 -0
- package/src/tools/helpers.js +132 -0
- package/src/ui/abstract-control.js +41 -3
- package/src/ui/fx-alert.js +0 -1
- package/src/ui/fx-container.js +14 -3
- package/src/ui/fx-control.js +553 -474
- package/src/ui/fx-dialog.js +2 -0
- package/src/ui/fx-dom-inspector.js +1255 -0
- package/src/ui/fx-group.js +3 -4
- package/src/ui/fx-hint.js +2 -4
- package/src/ui/fx-inspector.js +5 -6
- package/src/ui/fx-items.js +55 -14
- package/src/ui/fx-output.js +36 -17
- package/src/ui/fx-repeat-attributes.js +10 -43
- package/src/ui/fx-repeat.js +5 -7
- package/src/ui/fx-switch.js +14 -3
- package/src/ui/fx-trigger.js +13 -1
- package/src/xpath-evaluation.js +109 -26
- package/src/xpath-util.js +55 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export function addClass(element, strClass) {
|
|
2
|
+
element.classList.add(strClass);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function removeClass(element, strClass) {
|
|
6
|
+
element.classList.remove(strClass);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Checks whether the text node is not empty or contains only the EOL
|
|
10
|
+
export function isEmptyTextNode(node) {
|
|
11
|
+
if (typeof node !== 'object') {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`isEmptyTextNode: Expected argument node of type object, ${typeof node} given.`,
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return /^\s*$/.test(node.textContent);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Checks whether the node or its children contains only text information
|
|
21
|
+
export function containsOnlyText(node, checkChildren) {
|
|
22
|
+
if (typeof node !== 'object') {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`containsOnlyText: Expected argument node of type object, ${typeof node} given.`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
checkChildren = checkChildren || false;
|
|
29
|
+
|
|
30
|
+
let result = false;
|
|
31
|
+
let nodeTmp = null;
|
|
32
|
+
|
|
33
|
+
// does the node contain only text nodes?
|
|
34
|
+
if (checkChildren) {
|
|
35
|
+
for (let i = 0, len = node.childNodes.length; i < len; i += 1) {
|
|
36
|
+
nodeTmp = node.childNodes[i];
|
|
37
|
+
result =
|
|
38
|
+
nodeTmp.nodeType === Node.TEXT_NODE ||
|
|
39
|
+
nodeTmp.nodeType === Node.COMMENT_NODE ||
|
|
40
|
+
nodeTmp.nodeType === Node.CDATA_SECTION_NODE;
|
|
41
|
+
|
|
42
|
+
if (!result) {
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
// check the node type if it doesn't have any children
|
|
48
|
+
result =
|
|
49
|
+
node.nodeType === Node.TEXT_NODE ||
|
|
50
|
+
node.nodeType === Node.COMMENT_NODE ||
|
|
51
|
+
node.nodeType === Node.CDATA_SECTION_NODE;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Create element wrapper -- allows to set attributes using the config object.
|
|
58
|
+
export function newElement(elem, attrs) {
|
|
59
|
+
const el = document.createElement(elem);
|
|
60
|
+
|
|
61
|
+
attrs = attrs || {};
|
|
62
|
+
for (const attr of Object.keys(attrs)) {
|
|
63
|
+
el.setAttribute(attr, attrs[attr]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return el;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Helper function for options view
|
|
70
|
+
export function drawOptionRow(optionCode, optionText) {
|
|
71
|
+
const row = newElement('span', { class: 'adi-opt' });
|
|
72
|
+
row.innerHTML = `<label><input type="checkbox" data-opt="${optionCode}">${optionText}</label>`;
|
|
73
|
+
|
|
74
|
+
return row;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Renders the options panel
|
|
78
|
+
export function drawOptions() {
|
|
79
|
+
const ui = newElement('div', { id: 'adi-opts-view', class: 'adi-hidden' });
|
|
80
|
+
const head1 = newElement('span', { class: 'adi-opt-heading' });
|
|
81
|
+
const head2 = newElement('span', { class: 'adi-opt-heading' });
|
|
82
|
+
const close = newElement('span', { class: 'adi-opt-close' });
|
|
83
|
+
|
|
84
|
+
head1.textContent = 'General options';
|
|
85
|
+
head2.textContent = 'Observed nodes';
|
|
86
|
+
|
|
87
|
+
ui.appendChild(head1);
|
|
88
|
+
ui.appendChild(drawOptionRow('saving', 'Enable saving of settings'));
|
|
89
|
+
ui.appendChild(drawOptionRow('makeVisible', 'Scroll to the active element in DOM View'));
|
|
90
|
+
ui.appendChild(drawOptionRow('omitEmptyText', 'Hide empty text nodes'));
|
|
91
|
+
ui.appendChild(drawOptionRow('foldText', 'Fold the text nodes'));
|
|
92
|
+
ui.appendChild(drawOptionRow('transparent', 'Enable transparent background'));
|
|
93
|
+
ui.appendChild(head2);
|
|
94
|
+
ui.appendChild(drawOptionRow('nodeTypes-3', 'Text node'));
|
|
95
|
+
ui.appendChild(drawOptionRow('nodeTypes-8', 'Comment node'));
|
|
96
|
+
// ui.appendChild(drawOptionRow('nodeTypes-1', 'Element node'));
|
|
97
|
+
// ui.appendChild(drawOptionRow('nodeTypes-9', 'Document node'));
|
|
98
|
+
ui.appendChild(close);
|
|
99
|
+
|
|
100
|
+
return ui;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Stops event propagation and also prevents the default behavior.
|
|
104
|
+
export function pauseEvent(e) {
|
|
105
|
+
if (e.stopPropagation) {
|
|
106
|
+
e.stopPropagation();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (e.preventDefault) {
|
|
110
|
+
e.preventDefault();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
e.cancelBubble = true;
|
|
114
|
+
e.returnValue = false;
|
|
115
|
+
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
// Helper function for attributes view
|
|
119
|
+
export function drawAttrRow(attrName, attrValue) {
|
|
120
|
+
const row = newElement('span', { class: 'adi-attr' });
|
|
121
|
+
switch (attrName.toLowerCase()) {
|
|
122
|
+
case 'defaultaction':
|
|
123
|
+
row.innerHTML = `<label>${attrName}: <select data-attr="${attrName}" value="${attrValue}"><option>perform</option><option>cancel</option></label>`;
|
|
124
|
+
break;
|
|
125
|
+
case 'delay':
|
|
126
|
+
row.innerHTML = `<label>${attrName}: <input type="number" data-attr="${attrName}" value="${attrValue}" readonly="readonly"></label>`;
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
row.innerHTML = `<label>${attrName}: <input type="text" data-attr="${attrName}" value="${attrValue}" readonly="readonly"></label>`;
|
|
130
|
+
}
|
|
131
|
+
return row;
|
|
132
|
+
}
|
|
@@ -2,6 +2,9 @@ import '../fx-model.js';
|
|
|
2
2
|
import { foreElementMixin } from '../ForeElementMixin.js';
|
|
3
3
|
import { ModelItem } from '../modelitem.js';
|
|
4
4
|
import { Fore } from '../fore.js';
|
|
5
|
+
import {XPathUtil} from "../xpath-util";
|
|
6
|
+
import getInScopeContext from "../getInScopeContext";
|
|
7
|
+
import { evaluateXPathToFirstNode} from '../xpath-evaluation.js';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* `AbstractControl` -
|
|
@@ -69,7 +72,41 @@ export default class AbstractControl extends foreElementMixin(HTMLElement) {
|
|
|
69
72
|
// this.control = this.querySelector('#control');
|
|
70
73
|
|
|
71
74
|
if(!this.nodeset){
|
|
72
|
-
|
|
75
|
+
|
|
76
|
+
const create = this.closest('[create]');
|
|
77
|
+
if(create){
|
|
78
|
+
// ### check if parent element exists
|
|
79
|
+
let attrName,parentPath, parentNode;
|
|
80
|
+
|
|
81
|
+
if(this.ref.includes('/')){
|
|
82
|
+
parentPath = this.ref.substring(0, this.ref.indexOf('/'));
|
|
83
|
+
const inscope = getInScopeContext(this.parentNode, this.ref);
|
|
84
|
+
parentNode = evaluateXPathToFirstNode(parentPath,inscope,this);
|
|
85
|
+
|
|
86
|
+
if(parentNode && parentNode.nodeType === Node.ELEMENT_NODE){
|
|
87
|
+
if(this.ref.includes('@')){
|
|
88
|
+
attrName = this.ref.substring(this.ref.indexOf('/')+2);
|
|
89
|
+
parentNode.setAttribute(attrName,'');
|
|
90
|
+
}else{
|
|
91
|
+
Fore.dispatch(this,'warn',{message:'"create" is not implemented for elements'})
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}else{
|
|
95
|
+
let inscope = getInScopeContext(this, this.ref);
|
|
96
|
+
|
|
97
|
+
if(this.ref.includes('@')) {
|
|
98
|
+
attrName = this.ref.substring(this.ref.indexOf('@') + 1);
|
|
99
|
+
inscope.setAttribute(attrName, '');
|
|
100
|
+
}else{
|
|
101
|
+
Fore.dispatch(this,'warn',{message:'"create" is not implemented for elements'})
|
|
102
|
+
// inscope = getInScopeContext(this.parentNode, this.ref);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}else{
|
|
106
|
+
// ### this actually makes the control nonrelevant
|
|
107
|
+
// todo: we should call a template function here to allow detachment of event-listeners and resetting eventual state
|
|
108
|
+
this.style.display = 'none';
|
|
109
|
+
}
|
|
73
110
|
return;
|
|
74
111
|
}
|
|
75
112
|
|
|
@@ -119,6 +156,9 @@ export default class AbstractControl extends foreElementMixin(HTMLElement) {
|
|
|
119
156
|
this.handleModelItemProperties();
|
|
120
157
|
|
|
121
158
|
// if(!this.closest('fx-fore').ready) return; // state change event do not fire during init phase (initial refresh)
|
|
159
|
+
if(this.getOwnerForm().initialRun){
|
|
160
|
+
Fore.dispatch(this,'init',{});
|
|
161
|
+
}
|
|
122
162
|
if (!this.getOwnerForm().ready) return; // state change event do not fire during init phase (initial refresh)
|
|
123
163
|
if (currentVal !== this.value ) {
|
|
124
164
|
// todo: discuss how to prevent unnecessary/unwanted value-changes e.g. when repeatitems are inserted
|
|
@@ -254,9 +294,7 @@ export default class AbstractControl extends foreElementMixin(HTMLElement) {
|
|
|
254
294
|
// todo - review alert handling altogether. There could be potentially multiple ones in model
|
|
255
295
|
handleValid() {
|
|
256
296
|
// console.log('mip valid', this.modelItem.required);
|
|
257
|
-
const alert = this.querySelector('fx-alert');
|
|
258
297
|
|
|
259
|
-
const mi = this.getModelItem();
|
|
260
298
|
// console.log('late modelItem', mi);
|
|
261
299
|
if (this.isValid() !== this.modelItem.constraint) {
|
|
262
300
|
if (this.modelItem.constraint) {
|
package/src/ui/fx-alert.js
CHANGED
package/src/ui/fx-container.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import '../fx-model.js';
|
|
2
|
-
import { Fore } from '../fore.js';
|
|
3
2
|
import { foreElementMixin } from '../ForeElementMixin.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -32,6 +31,18 @@ export class FxContainer extends foreElementMixin(HTMLElement) {
|
|
|
32
31
|
`;
|
|
33
32
|
|
|
34
33
|
this.getOwnerForm().registerLazyElement(this);
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
this.addEventListener('mousedown', e => {
|
|
37
|
+
|
|
38
|
+
if(e.target === this){
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
// e.stopImmediatePropagation();
|
|
41
|
+
}
|
|
42
|
+
} );
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
this.setAttribute('tabindex','0');
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
/**
|
|
@@ -58,7 +69,7 @@ export class FxContainer extends foreElementMixin(HTMLElement) {
|
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
/**
|
|
61
|
-
*
|
|
72
|
+
* relevance is processed for container controls only
|
|
62
73
|
*/
|
|
63
74
|
handleModelItemProperties() {
|
|
64
75
|
this.handleRelevant();
|
|
@@ -71,7 +82,7 @@ export class FxContainer extends foreElementMixin(HTMLElement) {
|
|
|
71
82
|
handleRelevant() {
|
|
72
83
|
// console.log('mip valid', this.modelItem.enabled);
|
|
73
84
|
if (!this.modelItem) {
|
|
74
|
-
console.log('container is not relevant');
|
|
85
|
+
// console.log('container is not relevant');
|
|
75
86
|
this.removeAttribute('relevant','');
|
|
76
87
|
this.setAttribute('nonrelevant','');
|
|
77
88
|
this.dispatchEvent(new CustomEvent('disabled', {}));
|