@chenyomi/leafer-htmltext-editor 1.0.8 → 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 -5
  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 -18
  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 -140
  45. package/dist/index.js +0 -178
  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/TextEditor.ts DELETED
@@ -1,213 +0,0 @@
1
- import { InnerEditor, registerInnerEditor } from "@leafer-in/editor";
2
- import { Matrix, PointerEvent } from "@leafer-ui/core";
3
- import { quillManager } from ".";
4
- import { updataHtmlText } from "./utils";
5
- @registerInnerEditor()
6
- export class TextEditor extends InnerEditor {
7
- public get tag() {
8
- return "TextEditor";
9
- }
10
- declare public editTarget: any;
11
-
12
- public editDom: any;
13
- public config = {
14
- selectAll: false,
15
- };
16
-
17
- public eventIds: any[] = [];
18
-
19
- protected selectText:
20
- | { start: number; end: number; text: string }
21
- | undefined = undefined;
22
- protected inBody: boolean | undefined = undefined; // App 的 view 为 canvas 类型时,文本编辑框只能添加到 body 下了
23
- protected isHTMLText: boolean | undefined = undefined;
24
- protected _keyEvent: boolean | undefined = undefined;
25
- public quill: any = null;
26
- public isComposing: boolean = false;
27
-
28
- // 拼写检查相关属性
29
- private misspelledWords: Array<{
30
- word: string;
31
- offset: number;
32
- length: number;
33
- }> = [];
34
- private overlay: HTMLDivElement | null = null;
35
-
36
- // 判断是否为OA系统的属性
37
- private get isOASystem(): boolean {
38
- return window.location.host.includes("oa");
39
- }
40
- public onLoad(): void {
41
- const { editor } = this;
42
- const { config } = editor.app;
43
- const text = this.editTarget;
44
- const { scaleX, scaleY } = text.worldTransform;
45
- const zoomScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
46
- // text.textEditing = true
47
-
48
- this.isHTMLText = !(text instanceof Text); // HTMLText
49
- this._keyEvent = config.keyEvent;
50
- config.keyEvent = false;
51
-
52
- const div = (this.editDom = document.querySelector("#textInnerEditor"));
53
- const { style } = div;
54
- style.visibility = "visible";
55
-
56
- // style.boxSizing = 'border-box'
57
- // 获取外部box的宽高 这个box也是可以手动调整的
58
- if (text.data.canChangeBox) {
59
- style.width = text.parent.width * zoomScale + "px";
60
- style.height = text.parent.height * zoomScale + "px";
61
- } else {
62
- style.width = "auto";
63
- style.height = "auto";
64
- }
65
-
66
- // style.border = '1.5px solid #8499EF'
67
- style.outline = "solid #8499EF";
68
-
69
- // 初始化文本样式
70
- if (text.data.textData.fontSize) {
71
- console.log(text.data.textData.fontSize)
72
- div.style.fontSize = `${text.data.textData.fontSize}px`;
73
- }
74
- if (text.data.textData.fontFamily) {
75
- div.style.fontFamily = `${text.data.textData.fontFamily}`;
76
- }
77
- if (text.data.textData.lineHeight) {
78
- div.style.lineHeight = text.data.textData.lineHeight;
79
- }
80
- if (text.data.textData.letterSpacing) {
81
- div.style.letterSpacing = `${text.data.textData.letterSpacing}px`;
82
- }
83
- if (text.data.textData.textShadow) {
84
- div.style.textShadow = `${text.data.textData.textShadow}`;
85
- } else {
86
- div.style.textShadow = "none";
87
- }
88
- if (text.data.textData.alignContent) {
89
- const qlEditor: any = div.querySelector(".ql-editor");
90
- qlEditor.style.alignContent = `${text.data.textData.alignContent}`;
91
- }
92
-
93
- this.quill = quillManager.getQuill();
94
-
95
- // 加载文本到编辑器
96
- this.quill.clipboard.dangerouslyPasteHTML(text.text);
97
- // this.quill.focus()
98
- if (text.parent.children[0].tag.includes("Shape")) {
99
- style.width = text.parent.width * zoomScale + "px";
100
- style.left = "0px";
101
- this.quill.formatLine(0, this.quill.getLength(), "align", "center");
102
- } else {
103
- this.quill.setSelection(0, this.quill.getLength() - 1);
104
- }
105
-
106
- // 获取整个编辑器容器的边界
107
- // const containerBounds = this.quill.container.getBoundingClientRect()
108
- this.quill.on("text-change", this.onInput);
109
- this.quill.on("selection-change", this.onSelectionChange);
110
- localStorage.removeItem("selection-change");
111
-
112
- this.eventIds = [
113
- // 点击空白关闭
114
- editor.app.on_(PointerEvent.DOWN, (e: PointerEvent) => {
115
- let { target } = e.origin,
116
- find: boolean = false;
117
- while (target) {
118
- if (target === div) find = true;
119
- target = target.parentElement;
120
- }
121
- if (!find) {
122
- editor.closeInnerEditor();
123
- editor.cancel();
124
- }
125
- }),
126
- ];
127
- // const { canvas } = useEditor()
128
- // canvas.app.config.move.drag = false
129
- // canvas.app.tree.hittable = false
130
- // canvas.app.editor.hittable = false
131
- }
132
- private onSelectionChange = async (e: any) => {
133
- e && localStorage.setItem("selection-change", JSON.stringify(e));
134
- };
135
-
136
- private onInput = async () => {
137
- const { editDom } = this;
138
- // 主要是更新编辑内容
139
- console.log("onInput");
140
- updataHtmlText(this.editTarget);
141
- // 获取当前文字编辑文字内容的边界 这里是在没有修改过外部尺寸的情况下 自适应文字编辑内容的尺寸
142
- // updateChangeBoxBound(this.editTarget)
143
-
144
- // 如果是清空了 width要从0改成auto
145
- // editDom.style.width = documentBounds.width ? documentBounds.width : 'auto'
146
- };
147
-
148
- public onUpdate() {
149
- const { editTarget: text } = this;
150
- const { scaleX, scaleY } = text.worldTransform;
151
- const zoomScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
152
-
153
- // layout
154
- let { width, height } = text.parent.__local;
155
- ((width *= zoomScale), (height *= zoomScale));
156
-
157
- const { x, y } = this.inBody
158
- ? text.app.clientBounds
159
- : text.app.tree.clientBounds;
160
- const { a, b, c, d, e, f } = new Matrix(text.worldTransform)
161
- .scale(1 / zoomScale)
162
- .translateInner(0, 0);
163
-
164
- const { style } = this.editDom;
165
- style.transform = `matrix(${a},${b},${c},${d},${e},${f})`;
166
- style.left = x + "px";
167
- style.top = y + "px";
168
-
169
- // 打开内部或者编辑内部文本编辑强制隐藏
170
- text.set({
171
- visible: false,
172
- });
173
- }
174
- private isUpdatingPoints = false;
175
- public onUnload(): void {
176
- const { editTarget: text, editor, editDom: dom } = this;
177
- // const { canvas } = useEditor()
178
- // canvas.app.config.move.drag = false
179
- // canvas.app.tree.hittable = true
180
- // canvas.app.editor.hittable = true
181
- if (text) {
182
- this.onInput();
183
-
184
- if (editor.app) editor.app.config.keyEvent = this._keyEvent;
185
- editor.off_(this.eventIds);
186
-
187
- // dom.remove()
188
- // this.editDom = this.eventIds = undefined
189
- this.editDom.style.visibility = "hidden";
190
- this.eventIds = [];
191
- }
192
- // 如果大于1
193
- if (
194
- text.parent &&
195
- text.parent.name == "Text" &&
196
- text.parent.children.some((e: any) => e.tag === "Box")
197
- ) {
198
- text.parent.findOne("Box").opacity = 1;
199
- text.visible = false;
200
- } else {
201
- // 恢复显示
202
- text.set({
203
- visible: true,
204
- });
205
- }
206
- if (this.quill.getLength() === 1 && text.parent.name === "Text") {
207
- text.parent.remove();
208
- }
209
- console.log("onUnload");
210
- this.quill.off("text-change", this.onInput);
211
- this.quill.off("selection-change", this.onSelectionChange);
212
- }
213
- }
package/src/fonts/font.ts DELETED
@@ -1,86 +0,0 @@
1
- export const defaultFonts = [
2
- { code: 'Roboto', name: `"Roboto", sans-serif`, url: '/fonts/Roboto.woff2' },
3
- { code: 'Roboto Mono', name: `"Roboto Mono", monospace`, url: '/fonts/RobotoMono.woff2' },
4
- { code: 'Inter', name: `"Inter", sans-serif`, url: '/fonts/Inter.woff2' },
5
- { code: 'Open Sans', name: `"Open Sans", sans-serif`, url: '/fonts/OpenSans.woff2' },
6
- { code: 'Montserrat', name: `"Montserrat", sans-serif`, url: '/fonts/Montserrat.woff2' },
7
- { code: 'Roboto Condensed', name: `"Roboto Condensed", sans-serif`, url: '/fonts/RobotoCondensed.woff2' },
8
- { code: 'Arimo', name: `"Arimo", sans-serif`, url: '/fonts/Arimo.woff2' },
9
- { code: 'Noto Sans', name: `"Noto Sans", sans-serif`, url: '/fonts/NotoSans.woff2' },
10
- { code: 'Noto Sans Symbols', name: `"Noto Sans Symbols", sans-serif`, url: '/fonts/NotoSansSymbols.woff2' },
11
- { code: 'Merriweather', name: `"Merriweather", serif`, url: '/fonts/Merriweather.woff2' },
12
- { code: 'Playfair Display', name: `"Playfair Display", serif`, url: '/fonts/PlayfairDisplay.woff2' },
13
- { code: 'Noto Serif', name: `"Noto Serif", serif`, url: '/fonts/NotoSerif.woff2' },
14
- { code: 'Lato', name: `"Lato", sans-serif`, url: '/fonts/Lato.woff2' },
15
- { code: 'Spectral', name: `"Spectral", serif`, url: '/fonts/Spectral.woff2' },
16
- { code: 'Dancing Script', name: `"Dancing Script", cursive`, url: '/fonts/DancingScript.woff2' },
17
-
18
- { code: 'Noto Sans Simplified Chinese', name: `"Noto Sans SC", sans-serif`, url: '/fonts/NotoSansSimplifiedChinese.woff2' },
19
- { code: 'Noto Serif Simplified Chinese', name: `"Noto Serif SC", serif`, url: '/fonts/NotoSerifSimplifiedChinese.woff2' },
20
- { code: 'Noto Sans Traditional Chinese', name: `"Noto Sans TC", sans-serif`, url: '/fonts/NotoSansTraditionalChinese.woff2' },
21
- { code: 'Noto Sans Hong Kong', name: `"Noto Sans HK", sans-serif`, url: '/fonts/NotoSansHongKong.woff2' },
22
- { code: 'Noto Serif Traditional Chinese', name: `"Noto Serif TC", serif`, url: '/fonts/NotoSerifTraditionalChinese.woff2' },
23
- { code: 'Noto Serif Hong Kong', name: `"Noto Serif HK", serif`, url: '/fonts/NotoSerifHongKong.woff2' },
24
- { code: 'Noto Sans Japanese', name: `"Noto Sans JP", sans-serif`, url: '/fonts/NotoSansJapanese.woff2' },
25
- { code: 'Noto Sans Korean', name: `"Noto Sans KR", sans-serif`, url: '/fonts/NotoSansKorean.woff2' },
26
-
27
- { code: 'Poppins', name: `"Poppins", sans-serif`, url: '/fonts/Poppins.woff2' }
28
- ];
29
-
30
- const FONT_KEY = 'OPEN_FONTS';
31
- const FONT_VERSION_KEY = 'OPEN_FONTS_VERSION';
32
-
33
- // 简单的字体管理类
34
- export class FontManager {
35
- private fontList: any[] = [];
36
- private skipLoadFonts: any[] = defaultFonts.map((value) => value.name);
37
- private loadFonts: any[] = defaultFonts;
38
-
39
- constructor() {
40
- this.initFonts();
41
- }
42
-
43
- /**
44
- * 初始化部分字体
45
- */
46
- async initFonts() {
47
- let list: any[] = [];
48
-
49
- if (typeof localStorage !== 'undefined') {
50
- if (localStorage.getItem(FONT_VERSION_KEY) !== '1') {
51
- localStorage.removeItem(FONT_KEY);
52
- }
53
-
54
- let localFonts: any[] = [];
55
- try {
56
- const storedFonts = localStorage.getItem(FONT_KEY);
57
- localFonts = storedFonts ? JSON.parse(storedFonts) : [];
58
- } catch {
59
- localFonts = [];
60
- localStorage.removeItem(FONT_KEY);
61
- }
62
-
63
- if (localFonts.length > 0) {
64
- list.push(...localFonts);
65
- }
66
- }
67
-
68
- this.fontList = defaultFonts.concat(list);
69
- return list;
70
- }
71
-
72
- getFontList() {
73
- return this.fontList;
74
- }
75
-
76
- getSkipLoadFonts() {
77
- return this.skipLoadFonts;
78
- }
79
-
80
- getLoadFonts() {
81
- return this.loadFonts;
82
- }
83
- }
84
-
85
- // 导出单例实例
86
- export const fontManager = new FontManager();
@@ -1,232 +0,0 @@
1
- const FONT_CSS_TAG = "data-fonts"
2
- const FONT_CSS_TAG_BASE64 = "base64-fonts"
3
-
4
- export async function fetchFontAsBase64(url: string): Promise<string> {
5
- const response = await fetch(url);
6
- if (!response.ok) {
7
- throw new Error(`Failed to fetch font from ${url}`);
8
- }
9
- // 获取文件类型
10
- const contentType = response.headers.get('Content-Type');
11
- let mimeType: string;
12
-
13
- // 根据 Content-Type 设置 MIME 类型
14
- if (contentType?.includes('font/woff2')) {
15
- mimeType = 'font/woff2';
16
- } else if (contentType?.includes('font/woff')) {
17
- mimeType = 'font/woff';
18
- } else if (contentType?.includes('font/ttf') || contentType?.includes('font/sfnt')) {
19
- mimeType = 'font/ttf';
20
- } else if (contentType?.includes('application/octet-stream')) {
21
- // 如果 Content-Type 是通用的二进制流,尝试从文件扩展名推断类型
22
- const extension = url.split('.').pop()?.toLowerCase();
23
- if (extension === 'woff2') {
24
- mimeType = 'font/woff2';
25
- } else if (extension === 'woff') {
26
- mimeType = 'font/woff';
27
- } else if (extension === 'ttf') {
28
- mimeType = 'font/ttf';
29
- } else {
30
- throw new Error(`Unsupported font file type: ${extension}`);
31
- }
32
- } else {
33
- throw new Error(`Unsupported Content-Type: ${contentType}`);
34
- }
35
-
36
- // 将文件转换为 Base64
37
- const arrayBuffer = await response.arrayBuffer();
38
- const base64String = arrayBufferToBase64(arrayBuffer);
39
-
40
- // 返回 data: URL
41
- return `data:${mimeType};charset=utf-8;base64,${base64String}`;
42
- }
43
-
44
- function arrayBufferToBase64(buffer: ArrayBuffer): string {
45
- let binary = '';
46
- const bytes = new Uint8Array(buffer);
47
- const len = bytes.byteLength;
48
- for (let i = 0; i < len; i++) {
49
- binary += String.fromCharCode(bytes[i]);
50
- }
51
- return window.btoa(binary);
52
- }
53
-
54
- /**
55
- * 批量添加自定义字体样式
56
- * @param fontList
57
- */
58
- export function addCustomFonts(fontList: any = []) {
59
- let styleTag = document.createElement('style');
60
- styleTag.setAttribute(FONT_CSS_TAG, 'true');
61
- let fontRules = fontList.map((font: any) => `@font-face {
62
- font-family: "${font.name}";
63
- src: local("${font.name}"), url("${font.download}")
64
- }`).join('\n');
65
- styleTag.textContent = fontRules;
66
- document.head.appendChild(styleTag);
67
- }
68
-
69
- /**
70
- * 获取自定义字体样式
71
- */
72
- export function getCustomFontsStyle() {
73
- const styleTag = document.querySelector('style[data-fonts]');
74
- return styleTag?.textContent || '';
75
- }
76
-
77
- /**
78
- * 添加单个自定义字体样式
79
- * @param font
80
- */
81
- export function addCustomFont(font: any) {
82
- let styleTag = document.querySelector('style[data-fonts]') as HTMLStyleElement | null;
83
- // 如果不存在样式标签,则创建一个新的style标签
84
- if (!styleTag) {
85
- styleTag = document.createElement('style');
86
- styleTag.setAttribute(FONT_CSS_TAG, 'true');
87
- document.head.appendChild(styleTag);
88
- }
89
-
90
- if (!styleTag.sheet) return;
91
-
92
- let existingFonts: string[] = [];
93
- existingFonts = Array.from(styleTag.sheet.cssRules).map((rule: CSSRule) => {
94
- const match = rule.cssText.match(/font-family: "([^"]+)"/);
95
- return match ? match[1] : null;
96
- }).filter((font): font is string => font !== null);
97
-
98
- // 判断要添加的字体是否已经存在于样式表中
99
- if (!existingFonts.includes(font.name)) {
100
- // 创建新的 @font-face 规则
101
- const newFontRule = `@font-face {
102
- font-family: "${font.name}";
103
- src: url("${font.download}");
104
- }`;
105
-
106
- // 插入新的 @font-face 规则到样式表中
107
- try {
108
- styleTag.sheet.insertRule(newFontRule, styleTag.sheet.cssRules.length);
109
- } catch (e) {
110
- console.error('Failed to insert font rule:', e);
111
- }
112
- }
113
- }
114
-
115
- /**
116
- * 批量加载字体(要在生成完字体css后再调用次方法执行)
117
- * @param fontNameList 字体名称
118
- */
119
- export async function batchLoadFont(fontNameList: any = []) {
120
- // FontFaceObserver 需要额外安装,这里注释掉
121
- // 可以使用浏览器原生的 document.fonts API
122
- try {
123
- for (const fontFamily of fontNameList) {
124
- await document.fonts.load(`16px ${fontFamily}`);
125
- }
126
- } catch (e) {
127
- console.warn('Font loading failed:', e);
128
- }
129
- }
130
-
131
- function getFontUrlFromCSS(selectors: string, fontFamilyName: string): string | null {
132
- // 获取所有 <style> 标签
133
- const styleTags = document.querySelectorAll(selectors);
134
-
135
- for (let i = 0; i < styleTags.length; i++) {
136
- const styleTag = styleTags[i];
137
- // 获取 CSS 内容
138
- const cssText = styleTag.textContent || '';
139
-
140
- // 使用正则表达式匹配 @font-face 规则
141
- const fontFaceRules = cssText.match(/@font-face\s*\{[^}]+\}/g);
142
-
143
- if (fontFaceRules) {
144
- for (const rule of fontFaceRules) {
145
- // 提取 font-family
146
- const fontFamilyMatch = rule.match(/font-family:\s*(["'])(.*?)\1/);
147
- if (fontFamilyMatch && fontFamilyMatch[2] === fontFamilyName) {
148
- // 提取 src
149
- const srcMatch = rule.match(/src:\s*url\((["'])(.*?)\1\)/);
150
- if (srcMatch) {
151
- return srcMatch[2]; // 返回字体文件 URL
152
- } else {
153
- const srcMatch2 = rule.match(/src:\s*(?:local\([^)]+\)\s*,\s*)?url\((["'])(.*?)\1\)/);
154
- if (srcMatch2) {
155
- return srcMatch2[2];
156
- }
157
- }
158
- }
159
- }
160
- }
161
- }
162
-
163
- return null; // 未找到匹配的字体
164
- }
165
-
166
- /**
167
- * 添加单个自定义字体样式(Base64格式)
168
- * @param font
169
- */
170
- export async function addCustomFontBase64(font: any) {
171
- const fontUrl = getFontUrlFromCSS(`style[${FONT_CSS_TAG}]`, font);
172
- if (!fontUrl) {
173
- console.warn('Font URL not found for:', font);
174
- return;
175
- }
176
-
177
- console.log('fontUrl=', fontUrl);
178
- let styleTag = document.querySelector(`style[${FONT_CSS_TAG_BASE64}]`) as HTMLStyleElement | null;
179
- // 如果不存在样式标签,则创建一个新的style标签
180
- if (!styleTag) {
181
- styleTag = document.createElement('style');
182
- styleTag.setAttribute(FONT_CSS_TAG_BASE64, 'true');
183
- document.head.appendChild(styleTag);
184
- }
185
-
186
- // 确保样式标签已经被添加到文档中
187
- if (!styleTag.sheet) {
188
- await new Promise(resolve => setTimeout(resolve, 10)); // 等待样式标签被加载
189
- }
190
-
191
- if (!styleTag.sheet) return;
192
-
193
- let existingFonts = Array.from(styleTag.sheet.cssRules).map((rule: CSSRule) => {
194
- const match = rule.cssText.match(/font-family: "([^"]+)"/);
195
- return match ? match[1] : null;
196
- }).filter((font): font is string => font !== null);
197
-
198
- // 判断要添加的字体是否已经存在于样式表中
199
- if (!existingFonts.includes(font)) {
200
- const base64Url = await fetchFontAsBase64(fontUrl);
201
- // 创建新的 @font-face 规则
202
- const newFontRule = `@font-face {
203
- font-family: "${font}";
204
- src: local("${font}"), url("${base64Url}");
205
- }`;
206
-
207
- // 插入新的 @font-face 规则到样式表中
208
- try {
209
- styleTag.sheet.insertRule(newFontRule, styleTag.sheet.cssRules.length);
210
- styleTag.textContent += newFontRule;
211
- } catch (e) {
212
- console.error('Failed to insert font rule:', e);
213
- }
214
- }
215
- }
216
-
217
- /**
218
- * 获取自定义字体样式
219
- */
220
- export function getBase64CustomFontsStyle() {
221
- const styleTag = document.querySelector(`style[${FONT_CSS_TAG_BASE64}]`);
222
- return styleTag?.textContent || '';
223
- }
224
-
225
- /**
226
- * 加载单个字体并转换为 Base64 格式
227
- * @param font 字体名称
228
- * @returns Promise<void>
229
- */
230
- export async function loadFont(font: string): Promise<void> {
231
- await addCustomFontBase64(font);
232
- }
@@ -1,103 +0,0 @@
1
-
2
- .ql-editor {
3
- padding: 0 !important;
4
- line-height: unset !important;
5
- overflow: unset !important;
6
- outline: 0;
7
- }
8
-
9
- .ql-editor p {
10
- margin: 0 !important;
11
- }
12
-
13
- .ql-editor sub,
14
- .ql-editor sup {
15
- font-size: 63%;
16
- }
17
-
18
- .ql-editor sup {
19
- top: -0.58em;
20
- }
21
-
22
- .ql-editor sub {
23
- bottom: -0.38em;
24
- }
25
-
26
- .ql-editor ol {
27
- padding-left: 0 !important;
28
- }
29
-
30
- .ql-font-Roboto {
31
- font-family: 'Roboto', sans-serif;
32
- }
33
- .ql-font-RobotoMono {
34
- font-family: 'Roboto Mono', monospace;
35
- }
36
- .ql-font-Inter {
37
- font-family: 'Inter', sans-serif;
38
- }
39
- .ql-font-OpenSans {
40
- font-family: 'Open Sans', sans-serif;
41
- }
42
- .ql-font-Montserrat {
43
- font-family: 'Montserrat', sans-serif;
44
- }
45
- .ql-font-RobotoCondensed {
46
- font-family: 'Roboto Condensed', sans-serif;
47
- }
48
- .ql-font-Arimo {
49
- font-family: 'Arimo', sans-serif;
50
- }
51
- .ql-font-NotoSans {
52
- font-family: 'Noto Sans', sans-serif;
53
- }
54
- .ql-font-NotoSansSymbols {
55
- font-family: 'Noto Sans Symbols', sans-serif;
56
- }
57
- .ql-font-Merriweather {
58
- font-family: 'Merriweather', serif;
59
- }
60
- .ql-font-PlayfairDisplay {
61
- font-family: 'Playfair Display', serif;
62
- }
63
- .ql-font-NotoSerif {
64
- font-family: 'Noto Serif', serif;
65
- }
66
- .ql-font-Lato {
67
- font-family: 'Lato', sans-serif;
68
- }
69
- .ql-font-Spectral {
70
- font-family: 'Spectral', serif;
71
- }
72
- .ql-font-DancingScript {
73
- font-family: 'Dancing Script', cursive;
74
- }
75
-
76
- .ql-font-NotoSansSimplifiedChinese {
77
- font-family: 'Noto Sans SC', sans-serif;
78
- }
79
- .ql-font-NotoSerifSimplifiedChinese {
80
- font-family: 'Noto Serif SC', serif;
81
- }
82
- .ql-font-NotoSansTraditionalChinese {
83
- font-family: 'Noto Sans TC', sans-serif;
84
- }
85
- .ql-font-NotoSansHongKong {
86
- font-family: 'Noto Sans HK', sans-serif;
87
- }
88
- .ql-font-NotoSerifTraditionalChinese {
89
- font-family: 'Noto Serif TC', serif;
90
- }
91
- .ql-font-NotoSerifHongKong {
92
- font-family: 'Noto Serif HK', serif;
93
- }
94
- .ql-font-NotoSansJapanese {
95
- font-family: 'Noto Sans JP', sans-serif;
96
- }
97
- .ql-font-NotoSansKorean {
98
- font-family: 'Noto Sans KR', sans-serif;
99
- }
100
-
101
- .ql-font-Poppins {
102
- font-family: 'Poppins', sans-serif;
103
- }