Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into refactor-npm-package-…
Browse files Browse the repository at this point in the history
…process-facebookgh-5869
  • Loading branch information
etrepum committed Apr 20, 2024
2 parents bda5e5e + 78bac6c commit ddb2e9c
Show file tree
Hide file tree
Showing 13 changed files with 356 additions and 193 deletions.
8 changes: 4 additions & 4 deletions examples/react-rich/src/plugins/ToolbarPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function ToolbarPlugin() {
const [isUnderline, setIsUnderline] = useState(false);
const [isStrikethrough, setIsStrikethrough] = useState(false);

const updateToolbar = useCallback(() => {
const $updateToolbar = useCallback(() => {
const selection = $getSelection();
if ($isRangeSelection(selection)) {
// Update text format
Expand All @@ -52,13 +52,13 @@ export default function ToolbarPlugin() {
return mergeRegister(
editor.registerUpdateListener(({editorState}) => {
editorState.read(() => {
updateToolbar();
$updateToolbar();
});
}),
editor.registerCommand(
SELECTION_CHANGE_COMMAND,
(_payload, newEditor) => {
updateToolbar();
$updateToolbar();
return false;
},
LowPriority,
Expand All @@ -80,7 +80,7 @@ export default function ToolbarPlugin() {
LowPriority,
),
);
}, [editor, updateToolbar]);
}, [editor, $updateToolbar]);

return (
<div className="toolbar" ref={toolbarRef}>
Expand Down
288 changes: 150 additions & 138 deletions package-lock.json

Large diffs are not rendered by default.

17 changes: 10 additions & 7 deletions packages/lexical-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"scripts": {
"dev": "wxt",
"dev:firefox": "wxt -b firefox",
"dev:edge": "wxt -b edge",
"build": "wxt build",
"build:firefox": "wxt build -b firefox",
"zip": "wxt zip",
Expand All @@ -15,21 +16,23 @@
"postinstall": "wxt prepare"
},
"dependencies": {
"@eduardoac-skimlinks/webext-redux": "3.0.1-release-candidate",
"@webext-pegasus/rpc": "^0.0.4",
"@webext-pegasus/store-zustand": "^0.0.4",
"@webext-pegasus/transport": "^0.0.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"webext-bridge": "~6.0.1",
"zustand": "^4.5.1"
},
"devDependencies": {
"@lexical/devtools-core": "0.14.5",
"@rollup/plugin-babel": "^6.0.4",
"@types/react": "^18.2.46",
"@types/react-dom": "^18.2.18",
"@vitejs/plugin-react": "^4.2.1",
"lexical": "0.14.5",
"typescript": "^5.3.3",
"lexical": "0.14.5",
"@lexical/devtools-core": "0.14.5",
"wxt": "^0.17.0",
"vite": "^5.2.2",
"wxt": "^0.17.0"
}
"@rollup/plugin-babel": "^6.0.4"
},
"sideEffects": false
}
2 changes: 1 addition & 1 deletion packages/lexical-devtools/src/entrypoints/devtools/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
// Create the panel which appears within the browser devtools
browser.devtools.panels.create(
'Lexical',
'icon/128.png',
'/icon/logo.svg',
'devtools-panel.html',
);
1 change: 1 addition & 0 deletions packages/lexical-devtools/src/public/icon/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/lexical-devtools/wxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export default defineConfig({
return manifestConf;
},
runner: {
binaries: {
edge: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
},
chromiumArgs: [
'--auto-open-devtools-for-tabs',
// Open chrome://version to validate it works
Expand Down
90 changes: 90 additions & 0 deletions packages/lexical-playground/__tests__/e2e/Extensions.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
*
*/

import {
moveToEditorBeginning,
moveToEditorEnd,
} from '../keyboardShortcuts/index.mjs';
import {
assertHTML,
assertSelection,
Expand Down Expand Up @@ -255,4 +259,90 @@ test.describe('Extensions', () => {
focusPath: [1, 0, 0],
});
});

test('document.execCommand("insertText") with all text backward selection', async ({
page,
}) => {
await focusEditor(page);

await page.keyboard.type('Paragraph 1');
await moveToEditorEnd(page);
await page.keyboard.down('Shift');
await moveToEditorBeginning(page);
await page.keyboard.up('Shift');

await assertSelection(page, {
anchorOffset: 11,
anchorPath: [0, 0, 0],
focusOffset: 0,
focusPath: [0, 0, 0],
});

await evaluate(
page,
() => {
document.execCommand('insertText', false, 'New text');
},
[],
);
await assertHTML(
page,
html`
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span data-lexical-text="true">New text</span>
</p>
`,
);
await assertSelection(page, {
anchorOffset: 8,
anchorPath: [0, 0, 0],
focusOffset: 8,
focusPath: [0, 0, 0],
});
});

test('document.execCommand("insertText") with all text forward selection', async ({
page,
}) => {
await focusEditor(page);

await page.keyboard.type('Paragraph 1');
await moveToEditorBeginning(page);
await page.keyboard.down('Shift');
await moveToEditorEnd(page);
await page.keyboard.up('Shift');

await assertSelection(page, {
anchorOffset: 0,
anchorPath: [0, 0, 0],
focusOffset: 11,
focusPath: [0, 0, 0],
});

await evaluate(
page,
() => {
document.execCommand('insertText', false, 'New text');
},
[],
);
await assertHTML(
page,
html`
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span data-lexical-text="true">New text</span>
</p>
`,
);
await assertSelection(page, {
anchorOffset: 8,
anchorPath: [0, 0, 0],
focusOffset: 8,
focusPath: [0, 0, 0],
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
*/

import type {RangeSelection} from 'lexical';
import type {ElementNode, RangeSelection} from 'lexical';

import {$getListDepth, $isListItemNode, $isListNode} from '@lexical/list';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
Expand All @@ -15,15 +15,10 @@ import {
$isElementNode,
$isRangeSelection,
COMMAND_PRIORITY_CRITICAL,
ElementNode,
INDENT_CONTENT_COMMAND,
} from 'lexical';
import {useEffect} from 'react';

type Props = Readonly<{
maxDepth: number | null | undefined;
}>;

function getElementNodesInSelection(
selection: RangeSelection,
): Set<ElementNode> {
Expand All @@ -41,7 +36,7 @@ function getElementNodesInSelection(
);
}

function isIndentPermitted(maxDepth: number): boolean {
function shouldPreventIndent(maxDepth: number): boolean {
const selection = $getSelection();

if (!$isRangeSelection(selection)) {
Expand Down Expand Up @@ -69,16 +64,20 @@ function isIndentPermitted(maxDepth: number): boolean {
}
}

return totalDepth <= maxDepth;
return totalDepth > maxDepth;
}

export default function ListMaxIndentLevelPlugin({maxDepth}: Props): null {
export default function ListMaxIndentLevelPlugin({
maxDepth = 7,
}: {
maxDepth?: number;
}): null {
const [editor] = useLexicalComposerContext();

useEffect(() => {
return editor.registerCommand(
INDENT_CONTENT_COMMAND,
() => !isIndentPermitted(maxDepth ?? 7),
() => shouldPreventIndent(maxDepth),
COMMAND_PRIORITY_CRITICAL,
);
}, [editor, maxDepth]);
Expand Down
66 changes: 49 additions & 17 deletions packages/lexical-react/src/LexicalTablePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {NodeKey} from 'lexical';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import {
$computeTableMap,
$computeTableMapSkipCellCheck,
$createTableCellNode,
$createTableNodeWithDimensions,
$getNodeTriplet,
Expand All @@ -28,8 +29,13 @@ import {
TableNode,
TableRowNode,
} from '@lexical/table';
import {$insertFirst, $insertNodeToNearestRoot} from '@lexical/utils';
import {
$insertFirst,
$insertNodeToNearestRoot,
mergeRegister,
} from '@lexical/utils';
import {
$createParagraphNode,
$getNodeByKey,
$isTextNode,
$nodesOfType,
Expand Down Expand Up @@ -57,24 +63,50 @@ export function TablePlugin({
);
}

return editor.registerCommand<InsertTableCommandPayload>(
INSERT_TABLE_COMMAND,
({columns, rows, includeHeaders}) => {
const tableNode = $createTableNodeWithDimensions(
Number(rows),
Number(columns),
includeHeaders,
);
$insertNodeToNearestRoot(tableNode);
return mergeRegister(
editor.registerCommand<InsertTableCommandPayload>(
INSERT_TABLE_COMMAND,
({columns, rows, includeHeaders}) => {
const tableNode = $createTableNodeWithDimensions(
Number(rows),
Number(columns),
includeHeaders,
);
$insertNodeToNearestRoot(tableNode);

const firstDescendant = tableNode.getFirstDescendant();
if ($isTextNode(firstDescendant)) {
firstDescendant.select();
}

const firstDescendant = tableNode.getFirstDescendant();
if ($isTextNode(firstDescendant)) {
firstDescendant.select();
return true;
},
COMMAND_PRIORITY_EDITOR,
),
editor.registerNodeTransform(TableNode, (node) => {
const [gridMap] = $computeTableMapSkipCellCheck(node, null, null);
const maxRowLength = gridMap.reduce((curLength, row) => {
return Math.max(curLength, row.length);
}, 0);
for (let i = 0; i < gridMap.length; ++i) {
const rowLength = gridMap[i].length;
if (rowLength === maxRowLength) {
continue;
}
const lastCellMap = gridMap[i][rowLength - 1];
const lastRowCell = lastCellMap.cell;
for (let j = rowLength; j < maxRowLength; ++j) {
// TODO: inherit header state from another header or body
const newCell = $createTableCellNode(0);
newCell.append($createParagraphNode());
if (lastRowCell !== null) {
lastRowCell.insertAfter(newCell);
} else {
$insertFirst(lastRowCell, newCell);
}
}
}

return true;
},
COMMAND_PRIORITY_EDITOR,
}),
);
}, [editor]);

Expand Down
21 changes: 12 additions & 9 deletions packages/lexical-table/src/LexicalTableSelectionHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,18 @@ export function applyTableHandlers(
};

const onMouseMove = (moveEvent: MouseEvent) => {
const focusCell = getDOMCellFromTarget(moveEvent.target as Node);
if (
focusCell !== null &&
(tableObserver.anchorX !== focusCell.x ||
tableObserver.anchorY !== focusCell.y)
) {
moveEvent.preventDefault();
tableObserver.setFocusCellForSelection(focusCell);
}
// delaying mousemove handler to allow selectionchange handler from LexicalEvents.ts to be executed first
setTimeout(() => {
const focusCell = getDOMCellFromTarget(moveEvent.target as Node);
if (
focusCell !== null &&
(tableObserver.anchorX !== focusCell.x ||
tableObserver.anchorY !== focusCell.y)
) {
moveEvent.preventDefault();
tableObserver.setFocusCellForSelection(focusCell);
}
}, 0);
};
return {onMouseMove: onMouseMove, onMouseUp: onMouseUp};
};
Expand Down
Loading

0 comments on commit ddb2e9c

Please sign in to comment.