Commit 444ccfa3 by yanju

Merge branch 'fix-issue#15' into 'master'

fix func

See merge request pigbigbig/beyond-clouds-front!140
parents f6c0c2f1 dacea92c
......@@ -5,7 +5,6 @@
style="border:1px solid black;width:200px"
lineHeight="1.5" v-model="d_value" fullHeight
></yun-textarea>
<yun-video dataSrc=" http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></yun-video>
<div class="height"></div>
</div>
......@@ -16,11 +15,487 @@
<script>
export default {
name:'yunEditor',
data(){
return{
d_value:''
props: {
scrollStyle: { // 是否渲染滚动条样式(webkit)
type: Boolean,
default: true
},
boxShadow: { // 是否添加阴影
type: Boolean,
default: true
},
transition: { // 是否开启动画过渡
type: Boolean,
default: true
},
autofocus: { // 是否自动获取焦点
type: Boolean,
default: true
},
fontSize: { // 字体大小
type: String,
default: '15px'
},
toolbarsBackground: { // 工具栏背景色
type: String,
default: '#ffffff'
},
editorBackground: { // TODO: 编辑栏背景色
type: String,
default: '#ffffff'
},
previewBackground: { // 预览栏背景色
type: String,
default: '#fbfbfb'
},
boxShadowStyle: { // 阴影样式
type: String,
default: '0 2px 12px 0 rgba(0, 0, 0, 0.1)'
},
help: {
type: String,
default: null
},
value: { // 初始 value
type: String,
default: ''
},
language: { // 初始语言
type: String,
default: 'zh-CN'
},
subfield: {
type: Boolean,
default: true
},
navigation: {
type: Boolean,
default: false
},
defaultOpen: {
type: String,
default: null
},
editable: { // 是否开启编辑
type: Boolean,
default: true
},
toolbarsFlag: { // 是否开启工具栏
type: Boolean,
default: true
},
toolbars: { // 工具栏
type: Object,
default() {
return CONFIG.toolbars
}
},
codeStyle: { // <code></code> 样
type: String,
default() {
return 'github';
}
},
placeholder: { // 编辑器默认内容
type: String,
default: null
},
ishljs: {
type: Boolean,
default: true
},
externalLink: {
type: [Object, Boolean],
default: true
},
imageFilter: {
type: Function,
default: null
},
imageClick: {
type: Function,
default: null
},
tabSize: {
type: Number,
default: 0
},
shortCut:{
type: Boolean,
default: true
}
},
data() {
return {
s_right_click_menu_show: false,
right_click_menu_top: 0,
right_click_menu_left: 0,
s_subfield: (() => {
return this.subfield;
})(),
s_autofocus: true,
// 标题导航
s_navigation: (() => {
return this.navigation;
})(),
s_scrollStyle: (() => {
return this.scrollStyle
})(),// props 是否渲染滚动条样式
d_value: '',// props 文本内容
d_render: '',// props 文本内容render
s_preview_switch: (() => {
let default_open_ = this.defaultOpen;
if (!default_open_) {
default_open_ = this.subfield ? 'preview' : 'edit';
}
return default_open_ === 'preview' ? true : false;
})(), // props true 展示编辑 false展示预览
s_fullScreen: false,// 全屏编辑标志
s_help: false,// markdown帮助
s_html_code: false,// 分栏情况下查看html
d_help: null,
d_words: null,
edit_scroll_height: -1,
s_readmodel: false,
s_table_enter: false, // 回车事件是否在表格中执行
d_history: (() => {
let temp_array = []
temp_array.push(this.value)
return temp_array;
})(), // 编辑记录
d_history_index: 0, // 编辑记录索引
currentTimeout: '',
d_image_file: [],
d_preview_imgsrc: null, // 图片预览地址
s_external_link: {
markdown_css: function() {
return 'https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/2.9.0/github-markdown.min.css';
},
hljs_js: function() {
return 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js';
},
hljs_lang: function(lang) {
return 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/' + lang + '.min.js';
},
hljs_css: function(css) {
if (hljsCss[css]) {
return 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/' + css + '.min.css';
}
return '';
},
katex_js: function() {
return 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.8.3/katex.min.js';
},
katex_css: function() {
return 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.8.3/katex.min.css';
}
},
p_external_link: {}
};
},
methods: {
loadExternalLink(name, type, callback) {
if (typeof this.p_external_link[name] !== 'function') {
if (this.p_external_link[name] != false) {
console.error('external_link.' + name, 'is not a function, if you want to disabled this error log, set external_link.' + name, 'to function or false');
}
return;
}
var _obj = {
'css': loadLink,
'js': loadScript
};
if (_obj.hasOwnProperty(type)) {
_obj[type](this.p_external_link[name](), callback);
}
},
initExternalFuc() {
var $vm = this;
var _external_ = ['markdown_css', 'hljs_js', 'hljs_css', 'hljs_lang', 'katex_js', 'katex_css'];
var _type_ = typeof $vm.externalLink;
var _is_object = (_type_ === 'object');
var _is_boolean = (_type_ === 'boolean');
for (var i = 0; i < _external_.length; i++) {
if ((_is_boolean && !$vm.externalLink) || (_is_object && $vm.externalLink[_external_[i]] === false)) {
$vm.p_external_link[_external_[i]] = false;
} else if (_is_object && typeof $vm.externalLink[_external_[i]] === 'function') {
$vm.p_external_link[_external_[i]] = $vm.externalLink[_external_[i]];
} else {
$vm.p_external_link[_external_[i]] = $vm.s_external_link[_external_[i]];
}
}
},
textAreaFocus() {
this.$refs.vNoteTextarea.$refs.vTextarea.focus();
},
$drag($e) {
var dataTransfer = $e.dataTransfer;
if (dataTransfer) {
var files = dataTransfer.files;
if (files.length > 0) {
$e.preventDefault();
this.$refs.toolbar_left.$imgFilesAdd(files);
}
}
},
$paste($e) {
var clipboardData = $e.clipboardData;
if (clipboardData) {
var items = clipboardData.items;
if (!items) return;
var types = clipboardData.types || [];
var item = null;
for (var i = 0; i < types.length; i++) {
if (types[i] === 'Files') {
item = items[i];
break;
}
}
if (item && item.kind === 'file') {
// prevent filename being pasted parallel along
// with the image pasting process
stopEvent($e)
var oFile = item.getAsFile();
this.$refs.toolbar_left.$imgFilesAdd([oFile]);
}
}
},
$imgTouch(file) {
var $vm = this;
// TODO 跳转到图片位置
},
$imgDel(file) {
this.markdownIt.image_del(file[1]);
// 删除所有markdown中的图片
let fileReg = file[0]
let reg = new RegExp(`\\!\\[${file[1]._name}\\]\\(${fileReg}\\)`, "g")
this.d_value = this.d_value.replace(reg, '');
this.iRender();
this.$emit('imgDel', file);
},
$imgAdd(pos, $file, isinsert) {
if (isinsert === undefined) isinsert = true;
var $vm = this;
if (this.__rFilter == null) {
// this.__rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
this.__rFilter = /^image\//i;
}
this.__oFReader = new FileReader();
this.__oFReader.onload = function (oFREvent) {
$vm.markdownIt.image_add(pos, oFREvent.target.result);
$file.miniurl = oFREvent.target.result;
if (isinsert === true) {
// 去除特殊字符
$file._name = $file.name.replace(/[\[\]\(\)\+\{\}&\|\\\*^%$#@\-]/g, '');
$vm.insertText($vm.getTextareaDom(),
{
prefix: '![' + $file._name + '](' + pos + ')',
subfix: '',
str: ''
});
$vm.$nextTick(function () {
$vm.$emit('imgAdd', pos, $file);
})
}
}
if ($file) {
var oFile = $file;
if (this.__rFilter.test(oFile.type)) {
this.__oFReader.readAsDataURL(oFile);
}
}
},
$imgUpdateByUrl(pos, url) {
var $vm = this;
this.markdownIt.image_add(pos, url);
this.$nextTick(function () {
$vm.d_render = this.markdownIt.render(this.d_value);
})
},
$imgAddByUrl(pos, url) {
if (this.$refs.toolbar_left.$imgAddByUrl(pos, url)) {
this.$imgUpdateByUrl(pos, url);
return true;
}
return false;
},
$img2Url(fileIndex, url) {
// x.replace(/(\[[^\[]*?\](?=\())\(\s*(\.\/2)\s*\)/g, "$1(http://path/to/png.png)")
var reg_str = "/(!\\[\[^\\[\]*?\\]\(?=\\(\)\)\\(\\s*\(" + fileIndex + "\)\\s*\\)/g"
var reg = eval(reg_str);
this.d_value = this.d_value.replace(reg, "$1(" + url + ")")
this.$refs.toolbar_left.$changeUrl(fileIndex, url)
this.iRender()
},
$imglst2Url(imglst) {
if (imglst instanceof Array) {
for (var i = 0; i < imglst.length; i++) {
this.$img2Url(imglst[i][0], imglst[i][1]);
}
}
},
toolbar_left_click(_type) {
toolbar_left_click(_type, this);
},
toolbar_left_addlink(_type, text, link) {
toolbar_left_addlink(_type, text, link, this);
},
toolbar_right_click(_type) {
toolbar_right_click(_type, this);
},
getNavigation($vm, full) {
return getNavigation($vm, full);
},
// @event
// 修改数据触发 (val , val_render)
change(val, render) {
this.$emit('change', val, render)
},
// 切换全屏触发 (status , val)
fullscreen(status, val) {
this.$emit('fullScreen', status, val)
},
// 打开阅读模式触发(status , val)
readmodel(status, val) {
this.$emit('readModel', status, val)
},
// 切换阅读编辑触发 (status , val)
previewtoggle(status, val) {
this.$emit('previewToggle', status, val)
},
// 切换分栏触发 (status , val)
subfieldtoggle(status, val) {
this.$emit('subfieldToggle', status, val)
},
// 切换htmlcode触发 (status , val)
htmlcode(status, val) {
this.$emit('htmlCode', status, val)
},
// 打开 , 关闭 help触发 (status , val)
helptoggle(status, val) {
this.$emit('helpToggle', status, val)
},
// 监听ctrl + s
save(val, render) {
this.$emit('save', val, render)
},
// 导航栏切换
navigationtoggle(status, val) {
this.$emit('navigationToggle', status, val)
},
$toolbar_right_read_change_status() {
this.s_readmodel = !this.s_readmodel
if (this.readmodel) {
this.readmodel(this.s_readmodel, this.d_value)
}
if (this.s_readmodel && this.toolbars.navigation) {
this.getNavigation(this, true)
}
},
// ---------------------------------------
// 滚动条联动
$v_edit_scroll($event) {
scrollLink($event, this);
},
// 获取textarea dom节点
getTextareaDom() {
return this.$refs.vNoteTextarea.$refs.vTextarea;
},
// 工具栏插入内容
insertText(obj, {prefix, subfix, str, type}) {
// if (this.s_preview_switch) {
insertTextAtCaret(obj, {prefix, subfix, str, type}, this);
},
insertTab() {
insertTab(this, this.tabSize)
},
insertOl() {
insertOl(this)
},
removeLine() {
removeLine(this)
},
insertUl() {
insertUl(this)
},
unInsertTab() {
unInsertTab(this, this.tabSize)
},
insertEnter(event) {
insertEnter(this, event)
},
saveHistory() {
this.d_history.splice(this.d_history_index + 1, this.d_history.length)
this.d_history.push(this.d_value)
this.d_history_index = this.d_history.length - 1
},
initLanguage() {
let lang = CONFIG.langList.indexOf(this.language) >= 0 ? this.language : 'zh-CN';
var $vm = this;
$vm.$render(CONFIG[`help_${lang}`], function(res) {
$vm.d_help = res;
})
this.d_words = CONFIG[`words_${lang}`];
},
// 编辑开关
editableTextarea() {
let text_dom = this.$refs.vNoteTextarea.$refs.vTextarea;
if (this.editable) {
text_dom.removeAttribute('disabled');
} else {
text_dom.setAttribute('disabled', 'disabled');
}
},
codeStyleChange(val, isInit) {
isInit = isInit ? isInit : false;
if (typeof this.p_external_link.hljs_css !== 'function') {
if (this.p_external_link.hljs_css != false)
{ console.error('external_link.hljs_css is not a function, if you want to disabled this error log, set external_link.hljs_css to function or false'); }
return;
}
var url = this.p_external_link.hljs_css(val);
if (url.length === 0 && isInit) {
console.warn('hljs color scheme', val, 'do not exist, loading default github');
url = this.p_external_link.hljs_css('github')
}
if (url.length > 0) {
loadLink(url)
} else {
console.warn('hljs color scheme', val, 'do not exist, hljs color scheme will not change');
}
},
iRender(toggleChange) {
var $vm = this;
this.$render($vm.d_value, function(res) {
// render
$vm.d_render = res;
// change回调 toggleChange == false 时候触发change回调
if (!toggleChange)
{
if ($vm.change) $vm.change($vm.d_value, $vm.d_render);
}
// 改变标题导航
if ($vm.s_navigation) getNavigation($vm, false);
// v-model 语法糖
$vm.$emit('input', $vm.d_value)
// 塞入编辑记录数组
if ($vm.d_value === $vm.d_history[$vm.d_history_index]) return
window.clearTimeout($vm.currentTimeout)
$vm.currentTimeout = setTimeout(() => {
$vm.saveHistory();
}, 500);
})
},
// 清空上一步 下一步缓存
$emptyHistory() {
this.d_history = [this.d_value] // 编辑记录
this.d_history_index = 0 // 编辑记录索引
}
},
}
......
import hljsLangs from '../core/hljs/lang.hljs.js'
import {
loadScript
} from '../core/extra-function.js'
var markdown_config = {
html: true, // Enable HTML tags in source
xhtmlOut: true, // Use '/' to close single tags (<br />).
breaks: true, // Convert '\n' in paragraphs into <br>
langPrefix: 'lang-', // CSS language prefix for fenced blocks. Can be
linkify: false, // 自动识别url
typographer: true,
quotes: '“”‘’'
}
var markdown = require('markdown-it')(markdown_config);
// 表情
var emoji = require('markdown-it-emoji');
// 下标
var sub = require('markdown-it-sub')
// 上标
var sup = require('markdown-it-sup')
// <dl/>
var deflist = require('markdown-it-deflist')
// <abbr/>
var abbr = require('markdown-it-abbr')
// footnote
var footnote = require('markdown-it-footnote')
// insert 带有下划线 样式 ++ ++
var insert = require('markdown-it-ins')
// mark
var mark = require('markdown-it-mark')
// taskLists
var taskLists = require('markdown-it-task-lists')
// container
var container = require('markdown-it-container')
//
var toc = require('markdown-it-toc')
// add target="_blank" to all link
var defaultRender = markdown.renderer.rules.link_open || function(tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
};
markdown.renderer.rules.link_open = function (tokens, idx, options, env, self) {
var hIndex = tokens[idx].attrIndex('href');
if (tokens[idx].attrs[hIndex][1].startsWith('#')) return defaultRender(tokens, idx, options, env, self);
// If you are sure other plugins can't add `target` - drop check below
var aIndex = tokens[idx].attrIndex('target');
if (aIndex < 0) {
tokens[idx].attrPush(['target', '_blank']); // add new attribute
} else {
tokens[idx].attrs[aIndex][1] = '_blank'; // replace value of existing attr
}
// pass token to default renderer.
return defaultRender(tokens, idx, options, env, self);
};
var mihe = require('markdown-it-highlightjs-external');
// math katex
var katex = require('markdown-it-katex-external');
var miip = require('markdown-it-images-preview');
var missLangs = {};
var needLangs = [];
var hljs_opts = {
hljs: 'auto',
highlighted: true,
langCheck: function(lang) {
if (lang && hljsLangs[lang] && !missLangs[lang]) {
missLangs[lang] = 1;
needLangs.push(hljsLangs[lang])
}
}
};
markdown.use(mihe, hljs_opts)
.use(emoji)
.use(sup)
.use(sub)
.use(container)
.use(container, 'hljs-left') /* align left */
.use(container, 'hljs-center')/* align center */
.use(container, 'hljs-right')/* align right */
.use(deflist)
.use(abbr)
.use(footnote)
.use(insert)
.use(mark)
.use(container)
.use(miip)
.use(katex)
.use(taskLists)
.use(toc)
export default {
data() {
return {
markdownIt: markdown
}
},
mounted() {
var $vm = this;
hljs_opts.highlighted = this.ishljs;
},
methods: {
$render(src, func) {
var $vm = this;
missLangs = {};
needLangs = [];
var res = markdown.render(src);
if (this.ishljs) {
if (needLangs.length > 0) {
$vm.$_render(src, func, res);
}
}
func(res);
},
$_render(src, func, res) {
var $vm = this;
var deal = 0;
for (var i = 0; i < needLangs.length; i++) {
var url = $vm.p_external_link.hljs_lang(needLangs[i]);
loadScript(url, function() {
deal = deal + 1;
if (deal === needLangs.length) {
res = markdown.render(src);
func(res);
}
})
}
}
},
watch: {
ishljs: function(val) {
hljs_opts.highlighted = val;
}
}
};
......@@ -99,7 +99,7 @@
</div>
<div class="abs_down-arrow" @click="showPraiseCon=!showPraiseCon" v-if="praiseList.length>0">
<yun-icon :class="returnItem4IconClass" size="8px" name="down_arrow"></yun-icon>
<yun-icon :class="returnItem4IconClass" size="6px" name="down_arrow"></yun-icon>
</div>
</div>
</div>
......
......@@ -54,8 +54,8 @@
<yun-icon name="like1" class="heart"></yun-icon>
<p class="num">{{articleDetail.praiseNum}}</p>
</div>
<div class="article__praise-member">
<yun-avatar class="more-member" :key="val.userId" :style="{marginRight:(index+1)%10===0?'0px':'28px'}" size="40px" borderR="20px" v-for="(val,index) in praiseList" :userId="val.userId" :src="val.userAvatar" :name="val.nickName"></yun-avatar>
<div class="article__praise-member" :style="{justifyContent:praiseList.length<=9?'center':'flex-start'}">
<yun-avatar class="more-member" :key="val.userId" :style="{marginRight:(index+1)%10===0?'0px':'28px',marginLeft:index===0&&praiseList.length<=9?'28px':'0px'}" size="40px" borderR="20px" v-for="(val,index) in praiseList" :userId="val.userId" :src="val.userAvatar" :name="val.nickName"></yun-avatar>
<p class="more-member" v-if="!showAllPraise" @click="dataGetAllPraiseList">更多</p>
</div>
<div class="article__footer">
......
......@@ -54,8 +54,8 @@
<p class="num">{{articleDetail.praiseNum}}</p>
</div>
<div class="article__praise-member">
<yun-avatar class="more-member" :key="val.userId" :style="{marginRight:(index+1)%10===0?'0px':'28px'}" size="40px" borderR="20px" v-for="(val,index) in praiseList" :userId="val.userId" :src="val.userAvatar" :name="val.nickName"></yun-avatar>
<div class="article__praise-member" :style="{justifyContent:praiseList.length<=9?'center':'flex-start'}">
<yun-avatar class="more-member" :key="val.userId" :style="{marginRight:(index+1)%10===0?'0px':'28px',marginLeft:index===0&&praiseList.length<=9?'28px':'0px'}" size="40px" borderR="20px" v-for="(val,index) in praiseList" :userId="val.userId" :src="val.userAvatar" :name="val.nickName"></yun-avatar>
<p class="more-member" v-if="!showAllPraise" @click="dataGetAllPraiseList">更多</p>
</div>
<div class="article__footer">
......
......@@ -71,8 +71,8 @@
<yun-icon name="like1" class="heart"></yun-icon>
<p class="num">{{articleDetail.praiseNum}}</p>
</div>
<div class="article__praise-member">
<yun-avatar :key="val.userId" class="more-member" :style="{marginRight:(index+1)%10===0?'0px':'28px'}" size="40px" borderR="20px" v-for="(val,index) in praiseList" :userId="val.userId" :src="val.userAvatar" :name="val.nickName"></yun-avatar>
<div class="article__praise-member" :style="{justifyContent:praiseList.length<=9?'center':'flex-start'}">
<yun-avatar class="more-member" :key="val.userId" :style="{marginRight:(index+1)%10===0?'0px':'28px',marginLeft:index===0&&praiseList.length<=9?'28px':'0px'}" size="40px" borderR="20px" v-for="(val,index) in praiseList" :userId="val.userId" :src="val.userAvatar" :name="val.nickName"></yun-avatar>
<p class="more-member" v-if="!showAllPraise" @click="dataGetAllPraiseList">更多</p>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment