zview-mobile-editor
Version:
A WYSIWYG text editor base on html5 and vue
213 lines (210 loc) • 6.66 kB
JavaScript
import RangeHandler from './range/handler'
import './style.css'
import template from './editor.html'
/**
* Created by peak on 2017/2/9.
*/
export default {
template,
props: {
value: {
type: String,
default: ''
},
/* content: {
type: String,
required: true,
default: ''
},*/
height: {
type: Number,
default: 300,
validator(val){
return val >= 100
}
},
zIndex: {
type: Number,
default: 1000
},
autoHeight: {
type: Boolean,
default: true
},
showModuleName: {}
},
data(){
return {
// defaultShowModuleName:false
// locale: {},
// modules:{},
fullScreen: false,
dashboard: null
}
},
watch: {
/* content(val) {
const content = this.$refs.content.innerHTML
if (val !== content) {
this.$refs.content.innerHTML = val
}
},*/
fullScreen(val){
const component = this
if (val) {
component.parentEl = component.$el.parentNode
component.nextEl = component.$el.nextSibling
document.body.appendChild(component.$el)
return
}
if (component.nextEl) {
component.parentEl.insertBefore(component.$el, component.nextEl)
return
}
component.parentEl.appendChild(component.$el)
}
},
computed: {
contentStyle(){
const style = {}
if (this.fullScreen) {
style.height = `${window.innerHeight - this.$refs.toolbar.clientHeight - 1}px`
return style
}
if (!this.autoHeight) {
style.height = `${this.height}px`
return style
}
style['min-height'] = `${this.height}px`
return style
},
currentValue: {
// 动态计算currentValue的值
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
},
methods: {
toggleFullScreen(){
this.fullScreen = !this.fullScreen
},
enableFullScreen(){
this.fullScreen = true
},
exitFullScreen(){
this.fullScreen = false
},
focus(){
this.$refs.content.focus()
},
toggleDashboard(dashboard){
this.dashboard = this.dashboard === dashboard ? null : dashboard
},
execCommand(command, arg){
this.restoreSelection()
if (this.range) {
new RangeHandler(this.range).execCommand(command, arg)
}
this.toggleDashboard()
this.currentValue = this.$refs.content.innerHTML // L
// this.$emit('change', this.$refs.content.innerHTML)
},
getCurrentRange(){
return this.range
},
saveCurrentRange(){
const selection = window.getSelection ? window.getSelection() : document.getSelection()
if (!selection.rangeCount) {
return
}
const content = this.$refs.content
for (let i = 0; i < selection.rangeCount; i++) {
const range = selection.getRangeAt(0)
let start = range.startContainer
let end = range.endContainer
// for IE11 : node.contains(textNode) always return false
start = start.nodeType === Node.TEXT_NODE ? start.parentNode : start
end = end.nodeType === Node.TEXT_NODE ? end.parentNode : end
if (content.contains(start) && content.contains(end)) {
this.range = range
break
}
}
},
restoreSelection(){
const selection = window.getSelection ? window.getSelection() : document.getSelection()
selection.removeAllRanges()
if (this.range) {
selection.addRange(this.range)
} else {
const content = this.$refs.content
const div = document.createElement('div')
const range = document.createRange()
content.appendChild(div)
range.setStart(div, 0)
range.setEnd(div, 0)
selection.addRange(range)
this.range = range
}
},
activeModule(module){
if (typeof module.handler === 'function') {
module.handler(this)
return
}
if (module.hasDashboard) {
this.toggleDashboard(`dashboard-${module.name}`)
}
}
},
created(){
this.modules.forEach((module) => {
if (typeof module.init === 'function') {
module.init(this)
}
})
},
mounted(){
// console.log('mounted', this.value)
// alert(`mounted${this.value}`)
const content = this.$refs.content
// content.innerHTML = this.content;
content.innerHTML = this.currentValue
content.addEventListener('mouseup', this.saveCurrentRange, false)
content.addEventListener('keyup', () => {
// this.$emit('change', content.innerHTML)
this.currentValue = content.innerHTML // L
this.saveCurrentRange()
}, false)
content.addEventListener('mouseout', (e) => {
if (e.target === content) {
this.saveCurrentRange()
}
}, false)
this.touchHandler = (e) => {
this.currentValue = content.innerHTML // L
if (content.contains(e.target)) {
this.saveCurrentRange()
}
}
window.addEventListener('touchend', this.touchHandler, false)
},
updated(){
// update dashboard style
if (this.$refs.dashboard){
this.$refs.dashboard.style.maxHeight = `${this.$refs.content.clientHeight}px`
}
},
beforeDestroy(){
window.removeEventListener('touchend', this.touchHandler)
this.modules.forEach((module) => {
if (typeof module.destroyed === 'function') {
module.destroyed(this)
}
})
}
}