| Index: third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| index 29b60dbcc9004d172e795b27681167b60f0da4af..bb8284d2755d4863bc6e24f8418c5af7a71b9f82 100644
|
| --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| @@ -49,18 +49,6 @@
|
|
|
| namespace blink {
|
|
|
| -MarkerRemoverPredicate::MarkerRemoverPredicate(const Vector<String>& words)
|
| - : m_words(words) {}
|
| -
|
| -bool MarkerRemoverPredicate::operator()(const DocumentMarker& documentMarker,
|
| - const Text& textNode) const {
|
| - unsigned start = documentMarker.startOffset();
|
| - unsigned length = documentMarker.endOffset() - documentMarker.startOffset();
|
| -
|
| - String markerText = textNode.data().substring(start, length);
|
| - return m_words.contains(markerText);
|
| -}
|
| -
|
| DocumentMarkerController::DocumentMarkerController(Document& document)
|
| : m_document(&document) {
|
| setContext(&document);
|
| @@ -73,52 +61,77 @@ void DocumentMarkerController::clear() {
|
| m_compositions.clear();
|
| }
|
|
|
| -void DocumentMarkerController::addMarker(const Position& start,
|
| - const Position& end,
|
| - DocumentMarker::MarkerType type,
|
| - const String& description) {
|
| - // Use a TextIterator to visit the potentially multiple nodes the range
|
| - // covers.
|
| +void DocumentMarkerController::addCompositionMarker(const Position& start,
|
| + const Position& end,
|
| + Color underlineColor,
|
| + bool thick,
|
| + Color backgroundColor) {
|
| + DCHECK(!m_document->needsLayoutTreeUpdate());
|
| +
|
| for (TextIterator markedText(start, end); !markedText.atEnd();
|
| markedText.advance()) {
|
| addMarker(markedText.currentContainer(),
|
| - new DocumentMarker(
|
| - type, markedText.startOffsetInCurrentContainer(),
|
| - markedText.endOffsetInCurrentContainer(), description));
|
| + DocumentMarker::createCompositionMarker(
|
| + markedText.startOffsetInCurrentContainer(),
|
| + markedText.endOffsetInCurrentContainer(), underlineColor,
|
| + thick, backgroundColor));
|
| }
|
| }
|
|
|
| -void DocumentMarkerController::addTextMatchMarker(const EphemeralRange& range,
|
| - bool activeMatch) {
|
| +void DocumentMarkerController::addGrammarOrSpellingMarker(
|
| + const Position& start,
|
| + const Position& end,
|
| + DocumentMarker::MarkerType type,
|
| + const String& description) {
|
| DCHECK(!m_document->needsLayoutTreeUpdate());
|
| -
|
| + DCHECK(type == DocumentMarker::Grammar || type == DocumentMarker::Spelling);
|
| // Use a TextIterator to visit the potentially multiple nodes the range
|
| // covers.
|
| - for (TextIterator markedText(range.startPosition(), range.endPosition());
|
| - !markedText.atEnd(); markedText.advance()) {
|
| - addMarker(markedText.currentContainer(),
|
| - new DocumentMarker(markedText.startOffsetInCurrentContainer(),
|
| - markedText.endOffsetInCurrentContainer(),
|
| - activeMatch));
|
| + for (TextIterator markedText(start, end); !markedText.atEnd();
|
| + markedText.advance()) {
|
| + DocumentMarker* marker;
|
| + if (type == DocumentMarker::Grammar) {
|
| + marker = DocumentMarker::createGrammarMarker(
|
| + markedText.startOffsetInCurrentContainer(),
|
| + markedText.endOffsetInCurrentContainer(), description);
|
| + } else {
|
| + marker = DocumentMarker::createSpellingMarker(
|
| + markedText.startOffsetInCurrentContainer(),
|
| + markedText.endOffsetInCurrentContainer(), description);
|
| + }
|
| +
|
| + addMarker(markedText.currentContainer(), marker);
|
| }
|
| - // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a
|
| - // throttling algorithm. crbug.com/6819.
|
| }
|
|
|
| -void DocumentMarkerController::addCompositionMarker(const Position& start,
|
| - const Position& end,
|
| - Color underlineColor,
|
| - bool thick,
|
| - Color backgroundColor) {
|
| +void DocumentMarkerController::addGrammarMarker(const Position& start,
|
| + const Position& end,
|
| + const String& description) {
|
| + addGrammarOrSpellingMarker(start, end, DocumentMarker::Grammar, description);
|
| +}
|
| +
|
| +void DocumentMarkerController::addSpellingMarker(const Position& start,
|
| + const Position& end,
|
| + const String& description) {
|
| + addGrammarOrSpellingMarker(start, end, DocumentMarker::Spelling, description);
|
| +}
|
| +
|
| +void DocumentMarkerController::addTextMatchMarker(const Position& start,
|
| + const Position& end,
|
| + bool activeMatch) {
|
| DCHECK(!m_document->needsLayoutTreeUpdate());
|
|
|
| + // Use a TextIterator to visit the potentially multiple nodes the range
|
| + // covers.
|
| for (TextIterator markedText(start, end); !markedText.atEnd();
|
| markedText.advance()) {
|
| addMarker(markedText.currentContainer(),
|
| - new DocumentMarker(markedText.startOffsetInCurrentContainer(),
|
| - markedText.endOffsetInCurrentContainer(),
|
| - underlineColor, thick, backgroundColor));
|
| + DocumentMarker::createTextMatchMarker(
|
| + markedText.startOffsetInCurrentContainer(),
|
| + markedText.endOffsetInCurrentContainer(), activeMatch));
|
| }
|
| + // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a
|
| + // throttling algorithm. crbug.com/6819.
|
| }
|
|
|
| void DocumentMarkerController::prepareForDestruction() {
|
| @@ -304,8 +317,7 @@ DocumentMarkerVector DocumentMarkerController::markersInRange(
|
| return foundMarkers;
|
| }
|
|
|
| -Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(
|
| - DocumentMarker::MarkerType) {
|
| +Vector<IntRect> DocumentMarkerController::renderedRectsForTextMatchMarkers() {
|
| Vector<IntRect> result;
|
|
|
| // outer loop: process each node
|
| @@ -337,7 +349,8 @@ static void invalidatePaintForTickmarks(const Node& node) {
|
| frameView->invalidatePaintForTickmarks();
|
| }
|
|
|
| -void DocumentMarkerController::invalidateRectsForMarkersInNode(Node& node) {
|
| +void DocumentMarkerController::invalidateRectsForTextMatchMarkersInNode(
|
| + Node& node) {
|
| if (!m_textMatches.contains(&node))
|
| return;
|
|
|
| @@ -351,9 +364,9 @@ void DocumentMarkerController::invalidateRectsForMarkersInNode(Node& node) {
|
| invalidatePaintForTickmarks(node);
|
| }
|
|
|
| -void DocumentMarkerController::invalidateRectsForAllMarkers() {
|
| +void DocumentMarkerController::invalidateRectsForAllTextMatchMarkers() {
|
| for (auto& nodeMarkers : m_textMatches)
|
| - invalidateRectsForMarkersInNode(*nodeMarkers.key);
|
| + invalidateRectsForTextMatchMarkersInNode(*nodeMarkers.key);
|
| }
|
|
|
| DEFINE_TRACE(DocumentMarkerController) {
|
| @@ -381,6 +394,17 @@ void DocumentMarkerController::removeMarkers(
|
| m_compositions.remove(node);
|
| }
|
|
|
| +void DocumentMarkerController::removeSpellingMarkersForWords(
|
| + const Vector<String>& words) {
|
| + for (auto& nodeMarkers : m_spelling) {
|
| + const Node& node = *nodeMarkers.key;
|
| + if (!node.isTextNode())
|
| + continue;
|
| + nodeMarkers.value->removeMarkersForWords(static_cast<const Text&>(node),
|
| + words);
|
| + }
|
| +}
|
| +
|
| void DocumentMarkerController::removeMarkers(
|
| DocumentMarker::MarkerTypes markerTypes) {
|
| if (markerTypes.contains(DocumentMarker::Spelling))
|
| @@ -396,17 +420,6 @@ void DocumentMarkerController::removeMarkers(
|
| m_compositions.clear();
|
| }
|
|
|
| -void DocumentMarkerController::removeMarkers(
|
| - const MarkerRemoverPredicate& shouldRemoveMarker) {
|
| - for (auto& nodeMarkers : m_spelling) {
|
| - const Node& node = *nodeMarkers.key;
|
| - if (!node.isTextNode())
|
| - continue;
|
| - nodeMarkers.value->removeMarkersForWords(static_cast<const Text&>(node),
|
| - shouldRemoveMarker.m_words);
|
| - }
|
| -}
|
| -
|
| void DocumentMarkerController::repaintMarkers(
|
| DocumentMarker::MarkerTypes markerTypes) {
|
| HeapHashSet<Member<Node>> nodesToRepaint;
|
| @@ -440,8 +453,9 @@ void DocumentMarkerController::repaintMarkers(
|
| }
|
| }
|
|
|
| -bool DocumentMarkerController::setMarkersActive(const EphemeralRange& range,
|
| - bool active) {
|
| +bool DocumentMarkerController::setTextMatchMarkersActive(
|
| + const EphemeralRange& range,
|
| + bool active) {
|
| Node* const startContainer = range.startPosition().computeContainerNode();
|
| DCHECK(startContainer);
|
| Node* const endContainer = range.endPosition().computeContainerNode();
|
| @@ -456,7 +470,8 @@ bool DocumentMarkerController::setMarkersActive(const EphemeralRange& range,
|
| for (Node& node : range.nodes()) {
|
| int startOffset = node == startContainer ? containerStartOffset : 0;
|
| int endOffset = node == endContainer ? containerEndOffset : INT_MAX;
|
| - markerFound |= setMarkersActive(&node, startOffset, endOffset, active);
|
| + markerFound |=
|
| + setTextMatchMarkersActive(&node, startOffset, endOffset, active);
|
| }
|
| return markerFound;
|
| }
|
| @@ -466,10 +481,10 @@ bool DocumentMarkerController::hasMarkers(Node* node) const {
|
| m_textMatches.contains(node) || m_compositions.contains(node);
|
| }
|
|
|
| -bool DocumentMarkerController::setMarkersActive(Node* node,
|
| - unsigned startOffset,
|
| - unsigned endOffset,
|
| - bool active) {
|
| +bool DocumentMarkerController::setTextMatchMarkersActive(Node* node,
|
| + unsigned startOffset,
|
| + unsigned endOffset,
|
| + bool active) {
|
| bool docDirty = false;
|
| if (m_textMatches.contains(node)) {
|
| docDirty = m_textMatches.at(node)->setTextMatchMarkersActive(
|
| @@ -625,7 +640,7 @@ void DocumentMarkerController::didUpdateCharacterData(CharacterData* node,
|
| &didShiftMarker);
|
|
|
| if (didShiftMarker) {
|
| - invalidateRectsForMarkersInNode(*node);
|
| + invalidateRectsForTextMatchMarkersInNode(*node);
|
| // repaint the affected node
|
| if (node->layoutObject()) {
|
| node->layoutObject()->setShouldDoFullPaintInvalidation(
|
|
|