diff options
Diffstat (limited to 'Source/WebCore/editing')
-rw-r--r-- | Source/WebCore/editing/ApplyBlockElementCommand.cpp | 2 | ||||
-rw-r--r-- | Source/WebCore/editing/ApplyStyleCommand.cpp | 168 | ||||
-rw-r--r-- | Source/WebCore/editing/ApplyStyleCommand.h | 2 | ||||
-rw-r--r-- | Source/WebCore/editing/BreakBlockquoteCommand.cpp | 8 | ||||
-rw-r--r-- | Source/WebCore/editing/CompositeEditCommand.cpp | 32 | ||||
-rw-r--r-- | Source/WebCore/editing/DeleteButtonController.cpp | 2 | ||||
-rw-r--r-- | Source/WebCore/editing/Editor.cpp | 4 | ||||
-rw-r--r-- | Source/WebCore/editing/EditorCommand.cpp | 1 | ||||
-rw-r--r-- | Source/WebCore/editing/SmartReplace.h | 5 | ||||
-rw-r--r-- | Source/WebCore/editing/htmlediting.h | 12 |
10 files changed, 133 insertions, 103 deletions
diff --git a/Source/WebCore/editing/ApplyBlockElementCommand.cpp b/Source/WebCore/editing/ApplyBlockElementCommand.cpp index 285650d..e700875 100644 --- a/Source/WebCore/editing/ApplyBlockElementCommand.cpp +++ b/Source/WebCore/editing/ApplyBlockElementCommand.cpp @@ -102,7 +102,7 @@ void ApplyBlockElementCommand::formatSelection(const VisiblePosition& startOfSel insertNodeAt(blockquote, start); RefPtr<Element> placeholder = createBreakElement(document()); appendNode(placeholder, blockquote); - setEndingSelection(VisibleSelection(Position(placeholder.get(), 0), DOWNSTREAM)); + setEndingSelection(VisibleSelection(positionBeforeNode(placeholder.get()), DOWNSTREAM)); return; } diff --git a/Source/WebCore/editing/ApplyStyleCommand.cpp b/Source/WebCore/editing/ApplyStyleCommand.cpp index 71b6a27..7227d7b 100644 --- a/Source/WebCore/editing/ApplyStyleCommand.cpp +++ b/Source/WebCore/editing/ApplyStyleCommand.cpp @@ -33,6 +33,7 @@ #include "CSSPropertyNames.h" #include "CSSStyleSelector.h" #include "CSSValueKeywords.h" +#include "CSSValueList.h" #include "Document.h" #include "EditingStyle.h" #include "Editor.h" @@ -563,17 +564,16 @@ void ApplyStyleCommand::applyBlockStyle(CSSMutableStyleDeclaration *style) if (visibleStart.isNull() || visibleStart.isOrphan() || visibleEnd.isNull() || visibleEnd.isOrphan()) return; - + // Save and restore the selection endpoints using their indices in the document, since // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints. // Calculate start and end indices from the start of the tree that they're in. Node* scope = highestAncestor(visibleStart.deepEquivalent().node()); - Position rangeStart(scope, 0); - RefPtr<Range> startRange = Range::create(document(), rangeStart, rangeCompliantEquivalent(visibleStart.deepEquivalent())); - RefPtr<Range> endRange = Range::create(document(), rangeStart, rangeCompliantEquivalent(visibleEnd.deepEquivalent())); + RefPtr<Range> startRange = Range::create(document(), firstPositionInNode(scope), rangeCompliantEquivalent(visibleStart.deepEquivalent())); + RefPtr<Range> endRange = Range::create(document(), firstPositionInNode(scope), rangeCompliantEquivalent(visibleEnd.deepEquivalent())); int startIndex = TextIterator::rangeLength(startRange.get(), true); int endIndex = TextIterator::rangeLength(endRange.get(), true); - + VisiblePosition paragraphStart(startOfParagraph(visibleStart)); VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next()); VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next()); @@ -982,7 +982,7 @@ void ApplyStyleCommand::fixRangeAndApplyInlineStyle(CSSMutableStyleDeclaration* if (start.deprecatedEditingOffset() >= caretMaxOffset(start.node())) { startNode = startNode->traverseNextNode(); - if (!startNode || comparePositions(end, Position(startNode, 0)) < 0) + if (!startNode || comparePositions(end, firstPositionInOrBeforeNode(startNode)) < 0) return; } @@ -1333,7 +1333,7 @@ HTMLElement* ApplyStyleCommand::highestAncestorWithConflictingInlineStyle(CSSMut return 0; HTMLElement* result = 0; - Node* unsplittableElement = unsplittableElementForPosition(Position(node, 0)); + Node* unsplittableElement = unsplittableElementForPosition(firstPositionInOrBeforeNode(node)); for (Node *n = node; n; n = n->parentNode()) { if (n->isHTMLElement() && shouldRemoveInlineStyleFromElement(style, static_cast<HTMLElement*>(n))) @@ -1515,15 +1515,16 @@ void ApplyStyleCommand::removeInlineStyle(PassRefPtr<CSSMutableStyleDeclaration> if (s.node() == elem) { // Since elem must have been fully selected, and it is at the start // of the selection, it is clear we can set the new s offset to 0. - ASSERT(s.deprecatedEditingOffset() <= caretMinOffset(s.node())); - s = Position(next, 0); + ASSERT(s.anchorType() == Position::PositionIsBeforeAnchor || s.offsetInContainerNode() <= 0); + s = firstPositionInOrBeforeNode(next.get()); } if (e.node() == elem) { // Since elem must have been fully selected, and it is at the end // of the selection, it is clear we can set the new e offset to // the max range offset of prev. - ASSERT(e.deprecatedEditingOffset() >= lastOffsetForEditing(e.node())); - e = Position(prev, lastOffsetForEditing(prev.get())); + ASSERT(s.anchorType() == Position::PositionIsAfterAnchor + || s.offsetInContainerNode() >= lastOffsetInNode(s.containerNode())); + e = lastPositionInOrAfterNode(prev.get()); } } @@ -1545,8 +1546,8 @@ bool ApplyStyleCommand::nodeFullySelected(Node *node, const Position &start, con ASSERT(node); ASSERT(node->isElementNode()); - Position pos = Position(node, node->childNodeCount()).upstream(); - return comparePositions(Position(node, 0), start) >= 0 && comparePositions(pos, end) <= 0; + return comparePositions(firstPositionInOrBeforeNode(node), start) >= 0 + && comparePositions(lastPositionInOrAfterNode(node).upstream(), end) <= 0; } bool ApplyStyleCommand::nodeFullyUnselected(Node *node, const Position &start, const Position &end) const @@ -1554,51 +1555,68 @@ bool ApplyStyleCommand::nodeFullyUnselected(Node *node, const Position &start, c ASSERT(node); ASSERT(node->isElementNode()); - Position pos = Position(node, node->childNodeCount()).upstream(); - bool isFullyBeforeStart = comparePositions(pos, start) < 0; - bool isFullyAfterEnd = comparePositions(Position(node, 0), end) > 0; + bool isFullyBeforeStart = comparePositions(lastPositionInOrAfterNode(node).upstream(), start) < 0; + bool isFullyAfterEnd = comparePositions(firstPositionInOrBeforeNode(node), end) > 0; return isFullyBeforeStart || isFullyAfterEnd; } void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end) { - int endOffsetAdjustment = start.node() == end.node() ? start.deprecatedEditingOffset() : 0; + ASSERT(start.anchorType() == Position::PositionIsOffsetInAnchor); + + Position newEnd; + if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode()) + newEnd = Position(end.containerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor); + else + newEnd = end; + Text* text = static_cast<Text*>(start.node()); - splitTextNode(text, start.deprecatedEditingOffset()); - updateStartEnd(Position(start.node(), 0), Position(end.node(), end.deprecatedEditingOffset() - endOffsetAdjustment)); + splitTextNode(text, start.offsetInContainerNode()); + updateStartEnd(firstPositionInNode(start.node()), newEnd); } void ApplyStyleCommand::splitTextAtEnd(const Position& start, const Position& end) { + ASSERT(end.anchorType() == Position::PositionIsOffsetInAnchor); + + bool shouldUpdateStart = start.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode(); Text* text = static_cast<Text *>(end.node()); - splitTextNode(text, end.deprecatedEditingOffset()); + splitTextNode(text, end.offsetInContainerNode()); Node* prevNode = text->previousSibling(); ASSERT(prevNode); - Node* startNode = start.node() == end.node() ? prevNode : start.node(); - ASSERT(startNode); - updateStartEnd(Position(startNode, start.deprecatedEditingOffset()), Position(prevNode, caretMaxOffset(prevNode))); + Position newStart = shouldUpdateStart ? Position(prevNode, start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor) : start; + updateStartEnd(newStart, lastPositionInNode(prevNode)); } void ApplyStyleCommand::splitTextElementAtStart(const Position& start, const Position& end) { - int endOffsetAdjustment = start.node() == end.node() ? start.deprecatedEditingOffset() : 0; + ASSERT(start.anchorType() == Position::PositionIsOffsetInAnchor); + + Position newEnd; + if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode()) + newEnd = Position(end.containerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor); + else + newEnd = end; + Text* text = static_cast<Text*>(start.node()); splitTextNodeContainingElement(text, start.deprecatedEditingOffset()); - updateStartEnd(Position(start.node()->parentNode(), start.node()->nodeIndex()), Position(end.node(), end.deprecatedEditingOffset() - endOffsetAdjustment)); + updateStartEnd(Position(start.node()->parentNode(), start.node()->nodeIndex(), Position::PositionIsOffsetInAnchor), newEnd); } void ApplyStyleCommand::splitTextElementAtEnd(const Position& start, const Position& end) { + ASSERT(end.anchorType() == Position::PositionIsOffsetInAnchor); + + bool shouldUpdateStart = start.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode(); Text* text = static_cast<Text*>(end.node()); splitTextNodeContainingElement(text, end.deprecatedEditingOffset()); Node* prevNode = text->parentNode()->previousSibling()->lastChild(); ASSERT(prevNode); - Node* startNode = start.node() == end.node() ? prevNode : start.node(); - ASSERT(startNode); - updateStartEnd(Position(startNode, start.deprecatedEditingOffset()), Position(prevNode->parentNode(), prevNode->nodeIndex() + 1)); + Position newStart = shouldUpdateStart ? Position(prevNode, start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor) : start; + updateStartEnd(newStart, Position(prevNode->parentNode(), prevNode->nodeIndex() + 1, Position::PositionIsOffsetInAnchor)); } bool ApplyStyleCommand::shouldSplitTextElement(Element* element, CSSMutableStyleDeclaration* style) @@ -1611,11 +1629,11 @@ bool ApplyStyleCommand::shouldSplitTextElement(Element* element, CSSMutableStyle bool ApplyStyleCommand::isValidCaretPositionInTextNode(const Position& position) { - Node* node = position.node(); - if (!node->isTextNode()) + Node* node = position.containerNode(); + if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node->isTextNode()) return false; - int offsetInText = position.deprecatedEditingOffset(); - return (offsetInText > caretMinOffset(node) && offsetInText < caretMaxOffset(node)); + int offsetInText = position.offsetInContainerNode(); + return offsetInText > caretMinOffset(node) && offsetInText < caretMaxOffset(node); } static bool areIdenticalElements(Node *first, Node *second) @@ -1653,55 +1671,52 @@ static bool areIdenticalElements(Node *first, Node *second) return true; } -bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position &start, const Position &end) +bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position& start, const Position& end) { - Node *startNode = start.node(); - int startOffset = start.deprecatedEditingOffset(); - - if (isAtomicNode(start.node())) { - if (start.deprecatedEditingOffset() != 0) - return false; + Node* startNode = start.containerNode(); + int startOffset = start.computeOffsetInContainerNode(); + if (startOffset) + return false; + if (isAtomicNode(startNode)) { // note: prior siblings could be unrendered elements. it's silly to miss the // merge opportunity just for that. - if (start.node()->previousSibling()) + if (startNode->previousSibling()) return false; - startNode = start.node()->parentNode(); + startNode = startNode->parentNode(); startOffset = 0; } if (!startNode->isElementNode()) return false; - if (startOffset != 0) - return false; - - Node *previousSibling = startNode->previousSibling(); + Node* previousSibling = startNode->previousSibling(); if (previousSibling && areIdenticalElements(startNode, previousSibling)) { - Element *previousElement = static_cast<Element *>(previousSibling); - Element *element = static_cast<Element *>(startNode); - Node *startChild = element->firstChild(); + Element* previousElement = static_cast<Element*>(previousSibling); + Element* element = static_cast<Element*>(startNode); + Node* startChild = element->firstChild(); ASSERT(startChild); mergeIdenticalElements(previousElement, element); int startOffsetAdjustment = startChild->nodeIndex(); int endOffsetAdjustment = startNode == end.node() ? startOffsetAdjustment : 0; - updateStartEnd(Position(startNode, startOffsetAdjustment), Position(end.node(), end.deprecatedEditingOffset() + endOffsetAdjustment)); + updateStartEnd(Position(startNode, startOffsetAdjustment, Position::PositionIsOffsetInAnchor), + Position(end.node(), end.deprecatedEditingOffset() + endOffsetAdjustment, Position::PositionIsOffsetInAnchor)); return true; } return false; } -bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position &start, const Position &end) +bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const Position& end) { - Node *endNode = end.node(); - int endOffset = end.deprecatedEditingOffset(); + Node* endNode = end.containerNode(); + int endOffset = end.computeOffsetInContainerNode(); if (isAtomicNode(endNode)) { - if (endOffset < caretMaxOffset(endNode)) + if (endOffset < lastOffsetInNode(endNode)) return false; unsigned parentLastOffset = end.node()->parentNode()->childNodes()->length() - 1; @@ -1715,20 +1730,18 @@ bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position &start, const if (!endNode->isElementNode() || endNode->hasTagName(brTag)) return false; - Node *nextSibling = endNode->nextSibling(); - + Node* nextSibling = endNode->nextSibling(); if (nextSibling && areIdenticalElements(endNode, nextSibling)) { - Element *nextElement = static_cast<Element *>(nextSibling); - Element *element = static_cast<Element *>(endNode); - Node *nextChild = nextElement->firstChild(); + Element* nextElement = static_cast<Element *>(nextSibling); + Element* element = static_cast<Element *>(endNode); + Node* nextChild = nextElement->firstChild(); mergeIdenticalElements(element, nextElement); - Node *startNode = start.node() == endNode ? nextElement : start.node(); - ASSERT(startNode); - + bool shouldUpdateStart = start.containerNode() == endNode; int endOffset = nextChild ? nextChild->nodeIndex() : nextElement->childNodes()->length(); - updateStartEnd(Position(startNode, start.deprecatedEditingOffset()), Position(nextElement, endOffset)); + updateStartEnd(shouldUpdateStart ? Position(nextElement, start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor) : start, + Position(nextElement, endOffset, Position::PositionIsOffsetInAnchor)); return true; } @@ -1880,41 +1893,40 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->cloneElementWithoutChildren()); } -float ApplyStyleCommand::computedFontSize(const Node *node) +float ApplyStyleCommand::computedFontSize(Node* node) { if (!node) return 0; - - Position pos(const_cast<Node *>(node), 0); - RefPtr<CSSComputedStyleDeclaration> computedStyle = pos.computedStyle(); - if (!computedStyle) + + RefPtr<CSSComputedStyleDeclaration> style = computedStyle(node); + if (!style) return 0; - RefPtr<CSSPrimitiveValue> value = static_pointer_cast<CSSPrimitiveValue>(computedStyle->getPropertyCSSValue(CSSPropertyFontSize)); + RefPtr<CSSPrimitiveValue> value = static_pointer_cast<CSSPrimitiveValue>(style->getPropertyCSSValue(CSSPropertyFontSize)); if (!value) return 0; return value->getFloatValue(CSSPrimitiveValue::CSS_PX); } -void ApplyStyleCommand::joinChildTextNodes(Node *node, const Position &start, const Position &end) +void ApplyStyleCommand::joinChildTextNodes(Node* node, const Position& start, const Position& end) { if (!node) return; Position newStart = start; Position newEnd = end; - - Node *child = node->firstChild(); + + Node* child = node->firstChild(); while (child) { - Node *next = child->nextSibling(); + Node* next = child->nextSibling(); if (child->isTextNode() && next && next->isTextNode()) { - Text *childText = static_cast<Text *>(child); - Text *nextText = static_cast<Text *>(next); - if (next == start.node()) - newStart = Position(childText, childText->length() + start.deprecatedEditingOffset()); - if (next == end.node()) - newEnd = Position(childText, childText->length() + end.deprecatedEditingOffset()); + Text* childText = static_cast<Text *>(child); + Text* nextText = static_cast<Text *>(next); + if (start.anchorType() == Position::PositionIsOffsetInAnchor && next == start.containerNode()) + newStart = Position(childText, childText->length() + start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor); + if (end.anchorType() == Position::PositionIsOffsetInAnchor && next == end.containerNode()) + newEnd = Position(childText, childText->length() + end.offsetInContainerNode(), Position::PositionIsOffsetInAnchor); String textToMove = nextText->data(); insertTextIntoNode(childText, childText->length(), textToMove); removeNode(next); diff --git a/Source/WebCore/editing/ApplyStyleCommand.h b/Source/WebCore/editing/ApplyStyleCommand.h index 5f369ba..05af85c 100644 --- a/Source/WebCore/editing/ApplyStyleCommand.h +++ b/Source/WebCore/editing/ApplyStyleCommand.h @@ -108,7 +108,7 @@ private: void cleanupUnstyledAppleStyleSpans(Node* dummySpanAncestor); void surroundNodeRangeWithElement(PassRefPtr<Node> start, PassRefPtr<Node> end, PassRefPtr<Element>); - float computedFontSize(const Node*); + float computedFontSize(Node*); void joinChildTextNodes(Node*, const Position& start, const Position& end); HTMLElement* splitAncestorsWithUnicodeBidi(Node*, bool before, int allowedDirection); diff --git a/Source/WebCore/editing/BreakBlockquoteCommand.cpp b/Source/WebCore/editing/BreakBlockquoteCommand.cpp index 63956e5..ae409c6 100644 --- a/Source/WebCore/editing/BreakBlockquoteCommand.cpp +++ b/Source/WebCore/editing/BreakBlockquoteCommand.cpp @@ -82,7 +82,7 @@ void BreakBlockquoteCommand::doApply() // Instead, insert the break before the blockquote, unless the position is as the end of the the quoted content. if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPosInNode) { insertNodeBefore(breakNode.get(), topBlockquote); - setEndingSelection(VisibleSelection(Position(breakNode.get(), 0), DOWNSTREAM)); + setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOWNSTREAM)); rebalanceWhitespace(); return; } @@ -92,7 +92,7 @@ void BreakBlockquoteCommand::doApply() // If we're inserting the break at the end of the quoted content, we don't need to break the quote. if (isLastVisPosInNode) { - setEndingSelection(VisibleSelection(Position(breakNode.get(), 0), DOWNSTREAM)); + setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOWNSTREAM)); rebalanceWhitespace(); return; } @@ -125,7 +125,7 @@ void BreakBlockquoteCommand::doApply() // If there's nothing inside topBlockquote to move, we're finished. if (!startNode->isDescendantOf(topBlockquote)) { - setEndingSelection(VisibleSelection(VisiblePosition(Position(startNode, 0)))); + setEndingSelection(VisibleSelection(VisiblePosition(firstPositionInOrBeforeNode(startNode)))); return; } @@ -198,7 +198,7 @@ void BreakBlockquoteCommand::doApply() addBlockPlaceholderIfNeeded(clonedBlockquote.get()); // Put the selection right before the break. - setEndingSelection(VisibleSelection(Position(breakNode.get(), 0), DOWNSTREAM)); + setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOWNSTREAM)); rebalanceWhitespace(); } diff --git a/Source/WebCore/editing/CompositeEditCommand.cpp b/Source/WebCore/editing/CompositeEditCommand.cpp index 748777d..9e1dfca 100644 --- a/Source/WebCore/editing/CompositeEditCommand.cpp +++ b/Source/WebCore/editing/CompositeEditCommand.cpp @@ -301,7 +301,7 @@ void CompositeEditCommand::inputText(const String& text, bool selectInsertedText { unsigned offset = 0; unsigned length = text.length(); - RefPtr<Range> startRange = Range::create(document(), Position(document()->documentElement(), 0), endingSelection().start()); + RefPtr<Range> startRange = Range::create(document(), firstPositionInNode(document()->documentElement()), endingSelection().start()); unsigned startIndex = TextIterator::rangeLength(startRange.get()); size_t newline; do { @@ -398,17 +398,17 @@ static inline bool isWhitespace(UChar c) // FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, cousins, etc). void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position) { - Node* node = position.node(); - if (!node || !node->isTextNode()) + Node* node = position.containerNode(); + if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node || !node->isTextNode()) return; Text* textNode = static_cast<Text*>(node); - + if (textNode->length() == 0) return; RenderObject* renderer = textNode->renderer(); if (renderer && !renderer->style()->collapseWhiteSpace()) return; - + String text = textNode->data(); ASSERT(!text.isEmpty()); @@ -432,8 +432,8 @@ void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position) int length = downstream - upstream + 1; ASSERT(length > 0); - VisiblePosition visibleUpstreamPos(Position(position.node(), upstream)); - VisiblePosition visibleDownstreamPos(Position(position.node(), downstream + 1)); + VisiblePosition visibleUpstreamPos(Position(position.containerNode(), upstream, Position::PositionIsOffsetInAnchor)); + VisiblePosition visibleDownstreamPos(Position(position.containerNode(), downstream + 1, Position::PositionIsOffsetInAnchor)); String string = text.substring(upstream, length); String rebalancedString = stringWithRebalancedWhitespace(string, @@ -715,10 +715,10 @@ PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessar } RefPtr<Node> newBlock = insertNewDefaultParagraphElementAt(upstreamStart); - + bool endWasBr = visibleParagraphEnd.deepEquivalent().node()->hasTagName(brTag); - moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(Position(newBlock.get(), 0))); + moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(firstPositionInNode(newBlock.get()))); if (newBlock->lastChild() && newBlock->lastChild()->hasTagName(brTag) && !endWasBr) removeNode(newBlock->lastChild()); @@ -973,10 +973,10 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap // Need an updateLayout here in case inserting the br has split a text node. updateLayout(); } - - RefPtr<Range> startToDestinationRange(Range::create(document(), Position(document(), 0), rangeCompliantEquivalent(destination.deepEquivalent()))); + + RefPtr<Range> startToDestinationRange(Range::create(document(), firstPositionInNode(document()->documentElement()), rangeCompliantEquivalent(destination.deepEquivalent()))); destinationIndex = TextIterator::rangeLength(startToDestinationRange.get(), true); - + setEndingSelection(destination); ASSERT(endingSelection().isCaretOrRange()); applyCommandToComposite(ReplaceSelectionCommand::create(document(), fragment, true, false, !preserveStyle, false, true)); @@ -1055,7 +1055,7 @@ bool CompositeEditCommand::breakOutOfEmptyListItem() } appendBlockPlaceholder(newBlock); - setEndingSelection(VisibleSelection(Position(newBlock.get(), 0), DOWNSTREAM)); + setEndingSelection(VisibleSelection(firstPositionInNode(newBlock.get()), DOWNSTREAM)); style->prepareToApplyAt(endingSelection().start()); if (!style->isEmpty()) @@ -1088,7 +1088,7 @@ bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph() // We want to replace this quoted paragraph with an unquoted one, so insert a br // to hold the caret before the highest blockquote. insertNodeBefore(br, highestBlockquote); - VisiblePosition atBR(Position(br.get(), 0)); + VisiblePosition atBR(positionBeforeNode(br.get())); // If the br we inserted collapsed, for example foo<br><blockquote>...</blockquote>, insert // a second one. if (!isStartOfParagraph(atBR)) @@ -1191,8 +1191,8 @@ PassRefPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, b for (node = start; node && node->parentNode() != end; node = node->parentNode()) { if (!node->parentNode()->isElementNode()) break; - VisiblePosition positionInParent(Position(node->parentNode(), 0), DOWNSTREAM); - VisiblePosition positionInNode(Position(node, 0), DOWNSTREAM); + VisiblePosition positionInParent(firstPositionInNode(node->parentNode()), DOWNSTREAM); + VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get()), DOWNSTREAM); if (positionInParent != positionInNode) applyCommandToComposite(SplitElementCommand::create(static_cast<Element*>(node->parentNode()), node)); } diff --git a/Source/WebCore/editing/DeleteButtonController.cpp b/Source/WebCore/editing/DeleteButtonController.cpp index 028edc8..61e3190 100644 --- a/Source/WebCore/editing/DeleteButtonController.cpp +++ b/Source/WebCore/editing/DeleteButtonController.cpp @@ -159,7 +159,7 @@ static HTMLElement* enclosingDeletableElement(const VisibleSelection& selection) if (!container->isContentEditable()) return 0; - Node* element = enclosingNodeOfType(Position(container, 0), &isDeletableElement); + Node* element = enclosingNodeOfType(firstPositionInNode(container), &isDeletableElement); if (!element) return 0; diff --git a/Source/WebCore/editing/Editor.cpp b/Source/WebCore/editing/Editor.cpp index a24e7c6..bea74d9 100644 --- a/Source/WebCore/editing/Editor.cpp +++ b/Source/WebCore/editing/Editor.cpp @@ -52,6 +52,7 @@ #include "Frame.h" #include "FrameTree.h" #include "FrameView.h" +#include "GraphicsContext.h" #include "HTMLFrameOwnerElement.h" #include "HTMLInputElement.h" #include "HTMLTextAreaElement.h" @@ -3031,7 +3032,8 @@ void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, b String Editor::selectedText() const { - return plainText(m_frame->selection()->toNormalizedRange().get()); + // We remove '\0' characters because they are not visibly rendered to the user. + return plainText(m_frame->selection()->toNormalizedRange().get()).replace(0, ""); } IntRect Editor::firstRectForRange(Range* range) const diff --git a/Source/WebCore/editing/EditorCommand.cpp b/Source/WebCore/editing/EditorCommand.cpp index 5de44a6..64993d5 100644 --- a/Source/WebCore/editing/EditorCommand.cpp +++ b/Source/WebCore/editing/EditorCommand.cpp @@ -32,6 +32,7 @@ #include "CSSMutableStyleDeclaration.h" #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" +#include "CSSValueList.h" #include "Chrome.h" #include "CreateLinkCommand.h" #include "DocumentFragment.h" diff --git a/Source/WebCore/editing/SmartReplace.h b/Source/WebCore/editing/SmartReplace.h index 5a37137..b072e58 100644 --- a/Source/WebCore/editing/SmartReplace.h +++ b/Source/WebCore/editing/SmartReplace.h @@ -26,6 +26,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef SmartReplace_h +#define SmartReplace_h + #include <wtf/unicode/Unicode.h> namespace WebCore { @@ -33,3 +36,5 @@ namespace WebCore { bool isCharacterSmartReplaceExempt(UChar32 c, bool isPreviousCharacter); } // namespace WebCore + +#endif // SmartReplace_h diff --git a/Source/WebCore/editing/htmlediting.h b/Source/WebCore/editing/htmlediting.h index 1892357..1f6b986 100644 --- a/Source/WebCore/editing/htmlediting.h +++ b/Source/WebCore/editing/htmlediting.h @@ -114,7 +114,17 @@ Position positionBeforeTabSpan(const Position&); Position positionBeforeContainingSpecialElement(const Position&, Node** containingSpecialElement=0); Position positionAfterContainingSpecialElement(const Position&, Node** containingSpecialElement=0); Position positionOutsideContainingSpecialElement(const Position&, Node** containingSpecialElement=0); - + +inline Position firstPositionInOrBeforeNode(Node* node) +{ + return editingIgnoresContent(node) ? positionBeforeNode(node) : firstPositionInNode(node); +} + +inline Position lastPositionInOrAfterNode(Node* node) +{ + return editingIgnoresContent(node) ? positionAfterNode(node) : lastPositionInNode(node); +} + // Position creation functions are inline to prevent ref-churn. // Other Position creation functions are in Position.h // but these depend on lastOffsetForEditing which is defined in htmlediting.h. |