修改了ckeditor5 用户配置,获取编辑内容

master
joefalmko 3 months ago
parent 20a0d4c214
commit 325ebea2ee

@ -11,7 +11,63 @@ npm run serve
直接修改`App.vue`,见Export2Word插件
#### Export2Word插件
bug1图片只能插入url而不是base64,否则导出错误,导出的内容会在图片前截断
bug1图片导出为word会恢复原始大小而不是在编辑器中显示的大小。
bug2: 导出格式部分错误,如字体颜色、字体背景颜色、高亮
bug2: 导出格式部分错误如字体背景颜色等应该是style没有提取出
#### Export2PDF插件
bug1: 导出后编辑器框会显示出被选中的颜色 已修复√
bug2: 导出格式部分错误,字体颜色可以正常显示但背景颜色和高亮不行
#### 智能润色
选中需要处理的文本后点击对应按钮即可触发实现对应逻辑需要实现框架已搭建。见插件Translate
#### 智能格式排版
· 样式库的管理和编辑
利用ckeditor5已有插件`style`进行配置。可以对符合要求的block等应用选中的样式。只需要设定好样式库添加`大模型生成css样式``用户自定义样式管理`即可
https://ckeditor.com/docs/ckeditor5/latest/features/style.html
编辑器初始化时
```
// 配置文件定义样式
import { ClassicEditor, Style } from 'ckeditor5';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Style, /* ... */ ],
toolbar: {
items: [
'style',
// More toolbar items.
// ...
],
},
style: {
definitions: [
// Styles definitions.
// ...
]
}
} )
.then( /* ... */ )
.catch( /* ... */ );
```
```
// 定义对应样式的css格式
.ck.ck-content h3.category {
font-family: 'Bebas Neue';
font-size: 20px;
font-weight: bold;
color: #d1d1d1;
letter-spacing: 10px;
margin: 0;
padding: 0;
}
.ck.ck-content p.info-box {
padding: 1.2em 2em;
border: 1px solid #e91e63;
border-left: 10px solid #e91e63;
border-radius: 5px;
margin: 1.5em;
}
```

@ -6,10 +6,12 @@
margin: 0 !important;
}
}
.main-container {
--ckeditor5-preview-height: 700px;
/* --ckeditor5-preview-height: 700px; */
font-family: '宋体';
width: fit-content;
height: 100%;
margin-left: auto;
margin-right: auto;
}
@ -114,18 +116,14 @@
--background-color: #e91e63;
padding: 1.2em 2em;
border: 1px solid var(--background-color);
background: linear-gradient(
135deg,
background: linear-gradient(135deg,
var(--background-color) 0%,
var(--background-color) var(--background-size),
transparent var(--background-size)
),
linear-gradient(
135deg,
transparent var(--background-size)),
linear-gradient(135deg,
transparent calc(100% - var(--background-size)),
var(--background-color) calc(100% - var(--background-size)),
var(--background-color)
);
var(--background-color));
border-radius: 10px;
margin: 1.5em 2em;
box-shadow: 5px 5px 0 #ffe6ef;
@ -207,3 +205,66 @@
color: #000;
box-shadow: 5px 5px 0 #b3b3b3;
}
.ck-content p.gradientborder {
--borderWidth: 12px;
--bRadius: 5px;
width: 60%;
height: 60%;
position: relative;
z-index: 0;
overflow: hidden;
padding: 2rem;
z-index: 0;
border-radius: --bRadius;
&::after,
&::before {
box-sizing: border-box;
}
&::before {
content: '';
position: absolute;
left: -50%;
top: -50%;
width: 200%;
height: 200%;
z-index: -2;
background-repeat: no-repeat;
background-size: 50% 50%, 50% 50%;
background-position: 0 0, 100% 0, 100% 100%, 0 100%;
background-image: linear-gradient(#399953, #399953), linear-gradient(#fbb300, #fbb300), linear-gradient(#d53e33, #d53e33), linear-gradient(#377af5, #377af5);
animation: rotate 4s linear infinite;
@keyframes rotate {
100% {
transform: rotate(1turn);
}
}
}
&::after {
content: '';
position: absolute;
z-index: -1;
left: calc(var(--borderWidth) / 2);
top: calc(var(--borderWidth) / 2);
width: calc(100% - var(--borderWidth));
height: calc(100% - var(--borderWidth));
background: white;
border-radius: --bRadius;
/* 这一行是为了方便查看原来的样子的 */
animation: opacityChange 3s infinite alternate;
}
@keyframes opacityChange {
50% {
opacity: 1;
}
100% {
opacity: .5;
}
}
}

@ -29,6 +29,7 @@ import {
Autosave,
BalloonToolbar,
Base64UploadAdapter,
BlockQuote,
Bold,
Code,
CodeBlock,
@ -76,7 +77,7 @@ import {
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
// Style,
Style,
Subscript,
Superscript,
Table,
@ -98,6 +99,7 @@ import {
// SplitButtonView,
Collection,
addListToDropdown,
// Position,
// Model,
// addToolbarToDropdown
@ -128,6 +130,12 @@ function getStyle(){
str += "<style>table td,th{ font-size: 14px;padding: 1px 1px;border-width: 1px;border-style: solid;border-color: #d0d0d0;word-break: keep-all;white-space: nowrap;}</style>"
return str;
}
// <html>
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")
return pageContent.innerHTML;
}
// docx
class Export2Word extends Plugin {
init() {
const editor = this.editor;
@ -148,9 +156,9 @@ class Export2Word extends Plugin {
// Execute a callback function when the button is clicked
button.on('execute', () => {
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")
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.outerHTML + '</body></html>'
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 => {
@ -162,25 +170,26 @@ class Export2Word extends Plugin {
});
//
editor.ui.extendMenuBar({
menu: {
menuId: 'export',
label: '导出',
groups: [
{
groupId: 'export',
items: [
'ExportToWord'
]
}
]
},
position: 'after:help'
}
);
// editor.ui.extendMenuBar({
// menu: {
// menuId: 'export',
// label: '',
// groups: [
// {
// groupId: 'export',
// items: [
// 'ExportToWord'
// ]
// }
// ]
// },
// position: 'after:help'
// }
// );
}
}
// PDF
class Export2PDF extends Plugin {
init() {
const editor = this.editor;
@ -201,9 +210,10 @@ class Export2PDF extends Plugin{
// Execute a callback function when the button is clicked
button.on('execute', () => {
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");
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.outerHTML + '</body></html>'
// 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();
@ -217,7 +227,7 @@ class Export2PDF extends Plugin{
});
}
}
//
class Translation extends Plugin {
init() {
// console.log('Translation initialized!');
@ -286,7 +296,6 @@ class Translation extends Plugin {
});
}
}
export default {
name: 'app',
data() {
@ -298,6 +307,7 @@ export default {
};
},
mounted() {
const userConfig = getUserConfigFromBackend();
this.config = {
toolbar: {
items: [
@ -305,7 +315,7 @@ export default {
'redo',
'|',
'heading',
// 'style',
'style',
'|',
'fontSize',
'fontFamily',
@ -321,9 +331,9 @@ export default {
'insertTable',
'highlight',
'codeBlock',
'blockquote',
'|',
'alignment',
'|',
'bulletedList',
'numberedList',
'outdent',
@ -341,6 +351,7 @@ export default {
Autosave,
BalloonToolbar,
Base64UploadAdapter,
BlockQuote,
Bold,
Code,
CodeBlock,
@ -388,7 +399,7 @@ export default {
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
// Style,
Style,
Subscript,
Superscript,
Table,
@ -406,32 +417,14 @@ export default {
balloonToolbar: ['bold', 'italic', '|', 'link', 'insertImage', '|', 'bulletedList', 'numberedList'],
//
fontFamily: {
//
//
options: userConfig.fontFamily.options,
//
supportAllValues: true,
//
options: [
'default',
'宋体',
'新宋体',
'仿宋',
'楷体',
'微软雅黑',
'黑体',
'华文仿宋',
'华文楷体',
'华文隶书',
'华文宋体',
'华文细黑',
'华文新魏',
'华文行楷',
'华文中宋',
'隶书',
'苹方 常规',
'幼圆',
],
},
fontSize: {
options: [10, 12, 14, 'default', 18, 20, 22],
//
options: userConfig.fontSize.options,
supportAllValues: true
},
heading: {
@ -501,6 +494,9 @@ export default {
'resizeImage'
]
},
// /
//
// TODO
initialData:
'<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',
language: 'zh-cn',
@ -536,60 +532,24 @@ export default {
},
menuBar: {
isVisible: true,
removeItems: [ 'help' ],
},
placeholder: 'Type or paste your content here!',
// style: {
// definitions: [
// {
// name: 'Article category',
// element: 'h3',
// classes: ['category']
// },
// {
// name: 'Title',
// element: 'h2',
// classes: ['document-title']
// },
// {
// name: 'Subtitle',
// element: 'h3',
// classes: ['document-subtitle']
// },
// {
// name: 'Info box',
// element: 'p',
// classes: ['info-box']
// },
// {
// name: 'Side quote',
// element: 'blockquote',
// classes: ['side-quote']
// },
// {
// name: 'Marker',
// element: 'span',
// classes: ['marker']
// },
// {
// name: 'Spoiler',
// element: 'span',
// classes: ['spoiler']
// },
// {
// name: 'Code (dark)',
// element: 'pre',
// classes: ['fancy-code', 'fancy-code-dark']
// },
// {
// name: 'Code (bright)',
// element: 'pre',
// classes: ['fancy-code', 'fancy-code-bright']
// }
// ]
// },
//
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]
};
@ -605,4 +565,118 @@ export default {
}
}
};
//
function getUserConfigFromBackend(){
// TODO
const options={}
//
// TODO
const {
fontFamilyOptions = [
'default',
'宋体',
'新宋体',
'仿宋',
'楷体',
'微软雅黑',
'黑体',
'华文仿宋',
'华文楷体',
'华文隶书',
'华文宋体',
'华文细黑',
'华文新魏',
'华文行楷',
'华文中宋',
'隶书',
'苹方 常规',
'幼圆',
'Times New Roman'
],
//
fontSizeOptions = [10.5, 12, 14,15, 'default', 18,22],
styleDefinitions = [
{
name: 'Article category',
element: 'h3',
classes: ['category']
},
{
name: 'Title',
element: 'h2',
classes: ['document-title']
},
{
name: 'Subtitle',
element: 'h3',
classes: ['document-subtitle']
},
{
name: 'Info box',
element: 'p',
classes: ['info-box']
},
{
name: 'Side quote',
element: 'blockquote',
classes: ['side-quote']
},
{
name: 'Marker',
element: 'span',
classes: ['marker']
},
{
name: 'Spoiler',
element: 'span',
classes: ['spoiler']
},
{
name: 'Code (dark)',
element: 'pre',
classes: ['fancy-code', 'fancy-code-dark']
},
{
name: 'Code (bright)',
element: 'pre',
classes: ['fancy-code', 'fancy-code-bright']
},
{
name: 'GradientBorder',
element: 'p',
classes: ['gradientborder']
}
]
} = options;
// options使
return {
fontFamily: {
options: fontFamilyOptions
},
fontSize: {
options: fontSizeOptions
},
style: {
definitions: styleDefinitions
}
};
}
// TODO saveData
function saveData( data ) {
// return new Promise( resolve => {
// setTimeout( () => {
// console.log( 'Saved', data );
// resolve();
// }, HTTP_SERVER_LAG );
// } );
console.log(data);
}
// TODO
// function saveByHand(){
// this.editor.plugins.get('Autosave').save().then(() => {
// console.log('Data saved successfully');
// });
// }
</script>

Loading…
Cancel
Save