Changeset 25547 in webkit
- Timestamp:
- Sep 13, 2007, 4:03:57 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r25545 r25547 1 2007-09-13 Darin Adler <darin@apple.com> 2 3 Reviewed by Oliver. 4 5 - updated test results changed by change in input manager logic 6 7 * platform/mac/editing/input/firstrectforcharacterrange-styled-expected.txt: 8 * platform/mac/editing/input/text-input-controller-expected.txt: 9 * platform/mac/editing/input/wrapped-line-char-rect-expected.txt: 10 Updated. Small changes in which delegate methods are called. 11 1 12 2007-09-13 Kevin McCullough <kmccullough@apple.com> 2 13 3 Reviewed by Geof , Sam, Adam, Hyatt, Darin.14 Reviewed by Geoff, Sam, Adam, Hyatt, Darin. 4 15 5 16 - <rdar://problem/5480234> JS setTimeout function requires a second argument -
trunk/LayoutTests/platform/mac/editing/input/firstrectforcharacterrange-styled-expected.txt
r25367 r25547 2 2 EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification 3 3 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 4 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 4 5 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > I > B > BODY > HTML > #document to 1 of #text > I > B > BODY > HTML > #document toDOMRange:range from 1 of #text > I > B > BODY > HTML > #document to 3 of #text > I > B > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 5 6 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -
trunk/LayoutTests/platform/mac/editing/input/text-input-controller-expected.txt
r25367 r25547 15 15 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 16 16 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 17 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 17 18 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 18 19 EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 19 20 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 20 21 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 21 EDITING DELEGATE: shouldDeleteDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document22 22 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 23 23 EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE … … 28 28 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 29 29 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 30 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 30 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 31 EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 32 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 33 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 34 EDITING DELEGATE: shouldInsertText:Success replacingDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped 35 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 36 EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 7 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 37 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 38 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 39 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 40 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 31 41 Success -
trunk/LayoutTests/platform/mac/editing/input/wrapped-line-char-rect-expected.txt
r25367 r25547 2 2 EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification 3 3 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 4 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 4 5 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of P > BODY > HTML > #document to 0 of P > BODY > HTML > #document toDOMRange:range from 0 of #text > P > BODY > HTML > #document to 20 of #text > P > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 5 6 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -
trunk/WebCore/ChangeLog
r25546 r25547 1 2007-09-13 Darin Adler <darin@apple.com> 2 3 Reviewed by Oliver. 4 5 - fix <rdar://problem/5470457> REGRESSION: Input method inline hole is mishandled in text 6 <input> elements with maxlength limit 7 8 * editing/Editor.h: Moved MarkedTextUnderline here and renamed it CompositionUnderline. 9 Moved the rest of the marked text API here and used the term that will be more familiar 10 to those on platforms other than Macintosh, "composition". This helps prevent confusion 11 with the other kinds of mark -- the emacs "mark" and spelling/grammar marks. Also 12 cleaned up the conditionals a bit for the Macintosh-specific parts of this header. 13 14 * editing/Editor.cpp: 15 (WebCore::Editor::Editor): Updated for name change. 16 (WebCore::Editor::clear): Added. To be called by FrameLoader::clear(). 17 (WebCore::Editor::insertTextWithoutSendingTextEvent): Removed code to make inserted 18 text replace the marked text range -- we now deal with this explicitly by not 19 calling this function to replace marked text. Also removed unneeded code that was 20 specific to the use of this to replace the marked text. 21 (WebCore::Editor::selectComposition): Renamed from selectMarkedText. Updated since 22 the composition range is not stored as a Range. 23 (WebCore::Editor::confirmComposition): Added. To be called when changing a composition 24 into actual text. Unlike the old code path, deletes the composition first, then inserts 25 the text, triggering the normal insertion code path and events. This is helpful because 26 it means the inserted text will be truncated by the <input> element, for example. 27 (WebCore::Editor::confirmCompositionWithoutDisturbingSelection): Added. 28 (WebCore::Editor::setComposition): Added. To be called when changing the composition. 29 Takes parameters for the underlines and selection. Unlike the old code path, this passes 30 a flag down that indicates the inserted text is part of a composition. This is helpful 31 because we don't send the event that will cause the <input> element to do truncation. 32 It's also a better API for future improvements to our input method handling. 33 (WebCore::Editor::revealSelectionAfterEditingOperation): Updated for name change. 34 (WebCore::Editor::setIgnoreCompositionSelectionChange): Ditto. 35 (WebCore::Editor::compositionRange): Added. Needed now that the composition is not 36 stored as a Range. 37 (WebCore::Editor::getCompositionSelection): Added. 38 39 * editing/TypingCommand.h: 40 * editing/TypingCommand.cpp: (WebCore::TypingCommand::insertText): 41 Added an insertedTextIsComposition parameter, and don't send the BeforeTextInsertedEvent 42 if it's true. 43 44 * loader/FrameLoader.cpp: (WebCore::FrameLoader::clear): Replaced the Macintosh-specific 45 call to setMarkedTextRange with a call to the new Editor::clear(). 46 47 * page/Frame.h: 48 * page/Frame.cpp: 49 * page/FramePrivate.h: 50 * page/mac/FrameMac.mm: 51 Removed the marked text code. It was streamlined and moved to Editor, except for the 52 Mac-specific code, which was moved into WebKit. 53 54 * page/mac/WebCoreFrameBridge.h: 55 * page/mac/WebCoreFrameBridge.mm: Removed some now-unneeded marked text code. 56 (-[WebCoreFrameBridge markedTextNSRange]): Updated for name/API change. 57 58 * rendering/InlineTextBox.h: 59 * rendering/InlineTextBox.cpp: 60 (WebCore::InlineTextBox::paint): Updated marked text code for name changes, and also 61 streamlined the code a bit for the case where there is no composition. 62 (WebCore::InlineTextBox::paintCompositionBackground): Name change. 63 (WebCore::InlineTextBox::paintCompositionUnderline): Ditto. 64 65 * rendering/RenderTextControl.h: 66 * rendering/RenderTextControl.cpp: 67 (WebCore::RenderTextControl::finishText): Added. Helper function shared by the 68 (WebCore::RenderTextControl::text): 69 (WebCore::getNextSoftBreak): 70 (WebCore::RenderTextControl::textWithHardLineBreaks): 71 72 * platform/CharacterNames.h: Added newlineCharacter. 73 74 * dom/Range.h: Remove the now-unneeded version of toString that converts <br> 75 elements into newlines. 76 * dom/Range.cpp: 77 (WebCore::Range::toString): Changed this to use a Vector<UChar> instead of 78 a String so it will not have pathological reallocation performance, and removed 79 the <br> feature. 80 (WebCore::Range::pastEndNode): Made this return 0 when there is no start node. 81 This bit of extra robustness guarantees you can't do a null dereference if the 82 start node is 0 and the end node is not. Not sure this case really exists. 83 84 * page/ContextMenuController.cpp: (ContextMenuController::contextMenuItemSelected): 85 Removed a semi-bogus use of Range::toString(true). The right function to use here 86 is plainText(). 87 88 * bridge/EditorClient.h: Removed obsolete markedTextAbandoned function. 89 90 * WebCore.exp: Updated for above changes. 91 1 92 2007-09-13 Anders Carlsson <andersca@apple.com> 2 93 -
trunk/WebCore/WebCore.exp
r25439 r25547 311 311 __ZN7WebCore16NavigationActionC1ERKNS_4KURLENS_14NavigationTypeE 312 312 __ZN7WebCore16NavigationActionC1Ev 313 __ZN7WebCore16colorFromNSColorEP7NSColor 313 314 __ZN7WebCore18PlatformMouseEventC1EP7NSEvent 314 315 __ZN7WebCore19InspectorController16setWindowVisibleEb … … 374 375 __ZN7WebCore5Frame20windowScriptNPObjectEv 375 376 __ZN7WebCore5Frame21setProhibitsScrollingEb 376 __ZN7WebCore5Frame23selectRangeInMarkedTextEjj377 377 __ZN7WebCore5Frame26dashboardRegionsDictionaryEv 378 378 __ZN7WebCore5Frame29cleanupScriptObjectsForPluginEPv … … 390 390 __ZN7WebCore6Editor10applyStyleEPNS_19CSSStyleDeclarationENS_10EditActionE 391 391 __ZN7WebCore6Editor10insertTextERKNS_6StringEPNS_5EventE 392 __ZN7WebCore6Editor10unmarkTextEv393 392 __ZN7WebCore6Editor11canDHTMLCutEv 394 393 __ZN7WebCore6Editor11deleteRangeEPNS_5RangeEbbbNS_18EditorDeleteActionENS_15TextGranularityE … … 401 400 __ZN7WebCore6Editor13rangeForPointERKNS_8IntPointE 402 401 __ZN7WebCore6Editor13tryDHTMLPasteEv 402 __ZN7WebCore6Editor14setCompositionERKNS_6StringERKN3WTF6VectorINS_20CompositionUnderlineELm0EEEjj 403 403 __ZN7WebCore6Editor16pasteAsPlainTextEv 404 __ZN7WebCore6Editor16selectMarkedTextEv405 __ZN7WebCore6Editor17discardMarkedTextEv406 404 __ZN7WebCore6Editor17insertOrderedListEv 407 __ZN7WebCore6Editor17replaceMarkedTextERKNS_6StringE 405 __ZN7WebCore6Editor18confirmCompositionERKNS_6StringE 406 __ZN7WebCore6Editor18confirmCompositionEv 408 407 __ZN7WebCore6Editor19deleteWithDirectionENS_19SelectionController10EDirectionENS_15TextGranularityEbb 409 408 __ZN7WebCore6Editor19insertUnorderedListEv … … 421 420 __ZN7WebCore6Editor33increaseSelectionListLevelOrderedEv 422 421 __ZN7WebCore6Editor33insertTextWithoutSendingTextEventERKNS_6StringEbPNS_5EventE 423 __ZN7WebCore6Editor34setIgnoreMarkedTextSelectionChangeEb424 422 __ZN7WebCore6Editor35increaseSelectionListLevelUnorderedEv 423 __ZN7WebCore6Editor35setIgnoreCompositionSelectionChangeEb 425 424 __ZN7WebCore6Editor3cutEv 425 __ZN7WebCore6Editor44confirmCompositionWithoutDisturbingSelectionEv 426 426 __ZN7WebCore6Editor4copyEv 427 427 __ZN7WebCore6Editor5pasteEv … … 649 649 __ZNK7WebCore6Editor17shouldDeleteRangeEPNS_5RangeE 650 650 __ZNK7WebCore6Editor22selectionStartHasStyleEPNS_19CSSStyleDeclarationE 651 __ZNK7WebCore6Editor23getCompositionSelectionERjS1_ 651 652 __ZNK7WebCore6Editor6canCutEv 652 653 __ZNK7WebCore6Editor7canCopyEv -
trunk/WebCore/bridge/EditorClient.h
r25345 r25547 120 120 121 121 #if PLATFORM(MAC) 122 virtual void markedTextAbandoned(Frame*) = 0;123 124 122 // FIXME: This should become SelectionController::toWebArchive() 125 123 virtual NSData* dataForArchivedSelection(Frame*) = 0; -
trunk/WebCore/dom/Range.cpp
r24041 r25547 1 1 /** 2 * This file is part of the DOM implementation for KDE.3 *4 2 * (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) 6 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) 7 5 * (C) 2001 Peter Kelly (pmk@post.com) 8 * Copyright (C) 2004 Apple Computer, Inc.6 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 9 7 * 10 8 * This library is free software; you can redistribute it and/or … … 42 40 namespace WebCore { 43 41 42 using namespace std; 44 43 using namespace HTMLNames; 45 44 … … 1032 1031 String Range::toString(ExceptionCode& ec) const 1033 1032 { 1034 return toString(false, ec);1035 }1036 1037 String Range::toString(bool convertBRsToNewlines, ExceptionCode& ec) const1038 {1039 1033 if (m_detached) { 1040 1034 ec = INVALID_STATE_ERR; … … 1042 1036 } 1043 1037 1044 String text = ""; 1045 Node *pastEnd = pastEndNode(); 1046 for (Node *n = startNode(); n != pastEnd; n = n->traverseNextNode()) { 1038 Vector<UChar> result; 1039 1040 Node* pastEnd = pastEndNode(); 1041 for (Node* n = startNode(); n != pastEnd; n = n->traverseNextNode()) { 1047 1042 if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) { 1048 String str = static_cast<Text *>(n)->data().copy(); 1049 if (n == m_endContainer) 1050 str.truncate(m_endOffset); 1051 if (n == m_startContainer) 1052 str.remove(0, m_startOffset); 1053 text += str; 1054 } 1055 if (n->hasTagName(brTag) && convertBRsToNewlines) 1056 text += "\n"; 1057 } 1058 return text; 1043 String data = static_cast<CharacterData*>(n)->data(); 1044 unsigned length = data.length(); 1045 unsigned start = (n == m_startContainer) ? min(m_startOffset, length) : 0; 1046 unsigned end = (n == m_endContainer) ? min(max(start, m_endOffset), length) : length; 1047 result.append(data.characters() + start, end - start); 1048 } 1049 } 1050 1051 return String::adopt(result); 1059 1052 } 1060 1053 … … 1531 1524 Node *Range::pastEndNode() const 1532 1525 { 1533 if (!m_ endContainer)1526 if (!m_startContainer || !m_endContainer) 1534 1527 return 0; 1535 1528 if (m_endContainer->offsetInCharacters()) -
trunk/WebCore/dom/Range.h
r24041 r25547 80 80 void insertNode(PassRefPtr<Node>, ExceptionCode&); 81 81 String toString(ExceptionCode&) const; 82 String toString(bool convertBRsToNewlines, ExceptionCode&) const;83 82 84 83 String toHTML() const; -
trunk/WebCore/editing/Editor.cpp
r25305 r25547 65 65 #include "SelectionController.h" 66 66 #include "Sound.h" 67 #include "Text.h" 67 68 #include "TextIterator.h" 68 69 #include "TypingCommand.h" … … 74 75 75 76 class FontData; 77 78 using namespace std; 76 79 using namespace EventNames; 77 80 using namespace HTMLNames; … … 1355 1358 : m_frame(frame) 1356 1359 , m_deleteButtonController(new DeleteButtonController(frame)) 1357 , m_ignore MarkedTextSelectionChange(false)1360 , m_ignoreCompositionSelectionChange(false) 1358 1361 { 1359 1362 } … … 1361 1364 Editor::~Editor() 1362 1365 { 1366 } 1367 1368 void Editor::clear() 1369 { 1370 m_compositionNode = 0; 1371 m_customCompositionUnderlines.clear(); 1363 1372 } 1364 1373 … … 1396 1405 return false; 1397 1406 1398 RefPtr<Range> range = m_frame->markedTextRange(); 1399 if (!range) { 1400 Selection selection = selectionForEvent(m_frame, triggeringEvent); 1401 if (!selection.isContentEditable()) 1402 return false; 1403 range = selection.toRange(); 1404 } 1405 1406 if (!shouldInsertText(text, range.get(), EditorInsertActionTyped)) { 1407 discardMarkedText(); 1407 Selection selection = selectionForEvent(m_frame, triggeringEvent); 1408 if (!selection.isContentEditable()) 1409 return false; 1410 RefPtr<Range> range = selection.toRange(); 1411 1412 if (!shouldInsertText(text, range.get(), EditorInsertActionTyped)) 1408 1413 return true; 1409 }1410 1411 setIgnoreMarkedTextSelectionChange(true);1412 1413 // If we had marked text, replace that instead of the selection/caret.1414 selectMarkedText();1415 1414 1416 1415 // Get the selection to use for the event that triggered this insertText. 1417 1416 // If the event handler changed the selection, we may want to use a different selection 1418 1417 // that is contained in the event target. 1419 Selectionselection = selectionForEvent(m_frame, triggeringEvent);1418 selection = selectionForEvent(m_frame, triggeringEvent); 1420 1419 if (selection.isContentEditable()) { 1421 1420 if (Node* selectionStart = selection.start().node()) { … … 1431 1430 } 1432 1431 } 1433 1434 setIgnoreMarkedTextSelectionChange(false);1435 1436 // Inserting unmarks any marked text.1437 unmarkText();1438 1432 1439 1433 return true; … … 1665 1659 } 1666 1660 1667 void Editor::select MarkedText()1668 { 1669 R ange* range = m_frame->markedTextRange();1661 void Editor::selectComposition() 1662 { 1663 RefPtr<Range> range = compositionRange(); 1670 1664 if (!range) 1671 1665 return; 1672 1666 ExceptionCode ec = 0; 1673 m_frame->selectionController()->setSelectedRange(m_frame->markedTextRange(), DOWNSTREAM, false, ec); 1674 } 1675 1676 void Editor::discardMarkedText() 1677 { 1678 if (!m_frame->markedTextRange()) 1679 return; 1680 1681 setIgnoreMarkedTextSelectionChange(true); 1682 1683 selectMarkedText(); 1684 unmarkText(); 1685 #if PLATFORM(MAC) 1686 if (EditorClient* c = client()) 1687 c->markedTextAbandoned(m_frame); 1688 #endif 1667 m_frame->selectionController()->setSelectedRange(range.get(), DOWNSTREAM, false, ec); 1668 } 1669 1670 void Editor::confirmComposition() 1671 { 1672 if (!m_compositionNode) 1673 return; 1674 confirmComposition(m_compositionNode->data().substring(m_compositionStart, m_compositionEnd - m_compositionStart), false); 1675 } 1676 1677 void Editor::confirmCompositionWithoutDisturbingSelection() 1678 { 1679 if (!m_compositionNode) 1680 return; 1681 confirmComposition(m_compositionNode->data().substring(m_compositionStart, m_compositionEnd - m_compositionStart), true); 1682 } 1683 1684 void Editor::confirmComposition(const String& text) 1685 { 1686 confirmComposition(text, false); 1687 } 1688 1689 void Editor::confirmComposition(const String& text, bool preserveSelection) 1690 { 1691 setIgnoreCompositionSelectionChange(true); 1692 1693 Selection oldSelection = m_frame->selectionController()->selection(); 1694 1695 selectComposition(); 1696 1697 if (m_frame->selectionController()->isNone()) { 1698 setIgnoreCompositionSelectionChange(false); 1699 return; 1700 } 1701 1689 1702 deleteSelectionWithSmartDelete(false); 1690 1703 1691 setIgnoreMarkedTextSelectionChange(false); 1692 } 1693 1694 void Editor::unmarkText() 1695 { 1696 Vector<MarkedTextUnderline> underlines; 1697 m_frame->setMarkedTextRange(0, underlines); 1698 } 1699 1700 void Editor::replaceMarkedText(const String& text) 1701 { 1702 if (m_frame->selectionController()->isNone()) 1703 return; 1704 1705 int exception = 0; 1706 1707 Range *markedTextRange = m_frame->markedTextRange(); 1708 if (markedTextRange && !markedTextRange->collapsed(exception)) 1709 TypingCommand::deleteKeyPressed(m_frame->document(), false); 1710 1711 if (!text.isEmpty()) 1712 TypingCommand::insertText(m_frame->document(), text, true); 1713 1714 revealSelectionAfterEditingOperation(); 1704 m_compositionNode = 0; 1705 m_customCompositionUnderlines.clear(); 1706 1707 insertText(text, 0); 1708 1709 if (preserveSelection) 1710 m_frame->selectionController()->setSelection(oldSelection, false, false); 1711 1712 setIgnoreCompositionSelectionChange(false); 1713 } 1714 1715 void Editor::setComposition(const String& text, const Vector<CompositionUnderline>& underlines, unsigned selectionStart, unsigned selectionEnd) 1716 { 1717 setIgnoreCompositionSelectionChange(true); 1718 1719 selectComposition(); 1720 1721 if (m_frame->selectionController()->isNone()) { 1722 setIgnoreCompositionSelectionChange(false); 1723 return; 1724 } 1725 1726 deleteSelectionWithSmartDelete(false); 1727 1728 if (!text.isEmpty()) { 1729 TypingCommand::insertText(m_frame->document(), text, true, true); 1730 1731 Node* baseNode = m_frame->selectionController()->baseNode(); 1732 unsigned baseOffset = m_frame->selectionController()->base().offset(); 1733 Node* extentNode = m_frame->selectionController()->extentNode(); 1734 unsigned extentOffset = m_frame->selectionController()->extent().offset(); 1735 1736 if (baseNode && baseNode == extentNode && baseNode->isTextNode() && baseOffset + text.length() == extentOffset) { 1737 m_compositionNode = static_cast<Text*>(baseNode); 1738 m_compositionStart = baseOffset; 1739 m_compositionEnd = extentOffset; 1740 m_customCompositionUnderlines = underlines; 1741 size_t numUnderlines = m_customCompositionUnderlines.size(); 1742 for (size_t i = 0; i < numUnderlines; ++i) { 1743 m_customCompositionUnderlines[i].startOffset += baseOffset; 1744 m_customCompositionUnderlines[i].endOffset += baseOffset; 1745 } 1746 if (baseNode->renderer()) 1747 baseNode->renderer()->repaint(); 1748 1749 unsigned start = min(baseOffset + selectionStart, extentOffset); 1750 unsigned end = min(max(start, baseOffset + selectionEnd), extentOffset); 1751 RefPtr<Range> selectedRange = new Range(baseNode->document(), baseNode, start, baseNode, end); 1752 ExceptionCode ec = 0; 1753 m_frame->selectionController()->setSelectedRange(selectedRange.get(), DOWNSTREAM, false, ec); 1754 } 1755 } 1756 1757 setIgnoreCompositionSelectionChange(false); 1715 1758 } 1716 1759 … … 2270 2313 #endif 2271 2314 } 2272 2273 2315 2274 2316 PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint) 2275 2317 { … … 2290 2332 void Editor::revealSelectionAfterEditingOperation() 2291 2333 { 2292 if (m_ignore MarkedTextSelectionChange)2334 if (m_ignoreCompositionSelectionChange) 2293 2335 return; 2294 2336 … … 2296 2338 } 2297 2339 2298 void Editor::setIgnore MarkedTextSelectionChange(bool ignore)2299 { 2300 if (m_ignore MarkedTextSelectionChange == ignore)2301 return; 2302 2303 m_ignore MarkedTextSelectionChange = ignore;2340 void Editor::setIgnoreCompositionSelectionChange(bool ignore) 2341 { 2342 if (m_ignoreCompositionSelectionChange == ignore) 2343 return; 2344 2345 m_ignoreCompositionSelectionChange = ignore; 2304 2346 if (!ignore) 2305 2347 revealSelectionAfterEditingOperation(); 2306 2348 } 2307 2349 2350 PassRefPtr<Range> Editor::compositionRange() const 2351 { 2352 if (!m_compositionNode) 2353 return 0; 2354 unsigned length = m_compositionNode->length(); 2355 unsigned start = min(m_compositionStart, length); 2356 unsigned end = min(max(start, m_compositionEnd), length); 2357 if (start >= end) 2358 return 0; 2359 return new Range(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end); 2360 } 2361 2362 bool Editor::getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const 2363 { 2364 if (!m_compositionNode) 2365 return false; 2366 Position start = m_frame->selectionController()->start(); 2367 if (start.node() != m_compositionNode) 2368 return false; 2369 Position end = m_frame->selectionController()->end(); 2370 if (end.node() != m_compositionNode) 2371 return false; 2372 2373 if (static_cast<unsigned>(start.offset()) < m_compositionStart) 2374 return false; 2375 if (static_cast<unsigned>(end.offset()) > m_compositionEnd) 2376 return false; 2377 2378 selectionStart = start.offset() - m_compositionStart; 2379 selectionEnd = start.offset() - m_compositionEnd; 2380 return true; 2381 } 2382 2308 2383 } // namespace WebCore -
trunk/WebCore/editing/Editor.h
r25027 r25547 57 57 class Selection; 58 58 59 struct CompositionUnderline { 60 CompositionUnderline() 61 : startOffset(0), endOffset(0), thick(false) { } 62 CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t) 63 : startOffset(s), endOffset(e), color(c), thick(t) { } 64 unsigned startOffset; 65 unsigned endOffset; 66 Color color; 67 bool thick; 68 }; 69 59 70 class Editor { 60 71 public: … … 194 205 bool smartInsertDeleteEnabled(); 195 206 196 void selectMarkedText(); 197 void unmarkText(); 198 void discardMarkedText(); 199 void replaceMarkedText(const String&); 200 201 bool ignoreMarkedTextSelectionChange() const { return m_ignoreMarkedTextSelectionChange; } 202 void setIgnoreMarkedTextSelectionChange(bool ignore); 207 // international text input composition 208 bool hasComposition() const { return m_compositionNode; } 209 void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd); 210 void confirmComposition(); 211 void confirmComposition(const String&); // if no existing composition, replaces selection 212 void confirmCompositionWithoutDisturbingSelection(); 213 PassRefPtr<Range> compositionRange() const; 214 bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const; 215 216 // getting international text input composition state (for use by InlineTextBox) 217 Text* compositionNode() const { return m_compositionNode.get(); } 218 unsigned compositionStart() const { return m_compositionStart; } 219 unsigned compositionEnd() const { return m_compositionEnd; } 220 bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); } 221 const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; } 222 223 bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; } 224 225 void setStartNewKillRingSequence(bool); 203 226 204 227 #if PLATFORM(MAC) 205 228 NSString* userVisibleString(NSURL*); 206 void setStartNewKillRingSequence(bool flag) { m_startNewKillRingSequence = flag; }207 #else208 void setStartNewKillRingSequence(bool) { }209 229 #endif 210 230 211 231 PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint); 232 233 void clear(); 212 234 213 235 private: … … 216 238 RefPtr<EditCommand> m_lastEditCommand; 217 239 RefPtr<Node> m_removedAnchor; 218 bool m_ignoreMarkedTextSelectionChange; 240 241 RefPtr<Text> m_compositionNode; 242 unsigned m_compositionStart; 243 unsigned m_compositionEnd; 244 Vector<CompositionUnderline> m_customCompositionUnderlines; 245 bool m_ignoreCompositionSelectionChange; 219 246 220 247 bool canDeleteRange(Range*) const; … … 230 257 void revealSelectionAfterEditingOperation(); 231 258 232 #if PLATFORM(MAC) 259 void selectComposition(); 260 void confirmComposition(const String&, bool preserveSelection); 261 void setIgnoreCompositionSelectionChange(bool ignore); 262 233 263 void addToKillRing(Range*, bool prepend); 264 265 #if PLATFORM(MAC) 234 266 bool m_startNewKillRingSequence; 267 #endif 268 }; 269 270 #if PLATFORM(MAC) 271 272 inline void Editor::setStartNewKillRingSequence(bool flag) 273 { 274 m_startNewKillRingSequence = flag; 275 } 276 235 277 #else 236 void addToKillRing(Range*, bool) { } 237 #endif 238 239 }; 278 279 inline void Editor::setStartNewKillRingSequence(bool) { } 280 inline void Editor::addToKillRing(Range*, bool) { } 281 282 #endif 240 283 241 284 } // namespace WebCore -
trunk/WebCore/editing/TypingCommand.cpp
r25115 r25547 94 94 } 95 95 96 void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText )96 void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText, bool insertedTextIsComposition) 97 97 { 98 98 ASSERT(document); … … 101 101 ASSERT(frame); 102 102 103 insertText(document, text, frame->selectionController()->selection(), selectInsertedText );104 } 105 106 void TypingCommand::insertText(Document* document, const String& text, const Selection& selectionForInsertion, bool selectInsertedText )103 insertText(document, text, frame->selectionController()->selection(), selectInsertedText, insertedTextIsComposition); 104 } 105 106 void TypingCommand::insertText(Document* document, const String& text, const Selection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition) 107 107 { 108 108 ASSERT(document); … … 117 117 Node* startNode = selectionForInsertion.start().node(); 118 118 119 if (startNode && startNode->rootEditableElement() ) {119 if (startNode && startNode->rootEditableElement() && !insertedTextIsComposition) { 120 120 // Send BeforeTextInsertedEvent. The event handler will update text if necessary. 121 121 ExceptionCode ec = 0; -
trunk/WebCore/editing/TypingCommand.h
r25115 r25547 46 46 static void deleteKeyPressed(Document*, bool smartDelete = false, TextGranularity = CharacterGranularity); 47 47 static void forwardDeleteKeyPressed(Document*, bool smartDelete = false, TextGranularity = CharacterGranularity); 48 static void insertText(Document*, const String&, bool selectInsertedText = false );49 static void insertText(Document*, const String&, const Selection&, bool selectInsertedText = false );48 static void insertText(Document*, const String&, bool selectInsertedText = false, bool insertedTextIsComposition = false); 49 static void insertText(Document*, const String&, const Selection&, bool selectInsertedText = false, bool insertedTextIsComposition = false); 50 50 static void insertLineBreak(Document*); 51 51 static void insertParagraphSeparator(Document*); -
trunk/WebCore/loader/FrameLoader.cpp
r25439 r25547 774 774 // urlsBridgeKnowsAbout.clear(); 775 775 776 #if PLATFORM(MAC) 777 m_frame->setMarkedTextRange(0, nil, nil); 778 #endif 776 m_frame->editor()->clear(); 779 777 780 778 if (!m_needsClear) -
trunk/WebCore/page/ContextMenuController.cpp
r24422 r25547 54 54 #include "SelectionController.h" 55 55 #include "Settings.h" 56 #include "TextIterator.h" 56 57 #include "markup.h" 57 58 … … 231 232 selectedRange->selectNode(document->documentElement(), ec); 232 233 } 233 m_client->speak( selectedRange->toString(true, ec));234 m_client->speak(plainText(selectedRange.get())); 234 235 break; 235 236 } -
trunk/WebCore/page/Frame.cpp
r25397 r25547 308 308 } 309 309 310 Range* Frame::markedTextRange() const311 {312 return d->m_markedTextRange.get();313 }314 315 316 310 IntRect Frame::firstRectForRange(Range* range) const 317 311 { … … 338 332 startCaretRect.width() + extraWidthToEndOfLine, 339 333 startCaretRect.height()); 340 }341 342 void Frame::setMarkedTextRange(Range* range, Vector<MarkedTextUnderline>& markedRangeDecorations)343 {344 int exception = 0;345 346 ASSERT(!range || range->startContainer(exception) == range->endContainer(exception));347 ASSERT(!range || range->collapsed(exception) || range->startContainer(exception)->isTextNode());348 349 d->m_markedTextUnderlines.clear();350 if (markedRangeDecorations.size()) {351 d->m_markedTextUsesUnderlines = true;352 d->m_markedTextUnderlines = markedRangeDecorations;353 } else354 d->m_markedTextUsesUnderlines = false;355 356 if (d->m_markedTextRange.get() && document() && d->m_markedTextRange->startContainer(exception)->renderer())357 d->m_markedTextRange->startContainer(exception)->renderer()->repaint();358 359 if (range && range->collapsed(exception))360 d->m_markedTextRange = 0;361 else362 d->m_markedTextRange = range;363 364 if (d->m_markedTextRange.get() && document() && d->m_markedTextRange->startContainer(exception)->renderer())365 d->m_markedTextRange->startContainer(exception)->renderer()->repaint();366 }367 368 void Frame::selectRangeInMarkedText(unsigned selOffset, unsigned selLength)369 {370 ExceptionCode ec = 0;371 372 RefPtr<Range> selectedRange = document()->createRange();373 Range* markedTextRange = this->markedTextRange();374 375 ASSERT(markedTextRange->startContainer(ec) == markedTextRange->endContainer(ec));376 ASSERT(!ec);377 unsigned selectionStart = markedTextRange->startOffset(ec) + selOffset;378 unsigned selectionEnd = selectionStart + selLength;379 ASSERT(!ec);380 381 selectedRange->setStart(markedTextRange->startContainer(ec), selectionStart, ec);382 ASSERT(!ec);383 selectedRange->setEnd(markedTextRange->startContainer(ec), selectionEnd, ec);384 ASSERT(!ec);385 386 selectionController()->setSelectedRange(selectedRange.get(), DOWNSTREAM, false, ec);387 334 } 388 335 … … 1659 1606 } 1660 1607 1661 bool Frame::markedTextUsesUnderlines() const1662 {1663 return d->m_markedTextUsesUnderlines;1664 }1665 1666 const Vector<MarkedTextUnderline>& Frame::markedTextUnderlines() const1667 {1668 return d->m_markedTextUnderlines;1669 }1670 1671 1608 static bool isInShadowTree(Node* node) 1672 1609 { … … 2016 1953 , m_userStyleSheetLoader(0) 2017 1954 , m_paintRestriction(PaintRestrictionNone) 2018 , m_markedTextUsesUnderlines(false)2019 1955 , m_highlightTextMatches(false) 2020 1956 , m_windowHasFocus(false) -
trunk/WebCore/page/Frame.h
r25000 r25547 108 108 template <typename T> class Timer; 109 109 110 struct MarkedTextUnderline {111 MarkedTextUnderline()112 : startOffset(0), endOffset(0), thick(false) { }113 MarkedTextUnderline(unsigned s, unsigned e, const Color& c, bool t)114 : startOffset(s), endOffset(e), color(c), thick(t) { }115 unsigned startOffset;116 unsigned endOffset;117 Color color;118 bool thick;119 };120 121 110 class Frame : public Shared<Frame> { 122 111 public: … … 281 270 void removeEditingStyleFromElement(Element*) const; 282 271 283 Range* markedTextRange() const;284 272 IntRect firstRectForRange(Range*) const; 285 273 … … 293 281 RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const; 294 282 295 const Vector<MarkedTextUnderline>& markedTextUnderlines() const;296 bool markedTextUsesUnderlines() const;297 void setMarkedTextRange(Range* , Vector<MarkedTextUnderline>&);298 void selectRangeInMarkedText(unsigned selOffset, unsigned selLength);299 300 283 unsigned markAllMatchesForText(const String&, bool caseFlag, unsigned limit); 301 284 bool markedTextMatchesAreHighlighted() const; … … 391 374 NSWritingDirection baseWritingDirectionForSelectionStart() const; 392 375 393 void setMarkedTextRange(Range* , NSArray* attributes, NSArray* ranges);394 395 376 #endif 396 377 -
trunk/WebCore/page/FramePrivate.h
r24878 r25547 111 111 PaintRestriction m_paintRestriction; 112 112 113 bool m_markedTextUsesUnderlines;114 Vector<MarkedTextUnderline> m_markedTextUnderlines;115 113 bool m_highlightTextMatches; 116 114 bool m_windowHasFocus; … … 121 119 122 120 bool m_prohibitsScrolling; 123 124 RefPtr<Range> m_markedTextRange;125 121 126 122 // The root object used for objects bound outside the context of a plugin. -
trunk/WebCore/page/mac/FrameMac.mm
r25383 r25547 527 527 } 528 528 529 static void convertAttributesToUnderlines(Vector<MarkedTextUnderline>& result, const Range* markedTextRange, NSArray* attributes, NSArray* ranges)530 {531 int exception = 0;532 int baseOffset = markedTextRange->startOffset(exception);533 534 unsigned length = [attributes count];535 ASSERT([ranges count] == length);536 537 for (unsigned i = 0; i < length; i++) {538 NSNumber* style = [[attributes objectAtIndex:i] objectForKey:NSUnderlineStyleAttributeName];539 if (!style)540 continue;541 NSRange range = [[ranges objectAtIndex:i] rangeValue];542 NSColor* color = [[attributes objectAtIndex:i] objectForKey:NSUnderlineColorAttributeName];543 Color qColor = Color::black;544 if (color)545 qColor = colorFromNSColor([color colorUsingColorSpaceName:NSDeviceRGBColorSpace]);546 547 result.append(MarkedTextUnderline(range.location + baseOffset,548 range.location + baseOffset + range.length,549 qColor,550 [style intValue] > 1));551 }552 }553 554 void Frame::setMarkedTextRange(Range* range, NSArray* attributes, NSArray* ranges)555 {556 int exception;557 exception = 0;558 559 ASSERT(!range || range->startContainer(exception) == range->endContainer(exception));560 ASSERT(!range || range->collapsed(exception) || range->startContainer(exception)->isTextNode());561 562 Vector<MarkedTextUnderline> decorations;563 if (attributes)564 convertAttributesToUnderlines(decorations, range, attributes, ranges);565 566 setMarkedTextRange(range, decorations);567 }568 569 529 NSMutableDictionary* Frame::dashboardRegionsDictionary() 570 530 { -
trunk/WebCore/page/mac/WebCoreFrameBridge.h
r25283 r25547 169 169 - (DOMRange *)markDOMRange; 170 170 171 // international text input "marked text"172 - (void)setMarkedTextDOMRange:(DOMRange *)range customAttributes:(NSArray *)attributes ranges:(NSArray *)ranges;173 - (DOMRange *)markedTextDOMRange;174 175 171 - (NSFont *)fontForSelection:(BOOL *)hasMultipleFonts; 176 172 - (NSWritingDirection)baseWritingDirectionForSelectionStart; -
trunk/WebCore/page/mac/WebCoreFrameBridge.mm
r25169 r25547 77 77 #import "SubresourceLoader.h" 78 78 #import "SystemTime.h" 79 #import "Text.h" 79 80 #import "TextEncoding.h" 80 81 #import "TextIterator.h" … … 936 937 } 937 938 938 - (void)setMarkedTextDOMRange:(DOMRange *)range customAttributes:(NSArray *)attributes ranges:(NSArray *)ranges939 {940 m_frame->setMarkedTextRange([range _range], attributes, ranges);941 }942 943 - (DOMRange *)markedTextDOMRange944 {945 return [DOMRange _wrapRange:m_frame->markedTextRange()];946 }947 948 939 - (NSRange)markedTextNSRange 949 940 { 950 return [self convertToNSRange:m_frame-> markedTextRange()];941 return [self convertToNSRange:m_frame->editor()->compositionRange().get()]; 951 942 } 952 943 -
trunk/WebCore/platform/CharacterNames.h
r24740 r25547 42 42 const UChar leftToRightMark = 0x200E; 43 43 const UChar leftToRightOverride = 0x202D; 44 const UChar newlineCharacter = 0x000A; 44 45 const UChar noBreakSpace = 0x00A0; 45 46 const UChar objectReplacementCharacter = 0xFFFC; -
trunk/WebCore/rendering/InlineTextBox.cpp
r24887 r25547 25 25 26 26 #include "Document.h" 27 #include "Editor.h" 27 28 #include "Frame.h" 28 29 #include "GraphicsContext.h" 29 30 #include "HitTestResult.h" 30 #include "Range.h"31 31 #include "RenderArena.h" 32 32 #include "RenderBlock.h" 33 #include "Text.h" 33 34 #include "TextStyle.h" 34 35 #include "break_lines.h" … … 252 253 return; 253 254 254 // Determine whether or not we have marked text. 255 Range* markedTextRange = object()->document()->frame()->markedTextRange(); 256 int exception = 0; 257 bool haveMarkedText = markedTextRange && markedTextRange->startContainer(exception) == object()->node(); 258 bool markedTextUsesUnderlines = object()->document()->frame()->markedTextUsesUnderlines(); 255 // Determine whether or not we have composition underlines to draw. 256 bool containsComposition = object()->document()->frame()->editor()->compositionNode() == object()->node(); 257 bool useCustomUnderlines = containsComposition && object()->document()->frame()->editor()->compositionUsesCustomUnderlines(); 259 258 260 259 // Set our font. … … 265 264 paintInfo.context->setFont(*font); 266 265 267 // 1. Paint backgrounds behind text if needed. 268 // and marked text.266 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection 267 // and composition underlines. 269 268 if (paintInfo.phase != PaintPhaseSelection && !isPrinting) { 270 269 #if PLATFORM(MAC) … … 274 273 #endif 275 274 276 if (haveMarkedText && !markedTextUsesUnderlines) 277 paintMarkedTextBackground(paintInfo.context, tx, ty, styleToUse, font, markedTextRange->startOffset(exception), markedTextRange->endOffset(exception)); 275 if (containsComposition && !useCustomUnderlines) 276 paintCompositionBackground(paintInfo.context, tx, ty, styleToUse, font, 277 object()->document()->frame()->editor()->compositionStart(), 278 object()->document()->frame()->editor()->compositionEnd()); 278 279 279 280 paintDocumentMarkers(paintInfo.context, tx, ty, styleToUse, font, true); 280 281 281 if (haveSelection && ! markedTextUsesUnderlines)282 if (haveSelection && !useCustomUnderlines) 282 283 paintSelection(paintInfo.context, tx, ty, styleToUse, font); 283 284 } … … 286 287 if (m_len <= 0) 287 288 return; 288 289 const Vector<MarkedTextUnderline>* underlines = 0;290 size_t numUnderlines = 0;291 if (haveMarkedText && markedTextUsesUnderlines) {292 underlines = &object()->document()->frame()->markedTextUnderlines();293 numUnderlines = underlines->size();294 }295 289 296 290 Color textFillColor; … … 433 427 paintDocumentMarkers(paintInfo.context, tx, ty, styleToUse, font, false); 434 428 435 for (size_t index = 0; index < numUnderlines; ++index) { 436 const MarkedTextUnderline& underline = (*underlines)[index]; 437 438 if (underline.endOffset <= start()) 439 // underline is completely before this run. This might be an underline that sits 440 // before the first run we draw, or underlines that were within runs we skipped 441 // due to truncation. 442 continue; 443 444 if (underline.startOffset <= end()) { 445 // underline intersects this run. Paint it. 446 paintMarkedTextUnderline(paintInfo.context, tx, ty, underline); 447 if (underline.endOffset > end() + 1) 448 // underline also runs into the next run. Bail now, no more marker advancement. 429 if (useCustomUnderlines) { 430 const Vector<CompositionUnderline>& underlines = object()->document()->frame()->editor()->customCompositionUnderlines(); 431 size_t numUnderlines = underlines.size(); 432 433 for (size_t index = 0; index < numUnderlines; ++index) { 434 const CompositionUnderline& underline = underlines[index]; 435 436 if (underline.endOffset <= start()) 437 // underline is completely before this run. This might be an underline that sits 438 // before the first run we draw, or underlines that were within runs we skipped 439 // due to truncation. 440 continue; 441 442 if (underline.startOffset <= end()) { 443 // underline intersects this run. Paint it. 444 paintCompositionUnderline(paintInfo.context, tx, ty, underline); 445 if (underline.endOffset > end() + 1) 446 // underline also runs into the next run. Bail now, no more marker advancement. 447 break; 448 } else 449 // underline is completely after this run, bail. A later run will paint it. 449 450 break; 450 } else 451 // underline is completely after this run, bail. A later run will paint it. 452 break; 451 } 453 452 } 454 453 } … … 508 507 } 509 508 510 void InlineTextBox::paint MarkedTextBackground(GraphicsContext* p, int tx, int ty, RenderStyle* style, const Font* f, int startPos, int endPos)509 void InlineTextBox::paintCompositionBackground(GraphicsContext* p, int tx, int ty, RenderStyle* style, const Font* f, int startPos, int endPos) 511 510 { 512 511 int offset = m_start; … … 727 726 728 727 729 void InlineTextBox::paint MarkedTextUnderline(GraphicsContext* ctx, int tx, int ty, const MarkedTextUnderline& underline)728 void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int ty, const CompositionUnderline& underline) 730 729 { 731 730 tx += m_x; -
trunk/WebCore/rendering/InlineTextBox.h
r24887 r25547 37 37 class String; 38 38 class StringImpl; 39 class MarkedTextUnderline;40 39 class HitTestResult; 41 40 class Position; 41 42 struct CompositionUnderline; 42 43 43 44 class InlineTextBox : public InlineRunBox { … … 95 96 void paintDecoration(GraphicsContext*, int tx, int ty, int decoration); 96 97 void paintSelection(GraphicsContext*, int tx, int ty, RenderStyle*, const Font*); 97 void paint MarkedTextBackground(GraphicsContext*, int tx, int ty, RenderStyle*, const Font*, int startPos, int endPos);98 void paintCompositionBackground(GraphicsContext*, int tx, int ty, RenderStyle*, const Font*, int startPos, int endPos); 98 99 void paintDocumentMarkers(GraphicsContext*, int tx, int ty, RenderStyle*, const Font*, bool background); 99 100 void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font*, bool grammar); 100 101 void paintTextMatchMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font*); 101 void paint MarkedTextUnderline(GraphicsContext*, int tx, int ty, const MarkedTextUnderline&);102 void paintCompositionUnderline(GraphicsContext*, int tx, int ty, const CompositionUnderline&); 102 103 #if PLATFORM(MAC) 103 104 void paintCustomHighlight(int tx, int ty, const AtomicString& type); -
trunk/WebCore/rendering/RenderTextControl.cpp
r25245 r25547 1 1 /** 2 * Copyright (C) 2006, 2007 Apple Inc. 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 22 22 #include "RenderTextControl.h" 23 23 24 #include "CharacterNames.h" 24 25 #include "Document.h" 25 26 #include "Editor.h" … … 41 42 #include "SelectionController.h" 42 43 #include "Settings.h" 44 #include "Text.h" 43 45 #include "TextIterator.h" 44 46 #include "TextStyle.h" … … 547 549 } 548 550 551 String RenderTextControl::finishText(Vector<UChar>& result) const 552 { 553 UChar symbol = backslashAsCurrencySymbol(); 554 if (symbol != '\\') { 555 size_t size = result.size(); 556 for (size_t i = 0; i < size; ++i) 557 if (result[i] == '\\') 558 result[i] = symbol; 559 } 560 561 return String::adopt(result); 562 } 563 549 564 String RenderTextControl::text() 550 565 { 551 if (m_innerText) 552 return m_innerText->textContent().replace('\\', backslashAsCurrencySymbol()); 553 return String(); 566 if (!m_innerText) 567 return ""; 568 569 Frame* frame = document()->frame(); 570 Text* compositionNode = frame ? frame->editor()->compositionNode() : 0; 571 572 Vector<UChar> result; 573 574 for (Node* n = m_innerText.get(); n; n = n->traverseNextNode(m_innerText.get())) { 575 if (n->isTextNode()) { 576 Text* text = static_cast<Text*>(n); 577 String data = text->data(); 578 unsigned length = data.length(); 579 if (text != compositionNode) 580 result.append(data.characters(), length); 581 else { 582 unsigned compositionStart = min(frame->editor()->compositionStart(), length); 583 unsigned compositionEnd = min(max(compositionStart, frame->editor()->compositionEnd()), length); 584 result.append(data.characters(), compositionStart); 585 result.append(data.characters() + compositionEnd, length - compositionEnd); 586 } 587 } 588 } 589 590 return finishText(result); 591 } 592 593 static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& breakOffset) 594 { 595 RootInlineBox* next; 596 for (; line; line = next) { 597 next = line->nextRootBox(); 598 if (next && !line->endsWithBreak()) { 599 ASSERT(line->lineBreakObj()); 600 breakNode = line->lineBreakObj()->node(); 601 breakOffset = line->lineBreakPos(); 602 line = next; 603 return; 604 } 605 } 606 breakNode = 0; 554 607 } 555 608 556 609 String RenderTextControl::textWithHardLineBreaks() 557 610 { 558 String s(""); 559 560 if (!m_innerText || !m_innerText->firstChild()) 561 return s; 611 if (!m_innerText) 612 return ""; 613 Node* firstChild = m_innerText->firstChild(); 614 if (!firstChild) 615 return ""; 562 616 563 617 document()->updateLayout(); 564 618 565 RenderObject* renderer = m_innerText->firstChild()->renderer();619 RenderObject* renderer = firstChild->renderer(); 566 620 if (!renderer) 567 return s;621 return ""; 568 622 569 623 InlineBox* box = renderer->inlineBox(0, DOWNSTREAM); 570 624 if (!box) 571 return s; 572 573 ExceptionCode ec = 0; 574 RefPtr<Range> range = new Range(document()); 575 range->selectNodeContents(m_innerText.get(), ec); 576 for (RootInlineBox* line = box->root(); line; line = line->nextRootBox()) { 577 // If we're at a soft wrap, then insert the hard line break here 578 if (!line->endsWithBreak() && line->nextRootBox()) { 579 // Update range so it ends before this wrap 580 ASSERT(line->lineBreakObj()); 581 range->setEnd(line->lineBreakObj()->node(), line->lineBreakPos(), ec); 582 583 s.append(range->toString(true, ec)); 584 s.append("\n"); 585 586 // Update range so it starts after this wrap 587 range->setEnd(m_innerText.get(), maxDeepOffset(m_innerText.get()), ec); 588 range->setStart(line->lineBreakObj()->node(), line->lineBreakPos(), ec); 625 return ""; 626 627 Frame* frame = document()->frame(); 628 Text* compositionNode = frame ? frame->editor()->compositionNode() : 0; 629 630 Node* breakNode; 631 unsigned breakOffset; 632 RootInlineBox* line = box->root(); 633 getNextSoftBreak(line, breakNode, breakOffset); 634 635 Vector<UChar> result; 636 637 for (Node* n = firstChild; n; n = n->traverseNextNode(m_innerText.get())) { 638 if (n->hasTagName(brTag)) 639 result.append(&newlineCharacter, 1); 640 else if (n->isTextNode()) { 641 Text* text = static_cast<Text*>(n); 642 String data = text->data(); 643 unsigned length = data.length(); 644 unsigned compositionStart = (text == compositionNode) 645 ? min(frame->editor()->compositionStart(), length) : 0; 646 unsigned compositionEnd = (text == compositionNode) 647 ? min(max(compositionStart, frame->editor()->compositionEnd()), length) : 0; 648 unsigned position = 0; 649 while (breakNode == n && breakOffset < compositionStart) { 650 result.append(data.characters() + position, breakOffset - position); 651 position = breakOffset; 652 result.append(&newlineCharacter, 1); 653 getNextSoftBreak(line, breakNode, breakOffset); 654 } 655 result.append(data.characters() + position, compositionStart - position); 656 position = compositionEnd; 657 while (breakNode == n && breakOffset <= length) { 658 if (breakOffset > position) { 659 result.append(data.characters() + position, breakOffset - position); 660 position = breakOffset; 661 result.append(&newlineCharacter, 1); 662 } 663 getNextSoftBreak(line, breakNode, breakOffset); 664 } 665 result.append(data.characters() + position, length - position); 589 666 } 590 }591 s.append(range->toString(true, ec));592 ASSERT(!ec);593 594 return s.replace('\\', backslashAsCurrencySymbol());667 while (breakNode == n) 668 getNextSoftBreak(line, breakNode, breakOffset); 669 } 670 671 return finishText(result); 595 672 } 596 673 -
trunk/WebCore/rendering/RenderTextControl.h
r25245 r25547 134 134 void startSearchEventTimer(); 135 135 void searchEventTimerFired(Timer<RenderTextControl>*); 136 String finishText(Vector<UChar>&) const; 136 137 137 138 RefPtr<HTMLTextFieldInnerElement> m_innerBlock; -
trunk/WebKit/ChangeLog
r25519 r25547 1 2007-09-13 Darin Adler <darin@apple.com> 2 3 Reviewed by Oliver. 4 5 - fix <rdar://problem/5470457> REGRESSION: Input method inline hole is mishandled in text 6 <input> elements with maxlength limit 7 8 * WebView/WebHTMLView.mm: 9 (-[WebHTMLView _selectionChanged]): Tweaked code a bit. 10 (-[WebHTMLView markedRange]): Simplified logic, since markedTextNSRange works when there's 11 no composition range. 12 (-[WebHTMLView hasMarkedText]): Call directly to Editor instead of bridge. 13 (-[WebHTMLView unmarkText]): Call new confirmComposition to make it clear that this is 14 confirming text, not just unmarking it to discard it. 15 (extractUnderlines): Added. Converts directly from an NSAttributedString to the 16 CompositionUnderline vector that's used by WebCore. 17 (-[WebHTMLView setMarkedText:selectedRange:]): Changed to use the new setComposition. 18 (-[WebHTMLView insertText:]): Changed to use confirmComposition when appropriate, instead 19 of relying on special behavior of Editor::insertText. 20 (-[WebHTMLView _updateSelectionForInputManager]): Rewrote to use getCompositionSelection 21 and confirmCompositionWithoutDisturbingSelection. 22 23 * WebCoreSupport/WebEditorClient.h: 24 * WebCoreSupport/WebEditorClient.mm: 25 Removed obsolete markedTextAbandoned function. 26 1 27 2007-09-12 David Kilzer <ddkilzer@apple.com> 2 28 -
trunk/WebKit/WebCoreSupport/WebEditorClient.h
r25345 r25547 91 91 virtual void handleInputMethodKeypress(WebCore::KeyboardEvent*); 92 92 93 virtual void markedTextAbandoned(WebCore::Frame*);94 95 93 virtual void textFieldDidBeginEditing(WebCore::Element*); 96 94 virtual void textFieldDidEndEditing(WebCore::Element*); -
trunk/WebKit/WebCoreSupport/WebEditorClient.mm
r25396 r25547 447 447 } 448 448 449 void WebEditorClient::markedTextAbandoned(Frame* frame)450 {451 WebHTMLView *webHTMLView = [[kit(frame) frameView] documentView];452 [[NSInputManager currentInputManager] markedTextAbandoned:webHTMLView];453 }454 455 449 #define FormDelegateLog(ctrl) LOG(FormDelegate, "control=%@", ctrl) 456 450 -
trunk/WebKit/WebView/WebHTMLView.mm
r25493 r25547 76 76 #import <WebCore/CachedImage.h> 77 77 #import <WebCore/CachedResourceClient.h> 78 #import <WebCore/ColorMac.h> 78 79 #import <WebCore/ContextMenu.h> 79 80 #import <WebCore/ContextMenuController.h> … … 102 103 #import <WebCore/SelectionController.h> 103 104 #import <WebCore/SharedBuffer.h> 105 #import <WebCore/Text.h> 104 106 #import <WebCore/WebCoreObjCExtras.h> 105 107 #import <WebCore/WebCoreTextRenderer.h> … … 4947 4949 [self _updateSelectionForInputManager]; 4948 4950 [self _updateFontPanel]; 4949 if ( core([self _frame]))4950 core ([self _frame])->editor()->setStartNewKillRingSequence(true);4951 if (Frame* coreFrame = core([self _frame])) 4952 coreFrame->editor()->setStartNewKillRingSequence(true); 4951 4953 } 4952 4954 … … 5354 5356 NSAttributedString *result = [self attributedSubstringFromRange:NSMakeRange(0, UINT_MAX)]; 5355 5357 5356 LOG(TextInput, "textStorage -> \"% s\"", result ? [[result string] UTF8String] :"");5358 LOG(TextInput, "textStorage -> \"%@\"", result ? [result string] : @""); 5357 5359 5358 5360 // We have to return an empty string rather than null to prevent TSM from calling -string … … 5424 5426 - (NSRange)markedRange 5425 5427 { 5426 if (![self hasMarkedText]) {5427 LOG(TextInput, "markedRange -> (NSNotFound, 0)");5428 return NSMakeRange(NSNotFound, 0);5429 }5430 5428 NSRange result = [[self _bridge] markedTextNSRange]; 5431 5432 5429 LOG(TextInput, "markedRange -> (%u, %u)", result.location, result.length); 5433 5430 return result; … … 5457 5454 result = [result attributedSubstringFromRange:NSMakeRange(0, nsRange.length)]; 5458 5455 } 5459 LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> \"% s\"", nsRange.location, nsRange.length, [[result string] UTF8String]);5456 LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> \"%@\"", nsRange.location, nsRange.length, [result string]); 5460 5457 return result; 5461 5458 } … … 5476 5473 - (BOOL)hasMarkedText 5477 5474 { 5478 BOOL result = [[self _bridge] markedTextDOMRange] != nil;5479 5475 Frame* coreFrame = core([self _frame]); 5476 BOOL result = coreFrame && coreFrame->editor()->hasComposition(); 5480 5477 LOG(TextInput, "hasMarkedText -> %u", result); 5481 5478 return result; … … 5496 5493 5497 5494 if (Frame* coreFrame = core([self _frame])) 5498 coreFrame->editor()-> unmarkText();5499 } 5500 5501 - (void)_extractAttributes:(NSArray **)a ranges:(NSArray **)r fromAttributedString:(NSAttributedString *)string 5495 coreFrame->editor()->confirmComposition(); 5496 } 5497 5498 static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnderline>& result) 5502 5499 { 5503 5500 int length = [[string string] length]; 5501 5504 5502 int i = 0; 5505 NSMutableArray *attributes = [NSMutableArray array];5506 NSMutableArray *ranges = [NSMutableArray array];5507 5503 while (i < length) { 5508 NSRange effectiveRange; 5509 NSDictionary *attrs = [string attributesAtIndex:i longestEffectiveRange:&effectiveRange inRange:NSMakeRange(i,length - i)]; 5510 [attributes addObject:attrs]; 5511 [ranges addObject:[NSValue valueWithRange:effectiveRange]]; 5512 i = effectiveRange.location + effectiveRange.length; 5513 } 5514 *a = attributes; 5515 *r = ranges; 5504 NSRange range; 5505 NSDictionary *attrs = [string attributesAtIndex:i longestEffectiveRange:&range inRange:NSMakeRange(i, length - i)]; 5506 5507 if (NSNumber *style = [attrs objectForKey:NSUnderlineStyleAttributeName]) { 5508 Color color = Color::black; 5509 if (NSColor *colorAttr = [attrs objectForKey:NSUnderlineColorAttributeName]) 5510 color = colorFromNSColor([colorAttr colorUsingColorSpaceName:NSDeviceRGBColorSpace]); 5511 result.append(CompositionUnderline(range.location, NSMaxRange(range), color, [style intValue] > 1)); 5512 } 5513 5514 i = range.location + range.length; 5515 } 5516 5516 } 5517 5517 … … 5520 5520 BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; // Otherwise, NSString 5521 5521 5522 LOG(TextInput, "setMarkedText:\"% s\" selectedRange:(%u, %u)", isAttributedString ? [[string string] UTF8String] : [string UTF8String], newSelRange.location, newSelRange.length);5522 LOG(TextInput, "setMarkedText:\"%@\" selectedRange:(%u, %u)", isAttributedString ? [string string] : string, newSelRange.location, newSelRange.length); 5523 5523 5524 5524 // Use pointer to get parameters passed to us by the caller of interpretKeyEvents. … … 5535 5535 return; 5536 5536 5537 WebFrameBridge *bridge = [self _bridge];5538 5539 5537 if (![self _isEditable]) 5540 5538 return; 5539 5540 Vector<CompositionUnderline> underlines; 5541 NSString *text = string; 5541 5542 5542 5543 if (isAttributedString) { 5543 5544 unsigned markedTextLength = [(NSString *)string length]; 5544 5545 NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:NULL inRange:NSMakeRange(0, markedTextLength)]; 5545 LOG(TextInput, " ReplacementRange: %s", [rangeString UTF8String]); 5546 // The AppKit adds a 'secret' property to the string that contains the replacement 5547 // range. The replacement range is the range of the the text that should be replaced 5548 // with the new string. 5546 LOG(TextInput, " ReplacementRange: %@", rangeString); 5547 // The AppKit adds a 'secret' property to the string that contains the replacement range. 5548 // The replacement range is the range of the the text that should be replaced with the new string. 5549 5549 if (rangeString) 5550 5550 [[self _bridge] selectNSRange:NSRangeFromString(rangeString)]; 5551 } 5552 5553 coreFrame->editor()->setIgnoreMarkedTextSelectionChange(true); 5554 5555 // if we had marked text already, we need to make sure to replace 5556 // that, instead of the selection/caret 5557 coreFrame->editor()->selectMarkedText(); 5558 5559 NSString *text = string; 5560 NSArray *attributes = nil; 5561 NSArray *ranges = nil; 5562 if (isAttributedString) { 5551 5563 5552 text = [string string]; 5564 [self _extractAttributes:&attributes ranges:&ranges fromAttributedString:string]; 5565 } 5566 5567 coreFrame->editor()->replaceMarkedText(text); 5568 [bridge setMarkedTextDOMRange:[self _selectedRange] customAttributes:attributes ranges:ranges]; 5569 if ([self hasMarkedText]) 5570 coreFrame->selectRangeInMarkedText(newSelRange.location, newSelRange.length); 5571 5572 coreFrame->editor()->setIgnoreMarkedTextSelectionChange(false); 5553 extractUnderlines(string, underlines); 5554 } 5555 5556 coreFrame->editor()->setComposition(text, underlines, newSelRange.location, NSMaxRange(newSelRange)); 5573 5557 } 5574 5558 … … 5632 5616 BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; // Otherwise, NSString 5633 5617 5634 LOG(TextInput, "insertText:\"% s\"", isAttributedString ? [[string string] UTF8String] : [string UTF8String]);5618 LOG(TextInput, "insertText:\"%@\"", isAttributedString ? [string string] : string); 5635 5619 5636 5620 WebHTMLViewInterpretKeyEventsParameters* parameters = _private->interpretKeyEventsParameters; … … 5640 5624 5641 5625 // We don't support inserting an attributed string but input methods don't appear to require this. 5626 Frame* coreFrame = core([self _frame]); 5642 5627 NSString *text; 5643 bool isFromInputMethod = [self hasMarkedText];5628 bool isFromInputMethod = coreFrame->editor()->hasComposition(); 5644 5629 if (isAttributedString) { 5645 5630 text = [string string]; … … 5649 5634 // NSAttributedString 5650 5635 NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:NULL inRange:NSMakeRange(0, [text length])]; 5651 LOG(TextInput, " ReplacementRange: % s", [rangeString UTF8String]);5636 LOG(TextInput, " ReplacementRange: %@", rangeString); 5652 5637 if (rangeString) { 5653 5638 [[self _bridge] selectNSRange:NSRangeFromString(rangeString)]; … … 5675 5660 } 5676 5661 5677 Frame* coreFrame = core([self _frame]);5678 5662 String eventText = text; 5679 5663 eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore 5680 eventHandled = coreFrame && coreFrame->editor()->insertText(eventText, event); 5664 if (coreFrame) { 5665 if (!coreFrame->editor()->hasComposition()) 5666 eventHandled = coreFrame->editor()->insertText(eventText, event); 5667 else { 5668 eventHandled = true; 5669 coreFrame->editor()->confirmComposition(eventText); 5670 } 5671 } 5681 5672 } 5682 5673 … … 5694 5685 } 5695 5686 5696 - (BOOL)_selectionIsInsideMarkedText5697 {5698 WebFrameBridge *bridge = [self _bridge];5699 DOMRange *selection = [self _selectedRange];5700 DOMRange *markedTextRange = [bridge markedTextDOMRange];5701 5702 ASSERT([markedTextRange startContainer] == [markedTextRange endContainer]);5703 5704 if ([selection startContainer] != [markedTextRange startContainer])5705 return NO;5706 5707 if ([selection endContainer] != [markedTextRange startContainer])5708 return NO;5709 5710 if ([selection startOffset] < [markedTextRange startOffset])5711 return NO;5712 5713 if ([selection endOffset] > [markedTextRange endOffset])5714 return NO;5715 5716 return YES;5717 }5718 5719 5687 - (void)_updateSelectionForInputManager 5720 5688 { 5721 if (![self hasMarkedText])5722 return;5723 5724 5689 Frame* coreFrame = core([self _frame]); 5725 5690 if (!coreFrame) 5726 5691 return; 5727 5692 5728 if (coreFrame->editor()->ignoreMarkedTextSelectionChange()) 5729 return; 5730 5731 if ([self _selectionIsInsideMarkedText]) { 5732 DOMRange *selection = [self _selectedRange]; 5733 DOMRange *markedTextDOMRange = [[self _bridge] markedTextDOMRange]; 5734 5735 unsigned markedSelectionStart = [selection startOffset] - [markedTextDOMRange startOffset]; 5736 unsigned markedSelectionLength = [selection endOffset] - [selection startOffset]; 5737 NSRange newSelectionRange = NSMakeRange(markedSelectionStart, markedSelectionLength); 5738 5739 [[NSInputManager currentInputManager] markedTextSelectionChanged:newSelectionRange client:self]; 5740 } else { 5741 [self unmarkText]; 5693 if (!coreFrame->editor()->hasComposition()) 5694 return; 5695 5696 if (coreFrame->editor()->ignoreCompositionSelectionChange()) 5697 return; 5698 5699 unsigned start; 5700 unsigned end; 5701 if (coreFrame->editor()->getCompositionSelection(start, end)) 5702 [[NSInputManager currentInputManager] markedTextSelectionChanged:NSMakeRange(start, end - start) client:self]; 5703 else { 5704 coreFrame->editor()->confirmCompositionWithoutDisturbingSelection(); 5742 5705 [[NSInputManager currentInputManager] markedTextAbandoned:self]; 5743 5706 } -
trunk/WebKit/win/ChangeLog
r25530 r25547 1 2007-09-13 Darin Adler <darin@apple.com> 2 3 Reviewed by Oliver. 4 5 - fix <rdar://problem/5470457> REGRESSION: Input method inline hole is mishandled in text 6 <input> elements with maxlength limit 7 8 * WebView.cpp: 9 (WebView::resetIME): Change to use confirmCompositionWithoutDisturbingSelection. 10 (WebView::updateSelectionForIME): Update for name changes, and to use new functions 11 in Editor. 12 (WebView::onIMEStartComposition): Removed unneeded call to unmarkText. 13 (compositionToUnderlines): Removed startOffset parameter, since setComposition now 14 handles this. 15 (WebView::onIMEComposition): Changed to use confirmComposition and setComposition. 16 Logic gets a lot cleaner. 17 (WebView::onIMEEndComposition): Removed unneeded calls to Editor. 18 (WebView::onIMERequestCharPosition): Updated for name changes. 19 1 20 2007-09-12 Oliver Hunt <oliver@apple.com> 2 21 -
trunk/WebKit/win/WebView.cpp
r25523 r25547 3790 3790 } 3791 3791 3792 static bool markedTextContainsSelection(Range* markedTextRange, Range* selection)3793 {3794 ExceptionCode ec = 0;3795 3796 ASSERT(markedTextRange->startContainer(ec) == markedTextRange->endContainer(ec));3797 3798 if (selection->startContainer(ec) != markedTextRange->startContainer(ec))3799 return false;3800 3801 if (selection->endContainer(ec) != markedTextRange->endContainer(ec))3802 return false;3803 3804 if (selection->startOffset(ec) < markedTextRange->startOffset(ec))3805 return false;3806 3807 if (selection->endOffset(ec) > markedTextRange->endOffset(ec))3808 return false;3809 3810 return true;3811 }3812 3813 static void setSelectionToEndOfRange(Frame* targetFrame, Range* sourceRange)3814 {3815 ExceptionCode ec = 0;3816 Node* caretContainer = sourceRange->endContainer(ec);3817 unsigned caretOffset = sourceRange->endOffset(ec);3818 RefPtr<Range> range = targetFrame->document()->createRange();3819 range->setStart(caretContainer, caretOffset, ec);3820 range->setEnd(caretContainer, caretOffset, ec);3821 targetFrame->editor()->unmarkText();3822 targetFrame->selectionController()->setSelectedRange(range.get(), WebCore::DOWNSTREAM, true, ec);3823 }3824 3825 3792 void WebView::resetIME(Frame* targetFrame) 3826 3793 { 3827 3794 if (targetFrame) 3828 targetFrame->editor()-> unmarkText();3795 targetFrame->editor()->confirmCompositionWithoutDisturbingSelection(); 3829 3796 3830 3797 if (HIMC hInputContext = getIMMContext()) { … … 3837 3804 { 3838 3805 Frame* targetFrame = m_page->focusController()->focusedOrMainFrame(); 3839 if (!targetFrame || !targetFrame-> markedTextRange())3806 if (!targetFrame || !targetFrame->editor()->hasComposition()) 3840 3807 return; 3841 3808 3842 if (targetFrame->editor()->ignore MarkedTextSelectionChange())3809 if (targetFrame->editor()->ignoreCompositionSelectionChange()) 3843 3810 return; 3844 3811 3845 RefPtr<Range> selectionRange = targetFrame->selectionController()->selection().toRange(); 3846 if (!selectionRange || !markedTextContainsSelection(targetFrame->markedTextRange(), selectionRange.get())) 3812 unsigned start; 3813 unsigned end; 3814 if (!targetFrame->editor()->getCompositionSelection(start, end)) 3847 3815 resetIME(targetFrame); 3848 3816 } … … 3864 3832 if (!targetFrame) 3865 3833 return true; 3866 3867 //Tidy up in case the last IME composition was not correctly terminated3868 targetFrame->editor()->unmarkText();3869 3834 3870 3835 HIMC hInputContext = getIMMContext(); … … 3887 3852 } 3888 3853 3889 static void compositionToUnderlines(const Vector<DWORD>& clauses, const Vector<BYTE>& attributes, 3890 unsigned startOffset, Vector<MarkedTextUnderline>& underlines) 3891 {3892 if (!clauses.size())3854 static void compositionToUnderlines(const Vector<DWORD>& clauses, const Vector<BYTE>& attributes, Vector<CompositionUnderline>& underlines) 3855 { 3856 if (clauses.isEmpty()) { 3857 underlines.clear(); 3893 3858 return; 3859 } 3894 3860 3895 3861 const size_t numBoundaries = clauses.size() - 1; 3896 3862 underlines.resize(numBoundaries); 3897 3863 for (unsigned i = 0; i < numBoundaries; i++) { 3898 underlines[i].startOffset = startOffset +clauses[i];3899 underlines[i].endOffset = startOffset +clauses[i + 1];3864 underlines[i].startOffset = clauses[i]; 3865 underlines[i].endOffset = clauses[i + 1]; 3900 3866 BYTE attribute = attributes[clauses[i]]; 3901 3867 underlines[i].thick = attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED; … … 3915 3881 3916 3882 prepareCandidateWindow(targetFrame, hInputContext); 3917 targetFrame->editor()->setIgnoreMarkedTextSelectionChange(true);3918 3919 // if we had marked text already, we need to make sure to replace3920 // that, instead of the selection/caret3921 targetFrame->editor()->selectMarkedText();3922 3883 3923 3884 if (lparam & GCS_RESULTSTR || !lparam) { 3924 3885 String compositionString; 3925 3886 if (!getCompositionString(hInputContext, GCS_RESULTSTR, compositionString) && lparam) 3926 goto cleanup;3887 return true; 3927 3888 3928 targetFrame->editor()->replaceMarkedText(compositionString); 3929 RefPtr<Range> sourceRange = targetFrame->selectionController()->selection().toRange(); 3930 setSelectionToEndOfRange(targetFrame, sourceRange.get()); 3931 } else if (lparam) { 3889 targetFrame->editor()->confirmComposition(compositionString); 3890 } else { 3932 3891 String compositionString; 3933 3892 if (!getCompositionString(hInputContext, GCS_COMPSTR, compositionString)) 3934 goto cleanup;3893 return true; 3935 3894 3936 targetFrame->editor()->replaceMarkedText(compositionString);3937 3938 ExceptionCode ec = 0;3939 RefPtr<Range> sourceRange = targetFrame->selectionController()->selection().toRange();3940 if (!sourceRange)3941 goto cleanup;3942 3943 Node* startContainer = sourceRange->startContainer(ec);3944 const String& str = startContainer->textContent();3945 for (unsigned i = 0; i < str.length(); i++)3946 ASSERT(str[i]);3947 3948 unsigned startOffset = sourceRange->startOffset(ec);3949 RefPtr<Range> range = targetFrame->document()->createRange();3950 range->setStart(startContainer, startOffset, ec);3951 range->setEnd(startContainer, startOffset + compositionString.length(), ec);3952 3953 3895 // Composition string attributes 3954 3896 int numAttributes = IMMDict::dict().getCompositionString(hInputContext, GCS_COMPATTR, 0, 0); … … 3960 3902 Vector<DWORD> clauses(numClauses / sizeof(DWORD)); 3961 3903 IMMDict::dict().getCompositionString(hInputContext, GCS_COMPCLAUSE, clauses.data(), numClauses); 3962 Vector<MarkedTextUnderline> underlines; 3963 compositionToUnderlines(clauses, attributes, startOffset, underlines); 3964 targetFrame->setMarkedTextRange(range.get(), underlines); 3965 if (targetFrame->markedTextRange()) 3966 targetFrame->selectRangeInMarkedText(LOWORD(IMMDict::dict().getCompositionString(hInputContext, GCS_CURSORPOS, 0, 0)), 0); 3967 } 3968 cleanup: 3969 targetFrame->editor()->setIgnoreMarkedTextSelectionChange(false); 3904 3905 Vector<CompositionUnderline> underlines; 3906 compositionToUnderlines(clauses, attributes, underlines); 3907 3908 int cursorPosition = LOWORD(IMMDict::dict().getCompositionString(hInputContext, GCS_CURSORPOS, 0, 0)); 3909 3910 targetFrame->editor()->setComposition(compositionString, underlines, cursorPosition, 0); 3911 } 3912 3970 3913 return true; 3971 3914 } … … 3975 3918 if (m_inIMEComposition) 3976 3919 m_inIMEComposition--; 3977 Frame* targetFrame = m_page->focusController()->focusedOrMainFrame();3978 if (!targetFrame)3979 return true;3980 targetFrame->editor()->unmarkText();3981 3920 return true; 3982 3921 } … … 3995 3934 { 3996 3935 IntRect caret; 3997 ASSERT(charPos->dwCharPos == 0 || targetFrame-> markedTextRange());3998 if (RefPtr<Range> range = targetFrame-> markedTextRange() ? targetFrame->markedTextRange() : targetFrame->selectionController()->selection().toRange()) {3936 ASSERT(charPos->dwCharPos == 0 || targetFrame->editor()->hasComposition()); 3937 if (RefPtr<Range> range = targetFrame->editor()->hasComposition() ? targetFrame->editor()->compositionRange() : targetFrame->selectionController()->selection().toRange()) { 3999 3938 ExceptionCode ec = 0; 4000 3939 RefPtr<Range> tempRange = range->cloneRange(ec);
Note:
See TracChangeset
for help on using the changeset viewer.