@opentiny/fluent-editor 3.21.1 → 3.22.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/es/fluent-editor.es.js +13 -1
- package/es/fluent-editor.es.js.map +1 -1
- package/es/mathlive/formats.es.js +65 -0
- package/es/mathlive/formats.es.js.map +1 -0
- package/es/mathlive/index.es.js +16 -0
- package/es/mathlive/index.es.js.map +1 -0
- package/es/mathlive/tooltip.es.js +69 -0
- package/es/mathlive/tooltip.es.js.map +1 -0
- package/lib/fluent-editor.cjs.js +21 -9
- package/lib/fluent-editor.cjs.js.map +1 -1
- package/lib/mathlive/formats.cjs.js +65 -0
- package/lib/mathlive/formats.cjs.js.map +1 -0
- package/lib/mathlive/index.cjs.js +16 -0
- package/lib/mathlive/index.cjs.js.map +1 -0
- package/lib/mathlive/tooltip.cjs.js +69 -0
- package/lib/mathlive/tooltip.cjs.js.map +1 -0
- package/package.json +4 -2
- package/style.css +30 -0
- package/types/attributors/font-size.d.ts +1 -0
- package/types/attributors/font-style.d.ts +1 -0
- package/types/attributors/line-height.d.ts +1 -0
- package/types/attributors/text-indent.d.ts +1 -0
- package/types/mathlive/formats.d.ts +28 -0
- package/types/mathlive/index.d.ts +8 -0
- package/types/mathlive/tooltip.d.ts +17 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Fluent Editor
|
|
2
2
|
|
|
3
3
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
4
|
-
[](#contributors-)
|
|
5
5
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
6
6
|
|
|
7
7
|
Fluent Editor is a rich text editor based on Quill 2.0, which extends Quill with rich modules and formats such as tables, images, hyperlinks, copy and paste, inserting emoticons, file uploads, @ reminders, and diagonal menu. It is framework-independent, compatible with Quill API, and compatible with Quill module ecosystem.
|
|
@@ -75,6 +75,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
75
75
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zzxming"><img src="https://avatars.githubusercontent.com/u/74341337?v=4?s=100" width="100px;" alt="zzxming"/><br /><sub><b>zzxming</b></sub></a><br /><a href="https://github.com/opentiny/fluent-editor/commits?author=zzxming" title="Code">💻</a></td>
|
|
76
76
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Janson1012"><img src="https://avatars.githubusercontent.com/u/60996238?v=4?s=100" width="100px;" alt="Janson1012"/><br /><sub><b>Janson1012</b></sub></a><br /><a href="https://github.com/opentiny/fluent-editor/commits?author=Janson1012" title="Code">💻</a></td>
|
|
77
77
|
<td align="center" valign="top" width="14.28%"><a href="https://kagol.github.io/blogs"><img src="https://avatars.githubusercontent.com/u/9566362?v=4?s=100" width="100px;" alt="Kagol"/><br /><sub><b>Kagol</b></sub></a><br /><a href="https://github.com/opentiny/fluent-editor/commits?author=kagol" title="Code">💻</a></td>
|
|
78
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kiss-keray"><img src="https://avatars.githubusercontent.com/u/24504763?v=4?s=100" width="100px;" alt="keray"/><br /><sub><b>keray</b></sub></a><br /><a href="https://github.com/opentiny/fluent-editor/commits?author=kiss-keray" title="Code">💻</a></td>
|
|
78
79
|
</tr>
|
|
79
80
|
</tbody>
|
|
80
81
|
</table>
|
package/es/fluent-editor.es.js
CHANGED
|
@@ -11,6 +11,8 @@ import FileModule from "./file/index.es.js";
|
|
|
11
11
|
import { FormatPainter } from "./format-painter/index.es.js";
|
|
12
12
|
import { fullscreenHandler } from "./fullscreen/handler.es.js";
|
|
13
13
|
import Link from "./link/index.es.js";
|
|
14
|
+
import MathliveModule from "./mathlive/index.es.js";
|
|
15
|
+
import MathliveBlot from "./mathlive/formats.es.js";
|
|
14
16
|
import Mention from "./mention/Mention.es.js";
|
|
15
17
|
import { Screenshot } from "./screenshot/index.es.js";
|
|
16
18
|
import SoftBreak from "./soft-break/index.es.js";
|
|
@@ -45,6 +47,14 @@ const registerModules = function() {
|
|
|
45
47
|
"toolbar": {
|
|
46
48
|
handlers: {
|
|
47
49
|
...SnowTheme.DEFAULTS.modules.toolbar.handlers,
|
|
50
|
+
"formula": function() {
|
|
51
|
+
const mathlive = this.quill.getModule("mathlive");
|
|
52
|
+
if (!mathlive) {
|
|
53
|
+
this.quill.theme.tooltip.edit("formula");
|
|
54
|
+
} else {
|
|
55
|
+
mathlive.createDialog();
|
|
56
|
+
}
|
|
57
|
+
},
|
|
48
58
|
"undo": function() {
|
|
49
59
|
this.quill.history.undo();
|
|
50
60
|
},
|
|
@@ -144,6 +154,7 @@ const registerModules = function() {
|
|
|
144
154
|
// 报错
|
|
145
155
|
// 'modules/quickmenu': QuickMenu,//暂未开发
|
|
146
156
|
"modules/syntax": CustomSyntax,
|
|
157
|
+
"modules/mathlive": MathliveModule,
|
|
147
158
|
"formats/strike": StrikeBlot,
|
|
148
159
|
"formats/softBreak": SoftBreak,
|
|
149
160
|
"formats/video": Video,
|
|
@@ -151,7 +162,8 @@ const registerModules = function() {
|
|
|
151
162
|
"formats/font": FontStyle,
|
|
152
163
|
"formats/size": SizeStyle,
|
|
153
164
|
"formats/line-height": LineHeightStyle,
|
|
154
|
-
"formats/text-indent": TextIndentStyle
|
|
165
|
+
"formats/text-indent": TextIndentStyle,
|
|
166
|
+
[`formats/${MathliveBlot.blotName}`]: MathliveBlot
|
|
155
167
|
},
|
|
156
168
|
true
|
|
157
169
|
// 覆盖内部模块
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluent-editor.es.js","sources":["../../src/fluent-editor.ts"],"sourcesContent":["import type { Module, Parchment as TypeParchment } from 'quill'\r\nimport type { IEditorConfig } from './config/types'\r\nimport Quill from 'quill'\r\nimport { FontStyle, LineHeightStyle, SizeStyle, TextIndentStyle } from './attributors'\r\nimport { getListValue, ICONS_CONFIG, inputFile, TABLE_RIGHT_MENU_CONFIG } from './config'\r\nimport Counter from './counter' // 字符统计\r\nimport CustomClipboard from './custom-clipboard' // 粘贴板\r\nimport CustomImage from './custom-image/BlotFormatter' // 图片\r\nimport { CustomImageSpec } from './custom-image/specs/CustomImageSpec' // 图片拉伸模块\r\nimport CustomUploader from './custom-uploader' // 上传\r\nimport Emoji from './emoji' // 表情\r\nimport FileModule from './file' // 文件\r\nimport { FormatPainter } from './format-painter'\r\nimport { fullscreenHandler } from './fullscreen/handler'\r\nimport Link from './link' // 超链接\r\nimport Mention from './mention/Mention' // @提醒\r\nimport { Screenshot } from './screenshot'// 截图\r\nimport SoftBreak from './soft-break' // 软回车\r\nimport Strike from './strike' // 删除线\r\nimport CustomSyntax from './syntax' // 代码块高亮\r\nimport BetterTable from './table/better-table' // 表格\r\nimport Toolbar from './toolbar' // 工具栏\r\nimport Video from './video' // 视频\r\n// import GlobalLink from './global-link' // 全局链接\r\n// import QuickMenu from './quick-menu' // 快捷菜单\r\n\r\nexport class FluentEditor extends Quill {\r\n isFullscreen: boolean = false\r\n constructor(container: HTMLElement | string, options: IEditorConfig = {}) {\r\n super(container, options)\r\n }\r\n}\r\n\r\nconst registerModules = function () {\r\n const Icons = Quill.import('ui/icons')\r\n Object.entries(ICONS_CONFIG).forEach(([key, icon]) => {\r\n Icons[key] = icon\r\n })\r\n\r\n const SnowTheme = Quill.imports['themes/snow'] as typeof Module\r\n SnowTheme.DEFAULTS = {\r\n modules: {\r\n 'keyboard': {\r\n bindings: {\r\n ...BetterTable.keyboardBindings,\r\n },\r\n },\r\n 'toolbar': {\r\n handlers: {\r\n ...(SnowTheme.DEFAULTS as Record<string, any>).modules.toolbar.handlers,\r\n 'undo': function () {\r\n this.quill.history.undo()\r\n },\r\n 'redo': function () {\r\n this.quill.history.redo()\r\n },\r\n 'better-table': function () {\r\n this.quill.getModule('better-table').insertTable(3, 3)\r\n },\r\n 'file': function () {\r\n const accept = this.quill.options?.uploadOption?.fileAccept\r\n inputFile.call(this, 'file', accept)\r\n },\r\n 'image': function () {\r\n const accept = this.quill.options?.uploadOption?.imageAccept\r\n inputFile.call(this, 'image', accept)\r\n },\r\n 'emoji': function () {},\r\n 'fullscreen': fullscreenHandler,\r\n 'list': function (value) {\r\n const range = this.quill.getSelection()\r\n const formats = this.quill.getFormat(range)\r\n const preListValue = Array.isArray(formats.list) ? formats.list[0]?.value : formats.list?.value\r\n const curListValue = getListValue(value, preListValue)\r\n // 如果设置list的选区中有表格,判断第一个table-col位置,将表格前的内容设置为list格式\r\n const lines = this.quill.getLines(range.index, range.length)\r\n const tableCols = lines.filter(line => line.statics.blotName === 'table-col' && !line.prev)\r\n if (tableCols.length) {\r\n let start = range.index\r\n // 遍历table-col群组,以之获取表格,将表格前选区设置为对应list格式\r\n tableCols.forEach((item, index) => {\r\n const table = item.domNode.closest('table.quill-better-table')\r\n const tableBlot = Quill.find(table) as TypeParchment.Blot\r\n const tableLength = tableBlot.length()\r\n const tableStart = this.quill.getIndex(item)\r\n const tableEnd = tableStart + tableLength\r\n const beforeTableRangeLength = tableStart - start\r\n // 在表格前设置列表\r\n this.quill.setSelection(start, beforeTableRangeLength, Quill.sources.SILENT)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n table.parentNode.classList.remove('quill-better-table-selected')\r\n // 当前表格末尾为下一个选取的开始\r\n start = tableEnd\r\n if (index === tableCols.length - 1) {\r\n // 将最后一个表格之后所有选区内容设置list格式\r\n this.quill.setSelection(tableEnd, range.index + range.length - tableEnd)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n })\r\n }\r\n else {\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n },\r\n [FormatPainter.toolName]: FormatPainter,\r\n [Screenshot.toolName]: Screenshot,\r\n },\r\n },\r\n 'better-table': {\r\n operationMenu: {\r\n items: TABLE_RIGHT_MENU_CONFIG,\r\n color: true,\r\n },\r\n },\r\n 'image': {\r\n specs: [CustomImageSpec],\r\n overlay: {\r\n style: {\r\n border: '1px dashed rgb(68, 68, 68)',\r\n },\r\n },\r\n align: {\r\n icons: {\r\n left: '<i class=\"icon-text-align-left\"></i>',\r\n center: '<i class=\"icon-text-align-center\"></i>',\r\n right: '<i class=\"icon-text-align-right\"></i>',\r\n },\r\n },\r\n },\r\n },\r\n }\r\n\r\n FluentEditor.register(\r\n {\r\n 'modules/toolbar': Toolbar,\r\n 'modules/mention': Mention,\r\n 'modules/better-table': BetterTable,\r\n 'modules/clipboard': CustomClipboard,\r\n 'modules/uploader': CustomUploader, // 三者关联性最强\r\n 'modules/image': CustomImage, // 三者关联性最强\r\n 'modules/file': FileModule, // 三者关联性最强\r\n 'modules/counter': Counter,\r\n 'modules/emoji-toolbar': Emoji.ToolbarEmoji,\r\n 'modules/emoji-shortname': Emoji.ShortNameEmoji,\r\n // 'modules/global-link': GlobalLink,//暂未开发\r\n 'modules/link': Link, // 报错\r\n // 'modules/quickmenu': QuickMenu,//暂未开发\r\n 'modules/syntax': CustomSyntax,\r\n\r\n 'formats/strike': Strike,\r\n 'formats/softBreak': SoftBreak,\r\n 'formats/video': Video,\r\n 'formats/emoji': Emoji.EmojiBlot,\r\n 'formats/font': FontStyle,\r\n 'formats/size': SizeStyle,\r\n 'formats/line-height': LineHeightStyle,\r\n 'formats/text-indent': TextIndentStyle,\r\n },\r\n true, // 覆盖内部模块\r\n )\r\n\r\n return FluentEditor\r\n}\r\n\r\nexport default registerModules()\r\n"],"names":["Toolbar","CustomImage","Strike"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fluent-editor.es.js","sources":["../../src/fluent-editor.ts"],"sourcesContent":["import type { Module, Parchment as TypeParchment } from 'quill'\r\nimport type { IEditorConfig } from './config/types'\r\nimport Quill from 'quill'\r\nimport { FontStyle, LineHeightStyle, SizeStyle, TextIndentStyle } from './attributors'\r\nimport { getListValue, ICONS_CONFIG, inputFile, TABLE_RIGHT_MENU_CONFIG } from './config'\r\nimport Counter from './counter' // 字符统计\r\nimport CustomClipboard from './custom-clipboard' // 粘贴板\r\nimport CustomImage from './custom-image/BlotFormatter' // 图片\r\nimport { CustomImageSpec } from './custom-image/specs/CustomImageSpec' // 图片拉伸模块\r\nimport CustomUploader from './custom-uploader' // 上传\r\nimport Emoji from './emoji' // 表情\r\nimport FileModule from './file' // 文件\r\nimport { FormatPainter } from './format-painter'\r\nimport { fullscreenHandler } from './fullscreen/handler'\r\nimport Link from './link' // 超链接\r\nimport MathliveModule from './mathlive' // latex公式\r\nimport MathliveBlot from './mathlive/formats'\r\nimport Mention from './mention/Mention' // @提醒\r\nimport { Screenshot } from './screenshot'// 截图\r\nimport SoftBreak from './soft-break' // 软回车\r\nimport Strike from './strike' // 删除线\r\nimport CustomSyntax from './syntax' // 代码块高亮\r\nimport BetterTable from './table/better-table' // 表格\r\nimport Toolbar from './toolbar' // 工具栏\r\nimport Video from './video' // 视频\r\n// import GlobalLink from './global-link' // 全局链接\r\n// import QuickMenu from './quick-menu' // 快捷菜单\r\n\r\nexport class FluentEditor extends Quill {\r\n isFullscreen: boolean = false\r\n constructor(container: HTMLElement | string, options: IEditorConfig = {}) {\r\n super(container, options)\r\n }\r\n}\r\n\r\nconst registerModules = function () {\r\n const Icons = Quill.import('ui/icons')\r\n Object.entries(ICONS_CONFIG).forEach(([key, icon]) => {\r\n Icons[key] = icon\r\n })\r\n\r\n const SnowTheme = Quill.imports['themes/snow'] as typeof Module\r\n SnowTheme.DEFAULTS = {\r\n modules: {\r\n 'keyboard': {\r\n bindings: {\r\n ...BetterTable.keyboardBindings,\r\n },\r\n },\r\n 'toolbar': {\r\n handlers: {\r\n ...(SnowTheme.DEFAULTS as Record<string, any>).modules.toolbar.handlers,\r\n 'formula': function () {\r\n const mathlive = this.quill.getModule('mathlive')\r\n if (!mathlive) {\r\n this.quill.theme.tooltip.edit('formula')\r\n }\r\n else {\r\n mathlive.createDialog()\r\n }\r\n },\r\n 'undo': function () {\r\n this.quill.history.undo()\r\n },\r\n 'redo': function () {\r\n this.quill.history.redo()\r\n },\r\n 'better-table': function () {\r\n this.quill.getModule('better-table').insertTable(3, 3)\r\n },\r\n 'file': function () {\r\n const accept = this.quill.options?.uploadOption?.fileAccept\r\n inputFile.call(this, 'file', accept)\r\n },\r\n 'image': function () {\r\n const accept = this.quill.options?.uploadOption?.imageAccept\r\n inputFile.call(this, 'image', accept)\r\n },\r\n 'emoji': function () {},\r\n 'fullscreen': fullscreenHandler,\r\n 'list': function (value) {\r\n const range = this.quill.getSelection()\r\n const formats = this.quill.getFormat(range)\r\n const preListValue = Array.isArray(formats.list) ? formats.list[0]?.value : formats.list?.value\r\n const curListValue = getListValue(value, preListValue)\r\n // 如果设置list的选区中有表格,判断第一个table-col位置,将表格前的内容设置为list格式\r\n const lines = this.quill.getLines(range.index, range.length)\r\n const tableCols = lines.filter(line => line.statics.blotName === 'table-col' && !line.prev)\r\n if (tableCols.length) {\r\n let start = range.index\r\n // 遍历table-col群组,以之获取表格,将表格前选区设置为对应list格式\r\n tableCols.forEach((item, index) => {\r\n const table = item.domNode.closest('table.quill-better-table')\r\n const tableBlot = Quill.find(table) as TypeParchment.Blot\r\n const tableLength = tableBlot.length()\r\n const tableStart = this.quill.getIndex(item)\r\n const tableEnd = tableStart + tableLength\r\n const beforeTableRangeLength = tableStart - start\r\n // 在表格前设置列表\r\n this.quill.setSelection(start, beforeTableRangeLength, Quill.sources.SILENT)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n table.parentNode.classList.remove('quill-better-table-selected')\r\n // 当前表格末尾为下一个选取的开始\r\n start = tableEnd\r\n if (index === tableCols.length - 1) {\r\n // 将最后一个表格之后所有选区内容设置list格式\r\n this.quill.setSelection(tableEnd, range.index + range.length - tableEnd)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n })\r\n }\r\n else {\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n },\r\n [FormatPainter.toolName]: FormatPainter,\r\n [Screenshot.toolName]: Screenshot,\r\n },\r\n },\r\n 'better-table': {\r\n operationMenu: {\r\n items: TABLE_RIGHT_MENU_CONFIG,\r\n color: true,\r\n },\r\n },\r\n 'image': {\r\n specs: [CustomImageSpec],\r\n overlay: {\r\n style: {\r\n border: '1px dashed rgb(68, 68, 68)',\r\n },\r\n },\r\n align: {\r\n icons: {\r\n left: '<i class=\"icon-text-align-left\"></i>',\r\n center: '<i class=\"icon-text-align-center\"></i>',\r\n right: '<i class=\"icon-text-align-right\"></i>',\r\n },\r\n },\r\n },\r\n },\r\n }\r\n\r\n FluentEditor.register(\r\n {\r\n 'modules/toolbar': Toolbar,\r\n 'modules/mention': Mention,\r\n 'modules/better-table': BetterTable,\r\n 'modules/clipboard': CustomClipboard,\r\n 'modules/uploader': CustomUploader, // 三者关联性最强\r\n 'modules/image': CustomImage, // 三者关联性最强\r\n 'modules/file': FileModule, // 三者关联性最强\r\n 'modules/counter': Counter,\r\n 'modules/emoji-toolbar': Emoji.ToolbarEmoji,\r\n 'modules/emoji-shortname': Emoji.ShortNameEmoji,\r\n // 'modules/global-link': GlobalLink,//暂未开发\r\n 'modules/link': Link, // 报错\r\n // 'modules/quickmenu': QuickMenu,//暂未开发\r\n 'modules/syntax': CustomSyntax,\r\n 'modules/mathlive': MathliveModule,\r\n\r\n 'formats/strike': Strike,\r\n 'formats/softBreak': SoftBreak,\r\n 'formats/video': Video,\r\n 'formats/emoji': Emoji.EmojiBlot,\r\n 'formats/font': FontStyle,\r\n 'formats/size': SizeStyle,\r\n 'formats/line-height': LineHeightStyle,\r\n 'formats/text-indent': TextIndentStyle,\r\n [`formats/${MathliveBlot.blotName}`]: MathliveBlot,\r\n },\r\n true, // 覆盖内部模块\r\n )\r\n\r\n return FluentEditor\r\n}\r\n\r\nexport default registerModules()\r\n"],"names":["Toolbar","CustomImage","Strike"],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Quill from "quill";
|
|
2
|
+
const Parchment = Quill.import("parchment");
|
|
3
|
+
const _MathliveBlot = class _MathliveBlot extends Parchment.EmbedBlot {
|
|
4
|
+
constructor(scroll, domNode) {
|
|
5
|
+
super(scroll, domNode);
|
|
6
|
+
this.initFlag = false;
|
|
7
|
+
const dom = domNode;
|
|
8
|
+
dom.setAttribute("contenteditable", "false");
|
|
9
|
+
this.mode = dom.getAttribute("mode") || "only-read";
|
|
10
|
+
}
|
|
11
|
+
static create(obj) {
|
|
12
|
+
const el = super.create();
|
|
13
|
+
el.setAttribute("mode", obj.mode);
|
|
14
|
+
el.classList.add("view");
|
|
15
|
+
el.innerHTML = obj.value;
|
|
16
|
+
el.setValue(obj.value);
|
|
17
|
+
return el;
|
|
18
|
+
}
|
|
19
|
+
static value(domNode) {
|
|
20
|
+
return {
|
|
21
|
+
value: domNode.value,
|
|
22
|
+
mode: domNode.getAttribute("mode")
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
value() {
|
|
26
|
+
this.init();
|
|
27
|
+
return super.value();
|
|
28
|
+
}
|
|
29
|
+
init() {
|
|
30
|
+
if (this.initFlag) return;
|
|
31
|
+
if (this.mode === "only-read") return;
|
|
32
|
+
this.initFlag = true;
|
|
33
|
+
const dom = this.domNode;
|
|
34
|
+
this.quill = this.findQuillInstance();
|
|
35
|
+
if (this.mode === "dialog") {
|
|
36
|
+
dom.addEventListener("click", () => {
|
|
37
|
+
this.quill.getModule("mathlive").createDialog(dom.value);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
html() {
|
|
42
|
+
const formula = this.domNode.value;
|
|
43
|
+
return `<math-field class="ql-math-field view" contenteditable="false" mode="${this.mode}">${formula}</math-field>`;
|
|
44
|
+
}
|
|
45
|
+
findQuillInstance() {
|
|
46
|
+
if (this.quill) return this.quill;
|
|
47
|
+
let dom = this.domNode.parentElement;
|
|
48
|
+
while (dom) {
|
|
49
|
+
const quill = dom.quill;
|
|
50
|
+
if (quill instanceof Quill) {
|
|
51
|
+
return quill;
|
|
52
|
+
}
|
|
53
|
+
dom = dom.parentElement;
|
|
54
|
+
}
|
|
55
|
+
throw new Error("not found quill instance");
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
_MathliveBlot.blotName = "mathlive";
|
|
59
|
+
_MathliveBlot.tagName = "math-field";
|
|
60
|
+
_MathliveBlot.className = "ql-math-field";
|
|
61
|
+
let MathliveBlot = _MathliveBlot;
|
|
62
|
+
export {
|
|
63
|
+
MathliveBlot as default
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=formats.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.es.js","sources":["../../../src/mathlive/formats.ts"],"sourcesContent":["import type { MathfieldElement } from 'mathlive'\r\nimport type { Root } from 'parchment'\r\nimport Quill from 'quill'\r\n\r\nconst Parchment = Quill.import('parchment')\r\ntype MathliveBlotMode = 'dialog' | 'only-read'\r\nexport default class MathliveBlot extends Parchment.EmbedBlot {\r\n static blotName = 'mathlive'\r\n static tagName = 'math-field'\r\n static className = 'ql-math-field'\r\n quill?: Quill\r\n initFlag = false\r\n mode: MathliveBlotMode\r\n constructor(scroll: Root, domNode: Node) {\r\n super(scroll, domNode)\r\n const dom = domNode as HTMLElement\r\n dom.setAttribute('contenteditable', 'false')\r\n this.mode = (dom.getAttribute('mode')\r\n || 'only-read') as MathliveBlotMode\r\n }\r\n\r\n static create(obj: { value: string, mode: MathliveBlotMode }) {\r\n const el = super.create() as MathfieldElement\r\n el.setAttribute('mode', obj.mode)\r\n el.classList.add('view')\r\n el.innerHTML = obj.value\r\n el.setValue(obj.value)\r\n return el as MathfieldElement\r\n }\r\n\r\n static value(domNode: MathfieldElement) {\r\n return {\r\n value: domNode.value,\r\n mode: domNode.getAttribute('mode'),\r\n }\r\n }\r\n\r\n value() {\r\n this.init()\r\n return super.value()\r\n }\r\n\r\n init() {\r\n if (this.initFlag) return\r\n if (this.mode === 'only-read') return\r\n this.initFlag = true\r\n const dom = this.domNode as MathfieldElement\r\n this.quill = this.findQuillInstance()\r\n if (this.mode === 'dialog') {\r\n dom.addEventListener('click', () => {\r\n // @ts-ignore\r\n this.quill.getModule('mathlive').createDialog(dom.value)\r\n })\r\n }\r\n }\r\n\r\n html() {\r\n const formula = (this.domNode as MathfieldElement).value\r\n return `<math-field class=\"ql-math-field view\" contenteditable=\"false\" mode=\"${this.mode}\">${formula}</math-field>`\r\n }\r\n\r\n findQuillInstance(): Quill {\r\n if (this.quill) return this.quill\r\n let dom = (this.domNode as HTMLElement).parentElement\r\n while (dom) {\r\n const quill = (dom as any).quill\r\n if (quill instanceof Quill) {\r\n return quill\r\n }\r\n dom = dom.parentElement\r\n }\r\n throw new Error('not found quill instance')\r\n }\r\n}\r\n"],"names":[],"mappings":";AAIA,MAAM,YAAY,MAAM,OAAO,WAAW;AAErB,MAAA,gBAAA,MAAA,sBAAqB,UAAU,UAAU;AAAA,EAO5D,YAAY,QAAc,SAAe;AACvC,UAAM,QAAQ,OAAO;AAHZ,SAAA,WAAA;AAIT,UAAM,MAAM;AACR,QAAA,aAAa,mBAAmB,OAAO;AAC3C,SAAK,OAAQ,IAAI,aAAa,MAAM,KAC/B;AAAA,EACP;AAAA,EAEA,OAAO,OAAO,KAAgD;AACtD,UAAA,KAAK,MAAM;AACd,OAAA,aAAa,QAAQ,IAAI,IAAI;AAC7B,OAAA,UAAU,IAAI,MAAM;AACvB,OAAG,YAAY,IAAI;AAChB,OAAA,SAAS,IAAI,KAAK;AACd,WAAA;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,SAA2B;AAC/B,WAAA;AAAA,MACL,OAAO,QAAQ;AAAA,MACf,MAAM,QAAQ,aAAa,MAAM;AAAA,IAAA;AAAA,EAErC;AAAA,EAEA,QAAQ;AACN,SAAK,KAAK;AACV,WAAO,MAAM;EACf;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,SAAU;AACf,QAAA,KAAK,SAAS,YAAa;AAC/B,SAAK,WAAW;AAChB,UAAM,MAAM,KAAK;AACZ,SAAA,QAAQ,KAAK;AACd,QAAA,KAAK,SAAS,UAAU;AACtB,UAAA,iBAAiB,SAAS,MAAM;AAElC,aAAK,MAAM,UAAU,UAAU,EAAE,aAAa,IAAI,KAAK;AAAA,MAAA,CACxD;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO;AACC,UAAA,UAAW,KAAK,QAA6B;AACnD,WAAO,wEAAwE,KAAK,IAAI,KAAK,OAAO;AAAA,EACtG;AAAA,EAEA,oBAA2B;AACrB,QAAA,KAAK,MAAO,QAAO,KAAK;AACxB,QAAA,MAAO,KAAK,QAAwB;AACxC,WAAO,KAAK;AACV,YAAM,QAAS,IAAY;AAC3B,UAAI,iBAAiB,OAAO;AACnB,eAAA;AAAA,MACT;AACA,YAAM,IAAI;AAAA,IACZ;AACM,UAAA,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AACF;AAlEE,cAAO,WAAW;AAClB,cAAO,UAAU;AACjB,cAAO,YAAY;AAHA,IAAA,eAAA;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Module } from "quill";
|
|
2
|
+
import MathliveTooltip from "./tooltip.es.js";
|
|
3
|
+
class MathliveModule extends Module {
|
|
4
|
+
constructor(quill, options) {
|
|
5
|
+
super(quill, options);
|
|
6
|
+
quill.root.quill = quill;
|
|
7
|
+
this.tooltip = new MathliveTooltip(quill);
|
|
8
|
+
}
|
|
9
|
+
async createDialog(value) {
|
|
10
|
+
this.tooltip.edit(value);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
MathliveModule as default
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../../../src/mathlive/index.ts"],"sourcesContent":["import type Quill from 'quill'\r\nimport { Module } from 'quill'\r\nimport MathliveTooltip from './tooltip'\r\n\r\nexport default class MathliveModule extends Module<boolean> {\r\n tooltip: MathliveTooltip\r\n constructor(quill: Quill, options?: boolean) {\r\n super(quill, options)\r\n // @ts-ignore\r\n quill.root.quill = quill\r\n this.tooltip = new MathliveTooltip(quill)\r\n }\r\n\r\n async createDialog(value?: string) {\r\n this.tooltip.edit(value)\r\n }\r\n}\r\n"],"names":[],"mappings":";;AAIA,MAAqB,uBAAuB,OAAgB;AAAA,EAE1D,YAAY,OAAc,SAAmB;AAC3C,UAAM,OAAO,OAAO;AAEpB,UAAM,KAAK,QAAQ;AACd,SAAA,UAAU,IAAI,gBAAgB,KAAK;AAAA,EAC1C;AAAA,EAEA,MAAM,aAAa,OAAgB;AAC5B,SAAA,QAAQ,KAAK,KAAK;AAAA,EACzB;AACF;"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Delta } from "quill/core";
|
|
2
|
+
import Emitter from "quill/core/emitter";
|
|
3
|
+
import Tooltip from "quill/ui/tooltip";
|
|
4
|
+
const _MathliveTooltip = class _MathliveTooltip extends Tooltip {
|
|
5
|
+
constructor(quill, boundsContainer) {
|
|
6
|
+
super(quill, boundsContainer);
|
|
7
|
+
this.mathliveDom = document.createElement("math-field");
|
|
8
|
+
this.mathliveDom.classList.add("ql-math-field");
|
|
9
|
+
this.root.appendChild(this.mathliveDom);
|
|
10
|
+
this.root.classList.add("math-field-tooltip");
|
|
11
|
+
this.listen();
|
|
12
|
+
}
|
|
13
|
+
listen() {
|
|
14
|
+
this.mathliveDom.addEventListener("blur", (event) => {
|
|
15
|
+
this.hide();
|
|
16
|
+
});
|
|
17
|
+
this.root.addEventListener("keydown", (event) => {
|
|
18
|
+
if (event.key === "Enter") {
|
|
19
|
+
event.preventDefault();
|
|
20
|
+
this.save();
|
|
21
|
+
} else if (event.key === "Escape") {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
this.cancel();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
cancel() {
|
|
28
|
+
this.hide();
|
|
29
|
+
this.restoreFocus();
|
|
30
|
+
}
|
|
31
|
+
edit(value) {
|
|
32
|
+
this.editValue = value;
|
|
33
|
+
this.root.classList.remove("ql-hidden");
|
|
34
|
+
this.root.classList.add("ql-editing");
|
|
35
|
+
this.mathliveDom.setValue(value || "");
|
|
36
|
+
const range = this.quill.getSelection();
|
|
37
|
+
const bounds = range ? this.quill.getBounds(range) : null;
|
|
38
|
+
if (bounds != null) {
|
|
39
|
+
this.position(bounds);
|
|
40
|
+
}
|
|
41
|
+
this.show();
|
|
42
|
+
this.mathliveDom.focus();
|
|
43
|
+
}
|
|
44
|
+
restoreFocus() {
|
|
45
|
+
this.mathliveDom.blur();
|
|
46
|
+
this.quill.focus({ preventScroll: true });
|
|
47
|
+
}
|
|
48
|
+
save() {
|
|
49
|
+
const range = this.quill.getSelection(true);
|
|
50
|
+
const inputValue = this.mathliveDom.value;
|
|
51
|
+
if (!inputValue) return;
|
|
52
|
+
const index = range ? range.index : this.quill.getLength() - 1;
|
|
53
|
+
const delta = new Delta().retain(index).delete(this.editValue ? 1 : (range == null ? void 0 : range.length) || 0).insert({ mathlive: { value: inputValue, mode: "dialog" } });
|
|
54
|
+
this.quill.updateContents(delta, Emitter.sources.USER);
|
|
55
|
+
this.quill.setSelection(index + 1, Emitter.sources.USER);
|
|
56
|
+
this.hide();
|
|
57
|
+
}
|
|
58
|
+
position(reference) {
|
|
59
|
+
const adjustedReference = { ...reference };
|
|
60
|
+
adjustedReference.left = reference.left + this.root.offsetWidth / 2 - reference.width / 2;
|
|
61
|
+
return super.position(adjustedReference);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
_MathliveTooltip.TEMPLATE = ``;
|
|
65
|
+
let MathliveTooltip = _MathliveTooltip;
|
|
66
|
+
export {
|
|
67
|
+
MathliveTooltip as default
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=tooltip.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.es.js","sources":["../../../src/mathlive/tooltip.ts"],"sourcesContent":["import type { MathfieldElement } from 'mathlive'\r\nimport type Quill from 'quill'\r\nimport type { Bounds } from 'quill/core/selection'\r\nimport { Delta } from 'quill/core'\r\nimport Emitter from 'quill/core/emitter'\r\nimport Tooltip from 'quill/ui/tooltip'\r\n\r\nexport default class MathliveTooltip extends Tooltip {\r\n static TEMPLATE = ``\r\n\r\n mathliveDom: MathfieldElement\r\n editValue?: string\r\n\r\n constructor(quill: Quill, boundsContainer?: HTMLElement) {\r\n super(quill, boundsContainer)\r\n this.mathliveDom = document.createElement('math-field') as MathfieldElement\r\n this.mathliveDom.classList.add('ql-math-field')\r\n this.root.appendChild(this.mathliveDom)\r\n this.root.classList.add('math-field-tooltip')\r\n this.listen()\r\n }\r\n\r\n listen() {\r\n this.mathliveDom.addEventListener('blur', (event) => {\r\n this.hide()\r\n })\r\n this.root.addEventListener('keydown', (event) => {\r\n if (event.key === 'Enter') {\r\n event.preventDefault()\r\n this.save()\r\n }\r\n else if (event.key === 'Escape') {\r\n event.preventDefault()\r\n this.cancel()\r\n }\r\n })\r\n }\r\n\r\n cancel() {\r\n this.hide()\r\n this.restoreFocus()\r\n }\r\n\r\n edit(value?: string) {\r\n this.editValue = value\r\n this.root.classList.remove('ql-hidden')\r\n this.root.classList.add('ql-editing')\r\n this.mathliveDom.setValue(value || '')\r\n const range = this.quill.getSelection()\r\n const bounds = range ? this.quill.getBounds(range) : null\r\n if (bounds != null) {\r\n this.position(bounds)\r\n }\r\n this.show()\r\n this.mathliveDom.focus()\r\n }\r\n\r\n restoreFocus() {\r\n this.mathliveDom.blur()\r\n this.quill.focus({ preventScroll: true })\r\n }\r\n\r\n save() {\r\n const range = this.quill.getSelection(true)\r\n const inputValue = this.mathliveDom.value\r\n if (!inputValue) return\r\n const index = range ? range.index : this.quill.getLength() - 1\r\n const delta = new Delta()\r\n .retain(index)\r\n .delete(this.editValue ? 1 : range?.length || 0)\r\n .insert({ mathlive: { value: inputValue, mode: 'dialog' } })\r\n this.quill.updateContents(delta, Emitter.sources.USER)\r\n this.quill.setSelection(index + 1, Emitter.sources.USER)\r\n this.hide()\r\n }\r\n\r\n position(reference: Bounds) {\r\n const adjustedReference = { ...reference }\r\n adjustedReference.left = reference.left + this.root.offsetWidth / 2 - reference.width / 2\r\n return super.position(adjustedReference)\r\n }\r\n}\r\n"],"names":[],"mappings":";;;AAOA,MAAqB,mBAArB,MAAqB,yBAAwB,QAAQ;AAAA,EAMnD,YAAY,OAAc,iBAA+B;AACvD,UAAM,OAAO,eAAe;AACvB,SAAA,cAAc,SAAS,cAAc,YAAY;AACjD,SAAA,YAAY,UAAU,IAAI,eAAe;AACzC,SAAA,KAAK,YAAY,KAAK,WAAW;AACjC,SAAA,KAAK,UAAU,IAAI,oBAAoB;AAC5C,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,SAAS;AACP,SAAK,YAAY,iBAAiB,QAAQ,CAAC,UAAU;AACnD,WAAK,KAAK;AAAA,IAAA,CACX;AACD,SAAK,KAAK,iBAAiB,WAAW,CAAC,UAAU;AAC3C,UAAA,MAAM,QAAQ,SAAS;AACzB,cAAM,eAAe;AACrB,aAAK,KAAK;AAAA,MAAA,WAEH,MAAM,QAAQ,UAAU;AAC/B,cAAM,eAAe;AACrB,aAAK,OAAO;AAAA,MACd;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEA,SAAS;AACP,SAAK,KAAK;AACV,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,KAAK,OAAgB;AACnB,SAAK,YAAY;AACZ,SAAA,KAAK,UAAU,OAAO,WAAW;AACjC,SAAA,KAAK,UAAU,IAAI,YAAY;AAC/B,SAAA,YAAY,SAAS,SAAS,EAAE;AAC/B,UAAA,QAAQ,KAAK,MAAM,aAAa;AACtC,UAAM,SAAS,QAAQ,KAAK,MAAM,UAAU,KAAK,IAAI;AACrD,QAAI,UAAU,MAAM;AAClB,WAAK,SAAS,MAAM;AAAA,IACtB;AACA,SAAK,KAAK;AACV,SAAK,YAAY;EACnB;AAAA,EAEA,eAAe;AACb,SAAK,YAAY;AACjB,SAAK,MAAM,MAAM,EAAE,eAAe,KAAM,CAAA;AAAA,EAC1C;AAAA,EAEA,OAAO;AACL,UAAM,QAAQ,KAAK,MAAM,aAAa,IAAI;AACpC,UAAA,aAAa,KAAK,YAAY;AACpC,QAAI,CAAC,WAAY;AACjB,UAAM,QAAQ,QAAQ,MAAM,QAAQ,KAAK,MAAM,UAAc,IAAA;AACvD,UAAA,QAAQ,IAAI,MAAA,EACf,OAAO,KAAK,EACZ,OAAO,KAAK,YAAY,KAAI,+BAAO,WAAU,CAAC,EAC9C,OAAO,EAAE,UAAU,EAAE,OAAO,YAAY,MAAM,SAAS,EAAA,CAAG;AAC7D,SAAK,MAAM,eAAe,OAAO,QAAQ,QAAQ,IAAI;AACrD,SAAK,MAAM,aAAa,QAAQ,GAAG,QAAQ,QAAQ,IAAI;AACvD,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,SAAS,WAAmB;AACpB,UAAA,oBAAoB,EAAE,GAAG;AACb,sBAAA,OAAO,UAAU,OAAO,KAAK,KAAK,cAAc,IAAI,UAAU,QAAQ;AACjF,WAAA,MAAM,SAAS,iBAAiB;AAAA,EACzC;AACF;AAzEE,iBAAO,WAAW;AADpB,IAAqB,kBAArB;"}
|
package/lib/fluent-editor.cjs.js
CHANGED
|
@@ -13,14 +13,16 @@ const index$4 = require("./file/index.cjs.js");
|
|
|
13
13
|
const index$1 = require("./format-painter/index.cjs.js");
|
|
14
14
|
const handler = require("./fullscreen/handler.cjs.js");
|
|
15
15
|
const index$7 = require("./link/index.cjs.js");
|
|
16
|
+
const index$9 = require("./mathlive/index.cjs.js");
|
|
17
|
+
const formats = require("./mathlive/formats.cjs.js");
|
|
16
18
|
const Mention = require("./mention/Mention.cjs.js");
|
|
17
19
|
const index$2 = require("./screenshot/index.cjs.js");
|
|
18
|
-
const index$
|
|
19
|
-
const index$
|
|
20
|
+
const index$b = require("./soft-break/index.cjs.js");
|
|
21
|
+
const index$a = require("./strike/index.cjs.js");
|
|
20
22
|
const index$8 = require("./syntax/index.cjs.js");
|
|
21
23
|
const betterTable = require("./table/better-table.cjs.js");
|
|
22
24
|
const index$3 = require("./toolbar/index.cjs.js");
|
|
23
|
-
const index$
|
|
25
|
+
const index$c = require("./video/index.cjs.js");
|
|
24
26
|
const fontStyle = require("./attributors/font-style.cjs.js");
|
|
25
27
|
const fontSize = require("./attributors/font-size.cjs.js");
|
|
26
28
|
const lineHeight = require("./attributors/line-height.cjs.js");
|
|
@@ -47,6 +49,14 @@ const registerModules = function() {
|
|
|
47
49
|
"toolbar": {
|
|
48
50
|
handlers: {
|
|
49
51
|
...SnowTheme.DEFAULTS.modules.toolbar.handlers,
|
|
52
|
+
"formula": function() {
|
|
53
|
+
const mathlive = this.quill.getModule("mathlive");
|
|
54
|
+
if (!mathlive) {
|
|
55
|
+
this.quill.theme.tooltip.edit("formula");
|
|
56
|
+
} else {
|
|
57
|
+
mathlive.createDialog();
|
|
58
|
+
}
|
|
59
|
+
},
|
|
50
60
|
"undo": function() {
|
|
51
61
|
this.quill.history.undo();
|
|
52
62
|
},
|
|
@@ -72,8 +82,8 @@ const registerModules = function() {
|
|
|
72
82
|
"list": function(value) {
|
|
73
83
|
var _a, _b;
|
|
74
84
|
const range = this.quill.getSelection();
|
|
75
|
-
const
|
|
76
|
-
const preListValue = Array.isArray(
|
|
85
|
+
const formats2 = this.quill.getFormat(range);
|
|
86
|
+
const preListValue = Array.isArray(formats2.list) ? (_a = formats2.list[0]) == null ? void 0 : _a.value : (_b = formats2.list) == null ? void 0 : _b.value;
|
|
77
87
|
const curListValue = index.getListValue(value, preListValue);
|
|
78
88
|
const lines = this.quill.getLines(range.index, range.length);
|
|
79
89
|
const tableCols = lines.filter((line) => line.statics.blotName === "table-col" && !line.prev);
|
|
@@ -146,14 +156,16 @@ const registerModules = function() {
|
|
|
146
156
|
// 报错
|
|
147
157
|
// 'modules/quickmenu': QuickMenu,//暂未开发
|
|
148
158
|
"modules/syntax": index$8.default,
|
|
149
|
-
"
|
|
150
|
-
"formats/
|
|
151
|
-
"formats/
|
|
159
|
+
"modules/mathlive": index$9.default,
|
|
160
|
+
"formats/strike": index$a.default,
|
|
161
|
+
"formats/softBreak": index$b.default,
|
|
162
|
+
"formats/video": index$c.default,
|
|
152
163
|
"formats/emoji": index$6.default.EmojiBlot,
|
|
153
164
|
"formats/font": fontStyle.FontStyle,
|
|
154
165
|
"formats/size": fontSize.SizeStyle,
|
|
155
166
|
"formats/line-height": lineHeight.LineHeightStyle,
|
|
156
|
-
"formats/text-indent": textIndent.TextIndentStyle
|
|
167
|
+
"formats/text-indent": textIndent.TextIndentStyle,
|
|
168
|
+
[`formats/${formats.default.blotName}`]: formats.default
|
|
157
169
|
},
|
|
158
170
|
true
|
|
159
171
|
// 覆盖内部模块
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluent-editor.cjs.js","sources":["../../src/fluent-editor.ts"],"sourcesContent":["import type { Module, Parchment as TypeParchment } from 'quill'\r\nimport type { IEditorConfig } from './config/types'\r\nimport Quill from 'quill'\r\nimport { FontStyle, LineHeightStyle, SizeStyle, TextIndentStyle } from './attributors'\r\nimport { getListValue, ICONS_CONFIG, inputFile, TABLE_RIGHT_MENU_CONFIG } from './config'\r\nimport Counter from './counter' // 字符统计\r\nimport CustomClipboard from './custom-clipboard' // 粘贴板\r\nimport CustomImage from './custom-image/BlotFormatter' // 图片\r\nimport { CustomImageSpec } from './custom-image/specs/CustomImageSpec' // 图片拉伸模块\r\nimport CustomUploader from './custom-uploader' // 上传\r\nimport Emoji from './emoji' // 表情\r\nimport FileModule from './file' // 文件\r\nimport { FormatPainter } from './format-painter'\r\nimport { fullscreenHandler } from './fullscreen/handler'\r\nimport Link from './link' // 超链接\r\nimport Mention from './mention/Mention' // @提醒\r\nimport { Screenshot } from './screenshot'// 截图\r\nimport SoftBreak from './soft-break' // 软回车\r\nimport Strike from './strike' // 删除线\r\nimport CustomSyntax from './syntax' // 代码块高亮\r\nimport BetterTable from './table/better-table' // 表格\r\nimport Toolbar from './toolbar' // 工具栏\r\nimport Video from './video' // 视频\r\n// import GlobalLink from './global-link' // 全局链接\r\n// import QuickMenu from './quick-menu' // 快捷菜单\r\n\r\nexport class FluentEditor extends Quill {\r\n isFullscreen: boolean = false\r\n constructor(container: HTMLElement | string, options: IEditorConfig = {}) {\r\n super(container, options)\r\n }\r\n}\r\n\r\nconst registerModules = function () {\r\n const Icons = Quill.import('ui/icons')\r\n Object.entries(ICONS_CONFIG).forEach(([key, icon]) => {\r\n Icons[key] = icon\r\n })\r\n\r\n const SnowTheme = Quill.imports['themes/snow'] as typeof Module\r\n SnowTheme.DEFAULTS = {\r\n modules: {\r\n 'keyboard': {\r\n bindings: {\r\n ...BetterTable.keyboardBindings,\r\n },\r\n },\r\n 'toolbar': {\r\n handlers: {\r\n ...(SnowTheme.DEFAULTS as Record<string, any>).modules.toolbar.handlers,\r\n 'undo': function () {\r\n this.quill.history.undo()\r\n },\r\n 'redo': function () {\r\n this.quill.history.redo()\r\n },\r\n 'better-table': function () {\r\n this.quill.getModule('better-table').insertTable(3, 3)\r\n },\r\n 'file': function () {\r\n const accept = this.quill.options?.uploadOption?.fileAccept\r\n inputFile.call(this, 'file', accept)\r\n },\r\n 'image': function () {\r\n const accept = this.quill.options?.uploadOption?.imageAccept\r\n inputFile.call(this, 'image', accept)\r\n },\r\n 'emoji': function () {},\r\n 'fullscreen': fullscreenHandler,\r\n 'list': function (value) {\r\n const range = this.quill.getSelection()\r\n const formats = this.quill.getFormat(range)\r\n const preListValue = Array.isArray(formats.list) ? formats.list[0]?.value : formats.list?.value\r\n const curListValue = getListValue(value, preListValue)\r\n // 如果设置list的选区中有表格,判断第一个table-col位置,将表格前的内容设置为list格式\r\n const lines = this.quill.getLines(range.index, range.length)\r\n const tableCols = lines.filter(line => line.statics.blotName === 'table-col' && !line.prev)\r\n if (tableCols.length) {\r\n let start = range.index\r\n // 遍历table-col群组,以之获取表格,将表格前选区设置为对应list格式\r\n tableCols.forEach((item, index) => {\r\n const table = item.domNode.closest('table.quill-better-table')\r\n const tableBlot = Quill.find(table) as TypeParchment.Blot\r\n const tableLength = tableBlot.length()\r\n const tableStart = this.quill.getIndex(item)\r\n const tableEnd = tableStart + tableLength\r\n const beforeTableRangeLength = tableStart - start\r\n // 在表格前设置列表\r\n this.quill.setSelection(start, beforeTableRangeLength, Quill.sources.SILENT)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n table.parentNode.classList.remove('quill-better-table-selected')\r\n // 当前表格末尾为下一个选取的开始\r\n start = tableEnd\r\n if (index === tableCols.length - 1) {\r\n // 将最后一个表格之后所有选区内容设置list格式\r\n this.quill.setSelection(tableEnd, range.index + range.length - tableEnd)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n })\r\n }\r\n else {\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n },\r\n [FormatPainter.toolName]: FormatPainter,\r\n [Screenshot.toolName]: Screenshot,\r\n },\r\n },\r\n 'better-table': {\r\n operationMenu: {\r\n items: TABLE_RIGHT_MENU_CONFIG,\r\n color: true,\r\n },\r\n },\r\n 'image': {\r\n specs: [CustomImageSpec],\r\n overlay: {\r\n style: {\r\n border: '1px dashed rgb(68, 68, 68)',\r\n },\r\n },\r\n align: {\r\n icons: {\r\n left: '<i class=\"icon-text-align-left\"></i>',\r\n center: '<i class=\"icon-text-align-center\"></i>',\r\n right: '<i class=\"icon-text-align-right\"></i>',\r\n },\r\n },\r\n },\r\n },\r\n }\r\n\r\n FluentEditor.register(\r\n {\r\n 'modules/toolbar': Toolbar,\r\n 'modules/mention': Mention,\r\n 'modules/better-table': BetterTable,\r\n 'modules/clipboard': CustomClipboard,\r\n 'modules/uploader': CustomUploader, // 三者关联性最强\r\n 'modules/image': CustomImage, // 三者关联性最强\r\n 'modules/file': FileModule, // 三者关联性最强\r\n 'modules/counter': Counter,\r\n 'modules/emoji-toolbar': Emoji.ToolbarEmoji,\r\n 'modules/emoji-shortname': Emoji.ShortNameEmoji,\r\n // 'modules/global-link': GlobalLink,//暂未开发\r\n 'modules/link': Link, // 报错\r\n // 'modules/quickmenu': QuickMenu,//暂未开发\r\n 'modules/syntax': CustomSyntax,\r\n\r\n 'formats/strike': Strike,\r\n 'formats/softBreak': SoftBreak,\r\n 'formats/video': Video,\r\n 'formats/emoji': Emoji.EmojiBlot,\r\n 'formats/font': FontStyle,\r\n 'formats/size': SizeStyle,\r\n 'formats/line-height': LineHeightStyle,\r\n 'formats/text-indent': TextIndentStyle,\r\n },\r\n true, // 覆盖内部模块\r\n )\r\n\r\n return FluentEditor\r\n}\r\n\r\nexport default registerModules()\r\n"],"names":["ICONS_CONFIG","BetterTable","inputFile","fullscreenHandler","getListValue","index","FormatPainter","Screenshot","TABLE_RIGHT_MENU_CONFIG","CustomImageSpec","Toolbar","Mention","CustomClipboard","CustomUploader","CustomImage","FileModule","Counter","Emoji","Link","CustomSyntax","Strike","SoftBreak","Video","FontStyle","SizeStyle","LineHeightStyle","TextIndentStyle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fluent-editor.cjs.js","sources":["../../src/fluent-editor.ts"],"sourcesContent":["import type { Module, Parchment as TypeParchment } from 'quill'\r\nimport type { IEditorConfig } from './config/types'\r\nimport Quill from 'quill'\r\nimport { FontStyle, LineHeightStyle, SizeStyle, TextIndentStyle } from './attributors'\r\nimport { getListValue, ICONS_CONFIG, inputFile, TABLE_RIGHT_MENU_CONFIG } from './config'\r\nimport Counter from './counter' // 字符统计\r\nimport CustomClipboard from './custom-clipboard' // 粘贴板\r\nimport CustomImage from './custom-image/BlotFormatter' // 图片\r\nimport { CustomImageSpec } from './custom-image/specs/CustomImageSpec' // 图片拉伸模块\r\nimport CustomUploader from './custom-uploader' // 上传\r\nimport Emoji from './emoji' // 表情\r\nimport FileModule from './file' // 文件\r\nimport { FormatPainter } from './format-painter'\r\nimport { fullscreenHandler } from './fullscreen/handler'\r\nimport Link from './link' // 超链接\r\nimport MathliveModule from './mathlive' // latex公式\r\nimport MathliveBlot from './mathlive/formats'\r\nimport Mention from './mention/Mention' // @提醒\r\nimport { Screenshot } from './screenshot'// 截图\r\nimport SoftBreak from './soft-break' // 软回车\r\nimport Strike from './strike' // 删除线\r\nimport CustomSyntax from './syntax' // 代码块高亮\r\nimport BetterTable from './table/better-table' // 表格\r\nimport Toolbar from './toolbar' // 工具栏\r\nimport Video from './video' // 视频\r\n// import GlobalLink from './global-link' // 全局链接\r\n// import QuickMenu from './quick-menu' // 快捷菜单\r\n\r\nexport class FluentEditor extends Quill {\r\n isFullscreen: boolean = false\r\n constructor(container: HTMLElement | string, options: IEditorConfig = {}) {\r\n super(container, options)\r\n }\r\n}\r\n\r\nconst registerModules = function () {\r\n const Icons = Quill.import('ui/icons')\r\n Object.entries(ICONS_CONFIG).forEach(([key, icon]) => {\r\n Icons[key] = icon\r\n })\r\n\r\n const SnowTheme = Quill.imports['themes/snow'] as typeof Module\r\n SnowTheme.DEFAULTS = {\r\n modules: {\r\n 'keyboard': {\r\n bindings: {\r\n ...BetterTable.keyboardBindings,\r\n },\r\n },\r\n 'toolbar': {\r\n handlers: {\r\n ...(SnowTheme.DEFAULTS as Record<string, any>).modules.toolbar.handlers,\r\n 'formula': function () {\r\n const mathlive = this.quill.getModule('mathlive')\r\n if (!mathlive) {\r\n this.quill.theme.tooltip.edit('formula')\r\n }\r\n else {\r\n mathlive.createDialog()\r\n }\r\n },\r\n 'undo': function () {\r\n this.quill.history.undo()\r\n },\r\n 'redo': function () {\r\n this.quill.history.redo()\r\n },\r\n 'better-table': function () {\r\n this.quill.getModule('better-table').insertTable(3, 3)\r\n },\r\n 'file': function () {\r\n const accept = this.quill.options?.uploadOption?.fileAccept\r\n inputFile.call(this, 'file', accept)\r\n },\r\n 'image': function () {\r\n const accept = this.quill.options?.uploadOption?.imageAccept\r\n inputFile.call(this, 'image', accept)\r\n },\r\n 'emoji': function () {},\r\n 'fullscreen': fullscreenHandler,\r\n 'list': function (value) {\r\n const range = this.quill.getSelection()\r\n const formats = this.quill.getFormat(range)\r\n const preListValue = Array.isArray(formats.list) ? formats.list[0]?.value : formats.list?.value\r\n const curListValue = getListValue(value, preListValue)\r\n // 如果设置list的选区中有表格,判断第一个table-col位置,将表格前的内容设置为list格式\r\n const lines = this.quill.getLines(range.index, range.length)\r\n const tableCols = lines.filter(line => line.statics.blotName === 'table-col' && !line.prev)\r\n if (tableCols.length) {\r\n let start = range.index\r\n // 遍历table-col群组,以之获取表格,将表格前选区设置为对应list格式\r\n tableCols.forEach((item, index) => {\r\n const table = item.domNode.closest('table.quill-better-table')\r\n const tableBlot = Quill.find(table) as TypeParchment.Blot\r\n const tableLength = tableBlot.length()\r\n const tableStart = this.quill.getIndex(item)\r\n const tableEnd = tableStart + tableLength\r\n const beforeTableRangeLength = tableStart - start\r\n // 在表格前设置列表\r\n this.quill.setSelection(start, beforeTableRangeLength, Quill.sources.SILENT)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n table.parentNode.classList.remove('quill-better-table-selected')\r\n // 当前表格末尾为下一个选取的开始\r\n start = tableEnd\r\n if (index === tableCols.length - 1) {\r\n // 将最后一个表格之后所有选区内容设置list格式\r\n this.quill.setSelection(tableEnd, range.index + range.length - tableEnd)\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n })\r\n }\r\n else {\r\n this.quill.format('list', curListValue, Quill.sources.USER)\r\n }\r\n },\r\n [FormatPainter.toolName]: FormatPainter,\r\n [Screenshot.toolName]: Screenshot,\r\n },\r\n },\r\n 'better-table': {\r\n operationMenu: {\r\n items: TABLE_RIGHT_MENU_CONFIG,\r\n color: true,\r\n },\r\n },\r\n 'image': {\r\n specs: [CustomImageSpec],\r\n overlay: {\r\n style: {\r\n border: '1px dashed rgb(68, 68, 68)',\r\n },\r\n },\r\n align: {\r\n icons: {\r\n left: '<i class=\"icon-text-align-left\"></i>',\r\n center: '<i class=\"icon-text-align-center\"></i>',\r\n right: '<i class=\"icon-text-align-right\"></i>',\r\n },\r\n },\r\n },\r\n },\r\n }\r\n\r\n FluentEditor.register(\r\n {\r\n 'modules/toolbar': Toolbar,\r\n 'modules/mention': Mention,\r\n 'modules/better-table': BetterTable,\r\n 'modules/clipboard': CustomClipboard,\r\n 'modules/uploader': CustomUploader, // 三者关联性最强\r\n 'modules/image': CustomImage, // 三者关联性最强\r\n 'modules/file': FileModule, // 三者关联性最强\r\n 'modules/counter': Counter,\r\n 'modules/emoji-toolbar': Emoji.ToolbarEmoji,\r\n 'modules/emoji-shortname': Emoji.ShortNameEmoji,\r\n // 'modules/global-link': GlobalLink,//暂未开发\r\n 'modules/link': Link, // 报错\r\n // 'modules/quickmenu': QuickMenu,//暂未开发\r\n 'modules/syntax': CustomSyntax,\r\n 'modules/mathlive': MathliveModule,\r\n\r\n 'formats/strike': Strike,\r\n 'formats/softBreak': SoftBreak,\r\n 'formats/video': Video,\r\n 'formats/emoji': Emoji.EmojiBlot,\r\n 'formats/font': FontStyle,\r\n 'formats/size': SizeStyle,\r\n 'formats/line-height': LineHeightStyle,\r\n 'formats/text-indent': TextIndentStyle,\r\n [`formats/${MathliveBlot.blotName}`]: MathliveBlot,\r\n },\r\n true, // 覆盖内部模块\r\n )\r\n\r\n return FluentEditor\r\n}\r\n\r\nexport default registerModules()\r\n"],"names":["ICONS_CONFIG","BetterTable","inputFile","fullscreenHandler","formats","getListValue","index","FormatPainter","Screenshot","TABLE_RIGHT_MENU_CONFIG","CustomImageSpec","Toolbar","Mention","CustomClipboard","CustomUploader","CustomImage","FileModule","Counter","Emoji","Link","CustomSyntax","MathliveModule","Strike","SoftBreak","Video","FontStyle","SizeStyle","LineHeightStyle","TextIndentStyle","MathliveBlot"],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const Quill = require("quill");
|
|
4
|
+
const Parchment = Quill.import("parchment");
|
|
5
|
+
const _MathliveBlot = class _MathliveBlot extends Parchment.EmbedBlot {
|
|
6
|
+
constructor(scroll, domNode) {
|
|
7
|
+
super(scroll, domNode);
|
|
8
|
+
this.initFlag = false;
|
|
9
|
+
const dom = domNode;
|
|
10
|
+
dom.setAttribute("contenteditable", "false");
|
|
11
|
+
this.mode = dom.getAttribute("mode") || "only-read";
|
|
12
|
+
}
|
|
13
|
+
static create(obj) {
|
|
14
|
+
const el = super.create();
|
|
15
|
+
el.setAttribute("mode", obj.mode);
|
|
16
|
+
el.classList.add("view");
|
|
17
|
+
el.innerHTML = obj.value;
|
|
18
|
+
el.setValue(obj.value);
|
|
19
|
+
return el;
|
|
20
|
+
}
|
|
21
|
+
static value(domNode) {
|
|
22
|
+
return {
|
|
23
|
+
value: domNode.value,
|
|
24
|
+
mode: domNode.getAttribute("mode")
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
value() {
|
|
28
|
+
this.init();
|
|
29
|
+
return super.value();
|
|
30
|
+
}
|
|
31
|
+
init() {
|
|
32
|
+
if (this.initFlag) return;
|
|
33
|
+
if (this.mode === "only-read") return;
|
|
34
|
+
this.initFlag = true;
|
|
35
|
+
const dom = this.domNode;
|
|
36
|
+
this.quill = this.findQuillInstance();
|
|
37
|
+
if (this.mode === "dialog") {
|
|
38
|
+
dom.addEventListener("click", () => {
|
|
39
|
+
this.quill.getModule("mathlive").createDialog(dom.value);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
html() {
|
|
44
|
+
const formula = this.domNode.value;
|
|
45
|
+
return `<math-field class="ql-math-field view" contenteditable="false" mode="${this.mode}">${formula}</math-field>`;
|
|
46
|
+
}
|
|
47
|
+
findQuillInstance() {
|
|
48
|
+
if (this.quill) return this.quill;
|
|
49
|
+
let dom = this.domNode.parentElement;
|
|
50
|
+
while (dom) {
|
|
51
|
+
const quill = dom.quill;
|
|
52
|
+
if (quill instanceof Quill) {
|
|
53
|
+
return quill;
|
|
54
|
+
}
|
|
55
|
+
dom = dom.parentElement;
|
|
56
|
+
}
|
|
57
|
+
throw new Error("not found quill instance");
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
_MathliveBlot.blotName = "mathlive";
|
|
61
|
+
_MathliveBlot.tagName = "math-field";
|
|
62
|
+
_MathliveBlot.className = "ql-math-field";
|
|
63
|
+
let MathliveBlot = _MathliveBlot;
|
|
64
|
+
exports.default = MathliveBlot;
|
|
65
|
+
//# sourceMappingURL=formats.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.cjs.js","sources":["../../../src/mathlive/formats.ts"],"sourcesContent":["import type { MathfieldElement } from 'mathlive'\r\nimport type { Root } from 'parchment'\r\nimport Quill from 'quill'\r\n\r\nconst Parchment = Quill.import('parchment')\r\ntype MathliveBlotMode = 'dialog' | 'only-read'\r\nexport default class MathliveBlot extends Parchment.EmbedBlot {\r\n static blotName = 'mathlive'\r\n static tagName = 'math-field'\r\n static className = 'ql-math-field'\r\n quill?: Quill\r\n initFlag = false\r\n mode: MathliveBlotMode\r\n constructor(scroll: Root, domNode: Node) {\r\n super(scroll, domNode)\r\n const dom = domNode as HTMLElement\r\n dom.setAttribute('contenteditable', 'false')\r\n this.mode = (dom.getAttribute('mode')\r\n || 'only-read') as MathliveBlotMode\r\n }\r\n\r\n static create(obj: { value: string, mode: MathliveBlotMode }) {\r\n const el = super.create() as MathfieldElement\r\n el.setAttribute('mode', obj.mode)\r\n el.classList.add('view')\r\n el.innerHTML = obj.value\r\n el.setValue(obj.value)\r\n return el as MathfieldElement\r\n }\r\n\r\n static value(domNode: MathfieldElement) {\r\n return {\r\n value: domNode.value,\r\n mode: domNode.getAttribute('mode'),\r\n }\r\n }\r\n\r\n value() {\r\n this.init()\r\n return super.value()\r\n }\r\n\r\n init() {\r\n if (this.initFlag) return\r\n if (this.mode === 'only-read') return\r\n this.initFlag = true\r\n const dom = this.domNode as MathfieldElement\r\n this.quill = this.findQuillInstance()\r\n if (this.mode === 'dialog') {\r\n dom.addEventListener('click', () => {\r\n // @ts-ignore\r\n this.quill.getModule('mathlive').createDialog(dom.value)\r\n })\r\n }\r\n }\r\n\r\n html() {\r\n const formula = (this.domNode as MathfieldElement).value\r\n return `<math-field class=\"ql-math-field view\" contenteditable=\"false\" mode=\"${this.mode}\">${formula}</math-field>`\r\n }\r\n\r\n findQuillInstance(): Quill {\r\n if (this.quill) return this.quill\r\n let dom = (this.domNode as HTMLElement).parentElement\r\n while (dom) {\r\n const quill = (dom as any).quill\r\n if (quill instanceof Quill) {\r\n return quill\r\n }\r\n dom = dom.parentElement\r\n }\r\n throw new Error('not found quill instance')\r\n }\r\n}\r\n"],"names":[],"mappings":";;;AAIA,MAAM,YAAY,MAAM,OAAO,WAAW;AAErB,MAAA,gBAAA,MAAA,sBAAqB,UAAU,UAAU;AAAA,EAO5D,YAAY,QAAc,SAAe;AACvC,UAAM,QAAQ,OAAO;AAHZ,SAAA,WAAA;AAIT,UAAM,MAAM;AACR,QAAA,aAAa,mBAAmB,OAAO;AAC3C,SAAK,OAAQ,IAAI,aAAa,MAAM,KAC/B;AAAA,EACP;AAAA,EAEA,OAAO,OAAO,KAAgD;AACtD,UAAA,KAAK,MAAM;AACd,OAAA,aAAa,QAAQ,IAAI,IAAI;AAC7B,OAAA,UAAU,IAAI,MAAM;AACvB,OAAG,YAAY,IAAI;AAChB,OAAA,SAAS,IAAI,KAAK;AACd,WAAA;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,SAA2B;AAC/B,WAAA;AAAA,MACL,OAAO,QAAQ;AAAA,MACf,MAAM,QAAQ,aAAa,MAAM;AAAA,IAAA;AAAA,EAErC;AAAA,EAEA,QAAQ;AACN,SAAK,KAAK;AACV,WAAO,MAAM;EACf;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,SAAU;AACf,QAAA,KAAK,SAAS,YAAa;AAC/B,SAAK,WAAW;AAChB,UAAM,MAAM,KAAK;AACZ,SAAA,QAAQ,KAAK;AACd,QAAA,KAAK,SAAS,UAAU;AACtB,UAAA,iBAAiB,SAAS,MAAM;AAElC,aAAK,MAAM,UAAU,UAAU,EAAE,aAAa,IAAI,KAAK;AAAA,MAAA,CACxD;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO;AACC,UAAA,UAAW,KAAK,QAA6B;AACnD,WAAO,wEAAwE,KAAK,IAAI,KAAK,OAAO;AAAA,EACtG;AAAA,EAEA,oBAA2B;AACrB,QAAA,KAAK,MAAO,QAAO,KAAK;AACxB,QAAA,MAAO,KAAK,QAAwB;AACxC,WAAO,KAAK;AACV,YAAM,QAAS,IAAY;AAC3B,UAAI,iBAAiB,OAAO;AACnB,eAAA;AAAA,MACT;AACA,YAAM,IAAI;AAAA,IACZ;AACM,UAAA,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AACF;AAlEE,cAAO,WAAW;AAClB,cAAO,UAAU;AACjB,cAAO,YAAY;AAHA,IAAA,eAAA;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const Quill = require("quill");
|
|
4
|
+
const tooltip = require("./tooltip.cjs.js");
|
|
5
|
+
class MathliveModule extends Quill.Module {
|
|
6
|
+
constructor(quill, options) {
|
|
7
|
+
super(quill, options);
|
|
8
|
+
quill.root.quill = quill;
|
|
9
|
+
this.tooltip = new tooltip.default(quill);
|
|
10
|
+
}
|
|
11
|
+
async createDialog(value) {
|
|
12
|
+
this.tooltip.edit(value);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.default = MathliveModule;
|
|
16
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../src/mathlive/index.ts"],"sourcesContent":["import type Quill from 'quill'\r\nimport { Module } from 'quill'\r\nimport MathliveTooltip from './tooltip'\r\n\r\nexport default class MathliveModule extends Module<boolean> {\r\n tooltip: MathliveTooltip\r\n constructor(quill: Quill, options?: boolean) {\r\n super(quill, options)\r\n // @ts-ignore\r\n quill.root.quill = quill\r\n this.tooltip = new MathliveTooltip(quill)\r\n }\r\n\r\n async createDialog(value?: string) {\r\n this.tooltip.edit(value)\r\n }\r\n}\r\n"],"names":["Module","MathliveTooltip"],"mappings":";;;;AAIA,MAAqB,uBAAuBA,MAAAA,OAAgB;AAAA,EAE1D,YAAY,OAAc,SAAmB;AAC3C,UAAM,OAAO,OAAO;AAEpB,UAAM,KAAK,QAAQ;AACd,SAAA,UAAU,IAAIC,QAAA,QAAgB,KAAK;AAAA,EAC1C;AAAA,EAEA,MAAM,aAAa,OAAgB;AAC5B,SAAA,QAAQ,KAAK,KAAK;AAAA,EACzB;AACF;;"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const core = require("quill/core");
|
|
4
|
+
const Emitter = require("quill/core/emitter");
|
|
5
|
+
const Tooltip = require("quill/ui/tooltip");
|
|
6
|
+
const _MathliveTooltip = class _MathliveTooltip extends Tooltip {
|
|
7
|
+
constructor(quill, boundsContainer) {
|
|
8
|
+
super(quill, boundsContainer);
|
|
9
|
+
this.mathliveDom = document.createElement("math-field");
|
|
10
|
+
this.mathliveDom.classList.add("ql-math-field");
|
|
11
|
+
this.root.appendChild(this.mathliveDom);
|
|
12
|
+
this.root.classList.add("math-field-tooltip");
|
|
13
|
+
this.listen();
|
|
14
|
+
}
|
|
15
|
+
listen() {
|
|
16
|
+
this.mathliveDom.addEventListener("blur", (event) => {
|
|
17
|
+
this.hide();
|
|
18
|
+
});
|
|
19
|
+
this.root.addEventListener("keydown", (event) => {
|
|
20
|
+
if (event.key === "Enter") {
|
|
21
|
+
event.preventDefault();
|
|
22
|
+
this.save();
|
|
23
|
+
} else if (event.key === "Escape") {
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
this.cancel();
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
cancel() {
|
|
30
|
+
this.hide();
|
|
31
|
+
this.restoreFocus();
|
|
32
|
+
}
|
|
33
|
+
edit(value) {
|
|
34
|
+
this.editValue = value;
|
|
35
|
+
this.root.classList.remove("ql-hidden");
|
|
36
|
+
this.root.classList.add("ql-editing");
|
|
37
|
+
this.mathliveDom.setValue(value || "");
|
|
38
|
+
const range = this.quill.getSelection();
|
|
39
|
+
const bounds = range ? this.quill.getBounds(range) : null;
|
|
40
|
+
if (bounds != null) {
|
|
41
|
+
this.position(bounds);
|
|
42
|
+
}
|
|
43
|
+
this.show();
|
|
44
|
+
this.mathliveDom.focus();
|
|
45
|
+
}
|
|
46
|
+
restoreFocus() {
|
|
47
|
+
this.mathliveDom.blur();
|
|
48
|
+
this.quill.focus({ preventScroll: true });
|
|
49
|
+
}
|
|
50
|
+
save() {
|
|
51
|
+
const range = this.quill.getSelection(true);
|
|
52
|
+
const inputValue = this.mathliveDom.value;
|
|
53
|
+
if (!inputValue) return;
|
|
54
|
+
const index = range ? range.index : this.quill.getLength() - 1;
|
|
55
|
+
const delta = new core.Delta().retain(index).delete(this.editValue ? 1 : (range == null ? void 0 : range.length) || 0).insert({ mathlive: { value: inputValue, mode: "dialog" } });
|
|
56
|
+
this.quill.updateContents(delta, Emitter.sources.USER);
|
|
57
|
+
this.quill.setSelection(index + 1, Emitter.sources.USER);
|
|
58
|
+
this.hide();
|
|
59
|
+
}
|
|
60
|
+
position(reference) {
|
|
61
|
+
const adjustedReference = { ...reference };
|
|
62
|
+
adjustedReference.left = reference.left + this.root.offsetWidth / 2 - reference.width / 2;
|
|
63
|
+
return super.position(adjustedReference);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
_MathliveTooltip.TEMPLATE = ``;
|
|
67
|
+
let MathliveTooltip = _MathliveTooltip;
|
|
68
|
+
exports.default = MathliveTooltip;
|
|
69
|
+
//# sourceMappingURL=tooltip.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.cjs.js","sources":["../../../src/mathlive/tooltip.ts"],"sourcesContent":["import type { MathfieldElement } from 'mathlive'\r\nimport type Quill from 'quill'\r\nimport type { Bounds } from 'quill/core/selection'\r\nimport { Delta } from 'quill/core'\r\nimport Emitter from 'quill/core/emitter'\r\nimport Tooltip from 'quill/ui/tooltip'\r\n\r\nexport default class MathliveTooltip extends Tooltip {\r\n static TEMPLATE = ``\r\n\r\n mathliveDom: MathfieldElement\r\n editValue?: string\r\n\r\n constructor(quill: Quill, boundsContainer?: HTMLElement) {\r\n super(quill, boundsContainer)\r\n this.mathliveDom = document.createElement('math-field') as MathfieldElement\r\n this.mathliveDom.classList.add('ql-math-field')\r\n this.root.appendChild(this.mathliveDom)\r\n this.root.classList.add('math-field-tooltip')\r\n this.listen()\r\n }\r\n\r\n listen() {\r\n this.mathliveDom.addEventListener('blur', (event) => {\r\n this.hide()\r\n })\r\n this.root.addEventListener('keydown', (event) => {\r\n if (event.key === 'Enter') {\r\n event.preventDefault()\r\n this.save()\r\n }\r\n else if (event.key === 'Escape') {\r\n event.preventDefault()\r\n this.cancel()\r\n }\r\n })\r\n }\r\n\r\n cancel() {\r\n this.hide()\r\n this.restoreFocus()\r\n }\r\n\r\n edit(value?: string) {\r\n this.editValue = value\r\n this.root.classList.remove('ql-hidden')\r\n this.root.classList.add('ql-editing')\r\n this.mathliveDom.setValue(value || '')\r\n const range = this.quill.getSelection()\r\n const bounds = range ? this.quill.getBounds(range) : null\r\n if (bounds != null) {\r\n this.position(bounds)\r\n }\r\n this.show()\r\n this.mathliveDom.focus()\r\n }\r\n\r\n restoreFocus() {\r\n this.mathliveDom.blur()\r\n this.quill.focus({ preventScroll: true })\r\n }\r\n\r\n save() {\r\n const range = this.quill.getSelection(true)\r\n const inputValue = this.mathliveDom.value\r\n if (!inputValue) return\r\n const index = range ? range.index : this.quill.getLength() - 1\r\n const delta = new Delta()\r\n .retain(index)\r\n .delete(this.editValue ? 1 : range?.length || 0)\r\n .insert({ mathlive: { value: inputValue, mode: 'dialog' } })\r\n this.quill.updateContents(delta, Emitter.sources.USER)\r\n this.quill.setSelection(index + 1, Emitter.sources.USER)\r\n this.hide()\r\n }\r\n\r\n position(reference: Bounds) {\r\n const adjustedReference = { ...reference }\r\n adjustedReference.left = reference.left + this.root.offsetWidth / 2 - reference.width / 2\r\n return super.position(adjustedReference)\r\n }\r\n}\r\n"],"names":["Delta"],"mappings":";;;;;AAOA,MAAqB,mBAArB,MAAqB,yBAAwB,QAAQ;AAAA,EAMnD,YAAY,OAAc,iBAA+B;AACvD,UAAM,OAAO,eAAe;AACvB,SAAA,cAAc,SAAS,cAAc,YAAY;AACjD,SAAA,YAAY,UAAU,IAAI,eAAe;AACzC,SAAA,KAAK,YAAY,KAAK,WAAW;AACjC,SAAA,KAAK,UAAU,IAAI,oBAAoB;AAC5C,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,SAAS;AACP,SAAK,YAAY,iBAAiB,QAAQ,CAAC,UAAU;AACnD,WAAK,KAAK;AAAA,IAAA,CACX;AACD,SAAK,KAAK,iBAAiB,WAAW,CAAC,UAAU;AAC3C,UAAA,MAAM,QAAQ,SAAS;AACzB,cAAM,eAAe;AACrB,aAAK,KAAK;AAAA,MAAA,WAEH,MAAM,QAAQ,UAAU;AAC/B,cAAM,eAAe;AACrB,aAAK,OAAO;AAAA,MACd;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEA,SAAS;AACP,SAAK,KAAK;AACV,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,KAAK,OAAgB;AACnB,SAAK,YAAY;AACZ,SAAA,KAAK,UAAU,OAAO,WAAW;AACjC,SAAA,KAAK,UAAU,IAAI,YAAY;AAC/B,SAAA,YAAY,SAAS,SAAS,EAAE;AAC/B,UAAA,QAAQ,KAAK,MAAM,aAAa;AACtC,UAAM,SAAS,QAAQ,KAAK,MAAM,UAAU,KAAK,IAAI;AACrD,QAAI,UAAU,MAAM;AAClB,WAAK,SAAS,MAAM;AAAA,IACtB;AACA,SAAK,KAAK;AACV,SAAK,YAAY;EACnB;AAAA,EAEA,eAAe;AACb,SAAK,YAAY;AACjB,SAAK,MAAM,MAAM,EAAE,eAAe,KAAM,CAAA;AAAA,EAC1C;AAAA,EAEA,OAAO;AACL,UAAM,QAAQ,KAAK,MAAM,aAAa,IAAI;AACpC,UAAA,aAAa,KAAK,YAAY;AACpC,QAAI,CAAC,WAAY;AACjB,UAAM,QAAQ,QAAQ,MAAM,QAAQ,KAAK,MAAM,UAAc,IAAA;AACvD,UAAA,QAAQ,IAAIA,KAAA,MAAA,EACf,OAAO,KAAK,EACZ,OAAO,KAAK,YAAY,KAAI,+BAAO,WAAU,CAAC,EAC9C,OAAO,EAAE,UAAU,EAAE,OAAO,YAAY,MAAM,SAAS,EAAA,CAAG;AAC7D,SAAK,MAAM,eAAe,OAAO,QAAQ,QAAQ,IAAI;AACrD,SAAK,MAAM,aAAa,QAAQ,GAAG,QAAQ,QAAQ,IAAI;AACvD,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,SAAS,WAAmB;AACpB,UAAA,oBAAoB,EAAE,GAAG;AACb,sBAAA,OAAO,UAAU,OAAO,KAAK,KAAK,cAAc,IAAI,UAAU,QAAQ;AACjF,WAAA,MAAM,SAAS,iBAAiB;AAAA,EACzC;AACF;AAzEE,iBAAO,WAAW;AADpB,IAAqB,kBAArB;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentiny/fluent-editor",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.22.0-alpha.0",
|
|
4
4
|
"description": "A rich text editor based on Quill 2.0, which extends rich modules and formats on the basis of Quill. It's powerful and out-of-the-box.",
|
|
5
5
|
"author": "OpenTiny Team",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
"highlight.js": "^10.2.0",
|
|
44
44
|
"html2canvas": "^1.4.1",
|
|
45
45
|
"jest": "^26.6.3",
|
|
46
|
+
"mathlive": "^0.101.0",
|
|
47
|
+
"parchment": "^3.0.0",
|
|
46
48
|
"sass": "^1.47.0",
|
|
47
49
|
"shelljs": "^0.8.4",
|
|
48
50
|
"ts-jest": "^26.5.6",
|
|
@@ -51,4 +53,4 @@
|
|
|
51
53
|
"vite": "^5.0.0",
|
|
52
54
|
"vite-plugin-dts": "^4.3.0"
|
|
53
55
|
}
|
|
54
|
-
}
|
|
56
|
+
}
|
package/style.css
CHANGED
|
@@ -3602,6 +3602,36 @@ li.unchecked > .ql-ui {
|
|
|
3602
3602
|
border-top: 1px solid #333;
|
|
3603
3603
|
border-left: 1px solid #333;
|
|
3604
3604
|
}
|
|
3605
|
+
.ql-math-field {
|
|
3606
|
+
border: none;
|
|
3607
|
+
}
|
|
3608
|
+
.ql-math-field::part(virtual-keyboard-toggle) {
|
|
3609
|
+
height: unset;
|
|
3610
|
+
}
|
|
3611
|
+
.ql-math-field.view::part(menu-toggle) {
|
|
3612
|
+
display: none;
|
|
3613
|
+
}
|
|
3614
|
+
.ql-tooltip.math-field-tooltip {
|
|
3615
|
+
border: none !important;
|
|
3616
|
+
z-index: 10 !important;
|
|
3617
|
+
padding: 0 !important;
|
|
3618
|
+
}
|
|
3619
|
+
.ql-tooltip.math-field-tooltip::before {
|
|
3620
|
+
display: none;
|
|
3621
|
+
}
|
|
3622
|
+
.ql-tooltip.math-field-tooltip .ql-math-field {
|
|
3623
|
+
border: none;
|
|
3624
|
+
width: 400px;
|
|
3625
|
+
}
|
|
3626
|
+
.ql-tooltip.math-field-tooltip .ql-math-field::part(virtual-keyboard-toggle) {
|
|
3627
|
+
height: unset;
|
|
3628
|
+
}
|
|
3629
|
+
.ql-tooltip.math-field-tooltip .ql-math-field.view::part(menu-toggle) {
|
|
3630
|
+
display: none;
|
|
3631
|
+
}
|
|
3632
|
+
.ql-tooltip.math-field-tooltip .ql-math-field::part(container) {
|
|
3633
|
+
font-size: 24px;
|
|
3634
|
+
}
|
|
3605
3635
|
.ql-counter {
|
|
3606
3636
|
width: 100%;
|
|
3607
3637
|
bottom: 0;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SizeStyle: import('parchment').StyleAttributor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FontStyle: import('parchment').StyleAttributor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LineHeightStyle: import('parchment').StyleAttributor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TextIndentStyle: import('parchment').StyleAttributor;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MathfieldElement } from 'mathlive';
|
|
2
|
+
import { Root } from 'parchment';
|
|
3
|
+
import { default as Quill } from 'quill';
|
|
4
|
+
|
|
5
|
+
declare const Parchment: typeof import("parchment");
|
|
6
|
+
type MathliveBlotMode = 'dialog' | 'only-read';
|
|
7
|
+
export default class MathliveBlot extends Parchment.EmbedBlot {
|
|
8
|
+
static blotName: string;
|
|
9
|
+
static tagName: string;
|
|
10
|
+
static className: string;
|
|
11
|
+
quill?: Quill;
|
|
12
|
+
initFlag: boolean;
|
|
13
|
+
mode: MathliveBlotMode;
|
|
14
|
+
constructor(scroll: Root, domNode: Node);
|
|
15
|
+
static create(obj: {
|
|
16
|
+
value: string;
|
|
17
|
+
mode: MathliveBlotMode;
|
|
18
|
+
}): MathfieldElement;
|
|
19
|
+
static value(domNode: MathfieldElement): {
|
|
20
|
+
value: string;
|
|
21
|
+
mode: string;
|
|
22
|
+
};
|
|
23
|
+
value(): any;
|
|
24
|
+
init(): void;
|
|
25
|
+
html(): string;
|
|
26
|
+
findQuillInstance(): Quill;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as Quill, Module } from 'quill';
|
|
2
|
+
import { default as MathliveTooltip } from './tooltip';
|
|
3
|
+
|
|
4
|
+
export default class MathliveModule extends Module<boolean> {
|
|
5
|
+
tooltip: MathliveTooltip;
|
|
6
|
+
constructor(quill: Quill, options?: boolean);
|
|
7
|
+
createDialog(value?: string): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MathfieldElement } from 'mathlive';
|
|
2
|
+
import { default as Quill } from 'quill';
|
|
3
|
+
import { Bounds } from 'quill/core/selection';
|
|
4
|
+
import { default as Tooltip } from 'quill/ui/tooltip';
|
|
5
|
+
|
|
6
|
+
export default class MathliveTooltip extends Tooltip {
|
|
7
|
+
static TEMPLATE: string;
|
|
8
|
+
mathliveDom: MathfieldElement;
|
|
9
|
+
editValue?: string;
|
|
10
|
+
constructor(quill: Quill, boundsContainer?: HTMLElement);
|
|
11
|
+
listen(): void;
|
|
12
|
+
cancel(): void;
|
|
13
|
+
edit(value?: string): void;
|
|
14
|
+
restoreFocus(): void;
|
|
15
|
+
save(): void;
|
|
16
|
+
position(reference: Bounds): number;
|
|
17
|
+
}
|