@jinntec/fore 1.10.3 → 2.1.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.
@@ -61,18 +61,24 @@ export default function getInScopeContext(node, ref) {
61
61
  const parentElement = _getElement(node);
62
62
  // console.log('getInScopeContext parent', parentElement);
63
63
 
64
- if(parentElement.closest('fx-fore').mergePartial){
65
- console.log('mergePartial mode')
66
- }
67
-
68
64
  if(parentElement.nodeName === 'FX-FORE'){
69
- return parentElement.getModel().getDefaultInstance().getDefaultContext();
65
+ const context = parentElement.getModel().getDefaultInstance()?.getDefaultContext();
66
+ if (!context) {
67
+ // Edge-case, we are in an inner fore. Use the outer fore's default context
68
+ return getInScopeContext(parentElement.parentNode, ref);
69
+ }
70
+ return context;
70
71
  }
71
72
  const parentBind = XPathUtil.getClosest('[ref]', parentElement.parentNode);
72
73
  if (parentBind && (parentBind.nodeName === 'FX-GROUP' || parentBind.nodeName === 'FX-CONTROL')) {
73
74
  return parentBind.nodeset;
74
75
  }
75
76
 
77
+ const parentActionWithIterateExpr = parentElement.matches('[iterate]') ? parentElement : XPathUtil.getClosest('[iterate]', parentElement.parentNode);
78
+ if (parentActionWithIterateExpr && parentActionWithIterateExpr.currentContext) {
79
+ return parentActionWithIterateExpr.currentContext;
80
+ }
81
+
76
82
  const repeatItem = XPathUtil.getClosest('fx-repeatitem', parentElement);
77
83
  if (repeatItem) {
78
84
  if (node.nodeName === 'context') {
@@ -0,0 +1,27 @@
1
+ const jsonToXml = (json) => {
2
+ const convert = (obj) => {
3
+ let xml = '';
4
+ for (const key in obj) {
5
+ if (obj.hasOwnProperty(key)) {
6
+ xml += `<${key}`;
7
+ if (typeof obj[key] === 'object') {
8
+ if (Array.isArray(obj[key])) {
9
+ xml += ' type="array">';
10
+ obj[key].forEach((item) => {
11
+ xml += `<_>${convert(item)}</_>`;
12
+ });
13
+ } else {
14
+ xml += ' type="object">';
15
+ xml += convert(obj[key]);
16
+ }
17
+ } else {
18
+ xml += ` type="${typeof obj[key]}">${obj[key]}</${key}>`;
19
+ }
20
+ xml += `</${key}>`;
21
+ }
22
+ }
23
+ return xml;
24
+ };
25
+
26
+ return `<json>${convert(json)}</json>`;
27
+ };
package/src/relevance.js CHANGED
@@ -1,4 +1,22 @@
1
+ import {Fore} from "./fore.js";
2
+
1
3
  export class Relevance {
4
+
5
+ static handleRelevance(boundElement){
6
+ const modelItem = boundElement.getModelItem();
7
+
8
+ if (modelItem && modelItem.relevant) {
9
+ boundElement.removeAttribute('nonrelevant');
10
+ boundElement.setAttribute('relevant','');
11
+ Fore.dispatch(this,'relevant',{});
12
+
13
+ } else {
14
+ boundElement.removeAttribute('relevant');
15
+ boundElement.setAttribute('nonrelevant','');
16
+ Fore.dispatch(this,'nonrelevant',{});
17
+ }
18
+ }
19
+
2
20
  static selectRelevant(element, type) {
3
21
  // console.log('selectRelevant', type);
4
22
  switch (type) {
@@ -5,6 +5,7 @@ import { Fore } from '../fore.js';
5
5
  import { XPathUtil } from '../xpath-util.js';
6
6
  import getInScopeContext from '../getInScopeContext.js';
7
7
  import { evaluateXPathToFirstNode} from '../xpath-evaluation.js';
8
+ import {Relevance} from "../relevance.js";
8
9
 
9
10
  /**
10
11
  * `AbstractControl` -
@@ -172,6 +173,7 @@ export default class AbstractControl extends foreElementMixin(HTMLElement) {
172
173
  this.handleValid();
173
174
  }
174
175
  this.handleRelevant();
176
+ // Relevance.handleRelevance(this);
175
177
  // todo: handleType()
176
178
  }
177
179
 
package/src/ui/fx-case.js CHANGED
@@ -1,5 +1,7 @@
1
1
  // import { foreElementMixin } from '../ForeElementMixin';
2
2
 
3
+ import {FxContainer} from "./fx-container.js";
4
+
3
5
  /**
4
6
  * `fx-case`
5
7
  * a container allowing to switch between fx-case elements
@@ -7,11 +9,12 @@
7
9
  * * todo: implement
8
10
  * @customElement
9
11
  */
10
- class FxCase extends HTMLElement {
12
+ class FxCase extends FxContainer {
13
+ /*
11
14
  constructor() {
12
15
  super();
13
- this.attachShadow({ mode: 'open' });
14
16
  }
17
+ */
15
18
 
16
19
  connectedCallback() {
17
20
  if (this.hasAttribute('label')) {
@@ -1,5 +1,6 @@
1
1
  import '../fx-model.js';
2
2
  import { foreElementMixin } from '../ForeElementMixin.js';
3
+ import {Fore} from "../fore.js";
3
4
 
4
5
  /**
5
6
  * `fx-container` -
@@ -7,12 +8,23 @@ import { foreElementMixin } from '../ForeElementMixin.js';
7
8
  *
8
9
  */
9
10
  export class FxContainer extends foreElementMixin(HTMLElement) {
11
+ static get properties() {
12
+ return {
13
+ ...super.properties,
14
+ /*
15
+ src: {
16
+ type: String,
17
+ },
18
+ */
19
+ };
20
+ }
10
21
  constructor() {
11
22
  super();
12
23
  this.attachShadow({ mode: 'open' });
13
24
  }
14
25
 
15
26
  connectedCallback() {
27
+ this.src = this.hasAttribute('src') ? this.getAttribute('src'):null;
16
28
  const style = `
17
29
  :host {
18
30
  display: block;
@@ -51,6 +63,16 @@ export class FxContainer extends foreElementMixin(HTMLElement) {
51
63
  if (!force && this.hasAttribute('refresh-on-view')) return;
52
64
  // console.log('### FxContainer.refresh on : ', this);
53
65
 
66
+ // if loading from 'src' needs to be done do it now
67
+ /*
68
+ if(this.src){
69
+ await Fore.loadForeFromSrc(this,this.src,'fx-group')
70
+ .then(foreElement =>{
71
+ this.getOwnerForm().registerLazyElement(foreElement);
72
+ foreElement.refresh();
73
+ })
74
+ }
75
+ */
54
76
  if (this.isBound()) {
55
77
  this.evalInContext();
56
78
  this.modelItem = this.getModelItem();
@@ -48,6 +48,9 @@ export default class FxControl extends XfAbstractControl {
48
48
  },
49
49
  initial: {
50
50
  type: Boolean
51
+ },
52
+ src:{
53
+ type: String
51
54
  }
52
55
  };
53
56
  }
@@ -62,7 +65,7 @@ export default class FxControl extends XfAbstractControl {
62
65
 
63
66
  connectedCallback() {
64
67
  this.initial = this.hasAttribute('initial') ? this.getAttribute('initial') : null;
65
- this.url = this.hasAttribute('url') ? this.getAttribute('url') : null;
68
+ this.src = this.hasAttribute('src') ? this.getAttribute('src') : null;
66
69
  this.loaded = false;
67
70
  this.initialNode = null;
68
71
  this.debounceDelay = this.hasAttribute('debounce') ? this.getAttribute('debounce') : null;
@@ -263,7 +266,7 @@ export default class FxControl extends XfAbstractControl {
263
266
  } else (
264
267
  Fore.dispatch(this, "warn", {'message': 'trying to replace a node that is neither an Attribute, Elemment or Text node'})
265
268
  )
266
- this.getOwnerForm().refresh();
269
+ // this.getOwnerForm().refresh();
267
270
  }
268
271
 
269
272
  renderHTML(ref) {
@@ -374,8 +377,8 @@ export default class FxControl extends XfAbstractControl {
374
377
  return;
375
378
  }
376
379
 
377
- // ### when there's a url Fore is used as widget and will be loaded from external file
378
- if (this.url && !this.loaded && this.modelItem.relevant) {
380
+ // ### when there's a src Fore is used as widget and will be loaded from external file
381
+ if (this.src && !this.loaded && this.modelItem.relevant) {
379
382
  // ### evaluate initial data if necessary
380
383
 
381
384
  if (this.initial) {
@@ -383,8 +386,8 @@ export default class FxControl extends XfAbstractControl {
383
386
  // console.log('initialNodes', this.initialNode);
384
387
  }
385
388
 
386
- // ### load the markup from Url
387
- await this._loadForeFromUrl();
389
+ // ### load the markup from src
390
+ await this._loadForeFromSrc();
388
391
  this.loaded = true;
389
392
 
390
393
  // ### replace default instance of embedded Fore with initial nodes
@@ -393,20 +396,13 @@ export default class FxControl extends XfAbstractControl {
393
396
  return;
394
397
  }
395
398
 
396
- /*
397
- if(this.url && !this.loaded){
398
- this._loadForeFromUrl();
399
- this.loaded=true;
400
- return;
401
- }
402
- */
403
399
  if (widget.value !== this.value) {
404
400
  widget.value = this.value;
405
401
  }
406
402
  }
407
403
 
408
404
  /**
409
- * loads an external Fore from an HTML file given by `url` attribute and embed it as child of this control.
405
+ * loads an external Fore from an HTML file given by `src` attribute and embed it as child of this control.
410
406
  *
411
407
  * Will look for the `<fx-fore>` element within the returned HTML file and return that element.
412
408
  *
@@ -415,13 +411,13 @@ export default class FxControl extends XfAbstractControl {
415
411
  * todo: dispatch link error
416
412
  * @private
417
413
  */
418
- async _loadForeFromUrl() {
414
+ async _loadForeFromSrc() {
419
415
  console.info(
420
- `%cFore is processing URL ${this.url}`,
416
+ `%cControl ref="${this.ref}" is loading ${this.src}`,
421
417
  "background:#64b5f6; color:white; padding:0.5rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;",
422
418
  );
423
419
  try {
424
- const response = await fetch(this.url, {
420
+ const response = await fetch(this.src, {
425
421
  method: 'GET',
426
422
  credentials: this.credentials,
427
423
  mode: 'cors',
@@ -457,10 +453,12 @@ export default class FxControl extends XfAbstractControl {
457
453
  this.initialNode = evaluateXPathToFirstNode(this.initial, this.nodeset, this);
458
454
 
459
455
  doc.firstElementChild.appendChild(this.initialNode.cloneNode(true));
460
- defaultInst.setInstanceData(doc);
456
+ defaultInst.instanceData = doc;
461
457
  }
462
- imported.getModel().updateModel();
463
- imported.refresh();
458
+ imported.model = imported.querySelector('fx-model');
459
+ imported.model.updateModel();
460
+
461
+ imported.refresh(true);
464
462
  },
465
463
  {once: true},
466
464
  );
@@ -477,23 +475,19 @@ export default class FxControl extends XfAbstractControl {
477
475
  dummy.replaceWith(imported);
478
476
  }
479
477
 
480
-
481
478
  if (!theFore) {
482
- this.dispatchEvent(
483
- new CustomEvent('error', {
484
- detail: {
485
- message: `Fore element not found in '${this.src}'. Maybe wrapped within 'template' element?`,
486
- },
487
- }),
488
- );
479
+ Fore.dispatch('error', {
480
+ detail: {
481
+ message: `Fore element not found in '${this.src}'. Maybe wrapped within 'template' element?`,
482
+ }
483
+ });
489
484
  }
490
- this.dispatchEvent(new CustomEvent('loaded', {detail: {fore: theFore}}));
485
+ Fore.dispatch('loaded', {detail: {fore: theFore}});
491
486
  } catch (error) {
492
487
  // console.log('error', error);
493
488
  Fore.dispatch(this, 'error', {
494
489
  origin: this,
495
- message: `control couldn't be loaded from url '${this.url}'`,
496
- expr:xpath,
490
+ message: `control couldn't be loaded from src '${this.src}'`,
497
491
  level:'Error'
498
492
  });
499
493
 
@@ -0,0 +1,9 @@
1
+ import { foreElementMixin } from '../ForeElementMixin.js';
2
+ import { withDraggability } from '../withDraggability.js';
3
+
4
+ class FxDroptarget extends withDraggability(foreElementMixin(HTMLElement)) {
5
+ }
6
+
7
+ if (!customElements.get('fx-droptarget')) {
8
+ window.customElements.define('fx-droptarget', FxDroptarget);
9
+ }
@@ -86,19 +86,23 @@ export class FxInspector extends HTMLElement {
86
86
 
87
87
  update() {
88
88
  // console.log('update');
89
- const pre = this.shadowRoot.querySelectorAll('pre');
90
- // console.log('pre', pre);
91
- const fore = this.closest('fx-fore');
89
+ try{
90
+ const pre = this.shadowRoot.querySelectorAll('pre');
91
+ // console.log('pre', pre);
92
+ const fore = this.closest('fx-fore');
92
93
 
93
- Array.from(pre).forEach(element => {
94
- const inst = fore.getModel().getInstance(element.getAttribute('id'));
95
- if (inst.getAttribute('type') === 'xml') {
96
- element.innerText = this.serializeDOM(inst.instanceData);
97
- }
98
- if (inst.getAttribute('type') === 'json') {
99
- element.innerText = JSON.stringify(inst.instanceData, undefined, 2);
100
- }
101
- });
94
+ Array.from(pre).forEach(element => {
95
+ const inst = fore.getModel().getInstance(element.getAttribute('id'));
96
+ if (inst.getAttribute('type') === 'xml') {
97
+ element.innerText = this.serializeDOM(inst.instanceData);
98
+ }
99
+ if (inst.getAttribute('type') === 'json') {
100
+ element.innerText = JSON.stringify(inst.instanceData, undefined, 2);
101
+ }
102
+ });
103
+ }catch (e){
104
+ console.warn('caught problem in inspector', e.message);
105
+ }
102
106
  }
103
107
 
104
108
  render(style) {
@@ -3,6 +3,7 @@ import { evaluateXPath } from '../xpath-evaluation.js';
3
3
  import getInScopeContext from '../getInScopeContext.js';
4
4
  import { XPathUtil } from '../xpath-util.js';
5
5
  import {foreElementMixin} from "../ForeElementMixin.js";
6
+ import {withDraggability} from "../withDraggability.js";
6
7
 
7
8
  /**
8
9
  * `fx-repeat`
@@ -19,7 +20,7 @@ import {foreElementMixin} from "../ForeElementMixin.js";
19
20
  *
20
21
  * todo: it should be seriously be considered to extend FxContainer instead but needs refactoring first.
21
22
  */
22
- export class FxRepeatAttributes extends foreElementMixin(HTMLElement) {
23
+ export class FxRepeatAttributes extends withDraggability(foreElementMixin(HTMLElement), false) {
23
24
  static get properties() {
24
25
  return {
25
26
  ...super.properties,
@@ -51,6 +52,7 @@ export class FxRepeatAttributes extends foreElementMixin(HTMLElement) {
51
52
  super();
52
53
  this.ref = '';
53
54
  this.dataTemplate = [];
55
+ this.isDraggable=null;
54
56
  this.focusOnCreate = '';
55
57
  this.initDone = false;
56
58
  this.repeatIndex = 1;
@@ -87,7 +89,7 @@ export class FxRepeatAttributes extends foreElementMixin(HTMLElement) {
87
89
  }
88
90
 
89
91
  get index() {
90
- return this.getAttribute('index');
92
+ return parseInt(this.getAttribute('index'), 10);
91
93
  }
92
94
 
93
95
  set index(idx) {