@burger-editor/frozen-patty 4.0.0-alpha.7 → 4.0.0-alpha.70

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/README.md CHANGED
@@ -584,6 +584,24 @@ HTML文字列に変換します。
584
584
 
585
585
  DOM要素に変換します。
586
586
 
587
+ ## サブモジュールエクスポート
588
+
589
+ メインの`frozenPatty`関数以外に、個別の機能をサブモジュールとしてインポートできます。
590
+
591
+ | エクスポートパス | 説明 |
592
+ | --------------------------------------- | -------------------------------------------------------------- |
593
+ | `@burger-editor/frozen-patty` | メインの `frozenPatty` 関数 |
594
+ | `@burger-editor/frozen-patty/get-value` | HTML要素からフィールド値を取得する `getValue` 関数 |
595
+ | `@burger-editor/frozen-patty/set-value` | HTML要素にフィールド値を設定する `setValue`, `setContent` 関数 |
596
+ | `@burger-editor/frozen-patty/utils` | HTML正規化、フィールドパースなどのユーティリティ |
597
+ | `@burger-editor/frozen-patty/types` | TypeScript型定義 |
598
+
599
+ ```js
600
+ // サブモジュールの個別インポート例
601
+ import { setValue } from '@burger-editor/frozen-patty/set-value';
602
+ import { getValue } from '@burger-editor/frozen-patty/get-value';
603
+ ```
604
+
587
605
  ## ライセンス
588
606
 
589
607
  MIT
@@ -1,4 +1,5 @@
1
1
  import { kebabCase } from '@burger-editor/utils';
2
+ import { normalizeIndent } from './normalize-indent.js';
2
3
  import { parseFields } from './parse-fields.js';
3
4
  /**
4
5
  * Get value from an element
@@ -30,7 +31,7 @@ export function getValues(el, convertType = false, attr = 'field', filter) {
30
31
  break;
31
32
  }
32
33
  case 'html': {
33
- value = el.innerHTML.trim();
34
+ value = normalizeIndent(el.innerHTML);
34
35
  break;
35
36
  }
36
37
  case 'style': {
@@ -67,7 +68,7 @@ export function getValues(el, convertType = false, attr = 'field', filter) {
67
68
  value = convertType ? convert(val) : val;
68
69
  }
69
70
  else {
70
- value = el.innerHTML.trim();
71
+ value = normalizeIndent(el.innerHTML);
71
72
  }
72
73
  }
73
74
  if (filter) {
@@ -127,7 +128,8 @@ function getAttribute(el, keyAttr, attr, typeConvert) {
127
128
  // For shorthand notation, get value from data-field-* attribute
128
129
  const dataAttr = ['data', attr, kebabCase(keyAttr)].join('-');
129
130
  if (el.hasAttribute(dataAttr)) {
130
- return el.getAttribute(dataAttr) ?? '';
131
+ const value = el.getAttribute(dataAttr);
132
+ return typeConvert ? convert(value) : value;
131
133
  }
132
134
  value = el.getAttribute(keyAttr) ?? null;
133
135
  if ((value === '' || value == null) &&
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Normalizes the indentation of a multi-line HTML string by detecting the indentation
3
+ * of the first line and removing the same amount of leading whitespace (spaces or tabs)
4
+ * from all lines.
5
+ *
6
+ * - The function first removes any leading empty lines (lines containing only line breaks).
7
+ * - It then detects the leading whitespace (indent) from the first line.
8
+ * - For each line, if that indent is present at the start of the line, it is removed.
9
+ * - After normalization, any trailing empty lines (containing only whitespace or line breaks)
10
+ * are also removed.
11
+ * - Supports both LF (\n) and CRLF (\r\n) line endings.
12
+ *
13
+ * This is useful when copying and pasting or serializing innerHTML that includes
14
+ * indentation due to template formatting, so the returned HTML has normalized,
15
+ * consistent indentation and no unwanted leading/trailing blank lines.
16
+ * @param html - The multi-line HTML string to normalize.
17
+ * @returns The HTML string with normalized indentation and no leading/trailing empty lines.
18
+ */
19
+ export declare function normalizeIndent(html: string): string;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Normalizes the indentation of a multi-line HTML string by detecting the indentation
3
+ * of the first line and removing the same amount of leading whitespace (spaces or tabs)
4
+ * from all lines.
5
+ *
6
+ * - The function first removes any leading empty lines (lines containing only line breaks).
7
+ * - It then detects the leading whitespace (indent) from the first line.
8
+ * - For each line, if that indent is present at the start of the line, it is removed.
9
+ * - After normalization, any trailing empty lines (containing only whitespace or line breaks)
10
+ * are also removed.
11
+ * - Supports both LF (\n) and CRLF (\r\n) line endings.
12
+ *
13
+ * This is useful when copying and pasting or serializing innerHTML that includes
14
+ * indentation due to template formatting, so the returned HTML has normalized,
15
+ * consistent indentation and no unwanted leading/trailing blank lines.
16
+ * @param html - The multi-line HTML string to normalize.
17
+ * @returns The HTML string with normalized indentation and no leading/trailing empty lines.
18
+ */
19
+ export function normalizeIndent(html) {
20
+ // Remove leading line breaks
21
+ const trimmedHtml = html.replace(/^(?:\r?\n)+/, '');
22
+ const lines = trimmedHtml.split(/(?<=\r\n|\n|$)/);
23
+ const firstLineIndent = lines[0]?.match(/^\s+/)?.[0] ?? '';
24
+ if (firstLineIndent.length === 0) {
25
+ return trimmedHtml.trimEnd();
26
+ }
27
+ const normalizedLines = lines.map((line) => line.replace(firstLineIndent, ''));
28
+ return normalizedLines.join('').trimEnd();
29
+ }
@@ -40,6 +40,8 @@ export function setComponent(el, data, attr, filter, xssSanitize = true) {
40
40
  while (listRoot.firstChild) {
41
41
  listRoot.firstChild.remove();
42
42
  }
43
+ // Track used paths for picture elements to avoid duplicates
44
+ const usedPaths = new Set();
43
45
  for (let i = 0; i < maxLength; i++) {
44
46
  let item = listItem.cloneNode(true);
45
47
  const itemData = flattenData(data, i);
@@ -47,6 +49,14 @@ export function setComponent(el, data, attr, filter, xssSanitize = true) {
47
49
  switch (listRoot.localName) {
48
50
  case 'picture': {
49
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
+ }
50
60
  let fields = getFields(item, attr);
51
61
  if (i === 0) {
52
62
  // Convert first item to img element
@@ -14,10 +14,11 @@ import type { Filter, PrimitiveDatum } from './types.js';
14
14
  */
15
15
  export declare function setValue(el: Element, name: string, datum: PrimitiveDatum, attr?: string, filter?: Filter, xssSanitize?: boolean): void;
16
16
  /**
17
- *
18
- * @param el
19
- * @param datum
20
- * @param asHtml
21
- * @param xssSanitize
17
+ * Set content value on a form element or general element.
18
+ * Handles checkbox/radio checked state, input values, and innerHTML/textContent.
19
+ * @param el - The target element
20
+ * @param datum - The value to set
21
+ * @param asHtml - Whether to set as innerHTML (true) or textContent (false)
22
+ * @param xssSanitize - Whether to sanitize HTML content for XSS protection
22
23
  */
23
24
  export declare function setContent(el: Element, datum: PrimitiveDatum, asHtml?: boolean, xssSanitize?: boolean): void;