更新依赖项,添加侧边栏样式,优化获取页面内容的逻辑

master
joefalmko 1 week ago
parent 672415881c
commit df52ddd35e

@ -31,7 +31,9 @@
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
"eslint-plugin-vue": "^8.0.3",
"unplugin-auto-import": "^0.16.1",
"unplugin-vue-components": "^0.25.0"
}
},
"node_modules/@achrinza/node-ipc": {
@ -61,6 +63,15 @@
"node": ">=6.0.0"
}
},
"node_modules/@antfu/utils": {
"version": "0.7.10",
"resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.10.tgz",
"integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@babel/code-frame": {
"version": "7.26.0",
"resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.26.0.tgz",
@ -2676,6 +2687,40 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.3",
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz",
"integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/pluginutils/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz",
@ -3847,9 +3892,9 @@
}
},
"node_modules/acorn": {
"version": "8.13.0",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.13.0.tgz",
"integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==",
"version": "8.14.0",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@ -4928,6 +4973,12 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
"node_modules/confbox": {
"version": "0.1.8",
"resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz",
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
"dev": true
},
"node_modules/connect-history-api-fallback": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
@ -8028,6 +8079,22 @@
"json5": "lib/cli.js"
}
},
"node_modules/local-pkg": {
"version": "0.5.0",
"resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.0.tgz",
"integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
"dev": true,
"dependencies": {
"mlly": "^1.4.2",
"pkg-types": "^1.0.3"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
@ -8567,6 +8634,18 @@
"mkdirp": "bin/cmd.js"
}
},
"node_modules/mlly": {
"version": "1.7.3",
"resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.7.3.tgz",
"integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==",
"dev": true,
"dependencies": {
"acorn": "^8.14.0",
"pathe": "^1.1.2",
"pkg-types": "^1.2.1",
"ufo": "^1.5.4"
}
},
"node_modules/module-alias": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz",
@ -9153,6 +9232,12 @@
"node": ">=8"
}
},
"node_modules/pathe": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/pathe/-/pathe-1.1.2.tgz",
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
"dev": true
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
@ -9182,6 +9267,17 @@
"node": ">=8"
}
},
"node_modules/pkg-types": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.2.1.tgz",
"integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==",
"dev": true,
"dependencies": {
"confbox": "^0.1.8",
"mlly": "^1.7.2",
"pathe": "^1.1.2"
}
},
"node_modules/portfinder": {
"version": "1.0.32",
"resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.32.tgz",
@ -10335,6 +10431,12 @@
"url": "https://opencollective.com/webpack"
}
},
"node_modules/scule": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
"dev": true
},
"node_modules/select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz",
@ -10861,6 +10963,24 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-literal": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-2.1.0.tgz",
"integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
"dev": true,
"dependencies": {
"js-tokens": "^9.0.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/strip-literal/node_modules/js-tokens": {
"version": "9.0.0",
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.0.tgz",
"integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
"dev": true
},
"node_modules/stylehacks": {
"version": "5.1.1",
"resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.1.tgz",
@ -11237,6 +11357,12 @@
"node": ">= 0.6"
}
},
"node_modules/ufo": {
"version": "1.5.4",
"resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.5.4.tgz",
"integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
"dev": true
},
"node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz",
@ -11283,6 +11409,48 @@
"node": ">=4"
}
},
"node_modules/unimport": {
"version": "3.13.2",
"resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.13.2.tgz",
"integrity": "sha512-VKAepeIb6BWLtBl4tmyHY1/7rJgz3ynmZrWf8cU1a+v5Uv/k1gyyAEeGBnYcrwy8bxG5sflxEx4a9VQUqOVHUA==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^5.1.3",
"acorn": "^8.14.0",
"escape-string-regexp": "^5.0.0",
"estree-walker": "^3.0.3",
"fast-glob": "^3.3.2",
"local-pkg": "^0.5.0",
"magic-string": "^0.30.12",
"mlly": "^1.7.3",
"pathe": "^1.1.2",
"pkg-types": "^1.2.1",
"scule": "^1.3.0",
"strip-literal": "^2.1.0",
"unplugin": "^1.15.0"
}
},
"node_modules/unimport/node_modules/escape-string-regexp": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/unimport/node_modules/estree-walker": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.0"
}
},
"node_modules/universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
@ -11301,6 +11469,167 @@
"node": ">= 0.8"
}
},
"node_modules/unplugin": {
"version": "1.16.0",
"resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-1.16.0.tgz",
"integrity": "sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==",
"dev": true,
"dependencies": {
"acorn": "^8.14.0",
"webpack-virtual-modules": "^0.6.2"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/unplugin-auto-import": {
"version": "0.16.1",
"resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.16.1.tgz",
"integrity": "sha512-H3Ky56cGEEHTssxUIFuGXTowGVlT/Bp3MBx1yyCzUHzAtdrO+2r9zpid32f2AkTpQxo2lch6yaTK61Im+rEyPQ==",
"dev": true,
"dependencies": {
"@antfu/utils": "^0.7.2",
"@rollup/pluginutils": "^5.0.2",
"local-pkg": "^0.4.3",
"magic-string": "^0.30.0",
"minimatch": "^9.0.1",
"unimport": "^3.0.7",
"unplugin": "^1.3.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@nuxt/kit": "^3.2.2",
"@vueuse/core": "*"
},
"peerDependenciesMeta": {
"@nuxt/kit": {
"optional": true
},
"@vueuse/core": {
"optional": true
}
}
},
"node_modules/unplugin-auto-import/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/unplugin-auto-import/node_modules/local-pkg": {
"version": "0.4.3",
"resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz",
"integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
"dev": true,
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/unplugin-auto-import/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/unplugin-vue-components": {
"version": "0.25.0",
"resolved": "https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-0.25.0.tgz",
"integrity": "sha512-HxrQ4GMSS1RwVww2av3a42cABo/v5AmTRN9iARv6e/xwkrfTyHhLh84kFwXxKkXK61vxDHxaryn694mQmkiVBg==",
"dev": true,
"dependencies": {
"@antfu/utils": "^0.7.3",
"@rollup/pluginutils": "^5.0.2",
"chokidar": "^3.5.3",
"debug": "^4.3.4",
"fast-glob": "^3.2.12",
"local-pkg": "^0.4.3",
"magic-string": "^0.30.0",
"minimatch": "^9.0.1",
"resolve": "^1.22.2",
"unplugin": "^1.3.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@babel/parser": "^7.15.8",
"@nuxt/kit": "^3.2.2",
"vue": "2 || 3"
},
"peerDependenciesMeta": {
"@babel/parser": {
"optional": true
},
"@nuxt/kit": {
"optional": true
}
}
},
"node_modules/unplugin-vue-components/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/unplugin-vue-components/node_modules/local-pkg": {
"version": "0.4.3",
"resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz",
"integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
"dev": true,
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/unplugin-vue-components/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/unplugin/node_modules/webpack-virtual-modules": {
"version": "0.6.2",
"resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
"dev": true
},
"node_modules/update-browserslist-db": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",

@ -31,7 +31,9 @@
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
"eslint-plugin-vue": "^8.0.3",
"unplugin-auto-import": "^0.16.1",
"unplugin-vue-components": "^0.25.0"
},
"eslintConfig": {
"root": true,

@ -1,18 +1,101 @@
import {
AccessibilityHelp,
Alignment,
Autoformat,
AutoImage,
AutoLink,
Autosave,
BalloonToolbar,
Base64UploadAdapter,
BlockQuote,
Bold,
Code,
CodeBlock,
Essentials,
FindAndReplace,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
GeneralHtmlSupport,
Heading,
Highlight,
HorizontalLine,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Italic,
Link,
LinkImage,
List,
ListProperties,
Markdown,
MediaEmbed,
Mention,
PageBreak,
Paragraph,
PasteFromMarkdownExperimental,
PasteFromOffice,
RemoveFormat,
SelectAll,
SpecialCharacters,
SpecialCharactersArrows,
SpecialCharactersCurrency,
SpecialCharactersEssentials,
SpecialCharactersLatin,
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
Style,
Subscript,
Superscript,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TextTransformation,
TodoList,
Underline,
Undo,
Plugin,
ButtonView,
createDropdown,
Collection,
addListToDropdown,
} from 'ckeditor5';
import translations from 'ckeditor5/translations/zh-cn.js';
import { asBlob } from 'html-docx-js-typescript'
import { saveAs } from 'file-saver';
import {
getStyle,
getPageContent
getPageContent,
getUserConfigFromBackend,
saveData
} from './utils';
// 导出为docx插件
function exportWord(){
const pageContent = getPageContent();
const style = getStyle();
const page = '<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style>@media print{@page{size:A4 portrait;margin:0cm 3cm}@page:left{margin-left:2.5cm;margin-right:2.7cm;}@page:right{margin-left:2.7cm;margin-right:2.5cm;}}</style>' + style + '</head><body>' + pageContent + '</body></html>'
// console.log(page);
asBlob(page).then(data => {
saveAs(data, 'file.docx') // save as docx file
}); // asBlob() return Promise<Blob|Buffer>
}
class Export2Word extends Plugin {
init() {
const editor = this.editor;
@ -27,22 +110,20 @@ class Export2Word extends Plugin {
tooltip: true,
// 图标 直接插入svg文件
icon: '<svg t="1730216969869" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2612" width="200" height="200"><path d="M576 832H224c-17.6 0-32-14.4-32-32V192h608c17.6 0 32 14.4 32 32v288c0 17.7 14.3 32 32 32s32-14.3 32-32V224c0-52.9-43.1-96-96-96H160c-17.7 0-32 14.3-32 32v640c0 52.9 43.1 96 96 96h352c17.7 0 32-14.3 32-32s-14.3-32-32-32z" p-id="2613"></path><path d="M951.7 757.5c0.2-0.2 0.4-0.5 0.6-0.7 0.1-0.2 0.3-0.3 0.4-0.5 0.2-0.3 0.4-0.6 0.7-0.8 0.1-0.1 0.2-0.3 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.2 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.3 0.2-0.4 0.2-0.3 0.4-0.6 0.5-0.9 0.1-0.1 0.2-0.3 0.3-0.4 0.2-0.3 0.3-0.6 0.4-0.9 0.1-0.2 0.2-0.4 0.3-0.5 0.1-0.3 0.2-0.5 0.4-0.8 0.1-0.2 0.2-0.4 0.3-0.7 0.1-0.2 0.2-0.5 0.3-0.7 0.1-0.3 0.2-0.5 0.3-0.8 0.1-0.2 0.1-0.4 0.2-0.6l0.3-0.9c0.1-0.2 0.1-0.4 0.2-0.6 0.1-0.3 0.2-0.6 0.3-1 0-0.2 0.1-0.3 0.1-0.5 0.1-0.3 0.2-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.5 0.1-0.3 0.1-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.6 0-0.3 0.1-0.6 0.1-0.9 0-0.3 0-0.5 0.1-0.8 0-0.2 0-0.5 0.1-0.7 0.1-1.1 0.1-2.1 0-3.2 0-0.3 0-0.5-0.1-0.7 0-0.3 0-0.5-0.1-0.8 0-0.3-0.1-0.6-0.1-0.9 0-0.2 0-0.4-0.1-0.6 0-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.4-0.1-0.5-0.1-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.3-0.1-0.5-0.1-0.3-0.2-0.6-0.3-1-0.1-0.2-0.1-0.4-0.2-0.6l-0.3-0.9c-0.1-0.2-0.1-0.4-0.2-0.6-0.1-0.3-0.2-0.5-0.3-0.8-0.1-0.2-0.2-0.5-0.3-0.7-0.1-0.2-0.2-0.4-0.3-0.7-0.1-0.3-0.2-0.5-0.4-0.8-0.1-0.2-0.2-0.4-0.3-0.5-0.1-0.3-0.3-0.6-0.4-0.9-0.1-0.2-0.2-0.3-0.3-0.4-0.2-0.3-0.3-0.6-0.5-0.9-0.1-0.1-0.2-0.3-0.2-0.4l-0.6-0.9c-0.1-0.1-0.2-0.2-0.3-0.4l-0.6-0.9c-0.1-0.1-0.2-0.3-0.3-0.4-0.2-0.3-0.4-0.6-0.7-0.8-0.1-0.2-0.3-0.3-0.4-0.5-0.2-0.2-0.4-0.5-0.6-0.7-0.2-0.2-0.4-0.5-0.7-0.7l-0.4-0.4-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l73.4 73.4H592c-17.7 0-32 14.3-32 32s14.3 32 32 32h258.7l-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3 6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4l128-128 0.4-0.4c0.4-0.6 0.6-0.9 0.8-1.1z" p-id="2614"></path><path d="M709.3 320.4c-17.4-2.9-33.9 8.9-36.8 26.3l-42.8 256.9-87.3-261.8c-4.4-13-16.6-21.8-30.4-21.8-13.8 0-26 8.8-30.4 21.9l-87.3 261.8-42.8-256.9c-2.9-17.4-19.4-29.2-36.8-26.3-17.4 2.9-29.2 19.4-26.3 36.8l64 384c2.4 14.5 14.4 25.5 29.1 26.6 14.7 1.1 28.2-7.8 32.9-21.8L512 453.2l66.4 199.1c3.9 11.8 15 19.8 27.4 19.8h52.9c14.1 0 26.2-10.2 28.5-24.1l48.4-290.6c2.9-17.6-8.9-34.1-26.3-37z" p-id="2615"></path></svg>'
icon: '<svg t="1730216969869" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2612" width="200" height="200"><path d="M576 832H224c-17.6 0-32-14.4-32-32V192h608c17.6 0 32 14.4 32 32v288c0 17.7 14.3 32 32 32s32-14.3 32-32V224c0-52.9-43.1-96-96-96H160c-17.7 0-32 14.3-32 32v640c0 52.9 43.1 96 96 96h352c17.7 0 32-14.3 32-32s-14.3-32-32-32z" p-id="2613"></path><path d="M951.7 757.5c0.2-0.2 0.4-0.5 0.6-0.7 0.1-0.2 0.3-0.3 0.4-0.5 0.2-0.3 0.4-0.6 0.7-0.8 0.1-0.1 0.2-0.3 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.2 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.3 0.2-0.4 0.2-0.3 0.4-0.6 0.5-0.9 0.1-0.1 0.2-0.3 0.3-0.4 0.2-0.3 0.3-0.6 0.4-0.9 0.1-0.2 0.2-0.4 0.3-0.5 0.1-0.3 0.2-0.5 0.4-0.8 0.1-0.2 0.2-0.4 0.3-0.7 0.1-0.2 0.2-0.5 0.3-0.7 0.1-0.3 0.2-0.5 0.3-0.8 0.1-0.2 0.1-0.4 0.2-0.6l0.3-0.9c0.1-0.2 0.1-0.4 0.2-0.6 0.1-0.3 0.2-0.6 0.3-1 0-0.2 0.1-0.3 0.1-0.5 0.1-0.3 0.2-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.5 0.1-0.3 0.1-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.6 0-0.3 0.1-0.6 0.1-0.9 0-0.3 0-0.5 0.1-0.8 0-0.2 0-0.5 0.1-0.7 0.1-1.1 0.1-2.1 0-3.2 0-0.3 0-0.5-0.1-0.7 0-0.3 0-0.5-0.1-0.8 0-0.3-0.1-0.6-0.1-0.9 0-0.2 0-0.4-0.1-0.6 0-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.4-0.1-0.5-0.1-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.3-0.1-0.5-0.1-0.3-0.2-0.6-0.3-1-0.1-0.2-0.1-0.4-0.2-0.6l-0.3-0.9c-0.1-0.2-0.1-0.4-0.2-0.6-0.1-0.3-0.2-0.5-0.3-0.8-0.1-0.2-0.2-0.5-0.3-0.7-0.1-0.2-0.2-0.4-0.3-0.7-0.1-0.3-0.2-0.5-0.4-0.8-0.1-0.2-0.2-0.4-0.3-0.5-0.1-0.3-0.3-0.6-0.4-0.9-0.1-0.2-0.2-0.3-0.3-0.4-0.2-0.3-0.3-0.6-0.5-0.9-0.1-0.1-0.2-0.3-0.2-0.4l-0.6-0.9c-0.1-0.1-0.2-0.2-0.3-0.4l-0.6-0.9c-0.1-0.1-0.2-0.3-0.3-0.4-0.2-0.3-0.4-0.6-0.7-0.8-0.1-0.2-0.3-0.3-0.4-0.5-0.2-0.2-0.4-0.5-0.6-0.7-0.2-0.2-0.4-0.5-0.7-0.7l-0.4-0.4-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l73.4 73.4H592c-17.7 0-32 14.3-32 32s14.3 32 32 32h258.7l-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3 6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4l128-128 0.4-0.4c0.4-0.6 0.6-0.9 0.8-1.1z" p-id="2614"></path><path d="M709.3 320.4c-17.4-2.9-33.9 8.9-36.8 26.3l-42.8 256.9-87.3-261.8c-4.4-13-16.6-21.8-30.4-21.8-13.8 0-26 8.8-30.4 21.9l-87.3 261.8-42.8-256.9c-2.9-17.4-19.4-29.2-36.8-26.3-17.4 2.9-29.2 19.4-26.3 36.8l64 384c2.4 14.5 14.4 25.5 29.1 26.6 14.7 1.1 28.2-7.8 32.9-21.8L512 453.2l66.4 199.1c3.9 11.8 15 19.8 27.4 19.8h52.9c14.1 0 26.2-10.2 28.5-24.1l48.4-290.6c2.9-17.6-8.9-34.1-26.3-37z" p-id="2615"></path></svg>',
keystroke: 'Ctrl+W'
});
// Execute a callback function when the button is clicked
button.on('execute', () => {
const pageContent = getPageContent();
const style = getStyle();
const page = '<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style>@media print{@page{size:A4 portrait;margin:0cm 3cm}@page:left{margin-left:2.5cm;margin-right:2.7cm;}@page:right{margin-left:2.7cm;margin-right:2.5cm;}}</style>' + style + '</head><body>' + pageContent + '</body></html>'
// console.log(page);
asBlob(page).then(data => {
saveAs(data, 'file.docx') // save as docx file
}); // asBlob() return Promise<Blob|Buffer>
exportWord();
});
// 添加快捷键 Ctrl+W 导出为docx
editor.keystrokes.set('Ctrl+W', (event, cancel) => {
exportWord();
cancel();
});
return button;
});
@ -66,7 +147,22 @@ class Export2Word extends Plugin {
}
}
// 导出为PDF插件
function printPDF() {
const pageContent = getPageContent();
console.log(pageContent);
const style = getStyle();
// 去掉element中的 ck-focused ck-weight_selected消除页面和图片的蓝边
const page = '<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style>@media print{@page{size:A4 portrait;margin:0cm 3cm}@page:left{margin-left:2.5cm;margin-right:2.7cm;}@page:right{margin-left:2.7cm;margin-right:2.5cm;}}</style>' + style + '</head><body>' + pageContent.replaceAll('ck-focused', 'ck-blurred').replaceAll('ck-weight_selected', '') + '</body></html>'
const newWindow = window.open('', 'PrintDocument', 'height=600,width=700,top=50,left=50');
newWindow.document.write(page);
newWindow.document.close();
newWindow.print();
newWindow.onafterprint = function () {
newWindow.close();
}
}
class Export2PDF extends Plugin {
init() {
const editor = this.editor;
@ -81,30 +177,26 @@ class Export2PDF extends Plugin {
tooltip: true,
// 图标 直接插入svg文件
icon: '<svg t="1730309942693" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2589" width="200" height="200"><path d="M576 832H224c-17.6 0-32-14.4-32-32V192h608c17.6 0 32 14.4 32 32v288c0 17.7 14.3 32 32 32s32-14.3 32-32V224c0-52.9-43.1-96-96-96H160c-17.7 0-32 14.3-32 32v640c0 52.9 43.1 96 96 96h352c17.7 0 32-14.3 32-32s-14.3-32-32-32z" p-id="2590"></path><path d="M960 734.4c0-0.3 0-0.5-0.1-0.7 0-0.3 0-0.5-0.1-0.8 0-0.3-0.1-0.6-0.1-0.9 0-0.2 0-0.4-0.1-0.6 0-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.4-0.1-0.5-0.1-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.3-0.1-0.5-0.1-0.3-0.2-0.6-0.3-1-0.1-0.2-0.1-0.4-0.2-0.6l-0.3-0.9c-0.1-0.2-0.1-0.4-0.2-0.6-0.1-0.3-0.2-0.5-0.3-0.8-0.1-0.2-0.2-0.5-0.3-0.7-0.1-0.2-0.2-0.4-0.3-0.7-0.1-0.3-0.2-0.5-0.4-0.8-0.1-0.2-0.2-0.4-0.3-0.5-0.1-0.3-0.3-0.6-0.4-0.9-0.1-0.2-0.2-0.3-0.3-0.4-0.2-0.3-0.3-0.6-0.5-0.9-0.1-0.1-0.2-0.3-0.2-0.4l-0.6-0.9c-0.1-0.1-0.2-0.2-0.3-0.4l-0.6-0.9c-0.1-0.1-0.2-0.3-0.3-0.4-0.2-0.3-0.4-0.6-0.7-0.8-0.1-0.2-0.3-0.3-0.4-0.5-0.2-0.2-0.4-0.5-0.6-0.7-0.2-0.2-0.4-0.5-0.7-0.7l-0.4-0.4-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l73.4 73.4H592c-17.7 0-32 14.3-32 32s14.3 32 32 32h258.7l-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3 6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4l128-128 0.4-0.4 0.7-0.7c0.2-0.2 0.4-0.5 0.6-0.7 0.1-0.2 0.3-0.3 0.4-0.5 0.2-0.3 0.4-0.6 0.7-0.8 0.1-0.1 0.2-0.3 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.2 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.3 0.2-0.4 0.2-0.3 0.4-0.6 0.5-0.9 0.1-0.1 0.2-0.3 0.3-0.4 0.2-0.3 0.3-0.6 0.4-0.9 0.1-0.2 0.2-0.4 0.3-0.5 0.1-0.3 0.2-0.5 0.4-0.8 0.1-0.2 0.2-0.4 0.3-0.7 0.1-0.2 0.2-0.5 0.3-0.7 0.1-0.3 0.2-0.5 0.3-0.8 0.1-0.2 0.1-0.4 0.2-0.6l0.3-0.9c0.1-0.2 0.1-0.4 0.2-0.6 0.1-0.3 0.2-0.6 0.3-1 0-0.2 0.1-0.3 0.1-0.5 0.1-0.3 0.2-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.5 0.1-0.3 0.1-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.6 0-0.3 0.1-0.6 0.1-0.9 0-0.3 0-0.5 0.1-0.8 0-0.2 0-0.5 0.1-0.7-0.1-1.5-0.1-2.5-0.1-3.6zM352 320c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32s32-14.3 32-32V576h192c70.6 0 128-57.4 128-128s-57.4-128-128-128H352z m288 128c0 35.3-28.7 64-64 64H384V384h192c35.3 0 64 28.7 64 64z" p-id="2591"></path></svg>'
icon: '<svg t="1730309942693" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2589" width="200" height="200"><path d="M576 832H224c-17.6 0-32-14.4-32-32V192h608c17.6 0 32 14.4 32 32v288c0 17.7 14.3 32 32 32s32-14.3 32-32V224c0-52.9-43.1-96-96-96H160c-17.7 0-32 14.3-32 32v640c0 52.9 43.1 96 96 96h352c17.7 0 32-14.3 32-32s-14.3-32-32-32z" p-id="2590"></path><path d="M960 734.4c0-0.3 0-0.5-0.1-0.7 0-0.3 0-0.5-0.1-0.8 0-0.3-0.1-0.6-0.1-0.9 0-0.2 0-0.4-0.1-0.6 0-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.4-0.1-0.5-0.1-0.3-0.1-0.7-0.2-1 0-0.2-0.1-0.3-0.1-0.5-0.1-0.3-0.2-0.6-0.3-1-0.1-0.2-0.1-0.4-0.2-0.6l-0.3-0.9c-0.1-0.2-0.1-0.4-0.2-0.6-0.1-0.3-0.2-0.5-0.3-0.8-0.1-0.2-0.2-0.5-0.3-0.7-0.1-0.2-0.2-0.4-0.3-0.7-0.1-0.3-0.2-0.5-0.4-0.8-0.1-0.2-0.2-0.4-0.3-0.5-0.1-0.3-0.3-0.6-0.4-0.9-0.1-0.2-0.2-0.3-0.3-0.4-0.2-0.3-0.3-0.6-0.5-0.9-0.1-0.1-0.2-0.3-0.2-0.4l-0.6-0.9c-0.1-0.1-0.2-0.2-0.3-0.4l-0.6-0.9c-0.1-0.1-0.2-0.3-0.3-0.4-0.2-0.3-0.4-0.6-0.7-0.8-0.1-0.2-0.3-0.3-0.4-0.5-0.2-0.2-0.4-0.5-0.6-0.7-0.2-0.2-0.4-0.5-0.7-0.7l-0.4-0.4-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l73.4 73.4H592c-17.7 0-32 14.3-32 32s14.3 32 32 32h258.7l-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3 6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4l128-128 0.4-0.4 0.7-0.7c0.2-0.2 0.4-0.5 0.6-0.7 0.1-0.2 0.3-0.3 0.4-0.5 0.2-0.3 0.4-0.6 0.7-0.8 0.1-0.1 0.2-0.3 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.2 0.3-0.4l0.6-0.9c0.1-0.1 0.2-0.3 0.2-0.4 0.2-0.3 0.4-0.6 0.5-0.9 0.1-0.1 0.2-0.3 0.3-0.4 0.2-0.3 0.3-0.6 0.4-0.9 0.1-0.2 0.2-0.4 0.3-0.5 0.1-0.3 0.2-0.5 0.4-0.8 0.1-0.2 0.2-0.4 0.3-0.7 0.1-0.2 0.2-0.5 0.3-0.7 0.1-0.3 0.2-0.5 0.3-0.8 0.1-0.2 0.1-0.4 0.2-0.6l0.3-0.9c0.1-0.2 0.1-0.4 0.2-0.6 0.1-0.3 0.2-0.6 0.3-1 0-0.2 0.1-0.3 0.1-0.5 0.1-0.3 0.2-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.5 0.1-0.3 0.1-0.7 0.2-1 0-0.2 0.1-0.4 0.1-0.6 0-0.3 0.1-0.6 0.1-0.9 0-0.3 0-0.5 0.1-0.8 0-0.2 0-0.5 0.1-0.7-0.1-1.5-0.1-2.5-0.1-3.6zM352 320c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32s32-14.3 32-32V576h192c70.6 0 128-57.4 128-128s-57.4-128-128-128H352z m288 128c0 35.3-28.7 64-64 64H384V384h192c35.3 0 64 28.7 64 64z" p-id="2591"></path></svg>',
keystroke: 'Ctrl+P'
});
// Execute a callback function when the button is clicked
button.on('execute', () => {
const pageContent = getPageContent();
console.log(pageContent);
const style = getStyle();
// 去掉element中的 ck-focused ck-weight_selected消除页面和图片的蓝边
const page = '<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style>@media print{@page{size:A4 portrait;margin:0cm 3cm}@page:left{margin-left:2.5cm;margin-right:2.7cm;}@page:right{margin-left:2.7cm;margin-right:2.5cm;}}</style>' + style + '</head><body>' + pageContent.replaceAll('ck-focused', 'ck-blurred').replaceAll('ck-weight_selected', '') + '</body></html>'
const newWindow = window.open('', 'PrintDocument', 'height=600,width=700,top=50,left=50');
newWindow.document.write(page);
newWindow.document.close();
newWindow.print();
newWindow.onafterprint = function () {
newWindow.close();
}
printPDF();
});
// 添加快捷键 Ctrl+P 导出为PDF
editor.keystrokes.set('Ctrl+P', (event, cancel) => {
printPDF();
cancel();
});
return button;
});
}
}
// 智能润色插件
class Translation extends Plugin {
init() {
@ -174,7 +266,8 @@ class Translation extends Plugin {
});
}
}
// 侧边栏
// 侧边栏按钮
class ToggleSideBar extends Plugin {
// constructor(toggleSidebar) {
// super();
@ -200,7 +293,6 @@ class ToggleSideBar extends Plugin{
button.on('execute', () => {
// 打开sidebar
const bt = document.getElementById("toggleSidebarButton");
console.log(bt);
bt.click();
});
@ -209,4 +301,288 @@ class ToggleSideBar extends Plugin{
}
}
export { Export2Word, Export2PDF, Translation, ToggleSideBar };
// 保存按钮
class SaveButton extends Plugin {
// constructor(toggleSidebar) {
// super();
// this.toggleSidebar = toggleSidebar;
// }
init() {
const editor = this.editor;
editor.ui.componentFactory.add('SaveButton', () => {
// The button will be an instance of ButtonView.
const button = new ButtonView();
button.set({
label: '保存',
// withText: true
tooltip: true,
// 图标 直接插入svg文件
icon: '<svg t="1731573509489" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5448" width="200" height="200"><path d="M933.376 977.066667H89.429333A45.952 45.952 0 0 1 42.666667 930.261333V89.472C42.666667 62.933333 62.933333 42.666667 89.472 42.666667H618.24c26.538667 0 46.805333 20.266667 46.805333 46.805333 0 26.496-20.266667 46.805333-46.805333 46.805333H136.277333v747.178667h750.293334V404.565333c0-26.496 20.309333-46.805333 46.805333-46.805333 26.538667 0 46.805333 20.309333 46.805333 46.805333v525.696a46.933333 46.933333 0 0 1-46.805333 46.805334z" fill="#172B4D" p-id="5449"></path><path d="M933.376 451.370667c-12.458667 0-23.381333-4.693333-32.768-14.08l-315.093333-315.050667c-18.730667-18.773333-18.730667-48.384 0-65.536 18.730667-18.730667 48.384-18.730667 65.536 0l315.093333 313.557333c18.730667 18.730667 18.730667 48.341333 0 65.493334a43.52 43.52 0 0 1-32.768 15.616zM724.352 925.610667a45.952 45.952 0 0 1-46.805333-46.805334v-258.986666H345.301333v258.986666c0 26.496-20.266667 46.762667-46.805333 46.762667a45.952 45.952 0 0 1-46.805333-46.762667V573.013333c0-26.538667 20.266667-46.805333 46.805333-46.805333h425.856c26.538667 0 46.805333 20.266667 46.805333 46.805333v305.749334a46.933333 46.933333 0 0 1-46.805333 46.762666zM724.352 423.253333H298.496a45.952 45.952 0 0 1-46.805333-46.762666V133.162667c0-26.538667 20.266667-46.805333 46.805333-46.805334s46.805333 20.266667 46.805333 46.805334v196.522666h379.050667c26.538667 0 46.805333 20.266667 46.805333 46.805334a46.933333 46.933333 0 0 1-46.805333 46.805333z" fill="#172B4D" p-id="5450"></path></svg>',
keystroke: 'Ctrl+S'
});
// Execute a callback function when the button is clicked
button.on('execute', () => {
saveData(getPageContent())
});
return button;
});
// 添加快捷键 Ctrl+S 保存
editor.keystrokes.set('Ctrl+S', (event, cancel) => {
saveData(getPageContent());
cancel();
});
}
}
// 配置CKEditor5
function setConfig() {
// 获取用户的样式配置
const userConfig = getUserConfigFromBackend();
return {
toolbar: {
items: [
'undo',
'redo',
'|',
'heading',
'style',
'|',
'fontSize',
'fontFamily',
'fontColor',
'fontBackgroundColor',
'|',
'bold',
'italic',
'underline',
'|',
'link',
'insertImage',
'insertTable',
'highlight',
'codeBlock',
'blockquote',
'|',
'alignment',
'bulletedList',
'numberedList',
'outdent',
'indent',
'|', 'ExportToWord', 'ExportToPDF', 'translate', 'SideBar', 'SaveButton'
],
shouldNotGroupWhenFull: true
},
plugins: [
AccessibilityHelp,
Alignment,
Autoformat,
AutoImage,
AutoLink,
Autosave,
BalloonToolbar,
Base64UploadAdapter,
BlockQuote,
Bold,
Code,
CodeBlock,
Essentials,
FindAndReplace,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
GeneralHtmlSupport,
Heading,
Highlight,
HorizontalLine,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Italic,
Link,
LinkImage,
List,
ListProperties,
Markdown,
MediaEmbed,
Mention,
PageBreak,
Paragraph,
PasteFromMarkdownExperimental,
PasteFromOffice,
RemoveFormat,
SelectAll,
SpecialCharacters,
SpecialCharactersArrows,
SpecialCharactersCurrency,
SpecialCharactersEssentials,
SpecialCharactersLatin,
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
Style,
Subscript,
Superscript,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TextTransformation,
TodoList,
Underline,
Undo,
Export2Word, Translation, Export2PDF, ToggleSideBar, SaveButton
],
balloonToolbar: ['bold', 'italic', '|', 'link', 'insertImage', '|', 'bulletedList', 'numberedList'],
//自定义设置字体
fontFamily: {
// 自定义字体
options: userConfig.fontFamily.options,
// 启用对所有字体名称的支持
supportAllValues: true,
},
fontSize: {
// 五号,小四,四号,小三,三号,小二,二号
options: userConfig.fontSize.options,
supportAllValues: true
},
heading: {
options: [
{
model: 'paragraph',
title: 'Paragraph',
class: 'ck-heading_paragraph'
},
{
model: 'heading1',
view: 'h1',
title: 'Heading 1',
class: 'ck-heading_heading1'
},
{
model: 'heading2',
view: 'h2',
title: 'Heading 2',
class: 'ck-heading_heading2'
},
{
model: 'heading3',
view: 'h3',
title: 'Heading 3',
class: 'ck-heading_heading3'
},
{
model: 'heading4',
view: 'h4',
title: 'Heading 4',
class: 'ck-heading_heading4'
},
{
model: 'heading5',
view: 'h5',
title: 'Heading 5',
class: 'ck-heading_heading5'
},
{
model: 'heading6',
view: 'h6',
title: 'Heading 6',
class: 'ck-heading_heading6'
}
]
},
htmlSupport: {
allow: [
{
name: /^.*$/,
styles: true,
attributes: true,
classes: true
}
]
},
image: {
toolbar: [
'toggleImageCaption',
'imageTextAlternative',
'|',
'imageStyle:inline',
'imageStyle:wrapText',
'imageStyle:breakText',
'|',
'resizeImage'
]
},
initialData:
'',
language: 'zh-cn',
link: {
addTargetToExternalLinks: true,
defaultProtocol: 'https://',
decorators: {
toggleDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
},
list: {
properties: {
styles: true,
startIndex: true,
reversed: true
}
},
mention: {
feeds: [
{
marker: '@',
feed: [
/* See: https://ckeditor.com/docs/ckeditor5/latest/features/mentions.html */
]
}
]
},
menuBar: {
isVisible: true,
removeItems: ['help'],
},
placeholder: 'Type or paste your content here!',
// 用户可以自定义和管理样式
style: {
definitions: userConfig.style.definitions
},
table: {
contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties']
},
autosave: {
waitingTime: 180000, // (in ms) 3minutes
save() {
// TODO save
return saveData(getPageContent());
}
},
translations: [translations]
}
}
export { Export2Word, Export2PDF, Translation, ToggleSideBar, setConfig };

@ -75,11 +75,6 @@ export function getUserConfigFromBackend() {
name: 'Code (bright)',
element: 'pre',
classes: ['fancy-code', 'fancy-code-bright']
},
{
name: 'GradientBorder',
element: 'p',
classes: ['gradientborder']
}
]
} = options;
@ -126,9 +121,9 @@ export function getStyle() {
// 获取用户编辑的内容 <html>
export function getPageContent() {
// const pageContent = document.querySelector("#app > div > div > div > div.editor-container__editor-wrapper > div > div > div.ck.ck-reset.ck-editor.ck-rounded-corners > div.ck.ck-editor__main > div");
const pageContent = document.querySelector("#app > div > div > div > div.editor-container__editor-wrapper > div > div > div");
return pageContent.innerHTML;
const pageContent =document.querySelector("#app > div > div > div.editor-container.editor-container_document-editor.editor-container_include-style > div.editor-container__editor-wrapper > div > div");
// const pageContent = document.querySelector("#app > div > div > div > div.editor-container__editor-wrapper > div > div > div");
return pageContent.outerHTML;
}
// 获取并应用用户定义的样式

@ -0,0 +1,127 @@
/*侧边栏样式*/
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 350px;
height: 100%;
overflow-y: hidden;
transition: transform 0.3s ease;
transform: translateX(-100%);
background-color: #f9f9f9;
padding-left: 8px;
/* 调整内边距,使文字右移 */
padding-right: 8px;
/* 调整内边距,使文字右移 */
z-index: 9;
border-right: 5px solid #aec7e5;
resize: horizontal;
overflow: auto;
}
.sidebar.active {
transform: translateX(0);
}
.sidebar-menu {
flex-direction: row;
justify-content: space-between;
/* background-color: rgb(182, 229, 244); */
border-radius: 19px;
/* 添加圆角 */
display: flex;
}
.sidebar-menu .el-sub-menu {
display: flex;
flex-direction: column;
}
.sidebar-menu .el-menu-item {
flex: 1;
text-align: left;
background-color: #9cd6ce;
border-radius: 8px;
/* 添加圆角 */
margin: 2px 0;
/* 添加间距 */
}
.sidebar-menu .el-menu-item span {
display: block;
padding: 10px;
background-color: #ffffff;
border-radius: 4px;
}
.sidebar-menu .el-menu-item span:hover {
background-color: #e0e0e0;
}
.preview {
margin-top: 20px;
/* 调整预览区与表单之间的距离 */
border: 1px solid #ccc;
/* 添加边框 */
padding: 10px;
/* 添加内边距 */
border-radius: 4px;
/* 添加圆角 */
}
.form-item {
margin-bottom: 1px;
/* 减小表单项之间的距离 */
}
.chat-container {
display: flex;
flex-direction: column;
height: 90vh;
justify-content: space-between;
}
.messages {
flex: 1;
overflow-y: auto;
margin-bottom: 10px;
}
.message pre {
white-space: pre-wrap;
/* 保留空白符,但允许自动换行 */
word-wrap: break-word;
/* 允许长单词换行 */
}
.input-area {
display: flex;
}
.input-area input {
flex: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.input-area button {
padding: 10px 15px;
background-color: #2980b9;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin-left: 5px;
}
.input-area button:hover {
background-color: #3498db;
}
.message {
margin: 5px 0;
padding: 10px;
border-radius: 4px;
background-color: #ecf0f1;
}

@ -18,8 +18,8 @@
id="toggleSidebarButton">打开/关闭侧边栏</el-button>
<div class="sidebar" :class="{ 'active': isSidebarOpen }">
<!-- 侧边栏内容 -->
<el-menu class="sidebar-menu" :class="{ 'active': isNavbarOpen }">
<el-sub-menu index="1">
<el-menu class="sidebar-menu" :class="{ 'active': isNavbarOpen }" :collapse="isNavbarOpen">
<el-sub-menu index="1" class="horizontal-sub-menu">
<template #title>智能助手</template>
<el-menu-item index="1-1" @click="showContent('polish')"></el-menu-item>
<el-menu-item index="1-2" @click="showContent('rewrite')"></el-menu-item>
@ -27,12 +27,12 @@
<el-menu-item index="1-4" @click="showContent('edit')"></el-menu-item>
<el-menu-item index="1-5" @click="showContent('translate')"></el-menu-item>
</el-sub-menu>
<el-sub-menu index="2">
<el-sub-menu index="2" class="horizontal-sub-menu">
<template #title>图文转换</template>
<el-menu-item index="2-1" @click="showContent('ocr')">OCR</el-menu-item>
<el-menu-item index="2-2" @click="showContent('mindmap')"></el-menu-item>
</el-sub-menu>
<el-sub-menu index="3">
<el-sub-menu index="3" class="horizontal-sub-menu">
<template #title>样式生成</template>
<el-menu-item index="3-1" @click="showContent('manual')"></el-menu-item>
<el-menu-item index="3-2" @click="showContent('ai')"></el-menu-item>
@ -40,7 +40,6 @@
</el-menu>
<!-- Content Sections -->
<div v-if="currentContent" class="content-section">
<el-button icon="el-icon-menu" @click="toggleNavBar()"></el-button>
<!-- Dynamic content based on navigation selection -->
<div v-if="currentContent === 'polish'"></div>
<div v-if="currentContent === 'rewrite'"></div>
@ -49,7 +48,7 @@
<div v-if="currentContent === 'translate'"></div>
<div v-if="currentContent === 'ocr'">OCR</div>
<div v-if="currentContent === 'mindmap'"></div>
<div v-if="currentContent === 'manual'" class="p-3">
<div v-if="currentContent === 'manual'">
<!-- 手动输入表单 -->
<el-form @submit.prevent="submitForm">
<el-col :span="30">
@ -269,12 +268,14 @@
Aa Bb Cc 上下 左右 12345 Aa Bb Cc 上下 左右 12345 Aa Bb Cc 上下 左右 12345
</div>
</div>
<div v-if="currentContent === 'ai'" class="p-3">
<div v-if="currentContent === 'ai'">
<!-- AI对话框 -->
<div class="chat-box border rounded p-3">
<p v-for="message in messages" :key="message.id" class="mb-1">{{ message.text }}</p>
<el-input v-model="aiInput" @keyup.enter="sendMessageToAI" placeholder="请输入消息"
class="w-100"></el-input>
<div class="chat-container">
<div class="messages" id="messages"></div>
<div class="input-area">
<input type="text" id="userInput" placeholder="输入您的消息...">
<button @click="sendMessage()"></button>
</div>
</div>
</div>
</div>
@ -284,157 +285,16 @@
</div>
</div>
</template>
<style>
/*侧边栏样式*/
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 350px;
height: 100%;
overflow-y: hidden;
transition: transform 0.3s ease;
transform: translateX(-100%);
background-color: #f9f9f9;
padding-left: 8px;
/* 调整内边距,使文字右移 */
padding-right: 8px;
/* 调整内边距,使文字右移 */
z-index: 9;
}
.sidebar.active {
transform: translateX(0);
}
.sidebar-menu {
display: none;
flex-direction: column;
justify-content: space-between;
}
.sidebar-menu.active {
display: block;
}
.sidebar-menu .el-menu-item {
flex: 1;
text-align: left;
}
.sidebar-menu .el-menu-item span {
display: block;
padding: 10px;
background-color: #f5f5f5;
border-radius: 4px;
margin: 5px;
transition: background-color 0.3s;
}
.sidebar-menu .el-menu-item span:hover {
background-color: #e0e0e0;
}
.chat-box {
max-height: 350px;
overflow-y: auto;
}
.preview {
margin-top: 20px;
/* 调整预览区与表单之间的距离 */
border: 1px solid #ccc;
/* 添加边框 */
padding: 10px;
/* 添加内边距 */
border-radius: 4px;
/* 添加圆角 */
}
.form-item {
margin-bottom: 1px;
/* 减小表单项之间的距离 */
}
</style>
<script>
import {
DecoupledEditor,
// ClassicEditor,
AccessibilityHelp,
Alignment,
Autoformat,
AutoImage,
AutoLink,
Autosave,
BalloonToolbar,
Base64UploadAdapter,
BlockQuote,
Bold,
Code,
CodeBlock,
Essentials,
FindAndReplace,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
GeneralHtmlSupport,
Heading,
Highlight,
HorizontalLine,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Italic,
Link,
LinkImage,
List,
ListProperties,
Markdown,
MediaEmbed,
Mention,
PageBreak,
Paragraph,
PasteFromMarkdownExperimental,
PasteFromOffice,
RemoveFormat,
SelectAll,
SpecialCharacters,
SpecialCharactersArrows,
SpecialCharactersCurrency,
SpecialCharactersEssentials,
SpecialCharactersLatin,
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
Style,
Subscript,
Superscript,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TextTransformation,
TodoList,
Underline,
Undo,
} from 'ckeditor5';
import translations from 'ckeditor5/translations/zh-cn.js';
import 'ckeditor5/ckeditor5.css';
import '../public/sidebar.css';
import { ElButton, ElInput, ElSelect, ElOption, ElForm, ElFormItem, ElMenu, ElMenuItem, ElColorPicker, ElSubMenu } from 'element-plus';
import { setConfig } from '../components/plugins'
// import {getUserConfigFromBackend,saveData,getPageContent,getAndApplyUserStyles} from './components/utils';
import { getUserConfigFromBackend, saveData, getPageContent } from '../components/utils';
import { Export2PDF, Export2Word, ToggleSideBar, Translation } from '../components/plugins';
import { useStore } from 'vuex';
import router from '../router/index.js';
@ -466,256 +326,11 @@ export default {
wordSpacing: ''
},
previewStyle: {},
aiInput: '', // AI
messages: [], //
};
},
mounted() {
//
const userConfig = getUserConfigFromBackend();
//
// getAndApplyUserStyles();
this.config = {
toolbar: {
items: [
'undo',
'redo',
'|',
'heading',
'style',
'|',
'fontSize',
'fontFamily',
'fontColor',
'fontBackgroundColor',
'|',
'bold',
'italic',
'underline',
'|',
'link',
'insertImage',
'insertTable',
'highlight',
'codeBlock',
'blockquote',
'|',
'alignment',
'bulletedList',
'numberedList',
'outdent',
'indent',
'|', 'ExportToWord', 'ExportToPDF', 'translate', 'SideBar'
],
shouldNotGroupWhenFull: true
},
plugins: [
AccessibilityHelp,
Alignment,
Autoformat,
AutoImage,
AutoLink,
Autosave,
BalloonToolbar,
Base64UploadAdapter,
BlockQuote,
Bold,
Code,
CodeBlock,
Essentials,
FindAndReplace,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
GeneralHtmlSupport,
Heading,
Highlight,
HorizontalLine,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Italic,
Link,
LinkImage,
List,
ListProperties,
Markdown,
MediaEmbed,
Mention,
PageBreak,
Paragraph,
PasteFromMarkdownExperimental,
PasteFromOffice,
RemoveFormat,
SelectAll,
SpecialCharacters,
SpecialCharactersArrows,
SpecialCharactersCurrency,
SpecialCharactersEssentials,
SpecialCharactersLatin,
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
Style,
Subscript,
Superscript,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TextTransformation,
TodoList,
Underline,
Undo,
Export2Word, Translation, Export2PDF, ToggleSideBar
],
balloonToolbar: ['bold', 'italic', '|', 'link', 'insertImage', '|', 'bulletedList', 'numberedList'],
//
fontFamily: {
//
options: userConfig.fontFamily.options,
//
supportAllValues: true,
},
fontSize: {
//
options: userConfig.fontSize.options,
supportAllValues: true
},
heading: {
options: [
{
model: 'paragraph',
title: 'Paragraph',
class: 'ck-heading_paragraph'
},
{
model: 'heading1',
view: 'h1',
title: 'Heading 1',
class: 'ck-heading_heading1'
},
{
model: 'heading2',
view: 'h2',
title: 'Heading 2',
class: 'ck-heading_heading2'
},
{
model: 'heading3',
view: 'h3',
title: 'Heading 3',
class: 'ck-heading_heading3'
},
{
model: 'heading4',
view: 'h4',
title: 'Heading 4',
class: 'ck-heading_heading4'
},
{
model: 'heading5',
view: 'h5',
title: 'Heading 5',
class: 'ck-heading_heading5'
},
{
model: 'heading6',
view: 'h6',
title: 'Heading 6',
class: 'ck-heading_heading6'
}
]
},
htmlSupport: {
allow: [
{
name: /^.*$/,
styles: true,
attributes: true,
classes: true
}
]
},
image: {
toolbar: [
'toggleImageCaption',
'imageTextAlternative',
'|',
'imageStyle:inline',
'imageStyle:wrapText',
'imageStyle:breakText',
'|',
'resizeImage'
]
},
initialData:
'',
language: 'zh-cn',
link: {
addTargetToExternalLinks: true,
defaultProtocol: 'https://',
decorators: {
toggleDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
},
list: {
properties: {
styles: true,
startIndex: true,
reversed: true
}
},
mention: {
feeds: [
{
marker: '@',
feed: [
/* See: https://ckeditor.com/docs/ckeditor5/latest/features/mentions.html */
]
}
]
},
menuBar: {
isVisible: true,
removeItems: ['help'],
},
placeholder: 'Type or paste your content here!',
//
style: {
definitions: userConfig.style.definitions
},
table: {
contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties']
},
autosave: {
waitingTime: 180000, // (in ms) 3minutes
save() {
// TODO save
return saveData(getPageContent());
}
},
translations: [translations]
};
this.config = setConfig();
this.isLayoutReady = true;
},
methods: {
@ -726,8 +341,8 @@ export default {
this.$refs.editorToolbarElement.appendChild(editor.ui.view.toolbar.element);
this.$refs.editorMenuBarElement.appendChild(editor.ui.view.menuBarView.element);
//
const pageContent = this.store.state.user.filecontent;
// const pageContent = '<h2>Congratulations on setting up CKEditor 5! 🎉</h2>\n<p>\n You\'ve successfully created a CKEditor 5 project. This powerful text editor will enhance your application, enabling rich text editing\n capabilities that are customizable and easy to use.\n</p>\n<h3>What\'s next?</h3>\n<ol>\n <li>\n <strong>Integrate into your app</strong>: time to bring the editing into your application. Take the code you created and add to your\n application.\n </li>\n <li>\n <strong>Explore features:</strong> Experiment with different plugins and toolbar options to discover what works best for your needs.\n </li>\n <li>\n <strong>Customize your editor:</strong> Tailor the editor\'s configuration to match your application\'s style and requirements. Or even\n write your plugin!\n </li>\n</ol>\n<p>\n Keep experimenting, and don\'t hesitate to push the boundaries of what you can achieve with CKEditor 5. Your feedback is invaluable to us\n as we strive to improve and evolve. Happy editing!\n</p>\n<h3>Helpful resources</h3>\n<ul>\n <li>📝 <a href="https://orders.ckeditor.com/trial/premium-features">Trial sign up</a>,</li>\n <li>📕 <a href="https://ckeditor.com/docs/ckeditor5/latest/installation/index.html">Documentation</a>,</li>\n <li> <a href="https://github.com/ckeditor/ckeditor5">GitHub</a> (star us if you can!),</li>\n <li>🏠 <a href="https://ckeditor.com">CKEditor Homepage</a>,</li>\n <li>🧑💻 <a href="https://ckeditor.com/ckeditor-5/demo/">CKEditor 5 Demos</a>,</li>\n</ul>\n<h3>Need help?</h3>\n<p>\n See this text, but the editor is not starting up? Check the browser\'s console for clues and guidance. It may be related to an incorrect\n license key if you use premium features or another feature-related requirement. If you cannot make it work, file a GitHub issue, and we\n will help as soon as possible!\n</p>\n';
// const pageContent = this.store.state.user.filecontent;
const pageContent = '<h2>Congratulations on setting up CKEditor 5! 🎉</h2>\n<p>\n You\'ve successfully created a CKEditor 5 project. This powerful text editor will enhance your application, enabling rich text editing\n capabilities that are customizable and easy to use.\n</p>\n<h3>What\'s next?</h3>\n<ol>\n <li>\n <strong>Integrate into your app</strong>: time to bring the editing into your application. Take the code you created and add to your\n application.\n </li>\n <li>\n <strong>Explore features:</strong> Experiment with different plugins and toolbar options to discover what works best for your needs.\n </li>\n <li>\n <strong>Customize your editor:</strong> Tailor the editor\'s configuration to match your application\'s style and requirements. Or even\n write your plugin!\n </li>\n</ol>\n<p>\n Keep experimenting, and don\'t hesitate to push the boundaries of what you can achieve with CKEditor 5. Your feedback is invaluable to us\n as we strive to improve and evolve. Happy editing!\n</p>\n<h3>Helpful resources</h3>\n<ul>\n <li>📝 <a href="https://orders.ckeditor.com/trial/premium-features">Trial sign up</a>,</li>\n <li>📕 <a href="https://ckeditor.com/docs/ckeditor5/latest/installation/index.html">Documentation</a>,</li>\n <li>⭐️ <a href="https://github.com/ckeditor/ckeditor5">GitHub</a> (star us if you can!),</li>\n <li>🏠 <a href="https://ckeditor.com">CKEditor Homepage</a>,</li>\n <li>🧑‍💻 <a href="https://ckeditor.com/ckeditor-5/demo/">CKEditor 5 Demos</a>,</li>\n</ul>\n<h3>Need help?</h3>\n<p>\n See this text, but the editor is not starting up? Check the browser\'s console for clues and guidance. It may be related to an incorrect\n license key if you use premium features or another feature-related requirement. If you cannot make it work, file a GitHub issue, and we\n will help as soon as possible!\n</p>\n';
// pageContent
// TODO
editor.setData(pageContent);
@ -738,13 +353,9 @@ export default {
this.isSidebarOpen = !this.isSidebarOpen;
this.isNavbarOpen = this.isSidebarOpen;
},
toggleNavBar() {
this.isNavbarOpen = !this.isNavbarOpen;
},
//
showContent(formType) {
this.currentContent = formType;
this.isNavbarOpen=false;
},
//
submitForm() {
@ -779,15 +390,176 @@ export default {
}
}
},
// API
sendMessageToAI() {
// APIAI
this.messages.push({ text: this.aiInput });
this.aiInput = ''; //
// AI
// AI
displayMessage(text, sender) {
const messagesDiv = document.getElementById('messages');
// messages
const previousButtonsMessage = messagesDiv.querySelectorAll('.preview-buttons');
previousButtonsMessage.forEach(buttons => buttons.remove());
const messageDiv = document.createElement('div');
messageDiv.className = 'message';
// 使 pre text
// css htmlpre set language
const preElement = document.createElement('pre');
preElement.textContent = text;
messageDiv.appendChild(preElement);
messagesDiv.appendChild(messageDiv);
if (sender === 'ai') {
// TODO css
preElement.textContent = `文心一言:\n` + preElement.textContent;
messageDiv.style.backgroundColor = '#bdc3c7';
// preview
const previewWrapper = document.createElement('div');
previewWrapper.style.border = '1px solid #ccc';
previewWrapper.style.display = 'flow-root';
// 'preview'
const previewLabel = document.createElement('div');
previewLabel.textContent = 'preview';
previewWrapper.appendChild(previewLabel);
//
const previewStyle = document.createElement('style');
//
// csscss,css,}
const cssRegex = /css([\s\S]*)\}/;
const cssMatch = cssRegex.exec(text);
if (cssMatch) {
previewStyle.textContent = cssMatch[0].replace('css', '');
}else{
previewStyle.textContent = text;
}
previewStyle.textContent = previewStyle.textContent.replace(/\.ck-content/g, '');
document.head.appendChild(previewStyle);
//
let previewElement;
// element tag class name
const styleRegex = /\.ck-content\s+([a-z]+)\.([a-z-]+)\s*\{/g;
let match;
const classNames = [];
while ((match = styleRegex.exec(text)) !== null) {
if (!previewElement) {
previewElement = document.createElement(match[1]);
previewElement.textContent = 'AaBbCcDdEeFf';
previewWrapper.appendChild(previewElement);
}
classNames.push(match[2]);
}
if (previewElement) {
previewElement.className = classNames.join(' ');
}
messagesDiv.appendChild(previewWrapper);
//
const buttonsMessageDiv = document.createElement('div');
buttonsMessageDiv.className = 'preview-buttons';
buttonsMessageDiv.style.display = 'flex';
buttonsMessageDiv.style.justifyContent = 'flex-end';
buttonsMessageDiv.style.marginTop = '10px';
// save
const saveButton = document.createElement('el-button');
saveButton.innerHTML = '<svg t="1731509644125" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6346" width="20" height="20"><path d="M512 1024C229.248 1024 0 794.752 0 512S229.248 0 512 0s512 229.248 512 512-229.248 512-512 512z m0-938.666667C276.352 85.333333 85.333333 276.352 85.333333 512s191.018667 426.666667 426.666667 426.666667 426.666667-191.018667 426.666667-426.666667S747.648 85.333333 512 85.333333z m-3.413333 611.541334a34.944 34.944 0 0 1-9.386667 16.682666 38.058667 38.058667 0 0 1-30.72 11.050667 38.954667 38.954667 0 0 1-40.106667-27.946667L308.053333 576.426667a38.4 38.4 0 0 1 54.186667-54.229334l93.013333 93.184 190.293334-337.365333a42.666667 42.666667 0 0 1 58.88-16.426667c20.608 12.714667 27.392 39.466667 15.36 60.458667l-211.2 374.826667z" fill="#000000" p-id="6347"></path></svg>';
saveButton.style.marginLeft = '10px';
saveButton.style.width = '40px';
saveButton.style.height = '40px';
saveButton.onclick = () => {
// save
// TODO
// 使style
// styleDefinition:[name: 'styleName',element: 'element',classes: [className]]
const styleName = prompt("请输入样式名称:");
// styleDefiniton
const styleDefinition = {
name: styleName,
element: previewElement.tagName,
classes: classNames
};
console.log(styleDefinition);
};
// clear
const clearButton = document.createElement('el-button');
clearButton.innerHTML = '<svg t="1731509926355" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8154" width="20" height="20"><path d="M1011.43552 981.92384l-68.4032-394.40384h23.10144c18.5856 0 33.54624-14.97088 33.54624-33.55648V306.16576c0-18.5856-14.97088-33.55648-33.54624-33.55648H648.6528V37.71392c0-18.5856-14.97088-33.55648-33.55648-33.55648H408.59648c-18.5856 0-33.55648 14.97088-33.55648 33.55648v234.88512H57.5488c-18.5856 0-33.54624 14.97088-33.54624 33.55648v247.79776c0 18.5856 14.97088 33.55648 33.54624 33.55648h23.10144L12.24704 981.9136c-0.38912 1.9456-0.512 3.87072-0.512 5.6832 0 18.5856 14.97088 33.54624 33.55648 33.54624h933.10976c1.93536 0 3.88096-0.12288 5.6832-0.512 18.31936-3.08224 30.57664-20.51072 27.35104-38.7072zM114.33984 362.94656h351.03744V94.50496h92.928v268.4416h351.03744v134.22592H114.33984V362.94656zM718.336 930.816V729.48736c0-5.6832-4.64896-10.33216-10.32192-10.33216h-61.952c-5.67296 0-10.32192 4.64896-10.32192 10.33216V930.816H387.9424V729.48736c0-5.6832-4.64896-10.33216-10.32192-10.33216h-61.952c-5.67296 0-10.32192 4.64896-10.32192 10.33216V930.816H112.78336l58.20416-335.55456h681.5744L910.76608 930.816H718.336z m0 0" fill="#2C2C2C" p-id="8155"></path></svg>';
clearButton.style.marginLeft = '10px';
clearButton.style.width = '40px';
clearButton.style.height = '40px';
clearButton.onclick = () => {
// clear message
const messagesDiv = document.getElementById('messages');
while (messagesDiv.firstChild) {
messagesDiv.removeChild(messagesDiv.firstChild);
}
// style
document.head.removeChild(previewStyle);
};
//
buttonsMessageDiv.appendChild(saveButton);
buttonsMessageDiv.appendChild(clearButton);
messagesDiv.appendChild(buttonsMessageDiv);
}
// messagesDiv.scrollTop = messagesDiv.scrollHeight;
},
sendMessage() {
const userInput = document.getElementById('userInput');
const messageText = userInput.value;
if (messageText.trim() === '') return;
// Display user's message
this.displayMessage(messageText, 'user');
// APIresponse
setTimeout(() => {
this.messages.push({ text: '这是来自AI的回复' });
// Simulate AI response
let formatedResponse = `css
.ck-content p.marquee {
display: inline-block;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
padding: 0.5em;
background: linear-gradient(90deg, #ff7e5f, #feb47b);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: marquee 10s linear infinite;
position: relative;
}
@keyframes marquee {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
.ck-content p.marquee::selection {
background: rgba(255, 255, 255, 0.3); /* Ensure text is readable when selected */
}
/* Container to make sure the marquee stays within bounds */
.ck-content .marquee-container {
overflow: hidden;
white-space: nowrap;
width: 100%; /* Adjust as needed */
}
请注意由于使用了 inline-block文本框的长和宽会根据内容自动调整同时由于动画使用了 translateX 而不是 text-indent因此可以正确地处理不同长度的文本另外我添加了一个 .marquee-container 用于确保滚动文本保持在指定区域内例如不超出其父容器的边界您需要将 p.marquee 元素放置在一个具有 .marquee-container 类的元素内以确保动画效果正确
示例 HTML 结构
html
<div class="ck-content">
<div class="marquee-container">
<p class="marquee">这是一个带有流水灯效果的文本框它的宽度和高度会根据内容自动调整</p>
</div>
</div>
`;
this.displayMessage(formatedResponse, 'ai');
}, 1000);
userInput.value = '';
},
},
components: {

Loading…
Cancel
Save