Merge remote-tracking branch 'origin/release' into danieljgeiger-mathjax

This commit is contained in:
Daniel J. Geiger
2023-06-15 14:36:09 -05:00
221 changed files with 15664 additions and 8165 deletions
+49 -78
View File
@@ -11,7 +11,7 @@ import {
isBoundToContainer,
isTextElement,
} from "./typeChecks";
import { CLASSES, isSafari, VERTICAL_ALIGN } from "../constants";
import { CLASSES, isSafari } from "../constants";
import {
ExcalidrawElement,
ExcalidrawLinearElement,
@@ -23,7 +23,6 @@ import { AppState } from "../types";
import { mutateElement } from "./mutateElement";
import {
getBoundTextElementId,
getContainerCoords,
getContainerDims,
getContainerElement,
getTextElementAngle,
@@ -36,6 +35,7 @@ import {
getBoundTextMaxWidth,
computeContainerDimensionForBoundText,
detectLineHeight,
computeBoundTextPosition,
} from "./textElement";
import {
actionDecreaseFontSize,
@@ -185,13 +185,9 @@ export const textWysiwyg = ({
let textElementWidth = Math.max(updatedTextElement.width, eMetrics.width);
// Set to element height by default since that's
// what is going to be used for unbounded text
let textElementHeight = Math.max(updatedTextElement.height, maxHeight);
const textElementHeight = Math.max(updatedTextElement.height, maxHeight);
if (container && updatedTextElement.containerId) {
textElementHeight = Math.min(
getBoundTextMaxWidth(container),
textElementHeight,
);
if (isArrowElement(container)) {
const boundTextCoords =
LinearElementEditor.getBoundTextElementPosition(
@@ -200,34 +196,12 @@ export const textWysiwyg = ({
);
coordX = boundTextCoords.x;
coordY = boundTextCoords.y;
} else {
coordX = Math.max(coordX, getContainerCoords(container).x);
}
const propertiesUpdated = textPropertiesUpdated(
updatedTextElement,
editable,
);
const containerDims = getContainerDims(container);
// using editor.style.height to get the accurate height of text editor
const editorHeight = Number(editable.style.height.slice(0, -2));
if (editorHeight > 0) {
textElementHeight = editorHeight;
}
if (propertiesUpdated) {
// update height of the editor after properties updated
const font = getFontString(updatedTextElement);
textElementHeight =
updatedTextElement.lineHeight *
wrapText(
updatedTextElement.originalText,
font,
getBoundTextMaxWidth(container),
).split("\n").length;
textElementHeight = Math.max(
textElementHeight,
updatedTextElement.height,
);
}
let originalContainerData;
if (propertiesUpdated) {
@@ -272,22 +246,12 @@ export const textWysiwyg = ({
container.type,
);
mutateElement(container, { height: targetContainerHeight });
}
// Start pushing text upward until a diff of 30px (padding)
// is reached
else {
const containerCoords = getContainerCoords(container);
// vertically center align the text
if (verticalAlign === VERTICAL_ALIGN.MIDDLE) {
if (!isArrowElement(container)) {
coordY =
containerCoords.y + maxHeight / 2 - textElementHeight / 2;
}
}
if (verticalAlign === VERTICAL_ALIGN.BOTTOM) {
coordY = containerCoords.y + (maxHeight - textElementHeight);
}
} else {
const { y } = computeBoundTextPosition(
container,
updatedTextElement as ExcalidrawTextElementWithContainer,
);
coordY = y;
}
}
const [viewportX, viewportY] = getViewportCoords(coordX, coordY);
@@ -448,25 +412,6 @@ export const textWysiwyg = ({
};
editable.oninput = () => {
const updatedTextElement = Scene.getScene(element)?.getElement(
id,
) as ExcalidrawTextElement;
const font = getFontString(updatedTextElement);
if (isBoundToContainer(element)) {
const container = getContainerElement(element);
const wrappedText = wrapText(
normalizeText(editable.value),
font,
getBoundTextMaxWidth(container!),
);
const { width, height } = measureText(
wrappedText,
font,
updatedTextElement.lineHeight,
);
editable.style.width = `${width}px`;
editable.style.height = `${height}px`;
}
onChange(normalizeText(editable.value));
};
}
@@ -696,20 +641,46 @@ export const textWysiwyg = ({
// in that same tick.
const target = event?.target;
const isTargetColorPicker =
target instanceof HTMLInputElement &&
target.closest(".color-picker-input") &&
isWritableElement(target);
const isTargetPickerTrigger =
target instanceof HTMLElement &&
target.classList.contains("active-color");
setTimeout(() => {
editable.onblur = handleSubmit;
if (target && isTargetColorPicker) {
target.onblur = () => {
editable.focus();
if (isTargetPickerTrigger) {
const callback = (
mutationList: MutationRecord[],
observer: MutationObserver,
) => {
const radixIsRemoved = mutationList.find(
(mutation) =>
mutation.removedNodes.length > 0 &&
(mutation.removedNodes[0] as HTMLElement).dataset
?.radixPopperContentWrapper !== undefined,
);
if (radixIsRemoved) {
// should work without this in theory
// and i think it does actually but radix probably somewhere,
// somehow sets the focus elsewhere
setTimeout(() => {
editable.focus();
});
observer.disconnect();
}
};
const observer = new MutationObserver(callback);
observer.observe(document.querySelector(".excalidraw-container")!, {
childList: true,
});
}
// case: clicking on the same property → no change → no update → no focus
if (!isTargetColorPicker) {
if (!isTargetPickerTrigger) {
editable.focus();
}
});
@@ -717,16 +688,16 @@ export const textWysiwyg = ({
// prevent blur when changing properties from the menu
const onPointerDown = (event: MouseEvent) => {
const isTargetColorPicker =
event.target instanceof HTMLInputElement &&
event.target.closest(".color-picker-input") &&
isWritableElement(event.target);
const isTargetPickerTrigger =
event.target instanceof HTMLElement &&
event.target.classList.contains("active-color");
if (
((event.target instanceof HTMLElement ||
event.target instanceof SVGElement) &&
event.target.closest(`.${CLASSES.SHAPE_ACTIONS_MENU}`) &&
!isWritableElement(event.target)) ||
isTargetColorPicker
isTargetPickerTrigger
) {
editable.onblur = null;
window.addEventListener("pointerup", bindBlurEvent);
@@ -740,7 +711,7 @@ export const textWysiwyg = ({
const unbindUpdate = Scene.getScene(element)!.addCallback(() => {
updateWysiwygStyle();
const isColorPickerActive = !!document.activeElement?.closest(
".color-picker-input",
".color-picker-content",
);
if (!isColorPickerActive) {
editable.focus();