diff options
author | bptato <nincsnevem662@gmail.com> | 2024-11-26 22:54:21 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-11-26 23:05:49 +0100 |
commit | 58da6cf90ce80f0bfc77a5ebd6603bec0cbc240c (patch) | |
tree | 978921e212763eb5cfc034a64876edbb88f4bc4f /src | |
parent | 14c4a11eaaea5dfa13afb6f44ab9531a90445f36 (diff) | |
download | chawan-58da6cf90ce80f0bfc77a5ebd6603bec0cbc240c.tar.gz |
buffer: optimize hover switching
Fixed a bug that would lead to styles unnecessarily being recalculated if the root element had a :hover dependency.
Diffstat (limited to 'src')
-rw-r--r-- | src/css/match.nim | 6 | ||||
-rw-r--r-- | src/server/buffer.nim | 11 |
2 files changed, 15 insertions, 2 deletions
diff --git a/src/css/match.nim b/src/css/match.nim index 51dd9a6e..695f2404 100644 --- a/src/css/match.nim +++ b/src/css/match.nim @@ -77,6 +77,12 @@ func pseudoSelectorMatches(element: Element; sel: Selector; return element.parentNode.firstElementChild == element and element.parentNode.lastElementChild == element of pcHover: + #TODO this is somewhat problematic. + # e.g. if there is a rule like ".class :hover", then you set + # dtHover for basically every element, even if most of them are not + # a .class descendant. + # Ideally we should try to match the rest of the selector before + # attaching dependencies in general. depends.add(element, dtHover) return element.hover of pcRoot: return element == element.document.documentElement diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 846191a7..41b1ec1e 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -893,10 +893,10 @@ proc updateHover*(buffer: Buffer; cursorx, cursory: int): UpdateHoverResult let prevNode = buffer.prevHover if thisNode != prevNode and (thisNode == nil or prevNode == nil or thisNode != prevNode): + var oldHover: seq[Element] = @[] for element in prevNode.branchElems: if element.hover: - element.setHover(false) - repaint = true + oldHover.add(element) for ht in HoverType: let s = HoverFun[ht](buffer, thisNode) if buffer.hoverText[ht] != s: @@ -906,6 +906,13 @@ proc updateHover*(buffer: Buffer; cursorx, cursory: int): UpdateHoverResult if not element.hover: element.setHover(true) repaint = true + elif (let i = oldHover.find(element); i != -1): + # branches converged + oldHover.setLen(i) + break + for element in oldHover: + element.setHover(false) + repaint = true if repaint: buffer.reshape() buffer.prevHover = thisNode |