Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paste Elements always as Elements even if we are writting in a textarea #4

Closed
wants to merge 4 commits into from
Closed
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
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
<p align="center">
<p align="center">
<a href="https://alkemio.foundation/" target="blank"><img src="https://alkemio.foundation/uploads/logos/alkemio-logo.svg" width="400" alt="Alkemio Logo" /></a>
</p>
<p align="center"><i>Enabling society to collaborate. Building a better future, together.</i></p>

# Alkemio fork of Excalidraw v0.17.0
- Upgraded from Excalidraw v0.16.1 to v0.17.0
- Procedure is very similar to previous versions below:

- Upgraded from Excalidraw v0.16.1 to v0.17.0
- Build Procedure is very similar to previous versions below:
```
git fetch --tags upstream
git checkout 0.16.1-alkemio-1
git merge v0.17.0
git push --set-upstream origin 0.17.0-alkemio-1
```
- Applied the new styles of the buttons to Alkemio's ZoomToFit added button
- Applied the new styles of the buttons to Alkemio's ZoomToFit added button.
- **v0.17.0-alkemio-3-beta**: Modified the paste functionality to avoid pasting elements (such as images) as JSON when editing text.

### For testing you can link the new package from the local client

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
},
"homepage": "https://github.com/alkem-io/excalidraw",
"name": "@alkemio/excalidraw",
"version": "0.17.0-alkemio-2",
"version": "0.17.0-alkemio-3-beta",
"prettier": "@excalidraw/prettier-config",
"private": false,
"scripts": {
Expand Down
36 changes: 18 additions & 18 deletions src/clipboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,39 @@ import {
import { API } from "./tests/helpers/api";

describe("parseClipboard()", () => {
it("should parse JSON as plaintext if not excalidraw-api/clipboard data", async () => {
it("should parse JSON as plaintext if not excalidraw-api/clipboard data", () => {
let text;
let clipboardData;
// -------------------------------------------------------------------------

text = "123";
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({ types: { "text/plain": text } }),
);
expect(clipboardData.text).toBe(text);

// -------------------------------------------------------------------------

text = "[123]";
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({ types: { "text/plain": text } }),
);
expect(clipboardData.text).toBe(text);

// -------------------------------------------------------------------------

text = JSON.stringify({ val: 42 });
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({ types: { "text/plain": text } }),
);
expect(clipboardData.text).toBe(text);
});

it("should parse valid excalidraw JSON if inside text/plain", async () => {
it("should parse valid excalidraw JSON if inside text/plain", () => {
const rect = API.createElement({ type: "rectangle" });

const json = serializeAsClipboardJSON({ elements: [rect], files: null });
const clipboardData = await parseClipboard(
const clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/plain": json,
Expand All @@ -48,14 +48,14 @@ describe("parseClipboard()", () => {
expect(clipboardData.elements).toEqual([rect]);
});

it("should parse valid excalidraw JSON if inside text/html", async () => {
it("should parse valid excalidraw JSON if inside text/html", () => {
const rect = API.createElement({ type: "rectangle" });

let json;
let clipboardData;
// -------------------------------------------------------------------------
json = serializeAsClipboardJSON({ elements: [rect], files: null });
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/html": json,
Expand All @@ -65,7 +65,7 @@ describe("parseClipboard()", () => {
expect(clipboardData.elements).toEqual([rect]);
// -------------------------------------------------------------------------
json = serializeAsClipboardJSON({ elements: [rect], files: null });
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/html": `<div> ${json}</div>`,
Expand All @@ -76,10 +76,10 @@ describe("parseClipboard()", () => {
// -------------------------------------------------------------------------
});

it("should parse <image> `src` urls out of text/html", async () => {
it("should parse <image> `src` urls out of text/html", () => {
let clipboardData;
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/html": `<img src="https://example.com/image.png" />`,
Expand All @@ -93,7 +93,7 @@ describe("parseClipboard()", () => {
},
]);
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/html": `<div><img src="https://example.com/image.png" /></div><a><img src="https://example.com/image2.png" /></a>`,
Expand All @@ -112,8 +112,8 @@ describe("parseClipboard()", () => {
]);
});

it("should parse text content alongside <image> `src` urls out of text/html", async () => {
const clipboardData = await parseClipboard(
it("should parse text content alongside <image> `src` urls out of text/html", () => {
const clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/html": `<a href="https://example.com">hello </a><div><img src="https://example.com/image.png" /></div><b>my friend!</b>`,
Expand All @@ -137,10 +137,10 @@ describe("parseClipboard()", () => {
]);
});

it("should parse spreadsheet from either text/plain and text/html", async () => {
it("should parse spreadsheet from either text/plain and text/html", () => {
let clipboardData;
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/plain": `a b
Expand All @@ -156,7 +156,7 @@ describe("parseClipboard()", () => {
values: [2, 5, 10],
});
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/html": `a b
Expand All @@ -172,7 +172,7 @@ describe("parseClipboard()", () => {
values: [2, 5, 10],
});
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
clipboardData = parseClipboard(
createPasteEvent({
types: {
"text/html": `<html>
Expand Down
10 changes: 5 additions & 5 deletions src/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,10 @@ export const readSystemClipboard = async () => {
/**
* Parses "paste" ClipboardEvent.
*/
const parseClipboardEvent = async (
const parseClipboardEvent = (
event: ClipboardEvent,
isPlainPaste = false,
): Promise<ParsedClipboardEvent> => {
): ParsedClipboardEvent => {
try {
const mixedContent = !isPlainPaste && event && maybeParseHTMLPaste(event);

Expand Down Expand Up @@ -326,11 +326,11 @@ const parseClipboardEvent = async (
/**
* Attempts to parse clipboard. Prefers system clipboard.
*/
export const parseClipboard = async (
export const parseClipboard = (
event: ClipboardEvent,
isPlainPaste = false,
): Promise<ClipboardData> => {
const parsedEventData = await parseClipboardEvent(event, isPlainPaste);
): ClipboardData => {
const parsedEventData = parseClipboardEvent(event, isPlainPaste);

if (parsedEventData.type === "mixedContent") {
return {
Expand Down
13 changes: 6 additions & 7 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2237,14 +2237,19 @@ class App extends React.Component<AppProps, AppState> {
return;
}

// These two lines are moved up by Alkemio to avoid pasting images json as text inside text elements
let file = event?.clipboardData?.files[0];
const data = parseClipboard(event, isPlainPaste);

const elementUnderCursor = document.elementFromPoint(
this.lastViewportPosition.x,
this.lastViewportPosition.y,
);
if (
event &&
(!(elementUnderCursor instanceof HTMLCanvasElement) ||
isWritableElement(target))
isWritableElement(target)) &&
!data.elements // If there are any elements, they will not be inserted as text
) {
return;
}
Expand All @@ -2257,12 +2262,6 @@ class App extends React.Component<AppProps, AppState> {
this.state,
);

// must be called in the same frame (thus before any awaits) as the paste
// event else some browsers (FF...) will clear the clipboardData
// (something something security)
let file = event?.clipboardData?.files[0];

const data = await parseClipboard(event, isPlainPaste);
if (!file && !isPlainPaste) {
if (data.mixedContent) {
return this.addElementsFromMixedContentPaste(data.mixedContent, {
Expand Down
4 changes: 2 additions & 2 deletions src/element/textWysiwyg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ export const textWysiwyg = ({
updateWysiwygStyle();

if (onChange) {
editable.onpaste = async (event) => {
const clipboardData = await parseClipboard(event, true);
editable.onpaste = (event) => {
const clipboardData = parseClipboard(event, true);
if (!clipboardData.text) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/packages/excalidraw/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@alkemio/excalidraw",
"version": "0.17.0-alkemio-2",
"version": "0.17.0-alkemio-3-beta",
"main": "main.js",
"types": "types/packages/excalidraw/index.d.ts",
"files": [
Expand Down
Loading