Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ooxml-inspector/src/children/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ Options:
}

function notFound(q) {
console.error(`Unknown element: \${q}\\`);
console.error(`Unknown element: ${q}`);
Comment thread
harbournick marked this conversation as resolved.
process.exit(2);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const handleBackspaceNextToList =
// --- Case A: caret INSIDE a list item (our MS-Word model: list -> listItem -> paragraph)
const ctx = getListContext(state);
if (ctx) {
const { listDepth, listPos, listNode, liNode } = ctx;
const { listPos, listNode, liNode } = ctx;

// Only trigger at the start of the item's current paragraph OR if the item is empty
const atStartOfParagraph = $from.parentOffset === 0;
Expand Down
30 changes: 17 additions & 13 deletions packages/super-editor/src/core/commands/decreaseListIndent.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export const decreaseListIndent =
// 2) Parent list (ordered OR bullet)
const parentOrdered = ListHelpers.getParentOrderedList && ListHelpers.getParentOrderedList(state);
const parentBullet = ListHelpers.getParentBulletList && ListHelpers.getParentBulletList(state);

const parentList =
parentOrdered ||
parentBullet ||
Expand All @@ -30,23 +29,28 @@ export const decreaseListIndent =
const attrs = currentItem.node.attrs || {};
const currLevel = typeof attrs.level === 'number' ? attrs.level : 0;

// No-op at level 0 (consume the key so the browser doesn't Shift-Tab focus)
if (currLevel <= 0) {
return true;
}
// No-op at level 0 (consume Shift+Tab)
if (currLevel <= 0) return true;

// Decrease level by 1; keep/repair numId
const newLevel = currLevel - 1;
let numId =
attrs.numId ??
parentList.node?.attrs?.listId ??
(ListHelpers.getNewListId ? ListHelpers.getNewListId(editor) : null);

// Ensure definition exists for this list/id (safe no-op if already exists)
if (numId != null && ListHelpers.generateNewListDefinition) {
// Resolve numId: prefer parent's listId (keeps the current container’s definition),
// else keep the item's, else mint a new one.
const parentNumId = parentList.node?.attrs?.listId ?? null;
let numId = parentNumId ?? attrs.numId ?? null;

let createdNewId = false;
if (numId == null && ListHelpers.getNewListId) {
numId = ListHelpers.getNewListId(editor);
createdNewId = true;
}

// Only create a definition when we *just* minted the id.
// Never re-generate for an existing id (prevents clobbering bullet/ordered mapping).
if (createdNewId && numId != null && ListHelpers.generateNewListDefinition) {
ListHelpers.generateNewListDefinition({
numId,
listType: parentList.node.type, // orderedList or bulletList NodeType
listType: parentList.node.type,
editor,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { ListHelpers } from '../helpers/list-numbering-helpers.js';
import { decreaseListIndent } from './decreaseListIndent.js';

// Mock the helper modules used by the command
vi.mock('../helpers/list-numbering-helpers.js', () => {
const fns = {
getCurrentListItem: vi.fn(),
Expand Down Expand Up @@ -85,7 +84,7 @@ describe('decreaseListIndent', () => {
expect(ListHelpers.generateNewListDefinition).not.toHaveBeenCalled();
});

it('decreases level by 1 and keeps existing numId; ensures list definition', () => {
it('decreases level by 1 and ADOPTS parent listId when parent has one; does NOT re-generate definition', () => {
const currentItem = {
node: { type: { name: 'listItem' }, attrs: { level: 2, numId: 123, foo: 'bar' } },
pos: 42,
Expand All @@ -105,18 +104,14 @@ describe('decreaseListIndent', () => {
expect(tr.setNodeMarkup).toHaveBeenCalledWith(42, null, {
foo: 'bar',
level: 1, // 2 -> 1
numId: 123, // keeps existing
numId: 777, // adopts parent's listId, not the stale 123
});

expect(ListHelpers.generateNewListDefinition).toHaveBeenCalledTimes(1);
expect(ListHelpers.generateNewListDefinition).toHaveBeenCalledWith({
numId: 123,
listType: OrderedListType,
editor,
});
// No re-generation for an existing id
expect(ListHelpers.generateNewListDefinition).not.toHaveBeenCalled();
});

it('uses parent list listId when current item has no numId', () => {
it('uses parent list listId when current item has no numId (no re-generation)', () => {
const currentItem = {
node: { type: { name: 'listItem' }, attrs: { level: 3 } },
pos: 7,
Expand All @@ -137,14 +132,11 @@ describe('decreaseListIndent', () => {
numId: 888, // inherited from parent
});

expect(ListHelpers.generateNewListDefinition).toHaveBeenCalledWith({
numId: 888,
listType: BulletListType,
editor,
});
// Do not re-generate for an existing id
expect(ListHelpers.generateNewListDefinition).not.toHaveBeenCalled();
});

it('falls back to ListHelpers.getNewListId when neither item nor parent have ids', () => {
it('falls back to ListHelpers.getNewListId when neither item nor parent have ids, and generates a definition', () => {
const currentItem = {
node: { type: { name: 'listItem' }, attrs: { level: 1 } },
pos: 11,
Expand All @@ -169,7 +161,7 @@ describe('decreaseListIndent', () => {
expect(ListHelpers.getNewListId).toHaveBeenCalledWith(editor);
expect(tr.setNodeMarkup).toHaveBeenCalledWith(11, null, {
level: 0, // 1 -> 0
numId: 9999, // fallback
numId: 9999, // minted
});

expect(ListHelpers.generateNewListDefinition).toHaveBeenCalledWith({
Expand Down Expand Up @@ -198,8 +190,34 @@ describe('decreaseListIndent', () => {
expect(result).toBe(true);
expect(tr.setNodeMarkup).toHaveBeenCalledWith(21, null, {
level: 1,
numId: null, // explicit null is fine; command should still set it
numId: null, // command writes what it resolved
});
expect(ListHelpers.generateNewListDefinition).not.toHaveBeenCalled();
});

it('bullet list: adopts parent listId and does NOT re-generate definition', () => {
const currentItem = {
node: { type: { name: 'listItem' }, attrs: { level: 2 /* no numId */ } },
pos: 13,
};
const parentList = {
node: { type: BulletListType, attrs: { listId: 888 } },
};

ListHelpers.getCurrentListItem.mockReturnValue(currentItem);
ListHelpers.getParentOrderedList.mockReturnValue(null);
ListHelpers.getParentBulletList.mockReturnValue(parentList);

const result = decreaseListIndent()({ editor, tr });

expect(result).toBe(true);
expect(tr.setNodeMarkup).toHaveBeenCalledTimes(1);
expect(tr.setNodeMarkup).toHaveBeenCalledWith(13, null, {
level: 1, // 2 -> 1
numId: 888, // bullets carry numId; adopt parent
});

// No re-generation for existing id
expect(ListHelpers.generateNewListDefinition).not.toHaveBeenCalled();
});
});
1 change: 0 additions & 1 deletion packages/super-editor/src/core/commands/toggleList.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ export const toggleList =
spanToBefore = Math.max(spanToBefore, pos + node.nodeSize);
}

const switchingToOrdered = targetKind === 'ordered';
let sharedNumId = ListHelpers.getNewListId(editor);
ListHelpers.generateNewListDefinition?.({ numId: sharedNumId, listType: TargetType, editor });

Expand Down
Loading