Files
outline/shared/editor/nodes/OrderedList.ts
T
dependabot[bot] fc01deeefd chore(deps-dev): bump oxlint-tsgolint from 0.14.2 to 0.22.1 (#12320)
* chore(deps-dev): bump oxlint-tsgolint from 0.14.2 to 0.22.1

Bumps [oxlint-tsgolint](https://github.com/oxc-project/tsgolint) from 0.14.2 to 0.22.1.
- [Release notes](https://github.com/oxc-project/tsgolint/releases)
- [Commits](https://github.com/oxc-project/tsgolint/compare/v0.14.2...v0.22.1)

---
updated-dependencies:
- dependency-name: oxlint-tsgolint
  dependency-version: 0.22.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: Switch tsconfig to bundler resolution for tsgolint 0.22.1

oxlint-tsgolint 0.22.1 removed support for moduleResolution=node10
(the alias for "node"). Switch to "bundler" with resolvePackageJsonExports
disabled so packages whose exports field omits a types condition still
resolve. Update markdown-it type imports to sub-paths since the package's
.d.mts entry only re-exports a subset of named types.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: Resolve type-aware lint errors caught by tsgolint 0.22.1

oxlint-tsgolint 0.22.1 catches several await-thenable, no-floating-promises,
and no-meaningless-void-operator cases the prior 0.14.2 missed:

- Drop redundant inner `await` from Promise.all([await x, await y]) call sites
  so the array entries are real Promises rather than already-resolved values.
- Replace Promise.all wrappers around synchronous presenters (presentEvent,
  presentTemplate, presentPublicTeam) with plain map / direct calls.
- Wrap non-promise branches of ternaries inside Promise.all with
  Promise.resolve so the array remains thenable across both arms.
- Add `void` to the unawaited provider.connect() in the auth-failed retry
  chain, and remove `void` from the disconnect() call which returns void.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 07:59:13 -04:00

193 lines
5.2 KiB
TypeScript

import type { PluginSimple } from "markdown-it";
import type Token from "markdown-it/lib/token.mjs";
import type {
NodeSpec,
NodeType,
Schema,
Node as ProsemirrorNode,
} from "prosemirror-model";
import toggleList from "../commands/toggleList";
import type { MarkdownSerializerState } from "../lib/markdown/serializer";
import { listWrappingInputRule } from "../lib/listInputRule";
import alphaListsRule from "../rules/alphaLists";
import Node from "./Node";
export default class OrderedList extends Node {
get name() {
return "ordered_list";
}
get rulePlugins(): PluginSimple[] {
return [alphaListsRule];
}
get schema(): NodeSpec {
return {
attrs: {
order: {
default: 1,
validate: "number",
},
listStyle: {
default: "number",
validate: (style: string) =>
["number", "lower-alpha", "upper-alpha"].includes(style),
},
},
content: "list_item+",
group: "block list",
parseDOM: [
{
tag: "ol",
getAttrs: (dom: HTMLOListElement) => ({
order: dom.hasAttribute("start")
? parseInt(dom.getAttribute("start") || "1", 10)
: 1,
listStyle: dom.style.listStyleType,
}),
},
],
toDOM: (node) => {
const attrs: { start?: number; style?: string } = {};
if (node.attrs.order !== 1) {
attrs.start = node.attrs.order;
}
if (node.attrs.listStyle !== "number") {
attrs.style = `list-style-type: ${node.attrs.listStyle}`;
}
return ["ol", attrs, 0];
},
};
}
commands({ type, schema }: { type: NodeType; schema: Schema }) {
return {
ordered_list: () => toggleList(type, schema.nodes.list_item),
toggleLowerLetterList: () =>
toggleList(type, schema.nodes.list_item, "lower-alpha"),
toggleUpperLetterList: () =>
toggleList(type, schema.nodes.list_item, "upper-alpha"),
};
}
keys({ type, schema }: { type: NodeType; schema: Schema }) {
return {
"Shift-Ctrl-9": toggleList(type, schema.nodes.list_item),
"Shift-Ctrl-5": this.commands({ type, schema }).toggleUpperLetterList(),
"Shift-Ctrl-6": this.commands({ type, schema }).toggleLowerLetterList(),
};
}
inputRules({ type }: { type: NodeType }) {
return [
listWrappingInputRule(
/^(\d+)\.\s$/,
type,
(match) => ({ order: +match[1], listStyle: "number" }),
(match, node) => node.childCount + node.attrs.order === +match[1]
),
listWrappingInputRule(
/^([a-z])\.\s$/,
type,
(match) => ({
order: match[1].charCodeAt(0) - 96,
listStyle: "lower-alpha",
}),
(match, node) => {
const expectedChar = String.fromCharCode(
96 + node.childCount + node.attrs.order
);
return expectedChar === match[1];
}
),
listWrappingInputRule(
/^([A-Z])\.\s$/,
type,
(match) => ({
order: match[1].charCodeAt(0) - 64,
listStyle: "upper-alpha",
}),
(match, node) => {
const expectedChar = String.fromCharCode(
64 + node.childCount + node.attrs.order
);
return expectedChar === match[1];
}
),
];
}
toMarkdown(state: MarkdownSerializerState, node: ProsemirrorNode) {
state.write("\n");
const start = node.attrs.order !== undefined ? node.attrs.order : 1;
const upperOrLowerAlpha =
node.attrs.listStyle === "lower-alpha" ||
node.attrs.listStyle === "upper-alpha";
if (upperOrLowerAlpha) {
const space = state.repeat(" ", 4);
state.renderList(node, space, (index: number) => {
const alphabetSize = 26;
const position = start + index;
const asciiStart = node.attrs.listStyle === "lower-alpha" ? 97 : 65;
let n = position - 1;
let result = "";
do {
const charCode = asciiStart + (n % alphabetSize);
result = String.fromCharCode(charCode) + result;
n = Math.floor(n / alphabetSize) - 1;
} while (n >= 0);
return result + ". ";
});
} else {
const maxW = `${start + node.childCount - 1}`.length;
const space = state.repeat(" ", maxW + 2);
state.renderList(node, space, (index: number) => {
const nStr = `${start + index}`;
return state.repeat(" ", maxW - nStr.length) + nStr + ". ";
});
}
}
parseMarkdown() {
return {
block: "ordered_list",
getAttrs: (tok: Token) => {
const start = tok.attrGet("start") || "1";
// Check for data-list-style attribute set by alphaLists plugin
const dataListStyle = tok.attrGet("data-list-style");
let listStyle = dataListStyle || "number";
// Fallback to checking markup if data-list-style is not present
if (!dataListStyle) {
if (tok.markup && /^[a-z]/.test(tok.markup)) {
listStyle = "lower-alpha";
} else if (tok.markup && /^[A-Z]/.test(tok.markup)) {
listStyle = "upper-alpha";
}
}
return {
order: parseInt(start, 10),
listStyle,
};
},
};
}
}