From 5335434af900f7d3c0d32aac6ab09173d5a19312 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Wed, 31 Jan 2024 15:17:17 +0100 Subject: [PATCH] Simplified the selection update code --- edit-context/index.html | 47 ++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/edit-context/index.html b/edit-context/index.html index a0c8b9f..7424d64 100644 --- a/edit-context/index.html +++ b/edit-context/index.html @@ -344,24 +344,16 @@ // Update the character bounds when the EditContext needs it. editContext.addEventListener("characterboundsupdate", e => { - const rangeStart = e.rangeStart; - const rangeEnd = e.rangeEnd; + const tokenNodes = convertFromOffsetsToListOfRenderedTokenNodes(e.rangeStart, e.rangeEnd); - const charBounds = []; - - // Find the tokens in currentTokens that are in the range. - // Get the node for each token in range, and convert it - // into a DOMRect. - for (let offset = rangeStart; offset < rangeEnd; offset++) { - const token = currentTokens.find(token => token.pos <= offset && token.pos + token.value.length > offset); - const node = token.node; + const charBounds = tokenNodes.map(({ node, nodeOffset, charOffset }) => { const range = document.createRange(); - range.setStart(node.firstChild, offset - token.pos); - range.setEnd(node.firstChild, offset - token.pos + 1); - charBounds.push(range.getBoundingClientRect()); - } + range.setStart(node.firstChild, charOffset - nodeOffset); + range.setEnd(node.firstChild, charOffset - nodeOffset + 1); + return range.getBoundingClientRect(); + }); - editContext.updateCharacterBounds(rangeStart, charBounds); + editContext.updateCharacterBounds(e.rangeStart, charBounds); }); // Draw IME composition text formats if needed. @@ -408,10 +400,27 @@ // Listen to selectionchange events to let the EditContext know where it is. document.addEventListener("selectionchange", () => { const selection = document.getSelection(); - const { start, end } = convertFromSelectionToOffsets(selection); - updateSelection(start, end); + const offsets = convertFromSelectionToOffsets(selection); + if (offsets) { + updateSelection(offsets.start, offsets.end); + } }); + // Find the tokens in currentTokens that are in the given range and return + // the corresponding nodes. + function convertFromOffsetsToListOfRenderedTokenNodes(start, end) { + const tokenNodes = []; + + for (let offset = start; offset < end; offset++) { + const token = currentTokens.find(token => token.pos <= offset && token.pos + token.value.length > offset); + if (token) { + tokenNodes.push({ node: token.node, nodeOffset: token.pos, charOffset: offset }); + } + } + + return tokenNodes; + } + // The EditContext object only knows about a plain text string and about // character offsets. However, our editor view renders the text by using // DOM nodes. So we sometimes need to convert between the two. @@ -445,6 +454,10 @@ } } + if (!anchorNodeFound || !extentNodeFound) { + return null; + } + if (anchorOffset > extentOffset) { [anchorOffset, extentOffset] = [extentOffset, anchorOffset]; }