WangEditor添加首行缩进功能

官方也不增加这个,但对于经常写文章的用户来说,首行缩进是很实用的功能,改变一下样式就可以了text-indent: 2em;

修改一下初始化wangEditor的地方,注册一个菜单

//初始化编辑器
var E = window.wangEditor;
// 菜单 key ,各个菜单不能重复
const menuKey = ‘MyTextIndentMenuKey’

// 注册菜单
E.registerMenu(menuKey, MyTextIndentMenu)

var editor = new E(‘#’+id);

 

新增一个MyTextIndentMenu.js,代码如下:

 

const E = window.wangEditor
const { $, BtnMenu , DropListMenu, PanelMenu, DropList, Panel, Tooltip } = E

const lengthRegex = /^(\d+)(\w+)$/
const percentRegex = /^(\d+)%$/
const reg = /^(SECTION|P|H[0-9]*)$/

// 第一,菜单 class ,Button 菜单继承 BtnMenu class https://www.wangeditor.com/doc/
class MyTextIndentMenu extends BtnMenu{
constructor(editor) {
// data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述text-indent: 2em;
const $elem = E.$(
`<div class=”w-e-menu w-e-icon-indent-increase” data-title=”首行缩进”>
</div>`
)
super($elem, editor)
}
// 菜单点击事件
clickHandler() {
// 做任何你想做的事情text-indent: 2em;
// 可参考【常用 API】文档,来操作编辑器
this.command();
}
// 菜单是否被激活(如果不需要,这个函数可以空着)
// 1. 激活是什么?光标放在一段加粗、下划线的文本时,菜单栏里的 B 和 U 被激活,如下图
// 2. 什么时候执行这个函数?每次编辑器区域的选区变化(如鼠标操作、键盘操作等),都会触发各个菜单的 tryChangeActive 函数,重新计算菜单的激活状态
tryChangeActive() {
// 激活菜单
// 1. 菜单 DOM 节点会增加一个 .w-e-active 的 css class
// 2. this.this.isActive === true
const editor = this.editor
const $selectionElem = editor.selection.getSelectionStartElem()
const $selectionStartElem = $($selectionElem).getNodeTop(editor)

if ($selectionStartElem.length <= 0) return

if ($selectionStartElem.elems[0].style[‘textIndent’] !== ”) {
this.active()
} else {
this.unActive()
}
}
/**
* 执行命令
* @param value value
*/
command() {
const editor = this.editor
const $selectionElem = editor.selection.getSelectionContainerElem()

// 判断 当前选区为 textElem 时
if ($selectionElem && editor.$textElem.equal($selectionElem)) {
// 当 当前选区 等于 textElem 时
// 代表 当前选区 可能是一个选择了一个完整的段落或者多个段落
const $elems = editor.selection.getSelectionRangeTopNodes()
if ($elems.length > 0) {
$elems.forEach((item) => {
this.operateElement($(item), editor)
})
}
} else {
// 当 当前选区 不等于 textElem 时
// 代表 当前选区要么是一个段落,要么是段落中的一部分
if ($selectionElem && $selectionElem.length > 0) {
$selectionElem.forEach((item) => {
this.operateElement($(item), editor)
})
}
}

// 恢复选区
editor.selection.restoreSelection()
this.tryChangeActive()
}

operateElement($node, editor) {
const $elem = $node.getNodeTop(editor)
let type = ‘increase’;
if($node.elems[0].style[‘textIndent’] !== ”)
type = ‘decrease’;

if (reg.test($elem.getNodeName())) {
if (type === ‘increase’) this.increaseIndentStyle($elem, this.parseIndentation(editor))
else if (type === ‘decrease’) this.decreaseIndentStyle($elem, this.parseIndentation(editor))
}
}
increaseIndentStyle($node, options) {
const $elem = $node.elems[0]
if ($elem.style[‘textIndent’] === ”) {
$node.css(‘text-indent’, options.value + options.unit)
} else {
const oldPL = $elem.style[‘textIndent’]
const oldVal = oldPL.slice(0, oldPL.length – options.unit.length)
const newVal = Number(oldVal) + options.value
$node.css(‘text-indent’, `${newVal}${options.unit}`)
}
}
decreaseIndentStyle($node, options) {
const $elem = $node.elems[0]
if ($elem.style[‘textIndent’] !== ”) {
const oldPL = $elem.style[‘textIndent’]
const oldVal = oldPL.slice(0, oldPL.length – options.unit.length)
const newVal = Number(oldVal) – options.value
if (newVal > 0) {
$node.css(‘text-indent’, `${newVal}${options.unit}`)
} else {
$node.css(‘text-indent’, ”)
}
}
}

parseIndentation(editor) {
const { indentation } = editor.config

if (typeof indentation === ‘string’) {
if (lengthRegex.test(indentation)) {
const [value, unit] = indentation.trim().match(lengthRegex).slice(1, 3)
return {
value: Number(value),
unit,
}
} else if (percentRegex.test(indentation)) {
return {
value: Number(indentation.trim().match(percentRegex)?indentation.trim().match(percentRegex):[1]),
unit: ‘%’,
}
}
} else if (indentation.value !== void 0 && indentation.unit) {
return indentation
}

return {
value: 2,
unit: ’em’,
}
}

}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.