OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } // anonymous namespace | 118 } // anonymous namespace |
119 | 119 |
120 InputMethodController* InputMethodController::create(LocalFrame& frame) | 120 InputMethodController* InputMethodController::create(LocalFrame& frame) |
121 { | 121 { |
122 return new InputMethodController(frame); | 122 return new InputMethodController(frame); |
123 } | 123 } |
124 | 124 |
125 InputMethodController::InputMethodController(LocalFrame& frame) | 125 InputMethodController::InputMethodController(LocalFrame& frame) |
126 : m_frame(&frame) | 126 : m_frame(&frame) |
127 , m_isDirty(false) | 127 , m_isDirty(false) |
128 , m_hasComposition(false) | |
129 { | 128 { |
130 } | 129 } |
131 | 130 |
132 bool InputMethodController::hasComposition() const | 131 bool InputMethodController::hasComposition() const |
133 { | 132 { |
134 return m_hasComposition; | 133 return m_compositionRange && !m_compositionRange->collapsed(); |
135 } | 134 } |
136 | 135 |
137 inline Editor& InputMethodController::editor() const | 136 inline Editor& InputMethodController::editor() const |
138 { | 137 { |
139 return frame().editor(); | 138 return frame().editor(); |
140 } | 139 } |
141 | 140 |
142 void InputMethodController::clear() | 141 void InputMethodController::clear() |
143 { | 142 { |
144 m_hasComposition = false; | |
145 if (m_compositionRange) { | 143 if (m_compositionRange) { |
146 m_compositionRange->setStart(frame().document(), 0); | 144 m_compositionRange->setStart(frame().document(), 0); |
147 m_compositionRange->collapse(true); | 145 m_compositionRange->collapse(true); |
148 } | 146 } |
149 frame().document()->markers().removeMarkers(DocumentMarker::Composition); | 147 frame().document()->markers().removeMarkers(DocumentMarker::Composition); |
150 m_isDirty = false; | 148 m_isDirty = false; |
151 } | 149 } |
152 | 150 |
153 void InputMethodController::documentDetached() | 151 void InputMethodController::documentDetached() |
154 { | 152 { |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 return; | 312 return; |
315 | 313 |
316 // An open typing command that disagrees about current selection would cause | 314 // An open typing command that disagrees about current selection would cause |
317 // issues with typing later on. | 315 // issues with typing later on. |
318 TypingCommand::closeTyping(m_frame); | 316 TypingCommand::closeTyping(m_frame); |
319 | 317 |
320 // No DOM update after 'compositionend'. | 318 // No DOM update after 'compositionend'. |
321 dispatchCompositionEndEvent(frame(), emptyString()); | 319 dispatchCompositionEndEvent(frame(), emptyString()); |
322 } | 320 } |
323 | 321 |
324 void InputMethodController::cancelCompositionIfSelectionIsInvalid() | |
325 { | |
326 if (!hasComposition() || editor().preventRevealSelection()) | |
327 return; | |
328 | |
329 // Check if selection start and selection end are valid. | |
330 FrameSelection& selection = frame().selection(); | |
331 if (!selection.isNone() && !m_compositionRange->collapsed()) { | |
332 if (selection.start().compareTo(m_compositionRange->startPosition()) >=
0 | |
333 && selection.end().compareTo(m_compositionRange->endPosition()) <= 0
) | |
334 return; | |
335 } | |
336 | |
337 cancelComposition(); | |
338 frame().chromeClient().didCancelCompositionOnSelectionChange(); | |
339 } | |
340 | |
341 void InputMethodController::setComposition(const String& text, const Vector<Comp
ositionUnderline>& underlines, int selectionStart, int selectionEnd) | 322 void InputMethodController::setComposition(const String& text, const Vector<Comp
ositionUnderline>& underlines, int selectionStart, int selectionEnd) |
342 { | 323 { |
343 Editor::RevealSelectionScope revealSelectionScope(&editor()); | 324 Editor::RevealSelectionScope revealSelectionScope(&editor()); |
344 | 325 |
345 // Updates styles before setting selection for composition to prevent | 326 // Updates styles before setting selection for composition to prevent |
346 // inserting the previous composition text into text nodes oddly. | 327 // inserting the previous composition text into text nodes oddly. |
347 // See https://bugs.webkit.org/show_bug.cgi?id=46868 | 328 // See https://bugs.webkit.org/show_bug.cgi?id=46868 |
348 frame().document()->updateStyleAndLayoutTree(); | 329 frame().document()->updateStyleAndLayoutTree(); |
349 | 330 |
350 selectComposition(); | 331 selectComposition(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 Node* extentNode = extent.anchorNode(); | 410 Node* extentNode = extent.anchorNode(); |
430 if (baseNode != extentNode) | 411 if (baseNode != extentNode) |
431 return; | 412 return; |
432 | 413 |
433 unsigned extentOffset = extent.computeOffsetInContainerNode(); | 414 unsigned extentOffset = extent.computeOffsetInContainerNode(); |
434 unsigned baseOffset = base.computeOffsetInContainerNode(); | 415 unsigned baseOffset = base.computeOffsetInContainerNode(); |
435 if (baseOffset + text.length() != extentOffset) | 416 if (baseOffset + text.length() != extentOffset) |
436 return; | 417 return; |
437 | 418 |
438 m_isDirty = true; | 419 m_isDirty = true; |
439 m_hasComposition = true; | |
440 if (!m_compositionRange) | 420 if (!m_compositionRange) |
441 m_compositionRange = Range::create(baseNode->document()); | 421 m_compositionRange = Range::create(baseNode->document()); |
442 m_compositionRange->setStart(baseNode, baseOffset); | 422 m_compositionRange->setStart(baseNode, baseOffset); |
443 m_compositionRange->setEnd(baseNode, extentOffset); | 423 m_compositionRange->setEnd(baseNode, extentOffset); |
444 | 424 |
445 if (baseNode->layoutObject()) | 425 if (baseNode->layoutObject()) |
446 baseNode->layoutObject()->setShouldDoFullPaintInvalidation(); | 426 baseNode->layoutObject()->setShouldDoFullPaintInvalidation(); |
447 | 427 |
448 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 428 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
449 // needs to be audited. see http://crbug.com/590369 for more details. | 429 // needs to be audited. see http://crbug.com/590369 for more details. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 | 470 |
491 for (const auto& underline : underlines) { | 471 for (const auto& underline : underlines) { |
492 unsigned underlineStart = compositionStart + underline.startOffset(); | 472 unsigned underlineStart = compositionStart + underline.startOffset(); |
493 unsigned underlineEnd = compositionStart + underline.endOffset(); | 473 unsigned underlineEnd = compositionStart + underline.endOffset(); |
494 EphemeralRange ephemeralLineRange = PlainTextRange(underlineStart, under
lineEnd).createRange(*editable); | 474 EphemeralRange ephemeralLineRange = PlainTextRange(underlineStart, under
lineEnd).createRange(*editable); |
495 if (ephemeralLineRange.isNull()) | 475 if (ephemeralLineRange.isNull()) |
496 continue; | 476 continue; |
497 frame().document()->markers().addCompositionMarker(ephemeralLineRange.st
artPosition(), ephemeralLineRange.endPosition(), underline.color(), underline.th
ick(), underline.backgroundColor()); | 477 frame().document()->markers().addCompositionMarker(ephemeralLineRange.st
artPosition(), ephemeralLineRange.endPosition(), underline.color(), underline.th
ick(), underline.backgroundColor()); |
498 } | 478 } |
499 | 479 |
500 m_hasComposition = true; | |
501 if (!m_compositionRange) | 480 if (!m_compositionRange) |
502 m_compositionRange = Range::create(range.document()); | 481 m_compositionRange = Range::create(range.document()); |
503 m_compositionRange->setStart(range.startPosition()); | 482 m_compositionRange->setStart(range.startPosition()); |
504 m_compositionRange->setEnd(range.endPosition()); | 483 m_compositionRange->setEnd(range.endPosition()); |
505 } | 484 } |
506 | 485 |
507 EphemeralRange InputMethodController::compositionEphemeralRange() const | 486 EphemeralRange InputMethodController::compositionEphemeralRange() const |
508 { | 487 { |
509 if (!hasComposition()) | 488 if (!hasComposition()) |
510 return EphemeralRange(); | 489 return EphemeralRange(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 TypingCommand::deleteSelection(*frame().document()); | 608 TypingCommand::deleteSelection(*frame().document()); |
630 } | 609 } |
631 | 610 |
632 DEFINE_TRACE(InputMethodController) | 611 DEFINE_TRACE(InputMethodController) |
633 { | 612 { |
634 visitor->trace(m_frame); | 613 visitor->trace(m_frame); |
635 visitor->trace(m_compositionRange); | 614 visitor->trace(m_compositionRange); |
636 } | 615 } |
637 | 616 |
638 } // namespace blink | 617 } // namespace blink |
OLD | NEW |