@opentiny/fluent-editor 4.0.0-alpha.10 → 4.0.0-alpha.11

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 (259) hide show
  1. package/es/config/editor.utils.es.js.map +1 -1
  2. package/es/config/i18n/en-us.es.js +2 -0
  3. package/es/config/i18n/en-us.es.js.map +1 -1
  4. package/es/config/i18n/zh-cn.es.js +2 -0
  5. package/es/config/i18n/zh-cn.es.js.map +1 -1
  6. package/es/config/index.es.js.map +1 -1
  7. package/es/core/fluent-editor.es.js.map +1 -1
  8. package/es/fluent-editor.es.js +17 -13
  9. package/es/fluent-editor.es.js.map +1 -1
  10. package/es/formats/soft-break.es.js.map +1 -1
  11. package/es/formats/video.es.js.map +1 -1
  12. package/es/index.es.js +4 -0
  13. package/es/index.es.js.map +1 -1
  14. package/es/modules/ai/constants.es.js.map +1 -1
  15. package/es/modules/ai/index.es.js +1 -1
  16. package/es/modules/ai/index.es.js.map +1 -1
  17. package/es/modules/collaborative-editing/awareness/awareness.es.js.map +1 -1
  18. package/es/modules/collaborative-editing/awareness/y-indexeddb.es.js.map +1 -1
  19. package/es/modules/collaborative-editing/collaborative-editing.es.js.map +1 -1
  20. package/es/modules/collaborative-editing/module.es.js.map +1 -1
  21. package/es/modules/collaborative-editing/provider/providerRegistry.es.js.map +1 -1
  22. package/es/modules/collaborative-editing/provider/webrtc.es.js.map +1 -1
  23. package/es/modules/collaborative-editing/provider/websocket.es.js.map +1 -1
  24. package/es/modules/counter.es.js.map +1 -1
  25. package/es/modules/custom-clipboard.es.js.map +1 -1
  26. package/es/modules/custom-image/actions/action.es.js.map +1 -1
  27. package/es/modules/custom-image/actions/custom-resize-action.es.js.map +1 -1
  28. package/es/modules/custom-image/actions/delete-action.es.js.map +1 -1
  29. package/es/modules/custom-image/actions/image-toolbar-buttons.es.js +1 -1
  30. package/es/modules/custom-image/actions/image-toolbar-buttons.es.js.map +1 -1
  31. package/es/modules/custom-image/actions/toolbar-action.es.js.map +1 -1
  32. package/es/modules/custom-image/actions/toolbar.es.js.map +1 -1
  33. package/es/modules/custom-image/blot-formatter.es.js.map +1 -1
  34. package/es/modules/custom-image/image.es.js.map +1 -1
  35. package/es/modules/custom-image/options.es.js.map +1 -1
  36. package/es/modules/custom-image/specs/blot-spec.es.js.map +1 -1
  37. package/es/modules/custom-image/specs/custom-image-spec.es.js.map +1 -1
  38. package/es/modules/custom-image/specs/image-spec.es.js.map +1 -1
  39. package/es/modules/custom-uploader.es.js.map +1 -1
  40. package/es/modules/divider.es.js.map +1 -1
  41. package/es/modules/emoji.es.js.map +1 -1
  42. package/es/modules/file/formats/file.es.js.map +1 -1
  43. package/es/modules/file/modules/file-bar.es.js.map +1 -1
  44. package/es/modules/file/modules/file-module.es.js.map +1 -1
  45. package/es/modules/flow-chart/config-utils.es.js +102 -0
  46. package/es/modules/flow-chart/config-utils.es.js.map +1 -0
  47. package/es/modules/flow-chart/formats/flow-chart-blot.es.js +369 -0
  48. package/es/modules/flow-chart/formats/flow-chart-blot.es.js.map +1 -0
  49. package/es/modules/flow-chart/i18n/en-us.es.js +30 -0
  50. package/es/modules/flow-chart/i18n/en-us.es.js.map +1 -0
  51. package/es/modules/flow-chart/i18n/index.es.js +12 -0
  52. package/es/modules/flow-chart/i18n/index.es.js.map +1 -0
  53. package/es/modules/flow-chart/i18n/zh-cn.es.js +30 -0
  54. package/es/modules/flow-chart/i18n/zh-cn.es.js.map +1 -0
  55. package/es/modules/flow-chart/icons.es.js +27 -0
  56. package/es/modules/flow-chart/icons.es.js.map +1 -0
  57. package/es/modules/flow-chart/index.es.js +45 -0
  58. package/es/modules/flow-chart/index.es.js.map +1 -0
  59. package/es/modules/flow-chart/modules/context-menu.es.js +184 -0
  60. package/es/modules/flow-chart/modules/context-menu.es.js.map +1 -0
  61. package/es/modules/flow-chart/modules/control-panel.es.js +286 -0
  62. package/es/modules/flow-chart/modules/control-panel.es.js.map +1 -0
  63. package/es/modules/flow-chart/modules/custom-resize-action.es.js +150 -0
  64. package/es/modules/flow-chart/modules/custom-resize-action.es.js.map +1 -0
  65. package/es/modules/flow-chart/style/flow-chart.css +185 -0
  66. package/es/modules/i18n.es.js.map +1 -1
  67. package/es/modules/index.es.js +4 -0
  68. package/es/modules/index.es.js.map +1 -1
  69. package/es/modules/link/formats/link.es.js.map +1 -1
  70. package/es/modules/link/modules/tooltip.es.js.map +1 -1
  71. package/es/modules/mathlive/formats.es.js.map +1 -1
  72. package/es/modules/mathlive/module.es.js.map +1 -1
  73. package/es/modules/mathlive/tooltip.es.js.map +1 -1
  74. package/es/modules/mention/mention-link.es.js.map +1 -1
  75. package/es/modules/mention/mention.es.js.map +1 -1
  76. package/es/modules/mind-map/config-utils.es.js +108 -0
  77. package/es/modules/mind-map/config-utils.es.js.map +1 -0
  78. package/es/modules/mind-map/formats/mind-map-blot.es.js +356 -0
  79. package/es/modules/mind-map/formats/mind-map-blot.es.js.map +1 -0
  80. package/es/modules/mind-map/i18n/en-us.es.js +29 -0
  81. package/es/modules/mind-map/i18n/en-us.es.js.map +1 -0
  82. package/es/modules/mind-map/i18n/index.es.js +12 -0
  83. package/es/modules/mind-map/i18n/index.es.js.map +1 -0
  84. package/es/modules/mind-map/i18n/zh-cn.es.js +29 -0
  85. package/es/modules/mind-map/i18n/zh-cn.es.js.map +1 -0
  86. package/es/modules/mind-map/icons.es.js +45 -0
  87. package/es/modules/mind-map/icons.es.js.map +1 -0
  88. package/es/modules/mind-map/index.es.js +56 -0
  89. package/es/modules/mind-map/index.es.js.map +1 -0
  90. package/es/modules/mind-map/modules/context-menu.es.js +128 -0
  91. package/es/modules/mind-map/modules/context-menu.es.js.map +1 -0
  92. package/es/modules/mind-map/modules/control-panel.es.js +424 -0
  93. package/es/modules/mind-map/modules/control-panel.es.js.map +1 -0
  94. package/es/modules/mind-map/modules/custom-resize-action.es.js +161 -0
  95. package/es/modules/mind-map/modules/custom-resize-action.es.js.map +1 -0
  96. package/es/modules/mind-map/style/mind-map.css +224 -0
  97. package/es/modules/shortcut-key/index.es.js +16 -0
  98. package/es/modules/shortcut-key/index.es.js.map +1 -1
  99. package/es/modules/syntax.es.js.map +1 -1
  100. package/es/modules/table-up/index.es.js.map +1 -1
  101. package/es/modules/toolbar/better-picker.es.js.map +1 -1
  102. package/es/modules/toolbar/better-toolbar.es.js.map +1 -1
  103. package/es/modules/toolbar/toolbar-tip.es.js.map +1 -1
  104. package/es/themes/snow.es.js.map +1 -1
  105. package/es/tools/format-painter.es.js.map +1 -1
  106. package/es/tools/fullscreen.es.js.map +1 -1
  107. package/es/tools/screenshot.es.js.map +1 -1
  108. package/es/ui/icons.config.es.js +4 -0
  109. package/es/ui/icons.config.es.js.map +1 -1
  110. package/es/ui/icons.es.js +4 -2
  111. package/es/ui/icons.es.js.map +1 -1
  112. package/es/utils/debounce.es.js.map +1 -1
  113. package/es/utils/image.es.js.map +1 -1
  114. package/es/utils/is.es.js.map +1 -1
  115. package/es/utils/method.es.js.map +1 -1
  116. package/es/utils/scroll-lock.es.js.map +1 -1
  117. package/lib/config/editor.utils.cjs.js.map +1 -1
  118. package/lib/config/i18n/en-us.cjs.js +2 -0
  119. package/lib/config/i18n/en-us.cjs.js.map +1 -1
  120. package/lib/config/i18n/zh-cn.cjs.js +2 -0
  121. package/lib/config/i18n/zh-cn.cjs.js.map +1 -1
  122. package/lib/config/index.cjs.js.map +1 -1
  123. package/lib/core/fluent-editor.cjs.js.map +1 -1
  124. package/lib/fluent-editor.cjs.js +23 -19
  125. package/lib/fluent-editor.cjs.js.map +1 -1
  126. package/lib/formats/soft-break.cjs.js.map +1 -1
  127. package/lib/formats/video.cjs.js.map +1 -1
  128. package/lib/index.cjs.js +9 -5
  129. package/lib/index.cjs.js.map +1 -1
  130. package/lib/modules/ai/constants.cjs.js.map +1 -1
  131. package/lib/modules/ai/index.cjs.js.map +1 -1
  132. package/lib/modules/collaborative-editing/awareness/awareness.cjs.js.map +1 -1
  133. package/lib/modules/collaborative-editing/awareness/y-indexeddb.cjs.js.map +1 -1
  134. package/lib/modules/collaborative-editing/collaborative-editing.cjs.js.map +1 -1
  135. package/lib/modules/collaborative-editing/module.cjs.js.map +1 -1
  136. package/lib/modules/collaborative-editing/provider/providerRegistry.cjs.js.map +1 -1
  137. package/lib/modules/collaborative-editing/provider/webrtc.cjs.js.map +1 -1
  138. package/lib/modules/collaborative-editing/provider/websocket.cjs.js.map +1 -1
  139. package/lib/modules/counter.cjs.js.map +1 -1
  140. package/lib/modules/custom-clipboard.cjs.js.map +1 -1
  141. package/lib/modules/custom-image/actions/action.cjs.js.map +1 -1
  142. package/lib/modules/custom-image/actions/custom-resize-action.cjs.js.map +1 -1
  143. package/lib/modules/custom-image/actions/delete-action.cjs.js.map +1 -1
  144. package/lib/modules/custom-image/actions/image-toolbar-buttons.cjs.js.map +1 -1
  145. package/lib/modules/custom-image/actions/toolbar-action.cjs.js.map +1 -1
  146. package/lib/modules/custom-image/actions/toolbar.cjs.js.map +1 -1
  147. package/lib/modules/custom-image/blot-formatter.cjs.js.map +1 -1
  148. package/lib/modules/custom-image/image.cjs.js.map +1 -1
  149. package/lib/modules/custom-image/options.cjs.js.map +1 -1
  150. package/lib/modules/custom-image/specs/blot-spec.cjs.js.map +1 -1
  151. package/lib/modules/custom-image/specs/custom-image-spec.cjs.js.map +1 -1
  152. package/lib/modules/custom-image/specs/image-spec.cjs.js.map +1 -1
  153. package/lib/modules/custom-uploader.cjs.js.map +1 -1
  154. package/lib/modules/divider.cjs.js.map +1 -1
  155. package/lib/modules/emoji.cjs.js.map +1 -1
  156. package/lib/modules/file/formats/file.cjs.js.map +1 -1
  157. package/lib/modules/file/modules/file-bar.cjs.js.map +1 -1
  158. package/lib/modules/file/modules/file-module.cjs.js.map +1 -1
  159. package/lib/modules/flow-chart/config-utils.cjs.js +102 -0
  160. package/lib/modules/flow-chart/config-utils.cjs.js.map +1 -0
  161. package/lib/modules/flow-chart/formats/flow-chart-blot.cjs.js +369 -0
  162. package/lib/modules/flow-chart/formats/flow-chart-blot.cjs.js.map +1 -0
  163. package/lib/modules/flow-chart/i18n/en-us.cjs.js +30 -0
  164. package/lib/modules/flow-chart/i18n/en-us.cjs.js.map +1 -0
  165. package/lib/modules/flow-chart/i18n/index.cjs.js +12 -0
  166. package/lib/modules/flow-chart/i18n/index.cjs.js.map +1 -0
  167. package/lib/modules/flow-chart/i18n/zh-cn.cjs.js +30 -0
  168. package/lib/modules/flow-chart/i18n/zh-cn.cjs.js.map +1 -0
  169. package/lib/modules/flow-chart/icons.cjs.js +27 -0
  170. package/lib/modules/flow-chart/icons.cjs.js.map +1 -0
  171. package/lib/modules/flow-chart/index.cjs.js +45 -0
  172. package/lib/modules/flow-chart/index.cjs.js.map +1 -0
  173. package/lib/modules/flow-chart/modules/context-menu.cjs.js +184 -0
  174. package/lib/modules/flow-chart/modules/context-menu.cjs.js.map +1 -0
  175. package/lib/modules/flow-chart/modules/control-panel.cjs.js +286 -0
  176. package/lib/modules/flow-chart/modules/control-panel.cjs.js.map +1 -0
  177. package/lib/modules/flow-chart/modules/custom-resize-action.cjs.js +150 -0
  178. package/lib/modules/flow-chart/modules/custom-resize-action.cjs.js.map +1 -0
  179. package/lib/modules/flow-chart/style/flow-chart.css +185 -0
  180. package/lib/modules/i18n.cjs.js.map +1 -1
  181. package/lib/modules/index.cjs.js +9 -5
  182. package/lib/modules/index.cjs.js.map +1 -1
  183. package/lib/modules/link/formats/link.cjs.js.map +1 -1
  184. package/lib/modules/link/modules/tooltip.cjs.js.map +1 -1
  185. package/lib/modules/mathlive/formats.cjs.js.map +1 -1
  186. package/lib/modules/mathlive/module.cjs.js.map +1 -1
  187. package/lib/modules/mathlive/tooltip.cjs.js.map +1 -1
  188. package/lib/modules/mention/mention-link.cjs.js.map +1 -1
  189. package/lib/modules/mention/mention.cjs.js.map +1 -1
  190. package/lib/modules/mind-map/config-utils.cjs.js +108 -0
  191. package/lib/modules/mind-map/config-utils.cjs.js.map +1 -0
  192. package/lib/modules/mind-map/formats/mind-map-blot.cjs.js +356 -0
  193. package/lib/modules/mind-map/formats/mind-map-blot.cjs.js.map +1 -0
  194. package/lib/modules/mind-map/i18n/en-us.cjs.js +29 -0
  195. package/lib/modules/mind-map/i18n/en-us.cjs.js.map +1 -0
  196. package/lib/modules/mind-map/i18n/index.cjs.js +12 -0
  197. package/lib/modules/mind-map/i18n/index.cjs.js.map +1 -0
  198. package/lib/modules/mind-map/i18n/zh-cn.cjs.js +29 -0
  199. package/lib/modules/mind-map/i18n/zh-cn.cjs.js.map +1 -0
  200. package/lib/modules/mind-map/icons.cjs.js +45 -0
  201. package/lib/modules/mind-map/icons.cjs.js.map +1 -0
  202. package/lib/modules/mind-map/index.cjs.js +56 -0
  203. package/lib/modules/mind-map/index.cjs.js.map +1 -0
  204. package/lib/modules/mind-map/modules/context-menu.cjs.js +128 -0
  205. package/lib/modules/mind-map/modules/context-menu.cjs.js.map +1 -0
  206. package/lib/modules/mind-map/modules/control-panel.cjs.js +424 -0
  207. package/lib/modules/mind-map/modules/control-panel.cjs.js.map +1 -0
  208. package/lib/modules/mind-map/modules/custom-resize-action.cjs.js +161 -0
  209. package/lib/modules/mind-map/modules/custom-resize-action.cjs.js.map +1 -0
  210. package/lib/modules/mind-map/style/mind-map.css +224 -0
  211. package/lib/modules/shortcut-key/index.cjs.js +16 -0
  212. package/lib/modules/shortcut-key/index.cjs.js.map +1 -1
  213. package/lib/modules/syntax.cjs.js.map +1 -1
  214. package/lib/modules/table-up/index.cjs.js.map +1 -1
  215. package/lib/modules/toolbar/better-picker.cjs.js.map +1 -1
  216. package/lib/modules/toolbar/better-toolbar.cjs.js.map +1 -1
  217. package/lib/modules/toolbar/toolbar-tip.cjs.js.map +1 -1
  218. package/lib/themes/snow.cjs.js.map +1 -1
  219. package/lib/tools/format-painter.cjs.js.map +1 -1
  220. package/lib/tools/fullscreen.cjs.js.map +1 -1
  221. package/lib/tools/screenshot.cjs.js.map +1 -1
  222. package/lib/ui/icons.cjs.js +3 -1
  223. package/lib/ui/icons.cjs.js.map +1 -1
  224. package/lib/ui/icons.config.cjs.js +4 -0
  225. package/lib/ui/icons.config.cjs.js.map +1 -1
  226. package/lib/utils/debounce.cjs.js.map +1 -1
  227. package/lib/utils/image.cjs.js.map +1 -1
  228. package/lib/utils/is.cjs.js.map +1 -1
  229. package/lib/utils/method.cjs.js.map +1 -1
  230. package/lib/utils/scroll-lock.cjs.js.map +1 -1
  231. package/package.json +5 -1
  232. package/style.css +3 -1
  233. package/types/config/i18n/en-us.d.ts +2 -0
  234. package/types/config/i18n/zh-cn.d.ts +2 -0
  235. package/types/config/types/editor-modules.interface.d.ts +4 -0
  236. package/types/modules/flow-chart/config-utils.d.ts +10 -0
  237. package/types/modules/flow-chart/formats/flow-chart-blot.d.ts +43 -0
  238. package/types/modules/flow-chart/i18n/en-us.d.ts +26 -0
  239. package/types/modules/flow-chart/i18n/index.d.ts +1 -0
  240. package/types/modules/flow-chart/i18n/zh-cn.d.ts +26 -0
  241. package/types/modules/flow-chart/icons.d.ts +12 -0
  242. package/types/modules/flow-chart/index.d.ts +10 -0
  243. package/types/modules/flow-chart/modules/context-menu.d.ts +3 -0
  244. package/types/modules/flow-chart/modules/control-panel.d.ts +3 -0
  245. package/types/modules/flow-chart/modules/custom-resize-action.d.ts +22 -0
  246. package/types/modules/flow-chart/options.d.ts +29 -0
  247. package/types/modules/index.d.ts +2 -0
  248. package/types/modules/mind-map/config-utils.d.ts +12 -0
  249. package/types/modules/mind-map/formats/mind-map-blot.d.ts +44 -0
  250. package/types/modules/mind-map/i18n/en-us.d.ts +25 -0
  251. package/types/modules/mind-map/i18n/index.d.ts +1 -0
  252. package/types/modules/mind-map/i18n/zh-cn.d.ts +25 -0
  253. package/types/modules/mind-map/icons.d.ts +21 -0
  254. package/types/modules/mind-map/index.d.ts +10 -0
  255. package/types/modules/mind-map/modules/context-menu.d.ts +3 -0
  256. package/types/modules/mind-map/modules/control-panel.d.ts +3 -0
  257. package/types/modules/mind-map/modules/custom-resize-action.d.ts +23 -0
  258. package/types/modules/mind-map/options.d.ts +26 -0
  259. package/types/ui/icons.config.d.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"image.es.js","sources":["../../../../src/modules/custom-image/image.ts"],"sourcesContent":["import type { Parchment as TypeParchment } from 'quill'\nimport type TypeEmbed from 'quill/blots/embed'\nimport Quill from 'quill'\nimport { isNullOrUndefined, sanitize } from '../../config/editor.utils'\nimport { isObject } from '../../utils/is'\nimport { ALIGN_ATTR, alignmentHandler } from './actions'\n\nconst Embed = Quill.import('blots/embed') as typeof TypeEmbed\nconst ATTRIBUTES = ['alt', 'height', 'width', 'image-id']\n\nexport type ImageValue = string | {\n src: string\n align?: string\n height?: number\n width?: number\n}\nexport class CustomImage extends Embed {\n static blotName = 'image'\n static tagName = 'IMG'\n static ID_SEED = 0\n static allowInvalidUrl: boolean = false\n declare domNode: HTMLElement\n\n static setOptions(allowInvalidUrl: boolean) {\n this.allowInvalidUrl = allowInvalidUrl\n }\n\n static create(value: ImageValue) {\n const node = super.create(value) as HTMLElement\n const url = typeof value === 'string' ? value : value.src\n if (url) {\n const imgURL = this.sanitize(url)\n if (!imgURL?.startsWith('data:image')) {\n node.dataset.src = imgURL\n }\n node.setAttribute('src', imgURL)\n }\n node.setAttribute('data-image-id', `img${CustomImage.ID_SEED++}`)\n node.style.verticalAlign = 'baseline'\n if (isObject(value)) {\n if (value.align && alignmentHandler[value.align]) {\n node.setAttribute(ALIGN_ATTR, value.align)\n alignmentHandler[value.align](node)\n }\n if (value.width) {\n node.setAttribute('width', String(value.width))\n }\n if (value.height) {\n node.setAttribute('height', String(value.height))\n }\n }\n return node\n }\n\n static formats(domNode: HTMLElement) {\n return ATTRIBUTES.reduce((formats, attribute) => {\n if (domNode.hasAttribute(attribute)) {\n formats[attribute] = domNode.getAttribute(attribute)\n }\n return formats\n }, {})\n }\n\n static match(url: string) {\n return /\\.(jpe?g|gif|png)$/.test(url) || /^data:image\\/.+;base64/.test(url)\n }\n\n static register() {\n if (/Firefox/i.test(navigator.userAgent)) {\n setTimeout(() => {\n // Disable image resizing in Firefox\n document.execCommand('enableObjectResizing', false, 'false')\n }, 1)\n }\n }\n\n static sanitize(url: string) {\n if (sanitize(url, ['http', 'https', 'blob', 'data']) || this.allowInvalidUrl) {\n return url\n }\n return '//:0'\n }\n\n static value(domNode: HTMLElement) {\n const formats: any = {}\n const imageSrc = domNode.getAttribute('src')\n formats.src = this.sanitize(imageSrc)\n formats.imageId = domNode.dataset.imageId\n if (domNode.dataset.align) {\n formats.align = domNode.dataset.align\n }\n if (domNode.hasAttribute('width')) {\n formats.width = domNode.getAttribute('width')\n }\n if (domNode.hasAttribute('height')) {\n formats.height = domNode.getAttribute('height')\n }\n return formats\n }\n\n format(name: string, value: any) {\n if (ATTRIBUTES.includes(name)) {\n if (value) {\n this.domNode.setAttribute(name, value)\n }\n else {\n this.domNode.removeAttribute(name)\n }\n }\n else {\n super.format(name, value)\n }\n }\n\n unWrap() {\n this.parent.replaceWith(this as TypeEmbed)\n }\n\n wrap(name: string, value?: any): TypeParchment.Parent\n wrap(wrapper: TypeParchment.Parent): TypeParchment.Parent\n wrap(name: string | TypeParchment.Parent, value?: any) {\n const wrapper = (typeof name === 'string' ? this.scroll.create(name, value) : name) as TypeParchment.Parent\n if (!isNullOrUndefined(this.parent)) {\n this.parent.insertBefore(wrapper, this.next || undefined)\n }\n if (typeof wrapper.appendChild !== 'function') {\n throw new TypeError(`Cannot wrap ${name}`)\n }\n wrapper.appendChild(this)\n return wrapper\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image.es.js","sources":["../../../../src/modules/custom-image/image.ts"],"sourcesContent":["import type { Parchment as TypeParchment } from 'quill'\nimport type TypeEmbed from 'quill/blots/embed'\nimport Quill from 'quill'\nimport { isNullOrUndefined, sanitize } from '../../config/editor.utils'\nimport { isObject } from '../../utils/is'\nimport { ALIGN_ATTR, alignmentHandler } from './actions'\n\nconst Embed = Quill.import('blots/embed') as typeof TypeEmbed\nconst ATTRIBUTES = ['alt', 'height', 'width', 'image-id']\n\nexport type ImageValue = string | {\n src: string\n align?: string\n height?: number\n width?: number\n}\nexport class CustomImage extends Embed {\n static blotName = 'image'\n static tagName = 'IMG'\n static ID_SEED = 0\n static allowInvalidUrl: boolean = false\n declare domNode: HTMLElement\n\n static setOptions(allowInvalidUrl: boolean) {\n this.allowInvalidUrl = allowInvalidUrl\n }\n\n static create(value: ImageValue) {\n const node = super.create(value) as HTMLElement\n const url = typeof value === 'string' ? value : value.src\n if (url) {\n const imgURL = this.sanitize(url)\n if (!imgURL?.startsWith('data:image')) {\n node.dataset.src = imgURL\n }\n node.setAttribute('src', imgURL)\n }\n node.setAttribute('data-image-id', `img${CustomImage.ID_SEED++}`)\n node.style.verticalAlign = 'baseline'\n if (isObject(value)) {\n if (value.align && alignmentHandler[value.align]) {\n node.setAttribute(ALIGN_ATTR, value.align)\n alignmentHandler[value.align](node)\n }\n if (value.width) {\n node.setAttribute('width', String(value.width))\n }\n if (value.height) {\n node.setAttribute('height', String(value.height))\n }\n }\n return node\n }\n\n static formats(domNode: HTMLElement) {\n return ATTRIBUTES.reduce((formats, attribute) => {\n if (domNode.hasAttribute(attribute)) {\n formats[attribute] = domNode.getAttribute(attribute)\n }\n return formats\n }, {})\n }\n\n static match(url: string) {\n return /\\.(jpe?g|gif|png)$/.test(url) || /^data:image\\/.+;base64/.test(url)\n }\n\n static register() {\n if (/Firefox/i.test(navigator.userAgent)) {\n setTimeout(() => {\n // Disable image resizing in Firefox\n document.execCommand('enableObjectResizing', false, 'false')\n }, 1)\n }\n }\n\n static sanitize(url: string) {\n if (sanitize(url, ['http', 'https', 'blob', 'data']) || this.allowInvalidUrl) {\n return url\n }\n return '//:0'\n }\n\n static value(domNode: HTMLElement) {\n const formats: any = {}\n const imageSrc = domNode.getAttribute('src')\n formats.src = this.sanitize(imageSrc)\n formats.imageId = domNode.dataset.imageId\n if (domNode.dataset.align) {\n formats.align = domNode.dataset.align\n }\n if (domNode.hasAttribute('width')) {\n formats.width = domNode.getAttribute('width')\n }\n if (domNode.hasAttribute('height')) {\n formats.height = domNode.getAttribute('height')\n }\n return formats\n }\n\n format(name: string, value: any) {\n if (ATTRIBUTES.includes(name)) {\n if (value) {\n this.domNode.setAttribute(name, value)\n }\n else {\n this.domNode.removeAttribute(name)\n }\n }\n else {\n super.format(name, value)\n }\n }\n\n unWrap() {\n this.parent.replaceWith(this as TypeEmbed)\n }\n\n wrap(name: string, value?: any): TypeParchment.Parent\n wrap(wrapper: TypeParchment.Parent): TypeParchment.Parent\n wrap(name: string | TypeParchment.Parent, value?: any) {\n const wrapper = (typeof name === 'string' ? this.scroll.create(name, value) : name) as TypeParchment.Parent\n if (!isNullOrUndefined(this.parent)) {\n this.parent.insertBefore(wrapper, this.next || undefined)\n }\n if (typeof wrapper.appendChild !== 'function') {\n throw new TypeError(`Cannot wrap ${name}`)\n }\n wrapper.appendChild(this)\n return wrapper\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"options.es.js","sources":["../../../../src/modules/custom-image/options.ts"],"sourcesContent":["import type { ImageToolbar, ImageToolbarButtons } from './actions'\nimport type { BlotSpec } from './specs'\nimport { ImageSpec } from './specs'\n\nexport interface OverlayOptions {\n // classname applied to the overlay element\n className: string\n // style applied to overlay element, or null to prevent styles\n style: Record<string, string>\n}\n\nexport interface ResizeOptions {\n // class name applied to the resize handles\n handleClassName: string\n // style applied to resize handles, or null to prevent styles\n handleStyle: Record<string, string>\n}\n\nexport interface ToolButtonOption {\n name: string\n icon: string\n isActive?: (el: HTMLElement) => boolean\n apply: (this: ImageToolbar, el: HTMLImageElement, toolbarButtons: ImageToolbarButtons) => void\n}\n\nexport interface ToolbarButtonOptions {\n buttons: Record<string, ToolButtonOption | boolean>\n}\n\nexport interface ToolbarOptions extends ToolbarButtonOptions {\n // class name applied to the root toolbar element\n mainClassName: string\n // style applied to root toolbar element, or null to prevent styles\n mainStyle: Record<string, unknown>\n // class name applied to each button in the toolbar\n buttonClassName: string\n /* whether or not to add the selected style to the buttons.\n they'll always get the is-selected class */\n addButtonSelectStyle: boolean\n // style applied to buttons, or null to prevent styles\n buttonStyle: Record<string, unknown>\n // style applied to the svgs in the buttons\n svgStyle: Record<string, unknown>\n}\n\nexport interface BlotFormatterOptionsInput {\n specs: typeof BlotSpec[]\n overlay: Partial<OverlayOptions>\n resize: Partial<ResizeOptions>\n toolbar: Partial<ToolbarOptions>\n}\nexport interface BlotFormatterOptions {\n specs: typeof BlotSpec[]\n overlay: OverlayOptions\n resize: ResizeOptions\n toolbar: ToolbarOptions\n allowInvalidUrl: boolean\n}\n\nexport const LEFT_ALIGN = 'align-left'\nexport const CENTER_ALIGN = 'align-center'\nexport const RIGHT_ALIGN = 'align-right'\nexport const COPY = 'copy'\nexport const DOWNLOAD = 'download'\nconst DefaultOptions: BlotFormatterOptions = {\n // 默认情况下,`file://` 格式的本地文件路径在浏览器环境无法读取,因此会被转换成 `//:0`,但是在一些特殊的场景下(比如:Electron),需要获取到图片的原始路径,进行后续的上传处理\n // 注意:该选项一旦设置为 true,本地磁盘路径会暴露出去,这可能会带来安全风险,请确保你了解相关的安全隐患\n allowInvalidUrl: false,\n\n specs: [\n ImageSpec,\n ],\n overlay: {\n className: 'blot-formatter__overlay',\n style: {\n position: 'absolute',\n boxSizing: 'border-box',\n border: '1px dashed #444',\n },\n },\n toolbar: {\n mainClassName: 'blot-formatter__toolbar',\n mainStyle: {\n position: 'absolute',\n top: '-12px',\n right: '0',\n left: '0',\n height: '0',\n minWidth: '120px',\n font: '12px/1.0 Arial, Helvetica, sans-serif',\n textAlign: 'center',\n color: '#333',\n boxSizing: 'border-box',\n cursor: 'default',\n zIndex: '1',\n },\n buttonClassName: 'blot-formatter__toolbar-button',\n addButtonSelectStyle: true,\n buttonStyle: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n background: 'white',\n border: '1px solid #999',\n verticalAlign: 'middle',\n cursor: 'pointer',\n },\n svgStyle: {\n display: 'inline-block',\n width: '16px',\n height: '16px',\n background: 'white',\n verticalAlign: 'middle',\n },\n buttons: {\n [LEFT_ALIGN]: true,\n [CENTER_ALIGN]: true,\n [RIGHT_ALIGN]: true,\n [COPY]: true,\n [DOWNLOAD]: true,\n },\n },\n resize: {\n handleClassName: 'blot-formatter__resize-handle',\n handleStyle: {\n position: 'absolute',\n height: '12px',\n width: '12px',\n backgroundColor: 'white',\n border: '1px solid #777',\n boxSizing: 'border-box',\n opacity: '0.80',\n },\n },\n}\n\nexport default DefaultOptions\n"],"names":[],"mappings":";;AA2DO,MAAM,aAAa;AACnB,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,OAAO;AACb,MAAM,WAAW;AACxB,MAAM,iBAAuC;AAAA;AAAA;AAAA,EAG3C,iBAAiB;AAAA,EAEjB,OAAO;AAAA,IACL;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,OAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA;AAAA,EAEZ;AAAA,EACA,SAAS;AAAA,IACP,eAAe;AAAA,IACf,WAAW;AAAA,MACT,UAAU;AAAA,MACV,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,IACA,iBAAiB;AAAA,IACjB,sBAAsB;AAAA,IACtB,aAAa;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,QAAQ;AAAA,IACV;AAAA,IACA,UAAU;AAAA,MACR,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,eAAe;AAAA,IACjB;AAAA,IACA,SAAS;AAAA,MACP,CAAC,UAAU,GAAG;AAAA,MACd,CAAC,YAAY,GAAG;AAAA,MAChB,CAAC,WAAW,GAAG;AAAA,MACf,CAAC,IAAI,GAAG;AAAA,MACR,CAAC,QAAQ,GAAG;AAAA,IAAA;AAAA,EAEhB;AAAA,EACA,QAAQ;AAAA,IACN,iBAAiB;AAAA,IACjB,aAAa;AAAA,MACX,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;"}
1
+ {"version":3,"file":"options.es.js","sources":["../../../../src/modules/custom-image/options.ts"],"sourcesContent":["import type { ImageToolbar, ImageToolbarButtons } from './actions'\nimport type { BlotSpec } from './specs'\nimport { ImageSpec } from './specs'\n\nexport interface OverlayOptions {\n // classname applied to the overlay element\n className: string\n // style applied to overlay element, or null to prevent styles\n style: Record<string, string>\n}\n\nexport interface ResizeOptions {\n // class name applied to the resize handles\n handleClassName: string\n // style applied to resize handles, or null to prevent styles\n handleStyle: Record<string, string>\n}\n\nexport interface ToolButtonOption {\n name: string\n icon: string\n isActive?: (el: HTMLElement) => boolean\n apply: (this: ImageToolbar, el: HTMLImageElement, toolbarButtons: ImageToolbarButtons) => void\n}\n\nexport interface ToolbarButtonOptions {\n buttons: Record<string, ToolButtonOption | boolean>\n}\n\nexport interface ToolbarOptions extends ToolbarButtonOptions {\n // class name applied to the root toolbar element\n mainClassName: string\n // style applied to root toolbar element, or null to prevent styles\n mainStyle: Record<string, unknown>\n // class name applied to each button in the toolbar\n buttonClassName: string\n /* whether or not to add the selected style to the buttons.\n they'll always get the is-selected class */\n addButtonSelectStyle: boolean\n // style applied to buttons, or null to prevent styles\n buttonStyle: Record<string, unknown>\n // style applied to the svgs in the buttons\n svgStyle: Record<string, unknown>\n}\n\nexport interface BlotFormatterOptionsInput {\n specs: typeof BlotSpec[]\n overlay: Partial<OverlayOptions>\n resize: Partial<ResizeOptions>\n toolbar: Partial<ToolbarOptions>\n}\nexport interface BlotFormatterOptions {\n specs: typeof BlotSpec[]\n overlay: OverlayOptions\n resize: ResizeOptions\n toolbar: ToolbarOptions\n allowInvalidUrl: boolean\n}\n\nexport const LEFT_ALIGN = 'align-left'\nexport const CENTER_ALIGN = 'align-center'\nexport const RIGHT_ALIGN = 'align-right'\nexport const COPY = 'copy'\nexport const DOWNLOAD = 'download'\nconst DefaultOptions: BlotFormatterOptions = {\n // 默认情况下,`file://` 格式的本地文件路径在浏览器环境无法读取,因此会被转换成 `//:0`,但是在一些特殊的场景下(比如:Electron),需要获取到图片的原始路径,进行后续的上传处理\n // 注意:该选项一旦设置为 true,本地磁盘路径会暴露出去,这可能会带来安全风险,请确保你了解相关的安全隐患\n allowInvalidUrl: false,\n\n specs: [\n ImageSpec,\n ],\n overlay: {\n className: 'blot-formatter__overlay',\n style: {\n position: 'absolute',\n boxSizing: 'border-box',\n border: '1px dashed #444',\n },\n },\n toolbar: {\n mainClassName: 'blot-formatter__toolbar',\n mainStyle: {\n position: 'absolute',\n top: '-12px',\n right: '0',\n left: '0',\n height: '0',\n minWidth: '120px',\n font: '12px/1.0 Arial, Helvetica, sans-serif',\n textAlign: 'center',\n color: '#333',\n boxSizing: 'border-box',\n cursor: 'default',\n zIndex: '1',\n },\n buttonClassName: 'blot-formatter__toolbar-button',\n addButtonSelectStyle: true,\n buttonStyle: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n background: 'white',\n border: '1px solid #999',\n verticalAlign: 'middle',\n cursor: 'pointer',\n },\n svgStyle: {\n display: 'inline-block',\n width: '16px',\n height: '16px',\n background: 'white',\n verticalAlign: 'middle',\n },\n buttons: {\n [LEFT_ALIGN]: true,\n [CENTER_ALIGN]: true,\n [RIGHT_ALIGN]: true,\n [COPY]: true,\n [DOWNLOAD]: true,\n },\n },\n resize: {\n handleClassName: 'blot-formatter__resize-handle',\n handleStyle: {\n position: 'absolute',\n height: '12px',\n width: '12px',\n backgroundColor: 'white',\n border: '1px solid #777',\n boxSizing: 'border-box',\n opacity: '0.80',\n },\n },\n}\n\nexport default DefaultOptions\n"],"names":[],"mappings":";;AA2DO,MAAM,aAAa;AACnB,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,OAAO;AACb,MAAM,WAAW;AACxB,MAAM,iBAAuC;AAAA;AAAA;AAAA,EAG3C,iBAAiB;AAAA,EAEjB,OAAO;AAAA,IACL;AAAA,EAAA;AAAA,EAEF,SAAS;AAAA,IACP,WAAW;AAAA,IACX,OAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA;AAAA,EACV;AAAA,EAEF,SAAS;AAAA,IACP,eAAe;AAAA,IACf,WAAW;AAAA,MACT,UAAU;AAAA,MACV,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA;AAAA,IAEV,iBAAiB;AAAA,IACjB,sBAAsB;AAAA,IACtB,aAAa;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,QAAQ;AAAA,IAAA;AAAA,IAEV,UAAU;AAAA,MACR,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,eAAe;AAAA,IAAA;AAAA,IAEjB,SAAS;AAAA,MACP,CAAC,UAAU,GAAG;AAAA,MACd,CAAC,YAAY,GAAG;AAAA,MAChB,CAAC,WAAW,GAAG;AAAA,MACf,CAAC,IAAI,GAAG;AAAA,MACR,CAAC,QAAQ,GAAG;AAAA,IAAA;AAAA,EACd;AAAA,EAEF,QAAQ;AAAA,IACN,iBAAiB;AAAA,IACjB,aAAa;AAAA,MACX,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"blot-spec.es.js","sources":["../../../../../src/modules/custom-image/specs/blot-spec.ts"],"sourcesContent":["import type { BlotFormatter } from '../blot-formatter'\nimport { CustomResizeAction, DeleteAction, ImageToolbarAction } from '../actions'\n\nexport class BlotSpec {\n formatter: BlotFormatter\n\n constructor(formatter: BlotFormatter) {\n this.formatter = formatter\n }\n\n init(): void {}\n\n getActions() {\n return [ImageToolbarAction, CustomResizeAction, DeleteAction]\n }\n\n getTargetElement(): HTMLElement | null {\n return null\n }\n\n getOverlayElement() {\n return this.getTargetElement()\n }\n\n setSelection(): void {\n this.formatter.quill.setSelection(null)\n }\n\n onHide() {}\n}\n"],"names":[],"mappings":";;;;;;;AAGO,MAAM,SAAS;AAAA,EAGpB,YAAY,WAA0B;AAFtC;AAGE,SAAK,YAAY;AAAA,EAAA;AAAA,EAGnB,OAAa;AAAA,EAAA;AAAA,EAEb,aAAa;AACJ,WAAA,CAAC,oBAAoB,oBAAoB,YAAY;AAAA,EAAA;AAAA,EAG9D,mBAAuC;AAC9B,WAAA;AAAA,EAAA;AAAA,EAGT,oBAAoB;AAClB,WAAO,KAAK,iBAAiB;AAAA,EAAA;AAAA,EAG/B,eAAqB;AACd,SAAA,UAAU,MAAM,aAAa,IAAI;AAAA,EAAA;AAAA,EAGxC,SAAS;AAAA,EAAA;AACX;"}
1
+ {"version":3,"file":"blot-spec.es.js","sources":["../../../../../src/modules/custom-image/specs/blot-spec.ts"],"sourcesContent":["import type { BlotFormatter } from '../blot-formatter'\nimport { CustomResizeAction, DeleteAction, ImageToolbarAction } from '../actions'\n\nexport class BlotSpec {\n formatter: BlotFormatter\n\n constructor(formatter: BlotFormatter) {\n this.formatter = formatter\n }\n\n init(): void {}\n\n getActions() {\n return [ImageToolbarAction, CustomResizeAction, DeleteAction]\n }\n\n getTargetElement(): HTMLElement | null {\n return null\n }\n\n getOverlayElement() {\n return this.getTargetElement()\n }\n\n setSelection(): void {\n this.formatter.quill.setSelection(null)\n }\n\n onHide() {}\n}\n"],"names":[],"mappings":";;;;;;;AAGO,MAAM,SAAS;AAAA,EAGpB,YAAY,WAA0B;AAFtC;AAGE,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,OAAa;AAAA,EAAC;AAAA,EAEd,aAAa;AACX,WAAO,CAAC,oBAAoB,oBAAoB,YAAY;AAAA,EAC9D;AAAA,EAEA,mBAAuC;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB;AAClB,WAAO,KAAK,iBAAA;AAAA,EACd;AAAA,EAEA,eAAqB;AACnB,SAAK,UAAU,MAAM,aAAa,IAAI;AAAA,EACxC;AAAA,EAEA,SAAS;AAAA,EAAC;AACZ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"custom-image-spec.es.js","sources":["../../../../../src/modules/custom-image/specs/custom-image-spec.ts"],"sourcesContent":["import type { BlotFormatter } from '../blot-formatter'\nimport { isInside } from '../../../config/editor.utils'\nimport { ImageSpec } from './image-spec'\n\nexport class CustomImageSpec extends ImageSpec {\n editorElem: HTMLElement | undefined\n observer: any\n oldRootScrollTop: number\n\n constructor(formatter: BlotFormatter) {\n super(formatter)\n this.formatter = formatter\n this.oldRootScrollTop = this.formatter.quill.root.scrollTop\n this.editorElem = this.formatter.quill.container\n this.formatter.quill.root.addEventListener('scroll', this.handleQuillRootScroll.bind(this))\n }\n\n handleQuillRootScroll() {\n if (this.formatter.overlay) {\n this.formatter.overlay.style.marginTop = `${this.oldRootScrollTop - this.formatter.quill.root.scrollTop}px`\n }\n }\n\n init(): void {\n this.editorElem.addEventListener('mouseover', this.imageMouseOver.bind(this))\n this.editorElem.addEventListener('mouseout', this.imageMouseout)\n\n super.init()\n }\n\n imageMouseOver(event) {\n const target = event.target\n const isBlotFormatter = target?.classList?.contains('blot-formatter__overlay')\n if (target.nodeName === 'IMG' || isBlotFormatter) {\n // this.addImagePreviewOverlay(event);\n }\n }\n\n imageMouseout = (event) => {\n if (event.target.nodeName === 'IMG'\n || event.target.classList.contains('blot-formatter__overlay')) {\n const imgDom = event.target\n if (!isInside(event, imgDom)) {\n this.removeImagePreviewOverlay()\n }\n }\n }\n\n addImagePreviewOverlay(event) {\n const target = event.target\n const {\n left: imgLeft,\n width: imgWidth,\n } = target.getBoundingClientRect()\n // fix: 解决 ql-container 容器设置 calc(100vh - 180px) 这样的视窗相对单位时,滚动视窗导致图片相对视窗的 top 相应改变,从而导致图片预览按钮的位置显示错误\n const imgTop = target.getBoundingClientRect().top + this.formatter.quill.container.scrollTop\n\n const {\n left: editorLeft,\n top: editorTop,\n } = event.currentTarget.getBoundingClientRect()\n\n const imgRelativeLeft = imgLeft - editorLeft\n const imgRelativeTop = imgTop - editorTop\n\n const maxmizeWidth = 24\n const maxmizePadding = 15\n const previewLeft = imgRelativeLeft + imgWidth - maxmizeWidth - maxmizePadding\n const previewTop = imgRelativeTop + maxmizePadding\n\n const previewStyle = `\n left: ${previewLeft}px;\n top: ${previewTop}px;\n width: ${maxmizeWidth}px;\n `\n const imageSrc = target.src || target.getAttribute('data-image')\n const imageId = target.getAttribute('data-image-id')\n\n const previewDom = event.currentTarget.querySelector('.image-preview__overlay')\n if (!previewDom) {\n event.currentTarget.insertAdjacentHTML('beforeend', `\n <div class=\"image-preview__overlay\" style=\"${previewStyle}\">\n <i class=\"icon-maxmize\" id=\"btn-image-preview\" data-image-id=\"${imageId}\"\n data-image=\"${imageSrc}\"></i>\n </div>\n `)\n }\n }\n\n removeImagePreviewOverlay() {\n const previewDom = this.editorElem.querySelector('.image-preview__overlay')\n if (previewDom) {\n previewDom.parentNode.removeChild(previewDom)\n }\n }\n\n onHide() {\n this.removeImagePreviewOverlay()\n super.onHide()\n }\n\n resetOverlayMarginTop() {\n if (this.formatter.overlay) {\n this.formatter.overlay.style.marginTop = '0px'\n }\n }\n\n onClick = (event: MouseEvent) => {\n const el = event.target\n const isReadonly = this.formatter.quill.options.readOnly\n if (!(el instanceof HTMLElement) || el.tagName !== 'IMG' || isReadonly) {\n return\n }\n\n this.img = el as HTMLImageElement\n this.oldRootScrollTop = this.formatter.quill.root.scrollTop\n this.resetOverlayMarginTop()\n this.formatter.show(this)\n\n // 通过图片dom获取图片选区用以复制,设置 current-select-img::selection 取消选区背景\n const imageDom = this.formatter.currentSpec?.getTargetElement()\n if (imageDom) {\n imageDom.classList.add('current-select-img')\n const quill = this.formatter.quill\n const imgBlot = quill.scroll.find(this.img)\n const index = quill.getIndex(imgBlot)\n const len = imgBlot.length()\n quill.setSelection(index, len)\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"custom-image-spec.es.js","sources":["../../../../../src/modules/custom-image/specs/custom-image-spec.ts"],"sourcesContent":["import type { BlotFormatter } from '../blot-formatter'\nimport { isInside } from '../../../config/editor.utils'\nimport { ImageSpec } from './image-spec'\n\nexport class CustomImageSpec extends ImageSpec {\n editorElem: HTMLElement | undefined\n observer: any\n oldRootScrollTop: number\n\n constructor(formatter: BlotFormatter) {\n super(formatter)\n this.formatter = formatter\n this.oldRootScrollTop = this.formatter.quill.root.scrollTop\n this.editorElem = this.formatter.quill.container\n this.formatter.quill.root.addEventListener('scroll', this.handleQuillRootScroll.bind(this))\n }\n\n handleQuillRootScroll() {\n if (this.formatter.overlay) {\n this.formatter.overlay.style.marginTop = `${this.oldRootScrollTop - this.formatter.quill.root.scrollTop}px`\n }\n }\n\n init(): void {\n this.editorElem.addEventListener('mouseover', this.imageMouseOver.bind(this))\n this.editorElem.addEventListener('mouseout', this.imageMouseout)\n\n super.init()\n }\n\n imageMouseOver(event) {\n const target = event.target\n const isBlotFormatter = target?.classList?.contains('blot-formatter__overlay')\n if (target.nodeName === 'IMG' || isBlotFormatter) {\n // this.addImagePreviewOverlay(event);\n }\n }\n\n imageMouseout = (event) => {\n if (event.target.nodeName === 'IMG'\n || event.target.classList.contains('blot-formatter__overlay')) {\n const imgDom = event.target\n if (!isInside(event, imgDom)) {\n this.removeImagePreviewOverlay()\n }\n }\n }\n\n addImagePreviewOverlay(event) {\n const target = event.target\n const {\n left: imgLeft,\n width: imgWidth,\n } = target.getBoundingClientRect()\n // fix: 解决 ql-container 容器设置 calc(100vh - 180px) 这样的视窗相对单位时,滚动视窗导致图片相对视窗的 top 相应改变,从而导致图片预览按钮的位置显示错误\n const imgTop = target.getBoundingClientRect().top + this.formatter.quill.container.scrollTop\n\n const {\n left: editorLeft,\n top: editorTop,\n } = event.currentTarget.getBoundingClientRect()\n\n const imgRelativeLeft = imgLeft - editorLeft\n const imgRelativeTop = imgTop - editorTop\n\n const maxmizeWidth = 24\n const maxmizePadding = 15\n const previewLeft = imgRelativeLeft + imgWidth - maxmizeWidth - maxmizePadding\n const previewTop = imgRelativeTop + maxmizePadding\n\n const previewStyle = `\n left: ${previewLeft}px;\n top: ${previewTop}px;\n width: ${maxmizeWidth}px;\n `\n const imageSrc = target.src || target.getAttribute('data-image')\n const imageId = target.getAttribute('data-image-id')\n\n const previewDom = event.currentTarget.querySelector('.image-preview__overlay')\n if (!previewDom) {\n event.currentTarget.insertAdjacentHTML('beforeend', `\n <div class=\"image-preview__overlay\" style=\"${previewStyle}\">\n <i class=\"icon-maxmize\" id=\"btn-image-preview\" data-image-id=\"${imageId}\"\n data-image=\"${imageSrc}\"></i>\n </div>\n `)\n }\n }\n\n removeImagePreviewOverlay() {\n const previewDom = this.editorElem.querySelector('.image-preview__overlay')\n if (previewDom) {\n previewDom.parentNode.removeChild(previewDom)\n }\n }\n\n onHide() {\n this.removeImagePreviewOverlay()\n super.onHide()\n }\n\n resetOverlayMarginTop() {\n if (this.formatter.overlay) {\n this.formatter.overlay.style.marginTop = '0px'\n }\n }\n\n onClick = (event: MouseEvent) => {\n const el = event.target\n const isReadonly = this.formatter.quill.options.readOnly\n if (!(el instanceof HTMLElement) || el.tagName !== 'IMG' || isReadonly) {\n return\n }\n\n this.img = el as HTMLImageElement\n this.oldRootScrollTop = this.formatter.quill.root.scrollTop\n this.resetOverlayMarginTop()\n this.formatter.show(this)\n\n // 通过图片dom获取图片选区用以复制,设置 current-select-img::selection 取消选区背景\n const imageDom = this.formatter.currentSpec?.getTargetElement()\n if (imageDom) {\n imageDom.classList.add('current-select-img')\n const quill = this.formatter.quill\n const imgBlot = quill.scroll.find(this.img)\n const index = quill.getIndex(imgBlot)\n const len = imgBlot.length()\n quill.setSelection(index, len)\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"image-spec.es.js","sources":["../../../../../src/modules/custom-image/specs/image-spec.ts"],"sourcesContent":["import { BlotSpec } from './blot-spec'\n\nexport class ImageSpec extends BlotSpec {\n img: HTMLImageElement | null = null\n\n init() {\n this.formatter.quill.root.addEventListener('click', this.onClick)\n }\n\n getTargetElement() {\n return this.img\n }\n\n onHide() {\n this.img = null\n }\n\n onClick = (event: MouseEvent) => {\n const el = event.target\n if (!(el instanceof HTMLElement) || el.tagName !== 'IMG') {\n return\n }\n event.stopPropagation()\n\n this.img = el as HTMLImageElement\n this.formatter.show(this)\n }\n}\n"],"names":[],"mappings":";;;;AAEO,MAAM,kBAAkB,SAAS;AAAA,EAAjC;AAAA;AACL,+BAA+B;AAc/B,mCAAU,CAAC,UAAsB;AAC/B,YAAM,KAAK,MAAM;AACjB,UAAI,EAAE,cAAc,gBAAgB,GAAG,YAAY,OAAO;AACxD;AAAA,MAAA;AAEF,YAAM,gBAAgB;AAEtB,WAAK,MAAM;AACN,WAAA,UAAU,KAAK,IAAI;AAAA,IAC1B;AAAA;AAAA,EArBA,OAAO;AACL,SAAK,UAAU,MAAM,KAAK,iBAAiB,SAAS,KAAK,OAAO;AAAA,EAAA;AAAA,EAGlE,mBAAmB;AACjB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGd,SAAS;AACP,SAAK,MAAM;AAAA,EAAA;AAaf;"}
1
+ {"version":3,"file":"image-spec.es.js","sources":["../../../../../src/modules/custom-image/specs/image-spec.ts"],"sourcesContent":["import { BlotSpec } from './blot-spec'\n\nexport class ImageSpec extends BlotSpec {\n img: HTMLImageElement | null = null\n\n init() {\n this.formatter.quill.root.addEventListener('click', this.onClick)\n }\n\n getTargetElement() {\n return this.img\n }\n\n onHide() {\n this.img = null\n }\n\n onClick = (event: MouseEvent) => {\n const el = event.target\n if (!(el instanceof HTMLElement) || el.tagName !== 'IMG') {\n return\n }\n event.stopPropagation()\n\n this.img = el as HTMLImageElement\n this.formatter.show(this)\n }\n}\n"],"names":[],"mappings":";;;;AAEO,MAAM,kBAAkB,SAAS;AAAA,EAAjC;AAAA;AACL,+BAA+B;AAc/B,mCAAU,CAAC,UAAsB;AAC/B,YAAM,KAAK,MAAM;AACjB,UAAI,EAAE,cAAc,gBAAgB,GAAG,YAAY,OAAO;AACxD;AAAA,MACF;AACA,YAAM,gBAAA;AAEN,WAAK,MAAM;AACX,WAAK,UAAU,KAAK,IAAI;AAAA,IAC1B;AAAA;AAAA,EArBA,OAAO;AACL,SAAK,UAAU,MAAM,KAAK,iBAAiB,SAAS,KAAK,OAAO;AAAA,EAClE;AAAA,EAEA,mBAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAAS;AACP,SAAK,MAAM;AAAA,EACb;AAYF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"custom-uploader.es.js","sources":["../../../src/modules/custom-uploader.ts"],"sourcesContent":["import type { Range } from 'quill'\r\nimport type TypeUploader from 'quill/modules/uploader'\r\nimport type FluentEditor from '../core/fluent-editor'\r\nimport Quill from 'quill'\r\nimport { isString } from '../utils/is'\r\n\r\nconst Uploader = Quill.import('modules/uploader') as typeof TypeUploader\r\nconst Delta = Quill.import('delta')\r\n\r\ninterface UploaderOptions {\r\n mimetypes: string[]\r\n handler: (this: { quill: Quill }, range: Range, files: File[]) => void\r\n}\r\nexport interface FileUploaderOptions {\r\n mimetypes: string[]\r\n maxSize: number\r\n handler: (this: { quill: FluentEditor }, range: Range, files: File[]) => Promise<(string | false)[]> | (string | false)[]\r\n success: (this: { quill: FluentEditor }, file: File, range: Range) => void\r\n fail: (this: { quill: FluentEditor }, file: File, range: Range) => void\r\n}\r\nexport class FileUploader extends Uploader {\r\n static DEFAULTS = {} as any\r\n // Partial<UploaderOptions> for ts type\r\n declare options: Partial<UploaderOptions> & FileUploaderOptions\r\n constructor(public quill: FluentEditor, options: Partial<FileUploaderOptions>) {\r\n super(quill, options as any)\r\n this.options = this.resolveOptions(options)\r\n // paste handle in clipboard\r\n }\r\n\r\n resolveOptions(options: Partial<FileUploaderOptions> = {}) {\r\n return Object.assign({\r\n mimetypes: ['*'],\r\n maxSize: Number.POSITIVE_INFINITY,\r\n handler(range: Range, files: File[]) {\r\n return files.map(file => URL.createObjectURL(file))\r\n },\r\n success() {},\r\n fail() {},\r\n }, options)\r\n }\r\n\r\n validateFile(file: File) {\r\n return this.options.mimetypes.some(type => (file.type || 'text/plain').match(type.replaceAll('*', '.*'))) && file.size < this.options.maxSize\r\n }\r\n\r\n async getFileUrls(files: File[], range: Range) {\r\n const uploads = files.filter(file => this.validateFile(file))\r\n return this.options.handler.call(this, range, uploads)\r\n }\r\n\r\n async upload(range: Range, files: FileList | File[]) {\r\n const uploads = []\r\n const fails = []\r\n\r\n for (const file of Array.from(files)) {\r\n if (this.validateFile(file)) {\r\n uploads.push(file)\r\n }\r\n else {\r\n fails.push(file)\r\n }\r\n }\r\n\r\n const result = await this.options.handler.call(this, range, uploads)\r\n const updateDelta = result.reduce((delta, url, i) => {\r\n if (isString(url)) {\r\n const type = uploads[i].type\r\n if (type.startsWith('image/')) {\r\n delta.insert({ image: url })\r\n }\r\n else if (type.startsWith('video/')) {\r\n delta.insert({ video: { src: url } })\r\n }\r\n else {\r\n delta.insert({ file: { size: uploads[i].size, title: uploads[i].name, src: url } })\r\n }\r\n }\r\n else {\r\n delta.insert(' ')\r\n }\r\n return delta\r\n }, new Delta().retain(range.index).delete(range.length))\r\n\r\n this.quill.updateContents(updateDelta, Quill.sources.USER)\r\n this.quill.setSelection(range.index + result.length, Quill.sources.SILENT)\r\n\r\n for (const file of fails) {\r\n this.options.fail.call(this, file, range)\r\n }\r\n\r\n for (const [i, res] of result.entries()) {\r\n if (isString(res)) {\r\n this.options.success.call(this, files[i], { index: range.index + i, length: 0 })\r\n }\r\n else {\r\n this.options.fail.call(this, files[i], { index: range.index + i, length: 0 })\r\n }\r\n }\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;AAMA,MAAM,WAAW,MAAM,OAAO,kBAAkB;AAChD,MAAM,QAAQ,MAAM,OAAO,OAAO;AAa3B,MAAM,qBAAqB,SAAS;AAAA,EAIzC,YAAmB,OAAqB,SAAuC;AAC7E,UAAM,OAAO,OAAc;AADV,SAAA,QAAA;AAEZ,SAAA,UAAU,KAAK,eAAe,OAAO;AAAA,EAAA;AAAA,EAI5C,eAAe,UAAwC,IAAI;AACzD,WAAO,OAAO,OAAO;AAAA,MACnB,WAAW,CAAC,GAAG;AAAA,MACf,SAAS,OAAO;AAAA,MAChB,QAAQ,OAAc,OAAe;AACnC,eAAO,MAAM,IAAI,CAAA,SAAQ,IAAI,gBAAgB,IAAI,CAAC;AAAA,MACpD;AAAA,MACA,UAAU;AAAA,MAAC;AAAA,MACX,OAAO;AAAA,MAAA;AAAA,OACN,OAAO;AAAA,EAAA;AAAA,EAGZ,aAAa,MAAY;AACvB,WAAO,KAAK,QAAQ,UAAU,KAAK,CAAS,UAAA,KAAK,QAAQ,cAAc,MAAM,KAAK,WAAW,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,KAAK,QAAQ;AAAA,EAAA;AAAA,EAGxI,MAAM,YAAY,OAAe,OAAc;AAC7C,UAAM,UAAU,MAAM,OAAO,UAAQ,KAAK,aAAa,IAAI,CAAC;AAC5D,WAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM,OAAO,OAAO;AAAA,EAAA;AAAA,EAGvD,MAAM,OAAO,OAAc,OAA0B;AACnD,UAAM,UAAU,CAAC;AACjB,UAAM,QAAQ,CAAC;AAEf,eAAW,QAAQ,MAAM,KAAK,KAAK,GAAG;AAChC,UAAA,KAAK,aAAa,IAAI,GAAG;AAC3B,gBAAQ,KAAK,IAAI;AAAA,MAAA,OAEd;AACH,cAAM,KAAK,IAAI;AAAA,MAAA;AAAA,IACjB;AAGI,UAAA,SAAS,MAAM,KAAK,QAAQ,QAAQ,KAAK,MAAM,OAAO,OAAO;AACnE,UAAM,cAAc,OAAO,OAAO,CAAC,OAAO,KAAK,MAAM;AAC/C,UAAA,SAAS,GAAG,GAAG;AACX,cAAA,OAAO,QAAQ,CAAC,EAAE;AACpB,YAAA,KAAK,WAAW,QAAQ,GAAG;AAC7B,gBAAM,OAAO,EAAE,OAAO,IAAA,CAAK;AAAA,QAEpB,WAAA,KAAK,WAAW,QAAQ,GAAG;AAClC,gBAAM,OAAO,EAAE,OAAO,EAAE,KAAK,IAAA,GAAO;AAAA,QAAA,OAEjC;AACH,gBAAM,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,EAAE,MAAM,OAAO,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAA,GAAO;AAAA,QAAA;AAAA,MACpF,OAEG;AACH,cAAM,OAAO,GAAG;AAAA,MAAA;AAEX,aAAA;AAAA,IAAA,GACN,IAAI,QAAQ,OAAO,MAAM,KAAK,EAAE,OAAO,MAAM,MAAM,CAAC;AAEvD,SAAK,MAAM,eAAe,aAAa,MAAM,QAAQ,IAAI;AACpD,SAAA,MAAM,aAAa,MAAM,QAAQ,OAAO,QAAQ,MAAM,QAAQ,MAAM;AAEzE,eAAW,QAAQ,OAAO;AACxB,WAAK,QAAQ,KAAK,KAAK,MAAM,MAAM,KAAK;AAAA,IAAA;AAG1C,eAAW,CAAC,GAAG,GAAG,KAAK,OAAO,WAAW;AACnC,UAAA,SAAS,GAAG,GAAG;AACjB,aAAK,QAAQ,QAAQ,KAAK,MAAM,MAAM,CAAC,GAAG,EAAE,OAAO,MAAM,QAAQ,GAAG,QAAQ,GAAG;AAAA,MAAA,OAE5E;AACH,aAAK,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,GAAG,EAAE,OAAO,MAAM,QAAQ,GAAG,QAAQ,GAAG;AAAA,MAAA;AAAA,IAC9E;AAAA,EACF;AAEJ;AA/EE,cADW,cACJ,YAAW,CAAC;"}
1
+ {"version":3,"file":"custom-uploader.es.js","sources":["../../../src/modules/custom-uploader.ts"],"sourcesContent":["import type { Range } from 'quill'\r\nimport type TypeUploader from 'quill/modules/uploader'\r\nimport type FluentEditor from '../core/fluent-editor'\r\nimport Quill from 'quill'\r\nimport { isString } from '../utils/is'\r\n\r\nconst Uploader = Quill.import('modules/uploader') as typeof TypeUploader\r\nconst Delta = Quill.import('delta')\r\n\r\ninterface UploaderOptions {\r\n mimetypes: string[]\r\n handler: (this: { quill: Quill }, range: Range, files: File[]) => void\r\n}\r\nexport interface FileUploaderOptions {\r\n mimetypes: string[]\r\n maxSize: number\r\n handler: (this: { quill: FluentEditor }, range: Range, files: File[]) => Promise<(string | false)[]> | (string | false)[]\r\n success: (this: { quill: FluentEditor }, file: File, range: Range) => void\r\n fail: (this: { quill: FluentEditor }, file: File, range: Range) => void\r\n}\r\nexport class FileUploader extends Uploader {\r\n static DEFAULTS = {} as any\r\n // Partial<UploaderOptions> for ts type\r\n declare options: Partial<UploaderOptions> & FileUploaderOptions\r\n constructor(public quill: FluentEditor, options: Partial<FileUploaderOptions>) {\r\n super(quill, options as any)\r\n this.options = this.resolveOptions(options)\r\n // paste handle in clipboard\r\n }\r\n\r\n resolveOptions(options: Partial<FileUploaderOptions> = {}) {\r\n return Object.assign({\r\n mimetypes: ['*'],\r\n maxSize: Number.POSITIVE_INFINITY,\r\n handler(range: Range, files: File[]) {\r\n return files.map(file => URL.createObjectURL(file))\r\n },\r\n success() {},\r\n fail() {},\r\n }, options)\r\n }\r\n\r\n validateFile(file: File) {\r\n return this.options.mimetypes.some(type => (file.type || 'text/plain').match(type.replaceAll('*', '.*'))) && file.size < this.options.maxSize\r\n }\r\n\r\n async getFileUrls(files: File[], range: Range) {\r\n const uploads = files.filter(file => this.validateFile(file))\r\n return this.options.handler.call(this, range, uploads)\r\n }\r\n\r\n async upload(range: Range, files: FileList | File[]) {\r\n const uploads = []\r\n const fails = []\r\n\r\n for (const file of Array.from(files)) {\r\n if (this.validateFile(file)) {\r\n uploads.push(file)\r\n }\r\n else {\r\n fails.push(file)\r\n }\r\n }\r\n\r\n const result = await this.options.handler.call(this, range, uploads)\r\n const updateDelta = result.reduce((delta, url, i) => {\r\n if (isString(url)) {\r\n const type = uploads[i].type\r\n if (type.startsWith('image/')) {\r\n delta.insert({ image: url })\r\n }\r\n else if (type.startsWith('video/')) {\r\n delta.insert({ video: { src: url } })\r\n }\r\n else {\r\n delta.insert({ file: { size: uploads[i].size, title: uploads[i].name, src: url } })\r\n }\r\n }\r\n else {\r\n delta.insert(' ')\r\n }\r\n return delta\r\n }, new Delta().retain(range.index).delete(range.length))\r\n\r\n this.quill.updateContents(updateDelta, Quill.sources.USER)\r\n this.quill.setSelection(range.index + result.length, Quill.sources.SILENT)\r\n\r\n for (const file of fails) {\r\n this.options.fail.call(this, file, range)\r\n }\r\n\r\n for (const [i, res] of result.entries()) {\r\n if (isString(res)) {\r\n this.options.success.call(this, files[i], { index: range.index + i, length: 0 })\r\n }\r\n else {\r\n this.options.fail.call(this, files[i], { index: range.index + i, length: 0 })\r\n }\r\n }\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;AAMA,MAAM,WAAW,MAAM,OAAO,kBAAkB;AAChD,MAAM,QAAQ,MAAM,OAAO,OAAO;AAa3B,MAAM,qBAAqB,SAAS;AAAA,EAIzC,YAAmB,OAAqB,SAAuC;AAC7E,UAAM,OAAO,OAAc;AADV,SAAA,QAAA;AAEjB,SAAK,UAAU,KAAK,eAAe,OAAO;AAAA,EAE5C;AAAA,EAEA,eAAe,UAAwC,IAAI;AACzD,WAAO,OAAO,OAAO;AAAA,MACnB,WAAW,CAAC,GAAG;AAAA,MACf,SAAS,OAAO;AAAA,MAChB,QAAQ,OAAc,OAAe;AACnC,eAAO,MAAM,IAAI,CAAA,SAAQ,IAAI,gBAAgB,IAAI,CAAC;AAAA,MACpD;AAAA,MACA,UAAU;AAAA,MAAC;AAAA,MACX,OAAO;AAAA,MAAC;AAAA,IAAA,GACP,OAAO;AAAA,EACZ;AAAA,EAEA,aAAa,MAAY;AACvB,WAAO,KAAK,QAAQ,UAAU,KAAK,CAAA,UAAS,KAAK,QAAQ,cAAc,MAAM,KAAK,WAAW,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,KAAK,QAAQ;AAAA,EACxI;AAAA,EAEA,MAAM,YAAY,OAAe,OAAc;AAC7C,UAAM,UAAU,MAAM,OAAO,UAAQ,KAAK,aAAa,IAAI,CAAC;AAC5D,WAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM,OAAO,OAAO;AAAA,EACvD;AAAA,EAEA,MAAM,OAAO,OAAc,OAA0B;AACnD,UAAM,UAAU,CAAA;AAChB,UAAM,QAAQ,CAAA;AAEd,eAAW,QAAQ,MAAM,KAAK,KAAK,GAAG;AACpC,UAAI,KAAK,aAAa,IAAI,GAAG;AAC3B,gBAAQ,KAAK,IAAI;AAAA,MACnB,OACK;AACH,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,KAAK,MAAM,OAAO,OAAO;AACnE,UAAM,cAAc,OAAO,OAAO,CAAC,OAAO,KAAK,MAAM;AACnD,UAAI,SAAS,GAAG,GAAG;AACjB,cAAM,OAAO,QAAQ,CAAC,EAAE;AACxB,YAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,gBAAM,OAAO,EAAE,OAAO,IAAA,CAAK;AAAA,QAC7B,WACS,KAAK,WAAW,QAAQ,GAAG;AAClC,gBAAM,OAAO,EAAE,OAAO,EAAE,KAAK,IAAA,GAAO;AAAA,QACtC,OACK;AACH,gBAAM,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,EAAE,MAAM,OAAO,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAA,GAAO;AAAA,QACpF;AAAA,MACF,OACK;AACH,cAAM,OAAO,GAAG;AAAA,MAClB;AACA,aAAO;AAAA,IACT,GAAG,IAAI,MAAA,EAAQ,OAAO,MAAM,KAAK,EAAE,OAAO,MAAM,MAAM,CAAC;AAEvD,SAAK,MAAM,eAAe,aAAa,MAAM,QAAQ,IAAI;AACzD,SAAK,MAAM,aAAa,MAAM,QAAQ,OAAO,QAAQ,MAAM,QAAQ,MAAM;AAEzE,eAAW,QAAQ,OAAO;AACxB,WAAK,QAAQ,KAAK,KAAK,MAAM,MAAM,KAAK;AAAA,IAC1C;AAEA,eAAW,CAAC,GAAG,GAAG,KAAK,OAAO,WAAW;AACvC,UAAI,SAAS,GAAG,GAAG;AACjB,aAAK,QAAQ,QAAQ,KAAK,MAAM,MAAM,CAAC,GAAG,EAAE,OAAO,MAAM,QAAQ,GAAG,QAAQ,GAAG;AAAA,MACjF,OACK;AACH,aAAK,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,GAAG,EAAE,OAAO,MAAM,QAAQ,GAAG,QAAQ,GAAG;AAAA,MAC9E;AAAA,IACF;AAAA,EACF;AACF;AA/EE,cADW,cACJ,YAAW,CAAA;"}
@@ -1 +1 @@
1
- {"version":3,"file":"divider.es.js","sources":["../../../src/modules/divider.ts"],"sourcesContent":["import type { BlockEmbed as TypeBlockEmbed } from 'quill/blots/block'\nimport Quill from 'quill'\n\nconst BlockEmbed = Quill.import('blots/block/embed') as typeof TypeBlockEmbed\n\nexport class DividerBlot extends BlockEmbed {\n static blotName = 'divider'\n static tagName = 'hr'\n\n static create() {\n const node = super.create() as HTMLElement\n node.setAttribute('contenteditable', 'false')\n return node\n }\n}\n"],"names":[],"mappings":";;;;AAGA,MAAM,aAAa,MAAM,OAAO,mBAAmB;AAE5C,MAAM,oBAAoB,WAAW;AAAA,EAI1C,OAAO,SAAS;AACR,UAAA,OAAO,MAAM,OAAO;AACrB,SAAA,aAAa,mBAAmB,OAAO;AACrC,WAAA;AAAA,EAAA;AAEX;AARE,cADW,aACJ,YAAW;AAClB,cAFW,aAEJ,WAAU;"}
1
+ {"version":3,"file":"divider.es.js","sources":["../../../src/modules/divider.ts"],"sourcesContent":["import type { BlockEmbed as TypeBlockEmbed } from 'quill/blots/block'\nimport Quill from 'quill'\n\nconst BlockEmbed = Quill.import('blots/block/embed') as typeof TypeBlockEmbed\n\nexport class DividerBlot extends BlockEmbed {\n static blotName = 'divider'\n static tagName = 'hr'\n\n static create() {\n const node = super.create() as HTMLElement\n node.setAttribute('contenteditable', 'false')\n return node\n }\n}\n"],"names":[],"mappings":";;;;AAGA,MAAM,aAAa,MAAM,OAAO,mBAAmB;AAE5C,MAAM,oBAAoB,WAAW;AAAA,EAI1C,OAAO,SAAS;AACd,UAAM,OAAO,MAAM,OAAA;AACnB,SAAK,aAAa,mBAAmB,OAAO;AAC5C,WAAO;AAAA,EACT;AACF;AARE,cADW,aACJ,YAAW;AAClB,cAFW,aAEJ,WAAU;"}
@@ -1 +1 @@
1
- {"version":3,"file":"emoji.es.js","sources":["../../../src/modules/emoji.ts"],"sourcesContent":["import type { EmojiMartData } from '@emoji-mart/data'\nimport type { computePosition } from '@floating-ui/dom'\nimport type { Picker } from 'emoji-mart'\nimport type TypeToolbar from 'quill/modules/toolbar'\nimport type FluentEditor from '../fluent-editor'\nimport { debounce } from 'lodash-es'\n\nexport interface EmojiModuleOptions {\n emojiData?: EmojiMartData\n EmojiPicker?: new (props: any) => Picker\n emojiPickerPosition?: typeof computePosition\n theme?: string\n locale?: string\n set?: string\n skinTonePosition?: string\n previewPosition?: string\n searchPosition?: string\n categories?: string[]\n maxFrequentRows?: number\n perLine?: number\n navPosition?: string\n noCountryFlags?: boolean\n dynamicWidth?: boolean\n}\n\nconst DEFAULT_OPTIONS: EmojiModuleOptions = {\n // @ts-ignore\n emojiData: window.emojiData,\n // @ts-ignore\n EmojiPicker: window.EmojiPicker,\n // @ts-ignore\n emojiPickerPosition: window.emojiPickerPosition,\n theme: 'light',\n set: 'native',\n skinTonePosition: 'none',\n previewPosition: 'bottom',\n searchPosition: 'sticky',\n categories: ['frequent', 'people', 'nature', 'foods', 'activity', 'places', 'objects', 'symbols', 'flags'],\n maxFrequentRows: 2,\n perLine: 8,\n navPosition: 'top',\n noCountryFlags: false,\n dynamicWidth: false,\n}\n\nconst PICKER_DOM_ID = 'emoji-picker'\n\nconst LOCALE_MAP = {\n 'zh-CN': 'zh',\n 'en-US': 'en',\n} as const\n\nclass EmojiModule {\n private readonly quill: FluentEditor\n private readonly options: EmojiModuleOptions\n private picker: HTMLElement | null = null\n private isPickerVisible = false\n private cleanupResizeObserver: (() => void) | null = null\n\n constructor(quill: FluentEditor, options: EmojiModuleOptions = {}) {\n this.quill = quill\n\n this.options = { ...DEFAULT_OPTIONS, ...options }\n\n const toolbar = this.quill.getModule('toolbar') as TypeToolbar\n\n if (toolbar) {\n toolbar.addHandler('emoji', () => {\n if (this.isPickerVisible) {\n this.closeDialog()\n }\n else {\n this.openDialog()\n }\n })\n }\n }\n\n private getEmojiButton() {\n return document.querySelector('.ql-emoji') as HTMLElement | null\n }\n\n private async updatePickerPosition() {\n const button = this.getEmojiButton()\n const pickerElement = document.getElementById(PICKER_DOM_ID)\n\n if (!button || !this.picker || !pickerElement) {\n return\n }\n\n const { emojiPickerPosition } = this.options\n\n try {\n const { x, y } = await emojiPickerPosition(button, pickerElement)\n this.picker.style.top = `${y}px`\n this.picker.style.left = `${x}px`\n }\n catch (error) {\n console.warn('Failed to compute picker position:', error)\n }\n }\n\n // 监听容器大小变化,更新表情选择弹窗位置\n private setupContainerResizeObserver() {\n const container = this.quill.root.parentElement\n if (!container) {\n return null\n }\n\n const debouncedUpdate = debounce(() => {\n this.updatePickerPosition()\n }, 100)\n\n const resizeObserver = new ResizeObserver(() => {\n debouncedUpdate()\n })\n\n resizeObserver.observe(container)\n\n return () => {\n resizeObserver.disconnect()\n debouncedUpdate.cancel()\n }\n }\n\n // 创建表情选择弹窗\n private createPicker() {\n const { EmojiPicker, emojiData, ...options } = this.options\n\n const pickerConfig = {\n // emoji-mart 与 tiny-editor 国际化的的 locale 不一致使用 LOCALE_MAP 转换\n locale: LOCALE_MAP[this.quill.lang] ?? 'en',\n data: emojiData,\n ...options,\n onEmojiSelect: this.handleEmojiSelect.bind(this),\n onClickOutside: this.handleClickOutside.bind(this),\n }\n\n const picker = new EmojiPicker(pickerConfig) as unknown as HTMLElement\n\n // 设置样式和属性\n picker.id = PICKER_DOM_ID\n picker.style.position = 'absolute'\n picker.style.zIndex = '1000'\n\n return picker\n }\n\n // 打开表情弹窗\n public openDialog() {\n if (this.picker) {\n return\n }\n\n try {\n this.picker = this.createPicker()\n document.body.appendChild(this.picker)\n\n this.updatePickerPosition()\n this.cleanupResizeObserver = this.setupContainerResizeObserver()\n this.isPickerVisible = true\n }\n catch (error) {\n console.error('Failed to open emoji picker:', error)\n this.closeDialog()\n }\n }\n\n // 关闭表情弹窗\n public closeDialog() {\n if (!this.picker) {\n return\n }\n\n this.isPickerVisible = false\n this.picker.remove()\n this.picker = null\n\n this.cleanupResizeObserver?.()\n this.cleanupResizeObserver = null\n }\n\n // 处理表情选择事件\n private handleEmojiSelect(emoji: { native: string }) {\n const selection = this.quill.getSelection(true)\n if (!selection) {\n console.warn('No selection available for emoji insertion')\n return\n }\n\n try {\n // 记录插入位置\n const insertIndex = selection.index\n this.quill.insertText(insertIndex, emoji.native, 'user')\n\n this.closeDialog()\n\n // 设置光标到表情符号后面\n this.quill.setSelection(insertIndex + emoji.native.length)\n }\n catch (error) {\n console.error('Failed to insert emoji:', error)\n }\n }\n\n // 处理外部点击事件\n private handleClickOutside(event: MouseEvent) {\n const button = this.getEmojiButton()\n\n const target = event.target\n\n const isClickOnButton = target === button || (target instanceof Element && button?.contains(target))\n\n // 如果点击的是表情符号按钮或其子元素,则不关闭选择器\n if (isClickOnButton) {\n return\n }\n\n this.closeDialog()\n }\n\n // 销毁模块,清理资源\n public destroy() {\n this.cleanupResizeObserver?.()\n this.cleanupResizeObserver = null\n this.closeDialog()\n }\n}\n\nexport { EmojiModule }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emoji.es.js","sources":["../../../src/modules/emoji.ts"],"sourcesContent":["import type { EmojiMartData } from '@emoji-mart/data'\nimport type { computePosition } from '@floating-ui/dom'\nimport type { Picker } from 'emoji-mart'\nimport type TypeToolbar from 'quill/modules/toolbar'\nimport type FluentEditor from '../fluent-editor'\nimport { debounce } from 'lodash-es'\n\nexport interface EmojiModuleOptions {\n emojiData?: EmojiMartData\n EmojiPicker?: new (props: any) => Picker\n emojiPickerPosition?: typeof computePosition\n theme?: string\n locale?: string\n set?: string\n skinTonePosition?: string\n previewPosition?: string\n searchPosition?: string\n categories?: string[]\n maxFrequentRows?: number\n perLine?: number\n navPosition?: string\n noCountryFlags?: boolean\n dynamicWidth?: boolean\n}\n\nconst DEFAULT_OPTIONS: EmojiModuleOptions = {\n // @ts-ignore\n emojiData: window.emojiData,\n // @ts-ignore\n EmojiPicker: window.EmojiPicker,\n // @ts-ignore\n emojiPickerPosition: window.emojiPickerPosition,\n theme: 'light',\n set: 'native',\n skinTonePosition: 'none',\n previewPosition: 'bottom',\n searchPosition: 'sticky',\n categories: ['frequent', 'people', 'nature', 'foods', 'activity', 'places', 'objects', 'symbols', 'flags'],\n maxFrequentRows: 2,\n perLine: 8,\n navPosition: 'top',\n noCountryFlags: false,\n dynamicWidth: false,\n}\n\nconst PICKER_DOM_ID = 'emoji-picker'\n\nconst LOCALE_MAP = {\n 'zh-CN': 'zh',\n 'en-US': 'en',\n} as const\n\nclass EmojiModule {\n private readonly quill: FluentEditor\n private readonly options: EmojiModuleOptions\n private picker: HTMLElement | null = null\n private isPickerVisible = false\n private cleanupResizeObserver: (() => void) | null = null\n\n constructor(quill: FluentEditor, options: EmojiModuleOptions = {}) {\n this.quill = quill\n\n this.options = { ...DEFAULT_OPTIONS, ...options }\n\n const toolbar = this.quill.getModule('toolbar') as TypeToolbar\n\n if (toolbar) {\n toolbar.addHandler('emoji', () => {\n if (this.isPickerVisible) {\n this.closeDialog()\n }\n else {\n this.openDialog()\n }\n })\n }\n }\n\n private getEmojiButton() {\n return document.querySelector('.ql-emoji') as HTMLElement | null\n }\n\n private async updatePickerPosition() {\n const button = this.getEmojiButton()\n const pickerElement = document.getElementById(PICKER_DOM_ID)\n\n if (!button || !this.picker || !pickerElement) {\n return\n }\n\n const { emojiPickerPosition } = this.options\n\n try {\n const { x, y } = await emojiPickerPosition(button, pickerElement)\n this.picker.style.top = `${y}px`\n this.picker.style.left = `${x}px`\n }\n catch (error) {\n console.warn('Failed to compute picker position:', error)\n }\n }\n\n // 监听容器大小变化,更新表情选择弹窗位置\n private setupContainerResizeObserver() {\n const container = this.quill.root.parentElement\n if (!container) {\n return null\n }\n\n const debouncedUpdate = debounce(() => {\n this.updatePickerPosition()\n }, 100)\n\n const resizeObserver = new ResizeObserver(() => {\n debouncedUpdate()\n })\n\n resizeObserver.observe(container)\n\n return () => {\n resizeObserver.disconnect()\n debouncedUpdate.cancel()\n }\n }\n\n // 创建表情选择弹窗\n private createPicker() {\n const { EmojiPicker, emojiData, ...options } = this.options\n\n const pickerConfig = {\n // emoji-mart 与 tiny-editor 国际化的的 locale 不一致使用 LOCALE_MAP 转换\n locale: LOCALE_MAP[this.quill.lang] ?? 'en',\n data: emojiData,\n ...options,\n onEmojiSelect: this.handleEmojiSelect.bind(this),\n onClickOutside: this.handleClickOutside.bind(this),\n }\n\n const picker = new EmojiPicker(pickerConfig) as unknown as HTMLElement\n\n // 设置样式和属性\n picker.id = PICKER_DOM_ID\n picker.style.position = 'absolute'\n picker.style.zIndex = '1000'\n\n return picker\n }\n\n // 打开表情弹窗\n public openDialog() {\n if (this.picker) {\n return\n }\n\n try {\n this.picker = this.createPicker()\n document.body.appendChild(this.picker)\n\n this.updatePickerPosition()\n this.cleanupResizeObserver = this.setupContainerResizeObserver()\n this.isPickerVisible = true\n }\n catch (error) {\n console.error('Failed to open emoji picker:', error)\n this.closeDialog()\n }\n }\n\n // 关闭表情弹窗\n public closeDialog() {\n if (!this.picker) {\n return\n }\n\n this.isPickerVisible = false\n this.picker.remove()\n this.picker = null\n\n this.cleanupResizeObserver?.()\n this.cleanupResizeObserver = null\n }\n\n // 处理表情选择事件\n private handleEmojiSelect(emoji: { native: string }) {\n const selection = this.quill.getSelection(true)\n if (!selection) {\n console.warn('No selection available for emoji insertion')\n return\n }\n\n try {\n // 记录插入位置\n const insertIndex = selection.index\n this.quill.insertText(insertIndex, emoji.native, 'user')\n\n this.closeDialog()\n\n // 设置光标到表情符号后面\n this.quill.setSelection(insertIndex + emoji.native.length)\n }\n catch (error) {\n console.error('Failed to insert emoji:', error)\n }\n }\n\n // 处理外部点击事件\n private handleClickOutside(event: MouseEvent) {\n const button = this.getEmojiButton()\n\n const target = event.target\n\n const isClickOnButton = target === button || (target instanceof Element && button?.contains(target))\n\n // 如果点击的是表情符号按钮或其子元素,则不关闭选择器\n if (isClickOnButton) {\n return\n }\n\n this.closeDialog()\n }\n\n // 销毁模块,清理资源\n public destroy() {\n this.cleanupResizeObserver?.()\n this.cleanupResizeObserver = null\n this.closeDialog()\n }\n}\n\nexport { EmojiModule }\n"],"names":[],"mappings":";;;;AAyBA,MAAM,kBAAsC;AAAA;AAAA,EAE1C,WAAW,OAAO;AAAA;AAAA,EAElB,aAAa,OAAO;AAAA;AAAA,EAEpB,qBAAqB,OAAO;AAAA,EAC5B,OAAO;AAAA,EACP,KAAK;AAAA,EACL,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,YAAY,CAAC,YAAY,UAAU,UAAU,SAAS,YAAY,UAAU,WAAW,WAAW,OAAO;AAAA,EACzG,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,cAAc;AAChB;AAEA,MAAM,gBAAgB;AAEtB,MAAM,aAAa;AAAA,EACjB,SAAS;AAAA,EACT,SAAS;AACX;AAEA,MAAM,YAAY;AAAA,EAOhB,YAAY,OAAqB,UAA8B,IAAI;AANlD;AACA;AACT,kCAA6B;AAC7B,2CAAkB;AAClB,iDAA6C;AAGnD,SAAK,QAAQ;AAEb,SAAK,UAAU,EAAE,GAAG,iBAAiB,GAAG,QAAA;AAExC,UAAM,UAAU,KAAK,MAAM,UAAU,SAAS;AAE9C,QAAI,SAAS;AACX,cAAQ,WAAW,SAAS,MAAM;AAChC,YAAI,KAAK,iBAAiB;AACxB,eAAK,YAAA;AAAA,QACP,OACK;AACH,eAAK,WAAA;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,iBAAiB;AACvB,WAAO,SAAS,cAAc,WAAW;AAAA,EAC3C;AAAA,EAEA,MAAc,uBAAuB;AACnC,UAAM,SAAS,KAAK,eAAA;AACpB,UAAM,gBAAgB,SAAS,eAAe,aAAa;AAE3D,QAAI,CAAC,UAAU,CAAC,KAAK,UAAU,CAAC,eAAe;AAC7C;AAAA,IACF;AAEA,UAAM,EAAE,wBAAwB,KAAK;AAErC,QAAI;AACF,YAAM,EAAE,GAAG,EAAA,IAAM,MAAM,oBAAoB,QAAQ,aAAa;AAChE,WAAK,OAAO,MAAM,MAAM,GAAG,CAAC;AAC5B,WAAK,OAAO,MAAM,OAAO,GAAG,CAAC;AAAA,IAC/B,SACO,OAAO;AACZ,cAAQ,KAAK,sCAAsC,KAAK;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA,EAGQ,+BAA+B;AACrC,UAAM,YAAY,KAAK,MAAM,KAAK;AAClC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,SAAS,MAAM;AACrC,WAAK,qBAAA;AAAA,IACP,GAAG,GAAG;AAEN,UAAM,iBAAiB,IAAI,eAAe,MAAM;AAC9C,sBAAA;AAAA,IACF,CAAC;AAED,mBAAe,QAAQ,SAAS;AAEhC,WAAO,MAAM;AACX,qBAAe,WAAA;AACf,sBAAgB,OAAA;AAAA,IAClB;AAAA,EACF;AAAA;AAAA,EAGQ,eAAe;AACrB,UAAM,EAAE,aAAa,WAAW,GAAG,QAAA,IAAY,KAAK;AAEpD,UAAM,eAAe;AAAA;AAAA,MAEnB,QAAQ,WAAW,KAAK,MAAM,IAAI,KAAK;AAAA,MACvC,MAAM;AAAA,MACN,GAAG;AAAA,MACH,eAAe,KAAK,kBAAkB,KAAK,IAAI;AAAA,MAC/C,gBAAgB,KAAK,mBAAmB,KAAK,IAAI;AAAA,IAAA;AAGnD,UAAM,SAAS,IAAI,YAAY,YAAY;AAG3C,WAAO,KAAK;AACZ,WAAO,MAAM,WAAW;AACxB,WAAO,MAAM,SAAS;AAEtB,WAAO;AAAA,EACT;AAAA;AAAA,EAGO,aAAa;AAClB,QAAI,KAAK,QAAQ;AACf;AAAA,IACF;AAEA,QAAI;AACF,WAAK,SAAS,KAAK,aAAA;AACnB,eAAS,KAAK,YAAY,KAAK,MAAM;AAErC,WAAK,qBAAA;AACL,WAAK,wBAAwB,KAAK,6BAAA;AAClC,WAAK,kBAAkB;AAAA,IACzB,SACO,OAAO;AACZ,cAAQ,MAAM,gCAAgC,KAAK;AACnD,WAAK,YAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA,EAGO,cAAc;;AACnB,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,SAAK,kBAAkB;AACvB,SAAK,OAAO,OAAA;AACZ,SAAK,SAAS;AAEd,eAAK,0BAAL;AACA,SAAK,wBAAwB;AAAA,EAC/B;AAAA;AAAA,EAGQ,kBAAkB,OAA2B;AACnD,UAAM,YAAY,KAAK,MAAM,aAAa,IAAI;AAC9C,QAAI,CAAC,WAAW;AACd,cAAQ,KAAK,4CAA4C;AACzD;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,cAAc,UAAU;AAC9B,WAAK,MAAM,WAAW,aAAa,MAAM,QAAQ,MAAM;AAEvD,WAAK,YAAA;AAGL,WAAK,MAAM,aAAa,cAAc,MAAM,OAAO,MAAM;AAAA,IAC3D,SACO,OAAO;AACZ,cAAQ,MAAM,2BAA2B,KAAK;AAAA,IAChD;AAAA,EACF;AAAA;AAAA,EAGQ,mBAAmB,OAAmB;AAC5C,UAAM,SAAS,KAAK,eAAA;AAEpB,UAAM,SAAS,MAAM;AAErB,UAAM,kBAAkB,WAAW,UAAW,kBAAkB,YAAW,iCAAQ,SAAS;AAG5F,QAAI,iBAAiB;AACnB;AAAA,IACF;AAEA,SAAK,YAAA;AAAA,EACP;AAAA;AAAA,EAGO,UAAU;;AACf,eAAK,0BAAL;AACA,SAAK,wBAAwB;AAC7B,SAAK,YAAA;AAAA,EACP;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"file.es.js","sources":["../../../../../src/modules/file/formats/file.ts"],"sourcesContent":["import type TypeEmbed from 'quill/blots/embed'\nimport Quill from 'quill'\nimport { sanitize } from '../../../config/editor.utils'\n\nconst Embed = Quill.import('blots/embed') as typeof TypeEmbed\nconst FILE_ATTRIBUTES = ['id', 'title', 'size', 'lastModified']\n\nexport interface FileValue {\n size: number\n src: string\n title: string\n}\nexport class File extends Embed {\n static blotName = 'file'\n static tagName = 'A'\n static className = 'ql-file-item'\n static PROTOCOL_WHITELIST = ['http', 'https', 'blob']\n\n static create(value: FileValue) {\n const node = super.create(value) as HTMLAnchorElement\n const size = value.size / 1024\n const fixSize = !size ? 0 : size < 1 ? 1 : size.toFixed(0)\n node.classList.add('icon-file')\n node.setAttribute('contenteditable', 'false')\n const fileSvg = '<svg viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path d=\"M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326z m1.8 562H232V136h302v216c0 23.2 18.8 42 42 42h216v494z\" p-id=\"2307\"></path></svg>'\n node.innerHTML = `${fileSvg} ${value.title} (${fixSize} KB)`\n const src = this.sanitize(value.src)\n if (src) {\n node.href = src\n node.target = '_blank'\n }\n FILE_ATTRIBUTES.forEach((key) => {\n if (value[key]) {\n node.dataset[key] = value[key]\n }\n })\n return node\n }\n\n static value(domNode: HTMLAnchorElement) {\n return this.getFormats(domNode)\n }\n\n static getFormats(domNode: HTMLAnchorElement) {\n const formats: Record<string, string> = {}\n const href = this.sanitize(domNode.href)\n if (href) {\n formats.src = href\n }\n FILE_ATTRIBUTES.forEach((key) => {\n if (domNode.dataset[key]) {\n formats[key] = domNode.dataset[key]\n }\n })\n return formats\n }\n\n static sanitize(url: string) {\n return (sanitize(url, this.PROTOCOL_WHITELIST) && url) || ''\n }\n}\n"],"names":[],"mappings":";;;;;AAIA,MAAM,QAAQ,MAAM,OAAO,aAAa;AACxC,MAAM,kBAAkB,CAAC,MAAM,SAAS,QAAQ,cAAc;AAOvD,MAAM,aAAa,MAAM;AAAA,EAM9B,OAAO,OAAO,OAAkB;AACxB,UAAA,OAAO,MAAM,OAAO,KAAK;AACzB,UAAA,OAAO,MAAM,OAAO;AACpB,UAAA,UAAU,CAAC,OAAO,IAAI,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC;AACpD,SAAA,UAAU,IAAI,WAAW;AACzB,SAAA,aAAa,mBAAmB,OAAO;AAC5C,UAAM,UAAU;AAChB,SAAK,YAAY,GAAG,OAAO,IAAI,MAAM,KAAK,KAAK,OAAO;AACtD,UAAM,MAAM,KAAK,SAAS,MAAM,GAAG;AACnC,QAAI,KAAK;AACP,WAAK,OAAO;AACZ,WAAK,SAAS;AAAA,IAAA;AAEA,oBAAA,QAAQ,CAAC,QAAQ;AAC3B,UAAA,MAAM,GAAG,GAAG;AACd,aAAK,QAAQ,GAAG,IAAI,MAAM,GAAG;AAAA,MAAA;AAAA,IAC/B,CACD;AACM,WAAA;AAAA,EAAA;AAAA,EAGT,OAAO,MAAM,SAA4B;AAChC,WAAA,KAAK,WAAW,OAAO;AAAA,EAAA;AAAA,EAGhC,OAAO,WAAW,SAA4B;AAC5C,UAAM,UAAkC,CAAC;AACzC,UAAM,OAAO,KAAK,SAAS,QAAQ,IAAI;AACvC,QAAI,MAAM;AACR,cAAQ,MAAM;AAAA,IAAA;AAEA,oBAAA,QAAQ,CAAC,QAAQ;AAC3B,UAAA,QAAQ,QAAQ,GAAG,GAAG;AACxB,gBAAQ,GAAG,IAAI,QAAQ,QAAQ,GAAG;AAAA,MAAA;AAAA,IACpC,CACD;AACM,WAAA;AAAA,EAAA;AAAA,EAGT,OAAO,SAAS,KAAa;AAC3B,WAAQ,SAAS,KAAK,KAAK,kBAAkB,KAAK,OAAQ;AAAA,EAAA;AAE9D;AA/CE,cADW,MACJ,YAAW;AAClB,cAFW,MAEJ,WAAU;AACjB,cAHW,MAGJ,aAAY;AACnB,cAJW,MAIJ,sBAAqB,CAAC,QAAQ,SAAS,MAAM;"}
1
+ {"version":3,"file":"file.es.js","sources":["../../../../../src/modules/file/formats/file.ts"],"sourcesContent":["import type TypeEmbed from 'quill/blots/embed'\nimport Quill from 'quill'\nimport { sanitize } from '../../../config/editor.utils'\n\nconst Embed = Quill.import('blots/embed') as typeof TypeEmbed\nconst FILE_ATTRIBUTES = ['id', 'title', 'size', 'lastModified']\n\nexport interface FileValue {\n size: number\n src: string\n title: string\n}\nexport class File extends Embed {\n static blotName = 'file'\n static tagName = 'A'\n static className = 'ql-file-item'\n static PROTOCOL_WHITELIST = ['http', 'https', 'blob']\n\n static create(value: FileValue) {\n const node = super.create(value) as HTMLAnchorElement\n const size = value.size / 1024\n const fixSize = !size ? 0 : size < 1 ? 1 : size.toFixed(0)\n node.classList.add('icon-file')\n node.setAttribute('contenteditable', 'false')\n const fileSvg = '<svg viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path d=\"M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326z m1.8 562H232V136h302v216c0 23.2 18.8 42 42 42h216v494z\" p-id=\"2307\"></path></svg>'\n node.innerHTML = `${fileSvg} ${value.title} (${fixSize} KB)`\n const src = this.sanitize(value.src)\n if (src) {\n node.href = src\n node.target = '_blank'\n }\n FILE_ATTRIBUTES.forEach((key) => {\n if (value[key]) {\n node.dataset[key] = value[key]\n }\n })\n return node\n }\n\n static value(domNode: HTMLAnchorElement) {\n return this.getFormats(domNode)\n }\n\n static getFormats(domNode: HTMLAnchorElement) {\n const formats: Record<string, string> = {}\n const href = this.sanitize(domNode.href)\n if (href) {\n formats.src = href\n }\n FILE_ATTRIBUTES.forEach((key) => {\n if (domNode.dataset[key]) {\n formats[key] = domNode.dataset[key]\n }\n })\n return formats\n }\n\n static sanitize(url: string) {\n return (sanitize(url, this.PROTOCOL_WHITELIST) && url) || ''\n }\n}\n"],"names":[],"mappings":";;;;;AAIA,MAAM,QAAQ,MAAM,OAAO,aAAa;AACxC,MAAM,kBAAkB,CAAC,MAAM,SAAS,QAAQ,cAAc;AAOvD,MAAM,aAAa,MAAM;AAAA,EAM9B,OAAO,OAAO,OAAkB;AAC9B,UAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,UAAM,OAAO,MAAM,OAAO;AAC1B,UAAM,UAAU,CAAC,OAAO,IAAI,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC;AACzD,SAAK,UAAU,IAAI,WAAW;AAC9B,SAAK,aAAa,mBAAmB,OAAO;AAC5C,UAAM,UAAU;AAChB,SAAK,YAAY,GAAG,OAAO,IAAI,MAAM,KAAK,KAAK,OAAO;AACtD,UAAM,MAAM,KAAK,SAAS,MAAM,GAAG;AACnC,QAAI,KAAK;AACP,WAAK,OAAO;AACZ,WAAK,SAAS;AAAA,IAChB;AACA,oBAAgB,QAAQ,CAAC,QAAQ;AAC/B,UAAI,MAAM,GAAG,GAAG;AACd,aAAK,QAAQ,GAAG,IAAI,MAAM,GAAG;AAAA,MAC/B;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,SAA4B;AACvC,WAAO,KAAK,WAAW,OAAO;AAAA,EAChC;AAAA,EAEA,OAAO,WAAW,SAA4B;AAC5C,UAAM,UAAkC,CAAA;AACxC,UAAM,OAAO,KAAK,SAAS,QAAQ,IAAI;AACvC,QAAI,MAAM;AACR,cAAQ,MAAM;AAAA,IAChB;AACA,oBAAgB,QAAQ,CAAC,QAAQ;AAC/B,UAAI,QAAQ,QAAQ,GAAG,GAAG;AACxB,gBAAQ,GAAG,IAAI,QAAQ,QAAQ,GAAG;AAAA,MACpC;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAAS,KAAa;AAC3B,WAAQ,SAAS,KAAK,KAAK,kBAAkB,KAAK,OAAQ;AAAA,EAC5D;AACF;AA/CE,cADW,MACJ,YAAW;AAClB,cAFW,MAEJ,WAAU;AACjB,cAHW,MAGJ,aAAY;AACnB,cAJW,MAIJ,sBAAqB,CAAC,QAAQ,SAAS,MAAM;"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-bar.es.js","sources":["../../../../../src/modules/file/modules/file-bar.ts"],"sourcesContent":["import Quill from 'quill'\nimport { Range } from 'quill/core/selection'\nimport { unshiftString } from '../../../utils/method'\nimport { File } from '../formats/file'\n\nconst Delta = Quill.import('delta')\n\nexport class FileBar {\n quill: any\n file: any\n domNode: HTMLElement\n fileRange: any\n template: string\n\n constructor(quill, target) {\n this.quill = quill\n this.file = target\n const fileBlot = Quill.find(target)\n const index = this.quill.getIndex(fileBlot)\n const [fileItem, offset] = this.quill.scroll.descendant(File, index)\n const length = fileItem && fileItem.length()\n this.fileRange = new Range(index - offset, length)\n\n const timestamp = Number(this.file.dataset.lastModified)\n const _lastModifiedDate = this.formatDate(timestamp)\n this.template = [\n // `<a class=\"ql-last-modified-date\" href=\"${this.file.href}\" target=\"_blank\">${this.file.href}</a>`,\n // '<span class=\"ql-split\"></span>',\n // `<a class=\"ql-file-preview\"><i class=\"icon-preview\"></i></a>`,\n `<a class=\"ql-file-download\"><i class=\"icon-download\"></i></a>`,\n '<a class=\"ql-file-delete\"><i class=\"icon-delete\"></i></a>',\n ].join('')\n\n this.createFileBar()\n }\n\n createFileBar() {\n this.domNode = document.createElement('div')\n this.domNode.className = 'ql-file-bar'\n this.domNode.innerHTML = this.template\n // 查看文件\n const filePreview = this.domNode.querySelector('a.ql-file-preview')\n if (filePreview) {\n filePreview.addEventListener('click', (event) => {\n this.operateFile(event, 'view')\n })\n }\n // 下载文件\n const fileDownload = this.domNode.querySelector('a.ql-file-download')\n if (fileDownload) {\n fileDownload.addEventListener('click', (event) => {\n this.operateFile(event, 'download')\n })\n }\n // 删除文件\n const fileDelete = this.domNode.querySelector('a.ql-file-delete')\n if (fileDelete) {\n fileDelete.addEventListener('click', (event) => {\n this.operateFile(event, 'delete')\n const delta = new Delta()\n .retain(this.fileRange.index)\n .delete(this.fileRange.length)\n this.quill.updateContents(delta, Quill.sources.USER)\n this.quill.setSelection(this.fileRange.index)\n })\n }\n\n this.setPosition()\n this.quill.root.parentNode.appendChild(this.domNode)\n }\n\n destroy() {\n if (this.domNode) {\n this.domNode.remove()\n this.domNode = null\n this.file = null\n }\n }\n\n operateFile(event, operate) {\n event.preventDefault()\n const fileId = this.file.dataset.id || ''\n const fileName = this.file.dataset.title || ''\n const fileDownloadUrl = this.file.href || ''\n if (fileId) {\n this.quill.emitter.emit('file-change', {\n operation: operate,\n data: { fileId, fileDownloadUrl },\n })\n }\n if (operate === 'download') {\n const a = document.createElement('a')\n a.href = fileDownloadUrl\n a.target = '_blank'\n a.id = 'exppub'\n a.download = fileName\n document.body.appendChild(a)\n const alink = document.getElementById('exppub')\n alink.click()\n alink.parentNode.removeChild(a)\n }\n this.destroy()\n }\n\n setPosition() {\n if (this.domNode && this.file) {\n const parent = this.quill.root.parentNode\n const child = this.file.querySelector('span')\n const containerRect = parent.getBoundingClientRect()\n const fileRect = child.getBoundingClientRect()\n this.css(this.domNode, {\n left: `${fileRect.left - containerRect.left}px`,\n top: `${fileRect.top - containerRect.top + 10}px`,\n })\n }\n }\n\n css(domNode, rules) {\n if (typeof rules === 'object') {\n for (const prop in rules) {\n if (prop) {\n if (Array.isArray(rules[prop])) {\n // 兼容IE11浏览器\n rules[prop].forEach((val) => {\n domNode.style[prop] = val\n })\n }\n else {\n domNode.style[prop] = rules[prop]\n }\n }\n }\n }\n }\n\n formatDate(timestamp) {\n const date = new Date(timestamp)\n const year = date.getFullYear()\n // TODO\n const month = unshiftString(`${date.getMonth() + 1}`, 2, '0')\n const day = unshiftString(`${date.getDate()}`, 2, '0')\n const hour = unshiftString(`${date.getHours()}`, 2, '0')\n const minute = unshiftString(`${date.getMinutes()}`, 2, '0')\n return Number.isNaN(year) ? '--' : `${year}/${month}/${day} ${hour}:${minute}`\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-bar.es.js","sources":["../../../../../src/modules/file/modules/file-bar.ts"],"sourcesContent":["import Quill from 'quill'\nimport { Range } from 'quill/core/selection'\nimport { unshiftString } from '../../../utils/method'\nimport { File } from '../formats/file'\n\nconst Delta = Quill.import('delta')\n\nexport class FileBar {\n quill: any\n file: any\n domNode: HTMLElement\n fileRange: any\n template: string\n\n constructor(quill, target) {\n this.quill = quill\n this.file = target\n const fileBlot = Quill.find(target)\n const index = this.quill.getIndex(fileBlot)\n const [fileItem, offset] = this.quill.scroll.descendant(File, index)\n const length = fileItem && fileItem.length()\n this.fileRange = new Range(index - offset, length)\n\n const timestamp = Number(this.file.dataset.lastModified)\n const _lastModifiedDate = this.formatDate(timestamp)\n this.template = [\n // `<a class=\"ql-last-modified-date\" href=\"${this.file.href}\" target=\"_blank\">${this.file.href}</a>`,\n // '<span class=\"ql-split\"></span>',\n // `<a class=\"ql-file-preview\"><i class=\"icon-preview\"></i></a>`,\n `<a class=\"ql-file-download\"><i class=\"icon-download\"></i></a>`,\n '<a class=\"ql-file-delete\"><i class=\"icon-delete\"></i></a>',\n ].join('')\n\n this.createFileBar()\n }\n\n createFileBar() {\n this.domNode = document.createElement('div')\n this.domNode.className = 'ql-file-bar'\n this.domNode.innerHTML = this.template\n // 查看文件\n const filePreview = this.domNode.querySelector('a.ql-file-preview')\n if (filePreview) {\n filePreview.addEventListener('click', (event) => {\n this.operateFile(event, 'view')\n })\n }\n // 下载文件\n const fileDownload = this.domNode.querySelector('a.ql-file-download')\n if (fileDownload) {\n fileDownload.addEventListener('click', (event) => {\n this.operateFile(event, 'download')\n })\n }\n // 删除文件\n const fileDelete = this.domNode.querySelector('a.ql-file-delete')\n if (fileDelete) {\n fileDelete.addEventListener('click', (event) => {\n this.operateFile(event, 'delete')\n const delta = new Delta()\n .retain(this.fileRange.index)\n .delete(this.fileRange.length)\n this.quill.updateContents(delta, Quill.sources.USER)\n this.quill.setSelection(this.fileRange.index)\n })\n }\n\n this.setPosition()\n this.quill.root.parentNode.appendChild(this.domNode)\n }\n\n destroy() {\n if (this.domNode) {\n this.domNode.remove()\n this.domNode = null\n this.file = null\n }\n }\n\n operateFile(event, operate) {\n event.preventDefault()\n const fileId = this.file.dataset.id || ''\n const fileName = this.file.dataset.title || ''\n const fileDownloadUrl = this.file.href || ''\n if (fileId) {\n this.quill.emitter.emit('file-change', {\n operation: operate,\n data: { fileId, fileDownloadUrl },\n })\n }\n if (operate === 'download') {\n const a = document.createElement('a')\n a.href = fileDownloadUrl\n a.target = '_blank'\n a.id = 'exppub'\n a.download = fileName\n document.body.appendChild(a)\n const alink = document.getElementById('exppub')\n alink.click()\n alink.parentNode.removeChild(a)\n }\n this.destroy()\n }\n\n setPosition() {\n if (this.domNode && this.file) {\n const parent = this.quill.root.parentNode\n const child = this.file.querySelector('span')\n const containerRect = parent.getBoundingClientRect()\n const fileRect = child.getBoundingClientRect()\n this.css(this.domNode, {\n left: `${fileRect.left - containerRect.left}px`,\n top: `${fileRect.top - containerRect.top + 10}px`,\n })\n }\n }\n\n css(domNode, rules) {\n if (typeof rules === 'object') {\n for (const prop in rules) {\n if (prop) {\n if (Array.isArray(rules[prop])) {\n // 兼容IE11浏览器\n rules[prop].forEach((val) => {\n domNode.style[prop] = val\n })\n }\n else {\n domNode.style[prop] = rules[prop]\n }\n }\n }\n }\n }\n\n formatDate(timestamp) {\n const date = new Date(timestamp)\n const year = date.getFullYear()\n // TODO\n const month = unshiftString(`${date.getMonth() + 1}`, 2, '0')\n const day = unshiftString(`${date.getDate()}`, 2, '0')\n const hour = unshiftString(`${date.getHours()}`, 2, '0')\n const minute = unshiftString(`${date.getMinutes()}`, 2, '0')\n return Number.isNaN(year) ? '--' : `${year}/${month}/${day} ${hour}:${minute}`\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-module.es.js","sources":["../../../../../src/modules/file/modules/file-module.ts"],"sourcesContent":["import type FluentEditor from '../../../core/fluent-editor'\nimport Quill from 'quill'\nimport { File } from '../formats/file'\nimport { FileBar } from './file-bar'\n\nexport class FileModule {\n fileBar: FileBar\n\n static register() {\n Quill.register('formats/file', File, true)\n }\n\n constructor(public quill: FluentEditor) {\n this.quill = quill\n quill.root.addEventListener('click', event => this.clickEvent(event), false)\n }\n\n clickEvent(event: MouseEvent) {\n event.preventDefault()\n const target = event.target as HTMLElement\n const fileDom = target.closest('a.ql-file-item')\n if (fileDom) {\n if (this.fileBar) {\n this.fileBar.destroy()\n }\n this.fileBar = new FileBar(this.quill, fileDom)\n }\n else if (this.fileBar && !target.closest('.ql-file-bar')) {\n this.fileBar.destroy()\n this.fileBar = null\n }\n }\n}\n"],"names":[],"mappings":";;;;;;AAKO,MAAM,WAAW;AAAA,EAOtB,YAAmB,OAAqB;AANxC;AAMmB,SAAA,QAAA;AACjB,SAAK,QAAQ;AACP,UAAA,KAAK,iBAAiB,SAAS,CAAA,UAAS,KAAK,WAAW,KAAK,GAAG,KAAK;AAAA,EAAA;AAAA,EAN7E,OAAO,WAAW;AACV,UAAA,SAAS,gBAAgB,MAAM,IAAI;AAAA,EAAA;AAAA,EAQ3C,WAAW,OAAmB;AAC5B,UAAM,eAAe;AACrB,UAAM,SAAS,MAAM;AACf,UAAA,UAAU,OAAO,QAAQ,gBAAgB;AAC/C,QAAI,SAAS;AACX,UAAI,KAAK,SAAS;AAChB,aAAK,QAAQ,QAAQ;AAAA,MAAA;AAEvB,WAAK,UAAU,IAAI,QAAQ,KAAK,OAAO,OAAO;AAAA,IAAA,WAEvC,KAAK,WAAW,CAAC,OAAO,QAAQ,cAAc,GAAG;AACxD,WAAK,QAAQ,QAAQ;AACrB,WAAK,UAAU;AAAA,IAAA;AAAA,EACjB;AAEJ;"}
1
+ {"version":3,"file":"file-module.es.js","sources":["../../../../../src/modules/file/modules/file-module.ts"],"sourcesContent":["import type FluentEditor from '../../../core/fluent-editor'\nimport Quill from 'quill'\nimport { File } from '../formats/file'\nimport { FileBar } from './file-bar'\n\nexport class FileModule {\n fileBar: FileBar\n\n static register() {\n Quill.register('formats/file', File, true)\n }\n\n constructor(public quill: FluentEditor) {\n this.quill = quill\n quill.root.addEventListener('click', event => this.clickEvent(event), false)\n }\n\n clickEvent(event: MouseEvent) {\n event.preventDefault()\n const target = event.target as HTMLElement\n const fileDom = target.closest('a.ql-file-item')\n if (fileDom) {\n if (this.fileBar) {\n this.fileBar.destroy()\n }\n this.fileBar = new FileBar(this.quill, fileDom)\n }\n else if (this.fileBar && !target.closest('.ql-file-bar')) {\n this.fileBar.destroy()\n this.fileBar = null\n }\n }\n}\n"],"names":[],"mappings":";;;;;;AAKO,MAAM,WAAW;AAAA,EAOtB,YAAmB,OAAqB;AANxC;AAMmB,SAAA,QAAA;AACjB,SAAK,QAAQ;AACb,UAAM,KAAK,iBAAiB,SAAS,CAAA,UAAS,KAAK,WAAW,KAAK,GAAG,KAAK;AAAA,EAC7E;AAAA,EAPA,OAAO,WAAW;AAChB,UAAM,SAAS,gBAAgB,MAAM,IAAI;AAAA,EAC3C;AAAA,EAOA,WAAW,OAAmB;AAC5B,UAAM,eAAA;AACN,UAAM,SAAS,MAAM;AACrB,UAAM,UAAU,OAAO,QAAQ,gBAAgB;AAC/C,QAAI,SAAS;AACX,UAAI,KAAK,SAAS;AAChB,aAAK,QAAQ,QAAA;AAAA,MACf;AACA,WAAK,UAAU,IAAI,QAAQ,KAAK,OAAO,OAAO;AAAA,IAChD,WACS,KAAK,WAAW,CAAC,OAAO,QAAQ,cAAc,GAAG;AACxD,WAAK,QAAQ,QAAA;AACb,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AACF;"}
@@ -0,0 +1,102 @@
1
+ function getGridConfig(quill) {
2
+ var _a, _b, _c;
3
+ const defaultGrid = {
4
+ size: 20,
5
+ visible: true,
6
+ type: "dot",
7
+ config: {
8
+ color: "#ababab",
9
+ thickness: 1
10
+ }
11
+ };
12
+ const flowChartModule = (_a = quill == null ? void 0 : quill.options.modules) == null ? void 0 : _a["flow-chart"];
13
+ if (!flowChartModule || typeof flowChartModule !== "object") {
14
+ return defaultGrid;
15
+ }
16
+ if ("grid" in flowChartModule) {
17
+ const grid = flowChartModule.grid;
18
+ if (grid === false || grid === void 0) {
19
+ return null;
20
+ }
21
+ if (typeof grid === "object" && grid !== null) {
22
+ const typedGrid = grid;
23
+ const gridConfig = {
24
+ size: typedGrid.size || defaultGrid.size,
25
+ visible: typedGrid.visible !== void 0 ? typedGrid.visible : defaultGrid.visible,
26
+ type: typedGrid.type || defaultGrid.type,
27
+ config: {
28
+ color: ((_b = typedGrid.config) == null ? void 0 : _b.color) || defaultGrid.config.color,
29
+ thickness: ((_c = typedGrid.config) == null ? void 0 : _c.thickness) || defaultGrid.config.thickness
30
+ }
31
+ };
32
+ return gridConfig;
33
+ }
34
+ }
35
+ return defaultGrid;
36
+ }
37
+ function getBackgroundConfig(quill) {
38
+ var _a;
39
+ const flowChartModule = (_a = quill == null ? void 0 : quill.options.modules) == null ? void 0 : _a["flow-chart"];
40
+ if (!flowChartModule || typeof flowChartModule !== "object") {
41
+ return false;
42
+ }
43
+ if ("background" in flowChartModule) {
44
+ const background = flowChartModule.background;
45
+ if (background === false || background === void 0) {
46
+ return false;
47
+ }
48
+ if (typeof background === "object" && background !== null) {
49
+ const typedBackground = background;
50
+ const backgroundConfig = {};
51
+ if (typedBackground.color) {
52
+ backgroundConfig.backgroundColor = typedBackground.color;
53
+ }
54
+ if (typedBackground.image) {
55
+ backgroundConfig.backgroundImage = typedBackground.image;
56
+ }
57
+ if (typedBackground.repeat) {
58
+ backgroundConfig.backgroundRepeat = typedBackground.repeat;
59
+ }
60
+ if (typedBackground.position) {
61
+ backgroundConfig.backgroundPosition = typedBackground.position;
62
+ }
63
+ if (typedBackground.size) {
64
+ backgroundConfig.backgroundSize = typedBackground.size;
65
+ }
66
+ if (typedBackground.opacity) {
67
+ backgroundConfig.opacity = typedBackground.opacity;
68
+ }
69
+ return backgroundConfig;
70
+ }
71
+ }
72
+ return false;
73
+ }
74
+ function getResizeConfig(quill) {
75
+ var _a;
76
+ const flowChartModule = (_a = quill == null ? void 0 : quill.options.modules) == null ? void 0 : _a["flow-chart"];
77
+ if (!flowChartModule || typeof flowChartModule !== "object") {
78
+ return false;
79
+ }
80
+ if ("resize" in flowChartModule) {
81
+ const resize = flowChartModule.resize;
82
+ return resize === true;
83
+ }
84
+ return false;
85
+ }
86
+ function getAllConfigs(quill) {
87
+ var _a, _b;
88
+ const deps = (_b = (_a = quill == null ? void 0 : quill.options.modules) == null ? void 0 : _a["flow-chart"]) == null ? void 0 : _b.deps;
89
+ return {
90
+ gridConfig: getGridConfig(quill),
91
+ backgroundConfig: getBackgroundConfig(quill),
92
+ resizeConfig: getResizeConfig(quill),
93
+ deps
94
+ };
95
+ }
96
+ export {
97
+ getAllConfigs,
98
+ getBackgroundConfig,
99
+ getGridConfig,
100
+ getResizeConfig
101
+ };
102
+ //# sourceMappingURL=config-utils.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-utils.es.js","sources":["../../../../src/modules/flow-chart/config-utils.ts"],"sourcesContent":["import type Quill from 'quill'\nimport type { BackgroundConfig, GridOptions } from './options'\n\nexport function getGridConfig(quill: Quill | null): any {\n const defaultGrid = {\n size: 20,\n visible: true,\n type: 'dot',\n config: {\n color: '#ababab',\n thickness: 1,\n },\n }\n\n const flowChartModule = quill?.options.modules?.['flow-chart']\n if (!flowChartModule || typeof flowChartModule !== 'object') {\n return defaultGrid\n }\n\n if ('grid' in flowChartModule) {\n const grid = flowChartModule.grid as GridOptions | boolean | undefined\n if (grid === false || grid === undefined) {\n return null\n }\n\n if (typeof grid === 'object' && grid !== null) {\n const typedGrid = grid as GridOptions\n const gridConfig = {\n size: typedGrid.size || defaultGrid.size,\n visible: typedGrid.visible !== undefined ? typedGrid.visible : defaultGrid.visible,\n type: typedGrid.type || defaultGrid.type,\n config: {\n color: typedGrid.config?.color || defaultGrid.config.color,\n thickness: typedGrid.config?.thickness || defaultGrid.config.thickness,\n },\n }\n\n return gridConfig\n }\n }\n\n return defaultGrid\n}\n\nexport function getBackgroundConfig(quill: Quill | null): false | object {\n const flowChartModule = quill?.options.modules?.['flow-chart']\n if (!flowChartModule || typeof flowChartModule !== 'object') {\n return false\n }\n if ('background' in flowChartModule) {\n const background = flowChartModule.background as BackgroundConfig | boolean | undefined\n\n if (background === false || background === undefined) {\n return false\n }\n if (typeof background === 'object' && background !== null) {\n const typedBackground = background as BackgroundConfig\n const backgroundConfig: any = {}\n\n if (typedBackground.color) {\n backgroundConfig.backgroundColor = typedBackground.color\n }\n if (typedBackground.image) {\n backgroundConfig.backgroundImage = typedBackground.image\n }\n if (typedBackground.repeat) {\n backgroundConfig.backgroundRepeat = typedBackground.repeat\n }\n if (typedBackground.position) {\n backgroundConfig.backgroundPosition = typedBackground.position\n }\n if (typedBackground.size) {\n backgroundConfig.backgroundSize = typedBackground.size\n }\n if (typedBackground.opacity) {\n backgroundConfig.opacity = typedBackground.opacity\n }\n return backgroundConfig\n }\n }\n return false\n}\n\nexport function getResizeConfig(quill: Quill | null): boolean {\n const flowChartModule = quill?.options.modules?.['flow-chart']\n if (!flowChartModule || typeof flowChartModule !== 'object') {\n return false\n }\n if ('resize' in flowChartModule) {\n const resize = (flowChartModule as any).resize as boolean | undefined\n return resize === true\n }\n return false\n}\n\nexport function getAllConfigs(quill: Quill | null): {\n gridConfig: any\n backgroundConfig: false | object\n resizeConfig: boolean\n deps?: any\n} {\n const deps = (quill?.options.modules?.['flow-chart'] as any)?.deps\n return {\n gridConfig: getGridConfig(quill),\n backgroundConfig: getBackgroundConfig(quill),\n resizeConfig: getResizeConfig(quill),\n deps,\n }\n}\n"],"names":[],"mappings":"AAGO,SAAS,cAAc,OAA0B;AAAjD;AACL,QAAM,cAAc;AAAA,IAClB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,EACb;AAGF,QAAM,mBAAkB,oCAAO,QAAQ,YAAf,mBAAyB;AACjD,MAAI,CAAC,mBAAmB,OAAO,oBAAoB,UAAU;AAC3D,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,iBAAiB;AAC7B,UAAM,OAAO,gBAAgB;AAC7B,QAAI,SAAS,SAAS,SAAS,QAAW;AACxC,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,YAAM,YAAY;AAClB,YAAM,aAAa;AAAA,QACjB,MAAM,UAAU,QAAQ,YAAY;AAAA,QACpC,SAAS,UAAU,YAAY,SAAY,UAAU,UAAU,YAAY;AAAA,QAC3E,MAAM,UAAU,QAAQ,YAAY;AAAA,QACpC,QAAQ;AAAA,UACN,SAAO,eAAU,WAAV,mBAAkB,UAAS,YAAY,OAAO;AAAA,UACrD,aAAW,eAAU,WAAV,mBAAkB,cAAa,YAAY,OAAO;AAAA,QAAA;AAAA,MAC/D;AAGF,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,oBAAoB,OAAqC;AAzClE;AA0CL,QAAM,mBAAkB,oCAAO,QAAQ,YAAf,mBAAyB;AACjD,MAAI,CAAC,mBAAmB,OAAO,oBAAoB,UAAU;AAC3D,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,iBAAiB;AACnC,UAAM,aAAa,gBAAgB;AAEnC,QAAI,eAAe,SAAS,eAAe,QAAW;AACpD,aAAO;AAAA,IACT;AACA,QAAI,OAAO,eAAe,YAAY,eAAe,MAAM;AACzD,YAAM,kBAAkB;AACxB,YAAM,mBAAwB,CAAA;AAE9B,UAAI,gBAAgB,OAAO;AACzB,yBAAiB,kBAAkB,gBAAgB;AAAA,MACrD;AACA,UAAI,gBAAgB,OAAO;AACzB,yBAAiB,kBAAkB,gBAAgB;AAAA,MACrD;AACA,UAAI,gBAAgB,QAAQ;AAC1B,yBAAiB,mBAAmB,gBAAgB;AAAA,MACtD;AACA,UAAI,gBAAgB,UAAU;AAC5B,yBAAiB,qBAAqB,gBAAgB;AAAA,MACxD;AACA,UAAI,gBAAgB,MAAM;AACxB,yBAAiB,iBAAiB,gBAAgB;AAAA,MACpD;AACA,UAAI,gBAAgB,SAAS;AAC3B,yBAAiB,UAAU,gBAAgB;AAAA,MAC7C;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,OAA8B;AAhFvD;AAiFL,QAAM,mBAAkB,oCAAO,QAAQ,YAAf,mBAAyB;AACjD,MAAI,CAAC,mBAAmB,OAAO,oBAAoB,UAAU;AAC3D,WAAO;AAAA,EACT;AACA,MAAI,YAAY,iBAAiB;AAC/B,UAAM,SAAU,gBAAwB;AACxC,WAAO,WAAW;AAAA,EACpB;AACA,SAAO;AACT;AAEO,SAAS,cAAc,OAK5B;AAjGK;AAkGL,QAAM,QAAQ,0CAAO,QAAQ,YAAf,mBAAyB,kBAAzB,mBAAgD;AAC9D,SAAO;AAAA,IACL,YAAY,cAAc,KAAK;AAAA,IAC/B,kBAAkB,oBAAoB,KAAK;AAAA,IAC3C,cAAc,gBAAgB,KAAK;AAAA,IACnC;AAAA,EAAA;AAEJ;"}