[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198
morrita at google.com
morrita at google.com
Sun Feb 20 23:41:00 UTC 2011
The following commit has been merged in the webkit-1.3 branch:
commit 6a3e425fe1e9bfaa74550eb96d90c8f4b7c1a492
Author: morrita at google.com <morrita at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Jan 24 06:53:34 2011 +0000
2011-01-19 MORITA Hajime <morrita at google.com>
Reviewed by Ryosuke Niwa.
Space and tab characters "sent" by an input method give totally different results than typing them directly.
https://bugs.webkit.org/show_bug.cgi?id=5241
Added a test that exercises continous whitespace characters and tabs inserted by IME.
* editing/inserting/insert-composition-whitespace-expected.txt: Added.
* editing/inserting/insert-composition-whitespace.html: Added.
2011-01-19 MORITA Hajime <morrita at google.com>
Reviewed by Ryosuke Niwa.
Space and tab characters "sent" by an input method give totally different results than typing them directly
https://bugs.webkit.org/show_bug.cgi?id=5241
* Introduced TextEvent::InputTypeComposition and TypingCommand::TextCompositionType to
distinguish text input which is originated by composition.
* Generalized rebalanceWhitespaceAt() to rebalanceWhitespaceOnTextSubstring() to rebalancing
range of string on text node, instead of surrounding part of that.
Test: editing/inserting/insert-composition-whitespace.html
* dom/TextEvent.h:
(WebCore::TextEvent::isComposition):
* dom/TextEventInputType.h: Added TextEventInputComposition as a member of TextEvent::InputType
* editing/CompositeEditCommand.cpp:
(WebCore::containsOnlyWhitespace):
(WebCore::CompositeEditCommand::shouldRebalanceLeadingWhitespaceFor):
(WebCore::CompositeEditCommand::canRebalance):
(WebCore::CompositeEditCommand::rebalanceWhitespaceAt):
(WebCore::CompositeEditCommand::rebalanceWhitespaceOnTextSubstring): Added: A generalized version of rebalanceWhitespaceAt(), which takes a range inside Text string.
* editing/CompositeEditCommand.h:
* editing/Editor.cpp:
(WebCore::Editor::insertTextForConfirmedComposition): Added.
(WebCore::Editor::insertTextWithoutSendingTextEvent):
(WebCore::Editor::confirmComposition): Now uses insertTextForConfirmedComposition().
(WebCore::Editor::setComposition):
* editing/Editor.h:
* editing/InsertTextCommand.cpp:
(WebCore::InsertTextCommand::input):
* editing/InsertTextCommand.h:
* editing/TypingCommand.cpp:
(WebCore::TypingCommand::TypingCommand):
(WebCore::TypingCommand::insertText):
(WebCore::TypingCommand::insertTextRunWithoutNewlines):
* editing/TypingCommand.h: Added TypingCommand::m_compositionType and TypingCommand::TextCompositionType
(WebCore::TypingCommand::setCompositionType): Added.
(WebCore::TypingCommand::create):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76482 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d1ec90f..951c77f 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2011-01-19 MORITA Hajime <morrita at google.com>
+
+ Reviewed by Ryosuke Niwa.
+
+ Space and tab characters "sent" by an input method give totally different results than typing them directly.
+ https://bugs.webkit.org/show_bug.cgi?id=5241
+
+ Added a test that exercises continous whitespace characters and tabs inserted by IME.
+
+ * editing/inserting/insert-composition-whitespace-expected.txt: Added.
+ * editing/inserting/insert-composition-whitespace.html: Added.
+
2011-01-23 Yuzo Fujishima <yuzo at google.com>
Unreviewed Chromium test expectation change.
diff --git a/LayoutTests/editing/inserting/insert-composition-whitespace-expected.txt b/LayoutTests/editing/inserting/insert-composition-whitespace-expected.txt
new file mode 100644
index 0000000..ade0725
--- /dev/null
+++ b/LayoutTests/editing/inserting/insert-composition-whitespace-expected.txt
@@ -0,0 +1,94 @@
+PASS compositingText is 'AB'
+PASS confirmedText is 'AB'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is ' A B '
+PASS confirmedText is ' A B '
+PASS compositingText is ' A B '
+PASS confirmedText is ' A B '
+PASS compositingText is ' '
+PASS confirmedText is ' '
+PASS compositingText is ' '
+PASS confirmedText is ' '
+PASS compositingText is ' '
+PASS confirmedText is ' '
+PASS compositingText is 'AB'
+PASS confirmedText is 'AB'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is 'A B'
+PASS confirmedText is 'A B'
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is 'AB '
+PASS confirmedText is 'AB '
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' AB'
+PASS confirmedText is ' AB'
+PASS compositingText is ' A B '
+PASS confirmedText is ' A B '
+PASS compositingText is ' A B '
+PASS confirmedText is ' A B '
+PASS compositingText is ' '
+PASS confirmedText is ' '
+PASS compositingText is ' '
+PASS confirmedText is ' '
+PASS compositingText is ' '
+PASS confirmedText is ' '
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/inserting/insert-composition-whitespace.html b/LayoutTests/editing/inserting/insert-composition-whitespace.html
new file mode 100644
index 0000000..81215dd
--- /dev/null
+++ b/LayoutTests/editing/inserting/insert-composition-whitespace.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+var sel = document.getSelection();
+var root = document.createElement("root");
+document.body.appendChild(root);
+
+
+function createEditable(tagName, text) {
+ var node = document.createElement(tagName);
+ node.contentEditable = true;
+ node.innerHTML = text;
+ return node;
+}
+
+function test(tagName, compositionText, expected) {
+ var node = createEditable(tagName, "X");
+ root.appendChild(node);
+
+ var textNode = node.firstChild;
+ sel.setBaseAndExtent(textNode, 0, textNode, textNode.data.length);
+ document.execCommand("Delete", false);
+
+ textInputController.setMarkedText(compositionText, 0, compositionText.length);
+ compositingText = node.innerText;
+ textInputController.unmarkText();
+ confirmedText = node.innerText;
+
+ shouldBe("compositingText", "'" + expected + "'");
+ shouldBe("confirmedText", "'" + expected + "'");
+}
+
+test("div", "AB", "AB");
+test("div", "A B", "A B");
+test("div", "A B", "A \xA0B");
+test("div", "A B", "A \xA0 B");
+test("div", "A B", "A \xA0 \xA0B");
+
+test("div", " AB", "\xA0AB");
+test("div", " AB", "\xA0\xA0AB");
+test("div", " AB", "\xA0\xA0 AB");
+test("div", " AB", "\xA0\xA0 \xA0AB");
+test("div", " AB", "\xA0\xA0 \xA0 AB");
+test("div", " AB", "\xA0\xA0 \xA0 \xA0AB");
+test("div", " AB", "\xA0\xA0 \xA0 \xA0 AB");
+test("div", "AB ", "AB \xA0");
+test("div", "AB ", "AB \xA0\xA0");
+test("div", "AB ", "AB \xA0 \xA0");
+test("div", "AB ", "AB \xA0 \xA0\xA0");
+test("div", "AB ", "AB \xA0 \xA0 \xA0");
+test("div", "AB ", "AB \xA0 \xA0 \xA0\xA0");
+
+test("div", " A B ", "\xA0\xA0A \xA0B \xA0");
+test("div", "\t\tA\t\tB\t\t", "\xA0\xA0A \xA0B \xA0");
+
+test("div", " ", "\xA0");
+test("div", " ", "\xA0\xA0");
+// This is wrong. This should insert interleaved nbsp and whitespace. See https://bugs.webkit.org/show_bug.cgi?id=52781.
+test("div", " ", "\xA0\xA0\xA0");
+
+test("pre", "AB", "AB");
+test("pre", "A B", "A B");
+test("pre", "A B", "A B");
+test("pre", "A B", "A B");
+test("pre", "A B", "A B");
+test("pre", "AB ", "AB ");
+test("pre", "AB ", "AB ");
+test("pre", "AB ", "AB ");
+test("pre", "AB ", "AB ");
+test("pre", "AB ", "AB ");
+test("pre", "AB ", "AB ");
+test("pre", " AB", " AB");
+test("pre", " AB", " AB");
+test("pre", " AB", " AB");
+test("pre", " AB", " AB");
+test("pre", " AB", " AB");
+test("pre", " AB", " AB");
+
+test("pre", " A B ", " A B ");
+test("pre", "\t\tA\t\tB\t\t", "\t\tA\t\tB\t\t");
+test("pre", " ", " ");
+test("pre", " ", " ");
+test("pre", " ", " ");
+
+root.style.display = "none";
+successfullyParsed = true;
+
+</script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 3f9e5ed..5a1bb1b 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,44 @@
+2011-01-19 MORITA Hajime <morrita at google.com>
+
+ Reviewed by Ryosuke Niwa.
+
+ Space and tab characters "sent" by an input method give totally different results than typing them directly
+ https://bugs.webkit.org/show_bug.cgi?id=5241
+
+ * Introduced TextEvent::InputTypeComposition and TypingCommand::TextCompositionType to
+ distinguish text input which is originated by composition.
+ * Generalized rebalanceWhitespaceAt() to rebalanceWhitespaceOnTextSubstring() to rebalancing
+ range of string on text node, instead of surrounding part of that.
+
+ Test: editing/inserting/insert-composition-whitespace.html
+
+ * dom/TextEvent.h:
+ (WebCore::TextEvent::isComposition):
+ * dom/TextEventInputType.h: Added TextEventInputComposition as a member of TextEvent::InputType
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::containsOnlyWhitespace):
+ (WebCore::CompositeEditCommand::shouldRebalanceLeadingWhitespaceFor):
+ (WebCore::CompositeEditCommand::canRebalance):
+ (WebCore::CompositeEditCommand::rebalanceWhitespaceAt):
+ (WebCore::CompositeEditCommand::rebalanceWhitespaceOnTextSubstring): Added: A generalized version of rebalanceWhitespaceAt(), which takes a range inside Text string.
+ * editing/CompositeEditCommand.h:
+ * editing/Editor.cpp:
+ (WebCore::Editor::insertTextForConfirmedComposition): Added.
+ (WebCore::Editor::insertTextWithoutSendingTextEvent):
+ (WebCore::Editor::confirmComposition): Now uses insertTextForConfirmedComposition().
+ (WebCore::Editor::setComposition):
+ * editing/Editor.h:
+ * editing/InsertTextCommand.cpp:
+ (WebCore::InsertTextCommand::input):
+ * editing/InsertTextCommand.h:
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::TypingCommand):
+ (WebCore::TypingCommand::insertText):
+ (WebCore::TypingCommand::insertTextRunWithoutNewlines):
+ * editing/TypingCommand.h: Added TypingCommand::m_compositionType and TypingCommand::TextCompositionType
+ (WebCore::TypingCommand::setCompositionType): Added.
+ (WebCore::TypingCommand::create):
+
2011-01-23 Mark Rowe <mrowe at apple.com>
Follow-up to r76477.
diff --git a/Source/WebCore/dom/TextEvent.h b/Source/WebCore/dom/TextEvent.h
index d770d38..26c8b93 100644
--- a/Source/WebCore/dom/TextEvent.h
+++ b/Source/WebCore/dom/TextEvent.h
@@ -51,6 +51,7 @@ namespace WebCore {
virtual bool isTextEvent() const;
bool isLineBreak() const { return m_inputType == TextEventInputLineBreak; }
+ bool isComposition() const { return m_inputType == TextEventInputComposition; }
bool isBackTab() const { return m_inputType == TextEventInputBackTab; }
bool isPaste() const { return m_inputType == TextEventInputPaste; }
bool isDrop() const { return m_inputType == TextEventInputDrop; }
diff --git a/Source/WebCore/dom/TextEventInputType.h b/Source/WebCore/dom/TextEventInputType.h
index 2522ec4..f5a05eb 100644
--- a/Source/WebCore/dom/TextEventInputType.h
+++ b/Source/WebCore/dom/TextEventInputType.h
@@ -31,6 +31,7 @@ namespace WebCore {
enum TextEventInputType {
TextEventInputKeyboard, // any newline characters in the text are line breaks only, not paragraph separators.
TextEventInputLineBreak, // any tab characters in the text are backtabs.
+ TextEventInputComposition,
TextEventInputBackTab,
TextEventInputPaste,
TextEventInputDrop,
diff --git a/Source/WebCore/editing/CompositeEditCommand.cpp b/Source/WebCore/editing/CompositeEditCommand.cpp
index 552ed79..39280d4 100644
--- a/Source/WebCore/editing/CompositeEditCommand.cpp
+++ b/Source/WebCore/editing/CompositeEditCommand.cpp
@@ -395,52 +395,84 @@ static inline bool isWhitespace(UChar c)
return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t';
}
-// FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, cousins, etc).
-void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position)
+static inline bool containsOnlyWhitespace(const String& text)
+{
+ for (unsigned i = 0; i < text.length(); ++i) {
+ if (!isWhitespace(text.characters()[i]))
+ return false;
+ }
+
+ return true;
+}
+
+bool CompositeEditCommand::shouldRebalanceLeadingWhitespaceFor(const String& text) const
+{
+ return containsOnlyWhitespace(text);
+}
+
+bool CompositeEditCommand::canRebalance(const Position& position) const
{
Node* node = position.containerNode();
if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node || !node->isTextNode())
- return;
- Text* textNode = static_cast<Text*>(node);
+ return false;
+ Text* textNode = static_cast<Text*>(node);
if (textNode->length() == 0)
- return;
+ return false;
+
RenderObject* renderer = textNode->renderer();
if (renderer && !renderer->style()->collapseWhiteSpace())
- return;
+ return false;
- String text = textNode->data();
- ASSERT(!text.isEmpty());
+ return true;
+}
+
+// FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, cousins, etc).
+void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position)
+{
+ Node* node = position.containerNode();
+ if (!canRebalance(position))
+ return;
+ // If the rebalance is for the single offset, and neither text[offset] nor text[offset - 1] are some form of whitespace, do nothing.
int offset = position.deprecatedEditingOffset();
- // If neither text[offset] nor text[offset - 1] are some form of whitespace, do nothing.
+ String text = static_cast<Text*>(node)->data();
if (!isWhitespace(text[offset])) {
offset--;
if (offset < 0 || !isWhitespace(text[offset]))
return;
}
-
+
+ rebalanceWhitespaceOnTextSubstring(static_cast<Text*>(node), position.offsetInContainerNode(), position.offsetInContainerNode());
+}
+
+void CompositeEditCommand::rebalanceWhitespaceOnTextSubstring(RefPtr<Text> textNode, int startOffset, int endOffset)
+{
+ String text = textNode->data();
+ ASSERT(!text.isEmpty());
+
// Set upstream and downstream to define the extent of the whitespace surrounding text[offset].
- int upstream = offset;
+ int upstream = startOffset;
while (upstream > 0 && isWhitespace(text[upstream - 1]))
upstream--;
- int downstream = offset;
- while ((unsigned)downstream + 1 < text.length() && isWhitespace(text[downstream + 1]))
+ int downstream = endOffset;
+ while ((unsigned)downstream < text.length() && isWhitespace(text[downstream]))
downstream++;
- int length = downstream - upstream + 1;
- ASSERT(length > 0);
-
- VisiblePosition visibleUpstreamPos(Position(position.containerNode(), upstream, Position::PositionIsOffsetInAnchor));
- VisiblePosition visibleDownstreamPos(Position(position.containerNode(), downstream + 1, Position::PositionIsOffsetInAnchor));
+ int length = downstream - upstream;
+ if (!length)
+ return;
+
+ VisiblePosition visibleUpstreamPos(Position(textNode, upstream, Position::PositionIsOffsetInAnchor));
+ VisiblePosition visibleDownstreamPos(Position(textNode, downstream, Position::PositionIsOffsetInAnchor));
String string = text.substring(upstream, length);
String rebalancedString = stringWithRebalancedWhitespace(string,
// FIXME: Because of the problem mentioned at the top of this function, we must also use nbsps at the start/end of the string because
// this function doesn't get all surrounding whitespace, just the whitespace in the current text node.
isStartOfParagraph(visibleUpstreamPos) || upstream == 0,
- isEndOfParagraph(visibleDownstreamPos) || (unsigned)downstream == text.length() - 1);
+ isEndOfParagraph(visibleDownstreamPos) || (unsigned)downstream == text.length());
if (string != rebalancedString)
replaceTextInNode(textNode, upstream, length, rebalancedString);
diff --git a/Source/WebCore/editing/CompositeEditCommand.h b/Source/WebCore/editing/CompositeEditCommand.h
index 6db4eb1..9066b65 100644
--- a/Source/WebCore/editing/CompositeEditCommand.h
+++ b/Source/WebCore/editing/CompositeEditCommand.h
@@ -71,7 +71,10 @@ protected:
void mergeIdenticalElements(PassRefPtr<Element>, PassRefPtr<Element>);
void rebalanceWhitespace();
void rebalanceWhitespaceAt(const Position&);
+ void rebalanceWhitespaceOnTextSubstring(RefPtr<Text>, int startOffset, int endOffset);
void prepareWhitespaceAtPositionForSplit(Position&);
+ bool canRebalance(const Position&) const;
+ bool shouldRebalanceLeadingWhitespaceFor(const String&) const;
void removeCSSProperty(PassRefPtr<StyledElement>, CSSPropertyID);
void removeNodeAttribute(PassRefPtr<Element>, const QualifiedName& attribute);
void removeChildrenInRange(PassRefPtr<Node>, unsigned from, unsigned to);
diff --git a/Source/WebCore/editing/Editor.cpp b/Source/WebCore/editing/Editor.cpp
index 23b41ce..3acec27 100644
--- a/Source/WebCore/editing/Editor.cpp
+++ b/Source/WebCore/editing/Editor.cpp
@@ -1173,7 +1173,12 @@ bool Editor::insertText(const String& text, Event* triggeringEvent)
return m_frame->eventHandler()->handleTextInputEvent(text, triggeringEvent);
}
-bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectInsertedText, Event* triggeringEvent)
+bool Editor::insertTextForConfirmedComposition(const String& text)
+{
+ return m_frame->eventHandler()->handleTextInputEvent(text, 0, TextEventInputComposition);
+}
+
+bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectInsertedText, TextEvent* triggeringEvent)
{
if (text.isEmpty())
return false;
@@ -1195,7 +1200,8 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
RefPtr<Document> document = selectionStart->document();
// Insert the text
- TypingCommand::insertText(document.get(), text, selection, selectInsertedText);
+ TypingCommand::insertText(document.get(), text, selection, selectInsertedText,
+ triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionConfirm : TypingCommand::TextCompositionNone);
// Reveal the current selection
if (Frame* editedFrame = document->frame())
@@ -1618,7 +1624,7 @@ void Editor::confirmComposition(const String& text, bool preserveSelection)
m_compositionNode = 0;
m_customCompositionUnderlines.clear();
- insertText(text, 0);
+ insertTextForConfirmedComposition(text);
if (preserveSelection) {
m_frame->selection()->setSelection(oldSelection, false, false);
@@ -1687,7 +1693,7 @@ void Editor::setComposition(const String& text, const Vector<CompositionUnderlin
m_customCompositionUnderlines.clear();
if (!text.isEmpty()) {
- TypingCommand::insertText(m_frame->document(), text, true, true);
+ TypingCommand::insertText(m_frame->document(), text, true, TypingCommand::TextCompositionUpdate);
// Find out what node has the composition now.
Position base = m_frame->selection()->base().downstream();
diff --git a/Source/WebCore/editing/Editor.h b/Source/WebCore/editing/Editor.h
index 2e61ce6..1e6e387 100644
--- a/Source/WebCore/editing/Editor.h
+++ b/Source/WebCore/editing/Editor.h
@@ -198,7 +198,8 @@ public:
static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame.
bool insertText(const String&, Event* triggeringEvent);
- bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, Event* triggeringEvent);
+ bool insertTextForConfirmedComposition(const String& text);
+ bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent);
bool insertLineBreak();
bool insertParagraphSeparator();
diff --git a/Source/WebCore/editing/InsertTextCommand.cpp b/Source/WebCore/editing/InsertTextCommand.cpp
index fc18e91..74a111a 100644
--- a/Source/WebCore/editing/InsertTextCommand.cpp
+++ b/Source/WebCore/editing/InsertTextCommand.cpp
@@ -106,7 +106,7 @@ bool InsertTextCommand::performTrivialReplace(const String& text, bool selectIns
return true;
}
-void InsertTextCommand::input(const String& text, bool selectInsertedText)
+void InsertTextCommand::input(const String& text, bool selectInsertedText, RebalanceType whitespaceRebalance)
{
ASSERT(text.find('\n') == notFound);
@@ -172,11 +172,17 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText)
insertTextIntoNode(textNode, offset, text);
endPosition = Position(textNode, offset + text.length());
- // The insertion may require adjusting adjacent whitespace, if it is present.
- rebalanceWhitespaceAt(endPosition);
- // Rebalancing on both sides isn't necessary if we've inserted a space.
- if (text != " ")
- rebalanceWhitespaceAt(startPosition);
+ if (whitespaceRebalance == RebalanceLeadingAndTrailingWhitespaces) {
+ // The insertion may require adjusting adjacent whitespace, if it is present.
+ rebalanceWhitespaceAt(endPosition);
+ // Rebalancing on both sides isn't necessary if we've inserted only spaces.
+ if (!shouldRebalanceLeadingWhitespaceFor(text))
+ rebalanceWhitespaceAt(startPosition);
+ } else {
+ ASSERT(whitespaceRebalance == RebalanceAllWhitespaces);
+ if (canRebalance(startPosition) && canRebalance(endPosition))
+ rebalanceWhitespaceOnTextSubstring(textNode, startPosition.deprecatedEditingOffset(), endPosition.deprecatedEditingOffset());
+ }
}
// We could have inserted a part of composed character sequence,
diff --git a/Source/WebCore/editing/InsertTextCommand.h b/Source/WebCore/editing/InsertTextCommand.h
index 77ae016..672e576 100644
--- a/Source/WebCore/editing/InsertTextCommand.h
+++ b/Source/WebCore/editing/InsertTextCommand.h
@@ -32,14 +32,20 @@ namespace WebCore {
class InsertTextCommand : public CompositeEditCommand {
public:
+ enum RebalanceType {
+ RebalanceLeadingAndTrailingWhitespaces,
+ RebalanceAllWhitespaces
+ };
+
static PassRefPtr<InsertTextCommand> create(Document* document)
{
return adoptRef(new InsertTextCommand(document));
}
- void input(const String& text, bool selectInsertedText = false);
+ void input(const String& text, bool selectInsertedText = false, RebalanceType = RebalanceLeadingAndTrailingWhitespaces);
private:
+
InsertTextCommand(Document*);
void deleteCharacter();
diff --git a/Source/WebCore/editing/TypingCommand.cpp b/Source/WebCore/editing/TypingCommand.cpp
index d54b388..21d4314 100644
--- a/Source/WebCore/editing/TypingCommand.cpp
+++ b/Source/WebCore/editing/TypingCommand.cpp
@@ -47,7 +47,8 @@ namespace WebCore {
using namespace HTMLNames;
-TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, const String &textToInsert, bool selectInsertedText, TextGranularity granularity, bool killRing)
+TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, const String &textToInsert, bool selectInsertedText, TextGranularity granularity, TextCompositionType compositionType,
+ bool killRing)
: CompositeEditCommand(document),
m_commandType(commandType),
m_textToInsert(textToInsert),
@@ -55,6 +56,7 @@ TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, con
m_selectInsertedText(selectInsertedText),
m_smartDelete(false),
m_granularity(granularity),
+ m_compositionType(compositionType),
m_killRing(killRing),
m_openedByBackwardDelete(false)
{
@@ -133,18 +135,18 @@ void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand
}
-void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText, bool insertedTextIsComposition)
+void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText, TextCompositionType composition)
{
ASSERT(document);
Frame* frame = document->frame();
ASSERT(frame);
- insertText(document, text, frame->selection()->selection(), selectInsertedText, insertedTextIsComposition);
+ insertText(document, text, frame->selection()->selection(), selectInsertedText, composition);
}
// FIXME: We shouldn't need to take selectionForInsertion. It should be identical to SelectionController's current selection.
-void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition)
+void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, TextCompositionType compositionType)
{
#if REMOVE_MARKERS_UPON_EDITING
if (!text.isEmpty())
@@ -161,7 +163,7 @@ void TypingCommand::insertText(Document* document, const String& text, const Vis
String newText = text;
Node* startNode = selectionForInsertion.start().node();
- if (startNode && startNode->rootEditableElement() && !insertedTextIsComposition) {
+ if (startNode && startNode->rootEditableElement() && compositionType != TextCompositionUpdate) {
// Send BeforeTextInsertedEvent. The event handler will update text if necessary.
ExceptionCode ec = 0;
RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
@@ -182,11 +184,13 @@ void TypingCommand::insertText(Document* document, const String& text, const Vis
lastTypingCommand->setStartingSelection(selectionForInsertion);
lastTypingCommand->setEndingSelection(selectionForInsertion);
}
+
+ lastTypingCommand->setCompositionType(compositionType);
lastTypingCommand->insertText(newText, selectInsertedText);
return;
}
- RefPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, selectInsertedText);
+ RefPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, selectInsertedText, compositionType);
if (changeSelection) {
cmd->setStartingSelection(selectionForInsertion);
cmd->setEndingSelection(selectionForInsertion);
@@ -386,7 +390,8 @@ void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool select
command->setStartingSelection(endingSelection());
command->setEndingSelection(endingSelection());
}
- command->input(text, selectInsertedText);
+ command->input(text, selectInsertedText,
+ m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces);
typingAddedToOpenCommand(InsertText);
}
diff --git a/Source/WebCore/editing/TypingCommand.h b/Source/WebCore/editing/TypingCommand.h
index 284ebc0..b34bdc1 100644
--- a/Source/WebCore/editing/TypingCommand.h
+++ b/Source/WebCore/editing/TypingCommand.h
@@ -42,11 +42,17 @@ public:
InsertParagraphSeparatorInQuotedContent
};
+ enum TextCompositionType {
+ TextCompositionNone,
+ TextCompositionUpdate,
+ TextCompositionConfirm
+ };
+
static void deleteSelection(Document*, bool smartDelete = false);
static void deleteKeyPressed(Document*, bool smartDelete = false, TextGranularity = CharacterGranularity, bool killRing = false);
static void forwardDeleteKeyPressed(Document*, bool smartDelete = false, TextGranularity = CharacterGranularity, bool killRing = false);
- static void insertText(Document*, const String&, bool selectInsertedText = false, bool insertedTextIsComposition = false);
- static void insertText(Document*, const String&, const VisibleSelection&, bool selectInsertedText = false, bool insertedTextIsComposition = false);
+ static void insertText(Document*, const String&, bool selectInsertedText = false, TextCompositionType = TextCompositionNone);
+ static void insertText(Document*, const String&, const VisibleSelection&, bool selectInsertedText = false, TextCompositionType = TextCompositionNone);
static void insertLineBreak(Document*);
static void insertParagraphSeparator(Document*);
static void insertParagraphSeparatorInQuotedContent(Document*);
@@ -64,14 +70,20 @@ public:
void deleteKeyPressed(TextGranularity, bool killRing);
void forwardDeleteKeyPressed(TextGranularity, bool killRing);
void deleteSelection(bool smartDelete);
+ void setCompositionType(TextCompositionType type) { m_compositionType = type; }
private:
static PassRefPtr<TypingCommand> create(Document* document, ETypingCommand command, const String& text = "", bool selectInsertedText = false, TextGranularity granularity = CharacterGranularity, bool killRing = false)
{
- return adoptRef(new TypingCommand(document, command, text, selectInsertedText, granularity, killRing));
+ return adoptRef(new TypingCommand(document, command, text, selectInsertedText, granularity, TextCompositionNone, killRing));
+ }
+
+ static PassRefPtr<TypingCommand> create(Document* document, ETypingCommand command, const String& text, bool selectInsertedText, TextCompositionType compositionType)
+ {
+ return adoptRef(new TypingCommand(document, command, text, selectInsertedText, CharacterGranularity, compositionType, false));
}
- TypingCommand(Document*, ETypingCommand, const String& text, bool selectInsertedText, TextGranularity, bool killRing);
+ TypingCommand(Document*, ETypingCommand, const String& text, bool selectInsertedText, TextGranularity, TextCompositionType, bool killRing);
bool smartDelete() const { return m_smartDelete; }
void setSmartDelete(bool smartDelete) { m_smartDelete = smartDelete; }
@@ -94,6 +106,7 @@ private:
bool m_selectInsertedText;
bool m_smartDelete;
TextGranularity m_granularity;
+ TextCompositionType m_compositionType;
bool m_killRing;
bool m_preservesTypingStyle;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list