|
@@ -29,7 +29,7 @@ export default {
|
|
|
normalizeSafariSpaceSpans(htmlString) {
|
|
|
return htmlString.replace(/<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g, (fullMatch, spaces) => {
|
|
|
return spaces.length === 1 ? ' ' : Array(spaces.length + 1).join('\u00A0 ').substr(0, spaces
|
|
|
- .length);
|
|
|
+ .length);
|
|
|
});
|
|
|
},
|
|
|
/* 粘贴文本的解析和轻量化操作 */
|
|
@@ -79,7 +79,7 @@ export default {
|
|
|
},
|
|
|
/* 粘贴事件监听 */
|
|
|
pasteEvent(e, editor) {
|
|
|
- if(e.target.nodeName === 'INPUT'){
|
|
|
+ if (e.target.nodeName === 'INPUT') {
|
|
|
return
|
|
|
}
|
|
|
let that = this
|
|
@@ -148,7 +148,7 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- initEditorLang(editor){
|
|
|
+ initEditorLang(editor) {
|
|
|
let curLang = localStorage.getItem('local') || 'zh-cn'
|
|
|
if (curLang === 'zh-tw') {
|
|
|
// 自定义语言
|
|
@@ -192,7 +192,7 @@ export default {
|
|
|
this.addVideoUpload(vm, editor)
|
|
|
this.addAudio(vm, editor)
|
|
|
this.addCanvas(vm, editor)
|
|
|
- this.addTextDot(vm,editor)
|
|
|
+ this.addTextDot(vm, editor)
|
|
|
// editor.config.pasteFilterStyle = false
|
|
|
editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 2M
|
|
|
editor.config.uploadImgShowBase64 = true;
|
|
@@ -220,17 +220,25 @@ export default {
|
|
|
isOption && editor.config.menus.splice(editor.config.menus.indexOf('video'), 1)
|
|
|
let dom = editor.toolbarSelector
|
|
|
if (dom) {
|
|
|
- editor.config.pasteTextHandle = function(pasteStr) {
|
|
|
- return ''
|
|
|
- }
|
|
|
- dom.removeEventListener('paste', e => {
|
|
|
- this.pasteEvent(e, editor)
|
|
|
- })
|
|
|
- dom.addEventListener('paste', e => {
|
|
|
- this.pasteEvent(e, editor)
|
|
|
- })
|
|
|
+ editor.config.pasteTextHandle = function (pasteStr) {
|
|
|
+ // 对粘贴的文本进行处理,然后返回处理后的结果
|
|
|
+ var newStr = pasteStr.replace(
|
|
|
+ /@font-face{[^>]*div.Section0{page:Section0;}/g,
|
|
|
+ ""
|
|
|
+ );
|
|
|
+ return newStr;
|
|
|
+ };
|
|
|
+ // editor.config.pasteTextHandle = function (pasteStr) {
|
|
|
+ // return ''
|
|
|
+ // }
|
|
|
+ // dom.removeEventListener('paste', e => {
|
|
|
+ // this.pasteEvent(e, editor)
|
|
|
+ // })
|
|
|
+ // dom.addEventListener('paste', e => {
|
|
|
+ // this.pasteEvent(e, editor)
|
|
|
+ // })
|
|
|
} else {
|
|
|
- editor.config.pasteTextHandle = function(pasteStr) {
|
|
|
+ editor.config.pasteTextHandle = function (pasteStr) {
|
|
|
// 对粘贴的文本进行处理,然后返回处理后的结果
|
|
|
var newStr = pasteStr.replace(
|
|
|
/@font-face{[^>]*div.Section0{page:Section0;}/g,
|
|
@@ -260,7 +268,7 @@ export default {
|
|
|
editor.i18next = i18next
|
|
|
}
|
|
|
// editor.config.pasteFilterStyle = false
|
|
|
- editor.config.pasteTextHandle = function(pasteStr) {
|
|
|
+ editor.config.pasteTextHandle = function (pasteStr) {
|
|
|
// 对粘贴的文本进行处理,然后返回处理后的结果
|
|
|
var newStr = pasteStr.replace(
|
|
|
/@font-face{[^>]*div.Section0{page:Section0;}/g,
|
|
@@ -286,7 +294,7 @@ export default {
|
|
|
]
|
|
|
},
|
|
|
/* 添加自定义本地视频上传功能 */
|
|
|
- addVideoUpload(vm, editor) {
|
|
|
+ addVideoUpload(vm, editor, isSimple) {
|
|
|
// 获取必要的变量,这些在下文中都会用到
|
|
|
const {
|
|
|
$,
|
|
@@ -370,7 +378,11 @@ export default {
|
|
|
// editor.selection.getSelectionStartElem().elems[0].innerHTML += '<span><span> </span><video src=' +
|
|
|
// url + ' class="richText-video" width="300" preload controls="controls"></video><span> </span></span>'
|
|
|
// editor.change.emit()
|
|
|
- $tools.doUploadVideo(vm, fileList[0], editor)
|
|
|
+ if (isSimple) {
|
|
|
+ app.$EventBus.$emit('selectFileFinish', { file: fileList[0], type: 'video' })
|
|
|
+ } else {
|
|
|
+ $tools.doUploadVideo(vm, fileList[0], editor)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
// 返回 true 可关闭 panel
|
|
@@ -389,10 +401,10 @@ export default {
|
|
|
return conf;
|
|
|
}
|
|
|
|
|
|
- command(value) {}
|
|
|
+ command(value) { }
|
|
|
|
|
|
// 菜单是否需要激活
|
|
|
- tryChangeActive() {}
|
|
|
+ tryChangeActive() { }
|
|
|
}
|
|
|
|
|
|
// 注册菜单
|
|
@@ -401,10 +413,10 @@ export default {
|
|
|
|
|
|
// 将菜单加入到 editor.config.menus 中
|
|
|
// 也可以通过配置 menus 调整菜单的顺序,参考【配置菜单】部分的文档
|
|
|
- // editor.config.menus = editor.config.menus.concat(videoUpload);
|
|
|
+ editor.config.menus = editor.config.menus.concat(videoUpload);
|
|
|
},
|
|
|
/* 添加自定义本地音频上传功能 */
|
|
|
- addAudio(vm, editor) {
|
|
|
+ addAudio(vm, editor, isSimple) {
|
|
|
// 获取必要的变量,这些在下文中都会用到
|
|
|
const {
|
|
|
$,
|
|
@@ -479,7 +491,11 @@ export default {
|
|
|
if (fileList[0].type.slice(0, 5) !== 'audio') {
|
|
|
Message.warning(app.$t('utils.audioFormatError'))
|
|
|
} else {
|
|
|
- $tools.doUploadAudio(vm, fileList[0], editor)
|
|
|
+ if (isSimple) {
|
|
|
+ app.$EventBus.$emit('selectFileFinish', { file: fileList[0], type: 'audio' })
|
|
|
+ } else {
|
|
|
+ $tools.doUploadAudio(vm, fileList[0], editor)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
// 返回 true 可关闭 panel
|
|
@@ -498,10 +514,10 @@ export default {
|
|
|
return conf;
|
|
|
}
|
|
|
|
|
|
- command(value) {}
|
|
|
+ command(value) { }
|
|
|
|
|
|
// 菜单是否需要激活
|
|
|
- tryChangeActive() {}
|
|
|
+ tryChangeActive() { }
|
|
|
}
|
|
|
|
|
|
// 注册菜单
|
|
@@ -540,7 +556,7 @@ export default {
|
|
|
onOk: () => {
|
|
|
app.$EventBus.$emit('doCanvasConfirm')
|
|
|
},
|
|
|
- render(h){
|
|
|
+ render(h) {
|
|
|
return h('div', {
|
|
|
style: {
|
|
|
display: 'flex',
|
|
@@ -571,7 +587,7 @@ export default {
|
|
|
// let widthPercent = val.width > 800 ? '50%' : '100%'
|
|
|
editor.txt.append('<img src=' + val.base64 +
|
|
|
' class="richText-canvas" style="max-width:100%"></img>'
|
|
|
- );
|
|
|
+ );
|
|
|
Modal.remove()
|
|
|
},
|
|
|
onCloseModal() {
|
|
@@ -584,10 +600,10 @@ export default {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- command(value) {}
|
|
|
+ command(value) { }
|
|
|
|
|
|
// 菜单是否需要激活
|
|
|
- tryChangeActive() {}
|
|
|
+ tryChangeActive() { }
|
|
|
}
|
|
|
|
|
|
// 注册菜单
|
|
@@ -606,7 +622,7 @@ export default {
|
|
|
BtnMenu,
|
|
|
Panel
|
|
|
} = E;
|
|
|
-
|
|
|
+
|
|
|
// 标题菜单的 class ,可作为 DropList 菜单的参考代码
|
|
|
class myPanel extends BtnMenu {
|
|
|
constructor(editor) {
|
|
@@ -617,7 +633,7 @@ export default {
|
|
|
);
|
|
|
super($elem, editor);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
clickHandler() {
|
|
|
// Modal.props.fullscreen.default = true
|
|
|
app.$EventBus.$emit('clickResource')
|
|
@@ -636,7 +652,7 @@ export default {
|
|
|
maxWidth: '1200px',
|
|
|
margin: '0 auto'
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
}, [
|
|
|
h('div', {
|
|
|
style: {
|
|
@@ -648,10 +664,10 @@ export default {
|
|
|
}),
|
|
|
h('NewChooseContent', {
|
|
|
props: {
|
|
|
- vm:vm,
|
|
|
- showSyllabus:false,
|
|
|
- showQuestion:false,
|
|
|
- showPaper:false
|
|
|
+ vm: vm,
|
|
|
+ showSyllabus: false,
|
|
|
+ showQuestion: false,
|
|
|
+ showPaper: false
|
|
|
},
|
|
|
on: {
|
|
|
'on-file-change'(val) {
|
|
@@ -666,29 +682,29 @@ export default {
|
|
|
},
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
- command(value) {}
|
|
|
-
|
|
|
+
|
|
|
+ command(value) { }
|
|
|
+
|
|
|
// 菜单是否需要激活
|
|
|
- tryChangeActive() {}
|
|
|
+ tryChangeActive() { }
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 注册菜单
|
|
|
const resourceDraw = "resource"; // 菜单 key ,各个菜单不能重复
|
|
|
editor.menus.extend("resource", myPanel);
|
|
|
-
|
|
|
+
|
|
|
// 将菜单加入到 editor.config.menus 中
|
|
|
// 也可以通过配置 menus 调整菜单的顺序,参考【配置菜单】部分的文档
|
|
|
editor.config.menus = editor.config.menus.concat(resourceDraw);
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/* 添加文字下加重点功能 */
|
|
|
addTextDot(vm, editor) {
|
|
|
const {
|
|
|
$,
|
|
|
- BtnMenu
|
|
|
+ BtnMenu
|
|
|
} = E;
|
|
|
- class TextDot extends BtnMenu{
|
|
|
+ class TextDot extends BtnMenu {
|
|
|
constructor(editor) {
|
|
|
const $elem = $(
|
|
|
`<div class="w-e-menu" style="color:red" title="${app.$t('evaluation.editor.addTextDot')}"><i class="icon iconfont icon-heavy" style="font-size: 20px;display: inline-block;margin-top: 3px;"></i></div>`
|
|
@@ -699,7 +715,7 @@ export default {
|
|
|
/**
|
|
|
* 点击事件
|
|
|
*/
|
|
|
- clickHandler(){
|
|
|
+ clickHandler() {
|
|
|
const editor = this.editor
|
|
|
const isSelectEmpty = editor.selection.isSelectionEmpty()
|
|
|
// console.log(editor)
|
|
@@ -711,16 +727,16 @@ export default {
|
|
|
editor.selection.createEmptyRange()
|
|
|
editor.selection.collapseRange()
|
|
|
editor.selection.restoreSelection()
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
let selectDom = editor.selection.getSelectionStartElem().elems[0]
|
|
|
let selectText = editor.selection.getSelectionText()
|
|
|
- if(selectDom.localName === 'dot'){
|
|
|
+ if (selectDom.localName === 'dot') {
|
|
|
// 如果选中的文本 本身就有着重号 就去除
|
|
|
editor.cmd.do('insertHTML', selectText)
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
// 添加着重号
|
|
|
// console.log(selectText)
|
|
|
- let textArr = selectText.replace(/\u200B/g,'').split('').filter(s => s && s.trim())
|
|
|
+ let textArr = selectText.replace(/\u200B/g, '').split('').filter(s => s && s.trim())
|
|
|
// console.log(textArr)
|
|
|
let html = ``
|
|
|
// let html = `​<dot>${selectText}</dot>​`
|
|
@@ -736,7 +752,7 @@ export default {
|
|
|
/**
|
|
|
* 尝试修改菜单激活状态
|
|
|
*/
|
|
|
- tryChangeActive(){
|
|
|
+ tryChangeActive() {
|
|
|
const editor = this.editor
|
|
|
if (editor.cmd.queryCommandState('textDot')) {
|
|
|
this.active()
|
|
@@ -745,7 +761,7 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 注册菜单
|
|
|
const TextDotKey = "textDot"; // 菜单 key ,各个菜单不能重复
|
|
|
editor.menus.extend("textDot", TextDot);
|
|
@@ -777,7 +793,7 @@ export default {
|
|
|
panel.create();
|
|
|
}
|
|
|
|
|
|
- tryChangeActive() {}
|
|
|
+ tryChangeActive() { }
|
|
|
}
|
|
|
|
|
|
// 注册菜单
|
|
@@ -801,7 +817,7 @@ export default {
|
|
|
// 公式输入插件
|
|
|
constructor(editors) {
|
|
|
const $elem = $(
|
|
|
- `<div class="w-e-menu" title="${ app.$t('evaluation.editor.canvasStemTip') }" style="color:red"><i class="icon iconfont icon-brush" style="font-size: 20px;"></i></div>`
|
|
|
+ `<div class="w-e-menu" title="${app.$t('evaluation.editor.canvasStemTip')}" style="color:red"><i class="icon iconfont icon-brush" style="font-size: 20px;"></i></div>`
|
|
|
);
|
|
|
super($elem, editors);
|
|
|
}
|
|
@@ -810,7 +826,7 @@ export default {
|
|
|
app.$EventBus.$emit('onStuCanvas', editor)
|
|
|
}
|
|
|
|
|
|
- tryChangeActive() {}
|
|
|
+ tryChangeActive() { }
|
|
|
}
|
|
|
|
|
|
// 注册菜单
|
|
@@ -819,14 +835,39 @@ export default {
|
|
|
|
|
|
// 将菜单加入到 editor.config.menus 中
|
|
|
// 也可以通过配置 menus 调整菜单的顺序,参考【配置菜单】部分的文档
|
|
|
- //editor.config.menus = editor.config.menus.concat(videoUpload);
|
|
|
+ editor.config.menus = editor.config.menus.concat(videoUpload);
|
|
|
+ },
|
|
|
+ /* 获取富文本中音视频相对路径 */
|
|
|
+ getRelativeSrcPath(richText) {
|
|
|
+ let videoSrcList = this.getRichTextSrc(richText, 'video')
|
|
|
+ let audioSrcList = this.getRichTextSrc(richText, 'audio')
|
|
|
+ let srcList = videoSrcList.concat(audioSrcList)
|
|
|
+ if (srcList.length) {
|
|
|
+ srcList.forEach(src => {
|
|
|
+ let withSas = src.split('/')[src.split('/').length - 1]
|
|
|
+ let j = withSas.lastIndexOf('?')
|
|
|
+ richText = richText.replaceAll(src, decodeURI(withSas.slice(0, j)));
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return richText
|
|
|
+ },
|
|
|
+ /* 获取富文本中音视频完整路径 */
|
|
|
+ getMideaFullPath(richText, host, sas) {
|
|
|
+ let videoSrcList = this.getRichTextSrc(richText, 'video')
|
|
|
+ let audioSrcList = this.getRichTextSrc(richText, 'audio')
|
|
|
+ let srcList = videoSrcList.concat(audioSrcList)
|
|
|
+ if (srcList.length) {
|
|
|
+ srcList.forEach(src => {
|
|
|
+ let fullSrc = host + src + sas
|
|
|
+ richText = richText.replaceAll(`src="${src}"`, `src="${fullSrc}"`);
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return richText
|
|
|
},
|
|
|
/* 移除上传的音视频富文本src中的HOST */
|
|
|
doRemoveMideaHost(exerciseItem) {
|
|
|
console.log('removeHost', exerciseItem.question)
|
|
|
- let isSubjective = exerciseItem.type === 'complete' || exerciseItem.type === 'subjective' || exerciseItem
|
|
|
- .type ===
|
|
|
- 'compose'
|
|
|
+ let isSubjective = exerciseItem.type === 'complete' || exerciseItem.type === 'subjective' || exerciseItem.type === 'compose'
|
|
|
let richTextObj = {
|
|
|
question: exerciseItem.question,
|
|
|
answer: Array.isArray(exerciseItem.answer) && exerciseItem.answer.length ? exerciseItem.answer[0] :
|
|
@@ -846,7 +887,7 @@ export default {
|
|
|
srcList.forEach(src => {
|
|
|
let withSas = src.split('/')[src.split('/').length - 1]
|
|
|
let j = withSas.lastIndexOf('?')
|
|
|
- richTextObj[key] = richTextObj[key].replace(src, decodeURI(
|
|
|
+ richTextObj[key] = richTextObj[key].replaceAll(src, decodeURI(
|
|
|
withSas.slice(0, j)));
|
|
|
})
|
|
|
if (key === 'answer' && Array.isArray(exerciseItem.answer) && exerciseItem
|
|
@@ -896,13 +937,13 @@ export default {
|
|
|
let imgList = [];
|
|
|
let srcList = []
|
|
|
item.replace(srcReg, async (
|
|
|
- match, capture
|
|
|
- ) => {
|
|
|
- imgList.push(
|
|
|
- match);
|
|
|
- srcList.push(
|
|
|
- capture)
|
|
|
- });
|
|
|
+ match, capture
|
|
|
+ ) => {
|
|
|
+ imgList.push(
|
|
|
+ match);
|
|
|
+ srcList.push(
|
|
|
+ capture)
|
|
|
+ });
|
|
|
// 如果富文本中有图片内容 则提取所有src的值
|
|
|
if (imgList.length) {
|
|
|
for (let j = 0; j < imgList
|
|
@@ -912,14 +953,14 @@ export default {
|
|
|
// 如果图片有被设置过宽高即有被拉伸过之后 则根据新的宽高来生成新的base64作为图片src
|
|
|
if (heightReg.test(
|
|
|
item) && widthReg
|
|
|
- .test(item)) {
|
|
|
+ .test(item)) {
|
|
|
let srcHeight = ''
|
|
|
let srcWidth = ''
|
|
|
item.replace(
|
|
|
heightReg,
|
|
|
async (match,
|
|
|
capture
|
|
|
- ) => {
|
|
|
+ ) => {
|
|
|
srcHeight
|
|
|
=
|
|
|
capture
|
|
@@ -928,17 +969,17 @@ export default {
|
|
|
widthReg,
|
|
|
async (match,
|
|
|
capture
|
|
|
- ) => {
|
|
|
+ ) => {
|
|
|
srcWidth
|
|
|
=
|
|
|
capture
|
|
|
});
|
|
|
let newBase64 =
|
|
|
await this
|
|
|
- .compressImg(
|
|
|
- src,
|
|
|
- srcWidth,
|
|
|
- srcHeight)
|
|
|
+ .compressImg(
|
|
|
+ src,
|
|
|
+ srcWidth,
|
|
|
+ srcHeight)
|
|
|
item = item.replace(
|
|
|
src,
|
|
|
newBase64)
|
|
@@ -946,58 +987,58 @@ export default {
|
|
|
} else if (!heightReg
|
|
|
.test(item) &&
|
|
|
widthReg.test(item)
|
|
|
- ) {
|
|
|
+ ) {
|
|
|
// 取到宽度的百分比
|
|
|
let srcWidth = ''
|
|
|
item.replace(
|
|
|
widthReg,
|
|
|
async (match,
|
|
|
capture
|
|
|
- ) => {
|
|
|
+ ) => {
|
|
|
srcWidth
|
|
|
=
|
|
|
parseInt(
|
|
|
capture
|
|
|
- )
|
|
|
+ )
|
|
|
});
|
|
|
let img =
|
|
|
- new Image();
|
|
|
+ new Image();
|
|
|
img.src = src;
|
|
|
// 如果是宽度 则需要根据编辑器的宽度来计算出 拉伸后的高度和宽度
|
|
|
img.onload =
|
|
|
- async () => {
|
|
|
- let newWidth =
|
|
|
- editorWidth
|
|
|
- .optionWidth *
|
|
|
- srcWidth *
|
|
|
- 0.01
|
|
|
- let newHeight =
|
|
|
- newWidth *
|
|
|
- (img.height /
|
|
|
- img
|
|
|
- .width
|
|
|
- )
|
|
|
- let newBase64 =
|
|
|
- await this
|
|
|
- .compressImg(
|
|
|
- src,
|
|
|
- newWidth,
|
|
|
- newHeight
|
|
|
+ async () => {
|
|
|
+ let newWidth =
|
|
|
+ editorWidth
|
|
|
+ .optionWidth *
|
|
|
+ srcWidth *
|
|
|
+ 0.01
|
|
|
+ let newHeight =
|
|
|
+ newWidth *
|
|
|
+ (img.height /
|
|
|
+ img
|
|
|
+ .width
|
|
|
)
|
|
|
- item =
|
|
|
- item
|
|
|
- .replace(
|
|
|
- src,
|
|
|
- newBase64
|
|
|
- )
|
|
|
- r(item)
|
|
|
- }
|
|
|
+ let newBase64 =
|
|
|
+ await this
|
|
|
+ .compressImg(
|
|
|
+ src,
|
|
|
+ newWidth,
|
|
|
+ newHeight
|
|
|
+ )
|
|
|
+ item =
|
|
|
+ item
|
|
|
+ .replace(
|
|
|
+ src,
|
|
|
+ newBase64
|
|
|
+ )
|
|
|
+ r(item)
|
|
|
+ }
|
|
|
} else {
|
|
|
// 如果没有拉伸或者点击百分比显示 则按照原图进行压缩 宽高不变
|
|
|
let newBase64 =
|
|
|
await this
|
|
|
- .compressImg(
|
|
|
- src, 0, 0)
|
|
|
+ .compressImg(
|
|
|
+ src, 0, 0)
|
|
|
item = item.replace(
|
|
|
src,
|
|
|
newBase64)
|