| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "core/dom/Node.h" | 29 #include "core/dom/Node.h" |
| 30 #include "core/editing/markers/DocumentMarkerController.h" | 30 #include "core/editing/markers/DocumentMarkerController.h" |
| 31 #include "core/editing/spellcheck/SpellChecker.h" | 31 #include "core/editing/spellcheck/SpellChecker.h" |
| 32 #include "core/frame/LocalFrame.h" | 32 #include "core/frame/LocalFrame.h" |
| 33 #include "core/frame/Settings.h" | 33 #include "core/frame/Settings.h" |
| 34 #include "platform/text/TextCheckerClient.h" | 34 #include "platform/text/TextCheckerClient.h" |
| 35 | 35 |
| 36 namespace blink { | 36 namespace blink { |
| 37 | 37 |
| 38 SpellCheckRequest::SpellCheckRequest( | 38 SpellCheckRequest::SpellCheckRequest( |
| 39 PassRefPtrWillBeRawPtr<Range> checkingRange, | 39 RawPtr<Range> checkingRange, |
| 40 PassRefPtrWillBeRawPtr<Range> paragraphRange, | 40 RawPtr<Range> paragraphRange, |
| 41 const String& text, | 41 const String& text, |
| 42 TextCheckingTypeMask mask, | 42 TextCheckingTypeMask mask, |
| 43 TextCheckingProcessType processType, | 43 TextCheckingProcessType processType, |
| 44 const Vector<uint32_t>& documentMarkersInRange, | 44 const Vector<uint32_t>& documentMarkersInRange, |
| 45 const Vector<unsigned>& documentMarkerOffsets, | 45 const Vector<unsigned>& documentMarkerOffsets, |
| 46 int requestNumber) | 46 int requestNumber) |
| 47 : m_requester(nullptr) | 47 : m_requester(nullptr) |
| 48 , m_checkingRange(checkingRange) | 48 , m_checkingRange(checkingRange) |
| 49 , m_paragraphRange(paragraphRange) | 49 , m_paragraphRange(paragraphRange) |
| 50 , m_rootEditableElement(m_checkingRange->startContainer()->rootEditableEleme
nt()) | 50 , m_rootEditableElement(m_checkingRange->startContainer()->rootEditableEleme
nt()) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 73 | 73 |
| 74 void SpellCheckRequest::dispose() | 74 void SpellCheckRequest::dispose() |
| 75 { | 75 { |
| 76 if (m_checkingRange) | 76 if (m_checkingRange) |
| 77 m_checkingRange->dispose(); | 77 m_checkingRange->dispose(); |
| 78 if (m_paragraphRange && m_paragraphRange != m_checkingRange) | 78 if (m_paragraphRange && m_paragraphRange != m_checkingRange) |
| 79 m_paragraphRange->dispose(); | 79 m_paragraphRange->dispose(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 // static | 82 // static |
| 83 PassRefPtrWillBeRawPtr<SpellCheckRequest> SpellCheckRequest::create(TextChecking
TypeMask textCheckingOptions, TextCheckingProcessType processType, const Ephemer
alRange& checkingRange, const EphemeralRange& paragraphRange, int requestNumber) | 83 RawPtr<SpellCheckRequest> SpellCheckRequest::create(TextCheckingTypeMask textChe
ckingOptions, TextCheckingProcessType processType, const EphemeralRange& checkin
gRange, const EphemeralRange& paragraphRange, int requestNumber) |
| 84 { | 84 { |
| 85 if (checkingRange.isNull()) | 85 if (checkingRange.isNull()) |
| 86 return nullptr; | 86 return nullptr; |
| 87 if (!checkingRange.startPosition().computeContainerNode()->rootEditableEleme
nt()) | 87 if (!checkingRange.startPosition().computeContainerNode()->rootEditableEleme
nt()) |
| 88 return nullptr; | 88 return nullptr; |
| 89 | 89 |
| 90 String text = plainText(checkingRange, TextIteratorEmitsObjectReplacementCha
racter); | 90 String text = plainText(checkingRange, TextIteratorEmitsObjectReplacementCha
racter); |
| 91 if (text.isEmpty()) | 91 if (text.isEmpty()) |
| 92 return nullptr; | 92 return nullptr; |
| 93 | 93 |
| 94 RefPtrWillBeRawPtr<Range> checkingRangeObject = createRange(checkingRange); | 94 RawPtr<Range> checkingRangeObject = createRange(checkingRange); |
| 95 RefPtrWillBeRawPtr<Range> paragraphRangeObject = nullptr; | 95 RawPtr<Range> paragraphRangeObject = nullptr; |
| 96 // Share identical Range objects. | 96 // Share identical Range objects. |
| 97 if (checkingRange == paragraphRange) | 97 if (checkingRange == paragraphRange) |
| 98 paragraphRangeObject = checkingRangeObject; | 98 paragraphRangeObject = checkingRangeObject; |
| 99 else | 99 else |
| 100 paragraphRangeObject = createRange(paragraphRange); | 100 paragraphRangeObject = createRange(paragraphRange); |
| 101 | 101 |
| 102 const DocumentMarkerVector& markers = checkingRangeObject->ownerDocument().m
arkers().markersInRange(checkingRange, DocumentMarker::SpellCheckClientMarkers()
); | 102 const DocumentMarkerVector& markers = checkingRangeObject->ownerDocument().m
arkers().markersInRange(checkingRange, DocumentMarker::SpellCheckClientMarkers()
); |
| 103 Vector<uint32_t> hashes(markers.size()); | 103 Vector<uint32_t> hashes(markers.size()); |
| 104 Vector<unsigned> offsets(markers.size()); | 104 Vector<unsigned> offsets(markers.size()); |
| 105 for (size_t i = 0; i < markers.size(); ++i) { | 105 for (size_t i = 0; i < markers.size(); ++i) { |
| 106 hashes[i] = markers[i]->hash(); | 106 hashes[i] = markers[i]->hash(); |
| 107 offsets[i] = markers[i]->startOffset(); | 107 offsets[i] = markers[i]->startOffset(); |
| 108 } | 108 } |
| 109 | 109 |
| 110 return adoptRefWillBeNoop(new SpellCheckRequest(checkingRangeObject, paragra
phRangeObject, text, textCheckingOptions, processType, hashes, offsets, requestN
umber)); | 110 return (new SpellCheckRequest(checkingRangeObject, paragraphRangeObject, tex
t, textCheckingOptions, processType, hashes, offsets, requestNumber)); |
| 111 } | 111 } |
| 112 | 112 |
| 113 const TextCheckingRequestData& SpellCheckRequest::data() const | 113 const TextCheckingRequestData& SpellCheckRequest::data() const |
| 114 { | 114 { |
| 115 return m_requestData; | 115 return m_requestData; |
| 116 } | 116 } |
| 117 | 117 |
| 118 bool SpellCheckRequest::isValid() const | 118 bool SpellCheckRequest::isValid() const |
| 119 { | 119 { |
| 120 return m_checkingRange->inDocument() && m_paragraphRange->inDocument() && m_
rootEditableElement->inDocument(); | 120 return m_checkingRange->inDocument() && m_paragraphRange->inDocument() && m_
rootEditableElement->inDocument(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 bool SpellCheckRequester::isCheckable(Range* range) const | 193 bool SpellCheckRequester::isCheckable(Range* range) const |
| 194 { | 194 { |
| 195 if (!range || !range->firstNode() || !range->firstNode()->layoutObject()) | 195 if (!range || !range->firstNode() || !range->firstNode()->layoutObject()) |
| 196 return false; | 196 return false; |
| 197 const Node* node = range->startContainer(); | 197 const Node* node = range->startContainer(); |
| 198 if (node && node->isElementNode() && !toElement(node)->isSpellCheckingEnable
d()) | 198 if (node && node->isElementNode() && !toElement(node)->isSpellCheckingEnable
d()) |
| 199 return false; | 199 return false; |
| 200 return true; | 200 return true; |
| 201 } | 201 } |
| 202 | 202 |
| 203 void SpellCheckRequester::requestCheckingFor(PassRefPtrWillBeRawPtr<SpellCheckRe
quest> request) | 203 void SpellCheckRequester::requestCheckingFor(RawPtr<SpellCheckRequest> request) |
| 204 { | 204 { |
| 205 if (!request || !canCheckAsynchronously(request->paragraphRange().get())) | 205 if (!request || !canCheckAsynchronously(request->paragraphRange().get())) |
| 206 return; | 206 return; |
| 207 | 207 |
| 208 ASSERT(request->data().sequence() == unrequestedTextCheckingSequence); | 208 ASSERT(request->data().sequence() == unrequestedTextCheckingSequence); |
| 209 int sequence = ++m_lastRequestSequence; | 209 int sequence = ++m_lastRequestSequence; |
| 210 if (sequence == unrequestedTextCheckingSequence) | 210 if (sequence == unrequestedTextCheckingSequence) |
| 211 sequence = ++m_lastRequestSequence; | 211 sequence = ++m_lastRequestSequence; |
| 212 | 212 |
| 213 request->setCheckerAndSequence(this, sequence); | 213 request->setCheckerAndSequence(this, sequence); |
| 214 | 214 |
| 215 if (m_timerToProcessQueuedRequest.isActive() || m_processingRequest) { | 215 if (m_timerToProcessQueuedRequest.isActive() || m_processingRequest) { |
| 216 enqueueRequest(request); | 216 enqueueRequest(request); |
| 217 return; | 217 return; |
| 218 } | 218 } |
| 219 | 219 |
| 220 invokeRequest(request); | 220 invokeRequest(request); |
| 221 } | 221 } |
| 222 | 222 |
| 223 void SpellCheckRequester::cancelCheck() | 223 void SpellCheckRequester::cancelCheck() |
| 224 { | 224 { |
| 225 if (m_processingRequest) | 225 if (m_processingRequest) |
| 226 m_processingRequest->didCancel(); | 226 m_processingRequest->didCancel(); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void SpellCheckRequester::invokeRequest(PassRefPtrWillBeRawPtr<SpellCheckRequest
> request) | 229 void SpellCheckRequester::invokeRequest(RawPtr<SpellCheckRequest> request) |
| 230 { | 230 { |
| 231 ASSERT(!m_processingRequest); | 231 ASSERT(!m_processingRequest); |
| 232 m_processingRequest = request; | 232 m_processingRequest = request; |
| 233 client().requestCheckingOfString(m_processingRequest); | 233 client().requestCheckingOfString(m_processingRequest); |
| 234 } | 234 } |
| 235 | 235 |
| 236 void SpellCheckRequester::clearProcessingRequest() | 236 void SpellCheckRequester::clearProcessingRequest() |
| 237 { | 237 { |
| 238 if (!m_processingRequest) | 238 if (!m_processingRequest) |
| 239 return; | 239 return; |
| 240 | 240 |
| 241 m_processingRequest->dispose(); | 241 m_processingRequest->dispose(); |
| 242 m_processingRequest.clear(); | 242 m_processingRequest.clear(); |
| 243 } | 243 } |
| 244 | 244 |
| 245 void SpellCheckRequester::enqueueRequest(PassRefPtrWillBeRawPtr<SpellCheckReques
t> request) | 245 void SpellCheckRequester::enqueueRequest(RawPtr<SpellCheckRequest> request) |
| 246 { | 246 { |
| 247 ASSERT(request); | 247 ASSERT(request); |
| 248 bool continuation = false; | 248 bool continuation = false; |
| 249 if (!m_requestQueue.isEmpty()) { | 249 if (!m_requestQueue.isEmpty()) { |
| 250 RefPtrWillBeRawPtr<SpellCheckRequest> lastRequest = m_requestQueue.last(
); | 250 RawPtr<SpellCheckRequest> lastRequest = m_requestQueue.last(); |
| 251 // It's a continuation if the number of the last request got incremented
in the new one and | 251 // It's a continuation if the number of the last request got incremented
in the new one and |
| 252 // both apply to the same editable. | 252 // both apply to the same editable. |
| 253 continuation = request->rootEditableElement() == lastRequest->rootEditab
leElement() | 253 continuation = request->rootEditableElement() == lastRequest->rootEditab
leElement() |
| 254 && request->requestNumber() == lastRequest->requestNumber() + 1; | 254 && request->requestNumber() == lastRequest->requestNumber() + 1; |
| 255 } | 255 } |
| 256 | 256 |
| 257 // Spellcheck requests for chunks of text in the same element should not ove
rwrite each other. | 257 // Spellcheck requests for chunks of text in the same element should not ove
rwrite each other. |
| 258 if (!continuation) { | 258 if (!continuation) { |
| 259 for (auto& requestQueue : m_requestQueue) { | 259 for (auto& requestQueue : m_requestQueue) { |
| 260 if (request->rootEditableElement() != requestQueue->rootEditableElem
ent()) | 260 if (request->rootEditableElement() != requestQueue->rootEditableElem
ent()) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 290 void SpellCheckRequester::didCheckSucceed(int sequence, const Vector<TextCheckin
gResult>& results) | 290 void SpellCheckRequester::didCheckSucceed(int sequence, const Vector<TextCheckin
gResult>& results) |
| 291 { | 291 { |
| 292 TextCheckingRequestData requestData = m_processingRequest->data(); | 292 TextCheckingRequestData requestData = m_processingRequest->data(); |
| 293 if (requestData.sequence() == sequence) { | 293 if (requestData.sequence() == sequence) { |
| 294 DocumentMarker::MarkerTypes markers = DocumentMarker::SpellCheckClientMa
rkers(); | 294 DocumentMarker::MarkerTypes markers = DocumentMarker::SpellCheckClientMa
rkers(); |
| 295 if (!requestData.maskContains(TextCheckingTypeSpelling)) | 295 if (!requestData.maskContains(TextCheckingTypeSpelling)) |
| 296 markers.remove(DocumentMarker::Spelling); | 296 markers.remove(DocumentMarker::Spelling); |
| 297 if (!requestData.maskContains(TextCheckingTypeGrammar)) | 297 if (!requestData.maskContains(TextCheckingTypeGrammar)) |
| 298 markers.remove(DocumentMarker::Grammar); | 298 markers.remove(DocumentMarker::Grammar); |
| 299 if (m_processingRequest->isValid()) { | 299 if (m_processingRequest->isValid()) { |
| 300 RefPtrWillBeRawPtr<Range> checkingRange = m_processingRequest->check
ingRange(); | 300 RawPtr<Range> checkingRange = m_processingRequest->checkingRange(); |
| 301 frame().document()->markers().removeMarkers(EphemeralRange(checkingR
ange.get()), markers); | 301 frame().document()->markers().removeMarkers(EphemeralRange(checkingR
ange.get()), markers); |
| 302 } | 302 } |
| 303 } | 303 } |
| 304 didCheck(sequence, results); | 304 didCheck(sequence, results); |
| 305 } | 305 } |
| 306 | 306 |
| 307 void SpellCheckRequester::didCheckCancel(int sequence) | 307 void SpellCheckRequester::didCheckCancel(int sequence) |
| 308 { | 308 { |
| 309 Vector<TextCheckingResult> results; | 309 Vector<TextCheckingResult> results; |
| 310 didCheck(sequence, results); | 310 didCheck(sequence, results); |
| 311 } | 311 } |
| 312 | 312 |
| 313 DEFINE_TRACE(SpellCheckRequester) | 313 DEFINE_TRACE(SpellCheckRequester) |
| 314 { | 314 { |
| 315 visitor->trace(m_frame); | 315 visitor->trace(m_frame); |
| 316 visitor->trace(m_processingRequest); | 316 visitor->trace(m_processingRequest); |
| 317 visitor->trace(m_requestQueue); | 317 visitor->trace(m_requestQueue); |
| 318 } | 318 } |
| 319 | 319 |
| 320 } // namespace blink | 320 } // namespace blink |
| OLD | NEW |