Merge remote-tracking branch 'origin/master' into barnabasmolnar/mainmenu-radix

This commit is contained in:
Aakansha Doshi 2023-07-27 12:17:28 +05:30
commit 66e347f7d2
7 changed files with 97 additions and 6 deletions

View File

@ -3,6 +3,7 @@ import {
ExcalidrawSelectionElement, ExcalidrawSelectionElement,
ExcalidrawTextElement, ExcalidrawTextElement,
FontFamilyValues, FontFamilyValues,
PointBinding,
StrokeRoundness, StrokeRoundness,
} from "../element/types"; } from "../element/types";
import { import {
@ -83,6 +84,13 @@ const getFontFamilyByName = (fontFamilyName: string): FontFamilyValues => {
return DEFAULT_FONT_FAMILY; return DEFAULT_FONT_FAMILY;
}; };
const repairBinding = (binding: PointBinding | null) => {
if (!binding) {
return null;
}
return { ...binding, focus: binding.focus || 0 };
};
const restoreElementWithProperties = < const restoreElementWithProperties = <
T extends Required<Omit<ExcalidrawElement, "customData">> & { T extends Required<Omit<ExcalidrawElement, "customData">> & {
customData?: ExcalidrawElement["customData"]; customData?: ExcalidrawElement["customData"];
@ -258,8 +266,8 @@ const restoreElement = (
(element.type as ExcalidrawElement["type"] | "draw") === "draw" (element.type as ExcalidrawElement["type"] | "draw") === "draw"
? "line" ? "line"
: element.type, : element.type,
startBinding: element.startBinding, startBinding: repairBinding(element.startBinding),
endBinding: element.endBinding, endBinding: repairBinding(element.endBinding),
lastCommittedPoint: null, lastCommittedPoint: null,
startArrowhead, startArrowhead,
endArrowhead, endArrowhead,

View File

@ -655,18 +655,23 @@ export const determineFocusDistance = (
const c = line[1]; const c = line[1];
const mabs = Math.abs(m); const mabs = Math.abs(m);
const nabs = Math.abs(n); const nabs = Math.abs(n);
let ret;
switch (element.type) { switch (element.type) {
case "rectangle": case "rectangle":
case "image": case "image":
case "text": case "text":
case "embeddable": case "embeddable":
case "frame": case "frame":
return c / (hwidth * (nabs + q * mabs)); ret = c / (hwidth * (nabs + q * mabs));
break;
case "diamond": case "diamond":
return mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight); ret = mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight);
break;
case "ellipse": case "ellipse":
return c / (hwidth * Math.sqrt(n ** 2 + q ** 2 * m ** 2)); ret = c / (hwidth * Math.sqrt(n ** 2 + q ** 2 * m ** 2));
break;
} }
return ret || 0;
}; };
export const determineFocusPoint = ( export const determineFocusPoint = (

View File

@ -52,6 +52,7 @@ const ALLOWED_DOMAINS = new Set([
"link.excalidraw.com", "link.excalidraw.com",
"gist.github.com", "gist.github.com",
"twitter.com", "twitter.com",
"stackblitz.com",
]); ]);
const createSrcDoc = (body: string) => { const createSrcDoc = (body: string) => {

View File

@ -333,7 +333,7 @@ class Collab extends PureComponent<Props, CollabState> {
* Indicates whether to fetch files that are errored or pending and older * Indicates whether to fetch files that are errored or pending and older
* than 10 seconds. * than 10 seconds.
* *
* Use this as a machanism to fetch files which may be ok but for some * Use this as a mechanism to fetch files which may be ok but for some
* reason their status was not updated correctly. * reason their status was not updated correctly.
*/ */
forceFetchFiles?: boolean; forceFetchFiles?: boolean;

6
src/global.d.ts vendored
View File

@ -120,3 +120,9 @@ declare module "image-blob-reduce" {
const reduce: ImageBlobReduce.ImageBlobReduceStatic; const reduce: ImageBlobReduce.ImageBlobReduceStatic;
export = reduce; export = reduce;
} }
declare namespace jest {
interface Expect {
toBeNonNaNNumber(): void;
}
}

View File

@ -15,6 +15,61 @@ describe("element binding", () => {
await render(<ExcalidrawApp />); await render(<ExcalidrawApp />);
}); });
it("should create valid binding if duplicate start/end points", async () => {
const rect = API.createElement({
type: "rectangle",
x: 0,
width: 50,
height: 50,
});
const arrow = API.createElement({
type: "arrow",
x: 100,
y: 0,
width: 100,
height: 1,
points: [
[0, 0],
[0, 0],
[100, 0],
[100, 0],
],
});
h.elements = [rect, arrow];
expect(arrow.startBinding).toBe(null);
API.setSelectedElements([arrow]);
expect(API.getSelectedElements()).toEqual([arrow]);
mouse.downAt(100, 0);
mouse.moveTo(55, 0);
mouse.up(0, 0);
expect(arrow.startBinding).toEqual({
elementId: rect.id,
focus: expect.toBeNonNaNNumber(),
gap: expect.toBeNonNaNNumber(),
});
mouse.downAt(100, 0);
mouse.move(-45, 0);
mouse.up();
expect(arrow.startBinding).toEqual({
elementId: rect.id,
focus: expect.toBeNonNaNNumber(),
gap: expect.toBeNonNaNNumber(),
});
mouse.down();
mouse.move(-50, 0);
mouse.up();
expect(arrow.startBinding).toBe(null);
expect(arrow.endBinding).toEqual({
elementId: rect.id,
focus: expect.toBeNonNaNNumber(),
gap: expect.toBeNonNaNNumber(),
});
});
//@TODO fix the test with rotation //@TODO fix the test with rotation
it.skip("rotation of arrow should rebind both ends", () => { it.skip("rotation of arrow should rebind both ends", () => {
const rectLeft = UI.createElement("rectangle", { const rectLeft = UI.createElement("rectangle", {

View File

@ -228,3 +228,19 @@ export const togglePopover = (label: string) => {
UI.clickLabeledElement(label); UI.clickLabeledElement(label);
}; };
expect.extend({
toBeNonNaNNumber(received) {
const pass = typeof received === "number" && !isNaN(received);
if (pass) {
return {
message: () => `expected ${received} not to be a non-NaN number`,
pass: true,
};
}
return {
message: () => `expected ${received} to be a non-NaN number`,
pass: false,
};
},
});