Commit ead9a459 authored by darin's avatar darin

WebCore:

        Reviewed by Oliver.

        - fix <rdar://problem/5470457> REGRESSION: Input method inline hole is mishandled in text
          <input> elements with maxlength limit

        * editing/Editor.h: Moved MarkedTextUnderline here and renamed it CompositionUnderline.
        Moved the rest of the marked text API here and used the term that will be more familiar
        to those on platforms other than Macintosh, "composition". This helps prevent confusion
        with the other kinds of mark -- the emacs "mark" and spelling/grammar marks. Also
        cleaned up the conditionals a bit for the Macintosh-specific parts of this header.

        * editing/Editor.cpp:
        (WebCore::Editor::Editor): Updated for name change.
        (WebCore::Editor::clear): Added. To be called by FrameLoader::clear().
        (WebCore::Editor::insertTextWithoutSendingTextEvent): Removed code to make inserted
        text replace the marked text range -- we now deal with this explicitly by not
        calling this function to replace marked text. Also removed unneeded code that was
        specific to the use of this to replace the marked text.
        (WebCore::Editor::selectComposition): Renamed from selectMarkedText. Updated since
        the composition range is not stored as a Range.
        (WebCore::Editor::confirmComposition): Added. To be called when changing a composition
        into actual text. Unlike the old code path, deletes the composition first, then inserts
        the text, triggering the normal insertion code path and events. This is helpful because
        it means the inserted text will be truncated by the <input> element, for example.
        (WebCore::Editor::confirmCompositionWithoutDisturbingSelection): Added.
        (WebCore::Editor::setComposition): Added. To be called when changing the composition.
        Takes parameters for the underlines and selection. Unlike the old code path, this passes
        a flag down that indicates the inserted text is part of a composition. This is helpful
        because we don't send the event that will cause the <input> element to do truncation.
        It's also a better API for future improvements to our input method handling.
        (WebCore::Editor::revealSelectionAfterEditingOperation): Updated for name change.
        (WebCore::Editor::setIgnoreCompositionSelectionChange): Ditto.
        (WebCore::Editor::compositionRange): Added. Needed now that the composition is not
        stored as a Range.
        (WebCore::Editor::getCompositionSelection): Added.

        * editing/TypingCommand.h:
        * editing/TypingCommand.cpp: (WebCore::TypingCommand::insertText):
        Added an insertedTextIsComposition parameter, and don't send the BeforeTextInsertedEvent
        if it's true.

        * loader/FrameLoader.cpp: (WebCore::FrameLoader::clear): Replaced the Macintosh-specific
        call to setMarkedTextRange with a call to the new Editor::clear().

        * page/Frame.h:
        * page/Frame.cpp:
        * page/FramePrivate.h:
        * page/mac/FrameMac.mm:
        Removed the marked text code. It was streamlined and moved to Editor, except for the
        Mac-specific code, which was moved into WebKit.

        * page/mac/WebCoreFrameBridge.h:
        * page/mac/WebCoreFrameBridge.mm: Removed some now-unneeded marked text code.
        (-[WebCoreFrameBridge markedTextNSRange]): Updated for name/API change.

        * rendering/InlineTextBox.h:
        * rendering/InlineTextBox.cpp:
        (WebCore::InlineTextBox::paint): Updated marked text code for name changes, and also
        streamlined the code a bit for the case where there is no composition.
        (WebCore::InlineTextBox::paintCompositionBackground): Name change.
        (WebCore::InlineTextBox::paintCompositionUnderline): Ditto.

        * rendering/RenderTextControl.h:
        * rendering/RenderTextControl.cpp:
        (WebCore::RenderTextControl::finishText): Added. Helper function shared by the
        (WebCore::RenderTextControl::text):
        (WebCore::getNextSoftBreak):
        (WebCore::RenderTextControl::textWithHardLineBreaks):

        * platform/CharacterNames.h: Added newlineCharacter.

        * dom/Range.h: Remove the now-unneeded version of toString that converts <br>
        elements into newlines.
        * dom/Range.cpp:
        (WebCore::Range::toString): Changed this to use a Vector<UChar> instead of
        a String so it will not have pathological reallocation performance, and removed
        the <br> feature.
        (WebCore::Range::pastEndNode): Made this return 0 when there is no start node.
        This bit of extra robustness guarantees you can't do a null dereference if the
        start node is 0 and the end node is not. Not sure this case really exists.

        * page/ContextMenuController.cpp: (ContextMenuController::contextMenuItemSelected):
        Removed a semi-bogus use of Range::toString(true). The right function to use here
        is plainText().

        * bridge/EditorClient.h: Removed obsolete markedTextAbandoned function.

        * WebCore.exp: Updated for above changes. 

WebKit:

        Reviewed by Oliver.

        - fix <rdar://problem/5470457> REGRESSION: Input method inline hole is mishandled in text
          <input> elements with maxlength limit

        * WebView/WebHTMLView.mm:
        (-[WebHTMLView _selectionChanged]): Tweaked code a bit.
        (-[WebHTMLView markedRange]): Simplified logic, since markedTextNSRange works when there's
        no composition range.
        (-[WebHTMLView hasMarkedText]): Call directly to Editor instead of bridge.
        (-[WebHTMLView unmarkText]): Call new confirmComposition to make it clear that this is
        confirming text, not just unmarking it to discard it.
        (extractUnderlines): Added. Converts directly from an NSAttributedString to the
        CompositionUnderline vector that's used by WebCore.
        (-[WebHTMLView setMarkedText:selectedRange:]): Changed to use the new setComposition.
        (-[WebHTMLView insertText:]): Changed to use confirmComposition when appropriate, instead
        of relying on special behavior of Editor::insertText.
        (-[WebHTMLView _updateSelectionForInputManager]): Rewrote to use getCompositionSelection
        and confirmCompositionWithoutDisturbingSelection.

        * WebCoreSupport/WebEditorClient.h:
        * WebCoreSupport/WebEditorClient.mm:
        Removed obsolete markedTextAbandoned function.

win:

        Reviewed by Oliver.

        - fix <rdar://problem/5470457> REGRESSION: Input method inline hole is mishandled in text
          <input> elements with maxlength limit

        * WebView.cpp:
        (WebView::resetIME): Change to use confirmCompositionWithoutDisturbingSelection.
        (WebView::updateSelectionForIME): Update for name changes, and to use new functions
        in Editor.
        (WebView::onIMEStartComposition): Removed unneeded call to unmarkText.
        (compositionToUnderlines): Removed startOffset parameter, since setComposition now
        handles this.
        (WebView::onIMEComposition): Changed to use confirmComposition and setComposition.
        Logic gets a lot cleaner.
        (WebView::onIMEEndComposition): Removed unneeded calls to Editor.
        (WebView::onIMERequestCharPosition): Updated for name changes.

LayoutTests:

        Reviewed by Oliver.

        - updated test results changed by change in input manager logic

        * platform/mac/editing/input/firstrectforcharacterrange-styled-expected.txt:
        * platform/mac/editing/input/text-input-controller-expected.txt:
        * platform/mac/editing/input/wrapped-line-char-rect-expected.txt:
        Updated. Small changes in which delegate methods are called.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@25547 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d980a28c
2007-09-13 Darin Adler <darin@apple.com>
Reviewed by Oliver.
- updated test results changed by change in input manager logic
* platform/mac/editing/input/firstrectforcharacterrange-styled-expected.txt:
* platform/mac/editing/input/text-input-controller-expected.txt:
* platform/mac/editing/input/wrapped-line-char-rect-expected.txt:
Updated. Small changes in which delegate methods are called.
2007-09-13 Kevin McCullough <kmccullough@apple.com>
Reviewed by Geof, Sam, Adam, Hyatt, Darin.
Reviewed by Geoff, Sam, Adam, Hyatt, Darin.
- <rdar://problem/5480234> JS setTimeout function requires a second argument
- Removed check for number of arguments in setTimeout to behave like other browsers.
EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of BODY > HTML > #document to 4 of BODY > HTML > #document
EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
......
......@@ -14,11 +14,11 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldDeleteDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 7 of #text > DIV > BODY > HTML > #document
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
......@@ -27,5 +27,15 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldInsertText:Success replacingDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
Success
EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of P > BODY > HTML > #document to 0 of P > BODY > HTML > #document
EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
......
2007-09-13 Darin Adler <darin@apple.com>
Reviewed by Oliver.
- fix <rdar://problem/5470457> REGRESSION: Input method inline hole is mishandled in text
<input> elements with maxlength limit
* editing/Editor.h: Moved MarkedTextUnderline here and renamed it CompositionUnderline.
Moved the rest of the marked text API here and used the term that will be more familiar
to those on platforms other than Macintosh, "composition". This helps prevent confusion
with the other kinds of mark -- the emacs "mark" and spelling/grammar marks. Also
cleaned up the conditionals a bit for the Macintosh-specific parts of this header.
* editing/Editor.cpp:
(WebCore::Editor::Editor): Updated for name change.
(WebCore::Editor::clear): Added. To be called by FrameLoader::clear().
(WebCore::Editor::insertTextWithoutSendingTextEvent): Removed code to make inserted
text replace the marked text range -- we now deal with this explicitly by not
calling this function to replace marked text. Also removed unneeded code that was
specific to the use of this to replace the marked text.
(WebCore::Editor::selectComposition): Renamed from selectMarkedText. Updated since
the composition range is not stored as a Range.
(WebCore::Editor::confirmComposition): Added. To be called when changing a composition
into actual text. Unlike the old code path, deletes the composition first, then inserts
the text, triggering the normal insertion code path and events. This is helpful because
it means the inserted text will be truncated by the <input> element, for example.
(WebCore::Editor::confirmCompositionWithoutDisturbingSelection): Added.
(WebCore::Editor::setComposition): Added. To be called when changing the composition.
Takes parameters for the underlines and selection. Unlike the old code path, this passes
a flag down that indicates the inserted text is part of a composition. This is helpful
because we don't send the event that will cause the <input> element to do truncation.
It's also a better API for future improvements to our input method handling.
(WebCore::Editor::revealSelectionAfterEditingOperation): Updated for name change.
(WebCore::Editor::setIgnoreCompositionSelectionChange): Ditto.
(WebCore::Editor::compositionRange): Added. Needed now that the composition is not
stored as a Range.
(WebCore::Editor::getCompositionSelection): Added.
* editing/TypingCommand.h:
* editing/TypingCommand.cpp: (WebCore::TypingCommand::insertText):
Added an insertedTextIsComposition parameter, and don't send the BeforeTextInsertedEvent
if it's true.
* loader/FrameLoader.cpp: (WebCore::FrameLoader::clear): Replaced the Macintosh-specific
call to setMarkedTextRange with a call to the new Editor::clear().
* page/Frame.h:
* page/Frame.cpp:
* page/FramePrivate.h:
* page/mac/FrameMac.mm:
Removed the marked text code. It was streamlined and moved to Editor, except for the
Mac-specific code, which was moved into WebKit.
* page/mac/WebCoreFrameBridge.h:
* page/mac/WebCoreFrameBridge.mm: Removed some now-unneeded marked text code.
(-[WebCoreFrameBridge markedTextNSRange]): Updated for name/API change.
* rendering/InlineTextBox.h:
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paint): Updated marked text code for name changes, and also
streamlined the code a bit for the case where there is no composition.
(WebCore::InlineTextBox::paintCompositionBackground): Name change.
(WebCore::InlineTextBox::paintCompositionUnderline): Ditto.
* rendering/RenderTextControl.h:
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::finishText): Added. Helper function shared by the
(WebCore::RenderTextControl::text):
(WebCore::getNextSoftBreak):
(WebCore::RenderTextControl::textWithHardLineBreaks):
* platform/CharacterNames.h: Added newlineCharacter.
* dom/Range.h: Remove the now-unneeded version of toString that converts <br>
elements into newlines.
* dom/Range.cpp:
(WebCore::Range::toString): Changed this to use a Vector<UChar> instead of
a String so it will not have pathological reallocation performance, and removed
the <br> feature.
(WebCore::Range::pastEndNode): Made this return 0 when there is no start node.
This bit of extra robustness guarantees you can't do a null dereference if the
start node is 0 and the end node is not. Not sure this case really exists.
* page/ContextMenuController.cpp: (ContextMenuController::contextMenuItemSelected):
Removed a semi-bogus use of Range::toString(true). The right function to use here
is plainText().
* bridge/EditorClient.h: Removed obsolete markedTextAbandoned function.
* WebCore.exp: Updated for above changes.
2007-09-13 Anders Carlsson <andersca@apple.com>
Reviewed by Adam and Geoff.
......@@ -310,6 +310,7 @@ __ZN7WebCore16MIMETypeRegistry32isSupportedImageResourceMIMETypeERKNS_6StringE
__ZN7WebCore16NavigationActionC1ERKNS_4KURLENS_13FrameLoadTypeEb
__ZN7WebCore16NavigationActionC1ERKNS_4KURLENS_14NavigationTypeE
__ZN7WebCore16NavigationActionC1Ev
__ZN7WebCore16colorFromNSColorEP7NSColor
__ZN7WebCore18PlatformMouseEventC1EP7NSEvent
__ZN7WebCore19InspectorController16setWindowVisibleEb
__ZN7WebCore19InspectorController7inspectEPNS_4NodeE
......@@ -373,7 +374,6 @@ __ZN7WebCore5Frame18windowScriptObjectEv
__ZN7WebCore5Frame20setSelectionFromNoneEv
__ZN7WebCore5Frame20windowScriptNPObjectEv
__ZN7WebCore5Frame21setProhibitsScrollingEb
__ZN7WebCore5Frame23selectRangeInMarkedTextEjj
__ZN7WebCore5Frame26dashboardRegionsDictionaryEv
__ZN7WebCore5Frame29cleanupScriptObjectsForPluginEPv
__ZN7WebCore5Frame4initEv
......@@ -389,7 +389,6 @@ __ZN7WebCore5equalEPKNS_10StringImplEPKc
__ZN7WebCore5equalEPKNS_10StringImplES2_
__ZN7WebCore6Editor10applyStyleEPNS_19CSSStyleDeclarationENS_10EditActionE
__ZN7WebCore6Editor10insertTextERKNS_6StringEPNS_5EventE
__ZN7WebCore6Editor10unmarkTextEv
__ZN7WebCore6Editor11canDHTMLCutEv
__ZN7WebCore6Editor11deleteRangeEPNS_5RangeEbbbNS_18EditorDeleteActionENS_15TextGranularityE
__ZN7WebCore6Editor11execCommandERKNS_12AtomicStringEPNS_5EventE
......@@ -400,11 +399,11 @@ __ZN7WebCore6Editor13canDHTMLPasteEv
__ZN7WebCore6Editor13performDeleteEv
__ZN7WebCore6Editor13rangeForPointERKNS_8IntPointE
__ZN7WebCore6Editor13tryDHTMLPasteEv
__ZN7WebCore6Editor14setCompositionERKNS_6StringERKN3WTF6VectorINS_20CompositionUnderlineELm0EEEjj
__ZN7WebCore6Editor16pasteAsPlainTextEv
__ZN7WebCore6Editor16selectMarkedTextEv
__ZN7WebCore6Editor17discardMarkedTextEv
__ZN7WebCore6Editor17insertOrderedListEv
__ZN7WebCore6Editor17replaceMarkedTextERKNS_6StringE
__ZN7WebCore6Editor18confirmCompositionERKNS_6StringE
__ZN7WebCore6Editor18confirmCompositionEv
__ZN7WebCore6Editor19deleteWithDirectionENS_19SelectionController10EDirectionENS_15TextGranularityEbb
__ZN7WebCore6Editor19insertUnorderedListEv
__ZN7WebCore6Editor21applyStyleToSelectionEPNS_19CSSStyleDeclarationENS_10EditActionE
......@@ -420,9 +419,10 @@ __ZN7WebCore6Editor30deleteSelectionWithSmartDeleteEb
__ZN7WebCore6Editor32guessesForUngrammaticalSelectionEv
__ZN7WebCore6Editor33increaseSelectionListLevelOrderedEv
__ZN7WebCore6Editor33insertTextWithoutSendingTextEventERKNS_6StringEbPNS_5EventE
__ZN7WebCore6Editor34setIgnoreMarkedTextSelectionChangeEb
__ZN7WebCore6Editor35increaseSelectionListLevelUnorderedEv
__ZN7WebCore6Editor35setIgnoreCompositionSelectionChangeEb
__ZN7WebCore6Editor3cutEv
__ZN7WebCore6Editor44confirmCompositionWithoutDisturbingSelectionEv
__ZN7WebCore6Editor4copyEv
__ZN7WebCore6Editor5pasteEv
__ZN7WebCore6Editor6indentEv
......@@ -648,6 +648,7 @@ __ZNK7WebCore5Range9startNodeEv
__ZNK7WebCore6Editor13canEditRichlyEv
__ZNK7WebCore6Editor17shouldDeleteRangeEPNS_5RangeE
__ZNK7WebCore6Editor22selectionStartHasStyleEPNS_19CSSStyleDeclarationE
__ZNK7WebCore6Editor23getCompositionSelectionERjS1_
__ZNK7WebCore6Editor6canCutEv
__ZNK7WebCore6Editor7canCopyEv
__ZNK7WebCore6Editor7canEditEv
......
......@@ -119,8 +119,6 @@ public:
virtual void textDidChangeInTextArea(Element*) = 0;
#if PLATFORM(MAC)
virtual void markedTextAbandoned(Frame*) = 0;
// FIXME: This should become SelectionController::toWebArchive()
virtual NSData* dataForArchivedSelection(Frame*) = 0;
......
/**
* This file is part of the DOM implementation for KDE.
*
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
* (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2004 Apple Computer, Inc.
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -41,6 +39,7 @@
namespace WebCore {
using namespace std;
using namespace HTMLNames;
#ifndef NDEBUG
......@@ -1030,32 +1029,26 @@ void Range::insertNode(PassRefPtr<Node> newNode, ExceptionCode& ec)
}
String Range::toString(ExceptionCode& ec) const
{
return toString(false, ec);
}
String Range::toString(bool convertBRsToNewlines, ExceptionCode& ec) const
{
if (m_detached) {
ec = INVALID_STATE_ERR;
return String();
}
String text = "";
Node *pastEnd = pastEndNode();
for (Node *n = startNode(); n != pastEnd; n = n->traverseNextNode()) {
Vector<UChar> result;
Node* pastEnd = pastEndNode();
for (Node* n = startNode(); n != pastEnd; n = n->traverseNextNode()) {
if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) {
String str = static_cast<Text *>(n)->data().copy();
if (n == m_endContainer)
str.truncate(m_endOffset);
if (n == m_startContainer)
str.remove(0, m_startOffset);
text += str;
String data = static_cast<CharacterData*>(n)->data();
unsigned length = data.length();
unsigned start = (n == m_startContainer) ? min(m_startOffset, length) : 0;
unsigned end = (n == m_endContainer) ? min(max(start, m_endOffset), length) : length;
result.append(data.characters() + start, end - start);
}
if (n->hasTagName(brTag) && convertBRsToNewlines)
text += "\n";
}
return text;
return String::adopt(result);
}
String Range::toHTML() const
......@@ -1530,7 +1523,7 @@ Position Range::editingStartPosition() const
Node *Range::pastEndNode() const
{
if (!m_endContainer)
if (!m_startContainer || !m_endContainer)
return 0;
if (m_endContainer->offsetInCharacters())
return m_endContainer->traverseNextSibling();
......
......@@ -79,7 +79,6 @@ public:
PassRefPtr<DocumentFragment> cloneContents(ExceptionCode&);
void insertNode(PassRefPtr<Node>, ExceptionCode&);
String toString(ExceptionCode&) const;
String toString(bool convertBRsToNewlines, ExceptionCode&) const;
String toHTML() const;
String text() const;
......
......@@ -64,6 +64,7 @@
#include "ReplaceSelectionCommand.h"
#include "SelectionController.h"
#include "Sound.h"
#include "Text.h"
#include "TextIterator.h"
#include "TypingCommand.h"
#include "htmlediting.h"
......@@ -73,6 +74,8 @@
namespace WebCore {
class FontData;
using namespace std;
using namespace EventNames;
using namespace HTMLNames;
......@@ -1354,7 +1357,7 @@ static CommandMap* createCommandMap()
Editor::Editor(Frame* frame)
: m_frame(frame)
, m_deleteButtonController(new DeleteButtonController(frame))
, m_ignoreMarkedTextSelectionChange(false)
, m_ignoreCompositionSelectionChange(false)
{
}
......@@ -1362,6 +1365,12 @@ Editor::~Editor()
{
}
void Editor::clear()
{
m_compositionNode = 0;
m_customCompositionUnderlines.clear();
}
bool Editor::execCommand(const AtomicString& command, Event* triggeringEvent)
{
if (!m_frame->document())
......@@ -1395,28 +1404,18 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
if (text.isEmpty())
return false;
RefPtr<Range> range = m_frame->markedTextRange();
if (!range) {
Selection selection = selectionForEvent(m_frame, triggeringEvent);
if (!selection.isContentEditable())
return false;
range = selection.toRange();
}
Selection selection = selectionForEvent(m_frame, triggeringEvent);
if (!selection.isContentEditable())
return false;
RefPtr<Range> range = selection.toRange();
if (!shouldInsertText(text, range.get(), EditorInsertActionTyped)) {
discardMarkedText();
if (!shouldInsertText(text, range.get(), EditorInsertActionTyped))
return true;
}
setIgnoreMarkedTextSelectionChange(true);
// If we had marked text, replace that instead of the selection/caret.
selectMarkedText();
// Get the selection to use for the event that triggered this insertText.
// If the event handler changed the selection, we may want to use a different selection
// that is contained in the event target.
Selection selection = selectionForEvent(m_frame, triggeringEvent);
selection = selectionForEvent(m_frame, triggeringEvent);
if (selection.isContentEditable()) {
if (Node* selectionStart = selection.start().node()) {
RefPtr<Document> document = selectionStart->document();
......@@ -1431,11 +1430,6 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
}
}
setIgnoreMarkedTextSelectionChange(false);
// Inserting unmarks any marked text.
unmarkText();
return true;
}
......@@ -1664,54 +1658,103 @@ void Editor::setBaseWritingDirection(String direction)
applyParagraphStyleToSelection(style.get(), EditActionSetWritingDirection);
}
void Editor::selectMarkedText()
void Editor::selectComposition()
{
Range* range = m_frame->markedTextRange();
RefPtr<Range> range = compositionRange();
if (!range)
return;
ExceptionCode ec = 0;
m_frame->selectionController()->setSelectedRange(m_frame->markedTextRange(), DOWNSTREAM, false, ec);
m_frame->selectionController()->setSelectedRange(range.get(), DOWNSTREAM, false, ec);
}
void Editor::discardMarkedText()
void Editor::confirmComposition()
{
if (!m_frame->markedTextRange())
if (!m_compositionNode)
return;
confirmComposition(m_compositionNode->data().substring(m_compositionStart, m_compositionEnd - m_compositionStart), false);
}
setIgnoreMarkedTextSelectionChange(true);
selectMarkedText();
unmarkText();
#if PLATFORM(MAC)
if (EditorClient* c = client())
c->markedTextAbandoned(m_frame);
#endif
deleteSelectionWithSmartDelete(false);
void Editor::confirmCompositionWithoutDisturbingSelection()
{
if (!m_compositionNode)
return;
confirmComposition(m_compositionNode->data().substring(m_compositionStart, m_compositionEnd - m_compositionStart), true);
}
setIgnoreMarkedTextSelectionChange(false);
void Editor::confirmComposition(const String& text)
{
confirmComposition(text, false);
}
void Editor::unmarkText()
void Editor::confirmComposition(const String& text, bool preserveSelection)
{
Vector<MarkedTextUnderline> underlines;
m_frame->setMarkedTextRange(0, underlines);
setIgnoreCompositionSelectionChange(true);
Selection oldSelection = m_frame->selectionController()->selection();
selectComposition();
if (m_frame->selectionController()->isNone()) {
setIgnoreCompositionSelectionChange(false);
return;
}
deleteSelectionWithSmartDelete(false);
m_compositionNode = 0;
m_customCompositionUnderlines.clear();
insertText(text, 0);
if (preserveSelection)
m_frame->selectionController()->setSelection(oldSelection, false, false);
setIgnoreCompositionSelectionChange(false);
}
void Editor::replaceMarkedText(const String& text)
void Editor::setComposition(const String& text, const Vector<CompositionUnderline>& underlines, unsigned selectionStart, unsigned selectionEnd)
{
if (m_frame->selectionController()->isNone())
setIgnoreCompositionSelectionChange(true);
selectComposition();
if (m_frame->selectionController()->isNone()) {
setIgnoreCompositionSelectionChange(false);
return;
int exception = 0;
Range *markedTextRange = m_frame->markedTextRange();
if (markedTextRange && !markedTextRange->collapsed(exception))
TypingCommand::deleteKeyPressed(m_frame->document(), false);
if (!text.isEmpty())
TypingCommand::insertText(m_frame->document(), text, true);
revealSelectionAfterEditingOperation();
}
deleteSelectionWithSmartDelete(false);
if (!text.isEmpty()) {
TypingCommand::insertText(m_frame->document(), text, true, true);
Node* baseNode = m_frame->selectionController()->baseNode();
unsigned baseOffset = m_frame->selectionController()->base().offset();
Node* extentNode = m_frame->selectionController()->extentNode();
unsigned extentOffset = m_frame->selectionController()->extent().offset();
if (baseNode && baseNode == extentNode && baseNode->isTextNode() && baseOffset + text.length() == extentOffset) {
m_compositionNode = static_cast<Text*>(baseNode);
m_compositionStart = baseOffset;
m_compositionEnd = extentOffset;
m_customCompositionUnderlines = underlines;
size_t numUnderlines = m_customCompositionUnderlines.size();
for (size_t i = 0; i < numUnderlines; ++i) {
m_customCompositionUnderlines[i].startOffset += baseOffset;
m_customCompositionUnderlines[i].endOffset += baseOffset;
}
if (baseNode->renderer())
baseNode->renderer()->repaint();
unsigned start = min(baseOffset + selectionStart, extentOffset);
unsigned end = min(max(start, baseOffset + selectionEnd), extentOffset);
RefPtr<Range> selectedRange = new Range(baseNode->document(), baseNode, start, baseNode, end);
ExceptionCode ec = 0;
m_frame->selectionController()->setSelectedRange(selectedRange.get(), DOWNSTREAM, false, ec);
}
}
setIgnoreCompositionSelectionChange(false);
}
void Editor::ignoreSpelling()
......@@ -2269,8 +2312,7 @@ void Editor::markBadGrammar(const Selection& selection)
markMisspellingsOrBadGrammar(this, selection, false);
#endif
}
PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
{
Document* document = m_frame->documentAtPoint(windowPoint);
......@@ -2289,20 +2331,53 @@ PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
void Editor::revealSelectionAfterEditingOperation()
{
if (m_ignoreMarkedTextSelectionChange)
if (m_ignoreCompositionSelectionChange)
return;
m_frame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
}
void Editor::setIgnoreMarkedTextSelectionChange(bool ignore)
void Editor::setIgnoreCompositionSelectionChange(bool ignore)
{
if (m_ignoreMarkedTextSelectionChange == ignore)
if (m_ignoreCompositionSelectionChange == ignore)
return;
m_ignoreMarkedTextSelectionChange = ignore;
m_ignoreCompositionSelectionChange = ignore;
if (!ignore)
revealSelectionAfterEditingOperation();
}
PassRefPtr<Range> Editor::compositionRange() const
{
if (!m_compositionNode)
return 0;
unsigned length = m_compositionNode->length();
unsigned start = min(m_compositionStart, length);
unsigned end = min(max(start, m_compositionEnd), length);
if (start >= end)
return 0;
return new Range(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end);
}
bool Editor::getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const
{
if (!m_compositionNode)
return false;
Position start = m_frame->selectionController()->start();
if (start.node() != m_compositionNode)
return false;
Position end = m_frame->selectionController()->end();
if (end.node() != m_compositionNode)
return false;
if (static_cast<unsigned>(start.offset()) < m_compositionStart)
return false;
if (static_cast<unsigned>(end.offset()) > m_compositionEnd)
return false;
selectionStart = start.offset() - m_compositionStart;
selectionEnd = start.offset() - m_compositionEnd;
return true;
}
} // namespace WebCore
......@@ -56,6 +56,17 @@ class Range;
class SelectionController;
class Selection;
struct CompositionUnderline {
CompositionUnderline()
: startOffset(0), endOffset(0), thick(false) { }
CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t)
: startOffset(s), endOffset(e), color(c), thick(t) { }
unsigned startOffset;
unsigned endOffset;
Color color;
bool thick;
};
class Editor {
public:
Editor(Frame*);
......@@ -193,29 +204,45 @@ public:
bool smartInsertDeleteEnabled();
void selectMarkedText();
void unmarkText();
void discardMarkedText();
void replaceMarkedText(const String&);
bool ignoreMarkedTextSelectionChange() const { return m_ignoreMarkedTextSelectionChange; }
void setIgnoreMarkedTextSelectionChange(bool ignore);
// international text input composition
bool hasComposition() const { return m_compositionNode; }
void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
void confirmComposition();
void confirmComposition(const String&); // if no existing composition, replaces selection
void confirmCompositionWithoutDisturbingSelection();
PassRefPtr<Range> compositionRange() const;
bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
// getting international text input composition state (for use by InlineTextBox)
Text* compositionNode() const { return m_compositionNode.get(); }
unsigned compositionStart() const { return m_compositionStart; }
unsigned compositionEnd() const { return m_compositionEnd; }
bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; }
void setStartNewKillRingSequence(bool);
#if PLATFORM(MAC)
NSString* userVisibleString(NSURL*);
void setStartNewKillRingSequence(bool flag) { m_startNewKillRingSequence = flag; }
#else
void setStartNewKillRingSequence(bool) { }
#endif
PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
void clear();
private:
Frame* m_frame;
OwnPtr<DeleteButtonController> m_deleteButtonController;
RefPtr<EditCommand> m_lastEditCommand;
RefPtr<Node> m_removedAnchor;
bool m_ignoreMarkedTextSelectionChange;
RefPtr<Text> m_compositionNode;
unsigned m_compositionStart;
unsigned m_compositionEnd;
Vector<CompositionUnderline> m_customCompositionUnderlines;
bool m_ignoreCompositionSelectionChange;
bool canDeleteRange(Range*) const;
bool canSmartCopyOrDelete();
......@@ -229,15 +256,31 @@ private:
void write