1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004-2019 Apple Inc. All rights reserved.
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 *
25 */
26
27#pragma once
28
29#include "DocumentMarker.h"
30#include <memory>
31#include <wtf/HashMap.h>
32#include <wtf/Vector.h>
33
34namespace WebCore {
35
36class Document;
37class LayoutPoint;
38class LayoutRect;
39class Node;
40class Range;
41class RenderedDocumentMarker;
42
43class DocumentMarkerController {
44 WTF_MAKE_NONCOPYABLE(DocumentMarkerController); WTF_MAKE_FAST_ALLOCATED;
45public:
46
47 DocumentMarkerController(Document&);
48 ~DocumentMarkerController();
49
50 void detach();
51 WEBCORE_EXPORT void addMarker(Range&, DocumentMarker::MarkerType);
52 WEBCORE_EXPORT void addMarker(Range&, DocumentMarker::MarkerType, const String& description);
53 void addMarkerToNode(Node&, unsigned startOffset, unsigned length, DocumentMarker::MarkerType);
54 void addMarkerToNode(Node&, unsigned startOffset, unsigned length, DocumentMarker::MarkerType, DocumentMarker::Data&&);
55 WEBCORE_EXPORT void addTextMatchMarker(const Range&, bool activeMatch);
56#if PLATFORM(IOS_FAMILY)
57 void addMarker(Range&, DocumentMarker::MarkerType, const String& description, const Vector<String>& interpretations, const RetainPtr<id>& metadata);
58 void addDictationPhraseWithAlternativesMarker(Range&, const Vector<String>& interpretations);
59 void addDictationResultMarker(Range&, const RetainPtr<id>& metadata);
60#endif
61 void addDraggedContentMarker(Range&);
62
63#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
64 WEBCORE_EXPORT void addPlatformTextCheckingMarker(Range&, const String& key, const String& value);
65#endif
66
67 void copyMarkers(Node& srcNode, unsigned startOffset, int length, Node& dstNode, int delta);
68 bool hasMarkers() const
69 {
70 ASSERT(m_markers.isEmpty() == !m_possiblyExistingMarkerTypes.containsAny(DocumentMarker::allMarkers()));
71 return !m_markers.isEmpty();
72 }
73 bool hasMarkers(Range&, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
74
75 // When a marker partially overlaps with range, if removePartiallyOverlappingMarkers is true, we completely
76 // remove the marker. If the argument is false, we will adjust the span of the marker so that it retains
77 // the portion that is outside of the range.
78 enum RemovePartiallyOverlappingMarkerOrNot { DoNotRemovePartiallyOverlappingMarker, RemovePartiallyOverlappingMarker };
79 WEBCORE_EXPORT void removeMarkers(Range&, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
80 void removeMarkers(Node&, unsigned startOffset, int length, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), std::function<bool(DocumentMarker*)> filterFunction = nullptr, RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
81
82 // Return false from filterFunction to remove the marker.
83 WEBCORE_EXPORT void filterMarkers(Range&, std::function<bool(DocumentMarker*)> filterFunction, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
84
85 WEBCORE_EXPORT void removeMarkers(OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
86 void removeMarkers(Node&, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
87 void repaintMarkers(OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
88 void shiftMarkers(Node&, unsigned startOffset, int delta);
89 void setMarkersActive(Range&, bool);
90 void setMarkersActive(Node&, unsigned startOffset, unsigned endOffset, bool);
91
92 WEBCORE_EXPORT Vector<RenderedDocumentMarker*> markersFor(Node&, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
93 WEBCORE_EXPORT Vector<RenderedDocumentMarker*> markersInRange(Range&, OptionSet<DocumentMarker::MarkerType>);
94 void clearDescriptionOnMarkersIntersectingRange(Range&, OptionSet<DocumentMarker::MarkerType>);
95
96 WEBCORE_EXPORT void updateRectsForInvalidatedMarkersOfType(DocumentMarker::MarkerType);
97
98 void invalidateRectsForAllMarkers();
99 void invalidateRectsForMarkersInNode(Node&);
100
101 DocumentMarker* markerContainingPoint(const LayoutPoint&, DocumentMarker::MarkerType);
102 WEBCORE_EXPORT Vector<FloatRect> renderedRectsForMarkers(DocumentMarker::MarkerType);
103
104#if ENABLE(TREE_DEBUGGING)
105 void showMarkers() const;
106#endif
107
108private:
109 void addMarker(Node&, const DocumentMarker&);
110
111 typedef Vector<RenderedDocumentMarker> MarkerList;
112 typedef HashMap<RefPtr<Node>, std::unique_ptr<MarkerList>> MarkerMap;
113 bool possiblyHasMarkers(OptionSet<DocumentMarker::MarkerType>);
114 void removeMarkersFromList(MarkerMap::iterator, OptionSet<DocumentMarker::MarkerType>);
115
116 MarkerMap m_markers;
117 // Provide a quick way to determine whether a particular marker type is absent without going through the map.
118 OptionSet<DocumentMarker::MarkerType> m_possiblyExistingMarkerTypes;
119 Document& m_document;
120};
121
122} // namespace WebCore
123
124#if ENABLE(TREE_DEBUGGING)
125void showDocumentMarkers(const WebCore::DocumentMarkerController*);
126#endif
127