Skip to content

Commit

Permalink
CSS Custom Highlights optimization add flag for when live ranges are …
Browse files Browse the repository at this point in the history
…changed

https://bugs.webkit.org/show_bug.cgi?id=259804
rdar://113361192

Reviewed by Ryosuke Niwa.

Does not collect range data for live ranges that were not changed/updated.
Before, would collect range data for all live ranges all the time, and repainting them.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::collectRangeDataFromRegister):
* Source/WebCore/dom/Range.cpp:
(WebCore::Range::setStart):
(WebCore::Range::setEnd):
(WebCore::Range::nodeChildrenChanged):
(WebCore::Range::nodeChildrenWillBeRemoved):
(WebCore::Range::nodeWillBeRemoved):
(WebCore::Range::textInserted):
(WebCore::Range::textRemoved):
(WebCore::Range::textNodesMerged):
(WebCore::Range::textNodeSplit):
* Source/WebCore/dom/Range.h:

Canonical link: https://commits.webkit.org/266614@main
  • Loading branch information
jesxilin authored and rniwa committed Aug 5, 2023
1 parent dbfde83 commit 21b6828
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
13 changes: 12 additions & 1 deletion Source/WebCore/dom/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2989,15 +2989,26 @@ void Document::collectRangeDataFromRegister(Vector<WeakPtr<HighlightRangeData>>&
{
for (auto& highlight : highlightRegister.map()) {
for (auto& rangeData : highlight.value->rangesData()) {
// FIXME: For live ranges, we can optimize by only performing this when the range changed.
if (rangeData->startPosition().isNotNull() && rangeData->endPosition().isNotNull() && !rangeData->range().isLiveRange())
continue;

if (auto* liveRange = dynamicDowncast<Range>(rangeData->range()); liveRange && !liveRange->didChangeHighlight())
continue;

auto simpleRange = makeSimpleRange(rangeData->range());
if (&simpleRange.startContainer().treeScope() != &simpleRange.endContainer().treeScope())
continue;
rangesData.append(rangeData.get());
}
}

// One range can belong to multiple highlights so resetting a range's flag cannot be done in the loops above.
for (auto& highlight : highlightRegister.map()) {
for (auto& rangeData : highlight.value->rangesData()) {
if (auto* liveRange = dynamicDowncast<Range>(rangeData->range()); liveRange && liveRange->didChangeHighlight())
liveRange->resetDidChangeHighlight();
}
}
}

void Document::updateHighlightPositions()
Expand Down
9 changes: 9 additions & 0 deletions Source/WebCore/dom/Range.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ ExceptionOr<void> Range::setStart(Ref<Node>&& container, unsigned offset)
m_end = m_start;
updateAssociatedSelection();
updateDocument();
m_didChangeHighlight = true;
return { };
}

Expand All @@ -144,6 +145,7 @@ ExceptionOr<void> Range::setEnd(Ref<Node>&& container, unsigned offset)
m_start = m_end;
updateAssociatedSelection();
updateDocument();
m_didChangeHighlight = true;
return { };
}

Expand Down Expand Up @@ -897,6 +899,7 @@ void Range::nodeChildrenChanged(ContainerNode& container)
ASSERT(&container.document() == m_ownerDocument.ptr());
boundaryNodeChildrenChanged(m_start, container);
boundaryNodeChildrenChanged(m_end, container);
m_didChangeHighlight = true;
}

static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode& containerOfNodesToBeRemoved)
Expand All @@ -910,6 +913,7 @@ void Range::nodeChildrenWillBeRemoved(ContainerNode& container)
ASSERT(&container.document() == m_ownerDocument.ptr());
boundaryNodeChildrenWillBeRemoved(m_start, container);
boundaryNodeChildrenWillBeRemoved(m_end, container);
m_didChangeHighlight = true;
}

static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node& nodeToBeRemoved)
Expand All @@ -927,6 +931,7 @@ void Range::nodeWillBeRemoved(Node& node)
ASSERT(node.parentNode());
boundaryNodeWillBeRemoved(m_start, node);
boundaryNodeWillBeRemoved(m_end, node);
m_didChangeHighlight = true;
}

bool Range::parentlessNodeMovedToNewDocumentAffectsRange(Node& node)
Expand Down Expand Up @@ -956,6 +961,7 @@ void Range::textInserted(Node& text, unsigned offset, unsigned length)
ASSERT(&text.document() == m_ownerDocument.ptr());
boundaryTextInserted(m_start, text, offset, length);
boundaryTextInserted(m_end, text, offset, length);
m_didChangeHighlight = true;
}

static inline void boundaryTextRemoved(RangeBoundaryPoint& boundary, Node& text, unsigned offset, unsigned length)
Expand All @@ -976,6 +982,7 @@ void Range::textRemoved(Node& text, unsigned offset, unsigned length)
ASSERT(&text.document() == m_ownerDocument.ptr());
boundaryTextRemoved(m_start, text, offset, length);
boundaryTextRemoved(m_end, text, offset, length);
m_didChangeHighlight = true;
}

static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, NodeWithIndex& oldNode, unsigned offset)
Expand All @@ -996,6 +1003,7 @@ void Range::textNodesMerged(NodeWithIndex& oldNode, unsigned offset)
ASSERT(oldNode.node()->previousSibling()->isTextNode());
boundaryTextNodesMerged(m_start, oldNode, offset);
boundaryTextNodesMerged(m_end, oldNode, offset);
m_didChangeHighlight = true;
}

static inline void boundaryTextNodesSplit(RangeBoundaryPoint& boundary, Text& oldNode)
Expand Down Expand Up @@ -1028,6 +1036,7 @@ void Range::textNodeSplit(Text& oldNode)
ASSERT(!oldNode.parentNode() || oldNode.nextSibling()->isTextNode());
boundaryTextNodesSplit(m_start, oldNode);
boundaryTextNodesSplit(m_end, oldNode);
m_didChangeHighlight = true;
}

ExceptionOr<void> Range::expand(const String& unit)
Expand Down
4 changes: 4 additions & 0 deletions Source/WebCore/dom/Range.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class Range final : public AbstractRange, public CanMakeWeakPtr<Range> {
bool collapsed() const final { return m_start == m_end; }
WEBCORE_EXPORT Node* commonAncestorContainer() const;

void resetDidChangeHighlight() { m_didChangeHighlight = false; }
bool didChangeHighlight() const { return m_didChangeHighlight; }

WEBCORE_EXPORT ExceptionOr<void> setStart(Ref<Node>&&, unsigned offset);
WEBCORE_EXPORT ExceptionOr<void> setEnd(Ref<Node>&&, unsigned offset);
WEBCORE_EXPORT ExceptionOr<void> setStartBefore(Node&);
Expand Down Expand Up @@ -133,6 +136,7 @@ class Range final : public AbstractRange, public CanMakeWeakPtr<Range> {
RangeBoundaryPoint m_start;
RangeBoundaryPoint m_end;
bool m_isAssociatedWithSelection { false };
bool m_didChangeHighlight { false };
};

WEBCORE_EXPORT SimpleRange makeSimpleRange(const Range&);
Expand Down

0 comments on commit 21b6828

Please sign in to comment.