@iyulab/chat-components 0.13.0 โ†’ 0.14.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +1 -0
  3. package/dist/_virtual/_glob-assets_raw/alert-triangle-fill.svg.4cfc4305.js +4 -0
  4. package/dist/_virtual/_glob-assets_raw/arrows-sort.svg.dda43a85.js +4 -0
  5. package/dist/_virtual/_glob-assets_raw/code.svg.c69bc144.js +4 -0
  6. package/dist/_virtual/_glob-assets_raw/download.svg.bce82177.js +4 -0
  7. package/dist/_virtual/_glob-assets_raw/external-link.svg.a9f7f02d.js +4 -0
  8. package/dist/_virtual/_glob-assets_raw/file-code.svg.0e706f93.js +4 -0
  9. package/dist/_virtual/_glob-assets_raw/file-music.svg.b9970203.js +4 -0
  10. package/dist/_virtual/_glob-assets_raw/file-spreadsheet.svg.8c03bdfa.js +4 -0
  11. package/dist/_virtual/_glob-assets_raw/file-text.svg.85bdd923.js +4 -0
  12. package/dist/_virtual/_glob-assets_raw/file-type-pdf.svg.bc12db6d.js +4 -0
  13. package/dist/_virtual/_glob-assets_raw/file-zip.svg.76dde660.js +4 -0
  14. package/dist/_virtual/_glob-assets_raw/file.svg.28f5d6f1.js +4 -0
  15. package/dist/_virtual/_glob-assets_raw/photo.svg.cc273cc1.js +4 -0
  16. package/dist/_virtual/_glob-assets_raw/player-stop-fill.svg.5378b752.js +4 -0
  17. package/dist/_virtual/_glob-assets_raw/send.svg.02326253.js +4 -0
  18. package/dist/_virtual/_glob-assets_raw/sort-ascending-letters.svg.14a3df67.js +4 -0
  19. package/dist/_virtual/_glob-assets_raw/sort-descending-letters.svg.3e03647c.js +4 -0
  20. package/dist/_virtual/_glob-assets_raw/video.svg.c183f03c.js +4 -0
  21. package/dist/_virtual/_glob-assets_raw/world.svg.cd9903c8.js +4 -0
  22. package/dist/components/UDataElement.d.ts +2 -0
  23. package/dist/components/UDataElement.js +9 -1
  24. package/dist/components/blocks/UCodeBlock.js +1 -0
  25. package/dist/components/blocks/UElementBlock.d.ts +12 -16
  26. package/dist/components/blocks/UElementBlock.js +23 -31
  27. package/dist/components/blocks/UFileBlock.js +1 -0
  28. package/dist/components/blocks/UMarkedBlock.d.ts +8 -1
  29. package/dist/components/blocks/UMarkedBlock.js +23 -5
  30. package/dist/components/blocks/UMarkedBlock.styles.js +10 -0
  31. package/dist/components/blocks/UTableBlock.js +1 -0
  32. package/dist/components/prompt/UPrompt.js +3 -1
  33. package/dist/components/references/URefCard.js +3 -1
  34. package/dist/components/references/URefTag.js +3 -1
  35. package/dist/components-extra/UChartBlock.js +4 -0
  36. package/dist/components-extra/UImagesBlock.d.ts +3 -0
  37. package/dist/components-extra/UImagesBlock.js +18 -3
  38. package/dist/components-extra/UImagesBlock.styles.js +19 -0
  39. package/dist/components-extra/UMapBlock.js +3 -0
  40. package/dist/components-extra/UVideoBlock.js +3 -0
  41. package/dist/extra.d.ts +7 -1
  42. package/dist/extra.js +12 -6
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +5 -2
  45. package/dist/utilities/ElementRegistry.d.ts +13 -0
  46. package/dist/utilities/ElementRegistry.js +33 -0
  47. package/dist/utilities/PromptBuilder.d.ts +3 -0
  48. package/dist/utilities/PromptBuilder.js +5 -0
  49. package/dist/utilities/icons.js +52 -0
  50. package/dist/utilities/imageSources.d.ts +25 -0
  51. package/dist/utilities/imageSources.js +61 -0
  52. package/dist/utilities/messages.d.ts +1 -1
  53. package/dist/utilities/messages.js +6 -2
  54. package/dist/utilities/sanitizers.d.ts +10 -1
  55. package/dist/utilities/sanitizers.js +16 -5
  56. package/package.json +4 -2
  57. package/skills/iyulab-chat-components/SKILL.md +1 -0
  58. package/skills/iyulab-chat-components/references/components/element-block.md +5 -6
  59. package/skills/iyulab-chat-components/references/components/images-block.md +1 -0
  60. package/skills/iyulab-chat-components/references/components/marked-block.md +12 -0
  61. package/skills/iyulab-chat-components/references/extra-system.md +4 -4
  62. package/skills/iyulab-chat-components/references/security.md +23 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,65 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.14.0] - 2026-09-30
4
+
5
+ ### Security
6
+
7
+ - ๐Ÿ”ด **Breaking โ€” `block-json` renders only registered blocks and assigns only their schema's
8
+ properties.** `u-element-block` used to create any element defined on the page and assign every
9
+ property except six names (`innerHTML`, `outerHTML`, โ€ฆ). `block-json` is model output, so a
10
+ prompt-injected document could create an element that renders a property as HTML (for example
11
+ `u-table-block`'s cell text) and run script. Now a tag must be registered as a block, and only the
12
+ names in that block's schema `properties` are assigned; other keys (including `style`) are dropped
13
+ and logged to the console.
14
+ - The four built-in extras register themselves when their module is imported, and
15
+ `ElementPromptBuilder.add()` registers the schema it is given โ€” extras set up as documented keep
16
+ working.
17
+ - New `registerElementBlock(schema)` for blocks you describe in your own prompt, and
18
+ `getElementBlockProperties(tag)`.
19
+ - The `blacklist` property of `u-element-block` is removed.
20
+ - **New `setAllowedImagePrefixes(prefixes)` โ€” an origin policy for images in model output.** Markdown
21
+ images in `u-marked-block` (table cells included) and the items of `u-images-block` load the URL the
22
+ model wrote as soon as they render, so a prompt-injected response can send data to a third party in
23
+ an image URL's query string. With a list set, only images whose resolved absolute URL starts with one
24
+ of the prefixes are requested; any other image is drawn as its alt text (`Image blocked: โ€ฆ`,
25
+ localized) and no request is made. The default (`undefined`) keeps loading every image; `[]` blocks
26
+ all, `['*']` allows all. `getAllowedImagePrefixes()` and `resolveImageSource(src)` are exported too.
27
+ - `data:image/โ€ฆ` URLs make no request and are shown under any policy โ€” markdown images with such a
28
+ URL used to be replaced by `#`.
29
+ - A markdown image with a blocked protocol (`javascript:` and the like) is drawn as its alt text
30
+ instead of `<img src="#">`, which requested the page itself as an image.
31
+ - `u-images-block` now applies the same protocol check to `src` as markdown images do.
32
+ - New `docs/security.md` (and a skill reference) โ€” what each input is trusted to contain, the requests
33
+ the components make, and what is left to the application.
34
+ - New `sanitizeHref(url)` โ€” the protocol check without HTML escaping, for property bindings.
35
+ - Migration: a custom element that `block-json` should render needs its schema registered with
36
+ `ElementPromptBuilder.add()` or `registerElementBlock()`, and every property the model may set
37
+ must be listed in that schema's `properties`.
38
+
39
+ ### Fixed
40
+
41
+ - **`u-ref-card` checks the protocol of its `url`, like `u-ref-tag` already did.** A citation source URL
42
+ such as `javascript:โ€ฆ` became `#` in the inline citation but stayed as written in the card inside its
43
+ tooltip. Both now use the same check.
44
+ - **`u-prompt` no longer sends on the Enter that finishes an IME composition.** Typing Korean (or
45
+ another composed language) and pressing Enter sent the message and then left the last syllable in
46
+ the box, so it was sent again. Requires `@iyulab/components` 1.51.0 or later.
47
+ - **Icons of `u-prompt`, `u-table-block`, `u-code-block` and the other components that use the
48
+ bundled `internal-chat` set are drawn again.** The module that registers that set had no exports
49
+ and was not declared in `sideEffects`, so the package build dropped it and those icons rendered at
50
+ 0ร—0 (0.11.1 โ€“ 0.13.0).
51
+ - **A table whose cell carries a citation keeps its rows.** The citation markup was inserted into the
52
+ table's JSON payload after it had been serialized, which broke the JSON, and the table rendered
53
+ empty. Citations inside `block-json` payloads are removed for the same reason.
54
+ - **`u-marked-block` keeps updating after it is detached and re-attached while a render or the
55
+ streaming indicator is pending.** It used to stop updating for good, showing an intermediate
56
+ frame, or leave a `block-json` block on its loading skeleton.
57
+ - Blocks that read their data from a `<script type="application/json">` child no longer log a
58
+ "Missing script" error when they are moved in the DOM after loading.
59
+ - `@iyulab/chat-components/extra` registers the built-in extras on `ElementPromptBuilder.instance`,
60
+ as documented. Adding your own extras there and calling `build()` again now returns the built-ins
61
+ too; it used to return only yours.
62
+
3
63
  ## [0.13.0] - 2026-09-28
4
64
 
5
65
  ### Fixed
package/README.md CHANGED
@@ -137,6 +137,7 @@ package's Accessibility section.
137
137
  | [docs/block-system.md](./docs/block-system.md) | Block components and `BlockItem` types in depth |
138
138
  | [docs/extras-system.md](./docs/extras-system.md) | Extras system setup and custom extras |
139
139
  | [docs/events.md](./docs/events.md) | Full event reference |
140
+ | [docs/security.md](./docs/security.md) | What each input is trusted to contain, requests the components make, and your application's part |
140
141
 
141
142
  ---
142
143
 
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/alert-triangle-fill.svg.4cfc4305
2
+ var alert_triangle_fill_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M12 1.67c.955 0 1.845 .467 2.39 1.247l.105 .16l8.114 13.548a2.914 2.914 0 0 1 -2.307 4.363l-.195 .008h-16.225a2.914 2.914 0 0 1 -2.582 -4.2l.099 -.185l8.11 -13.538a2.914 2.914 0 0 1 2.491 -1.403zm.01 13.33l-.127 .007a1 1 0 0 0 0 1.986l.117 .007l.127 -.007a1 1 0 0 0 0 -1.986l-.117 -.007zm-.01 -7a1 1 0 0 0 -.993 .883l-.007 .117v4l.007 .117a1 1 0 0 0 1.986 0l.007 -.117v-4l-.007 -.117a1 1 0 0 0 -.993 -.883z\" />\n</svg>\n";
3
+ //#endregion
4
+ export { alert_triangle_fill_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/arrows-sort.svg.dda43a85
2
+ var arrows_sort_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M3 9l4 -4l4 4m-4 -4v14\" />\n <path d=\"M21 15l-4 4l-4 -4m4 4v-14\" />\n</svg>\n";
3
+ //#endregion
4
+ export { arrows_sort_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/code.svg.c69bc144
2
+ var code_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M7 8l-4 4l4 4\" />\n <path d=\"M17 8l4 4l-4 4\" />\n <path d=\"M14 4l-4 16\" />\n</svg>\n";
3
+ //#endregion
4
+ export { code_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/download.svg.bce82177
2
+ var download_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2\" />\n <path d=\"M7 11l5 5l5 -5\" />\n <path d=\"M12 4l0 12\" />\n</svg>\n";
3
+ //#endregion
4
+ export { download_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/external-link.svg.a9f7f02d
2
+ var external_link_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6\" />\n <path d=\"M11 13l9 -9\" />\n <path d=\"M15 4h5v5\" />\n</svg>\n";
3
+ //#endregion
4
+ export { external_link_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/file-code.svg.0e706f93
2
+ var file_code_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2\" />\n <path d=\"M10 13l-1 2l1 2\" />\n <path d=\"M14 13l1 2l-1 2\" />\n</svg>\n";
3
+ //#endregion
4
+ export { file_code_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/file-music.svg.b9970203
2
+ var file_music_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2\" />\n <path d=\"M10 16a1 1 0 1 0 2 0a1 1 0 1 0 -2 0\" />\n <path d=\"M12 16l0 -5l2 1\" />\n</svg>\n";
3
+ //#endregion
4
+ export { file_music_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/file-spreadsheet.svg.8c03bdfa
2
+ var file_spreadsheet_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2\" />\n <path d=\"M8 11h8v7h-8l0 -7\" />\n <path d=\"M8 15h8\" />\n <path d=\"M11 11v7\" />\n</svg>\n";
3
+ //#endregion
4
+ export { file_spreadsheet_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/file-text.svg.85bdd923
2
+ var file_text_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2\" />\n <path d=\"M9 9l1 0\" />\n <path d=\"M9 13l6 0\" />\n <path d=\"M9 17l6 0\" />\n</svg>\n";
3
+ //#endregion
4
+ export { file_text_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/file-type-pdf.svg.bc12db6d
2
+ var file_type_pdf_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\" />\n <path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\" />\n <path d=\"M17 18h2\" />\n <path d=\"M20 15h-3v6\" />\n <path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\" />\n</svg>\n";
3
+ //#endregion
4
+ export { file_type_pdf_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/file-zip.svg.76dde660
2
+ var file_zip_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M6 20.735a2 2 0 0 1 -1 -1.735v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-1\" />\n <path d=\"M11 17a2 2 0 0 1 2 2v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-2a2 2 0 0 1 2 -2\" />\n <path d=\"M11 5l-1 0\" />\n <path d=\"M13 7l-1 0\" />\n <path d=\"M11 9l-1 0\" />\n <path d=\"M13 11l-1 0\" />\n <path d=\"M11 13l-1 0\" />\n <path d=\"M13 15l-1 0\" />\n</svg>\n";
3
+ //#endregion
4
+ export { file_zip_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/file.svg.28f5d6f1
2
+ var file_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2\" />\n</svg>\n";
3
+ //#endregion
4
+ export { file_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/photo.svg.cc273cc1
2
+ var photo_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M15 8h.01\" />\n <path d=\"M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12\" />\n <path d=\"M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5\" />\n <path d=\"M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3\" />\n</svg>\n";
3
+ //#endregion
4
+ export { photo_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/player-stop-fill.svg.5378b752
2
+ var player_stop_fill_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M17 4h-10a3 3 0 0 0 -3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3 -3v-10a3 3 0 0 0 -3 -3z\" />\n</svg>\n";
3
+ //#endregion
4
+ export { player_stop_fill_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/send.svg.02326253
2
+ var send_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M10 14l11 -11\" />\n <path d=\"M21 3l-6.5 18a.55 .55 0 0 1 -1 0l-3.5 -7l-7 -3.5a.55 .55 0 0 1 0 -1l18 -6.5\" />\n</svg>\n";
3
+ //#endregion
4
+ export { send_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/sort-ascending-letters.svg.14a3df67
2
+ var sort_ascending_letters_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M15 10v-5c0 -1.38 .62 -2 2 -2s2 .62 2 2v5m0 -3h-4\" />\n <path d=\"M19 21h-4l4 -7h-4\" />\n <path d=\"M4 15l3 3l3 -3\" />\n <path d=\"M7 6v12\" />\n</svg>\n";
3
+ //#endregion
4
+ export { sort_ascending_letters_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/sort-descending-letters.svg.3e03647c
2
+ var sort_descending_letters_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M15 21v-5c0 -1.38 .62 -2 2 -2s2 .62 2 2v5m0 -3h-4\" />\n <path d=\"M19 10h-4l4 -7h-4\" />\n <path d=\"M4 15l3 3l3 -3\" />\n <path d=\"M7 6v12\" />\n</svg>\n";
3
+ //#endregion
4
+ export { sort_descending_letters_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/video.svg.c183f03c
2
+ var video_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M15 10l4.553 -2.276a1 1 0 0 1 1.447 .894v6.764a1 1 0 0 1 -1.447 .894l-4.553 -2.276v-4\" />\n <path d=\"M3 8a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2l0 -8\" />\n</svg>\n";
3
+ //#endregion
4
+ export { video_svg_default as default };
@@ -0,0 +1,4 @@
1
+ //#region \0glob-assets_raw/world.svg.cd9903c8
2
+ var world_svg_default = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0\" />\n <path d=\"M3.6 9h16.8\" />\n <path d=\"M3.6 15h16.8\" />\n <path d=\"M11.5 3a17 17 0 0 0 0 18\" />\n <path d=\"M12.5 3a17 17 0 0 1 0 18\" />\n</svg>\n";
3
+ //#endregion
4
+ export { world_svg_default as default };
@@ -18,6 +18,8 @@ import { UElement } from '@iyulab/components/dist/components/UElement.js';
18
18
  */
19
19
  export declare class UDataElement extends UElement {
20
20
  static styles: import('lit').CSSResultGroup;
21
+ /** ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์ด๋ผ๋„ ์ฝ์—ˆ๋Š”๊ฐ€ โ€” ์žฌ์—ฐ๊ฒฐ ๋•Œ ยซ์Šคํฌ๋ฆฝํŠธ ์—†์Œยป ์„ ์˜ค๋ฅ˜๋กœ ๋ณด์ง€ ์•Š๊ธฐ ์œ„ํ•ด. */
22
+ private loaded;
21
23
  connectedCallback(): void;
22
24
  /**
23
25
  * ์ง€์ •ํ•œ ํƒœ๊ทธ์™€ ๋ฐ์ดํ„ฐ๋กœ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ HTML ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
@@ -19,6 +19,10 @@ import { UElement } from "@iyulab/components/dist/components/UElement.js";
19
19
  * (์˜ˆ: `URefCard` โ€” URefBlock์˜ property ๊ตฌ๋™๊ณผ UMarkedBlock์˜ script ์ฃผ์ž…์„ ๋ชจ๋‘ ์ง€์›)
20
20
  */
21
21
  var UDataElement = class extends UElement {
22
+ constructor(..._args) {
23
+ super(..._args);
24
+ this.loaded = false;
25
+ }
22
26
  static {
23
27
  this.styles = super.styles;
24
28
  }
@@ -55,12 +59,16 @@ var UDataElement = class extends UElement {
55
59
  try {
56
60
  if (!data) {
57
61
  const script = this.querySelector("script[type=\"application/json\"]");
58
- if (!script) throw new Error("Missing <script type=\"application/json\">");
62
+ if (!script) {
63
+ if (this.loaded) return;
64
+ throw new Error("Missing <script type=\"application/json\">");
65
+ }
59
66
  data = JSON.parse(script.textContent ?? "{}");
60
67
  script.remove();
61
68
  }
62
69
  if (typeof data !== "object" || data === null || Array.isArray(data)) throw new Error("Invalid JSON data: expected an object at the top level");
63
70
  Object.assign(this, data);
71
+ this.loaded = true;
64
72
  } catch (error) {
65
73
  await this.error(error);
66
74
  }
@@ -1,3 +1,4 @@
1
+ import "../../utilities/icons.js";
1
2
  import { styles } from "./UCodeBlock.styles.js";
2
3
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
4
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
@@ -1,19 +1,22 @@
1
1
  import { nothing, PropertyValues } from 'lit';
2
2
  import { UDataElement } from '../UDataElement.js';
3
3
  /**
4
- * `block-json` ์ฝ”๋“œํŽœ์Šค์—์„œ ์ง€์ •ํ•œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋™์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
4
+ * `block-json` ์ฝ”๋“œํŽœ์Šค์—์„œ ์ง€์ •ํ•œ ๋ธ”๋ก์„ ๋™์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
5
+ *
6
+ * ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ **๋ธ”๋ก์œผ๋กœ ๋“ฑ๋ก๋œ ํƒœ๊ทธ๋ฟ**์ด๊ณ (`registerElementBlock` ยท
7
+ * `ElementPromptBuilder.add`), ๋Œ€์ž…ํ•˜๋Š” ๊ฒƒ์€ **๊ทธ ์Šคํ‚ค๋งˆ์˜ `properties` ์— ์ ํžŒ ์ด๋ฆ„๋ฟ**์ž…๋‹ˆ๋‹ค.
8
+ * `tag`ยท`properties` ๋Š” LLM ์ถœ๋ ฅ์—์„œ ์˜ค๋ฏ€๋กœ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ž…๋ ฅ์œผ๋กœ ๋‹ค๋ฃน๋‹ˆ๋‹ค โ€” ์Šคํ‚ค๋งˆ ๋ฐ–์˜
9
+ * ์ด๋ฆ„์€ ๋Œ€์ž…ํ•˜์ง€ ์•Š๊ณ  ์ฝ˜์†”์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
5
10
  * ๋Œ€์ƒ ํƒœ๊ทธ๊ฐ€ ๋“ฑ๋ก๋˜์–ด ์žˆ์ง€ ์•Š๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ์—๋Ÿฌ ์นด๋“œ ์—†์ด ์ฝ˜์†”์—๋งŒ ๊ธฐ๋กํ•˜๊ณ  ์•„๋ฌด๊ฒƒ๋„ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
6
11
  */
7
12
  export declare class UElementBlock extends UDataElement {
8
13
  static styles: import('lit').CSSResultGroup[];
9
14
  /** ๋กœ๋”ฉ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. `true`์ธ ๊ฒฝ์šฐ, ์œ„์ ฏ์ด ๋กœ๋”ฉ ์ค‘์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. */
10
15
  loading: boolean;
11
- /** `tag` ํ”„๋กœํผํ‹ฐ์— ๋“ฑ๋ก๋œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. */
16
+ /** ๋ Œ๋”๋งํ•  ๋ธ”๋ก์˜ ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค. ๋ธ”๋ก์œผ๋กœ ๋“ฑ๋ก๋œ ํƒœ๊ทธ๋งŒ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. */
12
17
  tag?: string;
13
- /** `properties` ๊ฐ์ฒด์˜ ํ‚ค๊ฐ€ ๋ Œ๋”๋ง๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„๊ณผ ์ผ์น˜ํ•˜๋ฉด ์ž๋™์œผ๋กœ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. */
18
+ /** ๋ธ”๋ก์— ๋Œ€์ž…ํ•  ๊ฐ’์ž…๋‹ˆ๋‹ค. ๋ธ”๋ก ์Šคํ‚ค๋งˆ์˜ `properties` ์— ์ ํžŒ ์ด๋ฆ„๋งŒ ๋Œ€์ž…๋ฉ๋‹ˆ๋‹ค. */
14
19
  properties?: Record<string, unknown>;
15
- /** `properties` ๊ฐ์ฒด์—์„œ ์œ„ํ—˜ํ•œ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์„ ์ง€์ •ํ•˜์—ฌ ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. */
16
- blacklist: string[];
17
20
  /** ์‹ค์ œ ๋ Œ๋”๋ง๋œ ์—˜๋ฆฌ๋จผํŠธ์ž…๋‹ˆ๋‹ค. `tag` ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. */
18
21
  private element;
19
22
  protected willUpdate(changedProperties: PropertyValues): void;
@@ -24,24 +27,17 @@ export declare class UElementBlock extends UDataElement {
24
27
  */
25
28
  protected error(error: unknown): Promise<void>;
26
29
  /**
27
- * `tag` ํ”„๋กœํผํ‹ฐ์— ๋“ฑ๋ก๋œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
28
- * `tag`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋“ฑ๋ก๋œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์—ฌ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
29
- * `tag`๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋“ฑ๋ก๋œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, ์—๋Ÿฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
30
+ * `tag`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ธ”๋ก ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
31
+ * ๋ธ”๋ก์œผ๋กœ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ํƒœ๊ทธ๋‚˜ ์•„์ง ์ •์˜๋˜์ง€ ์•Š์€ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ธฐ๋ก๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
30
32
  * JSON ์ž์ฒด๋Š” ์ด๋ฏธ ํŒŒ์‹ฑ์— ์„ฑ๊ณตํ•œ ์ƒํƒœ์ด๋ฏ€๋กœ(์ŠคํŠธ๋ฆฌ๋ฐ ์ค‘ ํŒŒ์‹ฑ ์‹คํŒจ์™€๋Š” ๋‹ค๋ฅธ ์ผ€์ด์Šค),
31
33
  * `loading` ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ํ•ญ์ƒ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
32
34
  */
33
35
  private updateElement;
34
36
  /**
35
- * `properties` ๊ฐ์ฒด์˜ ํ‚ค๊ฐ€ ๋ Œ๋”๋ง๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„๊ณผ ์ผ์น˜ํ•˜๋ฉด ์ž๋™์œผ๋กœ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.
36
- * `properties` ๊ฐ์ฒด์— ์œ„ํ—˜ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ๊ฒ€์ฆํ•˜์—ฌ, ์œ ํšจํ•œ ๊ฒฝ์šฐ์—๋งŒ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
37
- * ํ• ๋‹น ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ, ์—๋Ÿฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
37
+ * ๋ธ”๋ก ์Šคํ‚ค๋งˆ์— ์ ํžŒ ์ด๋ฆ„๋งŒ ๋Œ€์ž…ํ•ฉ๋‹ˆ๋‹ค. ์Šคํ‚ค๋งˆ ๋ฐ–์˜ ์ด๋ฆ„์€ ๋Œ€์ž…ํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค โ€”
38
+ * ๋ธ”๋ก ํ•˜๋‚˜๋ฅผ ํ†ต์งธ๋กœ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š” ๊ฒƒ์€ LLM ์ด ๋ฌดํ•ดํ•œ ์—ฌ๋ถ„ ํ‚ค๋ฅผ ๋ถ™์ด๋Š” ์ผ์ด ํ”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
38
39
  */
39
40
  private updateProperties;
40
- /**
41
- * `properties` ๊ฐ์ฒด์— ์œ„ํ—˜ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
42
- * DOM ์กฐ์ž‘์ด๋‚˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ์•…์šฉ๋  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ตœ์†Œํ•œ์œผ๋กœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
43
- */
44
- private validateProperties;
45
41
  /**
46
42
  * ์—๋Ÿฌ ์นด๋“œ ์—†์ด ์ฝ˜์†”์—๋งŒ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์ฑ„ํŒ… UI์— ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ์—๋Ÿฌ ์นด๋“œ๊ฐ€ ๋œจ๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค โ€”
47
43
  * addon ๋ชจ๋“ˆ์„ importํ•˜์ง€ ์•Š์•„ ์•„์ง ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ํƒœ๊ทธ์ผ ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ, ์‹ค์ œ ์—๋Ÿฌ๋ผ๊ธฐ๋ณด๋‹ค
@@ -1,24 +1,16 @@
1
1
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
3
  import { UDataElement } from "../UDataElement.js";
4
+ import { getElementBlockProperties } from "../../utilities/ElementRegistry.js";
4
5
  import { styles } from "./UElementBlock.styles.js";
5
6
  import { html, nothing } from "lit";
6
7
  import { customElement, property, state } from "lit/decorators.js";
7
8
  import "@iyulab/components/dist/components/skeleton/USkeleton.js";
8
9
  //#region src/components/blocks/UElementBlock.ts
9
- var DEFAULT_BLACKLIST = [
10
- "innerHTML",
11
- "outerHTML",
12
- "textContent",
13
- "innerText",
14
- "outerText",
15
- "srcdoc"
16
- ];
17
10
  var UElementBlock = class UElementBlock extends UDataElement {
18
11
  constructor(..._args) {
19
12
  super(..._args);
20
13
  this.loading = false;
21
- this.blacklist = DEFAULT_BLACKLIST;
22
14
  this.element = null;
23
15
  }
24
16
  static {
@@ -27,8 +19,7 @@ var UElementBlock = class UElementBlock extends UDataElement {
27
19
  willUpdate(changedProperties) {
28
20
  super.willUpdate(changedProperties);
29
21
  if (changedProperties.has("tag")) this.updateElement(this.tag);
30
- if (changedProperties.has("properties") && this.element) this.updateProperties(this.element, this.properties);
31
- if (changedProperties.has("blacklist") && this.element && this.properties) this.updateProperties(this.element, this.properties);
22
+ if ((changedProperties.has("properties") || changedProperties.has("tag")) && this.element && this.properties) this.updateProperties(this.element, this.properties);
32
23
  }
33
24
  render() {
34
25
  if (this.loading === true) return html`
@@ -54,9 +45,8 @@ var UElementBlock = class UElementBlock extends UDataElement {
54
45
  this.reportError(error);
55
46
  }
56
47
  /**
57
- * `tag` ํ”„๋กœํผํ‹ฐ์— ๋“ฑ๋ก๋œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
58
- * `tag`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋“ฑ๋ก๋œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์—ฌ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
59
- * `tag`๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋“ฑ๋ก๋œ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, ์—๋Ÿฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
48
+ * `tag`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ธ”๋ก ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
49
+ * ๋ธ”๋ก์œผ๋กœ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ํƒœ๊ทธ๋‚˜ ์•„์ง ์ •์˜๋˜์ง€ ์•Š์€ ์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ธฐ๋ก๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
60
50
  * JSON ์ž์ฒด๋Š” ์ด๋ฏธ ํŒŒ์‹ฑ์— ์„ฑ๊ณตํ•œ ์ƒํƒœ์ด๋ฏ€๋กœ(์ŠคํŠธ๋ฆฌ๋ฐ ์ค‘ ํŒŒ์‹ฑ ์‹คํŒจ์™€๋Š” ๋‹ค๋ฅธ ์ผ€์ด์Šค),
61
51
  * `loading` ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ํ•ญ์ƒ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
62
52
  */
@@ -67,6 +57,11 @@ var UElementBlock = class UElementBlock extends UDataElement {
67
57
  this.reportError(/* @__PURE__ */ new Error("Tag is required"));
68
58
  return;
69
59
  }
60
+ if (!getElementBlockProperties(tag)) {
61
+ this.element = null;
62
+ this.reportError(/* @__PURE__ */ new Error(`"${tag}" is not a registered element block โ€” register its schema with registerElementBlock() or ElementPromptBuilder.add()`));
63
+ return;
64
+ }
70
65
  if (!customElements.get(tag)) {
71
66
  this.element = null;
72
67
  this.reportError(/* @__PURE__ */ new Error(`Unknown tag: ${tag}`));
@@ -75,27 +70,25 @@ var UElementBlock = class UElementBlock extends UDataElement {
75
70
  this.element = document.createElement(tag);
76
71
  }
77
72
  /**
78
- * `properties` ๊ฐ์ฒด์˜ ํ‚ค๊ฐ€ ๋ Œ๋”๋ง๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„๊ณผ ์ผ์น˜ํ•˜๋ฉด ์ž๋™์œผ๋กœ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.
79
- * `properties` ๊ฐ์ฒด์— ์œ„ํ—˜ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ๊ฒ€์ฆํ•˜์—ฌ, ์œ ํšจํ•œ ๊ฒฝ์šฐ์—๋งŒ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
80
- * ํ• ๋‹น ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ, ์—๋Ÿฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
73
+ * ๋ธ”๋ก ์Šคํ‚ค๋งˆ์— ์ ํžŒ ์ด๋ฆ„๋งŒ ๋Œ€์ž…ํ•ฉ๋‹ˆ๋‹ค. ์Šคํ‚ค๋งˆ ๋ฐ–์˜ ์ด๋ฆ„์€ ๋Œ€์ž…ํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค โ€”
74
+ * ๋ธ”๋ก ํ•˜๋‚˜๋ฅผ ํ†ต์งธ๋กœ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š” ๊ฒƒ์€ LLM ์ด ๋ฌดํ•ดํ•œ ์—ฌ๋ถ„ ํ‚ค๋ฅผ ๋ถ™์ด๋Š” ์ผ์ด ํ”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
81
75
  */
82
76
  updateProperties(element, props) {
83
- if (this.validateProperties(props)) try {
84
- Object.assign(element, props);
77
+ if (typeof props !== "object" || props === null || Array.isArray(props)) {
78
+ this.reportError(/* @__PURE__ */ new Error(`Properties must be an object: ${JSON.stringify(props)}`));
79
+ return;
80
+ }
81
+ const allowed = getElementBlockProperties(element.localName) ?? /* @__PURE__ */ new Set();
82
+ const accepted = {};
83
+ const rejected = [];
84
+ for (const [key, value] of Object.entries(props)) if (allowed.has(key)) accepted[key] = value;
85
+ else rejected.push(key);
86
+ if (rejected.length > 0) this.reportError(/* @__PURE__ */ new Error(`Not in the "${element.localName}" schema, not assigned: ${rejected.join(", ")}`));
87
+ try {
88
+ Object.assign(element, accepted);
85
89
  } catch (error) {
86
90
  this.reportError(error);
87
91
  }
88
- else this.reportError(/* @__PURE__ */ new Error(`Not allowed properties: ${JSON.stringify(props)}`));
89
- }
90
- /**
91
- * `properties` ๊ฐ์ฒด์— ์œ„ํ—˜ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
92
- * DOM ์กฐ์ž‘์ด๋‚˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ์•…์šฉ๋  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ตœ์†Œํ•œ์œผ๋กœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
93
- */
94
- validateProperties(props) {
95
- if (typeof props !== "object" || props === null || Array.isArray(props)) return false;
96
- const obj = props;
97
- for (const key of Object.keys(obj)) if (this.blacklist.includes(key)) return false;
98
- return true;
99
92
  }
100
93
  /**
101
94
  * ์—๋Ÿฌ ์นด๋“œ ์—†์ด ์ฝ˜์†”์—๋งŒ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์ฑ„ํŒ… UI์— ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ์—๋Ÿฌ ์นด๋“œ๊ฐ€ ๋œจ๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค โ€”
@@ -112,7 +105,6 @@ __decorate([property({
112
105
  }), __decorateMetadata("design:type", Object)], UElementBlock.prototype, "loading", void 0);
113
106
  __decorate([property({ type: String }), __decorateMetadata("design:type", String)], UElementBlock.prototype, "tag", void 0);
114
107
  __decorate([property({ type: Object }), __decorateMetadata("design:type", typeof Record === "undefined" ? Object : Record)], UElementBlock.prototype, "properties", void 0);
115
- __decorate([property({ type: Array }), __decorateMetadata("design:type", Array)], UElementBlock.prototype, "blacklist", void 0);
116
108
  __decorate([state(), __decorateMetadata("design:type", Object)], UElementBlock.prototype, "element", void 0);
117
109
  UElementBlock = __decorate([customElement("u-element-block")], UElementBlock);
118
110
  //#endregion
@@ -1,3 +1,4 @@
1
+ import "../../utilities/icons.js";
1
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import { messages } from "../../utilities/messages.js";
@@ -13,6 +13,8 @@ import { ReferenceCitation } from '../../types/References.js';
13
13
  * - ๋งˆํฌ๋‹ค์šด ๋งํฌ/์ด๋ฏธ์ง€(`[..](href)`, `![..](src)`, autolink)์˜ href/src๋Š”
14
14
  * `escapeHtmlHref`๋กœ protocol์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค(javascript:/data:/vbscript: ์ฐจ๋‹จ) โ€”
15
15
  * marked ์ž์‹ ์€ URL์„ encodeURIํ•  ๋ฟ protocol์„ ๊ฑธ๋Ÿฌ๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
16
+ * - ์ด๋ฏธ์ง€ src๋Š” ๊ทธ ์œ„์— ์ถœ์ฒ˜ ์ •์ฑ…(`setAllowedImagePrefixes`)์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค โ€” ๋ง‰ํžŒ ์ด๋ฏธ์ง€๋Š”
17
+ * ์š”์ฒญํ•˜์ง€ ์•Š๊ณ  ๋Œ€์ฒด ํ…์ŠคํŠธ๋กœ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค(์ด๋ฏธ์ง€ URL์€ ๋ฐ์ดํ„ฐ ๋ฐ˜์ถœ ๊ฒฝ๋กœ๋‹ค).
16
18
  * - ํ…Œ์ด๋ธ” ์…€ ์ธ๋ผ์ธ ์ฝ˜ํ…์ธ (renderTable)๋„ ์œ„ ๋‘ ๊ทœ์น™๊ณผ ๊ฐ™์€ ๋ Œ๋”๋Ÿฌ ์„ค์ •์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค
17
19
  * โ€” `Parser.parseInline`์„ ์˜ต์…˜ ์—†์ด ํ˜ธ์ถœํ•˜๋ฉด ๊ธฐ๋ณธ(๋น„-sanitize) ๋ Œ๋”๋Ÿฌ๋กœ ๋˜๋Œ์•„๊ฐ€๋ฏ€๋กœ
18
20
  * ๋ฐ˜๋“œ์‹œ `this.parser.defaults`๋ฅผ ํ•จ๊ป˜ ๋„˜๊ฒจ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@@ -30,6 +32,7 @@ export declare class UMarkedBlock extends UElement {
30
32
  private queuedTimer?;
31
33
  private streaming;
32
34
  private streamingTimer?;
35
+ connectedCallback(): void;
33
36
  disconnectedCallback(): void;
34
37
  protected shouldUpdate(_changedProperties: PropertyValues): boolean;
35
38
  protected willUpdate(changedProperties: PropertyValues): void;
@@ -60,7 +63,11 @@ export declare class UMarkedBlock extends UElement {
60
63
  * URL์„ encodeURIํ•  ๋ฟ protocol์„ ๊ฑธ๋Ÿฌ๋‚ด์ง€ ์•Š๋Š”๋‹ค.
61
64
  */
62
65
  private renderLink;
63
- /** ๋งˆํฌ๋‹ค์šด ์ด๋ฏธ์ง€์˜ src๋„ `renderLink`์™€ ๋™์ผํ•˜๊ฒŒ protocol์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. */
66
+ /**
67
+ * ๋งˆํฌ๋‹ค์šด ์ด๋ฏธ์ง€์˜ src๋„ `renderLink`์™€ ๋™์ผํ•˜๊ฒŒ protocol์„ ๊ฒ€์‚ฌํ•˜๊ณ , ์ด๋ฏธ์ง€ ์ถœ์ฒ˜ ์ •์ฑ…
68
+ * (`setAllowedImagePrefixes`)์— ๋Œ€์–ด ๋ด…๋‹ˆ๋‹ค. ๋ง‰ํžŒ ์ด๋ฏธ์ง€๋Š” `<img>` ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค โ€”
69
+ * ์š”์ฒญ ์ž์ฒด๊ฐ€ ๋ฐ˜์ถœ ๊ฒฝ๋กœ์ด๋ฏ€๋กœ ๋Œ€์ฒด ํ…์ŠคํŠธ๋งŒ ๊ทธ๋ฆฐ๋‹ค.
70
+ */
64
71
  private renderImage;
65
72
  /**
66
73
  * ์ธ์šฉ/์ถœ์ฒ˜ ์ฐธ์กฐ๊ฐ์ฒด๊ฐ€ ์žˆ์„๋•Œ ref ํƒœ๊ทธ HTML์„ this.placeholder์— ๋ณด๊ด€ํ•˜๊ณ 
@@ -4,11 +4,13 @@ import "./UCodeBlock.js";
4
4
  import { escapeHtmlAttr, escapeHtmlHref, escapeHtmlText, stripZeroWidth } from "../../utilities/sanitizers.js";
5
5
  import { HtmlBuilder } from "../../utilities/HtmlBuilder.js";
6
6
  import { UElementBlock } from "./UElementBlock.js";
7
+ import { messages } from "../../utilities/messages.js";
7
8
  import { markedKatex } from "../../utilities/markedKatex.js";
8
9
  import "../references/URefTag.js";
9
10
  import { URefCard } from "../references/URefCard.js";
10
11
  import "../references/URefCardGroup.js";
11
12
  import { UTableBlock } from "./UTableBlock.js";
13
+ import { resolveImageSource } from "../../utilities/imageSources.js";
12
14
  import { HtmlPlaceholder, stripRefPlaceholders } from "../../utilities/HtmlPlaceholder.js";
13
15
  import { styles } from "./UMarkedBlock.styles.js";
14
16
  import { nothing } from "lit";
@@ -40,9 +42,15 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
40
42
  static {
41
43
  this.styles = [super.styles, styles];
42
44
  }
45
+ connectedCallback() {
46
+ super.connectedCallback();
47
+ this.requestUpdate();
48
+ }
43
49
  disconnectedCallback() {
44
50
  clearTimeout(this.queuedTimer);
45
51
  clearTimeout(this.streamingTimer);
52
+ this.queued = false;
53
+ this.streaming = false;
46
54
  super.disconnectedCallback();
47
55
  }
48
56
  shouldUpdate(_changedProperties) {
@@ -79,7 +87,7 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
79
87
  */
80
88
  renderCode(token) {
81
89
  const lang = token.lang ?? "plaintext";
82
- if (lang === "block-json") return UElementBlock.buildHTML(token.text, { loading: this.streaming });
90
+ if (lang === "block-json") return UElementBlock.buildHTML(stripRefPlaceholders(token.text), { loading: this.streaming });
83
91
  const safeText = escapeHtmlText(this.removeRefs(token.text));
84
92
  return HtmlBuilder.build("u-code-block", { lang }, safeText);
85
93
  }
@@ -93,12 +101,13 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
93
101
  * ๋ฐ˜๋“œ์‹œ `this.parser.defaults`(์šฐ๋ฆฌ ๋ Œ๋”๋Ÿฌ๊ฐ€ ๋ณ‘ํ•ฉ๋œ ์„ค์ •)๋ฅผ ํ•จ๊ป˜ ๋„˜๊ธด๋‹ค.
94
102
  */
95
103
  renderTable(token) {
104
+ const cellHtml = (cell) => this.placeholder.restore(cell.tokens ? Parser.parseInline(cell.tokens, this.parser.defaults) : cell.text);
96
105
  const headers = token.header.map((h) => ({
97
- text: h.tokens ? Parser.parseInline(h.tokens, this.parser.defaults) : h.text,
106
+ text: cellHtml(h),
98
107
  align: h.align
99
108
  }));
100
109
  const rows = token.rows.map((row) => row.map((cell) => ({
101
- text: cell.tokens ? Parser.parseInline(cell.tokens, this.parser.defaults) : cell.text,
110
+ text: cellHtml(cell),
102
111
  align: cell.align
103
112
  })));
104
113
  return UTableBlock.buildHTML({
@@ -126,9 +135,18 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
126
135
  out += `>${text}</a>`;
127
136
  return out;
128
137
  }
129
- /** ๋งˆํฌ๋‹ค์šด ์ด๋ฏธ์ง€์˜ src๋„ `renderLink`์™€ ๋™์ผํ•˜๊ฒŒ protocol์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. */
138
+ /**
139
+ * ๋งˆํฌ๋‹ค์šด ์ด๋ฏธ์ง€์˜ src๋„ `renderLink`์™€ ๋™์ผํ•˜๊ฒŒ protocol์„ ๊ฒ€์‚ฌํ•˜๊ณ , ์ด๋ฏธ์ง€ ์ถœ์ฒ˜ ์ •์ฑ…
140
+ * (`setAllowedImagePrefixes`)์— ๋Œ€์–ด ๋ด…๋‹ˆ๋‹ค. ๋ง‰ํžŒ ์ด๋ฏธ์ง€๋Š” `<img>` ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค โ€”
141
+ * ์š”์ฒญ ์ž์ฒด๊ฐ€ ๋ฐ˜์ถœ ๊ฒฝ๋กœ์ด๋ฏ€๋กœ ๋Œ€์ฒด ํ…์ŠคํŠธ๋งŒ ๊ทธ๋ฆฐ๋‹ค.
142
+ */
130
143
  renderImage(token) {
131
- let out = `<img src="${escapeHtmlHref(token.href)}" alt="${escapeHtmlAttr(token.text)}"`;
144
+ const src = resolveImageSource(token.href);
145
+ if (src === null) {
146
+ const label = token.text ? messages.text("imageBlockedNamed", { name: token.text }) : messages.text("imageBlocked");
147
+ return `<span class="image-blocked" part="image-blocked">${escapeHtmlText(label)}</span>`;
148
+ }
149
+ let out = `<img src="${escapeHtmlAttr(src)}" alt="${escapeHtmlAttr(token.text)}"`;
132
150
  if (token.title) out += ` title="${escapeHtmlAttr(token.title)}"`;
133
151
  out += `>`;
134
152
  return out;
@@ -327,6 +327,16 @@ var styles = css`
327
327
  background-color: transparent;
328
328
  }
329
329
 
330
+ /* ์ด๋ฏธ์ง€ ์ถœ์ฒ˜ ์ •์ฑ…์ด ๋ง‰์€ ์ž๋ฆฌ โ€” ์š”์ฒญ ์—†์ด ๋Œ€์ฒด ํ…์ŠคํŠธ๋งŒ ๋ณด์ธ๋‹ค. */
331
+ .image-blocked {
332
+ display: inline-block;
333
+ padding: 0 var(--base-size-4);
334
+ border: 1px dashed var(--borderColor-default);
335
+ border-radius: 6px;
336
+ color: var(--fgColor-muted);
337
+ font-size: 0.875em;
338
+ }
339
+
330
340
  .emoji {
331
341
  max-width: none;
332
342
  vertical-align: text-top;
@@ -1,3 +1,4 @@
1
+ import "../../utilities/icons.js";
1
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import { UDataElement } from "../UDataElement.js";
@@ -1,3 +1,4 @@
1
+ import "../../utilities/icons.js";
1
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import { messages } from "../../utilities/messages.js";
@@ -9,6 +10,7 @@ import "@iyulab/components/dist/components/icon/UIcon.js";
9
10
  import { UElement } from "@iyulab/components/dist/components/UElement.js";
10
11
  import "@iyulab/components/dist/components/button/UButton.js";
11
12
  import { repeat } from "lit/directives/repeat.js";
13
+ import { isImeComposing } from "@iyulab/components/dist/utilities/keyboard.js";
12
14
  //#region src/components/prompt/UPrompt.ts
13
15
  var UPrompt = class UPrompt extends UElement {
14
16
  constructor(..._args) {
@@ -115,7 +117,7 @@ var UPrompt = class UPrompt extends UElement {
115
117
  this.value = target.value;
116
118
  }
117
119
  handleTextBlockKeydown(e) {
118
- if (e.key === "Enter" && !e.shiftKey) {
120
+ if (e.key === "Enter" && !e.shiftKey && !isImeComposing(e)) {
119
121
  e.preventDefault();
120
122
  this.submit();
121
123
  }
@@ -1,5 +1,7 @@
1
+ import "../../utilities/icons.js";
1
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
4
+ import { sanitizeHref } from "../../utilities/sanitizers.js";
3
5
  import { UDataElement } from "../UDataElement.js";
4
6
  import { styles } from "./URefCard.styles.js";
5
7
  import { html, nothing } from "lit";
@@ -36,7 +38,7 @@ var URefCard = class URefCard extends UDataElement {
36
38
  }
37
39
  render() {
38
40
  return html`
39
- <a href="${ifDefined(this.url)}" target="_blank" rel="noopener noreferrer"
41
+ <a href="${ifDefined(this.url ? sanitizeHref(this.url) : void 0)}" target="_blank" rel="noopener noreferrer"
40
42
  @click=${this.handleAnchorClick}>
41
43
  <div class="header">
42
44
  ${this.renderFavicon()}