@limetech/lime-elements 39.0.3 → 39.1.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 (254) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/index-nxo2UO7I.js +20355 -0
  3. package/dist/cjs/lime-elements.cjs.js +1 -1
  4. package/dist/cjs/limel-action-bar_2.cjs.entry.js +4 -4
  5. package/dist/cjs/limel-ai-avatar.cjs.entry.js +1 -1
  6. package/dist/cjs/limel-breadcrumbs_7.cjs.entry.js +6 -6
  7. package/dist/cjs/limel-callout.cjs.entry.js +1 -1
  8. package/dist/cjs/limel-chart.cjs.entry.js +1 -1
  9. package/dist/cjs/limel-chip_2.cjs.entry.js +1 -1
  10. package/dist/cjs/limel-code-editor.cjs.entry.js +1 -1
  11. package/dist/cjs/limel-collapsible-section.cjs.entry.js +2 -2
  12. package/dist/cjs/limel-drag-handle.cjs.entry.js +1 -1
  13. package/dist/cjs/limel-email-viewer.cjs.entry.js +351 -0
  14. package/dist/cjs/limel-file-dropzone_2.cjs.entry.js +2 -2
  15. package/dist/cjs/limel-file-viewer.cjs.entry.js +4967 -26
  16. package/dist/cjs/limel-file.cjs.entry.js +2 -2
  17. package/dist/cjs/limel-flatpickr-adapter.cjs.entry.js +1 -1
  18. package/dist/cjs/limel-flex-container.cjs.entry.js +1 -1
  19. package/dist/cjs/limel-form.cjs.entry.js +1 -1
  20. package/dist/cjs/limel-grid.cjs.entry.js +1 -1
  21. package/dist/cjs/limel-header.cjs.entry.js +1 -1
  22. package/dist/cjs/limel-help-content.cjs.entry.js +1 -1
  23. package/dist/cjs/limel-help.cjs.entry.js +2 -2
  24. package/dist/cjs/limel-helper-line_2.cjs.entry.js +3 -3
  25. package/dist/cjs/limel-icon-button.cjs.entry.js +1 -1
  26. package/dist/cjs/limel-icon.cjs.entry.js +1 -1
  27. package/dist/cjs/limel-info-tile.cjs.entry.js +2 -2
  28. package/dist/cjs/limel-linear-progress.cjs.entry.js +1 -1
  29. package/dist/cjs/limel-list-item.cjs.entry.js +3 -3
  30. package/dist/cjs/limel-markdown.cjs.entry.js +3 -2
  31. package/dist/cjs/limel-menu-item-meta.cjs.entry.js +1 -1
  32. package/dist/cjs/limel-picker.cjs.entry.js +1 -1
  33. package/dist/cjs/limel-popover_2.cjs.entry.js +2 -2
  34. package/dist/cjs/limel-portal_3.cjs.entry.js +4 -4
  35. package/dist/cjs/limel-profile-picture.cjs.entry.js +1 -1
  36. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +15 -14
  37. package/dist/cjs/limel-radio-button-group.cjs.entry.js +1 -1
  38. package/dist/cjs/limel-radio-button.cjs.entry.js +2 -2
  39. package/dist/cjs/limel-select.cjs.entry.js +1 -1
  40. package/dist/cjs/limel-shortcut.cjs.entry.js +1 -1
  41. package/dist/cjs/limel-slider.cjs.entry.js +1 -1
  42. package/dist/cjs/limel-snackbar.cjs.entry.js +3 -3
  43. package/dist/cjs/limel-split-button.cjs.entry.js +2 -2
  44. package/dist/cjs/limel-tab-bar.cjs.entry.js +2 -2
  45. package/dist/cjs/limel-tab-panel.cjs.entry.js +1 -1
  46. package/dist/cjs/limel-table.cjs.entry.js +4 -4
  47. package/dist/cjs/limel-text-editor.cjs.entry.js +1 -1
  48. package/dist/cjs/loader.cjs.js +1 -1
  49. package/dist/cjs/{markdown-parser-_1bsy-5h.js → markdown-parser-B66l_Zvo.js} +20342 -40680
  50. package/dist/cjs/{translations-BIHr3B9O.js → translations-B0hzD08N.js} +112 -0
  51. package/dist/collection/collection-manifest.json +1 -0
  52. package/dist/collection/components/collapsible-section/collapsible-section.css +1 -0
  53. package/dist/collection/components/email-viewer/email-loader.js +206 -0
  54. package/dist/collection/components/email-viewer/email-viewer.css +293 -0
  55. package/dist/collection/components/email-viewer/email-viewer.js +294 -0
  56. package/dist/collection/components/email-viewer/email-viewer.types.js +1 -0
  57. package/dist/collection/components/email-viewer/remote-images.js +50 -0
  58. package/dist/collection/components/email-viewer/sanitize-email-html.js +245 -0
  59. package/dist/collection/components/email-viewer/split-email-address-list.js +106 -0
  60. package/dist/collection/components/file/file.js +1 -1
  61. package/dist/collection/components/file-dropzone/file-dropzone.js +1 -1
  62. package/dist/collection/components/file-input/file-input.js +1 -1
  63. package/dist/collection/components/file-viewer/extension-mapping.js +1 -0
  64. package/dist/collection/components/file-viewer/file-viewer.js +54 -7
  65. package/dist/collection/components/flex-container/flex-container.js +1 -1
  66. package/dist/collection/components/form/form.js +1 -1
  67. package/dist/collection/components/grid/grid.js +1 -1
  68. package/dist/collection/components/header/header.js +1 -1
  69. package/dist/collection/components/help/help-content.js +1 -1
  70. package/dist/collection/components/help/help.js +2 -2
  71. package/dist/collection/components/helper-line/helper-line.js +2 -2
  72. package/dist/collection/components/icon/icon.js +1 -1
  73. package/dist/collection/components/icon-button/icon-button.js +1 -1
  74. package/dist/collection/components/info-tile/info-tile.js +2 -2
  75. package/dist/collection/components/input-field/input-field.js +1 -1
  76. package/dist/collection/components/list/list.js +1 -1
  77. package/dist/collection/components/list-item/list-item.js +2 -2
  78. package/dist/collection/components/list-item/menu-item-meta/menu-item-meta.js +1 -1
  79. package/dist/collection/components/markdown/markdown.js +1 -1
  80. package/dist/collection/components/menu/menu.js +1 -1
  81. package/dist/collection/components/menu-list/menu-list.js +1 -1
  82. package/dist/collection/components/menu-surface/menu-surface.js +1 -1
  83. package/dist/collection/components/notched-outline/notched-outline.js +1 -1
  84. package/dist/collection/components/picker/picker.js +1 -1
  85. package/dist/collection/components/popover/popover.js +1 -1
  86. package/dist/collection/components/popover-surface/popover-surface.js +1 -1
  87. package/dist/collection/components/portal/portal.js +1 -1
  88. package/dist/collection/components/radio-button-group/radio-button-group.js +1 -1
  89. package/dist/collection/components/radio-button-group/radio-button.js +2 -2
  90. package/dist/collection/components/select/select.js +1 -1
  91. package/dist/collection/components/shortcut/shortcut.js +1 -1
  92. package/dist/collection/components/slider/slider.js +1 -1
  93. package/dist/collection/components/snackbar/snackbar.js +2 -2
  94. package/dist/collection/components/spinner/spinner.js +1 -1
  95. package/dist/collection/components/split-button/split-button.js +2 -2
  96. package/dist/collection/components/tab-bar/tab-bar.js +2 -2
  97. package/dist/collection/components/tab-panel/tab-panel.js +1 -1
  98. package/dist/collection/components/table/table.js +3 -3
  99. package/dist/collection/components/text-editor/link-menu/editor-link-menu.js +3 -3
  100. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +1 -1
  101. package/dist/collection/components/text-editor/text-editor.js +1 -1
  102. package/dist/collection/components/tooltip/tooltip-content.js +1 -1
  103. package/dist/collection/components/tooltip/tooltip.js +2 -2
  104. package/dist/collection/interface.js +1 -0
  105. package/dist/collection/translations/da.js +14 -0
  106. package/dist/collection/translations/de.js +14 -0
  107. package/dist/collection/translations/en.js +14 -0
  108. package/dist/collection/translations/fi.js +14 -0
  109. package/dist/collection/translations/fr.js +14 -0
  110. package/dist/collection/translations/nl.js +14 -0
  111. package/dist/collection/translations/no.js +14 -0
  112. package/dist/collection/translations/sv.js +14 -0
  113. package/dist/collection/util/format-bytes.js +38 -0
  114. package/dist/esm/{file-metadata-D5joHaqk.js → file-metadata-BwF9vTXN.js} +1 -1
  115. package/dist/esm/{files-CkgibGPZ.js → files-P324wLau.js} +1 -1
  116. package/dist/esm/{get-icon-props-COzG_Mhw.js → get-icon-props-CgNJbSP4.js} +1 -1
  117. package/dist/esm/index-CJ0GYrWG.js +20341 -0
  118. package/dist/esm/lime-elements.js +1 -1
  119. package/dist/esm/limel-action-bar-item_2.entry.js +1 -1
  120. package/dist/esm/limel-action-bar_2.entry.js +4 -4
  121. package/dist/esm/limel-ai-avatar.entry.js +1 -1
  122. package/dist/esm/limel-breadcrumbs_7.entry.js +7 -7
  123. package/dist/esm/limel-button.entry.js +1 -1
  124. package/dist/esm/limel-callout.entry.js +1 -1
  125. package/dist/esm/limel-card.entry.js +1 -1
  126. package/dist/esm/limel-chart.entry.js +1 -1
  127. package/dist/esm/limel-chip_2.entry.js +2 -2
  128. package/dist/esm/limel-code-editor.entry.js +1 -1
  129. package/dist/esm/limel-collapsible-section.entry.js +3 -3
  130. package/dist/esm/limel-drag-handle.entry.js +1 -1
  131. package/dist/esm/limel-dynamic-label.entry.js +1 -1
  132. package/dist/esm/limel-email-viewer.entry.js +349 -0
  133. package/dist/esm/limel-file-dropzone_2.entry.js +5 -5
  134. package/dist/esm/limel-file-viewer.entry.js +4948 -7
  135. package/dist/esm/limel-file.entry.js +4 -4
  136. package/dist/esm/limel-flatpickr-adapter.entry.js +1 -1
  137. package/dist/esm/limel-flex-container.entry.js +1 -1
  138. package/dist/esm/limel-form.entry.js +1 -1
  139. package/dist/esm/limel-grid.entry.js +1 -1
  140. package/dist/esm/limel-header.entry.js +2 -2
  141. package/dist/esm/limel-help-content.entry.js +1 -1
  142. package/dist/esm/limel-help.entry.js +2 -2
  143. package/dist/esm/limel-helper-line_2.entry.js +3 -3
  144. package/dist/esm/limel-icon-button.entry.js +2 -2
  145. package/dist/esm/limel-icon.entry.js +1 -1
  146. package/dist/esm/limel-info-tile.entry.js +2 -2
  147. package/dist/esm/limel-linear-progress.entry.js +1 -1
  148. package/dist/esm/limel-list-item.entry.js +4 -4
  149. package/dist/esm/limel-markdown.entry.js +3 -2
  150. package/dist/esm/limel-menu-item-meta.entry.js +1 -1
  151. package/dist/esm/limel-picker.entry.js +2 -2
  152. package/dist/esm/limel-popover_2.entry.js +2 -2
  153. package/dist/esm/limel-portal_3.entry.js +4 -4
  154. package/dist/esm/limel-profile-picture.entry.js +4 -4
  155. package/dist/esm/limel-progress-flow-item.entry.js +1 -1
  156. package/dist/esm/limel-progress-flow.entry.js +1 -1
  157. package/dist/esm/limel-prosemirror-adapter.entry.js +7 -6
  158. package/dist/esm/limel-radio-button-group.entry.js +1 -1
  159. package/dist/esm/limel-radio-button.entry.js +2 -2
  160. package/dist/esm/limel-select.entry.js +2 -2
  161. package/dist/esm/limel-shortcut.entry.js +1 -1
  162. package/dist/esm/limel-slider.entry.js +1 -1
  163. package/dist/esm/limel-snackbar.entry.js +3 -3
  164. package/dist/esm/limel-split-button.entry.js +2 -2
  165. package/dist/esm/limel-tab-bar.entry.js +3 -3
  166. package/dist/esm/limel-tab-panel.entry.js +1 -1
  167. package/dist/esm/limel-table.entry.js +4 -4
  168. package/dist/esm/limel-text-editor.entry.js +1 -1
  169. package/dist/esm/loader.js +1 -1
  170. package/dist/esm/{markdown-parser-DkmQCwAi.js → markdown-parser-DJi1w622.js} +20287 -40624
  171. package/dist/esm/{translations-6rJPElLH.js → translations-Cdx3I2X8.js} +112 -0
  172. package/dist/lime-elements/lime-elements.esm.js +1 -1
  173. package/dist/lime-elements/{p-927622ec.entry.js → p-00fdb26c.entry.js} +1 -1
  174. package/dist/lime-elements/{p-880b9683.entry.js → p-1244d687.entry.js} +2 -2
  175. package/dist/lime-elements/p-1d71e9c8.entry.js +1 -0
  176. package/dist/lime-elements/p-21aef7f4.entry.js +1 -0
  177. package/dist/lime-elements/{p-68f49d6f.entry.js → p-278356b3.entry.js} +1 -1
  178. package/dist/lime-elements/{p-a6fae24d.entry.js → p-28dae22e.entry.js} +1 -1
  179. package/dist/lime-elements/{p-6951136b.entry.js → p-2d31cf0d.entry.js} +1 -1
  180. package/dist/lime-elements/{p-6e3666e5.entry.js → p-2ef38dac.entry.js} +1 -1
  181. package/dist/lime-elements/{p-dd36d57b.entry.js → p-2f788e92.entry.js} +7 -7
  182. package/dist/lime-elements/p-2kcqdtMr.js +1 -0
  183. package/dist/lime-elements/{p-11f716f5.entry.js → p-3000785f.entry.js} +1 -1
  184. package/dist/lime-elements/{p-2a5b259e.entry.js → p-3130d348.entry.js} +1 -1
  185. package/dist/lime-elements/{p-feeae1e4.entry.js → p-38097fa1.entry.js} +1 -1
  186. package/dist/lime-elements/p-3b299849.entry.js +1 -0
  187. package/dist/lime-elements/{p-00859fac.entry.js → p-3e6ce4e1.entry.js} +2 -2
  188. package/dist/lime-elements/{p-23f7956e.entry.js → p-3ec31835.entry.js} +1 -1
  189. package/dist/lime-elements/{p-52edfe86.entry.js → p-44396c0d.entry.js} +1 -1
  190. package/dist/lime-elements/{p-ec42a4aa.entry.js → p-494f880b.entry.js} +1 -1
  191. package/dist/lime-elements/{p-d1fa6da3.entry.js → p-4f6e3057.entry.js} +3 -3
  192. package/dist/lime-elements/{p-e6d74062.entry.js → p-504ae59f.entry.js} +1 -1
  193. package/dist/lime-elements/{p-7d5bd4a2.entry.js → p-51565372.entry.js} +1 -1
  194. package/dist/lime-elements/{p-5ddeb498.entry.js → p-52098c47.entry.js} +1 -1
  195. package/dist/lime-elements/{p-d2123236.entry.js → p-521a0204.entry.js} +1 -1
  196. package/dist/lime-elements/{p-38fb97fe.entry.js → p-54d85ae4.entry.js} +1 -1
  197. package/dist/lime-elements/{p-88f503eb.entry.js → p-59a522ee.entry.js} +1 -1
  198. package/dist/lime-elements/{p-2c1538f0.entry.js → p-5af72e1b.entry.js} +1 -1
  199. package/dist/lime-elements/p-64cc5094.entry.js +1 -0
  200. package/dist/lime-elements/{p-045c6027.entry.js → p-67a2c7f5.entry.js} +1 -1
  201. package/dist/lime-elements/{p-8db6b7d9.entry.js → p-68b1605f.entry.js} +1 -1
  202. package/dist/lime-elements/{p-7457bc07.entry.js → p-770981e6.entry.js} +1 -1
  203. package/dist/lime-elements/{p-9ea564fe.entry.js → p-7ed97446.entry.js} +1 -1
  204. package/dist/lime-elements/{p-cbb7d624.entry.js → p-8053727c.entry.js} +1 -1
  205. package/dist/lime-elements/{p-fc3209db.entry.js → p-80f9f2d3.entry.js} +1 -1
  206. package/dist/lime-elements/{p-34ef71f2.entry.js → p-95fb9ef8.entry.js} +1 -1
  207. package/dist/lime-elements/{p-6275668f.entry.js → p-961dff13.entry.js} +1 -1
  208. package/dist/lime-elements/{p-abef62d7.entry.js → p-97952658.entry.js} +1 -1
  209. package/dist/lime-elements/{p-d6270e4a.entry.js → p-982b9f50.entry.js} +1 -1
  210. package/dist/lime-elements/p-9c4156c6.entry.js +1 -0
  211. package/dist/lime-elements/p-BRCcjfVu.js +7 -0
  212. package/dist/lime-elements/{p-DSjFzQmB.js → p-CWuGCKo1.js} +1 -1
  213. package/dist/lime-elements/p-Cdx3I2X8.js +1 -0
  214. package/dist/lime-elements/{p-COzG_Mhw.js → p-CgNJbSP4.js} +1 -1
  215. package/dist/lime-elements/{p-BQY2kAWs.js → p-DlJXKdhK.js} +1 -1
  216. package/dist/lime-elements/{p-bbaf35ce.entry.js → p-a9f3f90c.entry.js} +1 -1
  217. package/dist/lime-elements/{p-c9e934af.entry.js → p-af5f2052.entry.js} +1 -1
  218. package/dist/lime-elements/{p-e11c9b40.entry.js → p-c2478225.entry.js} +1 -1
  219. package/dist/lime-elements/{p-6aebcf60.entry.js → p-c7f2e189.entry.js} +1 -1
  220. package/dist/lime-elements/{p-d424688d.entry.js → p-cb2cc243.entry.js} +1 -1
  221. package/dist/lime-elements/{p-c118eac0.entry.js → p-cce53162.entry.js} +1 -1
  222. package/dist/lime-elements/{p-6896d5c8.entry.js → p-d4fea438.entry.js} +1 -1
  223. package/dist/lime-elements/{p-534fdf9b.entry.js → p-df1fa930.entry.js} +1 -1
  224. package/dist/lime-elements/{p-52bb74b9.entry.js → p-e05ad4f8.entry.js} +1 -1
  225. package/dist/lime-elements/{p-303d01e5.entry.js → p-e6b0e0a2.entry.js} +1 -1
  226. package/dist/lime-elements/{p-80d35f8f.entry.js → p-e975cc29.entry.js} +1 -1
  227. package/dist/lime-elements/{p-9ed578ec.entry.js → p-f532b60f.entry.js} +1 -1
  228. package/dist/lime-elements/{p-4be18a57.entry.js → p-ff845f5c.entry.js} +1 -1
  229. package/dist/types/components/email-viewer/email-loader.d.ts +19 -0
  230. package/dist/types/components/email-viewer/email-viewer.d.ts +69 -0
  231. package/dist/types/components/email-viewer/email-viewer.types.d.ts +70 -0
  232. package/dist/types/components/email-viewer/remote-images.d.ts +22 -0
  233. package/dist/types/components/email-viewer/sanitize-email-html.d.ts +14 -0
  234. package/dist/types/components/email-viewer/split-email-address-list.d.ts +25 -0
  235. package/dist/types/components/file-viewer/file-viewer.d.ts +9 -0
  236. package/dist/types/components/file-viewer/file-viewer.types.d.ts +1 -1
  237. package/dist/types/components.d.ts +116 -0
  238. package/dist/types/interface.d.ts +1 -0
  239. package/dist/types/translations/da.d.ts +10 -0
  240. package/dist/types/translations/de.d.ts +10 -0
  241. package/dist/types/translations/en.d.ts +10 -0
  242. package/dist/types/translations/fi.d.ts +10 -0
  243. package/dist/types/translations/fr.d.ts +10 -0
  244. package/dist/types/translations/nl.d.ts +10 -0
  245. package/dist/types/translations/no.d.ts +10 -0
  246. package/dist/types/translations/sv.d.ts +10 -0
  247. package/dist/types/util/format-bytes.d.ts +21 -0
  248. package/package.json +4 -5
  249. package/dist/lime-elements/p-017dd326.entry.js +0 -1
  250. package/dist/lime-elements/p-4beeec39.entry.js +0 -1
  251. package/dist/lime-elements/p-55596d9a.entry.js +0 -1
  252. package/dist/lime-elements/p-6rJPElLH.js +0 -1
  253. package/dist/lime-elements/p-Df0HAtSs.js +0 -7
  254. package/dist/lime-elements/p-f395fbe3.entry.js +0 -1
@@ -0,0 +1,349 @@
1
+ import { r as registerInstance, c as createEvent, h, H as Host } from './index-xvTBZcD2.js';
2
+ import { t as translate } from './translations-Cdx3I2X8.js';
3
+
4
+ /**
5
+ * Checks whether the given HTML contains any images with a `data-remote-src`
6
+ * attribute, indicating they reference external (remote) resources.
7
+ *
8
+ * @param html - The HTML string to inspect.
9
+ */
10
+ function containsRemoteImages(html) {
11
+ const parser = new DOMParser();
12
+ const document = parser.parseFromString(html, 'text/html');
13
+ return document.querySelector('img[data-remote-src]') !== null;
14
+ }
15
+ /**
16
+ * If `allowRemoteImages` is `true`, replaces the `src` attribute of every
17
+ * `<img data-remote-src="...">` element with the value of `data-remote-src`
18
+ * (provided it points to an http(s) URL) and removes the data attribute.
19
+ *
20
+ * When `allowRemoteImages` is `false` the HTML is returned unchanged.
21
+ *
22
+ * Returns an HTML fragment that is safe to assign to `innerHTML` on a regular
23
+ * container element (not a full `<html>/<head>/<body>` document string).
24
+ *
25
+ * @param html - The HTML string to process.
26
+ * @param allowRemoteImages - Whether to restore remote image sources.
27
+ */
28
+ function applyRemoteImagesPolicy(html, allowRemoteImages) {
29
+ if (!allowRemoteImages) {
30
+ return html;
31
+ }
32
+ const parser = new DOMParser();
33
+ const document = parser.parseFromString(html, 'text/html');
34
+ const images = document.querySelectorAll('img[data-remote-src]');
35
+ for (const image of images) {
36
+ const remoteSrc = image.dataset.remoteSrc;
37
+ if (!remoteSrc || !isAllowedRemoteImageUrl(remoteSrc)) {
38
+ delete image.dataset.remoteSrc;
39
+ continue;
40
+ }
41
+ image.setAttribute('src', remoteSrc);
42
+ delete image.dataset.remoteSrc;
43
+ }
44
+ const headStyles = [...document.head.querySelectorAll('style')]
45
+ .map((style) => style.outerHTML)
46
+ .join('');
47
+ return `${headStyles}${document.body.innerHTML}`;
48
+ }
49
+ function isAllowedRemoteImageUrl(url) {
50
+ const trimmed = url.trim();
51
+ const lower = trimmed.toLowerCase();
52
+ return lower.startsWith('https://') || lower.startsWith('http://');
53
+ }
54
+
55
+ /**
56
+ * Splits a comma-separated email address list (e.g. `To:` / `Cc:`) into individual
57
+ * recipient strings.
58
+ *
59
+ * In RFC 5322, address lists are comma-separated. However, commas can also appear
60
+ * inside quoted display names (quoted-string) and must then be ignored as separators.
61
+ * This splitter only treats a comma as a separator when it is outside quoted strings
62
+ * and outside angle-bracketed address parts (`<...>`).
63
+ *
64
+ * Notes:
65
+ * - If a display name contains a comma, it should be quoted or encoded to be
66
+ * unambiguous, e.g. `"Doe, Jane" <jane.doe@example.com>` or
67
+ * `=?UTF-8?Q?Doe,_Jane?= <jane.doe@example.com>`.
68
+ * - Real-world `.eml` files are usually RFC-ish but not always perfectly compliant.
69
+ * Malformed input with unquoted commas in display names may be split incorrectly.
70
+ *
71
+ * @param value - A comma-separated list of recipients.
72
+ * @returns An array of trimmed recipient strings.
73
+ *
74
+ * @example
75
+ * splitEmailAddressList('"Doe, Jane" <jane@example.com>, Team <team@example.com>');
76
+ * // => ['"Doe, Jane" <jane@example.com>', 'Team <team@example.com>']
77
+ */
78
+ function splitEmailAddressList(value) {
79
+ const parts = [];
80
+ let current = '';
81
+ const state = {
82
+ inQuotes: false,
83
+ escapeNext: false,
84
+ angleDepth: 0,
85
+ };
86
+ const append = (character) => {
87
+ current += character;
88
+ };
89
+ const flush = () => {
90
+ const trimmed = current.trim();
91
+ if (trimmed) {
92
+ parts.push(trimmed);
93
+ }
94
+ current = '';
95
+ };
96
+ for (const character of value) {
97
+ if (consumeEscaped(character, state, append)) {
98
+ continue;
99
+ }
100
+ if (beginEscape(character, state, append)) {
101
+ continue;
102
+ }
103
+ if (toggleQuote(character, state, append)) {
104
+ continue;
105
+ }
106
+ if (adjustAngleDepth(character, state, append)) {
107
+ continue;
108
+ }
109
+ if (isAddressSeparator(character, state)) {
110
+ flush();
111
+ continue;
112
+ }
113
+ append(character);
114
+ }
115
+ flush();
116
+ return parts;
117
+ }
118
+ function consumeEscaped(character, state, append) {
119
+ if (!state.escapeNext) {
120
+ return false;
121
+ }
122
+ append(character);
123
+ state.escapeNext = false;
124
+ return true;
125
+ }
126
+ function beginEscape(character, state, append) {
127
+ if (!state.inQuotes || character !== '\\') {
128
+ return false;
129
+ }
130
+ append(character);
131
+ state.escapeNext = true;
132
+ return true;
133
+ }
134
+ function toggleQuote(character, state, append) {
135
+ if (character !== '"' || state.angleDepth !== 0) {
136
+ return false;
137
+ }
138
+ append(character);
139
+ state.inQuotes = !state.inQuotes;
140
+ return true;
141
+ }
142
+ function adjustAngleDepth(character, state, append) {
143
+ if (state.inQuotes) {
144
+ return false;
145
+ }
146
+ if (character === '<') {
147
+ append(character);
148
+ state.angleDepth += 1;
149
+ return true;
150
+ }
151
+ if (character !== '>' || state.angleDepth === 0) {
152
+ return false;
153
+ }
154
+ append(character);
155
+ state.angleDepth -= 1;
156
+ return true;
157
+ }
158
+ function isAddressSeparator(character, state) {
159
+ return character === ',' && !state.inQuotes && state.angleDepth === 0;
160
+ }
161
+
162
+ /**
163
+ * Format a file size in bytes into a human readable string.
164
+ *
165
+ * Uses base 1024 units (binary prefixes without the "i" designation)
166
+ * and applies adaptive precision: one decimal for values < 10 of the
167
+ * chosen unit, otherwise no decimals.
168
+ *
169
+ * Examples:
170
+ * - 0 => "0 B"
171
+ * - 512 => "512 B"
172
+ * - 1536 => "1.5 KB"
173
+ * - 1048576 => "1 MB"
174
+ * - 5368709120 => "5 GB"
175
+ * - formatBytes(5347737600, 2) => "4.98 GB" (value < 10 so two decimals)
176
+ *
177
+ * @param bytes - the size in bytes
178
+ * @param decimals - max number of decimals for small unit values (default: 1)
179
+ * @returns formatted size string
180
+ */
181
+ function formatBytes(bytes, decimals = 1) {
182
+ if (bytes == null || Number.isNaN(bytes)) {
183
+ return '';
184
+ }
185
+ if (bytes < 0) {
186
+ return '';
187
+ }
188
+ if (bytes === 0) {
189
+ return '0 B';
190
+ }
191
+ const k = 1024;
192
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
193
+ const i = Math.max(0, Math.min(sizes.length - 1, Math.floor(Math.log(bytes) / Math.log(k))));
194
+ const value = bytes / Math.pow(k, i);
195
+ const safeDecimals = Number.isFinite(decimals) ? Math.trunc(decimals) : 0;
196
+ const precision = value < 10 ? Math.min(100, Math.max(0, safeDecimals)) : 0; // only keep decimals for small values
197
+ const rounded = Number.parseFloat(value.toFixed(precision));
198
+ return `${rounded} ${sizes[i]}`;
199
+ }
200
+
201
+ const emailViewerCss = () => `@charset "UTF-8";:host(limel-email-viewer){display:block;width:100%;height:100%;box-sizing:border-box}*,*::before,*::after{box-sizing:border-box;min-width:0;min-height:0}.email{display:flex;flex-direction:column;width:100%;height:100%;padding-bottom:0.5rem;box-shadow:var(--shadow-depth-8)}.email-headers{position:relative;flex-shrink:0;display:flex;flex-direction:column}.email-headers dl,.email-headers dt,.email-headers dd{margin:0}.email-headers dl{display:flex;flex-wrap:wrap;gap:0 0.5rem;padding:0.5rem 0.75rem;font-size:0.75rem}.email-headers dl:nth-child(even){background-color:rgb(var(--contrast-800), 0.1)}.email-headers dl dt{opacity:0.6;min-width:3rem}.email-headers dl dt::after{content:":"}.email-headers dl dd:not(:last-child)::after{content:",";opacity:0.6}.email-headers dl.subject dd{font-weight:bold}.email-headers dl.date{position:absolute;right:0.25rem;transform:translateY(-50%);font-size:0.625rem;border-radius:9rem;padding:0.25rem 0.5rem;background-color:rgb(var(--contrast-100), 0.3)}.email-headers dl.date dt{position:absolute;width:0;height:0;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0, 0, 0, 0);clip-path:inset(50%);white-space:nowrap}.attachments{flex-shrink:0;padding:0.5rem;border-bottom:1px dashed rgba(var(--contrast-700))}.attachments span{padding-left:0.25rem;font-size:0.75rem;opacity:0.6}.attachments span:first-child::after{content:":"}.attachments ul{all:unset;display:grid;grid-template-columns:repeat(auto-fill, minmax(8rem, 1fr));gap:0.5rem;padding:0.5rem 0}.attachments li{all:unset;position:relative;display:flex;flex-direction:column;gap:0.25rem;font-size:0.6875rem;line-height:normal;padding:0.5rem 0.5rem 1rem 0.5rem;border-radius:0.5rem;border:1px solid rgba(var(--contrast-600));background-color:rgba(var(--contrast-400))}.attachments .attachment-filename{font-weight:500}.attachments .attachment-mime-type{opacity:0.7}.attachments limel-badge{--badge-max-width:auto;--badge-background-color:rgb(var(--contrast-1000), 0.7);--badge-text-color:rgb(var(--color-white));position:absolute;bottom:0.125rem;right:0.125rem;box-shadow:var(--shadow-brighten-edges-outside)}section{flex-grow:1;display:flex;flex-direction:column;border-top:1px dashed rgba(var(--contrast-700));min-height:2rem;overflow-y:auto}limel-collapsible-section{--closed-header-background-color:var( --lime-elevated-surface-background-color );flex-grow:1;flex-shrink:0;margin:0.5rem;border-radius:0.75rem;box-shadow:var(--shadow-depth-8)}limel-collapsible-section button{all:unset;flex-shrink:0;border-radius:0.375rem;padding:0.25rem 0.5rem;font-size:var(--limel-theme-small-font-size);margin:0 0.5rem}limel-collapsible-section button.load-images{transition:color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);cursor:pointer;color:var(--lime-primary-color, var(--limel-theme-primary-color));background-color:var(--lime-elevated-surface-background-color);box-shadow:var(--button-shadow-normal)}limel-collapsible-section button.load-images:hover,limel-collapsible-section button.load-images:focus,limel-collapsible-section button.load-images:focus-visible{will-change:color, background-color, box-shadow, transform}limel-collapsible-section button.load-images:hover,limel-collapsible-section button.load-images:focus-visible{transform:translate3d(0, -0.04rem, 0);color:var(--limel-theme-on-surface-color);background-color:var(--lime-elevated-surface-background-color);box-shadow:var(--button-shadow-hovered)}limel-collapsible-section button.load-images:active{--limel-clickable-transform-timing-function:cubic-bezier( 0.83, -0.15, 0.49, 1.16 );transform:translate3d(0, 0.05rem, 0);box-shadow:var(--button-shadow-pressed)}limel-collapsible-section button.load-images:hover,limel-collapsible-section button.load-images:active{--limel-clickable-transition-speed:0.2s;--limel-clickable-transform-speed:0.16s}limel-collapsible-section limel-markdown{padding:0.5rem}.body{flex-grow:1;max-width:100%;padding:0.75rem}.body.plain-text{white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-family:inherit}.body img{max-width:100% !important}`;
202
+
203
+ const EmailViewer = class {
204
+ constructor(hostRef) {
205
+ registerInstance(this, hostRef);
206
+ this.allowRemoteImagesChange = createEvent(this, "allowRemoteImagesChange");
207
+ /**
208
+ * Defines the localization for translations.
209
+ */
210
+ this.language = 'en';
211
+ this.allowRemoteImagesState = false;
212
+ this.renderAttachment = (attachment, index) => {
213
+ var _a, _b;
214
+ const filename = ((_a = attachment.filename) === null || _a === void 0 ? void 0 : _a.trim()) ||
215
+ this.getTranslation('file-viewer.email.attachment.unnamed');
216
+ const mimeType = ((_b = attachment.mimeType) === null || _b === void 0 ? void 0 : _b.trim()) || '';
217
+ return (h("li", { key: `attachment-${index}` }, h("span", { class: "attachment-filename" }, filename), h("span", { class: "attachment-mime-type" }, " ", mimeType), this.renderSizeBadge(attachment.size)));
218
+ };
219
+ this.renderSizeBadge = (size) => {
220
+ if (typeof size !== 'number') {
221
+ return;
222
+ }
223
+ return (h("limel-badge", { class: "attachment-size", label: formatBytes(size) }));
224
+ };
225
+ this.onEnableRemoteImagesClick = (event) => {
226
+ var _a;
227
+ (_a = event === null || event === void 0 ? void 0 : event.stopPropagation) === null || _a === void 0 ? void 0 : _a.call(event);
228
+ this.enableRemoteImages();
229
+ };
230
+ this.enableRemoteImages = () => {
231
+ if (this.allowRemoteImages !== undefined) {
232
+ this.allowRemoteImagesChange.emit(true);
233
+ return;
234
+ }
235
+ this.allowRemoteImagesState = true;
236
+ };
237
+ }
238
+ resetAllowRemoteImages(newEmail, oldEmail) {
239
+ if (!newEmail) {
240
+ this.allowRemoteImagesState = false;
241
+ return;
242
+ }
243
+ if (newEmail.from !== (oldEmail === null || oldEmail === void 0 ? void 0 : oldEmail.from)) {
244
+ this.allowRemoteImagesState = false;
245
+ }
246
+ }
247
+ render() {
248
+ return (h(Host, { key: 'a004af12989a477f4a9404ee86e0429bc5c2d427' }, h("div", { key: 'fc3bdeb81d823ff1cd39b4f6d52b4a88d9326392', class: "email", part: "email" }, this.renderHeaders(), this.renderRemoteImageBanner(), h("section", { key: '6fdd1cfe50cc4b41f7e70413541dc5950d7c44fa' }, this.renderAttachments(), this.renderBody()))));
249
+ }
250
+ renderHeaders() {
251
+ const headerFields = [
252
+ 'subject',
253
+ 'from',
254
+ 'to',
255
+ 'cc',
256
+ 'date',
257
+ ];
258
+ return (h("div", { class: "email-headers", part: "email-headers" }, headerFields.map((type) => {
259
+ var _a;
260
+ return this.renderEmailHeader(type, this.getTranslation(`file-viewer.email.${type}`), (_a = this.email) === null || _a === void 0 ? void 0 : _a[type]);
261
+ })));
262
+ }
263
+ renderBody() {
264
+ return (this.renderBodyHtml() ||
265
+ this.renderBodyText() ||
266
+ this.renderFallbackUrl() || h("slot", { name: "fallback" }));
267
+ }
268
+ renderBodyHtml() {
269
+ var _a;
270
+ const bodyHtml = (_a = this.email) === null || _a === void 0 ? void 0 : _a.bodyHtml;
271
+ if (!bodyHtml) {
272
+ return;
273
+ }
274
+ const innerHtml = applyRemoteImagesPolicy(bodyHtml, this.getAllowRemoteImages());
275
+ return h("div", { class: "body", innerHTML: innerHtml, part: "email-body" });
276
+ }
277
+ renderBodyText() {
278
+ var _a;
279
+ const bodyText = (_a = this.email) === null || _a === void 0 ? void 0 : _a.bodyText;
280
+ if (!bodyText) {
281
+ return;
282
+ }
283
+ return (h("pre", { class: "body plain-text", part: "email-body" }, bodyText));
284
+ }
285
+ renderFallbackUrl() {
286
+ if (!this.fallbackUrl) {
287
+ return;
288
+ }
289
+ return (h("object", { data: this.fallbackUrl, type: "text/plain" }, h("slot", { name: "fallback" })));
290
+ }
291
+ renderEmailHeader(type, label, value) {
292
+ if (!value) {
293
+ return;
294
+ }
295
+ const values = this.getHeaderValues(type, value);
296
+ return (h("dl", { class: `headers ${type}` }, h("dt", null, label), values.map((headerValue, index) => (h("dd", { key: `${type}-${index}` }, headerValue)))));
297
+ }
298
+ getHeaderValues(type, value) {
299
+ if (type === 'to' || type === 'cc') {
300
+ return splitEmailAddressList(value);
301
+ }
302
+ return [value];
303
+ }
304
+ renderAttachments() {
305
+ var _a;
306
+ const attachments = (_a = this.email) === null || _a === void 0 ? void 0 : _a.attachments;
307
+ if (!(attachments === null || attachments === void 0 ? void 0 : attachments.length)) {
308
+ return;
309
+ }
310
+ const label = this.getTranslation('file-viewer.email.attachments');
311
+ return (h("div", { class: "attachments" }, h("span", null, label), h("ul", null, attachments.map((attachment, index) => this.renderAttachment(attachment, index)))));
312
+ }
313
+ getTranslation(key) {
314
+ return translate.get(key, this.language);
315
+ }
316
+ shouldShowRemoteImagesBanner() {
317
+ var _a;
318
+ const bodyHtml = (_a = this.email) === null || _a === void 0 ? void 0 : _a.bodyHtml;
319
+ if (!bodyHtml || this.getAllowRemoteImages()) {
320
+ return false;
321
+ }
322
+ return containsRemoteImages(bodyHtml);
323
+ }
324
+ renderRemoteImageBanner() {
325
+ if (!this.shouldShowRemoteImagesBanner()) {
326
+ return;
327
+ }
328
+ const icon = {
329
+ name: 'warning_shield',
330
+ color: 'rgb(var(--color-orange-default))',
331
+ };
332
+ const heading = this.getTranslation('file-viewer.email.remote-images.warning');
333
+ const description = this.getTranslation('file-viewer.email.remote-images.warning.description');
334
+ const buttonLabel = this.getTranslation('file-viewer.email.remote-images.load');
335
+ return (h("limel-collapsible-section", { header: heading, icon: icon, language: this.language }, h("button", { type: "button", class: "load-images", slot: "header", onClick: this.onEnableRemoteImagesClick }, buttonLabel), h("limel-markdown", { value: description })));
336
+ }
337
+ getAllowRemoteImages() {
338
+ var _a;
339
+ return (_a = this.allowRemoteImages) !== null && _a !== void 0 ? _a : this.allowRemoteImagesState;
340
+ }
341
+ static get watchers() { return {
342
+ "email": [{
343
+ "resetAllowRemoteImages": 0
344
+ }]
345
+ }; }
346
+ };
347
+ EmailViewer.style = emailViewerCss();
348
+
349
+ export { EmailViewer as limel_email_viewer };
@@ -1,12 +1,12 @@
1
1
  import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-xvTBZcD2.js';
2
- import { c as createFileInfo, i as isTypeAccepted } from './files-CkgibGPZ.js';
2
+ import { c as createFileInfo, i as isTypeAccepted } from './files-P324wLau.js';
3
3
  import { b as baseForOwn } from './_baseForOwn-ByPjzJ4R.js';
4
4
  import { b as isArrayLike } from './isArrayLike-bWHU4ebg.js';
5
5
  import { b as baseIteratee } from './_baseIteratee-1mEitKxK.js';
6
6
  import { i as isArray } from './isArray-B8VKuhvH.js';
7
7
  import { c as createRandomString } from './random-string-JbKhhoXs.js';
8
- import './file-metadata-D5joHaqk.js';
9
- import './get-icon-props-COzG_Mhw.js';
8
+ import './file-metadata-BwF9vTXN.js';
9
+ import './get-icon-props-CgNJbSP4.js';
10
10
  import './_baseIsEqual-DEKrwcEh.js';
11
11
  import './eq-D7VMHFyO.js';
12
12
  import './isObject-BJQylLSL.js';
@@ -227,7 +227,7 @@ const FileDropzone = class {
227
227
  };
228
228
  }
229
229
  render() {
230
- return (h(Host, { key: 'e9f7393f8a211bf3c9bacee06fb76fcfdb206c9b', onDrop: this.handleDrop, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave }, h("slot", { key: '204a271ef2db4b53f9b2292688d7c9449f0fd6b1' }), this.renderOnDragLayout()));
230
+ return (h(Host, { key: '4a002d8108fcb9d87b3f063171e0a531de31c1b1', onDrop: this.handleDrop, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave }, h("slot", { key: 'ed0aa907729aab6bee39bad7c6f9f74fc718e286' }), this.renderOnDragLayout()));
231
231
  }
232
232
  };
233
233
  FileDropzone.style = fileDropzoneCss();
@@ -287,7 +287,7 @@ const FileInput = class {
287
287
  this.fileInput = this.element.shadowRoot.getElementById(this.fileInputId);
288
288
  }
289
289
  render() {
290
- return (h(Host, { key: '96dadd0f667baa8f7d0a043e453a86318843c872', onClick: this.handleClick, onKeyUp: this.handleKeyUp, onKeyDown: this.handleKeyDown }, h("input", { key: 'a79da5cfe7a9594eeb76310a42c8c5043b9fe990', hidden: true, id: this.fileInputId, onChange: this.handleFileChange, type: "file", accept: this.accept, disabled: this.disabled, multiple: this.multiple }), h("slot", { key: '8d3e40d93bb3787d190bde77d7037c7cee965b5f' })));
290
+ return (h(Host, { key: '64b0de513357ed03fa7ae508ec6382acd600f392', onClick: this.handleClick, onKeyUp: this.handleKeyUp, onKeyDown: this.handleKeyDown }, h("input", { key: '0685cf5051c06e7e246631a38b349c2492dbb5b8', hidden: true, id: this.fileInputId, onChange: this.handleFileChange, type: "file", accept: this.accept, disabled: this.disabled, multiple: this.multiple }), h("slot", { key: 'da931d302eef5ed81663cce0b2d191166539a51d' })));
291
291
  }
292
292
  handleKeyDown(event) {
293
293
  if (event.code === 'Tab' ||