Reviewed by Ojan Vafai.
Inserting multiple whitespace using text composition (IME) should insert interleaved nbsp and whitespace.
https://bugs.webkit.org/show_bug.cgi?id=52781
The test was rebaselined to have interleaved space and non-breaking space.
* editing/inserting/insert-composition-whitespace-expected.txt:
* editing/inserting/insert-composition-whitespace.html:
2011-01-24 Ryosuke Niwa <rniwa@webkit.org>
Reviewed by Ojan Vafai.
Inserting multiple whitespace using text composition (IME) should insert interleaved nbsp and whitespace.
https://bugs.webkit.org/show_bug.cgi?id=52781
The bug was caused by stringWithRebalancedWhitespace's replacing the space at the beginning of a paragraph
and the end of a paragraph by a non-breaking space after it replaced two consecutive spaces by a space and
non-breaking space pattern, thereby replacing more spaces by non-breaking spaces than needed.
Rewrote the function using Vector<UChar> to fix the bug. New function no longer calls String::replace
multiple times but instead it traverses through the string and replaces a space that immediately follows
another space or appears at the beginning of a paragraph or at the end of a paragraph by a non-break space.
* editing/CompositeEditCommand.cpp:
* editing/htmlediting.cpp:
(WebCore::stringWithRebalancedWhitespace): Written.
* editing/htmlediting.h:
(WebCore::isWhitespace): Removed from CompositeEditCommand.cpp
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@76565
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-01-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Ojan Vafai.
+
+ Inserting multiple whitespace using text composition (IME) should insert interleaved nbsp and whitespace.
+ https://bugs.webkit.org/show_bug.cgi?id=52781
+
+ The test was rebaselined to have interleaved space and non-breaking space.
+
+ * editing/inserting/insert-composition-whitespace-expected.txt:
+ * editing/inserting/insert-composition-whitespace.html:
+
2011-01-24 Martin Robinson <mrobinson@igalia.com>
Skip one more crashing test.
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 '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 ' 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 ' '
+PASS confirmedText is ' '
PASS compositingText is 'AB'
PASS confirmedText is 'AB'
PASS compositingText is 'A 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", "\xA0 AB");
+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 ", "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\xA0");
-test("div", " A B ", "\xA0\xA0A \xA0B \xA0");
-test("div", "\t\tA\t\tB\t\t", "\xA0\xA0A \xA0B \xA0");
+test("div", " A B ", "\xA0 A \xA0B \xA0");
+test("div", "\t\tA\t\tB\t\t", "\xA0 A \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("div", " ", "\xA0 \xA0");
test("pre", "AB", "AB");
test("pre", "A B", "A B");
+2011-01-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Ojan Vafai.
+
+ Inserting multiple whitespace using text composition (IME) should insert interleaved nbsp and whitespace.
+ https://bugs.webkit.org/show_bug.cgi?id=52781
+
+ The bug was caused by stringWithRebalancedWhitespace's replacing the space at the beginning of a paragraph
+ and the end of a paragraph by a non-breaking space after it replaced two consecutive spaces by a space and
+ non-breaking space pattern, thereby replacing more spaces by non-breaking spaces than needed.
+
+ Rewrote the function using Vector<UChar> to fix the bug. New function no longer calls String::replace
+ multiple times but instead it traverses through the string and replaces a space that immediately follows
+ another space or appears at the beginning of a paragraph or at the end of a paragraph by a non-break space.
+
+ * editing/CompositeEditCommand.cpp:
+ * editing/htmlediting.cpp:
+ (WebCore::stringWithRebalancedWhitespace): Written.
+ * editing/htmlediting.h:
+ (WebCore::isWhitespace): Removed from CompositeEditCommand.cpp
+
2011-01-24 Kenneth Russell <kbr@google.com>
Reviewed by James Robinson.
applyCommandToComposite(SetNodeAttributeCommand::create(element, attribute, value));
}
-static inline bool isWhitespace(UChar c)
-{
- return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t';
-}
-
static inline bool containsOnlyWhitespace(const String& text)
{
for (unsigned i = 0; i < text.length(); ++i) {
String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph)
{
- DEFINE_STATIC_LOCAL(String, twoSpaces, (" "));
- DEFINE_STATIC_LOCAL(String, nbsp, ("\xa0"));
- DEFINE_STATIC_LOCAL(String, pattern, (" \xa0"));
+ Vector<UChar> rebalancedString;
+ append(rebalancedString, string);
- String rebalancedString = string;
+ bool previousCharacterWasSpace = false;
+ for (size_t i = 0; i < rebalancedString.size(); i++) {
+ if (!isWhitespace(rebalancedString[i])) {
+ previousCharacterWasSpace = false;
+ continue;
+ }
- rebalancedString.replace(noBreakSpace, ' ');
- rebalancedString.replace('\n', ' ');
- rebalancedString.replace('\t', ' ');
-
- rebalancedString.replace(twoSpaces, pattern);
-
- if (startIsStartOfParagraph && rebalancedString[0] == ' ')
- rebalancedString.replace(0, 1, nbsp);
- int end = rebalancedString.length() - 1;
- if (endIsEndOfParagraph && rebalancedString[end] == ' ')
- rebalancedString.replace(end, 1, nbsp);
+ if (previousCharacterWasSpace || (!i && startIsStartOfParagraph) || (i + 1 == rebalancedString.size() && endIsEndOfParagraph)) {
+ rebalancedString[i] = noBreakSpace;
+ previousCharacterWasSpace = false;
+ } else {
+ rebalancedString[i] = ' ';
+ previousCharacterWasSpace = true;
+ }
+
+ }
- return rebalancedString;
+ return String::adopt(rebalancedString);
}
bool isTableStructureNode(const Node *node)
#ifndef htmlediting_h
#define htmlediting_h
-#include <wtf/Forward.h>
-#include "HTMLNames.h"
+#include "CharacterNames.h"
#include "ExceptionCode.h"
+#include "HTMLNames.h"
#include "Position.h"
+#include <wtf/Forward.h>
namespace WebCore {
VisibleSelection selectionForParagraphIteration(const VisibleSelection&);
-// Miscellaneous functions on String
-
+// Miscellaneous functions on Text
+inline bool isWhitespace(UChar c)
+{
+ return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t';
+}
String stringWithRebalancedWhitespace(const String&, bool, bool);
const String& nonBreakingSpaceString();