@massimo-cassandro/minimo 1.10.0 → 1.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/minimo",
3
- "version": "1.10.0",
3
+ "version": "1.10.1",
4
4
  "description": "Light css framework & utilities",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -7,8 +7,9 @@
7
7
  *
8
8
  * Where:
9
9
  * * `tag` is the element name; defaults to `div` if omitted
10
- * * `#id` is the optional element id; must immediately follow the tag
10
+ * * `#id` is the optional element id, preceded by `#`
11
11
  * * `.class1, .class2...` are optional CSS classes, each preceded by `.`
12
+ * * `#id` and `.class` tokens can appear in any order and interleaved (e.g. `.class1#id.class2`)
12
13
  * * `(...)` is the optional attribute block; can also use `[...]` or `{...}`.
13
14
  * Each name–value pair is separated by `:` or `=`. A bare name (no value) defaults to `true`.
14
15
  * * Text content follows after a space
@@ -26,24 +27,11 @@
26
27
 
27
28
  export function parseDomString(domString) {
28
29
 
29
- // version using named capture groups (kept for reference)
30
- // const regex = new RegExp(
31
- // /^(?<tag>[a-zA-Z][a-zA-Z0-9-]*)?/.source + // tag
32
- // /(?:#(?<id>[a-zA-Z0-9_-]+))?/.source + // id
33
- // /(?<classes>(?:\.[a-zA-Z0-9_-]+)*)?/.source + // classes
34
- // /(?<attrs>[([{].*?[)\]}])?/.source + // attrs
35
- // /(?: +(?<content>.*))?$/.source // content
36
- // );
37
-
38
-
39
- // FIX: does not work when id follows classes: <TAG>.<CLASS>#<ID>; id must precede classes
40
-
41
30
  const regex = new RegExp(
42
- /^([a-zA-Z][a-zA-Z0-9-]*)?/.source + // tag (also accepts web component names)
43
- /(?:#([a-zA-Z0-9_-]+))?/.source + // id
44
- /((?:\.[a-zA-Z0-9_-]+)*)?/.source + // classes
45
- /([([{].*?[)\]}])?/.source + // attrs
46
- /(?: +(.*))?$/.source // content
31
+ /^([a-zA-Z][a-zA-Z0-9-]*)?/.source + // tag (also accepts web component names)
32
+ /((?:[#.][a-zA-Z0-9_-]+)*)?/.source + // id and classes, in any order
33
+ /([([{].*?[)\]}])?/.source + // attrs
34
+ /(?: +(.*))?$/.source // content
47
35
  );
48
36
 
49
37
  const matches = domString.match(regex);
@@ -53,29 +41,24 @@ export function parseDomString(domString) {
53
41
  return null;
54
42
  }
55
43
 
56
- // Capture group indices:
44
+ // Capture group indexes:
57
45
  // [0]: full match
58
46
  // [1]: tag
59
- // [2]: id
60
- // [3]: classes
61
- // [4]: raw attributes
62
- // [5]: content
47
+ // [2]: id and classes (e.g. "#id.class1.class2" or ".class1#id.class2")
48
+ // [3]: raw attributes
49
+ // [4]: content
50
+
51
+ const idAndClasses = matches[2] || '',
52
+ idMatch = idAndClasses.match(/#([a-zA-Z0-9_-]+)/),
53
+ classMatches = [...idAndClasses.matchAll(/\.([a-zA-Z0-9_-]+)/g)];
63
54
 
64
55
  const tag = (matches[1] || 'div').toLowerCase(),
65
- id = matches[2]?.trim() || null,
66
- classes = matches[3] ? matches[3].slice(1).split('.').map(c => c.trim()) : [],
67
- rawAttrs = matches[4]?.trim() || null,
68
- content = matches[5]?.trim() || null
56
+ id = idMatch?.[1] || null,
57
+ classes = classMatches.map(m => m[1]),
58
+ rawAttrs = matches[3]?.trim() || null,
59
+ content = matches[4]?.trim() || null
69
60
  ;
70
61
 
71
- // version using named capture groups (kept for reference)
72
- // const tag = (matches.groups.tag || 'div').toLowerCase(),
73
- // id = matches.groups.id?.trim() || null,
74
- // classes = matches.groups.classes? matches[3].slice(1).split('.').map(c => c.trim()) : [],
75
- // rawAttrs = matches.groups.attrs?.trim() || null,
76
- // content = matches.groups.content?.trim() || null
77
- // ;
78
-
79
62
  /** @type {Record<string, string | true>} */
80
63
  const attrs = {};
81
64
  if (rawAttrs) {
@@ -16,7 +16,7 @@ form.addEventListener('submit', e => {
16
16
  form.classList.add('was-validated');
17
17
  try {
18
18
  if( ... ) {
19
- throw new ValidationError('__message__', [errorFields, ...] );
19
+ throw new ValidationError('__message__', [errorFields, ...] ); // errorFields is optional
20
20
  }
21
21
  } catch( error ) {
22
22
  e.preventDefault();
@@ -38,7 +38,7 @@ form.addEventListener('submit', e => {
38
38
  }, {once: true});
39
39
  });
40
40
 
41
- error.fields[0]?.focus({preventScroll:false});
41
+ error.fields?.[0]?.focus({preventScroll:false});
42
42
  }
43
43
  mAlert({
44
44
  type : 'error',