@chenyomi/leafer-htmltext-editor 1.0.7 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/index.cjs +4 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.mts +64 -0
  4. package/dist/index.d.ts +51 -6
  5. package/dist/index.mjs +4 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +16 -8
  8. package/dist/TextEditTool/index.d.ts +0 -17
  9. package/dist/TextEditTool/index.d.ts.map +0 -1
  10. package/dist/TextEditTool/index.js +0 -113
  11. package/dist/TextEditTool/utils.d.ts +0 -8
  12. package/dist/TextEditTool/utils.d.ts.map +0 -1
  13. package/dist/TextEditTool/utils.js +0 -256
  14. package/dist/TextEditor.d.ts +0 -30
  15. package/dist/TextEditor.d.ts.map +0 -1
  16. package/dist/TextEditor.js +0 -169
  17. package/dist/esm/TextEditTool/index.d.ts +0 -17
  18. package/dist/esm/TextEditTool/index.d.ts.map +0 -1
  19. package/dist/esm/TextEditTool/index.js +0 -110
  20. package/dist/esm/TextEditTool/utils.d.ts +0 -8
  21. package/dist/esm/TextEditTool/utils.d.ts.map +0 -1
  22. package/dist/esm/TextEditTool/utils.js +0 -248
  23. package/dist/esm/TextEditor.d.ts +0 -30
  24. package/dist/esm/TextEditor.d.ts.map +0 -1
  25. package/dist/esm/TextEditor.js +0 -166
  26. package/dist/esm/fonts/font.d.ts +0 -17
  27. package/dist/esm/fonts/font.d.ts.map +0 -1
  28. package/dist/esm/fonts/font.js +0 -68
  29. package/dist/esm/fonts/utils.d.ts +0 -9
  30. package/dist/esm/fonts/utils.d.ts.map +0 -1
  31. package/dist/esm/fonts/utils.js +0 -170
  32. package/dist/esm/index.d.ts +0 -19
  33. package/dist/esm/index.d.ts.map +0 -1
  34. package/dist/esm/utils.d.ts +0 -3
  35. package/dist/esm/utils.d.ts.map +0 -1
  36. package/dist/esm/utils.js +0 -266
  37. package/dist/fonts/font.d.ts +0 -17
  38. package/dist/fonts/font.d.ts.map +0 -1
  39. package/dist/fonts/font.js +0 -72
  40. package/dist/fonts/utils.d.ts +0 -9
  41. package/dist/fonts/utils.d.ts.map +0 -1
  42. package/dist/fonts/utils.js +0 -180
  43. package/dist/index.d.ts.map +0 -1
  44. package/dist/index.esm.js +0 -141
  45. package/dist/index.js +0 -179
  46. package/dist/utils.d.ts +0 -3
  47. package/dist/utils.d.ts.map +0 -1
  48. package/dist/utils.js +0 -271
  49. package/src/TextEditTool/index.ts +0 -132
  50. package/src/TextEditTool/utils.ts +0 -288
  51. package/src/TextEditor.ts +0 -213
  52. package/src/fonts/font.ts +0 -86
  53. package/src/fonts/utils.ts +0 -232
  54. package/src/htmltext-editor.css +0 -103
  55. package/src/index.ts +0 -163
  56. package/src/utils.ts +0 -294
package/src/index.ts DELETED
@@ -1,163 +0,0 @@
1
- import Quill, { Delta } from "quill";
2
- import "quill/dist/quill.core.css";
3
-
4
- export { TextEditTool } from "./TextEditTool";
5
- export { TextEditor } from "./TextEditor";
6
- class QuillManager {
7
- private static instance: QuillManager;
8
- private quill: Quill | null = null;
9
- public app_: any | null = null;
10
-
11
- private constructor() {}
12
-
13
- static getInstance() {
14
- if (!QuillManager.instance) {
15
- QuillManager.instance = new QuillManager();
16
- }
17
- return QuillManager.instance;
18
- }
19
-
20
- async init(app: any) {
21
- this.app_ = app;
22
- if (this.quill) return this.quill;
23
-
24
- let el = document.getElementById("textInnerEditor");
25
- if (!el) {
26
- el = document.createElement("div");
27
- el.id = "textInnerEditor";
28
- el.style.position = "fixed";
29
- el.style.transformOrigin = "left top";
30
- el.style.overflowWrap = "break-word";
31
- el.style.wordBreak = "break-all";
32
- el.style.visibility = "hidden";
33
- document.body.appendChild(el);
34
- this.quill = new Quill("#textInnerEditor", {
35
- theme: undefined,
36
- modules: {
37
- toolbar: false,
38
- keyboard: {
39
- bindings: {
40
- enter: {
41
- key: "Enter",
42
- handler: (range: any) => {
43
- const [line] = this.quill!.getLine(range.index);
44
- const BlockBlot: any = Quill.import("blots/block");
45
- if (!BlockBlot?.bubbleFormats) return true;
46
-
47
- const lineFormats = BlockBlot.bubbleFormats(line);
48
- const delta = new Delta()
49
- .retain(range.index)
50
- .delete(range.length)
51
- .insert("\n", lineFormats);
52
-
53
- this.quill!.updateContents(delta, Quill.sources.USER);
54
- this.quill!.setSelection(
55
- range.index + 1,
56
- Quill.sources.SILENT,
57
- );
58
- return false;
59
- },
60
- },
61
- },
62
- },
63
- },
64
- });
65
- this.app_.editor.quill = this.quill;
66
- this.registerFonts();
67
- return this.quill;
68
- } else {
69
- this.quill = this.app_.editor.quill
70
-
71
- }
72
-
73
-
74
- }
75
-
76
- getQuill() {
77
- if (!this.quill) {
78
- throw new Error("Quill editor not initialized. Call init() first.");
79
- }
80
- return this.quill;
81
- }
82
-
83
- getCanvas() {
84
- if (!this.app_) {
85
- throw new Error("app_ editor not initialized. Call init() first.");
86
- }
87
- return this.app_;
88
- }
89
-
90
- private registerFonts() {
91
- const FontAttributor: any = Quill.import("attributors/class/font");
92
- FontAttributor.whitelist = [
93
- "Roboto",
94
- "RobotoMono",
95
- "Inter",
96
- "OpenSans",
97
- "Montserrat",
98
- "RobotoCondensed",
99
- "Arimo",
100
- "NotoSans",
101
- "NotoSansSymbols",
102
- "Merriweather",
103
- "PlayfairDisplay",
104
- "NotoSerif",
105
- "Lato",
106
- "Spectral",
107
- "DancingScript",
108
- "NotoSansSimplifiedChinese",
109
- "NotoSerifSimplifiedChinese",
110
- "NotoSansTraditionalChinese",
111
- "NotoSansHongKong",
112
- "NotoSerifTraditionalChinese",
113
- "NotoSerifHongKong",
114
- "NotoSansJapanese",
115
- "NotoSansKorean",
116
- "Poppins",
117
- ];
118
- Quill.register(FontAttributor, true);
119
- }
120
- // 判断是否是多选情况下
121
- public isMultiSelect(): boolean {
122
- if (!this.app_.editor) return false;
123
- if (this.app_.editor.multiple === true) {
124
- return true;
125
- } else {
126
- return false;
127
- }
128
- }
129
- public dateEdit(
130
- callback: (leaf: any) => void,
131
- level = 0,
132
- listNew?: any,
133
- ): void {
134
- // 添加listNew支持,用来指定检索的数据源,防止因为防抖或者延迟执行造成的活跃对象变更
135
- const { editor } = this.app_;
136
- const list = listNew ? listNew : editor.leafList.list;
137
- // if (this.activeObject.value?.tag === 'Frame') {
138
- // callback(this.contentFrame)
139
- // }
140
- const applyCallback = (leaf: any) => {
141
- if (level && (leaf.tag === "Box" || leaf.name === "Text")) {
142
- callback(leaf.children?.[0] || leaf);
143
- } else {
144
- callback(leaf);
145
- }
146
- };
147
- if (!list.length) return;
148
- if (Array.isArray(list) && list.length > 1) {
149
- this.app_.lockLayout();
150
- list.forEach(applyCallback);
151
- this.app_.unlockLayout();
152
- editor.updateEditBox();
153
- } else {
154
- applyCallback(list[0]);
155
- }
156
- // 不知道为啥 加这个忘记了 先保留
157
- // else if (this.activeObject.value?.tag !== 'Frame') {
158
- // applyCallback(this.activeObject.value)
159
- // }
160
- }
161
- }
162
-
163
- export const quillManager = QuillManager.getInstance();
package/src/utils.ts DELETED
@@ -1,294 +0,0 @@
1
- import { quillManager } from '.'
2
- // 更新text样式
3
- export const updataHtmlText = async (e?: any, base64font?: any, fontObj?: any) => {
4
- const { scaleX, scaleY } = e.worldTransform
5
- const zoomScale = Math.max(Math.abs(scaleX), Math.abs(scaleY))
6
- const dom: any = document.querySelector('#textInnerEditor')
7
- if (dom && e.data.textData?.fontFamily) {
8
- dom.style.fontFamily = e.data.textData.fontFamily
9
- }
10
- if (dom && e.data.textData?.fontSize) {
11
- dom.style.fontSize = `${e.data.textData.fontSize * zoomScale}px`
12
- }
13
- if (dom && e.data.textData?.lineHeight) {
14
- dom.style.lineHeight = e.data.textData.lineHeight
15
- }
16
- if (dom && e.data.textData?.letterSpacing) {
17
- dom.style.letterSpacing = `${e.data.textData.letterSpacing}px`
18
- }
19
- if (dom && e.data.textData?.textShadow) {
20
- dom.style.textShadow = e.data.textData.textShadow
21
- } else {
22
- dom.style.textShadow = 'none'
23
- }
24
- if (dom && e.data.textData?.alignContent) {
25
- const qlEditor: any = dom.querySelector('.ql-editor')
26
- qlEditor.style.alignContent = e.data.textData.alignContent
27
- }
28
- // 如果是空的就把text滞空
29
- const quill = quillManager.getQuill()
30
- const html = quill.getSemanticHTML()
31
- if (html === '<p></p>') {
32
- if (e.text.includes('<style>@font-face')) {
33
- e.text = e.text.split('</style>')[0] + '</style>'
34
- } else {
35
- e.text = ''
36
- }
37
- return
38
- }
39
- if (e.text.includes('<style>@font-face')) {
40
- // text已经加载过字体
41
- const style = e.text.split('</style>')[0]
42
- if (fontObj && !style.includes(fontObj.code)) {
43
- // 在字体style标签检索是否有当前字体 没有就添加字体style
44
- const addStyle = `@font-face {font-family: ${fontObj.code};src: url(${base64font}) format('woff2') } .ql-font-${fontObj?.code?.replace(/\s+/g, '')} {font-family: ${fontObj.name};}`
45
- e.text =
46
- style +
47
- addStyle +
48
- '</style>' +
49
- addFontSizeToP(
50
- e,
51
- html,
52
- e.data.textData.fontSize,
53
- e.data.textData.lineHeight,
54
- e.data.textData.letterSpacing,
55
- e.data.textData.textShadow,
56
- e.data.textData?.alignContent
57
- )
58
- } else {
59
- // 样式当前字体已经存在
60
- e.text =
61
- style +
62
- '</style>' +
63
- addFontSizeToP(
64
- e,
65
- html,
66
- e.data.textData.fontSize,
67
- e.data.textData.lineHeight,
68
- e.data.textData.letterSpacing,
69
- e.data.textData.textShadow,
70
- e.data.textData?.alignContent
71
- )
72
- }
73
- } else if (base64font && fontObj) {
74
- // 未加载过字体初次添加字体 存在base64font && fontObj才触发
75
- const style = `<style>@font-face {font-family: ${e.data.textData.fontFamily.split(',')[0]};src: url(${base64font}) format('woff2') } .ql-font-${fontObj?.code?.replace(/\s+/g, '')} {font-family: ${fontObj.name};}</style>`
76
- e.text =
77
- style +
78
- addFontSizeToP(
79
- e,
80
- html,
81
- e.data.textData.fontSize,
82
- e.data.textData.lineHeight,
83
- e.data.textData.letterSpacing,
84
- e.data.textData.textShadow,
85
- e.data.textData?.alignContent
86
- )
87
- } else {
88
- // text没有包含字体就不加字体style
89
- e.text = addFontSizeToP(
90
- e,
91
- html,
92
- e.data.textData.fontSize,
93
- e.data.textData.lineHeight,
94
- e.data.textData.letterSpacing,
95
- e.data.textData.textShadow,
96
- e.data.textData?.alignContent
97
- )
98
- }
99
- }
100
- const addFontSizeToP = (e: any, html: any, fontSize = 16, lineHeight = '1.5', letterSpacing = '0', textShadow = 'none', alignContent = 'start') => {
101
- const { scaleX, scaleY } = e.worldTransform
102
- const zoomScale = Math.max(Math.abs(scaleX), Math.abs(scaleY))
103
- const wrapper = document.createElement('div')
104
- wrapper.innerHTML = html
105
- // 添加的样式 用于HTMLText渲染
106
- const wrapperStyle: any = {
107
- fontSize: `${fontSize}px`,
108
- lineHeight,
109
- letterSpacing: `${letterSpacing}px`,
110
- textShadow
111
- }
112
- wrapper.querySelectorAll('p,ol,ul').forEach((p: any) => {
113
- Object.assign(p.style, wrapperStyle)
114
- })
115
-
116
- // 这个上下标还是要控制一下尺寸 因为html和canvas规范不一样 所以这里要控制一下 当然如果存在别的style例如color的style就合并style
117
- let str = wrapper.innerHTML
118
- // 排查如果有回车换行的加上一个字符
119
- if (/<p\b[^>]*><\/p>/.test(str)) {
120
- str = str.replace(/<p\b([^>]*)><\/p>/g, '<p$1>&nbsp;</p>')
121
- }
122
- let height
123
- const div: any = document.querySelector('#textInnerEditor')
124
- const quill = quillManager.getQuill()
125
- // 这里别动
126
- // 获取包含自动换行的实际内容高度
127
- const actualHeight = Number((quill.scroll.domNode.scrollHeight / zoomScale).toFixed(0))
128
- const actualWidth = Number((quill.scroll.domNode.scrollWidth / zoomScale).toFixed(0))
129
- if (['center', 'end'].includes(e.data.textData.alignContent)) {
130
- if (e.parent.height < actualHeight) {
131
- e.data.textData.alignContent = 'start'
132
- height = (actualHeight || e.__layout.boxBounds.height) + 'px'
133
- } else {
134
- height = `${e.parent.height}px`
135
- }
136
- } else {
137
- if (e.parent.height < actualHeight) {
138
- height = (actualHeight || e.__layout.boxBounds.height) + 'px'
139
- } else {
140
- height = `${e.parent.height}px`
141
- }
142
- }
143
-
144
- // 水平居中相关样式内嵌 因为这个quill居中用的class没用style
145
- const style = `<style>sub,sup{font-size:63%;}.ql-ui{position:absolute}ol,ul{counter-reset:list-0;padding-left:1.5em;margin:0}ol>li,ul>li{counter-increment:list-0;list-style-type:none;position:relative;padding-left:0;margin:0}ol>li::before{content:counter(list-0,decimal) '. ';position:absolute;left:-1.5em;width:1.2em;text-align:right}ul>li::before{content:'\u2022';position:absolute;left:-1.5em;width:1.2em;text-align:right}li[data-list]{counter-set:list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}.ql-align-center{text-align:center}.ql-align-right{text-align:right}.ql-align-left{text-align:left}.ql-align-justify{text-align:justify}</style>`
146
- let divBox = ''
147
- if (e.parent.children[0].tag.includes('Shape')) {
148
- divBox =
149
- style +
150
- `<div style="width: ${e.parent.width}px;height: ${e.parent.height}px;overflow-wrap:break-word;word-break:break-all;align-content:center;">${str}</div>`
151
- } else if (e.data.canChangeBox) {
152
- divBox =
153
- style +
154
- `<div style="width: ${e.parent.width}px;height:${height};overflow-wrap:break-word;word-break:break-all;align-content:${alignContent};">${str}</div>`
155
- } else {
156
- // 斜体补偿宽度 控制
157
- if (e.data.textData.italic) {
158
- divBox = style + str
159
- } else {
160
- console.log(actualHeight)
161
- divBox = style + `<div style="width: ${actualWidth - 10}px;">${str}</div>`
162
- }
163
- }
164
- console.log(divBox, '最终的html内容')
165
- return divBox
166
- }
167
- export const setHTMLText = (key: string, value?: any, base64font?: any) => {
168
- const quill = quillManager.getQuill()
169
- const { editor, canvas } = quillManager.getCanvas()
170
- console.log(editor, quillManager.getCanvas(), 'editor')
171
- if (!quill) {
172
- return
173
- }
174
- const range = JSON.parse(localStorage.getItem('selection-change') || '{}')
175
-
176
- quillManager.dateEdit(async (e: any) => {
177
- if (key === 'font') {
178
- const fontSimpleName = value.code.replace(/\s+/g, '')
179
- if (editor.innerEditing) {
180
- if (range && range.length) {
181
- quill.formatText(range.index, range.length, key, fontSimpleName)
182
- } else {
183
- quill.formatText(0, quill.getLength() - 1, key, fontSimpleName)
184
- }
185
- updataHtmlText(e, base64font ?? null, value ?? null)
186
- } else {
187
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
188
- quill.formatText(0, quill.getLength() - 1, key, fontSimpleName)
189
- updataHtmlText(e, base64font ?? null, value ?? null)
190
- }
191
- } else if (key === 'fontSize') {
192
- // 字体和字号
193
- e.data.textData[key] = value
194
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
195
- updataHtmlText(e, base64font ?? null)
196
- } else if (key === 'textCase') {
197
- // 大小写
198
- if (editor.innerEditing) {
199
- const text = quill.getText(range.index, range.length)
200
- const formats = quill.getFormat(range.index, range.length)
201
- quill.deleteText(range.index, range.length)
202
- let convertedText
203
- if (text === text.toUpperCase() && /[A-Z]/.test(text)) {
204
- convertedText = text.toLowerCase()
205
- } else if (text === text.toLowerCase() && /[a-z]/.test(text)) {
206
- convertedText = text.toUpperCase()
207
- } else {
208
- convertedText = text.toUpperCase()
209
- }
210
-
211
- quill.insertText(range.index, convertedText, formats)
212
- range && editor.innerEditing && quill.setSelection(range.index, range.length)
213
- }
214
- } else if (key === 'script') {
215
- // 上下标
216
- let val = 'sub'
217
- if (value === 'super') val = 'sup'
218
- if (editor.innerEditing) {
219
- if (range && range.length) {
220
- quill.formatText(range.index, range.length, key, quill.getFormat(range).script === value ? false : val)
221
- } else {
222
- quill.formatText(0, quill.getLength() - 1, key, quill.getFormat().script === value ? false : val)
223
- }
224
- } else {
225
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
226
- quill.formatText(0, quill.getLength() - 1, key, quill.getFormat().script === value ? false : val)
227
- updataHtmlText(e)
228
- }
229
- } else if (key === 'align') {
230
- // 水平居中
231
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
232
- if (editor.innerEditing) {
233
- quill.format(key, value)
234
- } else {
235
- quill.formatLine(0, quill.getLength(), key, value)
236
- }
237
- updataHtmlText(e)
238
- } else if (key === 'alignContent') {
239
- // 水平居中
240
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
241
- e.data.textData[key] = value
242
- updataHtmlText(e)
243
- } else if (key === 'color') {
244
- // 颜色
245
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
246
- quill.formatText(0, quill.getLength() - 1, key, value)
247
- if (e.tag === 'HTMLText') {
248
- updataHtmlText(e)
249
- } else if (e.parent.findOne('HTMLText')) {
250
- updataHtmlText(e.parent.findOne('HTMLText'))
251
- }
252
- } else if (key === 'textShadow') {
253
- // 阴影
254
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
255
- e.data.textData[key] = value
256
- updataHtmlText(e)
257
- } else if (key === 'list') {
258
- // 有序无序列表
259
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
260
- if (editor.innerEditing) {
261
- const [line]: any = quill.getLine(range?.index || 0)
262
- if (line.formats().list) {
263
- quill.format(key, false)
264
- } else {
265
- quill.format(key, value)
266
- }
267
- } else {
268
- const [line]: any = quill.getLine(range?.index || 0)
269
- if (line.formats().list) {
270
- quill.formatLine(0, quill.getLength(), key, false)
271
- } else {
272
- quill.formatLine(0, quill.getLength(), key, value)
273
- }
274
- }
275
- updataHtmlText(e)
276
- } else {
277
- if (editor.innerEditing) {
278
- if (range && range.length) {
279
- quill.formatText(range.index, range.length, key, !quill.getFormat(range)[key])
280
- } else {
281
- quill.formatText(0, quill.getLength() - 1, key, !quill.getFormat()[key])
282
- }
283
- } else {
284
- quillManager.isMultiSelect() && quill.clipboard.dangerouslyPasteHTML(e.text)
285
- quill.formatText(0, quill.getLength() - 1, key, !quill.getFormat()[key])
286
- updataHtmlText(e)
287
- }
288
- }
289
-
290
- // if (e.parent.tag === 'Box' && e.parent.findOne('HTMLText') && e.parent.findOne('Box')) {
291
- // handleShowCurve(e.parent, false)
292
- // }
293
- }, 1)
294
- }