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 = false
const 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)
}