summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/editing/CompositeEditCommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/editing/CompositeEditCommand.cpp')
-rw-r--r--Source/WebCore/editing/CompositeEditCommand.cpp71
1 files changed, 49 insertions, 22 deletions
diff --git a/Source/WebCore/editing/CompositeEditCommand.cpp b/Source/WebCore/editing/CompositeEditCommand.cpp
index 552ed79..ac3d761 100644
--- a/Source/WebCore/editing/CompositeEditCommand.cpp
+++ b/Source/WebCore/editing/CompositeEditCommand.cpp
@@ -28,7 +28,6 @@
#include "AppendNodeCommand.h"
#include "ApplyStyleCommand.h"
-#include "CharacterNames.h"
#include "DeleteFromTextNodeCommand.h"
#include "DeleteSelectionCommand.h"
#include "Document.h"
@@ -63,6 +62,7 @@
#include "htmlediting.h"
#include "markup.h"
#include "visible_units.h"
+#include <wtf/unicode/CharacterNames.h>
using namespace std;
@@ -390,57 +390,84 @@ void CompositeEditCommand::setNodeAttribute(PassRefPtr<Element> element, const Q
applyCommandToComposite(SetNodeAttributeCommand::create(element, attribute, value));
}
-static inline bool isWhitespace(UChar c)
+static inline bool containsOnlyWhitespace(const String& text)
{
- return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t';
+ for (unsigned i = 0; i < text.length(); ++i) {
+ if (!isWhitespace(text.characters()[i]))
+ return false;
+ }
+
+ return true;
}
-// FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, cousins, etc).
-void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position)
+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);