canvas-editor中渲染部分的源码都在Draw.ts里,能找到computeRowList方法中并没有实现首行缩进相关的逻辑,但是实现了element.type === ElementType.TAB的缩进,如图:
因此我们可以基于tab进行首行缩进的逻辑编写,在main.ts末尾(初始化脚本内部)添加如下内容:
// 段落首行缩进按钮const indentParagraphsDom = document.querySelector<HTMLDivElement>('.menu-item__indent-paragraphs')!indentParagraphsDom.onclick = function () {console.log('indent paragraphs')const data = instance.command.getValue()console.log('data: ', data)// 插入tab符const tabElement: IElement = {type: ElementType.TAB,value: ''}if (data && data.data && Array.isArray(data.data.main)) {const newMain = data.data.main.flatMap(item => {// 检查是否为段落(不是标题或换行符)if (typeof item === 'object' &&!item.type &&typeof item.value === 'string' &&item.value.trim() !== '' &&item.value !== '\n') {// 如果是段落,在前面插入制表符对象return [tabElement,item]}return [item]})const fixedData = { ...data.data, main: newMain }console.log('fixedData: ', fixedData)// 更新编辑器内容instance.command.executeSetValue(fixedData)}const newdata = instance.command.getValue()console.log('newdata: ', newdata)}
我们就可以用一个按钮来直接控制全文正文部分进行首行缩进
更进一步的,如果想要一键切换缩进/不缩进可以这样写:
// 段落首行缩进按钮
const indentParagraphsDom = document.querySelector<HTMLDivElement>('.menu-item__indent-paragraphs'
)!
indentParagraphsDom.onclick = function () {console.log('indent paragraphs')const data = instance.command.getValue()console.log('data: ', data)if (data && data.data && Array.isArray(data.data.main)) {let shouldRemoveTabs = falseconst newMain: IElement[] = []// 检查是否存在制表符shouldRemoveTabs = data.data.main.some((item, index) => item.type === ElementType.TAB && index + 1 < data.data.main.length && typeof data.data.main[index + 1] === 'object' &&!data.data.main[index + 1].type &&typeof data.data.main[index + 1].value === 'string' &&data.data.main[index + 1].value.trim() !== '' &&data.data.main[index + 1].value !== '\n')console.log('shouldRemoveTabs:', shouldRemoveTabs)for (let i = 0; i < data.data.main.length; i++) {const item = data.data.main[i]if (shouldRemoveTabs) {// 移除制表符if (item.type !== ElementType.TAB) {newMain.push(item)}} else {// 添加制表符if (typeof item === 'object' &&!item.type &&typeof item.value === 'string' &&item.value.trim() !== '' &&item.value !== '\n') {// 如果是段落,在前面添加制表符if (i === 0 || data.data.main[i-1].type !== ElementType.TAB) {newMain.push({ type: ElementType.TAB, value: '' })}}newMain.push(item)}}const fixedData = { ...data.data, main: newMain }console.log('fixedData: ', fixedData)// 更新编辑器内容instance.command.executeSetValue(fixedData)}const newdata = instance.command.getValue()console.log('newdata: ', newdata)
}