@burger-editor/frozen-patty 0.11.0 → 4.0.0-alpha.10

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.
@@ -0,0 +1,91 @@
1
+ import { kebabCase } from '@burger-editor/utils';
2
+ import { setValue } from './set-value.js';
3
+ import { stringifyFields } from './stringify-fields.js';
4
+ import { definedFields, flattenData, getFields, hasField, maxLengthOf, removeProp, replaceNode, replaceProp, } from './utils.js';
5
+ /**
6
+ *
7
+ * @param el
8
+ * @param data
9
+ * @param attr
10
+ * @param filter
11
+ * @param xssSanitize Enable XSS protection
12
+ */
13
+ export function setComponent(el, data, attr, filter, xssSanitize = true) {
14
+ el = el.cloneNode(true);
15
+ for (const dataKeyName in data) {
16
+ const datum = data[dataKeyName];
17
+ if (Array.isArray(datum)) {
18
+ continue;
19
+ }
20
+ const targetList = [
21
+ // Include self
22
+ el,
23
+ // Perform rough filtering for performance
24
+ ...el.querySelectorAll(`[data-${attr}*="${kebabCase(dataKeyName)}"]`),
25
+ ]
26
+ // Perform more accurate filtering
27
+ .filter((el) => hasField(el, attr, dataKeyName));
28
+ for (const targetEl of targetList) {
29
+ setValue(targetEl, dataKeyName, datum, attr, filter, xssSanitize);
30
+ }
31
+ }
32
+ for (const listRoot of el.querySelectorAll(`[data-${attr}-list]`)) {
33
+ const decendants = listRoot.querySelectorAll('*');
34
+ const definedFieldsOfDecendants = new Set([...decendants].flatMap((el) => definedFields(el, attr)));
35
+ const maxLength = maxLengthOf(data, [...definedFieldsOfDecendants]);
36
+ const listItem = listRoot.children[0]?.cloneNode(true);
37
+ if (!listItem) {
38
+ continue;
39
+ }
40
+ while (listRoot.firstChild) {
41
+ listRoot.firstChild.remove();
42
+ }
43
+ // Track used paths for picture elements to avoid duplicates
44
+ const usedPaths = new Set();
45
+ for (let i = 0; i < maxLength; i++) {
46
+ let item = listItem.cloneNode(true);
47
+ const itemData = flattenData(data, i);
48
+ let reverse = false;
49
+ switch (listRoot.localName) {
50
+ case 'picture': {
51
+ reverse = true;
52
+ // Check for duplicate paths and skip if found
53
+ const pathValue = itemData.path;
54
+ if (pathValue != null && usedPaths.has(String(pathValue))) {
55
+ continue;
56
+ }
57
+ if (pathValue != null) {
58
+ usedPaths.add(String(pathValue));
59
+ }
60
+ let fields = getFields(item, attr);
61
+ if (i === 0) {
62
+ // Convert first item to img element
63
+ item = replaceNode(item, 'img', attr, xssSanitize);
64
+ fields = replaceProp(fields, 'srcset', 'src');
65
+ fields = removeProp(fields, 'sizes');
66
+ const fieldQuery = stringifyFields(fields);
67
+ item.setAttribute(`data-${attr}`, fieldQuery);
68
+ }
69
+ else {
70
+ // Convert subsequent items to source elements
71
+ item = replaceNode(item, 'source', attr, xssSanitize);
72
+ fields = replaceProp(fields, 'src', 'srcset');
73
+ fields = removeProp(fields, 'alt');
74
+ fields = removeProp(fields, 'loading');
75
+ const fieldQuery = stringifyFields(fields);
76
+ item.setAttribute(`data-${attr}`, fieldQuery);
77
+ }
78
+ break;
79
+ }
80
+ }
81
+ const newEl = setComponent(item, itemData, attr, filter, xssSanitize);
82
+ if (reverse) {
83
+ listRoot.prepend(newEl);
84
+ }
85
+ else {
86
+ listRoot.append(newEl);
87
+ }
88
+ }
89
+ }
90
+ return el;
91
+ }
@@ -5,10 +5,19 @@ import type { Filter, PrimitiveDatum } from './types.js';
5
5
  * ```html
6
6
  * <div [target-attribute] data-[attr]="[name]:[target-attribute]"></div>
7
7
  * ```
8
- *
9
8
  * @param el A target element
10
9
  * @param name A label name
11
10
  * @param datum A datum of value
12
11
  * @param attr Data attribute name for specifying the node that FrozenPatty treats as a field
12
+ * @param filter
13
+ * @param xssSanitize Enable XSS protection
14
+ */
15
+ export declare function setValue(el: Element, name: string, datum: PrimitiveDatum, attr?: string, filter?: Filter, xssSanitize?: boolean): void;
16
+ /**
17
+ *
18
+ * @param el
19
+ * @param datum
20
+ * @param asHtml
21
+ * @param xssSanitize
13
22
  */
14
- export declare function setValue(el: Element, name: string, datum: PrimitiveDatum, attr?: string, filter?: Filter): void;
23
+ export declare function setContent(el: Element, datum: PrimitiveDatum, asHtml?: boolean, xssSanitize?: boolean): void;