@jinntec/fore 3.1.0 → 3.1.1

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 CHANGED
@@ -1,4 +1,4 @@
1
- /* Version: 3.1.0 - May 20, 2026 13:19:57 */
1
+ /* Version: 3.1.1 - May 20, 2026 17:16:48 */
2
2
  function t$2(t, s, r, i) {
3
3
  const n = {
4
4
  op: s,
@@ -25307,6 +25307,17 @@ const dirtyStates = {
25307
25307
  DIRTY: 'dirty'
25308
25308
  };
25309
25309
 
25310
+ /*
25311
+ * Determine whether a string is a valid Name
25312
+ *
25313
+ * @param {string} name
25314
+ * @returns {boolean} whether the name is a valid one
25315
+ */
25316
+ function isValidName(name) {
25317
+ const result = new DOMParser().parseFromString(`<${name}/>`, 'application/xml');
25318
+ return result.querySelector('parsererror') === null;
25319
+ }
25320
+
25310
25321
  /**
25311
25322
  * Main class for Fore.Outermost container element for each Fore application.
25312
25323
  *
@@ -25470,7 +25481,7 @@ class FxFore extends HTMLElement {
25470
25481
  this._createRepeatsFromAttributes();
25471
25482
  this.inited = true;
25472
25483
  };
25473
- this.version = 'Version: 3.1.0 - built on May 20, 2026 13:19:57';
25484
+ this.version = 'Version: 3.1.1 - built on May 20, 2026 17:16:48';
25474
25485
 
25475
25486
  /**
25476
25487
  * @type {import('./fx-model.js').FxModel}
@@ -27053,7 +27064,44 @@ class FxFore extends HTMLElement {
27053
27064
  predicates
27054
27065
  };
27055
27066
  };
27056
- const steps = xpath.split('/').map(step => step.trim()).filter(step => step && step !== '.');
27067
+ const splitSteps = xpath => {
27068
+ /**
27069
+ * @type {string[]}
27070
+ */
27071
+ const steps = [];
27072
+ let scratch = '';
27073
+ let isInPredicate = false;
27074
+ for (const char of xpath.split('')) {
27075
+ if (char === '[') {
27076
+ isInPredicate = true;
27077
+ scratch += char;
27078
+ continue;
27079
+ }
27080
+ if (char === ']') {
27081
+ scratch += char;
27082
+ isInPredicate = false;
27083
+ continue;
27084
+ }
27085
+ if (!isInPredicate) {
27086
+ // Just add to the scratch. Do not check for slashes within predicates
27087
+ if (char === '/') {
27088
+ // Consume this path step
27089
+ if (scratch) {
27090
+ steps.push(scratch);
27091
+ }
27092
+ scratch = '';
27093
+ continue;
27094
+ }
27095
+ }
27096
+ scratch += char;
27097
+ }
27098
+ if (scratch) {
27099
+ // Flush it
27100
+ steps.push(scratch);
27101
+ }
27102
+ return steps;
27103
+ };
27104
+ const steps = splitSteps(xpath).map(step => step.trim()).filter(step => step && step !== '.');
27057
27105
  if (!steps.length) return null;
27058
27106
  let subtreeRoot = null;
27059
27107
  let current = null;
@@ -27074,6 +27122,11 @@ class FxFore extends HTMLElement {
27074
27122
  current.setAttribute(parsed.localName, '');
27075
27123
  continue;
27076
27124
  }
27125
+ if (!isValidName(parsed.localName)) {
27126
+ // This did not result in a valid name. Stop.
27127
+ console.warn(`Creating node for the XPath ${xpath} failed because the part ${parsed.localName} is not a valid Name.`);
27128
+ return;
27129
+ }
27077
27130
  const element = parsed.namespaceURI ? ownerDoc.createElementNS(parsed.namespaceURI, parsed.localName) : ownerDoc.createElement(parsed.localName);
27078
27131
  for (const predicate of predicates) {
27079
27132
  const attrName = predicate.name.includes(':') ? predicate.name.split(':')[1] : predicate.name;
package/dist/fore.js CHANGED
@@ -1,4 +1,4 @@
1
- /* Version: 3.1.0 - May 20, 2026 13:19:56 */
1
+ /* Version: 3.1.1 - May 20, 2026 17:16:47 */
2
2
  function t$2(t, s, r, i) {
3
3
  const n = {
4
4
  op: s,
@@ -25256,6 +25256,17 @@ const dirtyStates = {
25256
25256
  DIRTY: 'dirty'
25257
25257
  };
25258
25258
 
25259
+ /*
25260
+ * Determine whether a string is a valid Name
25261
+ *
25262
+ * @param {string} name
25263
+ * @returns {boolean} whether the name is a valid one
25264
+ */
25265
+ function isValidName(name) {
25266
+ const result = new DOMParser().parseFromString(`<${name}/>`, 'application/xml');
25267
+ return result.querySelector('parsererror') === null;
25268
+ }
25269
+
25259
25270
  /**
25260
25271
  * Main class for Fore.Outermost container element for each Fore application.
25261
25272
  *
@@ -25416,7 +25427,7 @@ class FxFore extends HTMLElement {
25416
25427
  this._createRepeatsFromAttributes();
25417
25428
  this.inited = true;
25418
25429
  };
25419
- this.version = 'Version: 3.1.0 - built on May 20, 2026 13:19:56';
25430
+ this.version = 'Version: 3.1.1 - built on May 20, 2026 17:16:47';
25420
25431
 
25421
25432
  /**
25422
25433
  * @type {import('./fx-model.js').FxModel}
@@ -26982,7 +26993,44 @@ class FxFore extends HTMLElement {
26982
26993
  predicates
26983
26994
  };
26984
26995
  };
26985
- const steps = xpath.split('/').map(step => step.trim()).filter(step => step && step !== '.');
26996
+ const splitSteps = xpath => {
26997
+ /**
26998
+ * @type {string[]}
26999
+ */
27000
+ const steps = [];
27001
+ let scratch = '';
27002
+ let isInPredicate = false;
27003
+ for (const char of xpath.split('')) {
27004
+ if (char === '[') {
27005
+ isInPredicate = true;
27006
+ scratch += char;
27007
+ continue;
27008
+ }
27009
+ if (char === ']') {
27010
+ scratch += char;
27011
+ isInPredicate = false;
27012
+ continue;
27013
+ }
27014
+ if (!isInPredicate) {
27015
+ // Just add to the scratch. Do not check for slashes within predicates
27016
+ if (char === '/') {
27017
+ // Consume this path step
27018
+ if (scratch) {
27019
+ steps.push(scratch);
27020
+ }
27021
+ scratch = '';
27022
+ continue;
27023
+ }
27024
+ }
27025
+ scratch += char;
27026
+ }
27027
+ if (scratch) {
27028
+ // Flush it
27029
+ steps.push(scratch);
27030
+ }
27031
+ return steps;
27032
+ };
27033
+ const steps = splitSteps(xpath).map(step => step.trim()).filter(step => step && step !== '.');
26986
27034
  if (!steps.length) return null;
26987
27035
  let subtreeRoot = null;
26988
27036
  let current = null;
@@ -27003,6 +27051,10 @@ class FxFore extends HTMLElement {
27003
27051
  current.setAttribute(parsed.localName, '');
27004
27052
  continue;
27005
27053
  }
27054
+ if (!isValidName(parsed.localName)) {
27055
+ // This did not result in a valid name. Stop.
27056
+ return;
27057
+ }
27006
27058
  const element = parsed.namespaceURI ? ownerDoc.createElementNS(parsed.namespaceURI, parsed.localName) : ownerDoc.createElement(parsed.localName);
27007
27059
  for (const predicate of predicates) {
27008
27060
  const attrName = predicate.name.includes(':') ? predicate.name.split(':')[1] : predicate.name;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jinntec/fore",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "Fore - declarative user interfaces in plain HTML",
5
5
  "module": "./index.js",
6
6
  "publishConfig": {
package/src/fx-fore.js CHANGED
@@ -29,6 +29,17 @@ async function waitForFunctionLibs(rootEl) {
29
29
  await Promise.all(libs.map(l => (l.readyPromise ? l.readyPromise : Promise.resolve())));
30
30
  }
31
31
 
32
+ /*
33
+ * Determine whether a string is a valid Name
34
+ *
35
+ * @param {string} name
36
+ * @returns {boolean} whether the name is a valid one
37
+ */
38
+ function isValidName(name) {
39
+ const result = new DOMParser().parseFromString(`<${name}/>`, 'application/xml');
40
+ return result.querySelector('parsererror') === null;
41
+ }
42
+
32
43
  /**
33
44
  * Main class for Fore.Outermost container element for each Fore application.
34
45
  *
@@ -1948,8 +1959,47 @@ export class FxFore extends HTMLElement {
1948
1959
  return { token, predicates };
1949
1960
  };
1950
1961
 
1951
- const steps = xpath
1952
- .split('/')
1962
+ const splitSteps = xpath => {
1963
+ /**
1964
+ * @type {string[]}
1965
+ */
1966
+ const steps = [];
1967
+ let scratch = '';
1968
+ let isInPredicate = false;
1969
+ for (const char of xpath.split('')) {
1970
+ if (char === '[') {
1971
+ isInPredicate = true;
1972
+ scratch += char;
1973
+ continue;
1974
+ }
1975
+ if (char === ']') {
1976
+ scratch += char;
1977
+ isInPredicate = false;
1978
+ continue;
1979
+ }
1980
+ if (!isInPredicate) {
1981
+ // Just add to the scratch. Do not check for slashes within predicates
1982
+ if (char === '/') {
1983
+ // Consume this path step
1984
+ if (scratch) {
1985
+ steps.push(scratch);
1986
+ }
1987
+ scratch = '';
1988
+ continue;
1989
+ }
1990
+ }
1991
+ scratch += char;
1992
+ }
1993
+
1994
+ if (scratch) {
1995
+ // Flush it
1996
+ steps.push(scratch);
1997
+ }
1998
+
1999
+ return steps;
2000
+ };
2001
+
2002
+ const steps = splitSteps(xpath)
1953
2003
  .map(step => step.trim())
1954
2004
  .filter(step => step && step !== '.');
1955
2005
 
@@ -1975,6 +2025,14 @@ export class FxFore extends HTMLElement {
1975
2025
  continue;
1976
2026
  }
1977
2027
 
2028
+ if (!isValidName(parsed.localName)) {
2029
+ // This did not result in a valid name. Stop.
2030
+ console.warn(
2031
+ `Creating node for the XPath ${xpath} failed because the part ${parsed.localName} is not a valid Name.`,
2032
+ );
2033
+ return;
2034
+ }
2035
+
1978
2036
  const element = parsed.namespaceURI
1979
2037
  ? ownerDoc.createElementNS(parsed.namespaceURI, parsed.localName)
1980
2038
  : ownerDoc.createElement(parsed.localName);