Skip to content

Commit

Permalink
Fix issue with apple numbers paste buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
jassmith committed Oct 2, 2023
1 parent fb8f084 commit ac85512
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
18 changes: 16 additions & 2 deletions packages/core/src/data-editor/copy-paste.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,18 @@ export function decodeHTML(html: string): CopyBuffer | undefined {
} else if (el instanceof HTMLTableCellElement) {
// be careful not to use innerText here as its behavior is not well defined for non DOM attached nodes
const clone: HTMLTableCellElement = el.cloneNode(true) as HTMLTableCellElement;

// Apple numbers seems to always wrap the cell in a p tag and a font tag. It also puts both <br> and \n
// linebreak markers in the code. This is both unneeded and causes issues with the paste code.
const firstTagIsPara = clone.children.length === 1 && clone.children[0].nodeName === "P";
const para = firstTagIsPara ? clone.children[0] : null;
const isAppleNumbers = para?.children.length === 1 && para.children[0].nodeName === "FONT";

const brs = clone.querySelectorAll("br");
for (const br of brs) {
br.replaceWith("\n");
}

const attributeValue = clone.getAttribute("gdg-raw-value");
const formatValue = (clone.getAttribute("gdg-format") ?? "string") as any; // fix me at some point
if (clone.querySelector("a") !== null) {
Expand All @@ -283,9 +291,15 @@ export function decodeHTML(html: string): CopyBuffer | undefined {
format: formatValue,
});
} else {
let textContent = clone.textContent ?? "";
if (isAppleNumbers) {
// replace and newline not preceded by a newline
textContent = textContent.replace(/(?<!\n)\n/g, "");
}

current?.push({
rawValue: clone.textContent ?? "",
formatted: clone.textContent ?? "",
rawValue: textContent ?? "",
formatted: textContent ?? "",
format: formatValue,
});
}
Expand Down
31 changes: 31 additions & 0 deletions packages/core/test/copy-paste.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,37 @@ test("decode ordered list", () => {
]);
});

test("decode apple numbers", () => {
const html = `
<table cellspacing="0" cellpadding="0" style="border-collapse: collapse">
<tbody>
<tr>
<td valign="top" style="width: 89.0px; height: 11.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px">
<p style="margin: 0.0px 0.0px 0.0px 0.0px"><font face="Helvetica Neue" size="2" color="#000000" style="font: 10.0px 'Helvetica Neue'; font-variant-ligatures: common-ligatures; color: #000000">Test</font></p>
</td>
<td valign="top" style="width: 89.0px; height: 11.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px">
<p style="margin: 0.0px 0.0px 0.0px 0.0px"><font face="Helvetica Neue" size="2" color="#000000" style="font: 10.0px 'Helvetica Neue'; font-variant-ligatures: common-ligatures; color: #000000">This</font></p>
</td>
</tr>
<tr>
<td valign="top" style="width: 89.0px; height: 23.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px">
<p style="margin: 0.0px 0.0px 0.0px 0.0px"><font face="Helvetica Neue" size="2" color="#000000" style="font: 10.0px 'Helvetica Neue'; font-variant-ligatures: common-ligatures; color: #000000">Out</font></p>
</td>
<td valign="top" style="width: 89.0px; height: 23.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px">
<p style="margin: 0.0px 0.0px 0.0px 0.0px"><font face="Helvetica Neue" size="2" color="#000000" style="font: 10.0px 'Helvetica Neue'; font-variant-ligatures: common-ligatures; color: #000000">With a<br>
newline and such</font></p>
</td>
</tr>
</tbody>
</table>
`;
const decoded = decodeHTML(html);
expect(decoded).toEqual([
[makeCellBuffer("Test"), makeCellBuffer("This")],
[makeCellBuffer("Out"), makeCellBuffer("With a\nnewline and such")],
]);
});

test("decode html attributes", () => {
const html = `
<table>
Expand Down

0 comments on commit ac85512

Please sign in to comment.