mirror of https://github.com/halo-dev/halo
feat: add the first line indent to the Tab shortcut key (#6388)
#### What type of PR is this? /kind feature /area editor #### What this PR does / why we need it: 支持在默认编辑器中使用 Tab 键实现首行缩进的功能。 当光标处于文本首行时,按下 Tab 键会触发首行缩进。 在首行缩进的情况下或者选中一段文本,再次按下 Tab 键会触发整段缩进。 #### How to test it? 测试文本块及区域标题块首行按下 Tab 键是否可以正常触发首行缩进 #### Which issue(s) this PR fixes: Fixes #6316 #### Does this PR introduce a user-facing change? ```release-note 默认编辑器增加 Tab 快捷键首行缩进功能 ```pull/6408/head
parent
687de1c550
commit
59b3f460fb
|
@ -24,6 +24,7 @@ type IndentOptions = {
|
|||
maxIndentLevel: number;
|
||||
defaultIndentLevel: number;
|
||||
HTMLAttributes: Record<string, any>;
|
||||
firstLineIndent: boolean;
|
||||
};
|
||||
const Indent = Extension.create<IndentOptions, never>({
|
||||
name: "indent",
|
||||
|
@ -36,6 +37,7 @@ const Indent = Extension.create<IndentOptions, never>({
|
|||
maxIndentLevel: 24 * 10,
|
||||
defaultIndentLevel: 0,
|
||||
HTMLAttributes: {},
|
||||
firstLineIndent: true,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -56,6 +58,13 @@ const Indent = Extension.create<IndentOptions, never>({
|
|||
parseInt(element.style.marginLeft, 10) ||
|
||||
this.options.defaultIndentLevel,
|
||||
},
|
||||
lineIndent: {
|
||||
default: false,
|
||||
renderHTML: (attributes) => ({
|
||||
style: attributes.lineIndent ? "text-indent: 2em" : "",
|
||||
}),
|
||||
parseHTML: (element) => element.style.textIndent === "2em",
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -76,9 +85,8 @@ const Indent = Extension.create<IndentOptions, never>({
|
|||
);
|
||||
if (tr.docChanged && dispatch) {
|
||||
dispatch(tr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
outdent:
|
||||
() =>
|
||||
|
@ -93,9 +101,8 @@ const Indent = Extension.create<IndentOptions, never>({
|
|||
);
|
||||
if (tr.docChanged && dispatch) {
|
||||
dispatch(tr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@ -133,22 +140,48 @@ export const clamp = (val: number, min: number, max: number): number => {
|
|||
function setNodeIndentMarkup(
|
||||
tr: Transaction,
|
||||
pos: number,
|
||||
delta: number,
|
||||
min: number,
|
||||
max: number
|
||||
dir: number,
|
||||
options: IndentOptions
|
||||
): Transaction {
|
||||
if (!tr.doc) return tr;
|
||||
if (!tr.doc) {
|
||||
return tr;
|
||||
}
|
||||
const node = tr.doc.nodeAt(pos);
|
||||
if (!node) return tr;
|
||||
if (!node) {
|
||||
return tr;
|
||||
}
|
||||
if (options.firstLineIndent && isLineIndent(tr)) {
|
||||
if (node.attrs.lineIndent !== dir > 0) {
|
||||
const nodeAttrs = { ...node.attrs, lineIndent: dir > 0 };
|
||||
return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);
|
||||
}
|
||||
}
|
||||
|
||||
const delta = options.indentRange * dir;
|
||||
const min = options.minIndentLevel;
|
||||
const max = options.maxIndentLevel;
|
||||
const indent = clamp((node.attrs.indent || 0) + delta, min, max);
|
||||
if (indent === node.attrs.indent) return tr;
|
||||
const nodeAttrs = {
|
||||
...node.attrs,
|
||||
indent,
|
||||
};
|
||||
if (indent === node.attrs.indent) {
|
||||
return tr;
|
||||
}
|
||||
const nodeAttrs = { ...node.attrs, indent };
|
||||
return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);
|
||||
}
|
||||
|
||||
const isLineIndent = (tr: Transaction) => {
|
||||
const { selection } = tr;
|
||||
const { $from, from, to } = selection;
|
||||
if (from == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (from != to) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $from.textOffset == 0;
|
||||
};
|
||||
|
||||
type IndentType = "indent" | "outdent";
|
||||
const updateIndentLevel = (
|
||||
tr: Transaction,
|
||||
|
@ -167,13 +200,7 @@ const updateIndentLevel = (
|
|||
if (isTextIndent(tr, pos) && type === "indent") {
|
||||
tr.insertText("\t", from, to);
|
||||
} else {
|
||||
tr = setNodeIndentMarkup(
|
||||
tr,
|
||||
pos,
|
||||
options.indentRange * (type === "indent" ? 1 : -1),
|
||||
options.minIndentLevel,
|
||||
options.maxIndentLevel
|
||||
);
|
||||
tr = setNodeIndentMarkup(tr, pos, type === "indent" ? 1 : -1, options);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -210,11 +237,9 @@ const isFilterActive = (editor: CoreEditor) => {
|
|||
export const getIndent: () => KeyboardShortcutCommand =
|
||||
() =>
|
||||
({ editor }) => {
|
||||
// @ts-ignore
|
||||
if (isFilterActive(editor)) {
|
||||
return false;
|
||||
}
|
||||
// @ts-ignore
|
||||
if (isListActive(editor)) {
|
||||
const name = editor.can().sinkListItem("listItem")
|
||||
? "listItem"
|
||||
|
|
Loading…
Reference in New Issue