Skip to content

Commit

Permalink
Merge branch 'main' into forEachSelectedTextNode
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanJablo authored Dec 19, 2024
2 parents f6407b7 + 62b3713 commit cd2a199
Show file tree
Hide file tree
Showing 113 changed files with 4,329 additions and 1,345 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ on:
- 'packages/lexical-website/**'
pull_request:
types: [opened, synchronize, reopened]
paths-ignore:
- 'examples/**'
- 'packages/lexical-website/**'
merge_group:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
3 changes: 2 additions & 1 deletion examples/react-rich/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
DOMConversionMap,
DOMExportOutput,
DOMExportOutputMap,
isHTMLElement,
Klass,
LexicalEditor,
LexicalNode,
Expand All @@ -36,7 +37,7 @@ const removeStylesExportDOM = (
target: LexicalNode,
): DOMExportOutput => {
const output = target.exportDOM(editor);
if (output && output.element instanceof HTMLElement) {
if (output && isHTMLElement(output.element)) {
// Remove all inline styles and classes if the element is an HTMLElement
// Children are checked as well since TextNode can be nested
// in i, b, and strong tags.
Expand Down
30 changes: 27 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 0 additions & 7 deletions packages/lexical-code/flow/LexicalCode.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,6 @@ declare export class CodeHighlightNode extends TextNode {
// $FlowFixMe
static clone(node: CodeHighlightNode): CodeHighlightNode;
createDOM(config: EditorConfig): HTMLElement;
updateDOM(
// $FlowFixMe
prevNode: CodeHighlightNode,
dom: HTMLElement,
config: EditorConfig,
): boolean;
setFormat(format: number): this;
}

Expand Down Expand Up @@ -125,7 +119,6 @@ declare export class CodeNode extends ElementNode {
static clone(node: CodeNode): CodeNode;
constructor(language: ?string, key?: NodeKey): void;
createDOM(config: EditorConfig): HTMLElement;
updateDOM(prevNode: CodeNode, dom: HTMLElement): boolean;
insertNewAfter(
selection: RangeSelection,
restoreSelection?: boolean,
Expand Down
6 changes: 1 addition & 5 deletions packages/lexical-code/src/CodeHighlightNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,7 @@ export class CodeHighlightNode extends TextNode {
return element;
}

updateDOM(
prevNode: CodeHighlightNode,
dom: HTMLElement,
config: EditorConfig,
): boolean {
updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean {
const update = super.updateDOM(prevNode, dom, config);
const prevClassName = getHighlightThemeClass(
config.theme,
Expand Down
6 changes: 1 addition & 5 deletions packages/lexical-code/src/CodeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,7 @@ export class CodeNode extends ElementNode {
}
return element;
}
updateDOM(
prevNode: CodeNode,
dom: HTMLElement,
config: EditorConfig,
): boolean {
updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean {
const language = this.__language;
const prevLanguage = prevNode.__language;

Expand Down
5 changes: 0 additions & 5 deletions packages/lexical-link/flow/LexicalLink.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ declare export class LinkNode extends ElementNode {
static clone(node: LinkNode): LinkNode;
constructor(url: string, attributes?: LinkAttributes, key?: NodeKey): void;
createDOM(config: EditorConfig): HTMLElement;
updateDOM(
prevNode: LinkNode,
dom: HTMLElement,
config: EditorConfig,
): boolean;
static importDOM(): DOMConversionMap | null;
exportJSON(): SerializedLinkNode;
getURL(): string;
Expand Down
6 changes: 3 additions & 3 deletions packages/lexical-link/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ export class LinkNode extends ElementNode {
}

updateDOM(
prevNode: LinkNode,
prevNode: this,
anchor: LinkHTMLElementType,
config: EditorConfig,
): boolean {
if (anchor instanceof HTMLAnchorElement) {
if (isHTMLAnchorElement(anchor)) {
const url = this.__url;
const target = this.__target;
const rel = this.__rel;
Expand Down Expand Up @@ -393,7 +393,7 @@ export class AutoLinkNode extends LinkNode {
}

updateDOM(
prevNode: AutoLinkNode,
prevNode: this,
anchor: LinkHTMLElementType,
config: EditorConfig,
): boolean {
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical-list/src/LexicalListItemNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export class ListItemNode extends ElementNode {
}

canMergeWith(node: LexicalNode): boolean {
return $isParagraphNode(node) || $isListItemNode(node);
return $isListItemNode(node) || $isParagraphNode(node);
}

extractWithChild(child: LexicalNode, selection: BaseSelection): boolean {
Expand Down
8 changes: 2 additions & 6 deletions packages/lexical-list/src/LexicalListNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,7 @@ export class ListNode extends ElementNode {
return dom;
}

updateDOM(
prevNode: ListNode,
dom: HTMLElement,
config: EditorConfig,
): boolean {
updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean {
if (prevNode.__tag !== this.__tag) {
return true;
}
Expand Down Expand Up @@ -156,7 +152,7 @@ export class ListNode extends ElementNode {

exportDOM(editor: LexicalEditor): DOMExportOutput {
const element = this.createDOM(editor._config, editor);
if (element && isHTMLElement(element)) {
if (isHTMLElement(element)) {
if (this.__start !== 1) {
element.setAttribute('start', String(this.__start));
}
Expand Down
17 changes: 7 additions & 10 deletions packages/lexical-list/src/formatList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
$getSelection,
$isElementNode,
$isLeafNode,
$isParagraphNode,
$isRangeSelection,
$isRootOrShadowRoot,
ElementNode,
Expand Down Expand Up @@ -494,10 +493,12 @@ export function $handleListInsertParagraph(): boolean {

const grandparent = parent.getParent();

let replacementNode;
let replacementNode: ParagraphNode | ListItemNode;

if ($isRootOrShadowRoot(grandparent)) {
replacementNode = $createParagraphNode();
replacementNode.setTextStyle(selection.style);
replacementNode.setTextFormat(selection.format);
topListNode.insertAfter(replacementNode);
} else if ($isListItemNode(grandparent)) {
replacementNode = $createListItemNode();
Expand All @@ -511,18 +512,14 @@ export function $handleListInsertParagraph(): boolean {

if (nextSiblings.length > 0) {
const newList = $createListNode(parent.getListType());

if ($isParagraphNode(replacementNode)) {
replacementNode.insertAfter(newList);
} else {
if ($isListItemNode(replacementNode)) {
const newListItem = $createListItemNode();
newListItem.append(newList);
replacementNode.insertAfter(newListItem);
} else {
replacementNode.insertAfter(newList);
}
nextSiblings.forEach((sibling) => {
sibling.remove();
newList.append(sibling);
});
newList.append(...nextSiblings);
}

// Don't leave hanging nested empty lists
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical-mark/src/MarkNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class MarkNode extends ElementNode {
}

updateDOM(
prevNode: MarkNode,
prevNode: this,
element: HTMLElement,
config: EditorConfig,
): boolean {
Expand Down
56 changes: 46 additions & 10 deletions packages/lexical-markdown/src/MarkdownExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ function exportChildren(
): string {
const output = [];
const children = node.getChildren();
// keep track of unclosed tags from the very beginning
const unclosedTags: {format: TextFormatType; tag: string}[] = [];

mainLoop: for (const child of children) {
for (const transformer of textMatchTransformers) {
Expand All @@ -124,7 +126,12 @@ function exportChildren(
textMatchTransformers,
),
(textNode, textContent) =>
exportTextFormat(textNode, textContent, textTransformersIndex),
exportTextFormat(
textNode,
textContent,
textTransformersIndex,
unclosedTags,
),
);

if (result != null) {
Expand All @@ -137,7 +144,12 @@ function exportChildren(
output.push('\n');
} else if ($isTextNode(child)) {
output.push(
exportTextFormat(child, child.getTextContent(), textTransformersIndex),
exportTextFormat(
child,
child.getTextContent(),
textTransformersIndex,
unclosedTags,
),
);
} else if ($isElementNode(child)) {
// empty paragraph returns ""
Expand All @@ -156,39 +168,63 @@ function exportTextFormat(
node: TextNode,
textContent: string,
textTransformers: Array<TextFormatTransformer>,
// unclosed tags include the markdown tags that haven't been closed yet, and their associated formats
unclosedTags: Array<{format: TextFormatType; tag: string}>,
): string {
// This function handles the case of a string looking like this: " foo "
// Where it would be invalid markdown to generate: "** foo **"
// We instead want to trim the whitespace out, apply formatting, and then
// bring the whitespace back. So our returned string looks like this: " **foo** "
const frozenString = textContent.trim();
let output = frozenString;
// the opening tags to be added to the result
let openingTags = '';
// the closing tags to be added to the result
let closingTags = '';

const prevNode = getTextSibling(node, true);
const nextNode = getTextSibling(node, false);

const applied = new Set();

for (const transformer of textTransformers) {
const format = transformer.format[0];
const tag = transformer.tag;

// dedup applied formats
if (hasFormat(node, format) && !applied.has(format)) {
// Multiple tags might be used for the same format (*, _)
applied.add(format);
// Prevent adding opening tag is already opened by the previous sibling
const previousNode = getTextSibling(node, true);

if (!hasFormat(previousNode, format)) {
output = tag + output;
// append the tag to openningTags, if it's not applied to the previous nodes,
// or the nodes before that (which would result in an unclosed tag)
if (
!hasFormat(prevNode, format) ||
!unclosedTags.find((element) => element.tag === tag)
) {
unclosedTags.push({format, tag});
openingTags += tag;
}
}
}

// Prevent adding closing tag if next sibling will do it
const nextNode = getTextSibling(node, false);
// close any tags in the same order they were applied, if necessary
for (let i = 0; i < unclosedTags.length; i++) {
// prevent adding closing tag if next sibling will do it
if (hasFormat(nextNode, unclosedTags[i].format)) {
continue;
}

if (!hasFormat(nextNode, format)) {
output += tag;
while (unclosedTags.length > i) {
const unclosedTag = unclosedTags.pop();
if (unclosedTag && typeof unclosedTag.tag === 'string') {
closingTags += unclosedTag.tag;
}
}
break;
}

output = openingTags + output + closingTags;
// Replace trimmed version of textContent ensuring surrounding whitespace is not modified
return textContent.replace(frozenString, () => output);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,15 @@ describe('Markdown', () => {
},
{
html: '<p><span style="white-space: pre-wrap;">Hello </span><s><i><b><strong style="white-space: pre-wrap;">world</strong></b></i></s><span style="white-space: pre-wrap;">!</span></p>',
md: 'Hello ~~***world***~~!',
md: 'Hello ***~~world~~***!',
},
{
html: '<p><b><strong style="white-space: pre-wrap;">Hello </strong></b><s><b><strong style="white-space: pre-wrap;">world</strong></b></s><span style="white-space: pre-wrap;">!</span></p>',
md: '**Hello ~~world~~**!',
},
{
html: '<p><s><b><strong style="white-space: pre-wrap;">Hello </strong></b></s><s><i><b><strong style="white-space: pre-wrap;">world</strong></b></i></s><s><span style="white-space: pre-wrap;">!</span></s></p>',
md: '**~~Hello *world*~~**~~!~~',
},
{
html: '<p><i><em style="white-space: pre-wrap;">Hello </em></i><i><b><strong style="white-space: pre-wrap;">world</strong></b></i><i><em style="white-space: pre-wrap;">!</em></i></p>',
Expand Down
Loading

0 comments on commit cd2a199

Please sign in to comment.