OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights |
7 * reserved. | 7 * reserved. |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
(...skipping 30 matching lines...) Expand all Loading... |
41 #include "core/editing/markers/TextMatchMarkerList.h" | 41 #include "core/editing/markers/TextMatchMarkerList.h" |
42 #include "core/frame/FrameView.h" | 42 #include "core/frame/FrameView.h" |
43 #include "core/layout/LayoutObject.h" | 43 #include "core/layout/LayoutObject.h" |
44 | 44 |
45 #ifndef NDEBUG | 45 #ifndef NDEBUG |
46 #include <stdio.h> | 46 #include <stdio.h> |
47 #endif | 47 #endif |
48 | 48 |
49 namespace blink { | 49 namespace blink { |
50 | 50 |
51 MarkerRemoverPredicate::MarkerRemoverPredicate(const Vector<String>& words) | |
52 : m_words(words) {} | |
53 | |
54 bool MarkerRemoverPredicate::operator()(const DocumentMarker& documentMarker, | |
55 const Text& textNode) const { | |
56 unsigned start = documentMarker.startOffset(); | |
57 unsigned length = documentMarker.endOffset() - documentMarker.startOffset(); | |
58 | |
59 String markerText = textNode.data().substring(start, length); | |
60 return m_words.contains(markerText); | |
61 } | |
62 | |
63 DocumentMarkerController::DocumentMarkerController(Document& document) | 51 DocumentMarkerController::DocumentMarkerController(Document& document) |
64 : m_document(&document) { | 52 : m_document(&document) { |
65 setContext(&document); | 53 setContext(&document); |
66 } | 54 } |
67 | 55 |
68 void DocumentMarkerController::clear() { | 56 void DocumentMarkerController::clear() { |
69 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { | 57 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
70 MarkerMap& markerMap = markerMapForType(type); | 58 MarkerMap& markerMap = markerMapForType(type); |
71 markerMap.clear(); | 59 markerMap.clear(); |
72 } | 60 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 if (node == startContainer && marker->endOffset() <= startOffset) | 272 if (node == startContainer && marker->endOffset() <= startOffset) |
285 continue; | 273 continue; |
286 if (node == endContainer && marker->startOffset() >= endOffset) | 274 if (node == endContainer && marker->startOffset() >= endOffset) |
287 continue; | 275 continue; |
288 foundMarkers.push_back(marker); | 276 foundMarkers.push_back(marker); |
289 } | 277 } |
290 } | 278 } |
291 return foundMarkers; | 279 return foundMarkers; |
292 } | 280 } |
293 | 281 |
294 // This method is only ever called with the type DocumentMarker::TextMatch | 282 Vector<IntRect> DocumentMarkerController::renderedRectsForTextMatchMarkers() { |
295 // TODO(rlanday): remove the param | |
296 Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers( | |
297 DocumentMarker::MarkerType) { | |
298 Vector<IntRect> result; | 283 Vector<IntRect> result; |
299 for (auto nodeIterator = m_textMatches.begin(); | 284 for (auto nodeIterator = m_textMatches.begin(); |
300 nodeIterator != m_textMatches.end(); ++nodeIterator) { | 285 nodeIterator != m_textMatches.end(); ++nodeIterator) { |
301 const Node& node = *nodeIterator->key; | 286 const Node& node = *nodeIterator->key; |
302 TextMatchMarkerList* list = | 287 TextMatchMarkerList* list = |
303 toTextMatchMarkerList(nodeIterator->value.get()); | 288 toTextMatchMarkerList(nodeIterator->value.get()); |
304 #if DCHECK_IS_ON() | 289 #if DCHECK_IS_ON() |
305 if (!list->empty()) { | 290 if (!list->empty()) { |
306 DCHECK(!m_document->view() || !m_document->view()->needsLayout()); | 291 DCHECK(!m_document->view() || !m_document->view()->needsLayout()); |
307 DCHECK(!m_document->needsLayoutTreeUpdate()); | 292 DCHECK(!m_document->needsLayoutTreeUpdate()); |
308 } | 293 } |
309 #endif | 294 #endif |
310 list->appendRenderedRectsToInputList(node, &result); | 295 list->appendRenderedRectsToInputList(node, &result); |
311 } | 296 } |
312 | 297 |
313 return result; | 298 return result; |
314 } | 299 } |
315 | 300 |
316 static void invalidatePaintForTickmarks(const Node& node) { | 301 static void invalidatePaintForTickmarks(const Node& node) { |
317 if (FrameView* frameView = node.document().view()) | 302 if (FrameView* frameView = node.document().view()) |
318 frameView->invalidatePaintForTickmarks(); | 303 frameView->invalidatePaintForTickmarks(); |
319 } | 304 } |
320 | 305 |
321 void DocumentMarkerController::invalidateRectsForMarkersInNode(Node& node) { | 306 void DocumentMarkerController::invalidateRectsForTextMatchMarkersInNode( |
| 307 Node& node) { |
322 if (!m_textMatches.contains(&node)) | 308 if (!m_textMatches.contains(&node)) |
323 return; | 309 return; |
324 | 310 |
325 toTextMatchMarkerList(m_textMatches.find(&node)->value.get()) | 311 toTextMatchMarkerList(m_textMatches.find(&node)->value.get()) |
326 ->invalidateRects(); | 312 ->invalidateRects(); |
327 invalidatePaintForTickmarks(node); | 313 invalidatePaintForTickmarks(node); |
328 } | 314 } |
329 | 315 |
330 void DocumentMarkerController::invalidateRectsForAllMarkers() { | 316 void DocumentMarkerController::invalidateRectsForAllTextMatchMarkers() { |
331 for (auto& nodeMarkers : m_textMatches) | 317 for (auto& nodeMarkers : m_textMatches) |
332 invalidateRectsForMarkersInNode(*nodeMarkers.key); | 318 invalidateRectsForTextMatchMarkersInNode(*nodeMarkers.key); |
333 } | 319 } |
334 | 320 |
335 DEFINE_TRACE(DocumentMarkerController) { | 321 DEFINE_TRACE(DocumentMarkerController) { |
336 visitor->trace(m_spelling); | 322 visitor->trace(m_spelling); |
337 visitor->trace(m_grammar); | 323 visitor->trace(m_grammar); |
338 visitor->trace(m_textMatches); | 324 visitor->trace(m_textMatches); |
339 visitor->trace(m_compositions); | 325 visitor->trace(m_compositions); |
340 visitor->trace(m_document); | 326 visitor->trace(m_document); |
341 SynchronousMutationObserver::trace(visitor); | 327 SynchronousMutationObserver::trace(visitor); |
342 } | 328 } |
343 | 329 |
344 void DocumentMarkerController::removeMarkers( | 330 void DocumentMarkerController::removeMarkers( |
345 Node* node, | 331 Node* node, |
346 DocumentMarker::MarkerTypes markerTypes) { | 332 DocumentMarker::MarkerTypes markerTypes) { |
347 for (DocumentMarker::MarkerType type : markerTypes) { | 333 for (DocumentMarker::MarkerType type : markerTypes) { |
348 MarkerMap& markerMap = markerMapForType(type); | 334 MarkerMap& markerMap = markerMapForType(type); |
349 markerMap.erase(node); | 335 markerMap.erase(node); |
350 } | 336 } |
351 } | 337 } |
352 | 338 |
353 void DocumentMarkerController::removeMarkers( | 339 void DocumentMarkerController::removeMarkers( |
354 DocumentMarker::MarkerTypes markerTypes) { | 340 DocumentMarker::MarkerTypes markerTypes) { |
355 for (DocumentMarker::MarkerType type : markerTypes) { | 341 for (DocumentMarker::MarkerType type : markerTypes) { |
356 MarkerMap& markerMap = markerMapForType(type); | 342 MarkerMap& markerMap = markerMapForType(type); |
357 markerMap.clear(); | 343 markerMap.clear(); |
358 } | 344 } |
359 } | 345 } |
360 | 346 |
361 void DocumentMarkerController::removeMarkers( | 347 void DocumentMarkerController::removeSpellingMarkersForWords( |
362 const MarkerRemoverPredicate& shouldRemoveMarker) { | 348 const Vector<String>& words) { |
363 for (auto& nodeMarkers : m_spelling) { | 349 for (auto& nodeMarkers : m_spelling) { |
364 const Node& node = *nodeMarkers.key; | 350 const Node& node = *nodeMarkers.key; |
365 if (!node.isTextNode()) | 351 if (!node.isTextNode()) |
366 continue; | 352 continue; |
367 toSpellCheckMarkerList(nodeMarkers.value.get()) | 353 toSpellCheckMarkerList(nodeMarkers.value.get()) |
368 ->removeMarkersForWords(static_cast<const Text&>(node).data(), | 354 ->removeMarkersForWords(static_cast<const Text&>(node).data(), words); |
369 shouldRemoveMarker.m_words); | |
370 } | 355 } |
371 } | 356 } |
372 | 357 |
373 void DocumentMarkerController::repaintMarkers( | 358 void DocumentMarkerController::repaintMarkers( |
374 DocumentMarker::MarkerTypes markerTypes) { | 359 DocumentMarker::MarkerTypes markerTypes) { |
375 HeapHashSet<Member<Node>> nodesToRepaint; | 360 HeapHashSet<Member<Node>> nodesToRepaint; |
376 for (DocumentMarker::MarkerType type : markerTypes) { | 361 for (DocumentMarker::MarkerType type : markerTypes) { |
377 MarkerMap& markerMap = markerMapForType(type); | 362 MarkerMap& markerMap = markerMapForType(type); |
378 for (auto& nodeMarkers : markerMap) { | 363 for (auto& nodeMarkers : markerMap) { |
379 if (!nodeMarkers.value->empty()) | 364 if (!nodeMarkers.value->empty()) |
380 nodesToRepaint.insert(nodeMarkers.key.get()); | 365 nodesToRepaint.insert(nodeMarkers.key.get()); |
381 } | 366 } |
382 } | 367 } |
383 | 368 |
384 for (Member<Node> node : nodesToRepaint) { | 369 for (Member<Node> node : nodesToRepaint) { |
385 // cause the node to be redrawn | 370 // cause the node to be redrawn |
386 if (LayoutObject* layoutObject = node->layoutObject()) { | 371 if (LayoutObject* layoutObject = node->layoutObject()) { |
387 layoutObject->setShouldDoFullPaintInvalidation( | 372 layoutObject->setShouldDoFullPaintInvalidation( |
388 PaintInvalidationDocumentMarkerChange); | 373 PaintInvalidationDocumentMarkerChange); |
389 break; | 374 break; |
390 } | 375 } |
391 } | 376 } |
392 } | 377 } |
393 | 378 |
394 bool DocumentMarkerController::setMarkersActive(const EphemeralRange& range, | 379 bool DocumentMarkerController::setTextMatchMarkersActive( |
395 bool active) { | 380 const EphemeralRange& range, |
| 381 bool active) { |
396 Node* const startContainer = range.startPosition().computeContainerNode(); | 382 Node* const startContainer = range.startPosition().computeContainerNode(); |
397 DCHECK(startContainer); | 383 DCHECK(startContainer); |
398 Node* const endContainer = range.endPosition().computeContainerNode(); | 384 Node* const endContainer = range.endPosition().computeContainerNode(); |
399 DCHECK(endContainer); | 385 DCHECK(endContainer); |
400 | 386 |
401 const unsigned containerStartOffset = | 387 const unsigned containerStartOffset = |
402 range.startPosition().computeOffsetInContainerNode(); | 388 range.startPosition().computeOffsetInContainerNode(); |
403 const unsigned containerEndOffset = | 389 const unsigned containerEndOffset = |
404 range.endPosition().computeOffsetInContainerNode(); | 390 range.endPosition().computeOffsetInContainerNode(); |
405 | 391 |
406 bool markerFound = false; | 392 bool markerFound = false; |
407 for (Node& node : range.nodes()) { | 393 for (Node& node : range.nodes()) { |
408 int startOffset = node == startContainer ? containerStartOffset : 0; | 394 int startOffset = node == startContainer ? containerStartOffset : 0; |
409 int endOffset = node == endContainer ? containerEndOffset : INT_MAX; | 395 int endOffset = node == endContainer ? containerEndOffset : INT_MAX; |
410 markerFound |= setMarkersActive(&node, startOffset, endOffset, active); | 396 markerFound |= |
| 397 setTextMatchMarkersActive(&node, startOffset, endOffset, active); |
411 } | 398 } |
412 return markerFound; | 399 return markerFound; |
413 } | 400 } |
414 | 401 |
415 bool DocumentMarkerController::hasMarkers(Node* node) const { | 402 bool DocumentMarkerController::hasMarkers(Node* node) const { |
416 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { | 403 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
417 const MarkerMap& markerMap = markerMapForType(type); | 404 const MarkerMap& markerMap = markerMapForType(type); |
418 if (markerMap.contains(node)) | 405 if (markerMap.contains(node)) |
419 return true; | 406 return true; |
420 } | 407 } |
421 | 408 |
422 return false; | 409 return false; |
423 } | 410 } |
424 | 411 |
425 bool DocumentMarkerController::setMarkersActive(Node* node, | 412 bool DocumentMarkerController::setTextMatchMarkersActive(Node* node, |
426 unsigned startOffset, | 413 unsigned startOffset, |
427 unsigned endOffset, | 414 unsigned endOffset, |
428 bool active) { | 415 bool active) { |
429 bool docDirty = false; | 416 bool docDirty = false; |
430 if (m_textMatches.contains(node)) { | 417 if (m_textMatches.contains(node)) { |
431 docDirty = toTextMatchMarkerList(m_textMatches.at(node)) | 418 docDirty = toTextMatchMarkerList(m_textMatches.at(node)) |
432 ->setTextMatchMarkersActive(startOffset, endOffset, active); | 419 ->setTextMatchMarkersActive(startOffset, endOffset, active); |
433 } | 420 } |
434 | 421 |
435 if (docDirty && node->layoutObject()) | 422 if (docDirty && node->layoutObject()) |
436 node->layoutObject()->setShouldDoFullPaintInvalidation( | 423 node->layoutObject()->setShouldDoFullPaintInvalidation( |
437 PaintInvalidationDocumentMarkerChange); | 424 PaintInvalidationDocumentMarkerChange); |
438 | 425 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 auto it = markerMap.find(node); | 568 auto it = markerMap.find(node); |
582 if (it != markerMap.end()) { | 569 if (it != markerMap.end()) { |
583 didShiftMarker = | 570 didShiftMarker = |
584 (it->value->shiftMarkers(offset, oldLength, newLength) == | 571 (it->value->shiftMarkers(offset, oldLength, newLength) == |
585 DocumentMarkerList::DidShiftMarkerOrNot::DidShiftMarker) || | 572 DocumentMarkerList::DidShiftMarkerOrNot::DidShiftMarker) || |
586 didShiftMarker; | 573 didShiftMarker; |
587 } | 574 } |
588 } | 575 } |
589 | 576 |
590 if (didShiftMarker) { | 577 if (didShiftMarker) { |
591 invalidateRectsForMarkersInNode(*node); | 578 invalidateRectsForTextMatchMarkersInNode(*node); |
592 // repaint the affected node | 579 // repaint the affected node |
593 if (node->layoutObject()) { | 580 if (node->layoutObject()) { |
594 node->layoutObject()->setShouldDoFullPaintInvalidation( | 581 node->layoutObject()->setShouldDoFullPaintInvalidation( |
595 PaintInvalidationDocumentMarkerChange); | 582 PaintInvalidationDocumentMarkerChange); |
596 } | 583 } |
597 } | 584 } |
598 } | 585 } |
599 | 586 |
600 } // namespace blink | 587 } // namespace blink |
601 | 588 |
602 #ifndef NDEBUG | 589 #ifndef NDEBUG |
603 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { | 590 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { |
604 if (controller) | 591 if (controller) |
605 controller->showMarkers(); | 592 controller->showMarkers(); |
606 } | 593 } |
607 #endif | 594 #endif |
OLD | NEW |