Skip to content

Commit

Permalink
Svelte: Fix calling DOM API functions on the actual elements
Browse files Browse the repository at this point in the history
  • Loading branch information
Keavon committed Jan 14, 2023
1 parent e849993 commit 8f61698
Show file tree
Hide file tree
Showing 15 changed files with 162 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,6 @@ impl NodeGraphMessageHandler {
disabled: network.disabled.contains(id),
})
}
log::debug!("Frontend Nodes:\n{:#?}\n\nLinks:\n{:#?}", nodes, links);
responses.push_back(FrontendMessage::UpdateNodeGraph { nodes, links }.into());
}

Expand Down Expand Up @@ -423,7 +422,6 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
input_node,
input_node_connector_index,
} => {
log::debug!("Connect primary output from node {output_node} to input of index {input_node_connector_index} on node {input_node}.");
let node_id = input_node;

let Some(network) = self.get_active_network(document) else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
const dialog = getContext<DialogState>("dialog");
let dialogModal: FloatingMenu;
let self: FloatingMenu;
export function dismiss() {
dialog.dismissDialog();
}
onMount(() => {
// Focus the first button in the popup
const emphasizedOrFirstButton = (dialogModal.div().querySelector("[data-emphasized]") || dialogModal.div().querySelector("[data-text-button]") || undefined) as HTMLButtonElement | undefined;
const emphasizedOrFirstButton = (self.div().querySelector("[data-emphasized]") || self.div().querySelector("[data-text-button]") || undefined) as HTMLButtonElement | undefined;
emphasizedOrFirstButton?.focus();
});
</script>

<FloatingMenu open={true} class="dialog-modal" type="Dialog" direction="Center" bind:this={dialogModal} data-dialog-modal>
<FloatingMenu open={true} class="dialog-modal" type="Dialog" direction="Center" bind:this={self} data-dialog-modal>
<LayoutRow>
<LayoutCol class="icon-column">
<!-- `$dialog.icon` class exists to provide special sizing in CSS to specific icons -->
Expand Down
12 changes: 6 additions & 6 deletions frontend-svelte/src/components/floating-menus/MenuList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import TextLabel from "@/components/widgets/labels/TextLabel.svelte";
import UserInputLabel from "@/components/widgets/labels/UserInputLabel.svelte";
let floatingMenu: FloatingMenu;
let self: FloatingMenu;
let scroller: LayoutCol;
// emits: ["update:open", "update:activeEntry", "naturalWidth"],
Expand All @@ -35,8 +35,8 @@
// Called only when `open` is changed from outside this component (with v-model)
$: watchOpen(open);
$: dispatch("open", isOpen);
$: watchEntries(entries, floatingMenu);
$: watchDrawIcon(drawIcon, floatingMenu);
$: watchEntries(entries, self);
$: watchDrawIcon(drawIcon, self);
$: virtualScrollingTotalHeight = entries.length === 0 ? 0 : entries[0].length * virtualScrollingEntryHeight;
$: virtualScrollingStartIndex = Math.floor(virtualScrollingEntriesStart / virtualScrollingEntryHeight) || 0;
$: virtualScrollingEndIndex = entries.length === 0 ? 0 : Math.min(entries[0].length, virtualScrollingStartIndex + 1 + 400 / virtualScrollingEntryHeight);
Expand All @@ -48,12 +48,12 @@
// TODO: Svelte: fix infinite loop and reenable
function watchEntries(_: MenuListEntry[][], floatingMenu: FloatingMenu) {
// floatingMenu?.measureAndEmitNaturalWidth();
// floatingMenu?.div().measureAndEmitNaturalWidth();
}
// TODO: Svelte: fix infinite loop and reenable
function watchDrawIcon(_: boolean, floatingMenu: FloatingMenu) {
// floatingMenu?.measureAndEmitNaturalWidth();
// floatingMenu?.div().measureAndEmitNaturalWidth();
}
function onScroll(e: Event) {
Expand Down Expand Up @@ -198,7 +198,7 @@
{direction}
{minWidth}
scrollableY={scrollableY && virtualScrollingEntryHeight === 0}
bind:this={floatingMenu}
bind:this={self}
>
<!-- If we put the scrollableY on the layoutcol for non-font dropdowns then for some reason it always creates a tiny scrollbar.
However when we are using the virtual scrolling then we need the layoutcol to be scrolling so we can bind the events without using $refs. -->
Expand Down
26 changes: 13 additions & 13 deletions frontend-svelte/src/components/layout/FloatingMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@
// Required to correctly position content when scrolled (it has a `position: fixed` to prevent clipping)
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
const tailOffset = type === "Popover" ? 10 : 0;
if (direction === "Bottom") floatingMenuContent.style.top = `${tailOffset + floatingMenuBounds.top}px`;
if (direction === "Top") floatingMenuContent.style.bottom = `${tailOffset + floatingMenuBounds.bottom}px`;
if (direction === "Right") floatingMenuContent.style.left = `${tailOffset + floatingMenuBounds.left}px`;
if (direction === "Left") floatingMenuContent.style.right = `${tailOffset + floatingMenuBounds.right}px`;
if (direction === "Bottom") floatingMenuContent.div().style.top = `${tailOffset + floatingMenuBounds.top}px`;
if (direction === "Top") floatingMenuContent.div().style.bottom = `${tailOffset + floatingMenuBounds.bottom}px`;
if (direction === "Right") floatingMenuContent.div().style.left = `${tailOffset + floatingMenuBounds.left}px`;
if (direction === "Left") floatingMenuContent.div().style.right = `${tailOffset + floatingMenuBounds.right}px`;
// Required to correctly position tail when scrolled (it has a `position: fixed` to prevent clipping)
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
Expand All @@ -154,11 +154,11 @@
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
if (floatingMenuContentBounds.left - windowEdgeMargin <= workspaceBounds.left) {
floatingMenuContent.style.left = `${windowEdgeMargin}px`;
floatingMenuContent.div().style.left = `${windowEdgeMargin}px`;
if (workspaceBounds.left + floatingMenuContainerBounds.left === 12) zeroedBorderHorizontal = "Left";
}
if (floatingMenuContentBounds.right + windowEdgeMargin >= workspaceBounds.right) {
floatingMenuContent.style.right = `${windowEdgeMargin}px`;
floatingMenuContent.div().style.right = `${windowEdgeMargin}px`;
if (workspaceBounds.right - floatingMenuContainerBounds.right === 12) zeroedBorderHorizontal = "Right";
}
}
Expand All @@ -167,11 +167,11 @@
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
if (floatingMenuContentBounds.top - windowEdgeMargin <= workspaceBounds.top) {
floatingMenuContent.style.top = `${windowEdgeMargin}px`;
floatingMenuContent.div().style.top = `${windowEdgeMargin}px`;
if (workspaceBounds.top + floatingMenuContainerBounds.top === 12) zeroedBorderVertical = "Top";
}
if (floatingMenuContentBounds.bottom + windowEdgeMargin >= workspaceBounds.bottom) {
floatingMenuContent.style.bottom = `${windowEdgeMargin}px`;
floatingMenuContent.div().style.bottom = `${windowEdgeMargin}px`;
if (workspaceBounds.bottom - floatingMenuContainerBounds.bottom === 12) zeroedBorderVertical = "Bottom";
}
}
Expand All @@ -181,16 +181,16 @@
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
switch (`${zeroedBorderVertical}${zeroedBorderHorizontal}`) {
case "TopLeft":
floatingMenuContent.style.borderTopLeftRadius = "0";
floatingMenuContent.div().style.borderTopLeftRadius = "0";
break;
case "TopRight":
floatingMenuContent.style.borderTopRightRadius = "0";
floatingMenuContent.div().style.borderTopRightRadius = "0";
break;
case "BottomLeft":
floatingMenuContent.style.borderBottomLeftRadius = "0";
floatingMenuContent.div().style.borderBottomLeftRadius = "0";
break;
case "BottomRight":
floatingMenuContent.style.borderBottomRightRadius = "0";
floatingMenuContent.div().style.borderBottomRightRadius = "0";
break;
default:
break;
Expand Down Expand Up @@ -219,7 +219,7 @@
// Measure the width of the floating menu content element, if it's currently visible
// The result will be `undefined` if the menu is invisible, perhaps because an ancestor component is hidden with a falsy `v-if` condition
const naturalWidth: number | undefined = floatingMenuContent?.clientWidth;
const naturalWidth: number | undefined = floatingMenuContent?.div().clientWidth;
// Turn off measuring mode for the component, which triggers another call to the `updated()` Vue event, so we can turn off the protection after that has happened
measuringOngoing = false;
Expand Down
55 changes: 43 additions & 12 deletions frontend-svelte/src/components/layout/LayoutCol.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
export let scrollableX: boolean = false;
export let scrollableY: boolean = false;
let divElement: HTMLDivElement;
let self: HTMLDivElement;
$: extraClasses = Object.entries(classes)
.flatMap((classAndState) => (classAndState[1] ? [classAndState[0]] : []))
Expand All @@ -19,7 +19,7 @@
.join(" ");
export function div(): HTMLDivElement {
return divElement;
return self;
}
</script>

Expand All @@ -29,21 +29,52 @@
class:scrollable-y={scrollableY}
style={`${styleName} ${extraStyles}`.trim() || undefined}
title={tooltip}
bind:this={divElement}
bind:this={self}
on:focus
on:blur
on:fullscreenchange
on:fullscreenerror
on:scroll
on:cut
on:copy
on:paste
on:keydown
on:keypress
on:keyup
on:auxclick
on:click
on:contextmenu
on:dblclick
on:pointerdown
on:pointermove
on:pointerup
on:mousedown
on:mouseenter
on:mouseleave
on:mousemove
on:mouseover
on:mouseout
on:mouseup
on:select
on:wheel
on:drag
on:dragend
on:dragenter
on:dragstart
on:dragleave
on:dragover
on:dragstart
on:dragend
on:drop
on:wheel
on:scroll
on:focus
on:blur
on:touchcancel
on:touchend
on:touchmove
on:touchstart
on:pointerover
on:pointerenter
on:pointerdown
on:pointermove
on:pointerup
on:pointercancel
on:pointerout
on:pointerleave
on:gotpointercapture
on:lostpointercapture
{...$$restProps}
>
<slot />
Expand Down
55 changes: 43 additions & 12 deletions frontend-svelte/src/components/layout/LayoutRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
export let scrollableX: boolean = false;
export let scrollableY: boolean = false;
let divElement: HTMLDivElement;
let self: HTMLDivElement;
$: extraClasses = Object.entries(classes)
.flatMap((classAndState) => (classAndState[1] ? [classAndState[0]] : []))
Expand All @@ -19,7 +19,7 @@
.join(" ");
export function div(): HTMLDivElement {
return divElement;
return self;
}
</script>

Expand All @@ -29,21 +29,52 @@
class:scrollable-y={scrollableY}
style={`${styleName} ${extraStyles}`.trim() || undefined}
title={tooltip}
bind:this={divElement}
bind:this={self}
on:focus
on:blur
on:fullscreenchange
on:fullscreenerror
on:scroll
on:cut
on:copy
on:paste
on:keydown
on:keypress
on:keyup
on:auxclick
on:click
on:contextmenu
on:dblclick
on:pointerdown
on:pointermove
on:pointerup
on:mousedown
on:mouseenter
on:mouseleave
on:mousemove
on:mouseover
on:mouseout
on:mouseup
on:select
on:wheel
on:drag
on:dragend
on:dragenter
on:dragstart
on:dragleave
on:dragover
on:dragstart
on:dragend
on:drop
on:wheel
on:scroll
on:focus
on:blur
on:touchcancel
on:touchend
on:touchmove
on:touchstart
on:pointerover
on:pointerenter
on:pointerdown
on:pointermove
on:pointerup
on:pointercancel
on:pointerout
on:pointerleave
on:gotpointercapture
on:lostpointercapture
{...$$restProps}
>
<slot />
Expand Down
15 changes: 7 additions & 8 deletions frontend-svelte/src/components/panels/Document.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@
import { type Editor } from "@/wasm-communication/editor";
import { type DocumentState } from "@/state-providers/document";
let self: LayoutCol;
let rulerHorizontal: CanvasRuler;
let rulerVertical: CanvasRuler;
let canvasDiv: HTMLDivElement;
let canvasContainer: HTMLDivElement;
const editor = getContext<Editor>("editor");
const document = getContext<DocumentState>("document");
Expand Down Expand Up @@ -116,7 +115,7 @@
function canvasPointerDown(e: PointerEvent) {
const onEditbox = e.target instanceof HTMLDivElement && e.target.contentEditable;
if (!onEditbox) canvasDiv?.setPointerCapture(e.pointerId);
if (!onEditbox) canvasContainer?.setPointerCapture(e.pointerId);
}
// Update rendered SVGs
Expand All @@ -127,7 +126,7 @@
await tick();
if (textInput) {
const foreignObject = canvasDiv.getElementsByTagName("foreignObject")[0] as SVGForeignObjectElement;
const foreignObject = canvasContainer.getElementsByTagName("foreignObject")[0] as SVGForeignObjectElement;
if (foreignObject.children.length > 0) return;
const addedInput = foreignObject.appendChild(textInput);
Expand Down Expand Up @@ -285,8 +284,8 @@
// Resize elements to render the new viewport size
export function viewportResize() {
// Resize the canvas
canvasSvgWidth = Math.ceil(parseFloat(getComputedStyle(canvasDiv).width));
canvasSvgHeight = Math.ceil(parseFloat(getComputedStyle(canvasDiv).height));
canvasSvgWidth = Math.ceil(parseFloat(getComputedStyle(canvasContainer).width));
canvasSvgHeight = Math.ceil(parseFloat(getComputedStyle(canvasContainer).height));
// Resize the rulers
rulerHorizontal?.resize();
Expand Down Expand Up @@ -382,7 +381,7 @@
});
</script>

<LayoutCol class="document" bind:this={self}>
<LayoutCol class="document">
<LayoutRow class="options-bar" scrollableX={true}>
<WidgetLayout layout={$document.documentModeLayout} />
<WidgetLayout layout={$document.toolOptionsLayout} />
Expand Down Expand Up @@ -422,7 +421,7 @@
y={cursorTop}
/>
{/if}
<div class="canvas" on:pointerdown={(e) => canvasPointerDown(e)} on:dragover={(e) => e.preventDefault()} on:drop={(e) => pasteFile(e)} bind:this={canvasDiv} data-canvas>
<div class="canvas" on:pointerdown={(e) => canvasPointerDown(e)} on:dragover={(e) => e.preventDefault()} on:drop={(e) => pasteFile(e)} bind:this={canvasContainer} data-canvas>
<svg class="artboards" style:width={canvasWidthCSS} style:height={canvasHeightCSS}>
{@html artboardSvg}
</svg>
Expand Down
4 changes: 2 additions & 2 deletions frontend-svelte/src/components/panels/LayerTree.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
await tick();
const textInput: HTMLInputElement | undefined = list?.querySelector("[data-text-input]:not([disabled])") || undefined;
const textInput = (list?.div().querySelector("[data-text-input]:not([disabled])") || undefined) as HTMLInputElement | undefined;
textInput?.select();
}
Expand Down Expand Up @@ -169,7 +169,7 @@
function calculateDragIndex(tree: LayoutCol, clientY: number, select?: () => void): DraggingData {
const treeChildren = tree.div().children;
const treeOffset = tree.getBoundingClientRect().top;
const treeOffset = tree.div().getBoundingClientRect().top;
// Closest distance to the middle of the row along the Y axis
let closest = Infinity;
Expand Down
Loading

0 comments on commit 8f61698

Please sign in to comment.