feat: Allow embeds to be used inside tables (#5315)

This commit is contained in:
Tom Moor
2023-05-07 21:05:54 -04:00
committed by GitHub
parent 738fa55e12
commit a0df79ea5a
8 changed files with 23 additions and 17 deletions

View File

@@ -1222,6 +1222,10 @@ table {
min-width: 100px; min-width: 100px;
} }
td .component-embed {
padding: 4px 0;
}
.selectedCell { .selectedCell {
background: ${ background: ${
props.readOnly ? "inherit" : props.theme.tableSelectedBackground props.readOnly ? "inherit" : props.theme.tableSelectedBackground

View File

@@ -10,7 +10,7 @@ function Trello(props: Props) {
return ( return (
<Frame <Frame
width="316px" width="316px"
height="158px" height="141px"
src={`https://trello.com/embed/card?id=${objectId}`} src={`https://trello.com/embed/card?id=${objectId}`}
title={`Trello Card (${objectId})`} title={`Trello Card (${objectId})`}
/> />

View File

@@ -1,7 +1,6 @@
import { toggleMark } from "prosemirror-commands"; import { toggleMark } from "prosemirror-commands";
import { Slice } from "prosemirror-model"; import { Slice } from "prosemirror-model";
import { Plugin } from "prosemirror-state"; import { Plugin } from "prosemirror-state";
import { isInTable } from "prosemirror-tables";
import { isUrl } from "../../utils/urls"; import { isUrl } from "../../utils/urls";
import Extension from "../lib/Extension"; import Extension from "../lib/Extension";
import isMarkdown from "../lib/isMarkdown"; import isMarkdown from "../lib/isMarkdown";
@@ -89,7 +88,6 @@ export default class PasteHandler extends Extension {
if ( if (
embeds && embeds &&
this.editor.commands.embed && this.editor.commands.embed &&
!isInTable(state) &&
!isInCode(state) && !isInCode(state) &&
!isInList(state) !isInList(state)
) { ) {

View File

@@ -366,16 +366,20 @@ export class MarkdownSerializerState {
row.forEach((cell, _, j) => { row.forEach((cell, _, j) => {
this.out += j === 0 ? "| " : " | "; this.out += j === 0 ? "| " : " | ";
cell.forEach((para) => { cell.forEach((node) => {
// just padding the output so that empty cells take up the same space // just padding the output so that empty cells take up the same space
// as headings. // as headings.
// TODO: Ideally we'd calc the longest cell length and use that // TODO: Ideally we'd calc the longest cell length and use that
// to pad all the others. // to pad all the others.
if (para.textContent === "" && para.content.size === 0) { if (
node.textContent === "" &&
node.content.size === 0 &&
node.type.name === "paragraph"
) {
this.out += " "; this.out += " ";
} else { } else {
this.closed = false; this.closed = false;
this.render(para, row, j); this.render(node, row, j);
} }
}); });

View File

@@ -126,7 +126,9 @@ export default class Embed extends Node {
} }
toMarkdown(state: MarkdownSerializerState, node: ProsemirrorNode) { toMarkdown(state: MarkdownSerializerState, node: ProsemirrorNode) {
state.ensureNewLine(); if (!state.inTable) {
state.ensureNewLine();
}
state.write( state.write(
"[" + "[" +
state.esc(node.attrs.href, false) + state.esc(node.attrs.href, false) +
@@ -134,7 +136,9 @@ export default class Embed extends Node {
state.esc(node.attrs.href, false) + state.esc(node.attrs.href, false) +
")" ")"
); );
state.write("\n\n"); if (!state.inTable) {
state.write("\n\n");
}
} }
parseMarkdown() { parseMarkdown() {

View File

@@ -18,7 +18,7 @@ export default class TableCell extends Node {
get schema(): NodeSpec { get schema(): NodeSpec {
return { return {
content: "paragraph+", content: "(paragraph | embed)+",
tableRole: "cell", tableRole: "cell",
isolating: true, isolating: true,
parseDOM: [{ tag: "td" }], parseDOM: [{ tag: "td" }],

View File

@@ -16,7 +16,7 @@ export default class TableHeadCell extends Node {
get schema(): NodeSpec { get schema(): NodeSpec {
return { return {
content: "paragraph+", content: "(paragraph | embed)+",
tableRole: "header_cell", tableRole: "header_cell",
isolating: true, isolating: true,
parseDOM: [{ tag: "th" }], parseDOM: [{ tag: "th" }],

View File

@@ -3,11 +3,7 @@ import Token from "markdown-it/lib/token";
import { EmbedDescriptor } from "../embeds"; import { EmbedDescriptor } from "../embeds";
function isParagraph(token: Token) { function isParagraph(token: Token) {
return token.type === "paragraph_open"; return token?.type === "paragraph_open";
}
function isInline(token: Token) {
return token.type === "inline" && token.level === 1;
} }
function isLinkOpen(token: Token) { function isLinkOpen(token: Token) {
@@ -49,8 +45,8 @@ export default function linksToEmbeds(embeds: EmbedDescriptor[]) {
let insideLink; let insideLink;
for (let i = 0; i < tokens.length - 1; i++) { for (let i = 0; i < tokens.length - 1; i++) {
// once we find an inline token look through it's children for links // once we find a paragraph, look through it's children for links
if (isInline(tokens[i]) && isParagraph(tokens[i - 1])) { if (isParagraph(tokens[i - 1])) {
const tokenChildren = tokens[i].children || []; const tokenChildren = tokens[i].children || [];
for (let j = 0; j < tokenChildren.length - 1; j++) { for (let j = 0; j < tokenChildren.length - 1; j++) {