Chromium Code Reviews| Index: Source/core/editing/ReplaceSelectionCommand.cpp |
| diff --git a/Source/core/editing/ReplaceSelectionCommand.cpp b/Source/core/editing/ReplaceSelectionCommand.cpp |
| index 3980379427ed3f56d5633071b8aca6f6f1b0b343..2e2fe9d4ab93494e9eabcc85ae65ab22e653c7ab 100644 |
| --- a/Source/core/editing/ReplaceSelectionCommand.cpp |
| +++ b/Source/core/editing/ReplaceSelectionCommand.cpp |
| @@ -53,6 +53,8 @@ |
| #include "core/html/HTMLElement.h" |
| #include "core/html/HTMLInputElement.h" |
| #include "core/html/HTMLLIElement.h" |
| +#include "core/html/HTMLQuoteElement.h" |
| +#include "core/html/HTMLSelectElement.h" |
| #include "core/html/HTMLSpanElement.h" |
| #include "core/rendering/RenderObject.h" |
| #include "core/rendering/RenderText.h" |
| @@ -82,13 +84,13 @@ public: |
| bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEnd; } |
| void removeNode(PassRefPtrWillBeRawPtr<Node>); |
| - void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node>); |
| + void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<ContainerNode>); |
| private: |
| - PassRefPtrWillBeRawPtr<Element> insertFragmentForTestRendering(Node* rootEditableNode); |
| - void removeUnrenderedNodes(Node*); |
| + PassRefPtrWillBeRawPtr<HTMLElement> insertFragmentForTestRendering(Element* rootEditableElement); |
| + void removeUnrenderedNodes(ContainerNode*); |
| void restoreAndRemoveTestRenderingNodesToFragment(Element*); |
| - void removeInterchangeNodes(Node*); |
| + void removeInterchangeNodes(ContainerNode*); |
| void insertNodeBefore(PassRefPtrWillBeRawPtr<Node>, Node* refNode); |
| @@ -98,16 +100,16 @@ private: |
| bool m_hasInterchangeNewlineAtEnd; |
| }; |
| -static bool isInterchangeNewlineNode(const Node *node) |
| +static bool isInterchangeHTMLBRElement(const Node* node) |
| { |
| DEFINE_STATIC_LOCAL(String, interchangeNewlineClassString, (AppleInterchangeNewline)); |
| - if (!isHTMLBRElement(node) || toElement(node)->getAttribute(classAttr) != interchangeNewlineClassString) |
| + if (!isHTMLBRElement(node) || toHTMLBRElement(node)->getAttribute(classAttr) != interchangeNewlineClassString) |
| return false; |
| UseCounter::count(node->document(), UseCounter::EditingAppleInterchangeNewline); |
| return true; |
| } |
| -static bool isInterchangeConvertedSpaceSpan(const Node *node) |
| +static bool isHTMLInterchangeConvertedSpaceSpan(const Node* node) |
| { |
| DEFINE_STATIC_LOCAL(String, convertedSpaceSpanClassString, (AppleConvertedSpace)); |
| if (!node->isHTMLElement() || toHTMLElement(node)->getAttribute(classAttr) != convertedSpaceSpanClassString) |
| @@ -126,8 +128,8 @@ static Position positionAvoidingPrecedingNodes(Position pos) |
| // same. E.g., |
| // <div>foo^</div>^ |
| // The two positions above are the same visual position, but we want to stay in the same block. |
| - Node* enclosingBlockNode = enclosingBlock(pos.containerNode()); |
| - for (Position nextPosition = pos; nextPosition.containerNode() != enclosingBlockNode; pos = nextPosition) { |
| + Element* enclosingBlockElement = enclosingBlock(pos.containerNode()); |
| + for (Position nextPosition = pos; nextPosition.containerNode() != enclosingBlockElement; pos = nextPosition) { |
| if (lineBreakExistsAtPosition(pos)) |
| break; |
| @@ -135,7 +137,7 @@ static Position positionAvoidingPrecedingNodes(Position pos) |
| nextPosition = positionInParentAfterNode(*pos.containerNode()); |
| if (nextPosition == pos |
| - || enclosingBlock(nextPosition.containerNode()) != enclosingBlockNode |
| + || enclosingBlock(nextPosition.containerNode()) != enclosingBlockElement |
| || VisiblePosition(pos) != VisiblePosition(nextPosition)) |
| break; |
| } |
| @@ -158,21 +160,21 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f |
| if (!editableRoot) |
| return; |
| - Node* shadowAncestorNode; |
| + Element* shadowAncestorElement; |
| if (editableRoot->isInShadowTree()) |
| - shadowAncestorNode = editableRoot->shadowHost(); |
| + shadowAncestorElement = editableRoot->shadowHost(); |
| else |
| - shadowAncestorNode = editableRoot.get(); |
| + shadowAncestorElement = editableRoot.get(); |
| - if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTextInserted) && |
| + if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTextInserted) |
| // FIXME: Remove these checks once textareas and textfields actually register an event handler. |
| - !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestorNode->renderer()->isTextControl()) && |
| - editableRoot->rendererIsRichlyEditable()) { |
| + && !(shadowAncestorElement && shadowAncestorElement->renderer() && shadowAncestorElement->renderer()->isTextControl()) |
| + && editableRoot->rendererIsRichlyEditable()) { |
| removeInterchangeNodes(m_fragment.get()); |
| return; |
| } |
| - RefPtrWillBeRawPtr<Element> holder = insertFragmentForTestRendering(editableRoot.get()); |
| + RefPtrWillBeRawPtr<HTMLElement> holder = insertFragmentForTestRendering(editableRoot.get()); |
| if (!holder) { |
| removeInterchangeNodes(m_fragment.get()); |
| return; |
| @@ -207,17 +209,17 @@ bool ReplacementFragment::isEmpty() const |
| return (!m_fragment || !m_fragment->hasChildren()) && !m_hasInterchangeNewlineAtStart && !m_hasInterchangeNewlineAtEnd; |
| } |
| -Node *ReplacementFragment::firstChild() const |
| +Node* ReplacementFragment::firstChild() const |
| { |
| return m_fragment ? m_fragment->firstChild() : 0; |
| } |
| -Node *ReplacementFragment::lastChild() const |
| +Node* ReplacementFragment::lastChild() const |
| { |
| return m_fragment ? m_fragment->lastChild() : 0; |
| } |
| -void ReplacementFragment::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node> node) |
| +void ReplacementFragment::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<ContainerNode> node) |
| { |
| if (!node) |
| return; |
| @@ -253,10 +255,10 @@ void ReplacementFragment::insertNodeBefore(PassRefPtrWillBeRawPtr<Node> node, No |
| parent->insertBefore(node, refNode); |
| } |
| -PassRefPtrWillBeRawPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* rootEditableElement) |
| +PassRefPtrWillBeRawPtr<HTMLElement> ReplacementFragment::insertFragmentForTestRendering(Element* rootEditableElement) |
| { |
| ASSERT(m_document); |
| - RefPtrWillBeRawPtr<Element> holder = createDefaultParagraphElement(*m_document.get()); |
| + RefPtrWillBeRawPtr<HTMLElement> holder = createDefaultParagraphElement(*m_document.get()); |
| holder->appendChild(m_fragment); |
| rootEditableElement->appendChild(holder.get()); |
| @@ -278,7 +280,7 @@ void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element* |
| removeNode(holder); |
| } |
| -void ReplacementFragment::removeUnrenderedNodes(Node* holder) |
| +void ReplacementFragment::removeUnrenderedNodes(ContainerNode* holder) |
| { |
| WillBeHeapVector<RefPtrWillBeMember<Node> > unrendered; |
| @@ -291,7 +293,7 @@ void ReplacementFragment::removeUnrenderedNodes(Node* holder) |
| removeNode(unrendered[i]); |
| } |
| -void ReplacementFragment::removeInterchangeNodes(Node* container) |
| +void ReplacementFragment::removeInterchangeNodes(ContainerNode* container) |
| { |
| m_hasInterchangeNewlineAtStart = false; |
| m_hasInterchangeNewlineAtEnd = false; |
| @@ -300,7 +302,7 @@ void ReplacementFragment::removeInterchangeNodes(Node* container) |
| // either the first node in the fragment or the first leaf in the fragment. |
| Node* node = container->firstChild(); |
| while (node) { |
| - if (isInterchangeNewlineNode(node)) { |
| + if (isInterchangeHTMLBRElement(node)) { |
| m_hasInterchangeNewlineAtStart = true; |
| removeNode(node); |
| break; |
| @@ -313,7 +315,7 @@ void ReplacementFragment::removeInterchangeNodes(Node* container) |
| // either the last node in the fragment or the last leaf in the fragment. |
| node = container->lastChild(); |
| while (node) { |
| - if (isInterchangeNewlineNode(node)) { |
| + if (isInterchangeHTMLBRElement(node)) { |
| m_hasInterchangeNewlineAtEnd = true; |
| removeNode(node); |
| break; |
| @@ -324,9 +326,10 @@ void ReplacementFragment::removeInterchangeNodes(Node* container) |
| node = container->firstChild(); |
| while (node) { |
| RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*node); |
| - if (isInterchangeConvertedSpaceSpan(node)) { |
| - next = NodeTraversal::nextSkippingChildren(*node); |
| - removeNodePreservingChildren(node); |
| + if (isHTMLInterchangeConvertedSpaceSpan(node)) { |
| + HTMLElement& element = toHTMLElement(*node); |
| + next = NodeTraversal::nextSkippingChildren(element); |
| + removeNodePreservingChildren(&element); |
| } |
| node = next.get(); |
| } |
| @@ -428,15 +431,18 @@ bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph) |
| && shouldMerge(endOfInsertedContent, next); |
| } |
| -static bool isMailPasteAsQuotationNode(const Node* node) |
| +static bool isMailPasteAsQuotationHTMLBlockQuoteElement(const Node* node) |
| { |
| - if (!node || !node->hasTagName(blockquoteTag) || toElement(node)->getAttribute(classAttr) != ApplePasteAsQuotation) |
| + if (!node || !node->isHTMLElement()) |
| + return false; |
| + const HTMLElement& element = toHTMLElement(*node); |
| + if (!element.hasTagName(blockquoteTag) || element.getAttribute(classAttr) != ApplePasteAsQuotation) |
| return false; |
| UseCounter::count(node->document(), UseCounter::EditingApplePasteAsQuotation); |
| return true; |
| } |
| -static bool isHeaderElement(const Node* a) |
| +static bool isHTMLHeaderElement(const Node* a) |
| { |
| if (!a || !a->isHTMLElement()) |
| return false; |
| @@ -450,9 +456,9 @@ static bool isHeaderElement(const Node* a) |
| || element.hasTagName(h6Tag); |
| } |
| -static bool haveSameTagName(Node* a, Node* b) |
| +static bool haveSameTagName(Element* a, Element* b) |
| { |
| - return a && b && a->isElementNode() && b->isElementNode() && toElement(a)->tagName() == toElement(b)->tagName(); |
| + return a && b && a->tagName() == b->tagName(); |
| } |
| bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const VisiblePosition& destination) |
| @@ -464,11 +470,11 @@ bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const V |
| Node* destinationNode = destination.deepEquivalent().deprecatedNode(); |
| Element* sourceBlock = enclosingBlock(sourceNode); |
| Element* destinationBlock = enclosingBlock(destinationNode); |
| - return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotationNode) |
| + return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotationHTMLBlockQuoteElement) |
| && sourceBlock && (!sourceBlock->hasTagName(blockquoteTag) || isMailHTMLBlockquoteElement(sourceBlock)) |
| && enclosingListChild(sourceBlock) == enclosingListChild(destinationNode) |
| && enclosingTableCell(source.deepEquivalent()) == enclosingTableCell(destination.deepEquivalent()) |
| - && (!isHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destinationBlock)) |
| + && (!isHTMLHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destinationBlock)) |
| // Don't merge to or from a position before or after a block because it would |
| // be a no-op and cause infinite recursion. |
| && !isBlock(sourceNode) && !isBlock(destinationNode); |
| @@ -506,7 +512,7 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert |
| EditingStyle::DoNotExtractMatchingStyle)) { |
| // e.g. <font size="3" style="font-size: 20px;"> is converted to <font style="font-size: 20px;"> |
| for (size_t i = 0; i < attributes.size(); i++) |
| - removeNodeAttribute(element, attributes[i]); |
| + removeElementAttribute(htmlElement, attributes[i]); |
| } |
| } |
| @@ -514,8 +520,8 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert |
| // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region, |
| // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. |
| - Node* blockquoteNode = !context || isMailPasteAsQuotationNode(context) ? context : enclosingNodeOfType(firstPositionInNode(context), isMailHTMLBlockquoteElement, CanCrossEditingBoundary); |
| - if (blockquoteNode) |
| + HTMLQuoteElement* blockquoteElement = !context || isMailPasteAsQuotationHTMLBlockQuoteElement(context) ? toHTMLQuoteElement(context) : toHTMLQuoteElement(enclosingNodeOfType(firstPositionInNode(context), isMailHTMLBlockquoteElement, CanCrossEditingBoundary)); |
|
leviw_travelin_and_unemployed
2014/08/11 22:13:27
Nit: I'd wrap this longness.
Inactive
2014/08/12 12:59:15
Done.
|
| + if (blockquoteElement) |
| newInlineStyle->removeStyleFromRulesAndContext(element, document().documentElement()); |
| newInlineStyle->removeStyleFromRulesAndContext(element, context); |
| @@ -527,7 +533,7 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert |
| removeNodePreservingChildren(element); |
| continue; |
| } |
| - removeNodeAttribute(element, styleAttr); |
| + removeElementAttribute(element, styleAttr); |
| } else if (newInlineStyle->style()->propertyCount() != inlineStyle->propertyCount()) { |
| setNodeAttribute(element, styleAttr, AtomicString(newInlineStyle->style()->asText())); |
| } |
| @@ -542,11 +548,11 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert |
| } |
| if (element->parentNode() && element->parentNode()->rendererIsRichlyEditable()) |
| - removeNodeAttribute(element, contenteditableAttr); |
| + removeElementAttribute(element, contenteditableAttr); |
| // WebKit used to not add display: inline and float: none on copy. |
| // Keep this code around for backward compatibility |
| - if (isLegacyAppleStyleSpan(element)) { |
| + if (isLegacyAppleHTMLSpanElement(element)) { |
| if (!element->hasChildren()) { |
| insertedNodes.willRemoveNodePreservingChildren(*element); |
| removeNodePreservingChildren(element); |
| @@ -635,38 +641,39 @@ void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild |
| if (!node->isHTMLElement()) |
| continue; |
| - if (isProhibitedParagraphChild(toHTMLElement(node)->localName())) { |
| - if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWithTag(positionInParentBeforeNode(*node), pTag))) |
| - moveNodeOutOfAncestor(node, paragraphElement); |
| + HTMLElement& element = toHTMLElement(*node); |
| + if (isProhibitedParagraphChild(element.localName())) { |
| + if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWithTag(positionInParentBeforeNode(element), pTag))) |
| + moveElementOutOfAncestor(&element, paragraphElement); |
| } |
| - if (isHeaderElement(node.get())) { |
| - if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(*node), isHeaderElement))) |
| - moveNodeOutOfAncestor(node, headerElement); |
| + if (isHTMLHeaderElement(&element)) { |
| + if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(element), isHTMLHeaderElement))) |
| + moveElementOutOfAncestor(&element, headerElement); |
| } |
| } |
| } |
| -void ReplaceSelectionCommand::moveNodeOutOfAncestor(PassRefPtrWillBeRawPtr<Node> prpNode, PassRefPtrWillBeRawPtr<ContainerNode> prpAncestor) |
| +void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<Element> prpElement, PassRefPtrWillBeRawPtr<ContainerNode> prpAncestor) |
| { |
| - RefPtrWillBeRawPtr<Node> node = prpNode; |
| - RefPtrWillBeRawPtr<Node> ancestor = prpAncestor; |
| + RefPtrWillBeRawPtr<Element> element = prpElement; |
| + RefPtrWillBeRawPtr<ContainerNode> ancestor = prpAncestor; |
| if (!ancestor->parentNode()->hasEditableStyle()) |
| return; |
| - VisiblePosition positionAtEndOfNode(lastPositionInOrAfterNode(node.get())); |
| + VisiblePosition positionAtEndOfNode(lastPositionInOrAfterNode(element.get())); |
| VisiblePosition lastPositionInParagraph(lastPositionInNode(ancestor.get())); |
| if (positionAtEndOfNode == lastPositionInParagraph) { |
| - removeNode(node); |
| + removeNode(element); |
| if (ancestor->nextSibling()) |
| - insertNodeBefore(node, ancestor->nextSibling()); |
| + insertNodeBefore(element, ancestor->nextSibling()); |
| else |
| - appendNode(node, ancestor->parentNode()); |
| + appendNode(element, ancestor->parentNode()); |
| } else { |
| - RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(node.get(), ancestor.get(), true); |
| - removeNode(node); |
| - insertNodeBefore(node, nodeToSplitTo); |
| + RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(), ancestor.get(), true); |
| + removeNode(element); |
| + insertNodeBefore(element, nodeToSplitTo); |
| } |
| if (!ancestor->hasChildren()) |
| removeNode(ancestor.release()); |
| @@ -701,7 +708,7 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins |
| VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const |
| { |
| // FIXME: Why is this hack here? What's special about <select> tags? |
| - Element* enclosingSelect = enclosingElementWithTag(m_endOfInsertedContent, selectTag); |
| + HTMLSelectElement* enclosingSelect = toHTMLSelectElement(enclosingElementWithTag(m_endOfInsertedContent, selectTag)); |
| return VisiblePosition(enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endOfInsertedContent); |
| } |
| @@ -735,21 +742,21 @@ static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const |
| // Handling the case where we are doing Paste as Quotation or pasting into quoted content is more complicated (see handleStyleSpans) |
| // and doesn't receive the optimization. |
| - if (isMailPasteAsQuotationNode(topNode) || enclosingNodeOfType(firstPositionInOrBeforeNode(topNode), isMailHTMLBlockquoteElement, CanCrossEditingBoundary)) |
| + if (isMailPasteAsQuotationHTMLBlockQuoteElement(topNode) || enclosingNodeOfType(firstPositionInOrBeforeNode(topNode), isMailHTMLBlockquoteElement, CanCrossEditingBoundary)) |
| return false; |
| // Either there are no style spans in the fragment or a WebKit client has added content to the fragment |
| // before inserting it. Look for and handle style spans after insertion. |
| - if (!isLegacyAppleStyleSpan(topNode)) |
| + if (!isLegacyAppleHTMLSpanElement(topNode)) |
| return false; |
| - Node* wrappingStyleSpan = topNode; |
| + HTMLSpanElement* wrappingStyleSpan = toHTMLSpanElement(topNode); |
| RefPtrWillBeRawPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create(insertionPos.parentAnchoredEquivalent()); |
| String styleText = styleAtInsertionPos->style()->asText(); |
| // FIXME: This string comparison is a naive way of comparing two styles. |
| // We should be taking the diff and check that the diff is empty. |
| - if (styleText != toElement(wrappingStyleSpan)->getAttribute(styleAttr)) |
| + if (styleText != wrappingStyleSpan->getAttribute(styleAttr)) |
| return false; |
| fragment.removeNodePreservingChildren(wrappingStyleSpan); |
| @@ -766,13 +773,13 @@ static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const |
| // or at copy time. |
| void ReplaceSelectionCommand::handleStyleSpans(InsertedNodes& insertedNodes) |
| { |
| - HTMLElement* wrappingStyleSpan = 0; |
| + HTMLSpanElement* wrappingStyleSpan = 0; |
| // The style span that contains the source document's default style should be at |
| // the top of the fragment, but Mail sometimes adds a wrapper (for Paste As Quotation), |
| // so search for the top level style span instead of assuming it's at the top. |
| for (Node* node = insertedNodes.firstNodeInserted(); node; node = NodeTraversal::next(*node)) { |
| - if (isLegacyAppleStyleSpan(node)) { |
| - wrappingStyleSpan = toHTMLElement(node); |
| + if (isLegacyAppleHTMLSpanElement(node)) { |
| + wrappingStyleSpan = toHTMLSpanElement(node); |
| break; |
| } |
| } |
| @@ -786,9 +793,9 @@ void ReplaceSelectionCommand::handleStyleSpans(InsertedNodes& insertedNodes) |
| ContainerNode* context = wrappingStyleSpan->parentNode(); |
| // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region, |
| - // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. |
| - Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : enclosingNodeOfType(firstPositionInNode(context), isMailHTMLBlockquoteElement, CanCrossEditingBoundary); |
| - if (blockquoteNode) |
| + // styles from blockquoteElement are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. |
| + HTMLQuoteElement* blockquoteElement = isMailPasteAsQuotationHTMLBlockQuoteElement(context) ? toHTMLQuoteElement(context) : toHTMLQuoteElement(enclosingNodeOfType(firstPositionInNode(context), isMailHTMLBlockquoteElement, CanCrossEditingBoundary)); |
|
leviw_travelin_and_unemployed
2014/08/11 22:13:27
Ditto wrapping.
Inactive
2014/08/12 12:59:15
Done.
|
| + if (blockquoteElement) |
| context = document().documentElement(); |
| // This operation requires that only editing styles to be removed from sourceDocumentStyle. |
| @@ -868,7 +875,7 @@ static Node* enclosingInline(Node* node) |
| return node; |
| } |
| -static bool isInlineNodeWithStyle(const Node* node) |
| +static bool isInlineHTMLElementWithStyle(const Node* node) |
| { |
| // We don't want to skip over any block elements. |
| if (isBlock(node)) |
| @@ -882,25 +889,25 @@ static bool isInlineNodeWithStyle(const Node* node) |
| const HTMLElement* element = toHTMLElement(node); |
| const AtomicString& classAttributeValue = element->getAttribute(classAttr); |
| if (classAttributeValue == AppleTabSpanClass) { |
| - UseCounter::count(node->document(), UseCounter::EditingAppleTabSpanClass); |
| + UseCounter::count(element->document(), UseCounter::EditingAppleTabSpanClass); |
| return true; |
| } |
| if (classAttributeValue == AppleConvertedSpace) { |
| - UseCounter::count(node->document(), UseCounter::EditingAppleConvertedSpace); |
| + UseCounter::count(element->document(), UseCounter::EditingAppleConvertedSpace); |
| return true; |
| } |
| if (classAttributeValue == ApplePasteAsQuotation) { |
| - UseCounter::count(node->document(), UseCounter::EditingApplePasteAsQuotation); |
| + UseCounter::count(element->document(), UseCounter::EditingApplePasteAsQuotation); |
| return true; |
| } |
| return EditingStyle::elementIsStyledSpanOrHTMLEquivalent(element); |
| } |
| -inline Node* nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(const Position& insertionPos) |
| +static inline HTMLElement* elementToSplitToAvoidPastingIntoInlineElementsWithStyle(const Position& insertionPos) |
| { |
| Element* containingBlock = enclosingBlock(insertionPos.containerNode()); |
| - return highestEnclosingNodeOfType(insertionPos, isInlineNodeWithStyle, CannotCrossEditingBoundary, containingBlock); |
| + return toHTMLElement(highestEnclosingNodeOfType(insertionPos, isInlineHTMLElementWithStyle, CannotCrossEditingBoundary, containingBlock)); |
| } |
| void ReplaceSelectionCommand::doApply() |
| @@ -934,7 +941,7 @@ void ReplaceSelectionCommand::doApply() |
| bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); |
| bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); |
| - Node* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEquivalent().deprecatedNode()); |
| + Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEquivalent().deprecatedNode()); |
| Position insertionPos = selection.start(); |
| bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, CanCrossEditingBoundary); |
| @@ -1011,12 +1018,12 @@ void ReplaceSelectionCommand::doApply() |
| // NOTE: This would be an incorrect usage of downstream() if downstream() were changed to mean the last position after |
| // p that maps to the same visible position as p (since in the case where a br is at the end of a block and collapsed |
| // away, there are positions after the br which map to the same visible position as [br, 0]). |
| - Node* endBR = isHTMLBRElement(*insertionPos.downstream().deprecatedNode()) ? insertionPos.downstream().deprecatedNode() : 0; |
| + HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().deprecatedNode()) ? toHTMLBRElement(insertionPos.downstream().deprecatedNode()) : 0; |
| VisiblePosition originalVisPosBeforeEndBR; |
| if (endBR) |
| originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), DOWNSTREAM).previous(); |
| - RefPtrWillBeRawPtr<Node> enclosingBlockOfInsertionPos = enclosingBlock(insertionPos.deprecatedNode()); |
| + RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(insertionPos.deprecatedNode()); |
| // Adjust insertionPos to prevent nesting. |
| // If the start was in a Mail blockquote, we will have already handled adjusting insertionPos above. |
| @@ -1065,12 +1072,12 @@ void ReplaceSelectionCommand::doApply() |
| insertionPos = firstPositionInNode(insertionPos.containerNode()); |
| } |
| - if (RefPtrWillBeRawPtr<Node> nodeToSplitTo = nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(insertionPos)) { |
| - if (insertionPos.containerNode() != nodeToSplitTo->parentNode()) { |
| + if (RefPtrWillBeRawPtr<HTMLElement> elementToSplitTo = elementToSplitToAvoidPastingIntoInlineElementsWithStyle(insertionPos)) { |
| + if (insertionPos.containerNode() != elementToSplitTo->parentNode()) { |
| Node* splitStart = insertionPos.computeNodeAfterPosition(); |
| if (!splitStart) |
| splitStart = insertionPos.containerNode(); |
| - nodeToSplitTo = splitTreeToNode(splitStart, nodeToSplitTo->parentNode()).get(); |
| + RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(splitStart, elementToSplitTo->parentNode()).get(); |
| insertionPos = positionInParentBeforeNode(*nodeToSplitTo); |
| } |
| } |
| @@ -1096,8 +1103,8 @@ void ReplaceSelectionCommand::doApply() |
| fragment.removeNode(refNode); |
| - Node* blockStart = enclosingBlock(insertionPos.deprecatedNode()); |
| - if ((isHTMLListElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isHTMLListElement(refNode->firstChild()))) |
| + Element* blockStart = enclosingBlock(insertionPos.deprecatedNode()); |
| + if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNode.get()) && isHTMLListElement(refNode->firstChild()))) |
| && blockStart && blockStart->renderer()->isListItem()) |
| refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertionPos, insertedNodes); |
| else { |
| @@ -1214,10 +1221,10 @@ void ReplaceSelectionCommand::doApply() |
| if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedContent) || next.isNull()) { |
| if (!isStartOfParagraph(endOfInsertedContent)) { |
| setEndingSelection(endOfInsertedContent); |
| - Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEquivalent().deprecatedNode()); |
| - if (isListItem(enclosingNode)) { |
| + Element* enclosingBlockElement = enclosingBlock(endOfInsertedContent.deepEquivalent().deprecatedNode()); |
| + if (isListItem(enclosingBlockElement)) { |
| RefPtrWillBeRawPtr<HTMLLIElement> newListItem = createListItemElement(document()); |
| - insertNodeAfter(newListItem, enclosingNode); |
| + insertNodeAfter(newListItem, enclosingBlockElement); |
| setEndingSelection(VisiblePosition(firstPositionInNode(newListItem.get()))); |
| } else { |
| // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph |
| @@ -1234,12 +1241,12 @@ void ReplaceSelectionCommand::doApply() |
| // Select up to the beginning of the next paragraph. |
| lastPositionToSelect = next.deepEquivalent().downstream(); |
| } |
| - |
| - } else |
| + } else { |
| mergeEndIfNeeded(); |
| + } |
| - if (Node* mailBlockquote = enclosingNodeOfType(positionAtStartOfInsertedContent().deepEquivalent(), isMailPasteAsQuotationNode)) |
| - removeNodeAttribute(toElement(mailBlockquote), classAttr); |
| + if (HTMLQuoteElement* mailBlockquote = toHTMLQuoteElement(enclosingNodeOfType(positionAtStartOfInsertedContent().deepEquivalent(), isMailPasteAsQuotationHTMLBlockQuoteElement))) |
| + removeElementAttribute(mailBlockquote, classAttr); |
| if (shouldPerformSmartReplace()) |
| addSpacesForSmartReplace(); |
| @@ -1252,7 +1259,7 @@ void ReplaceSelectionCommand::doApply() |
| completeHTMLReplacement(lastPositionToSelect); |
| } |
| -bool ReplaceSelectionCommand::shouldRemoveEndBR(Node* endBR, const VisiblePosition& originalVisPosBeforeEndBR) |
| +bool ReplaceSelectionCommand::shouldRemoveEndBR(HTMLBRElement* endBR, const VisiblePosition& originalVisPosBeforeEndBR) |
| { |
| if (!endBR || !endBR->inDocument()) |
| return false; |
| @@ -1277,7 +1284,7 @@ bool ReplaceSelectionCommand::shouldPerformSmartReplace() const |
| if (!m_smartReplace) |
| return false; |
| - Element* textControl = enclosingTextFormControl(positionAtStartOfInsertedContent().deepEquivalent()); |
| + HTMLTextFormControlElement* textControl = enclosingTextFormControl(positionAtStartOfInsertedContent().deepEquivalent()); |
| if (isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->isPasswordField()) |
| return false; // Disable smart replace for password fields. |
| @@ -1310,7 +1317,7 @@ void ReplaceSelectionCommand::addSpacesForSmartReplace() |
| if (m_endOfInsertedContent.containerNode() == endNode) |
| m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offsetInContainerNode() + 1); |
| } else { |
| - RefPtrWillBeRawPtr<Node> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " "); |
| + RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " "); |
| insertNodeAfter(node, endNode); |
| updateNodesInserted(node.get()); |
| } |
| @@ -1334,7 +1341,7 @@ void ReplaceSelectionCommand::addSpacesForSmartReplace() |
| if (m_endOfInsertedContent.containerNode() == startNode && m_endOfInsertedContent.offsetInContainerNode()) |
| m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offsetInContainerNode() + 1); |
| } else { |
| - RefPtrWillBeRawPtr<Node> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " "); |
| + RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " "); |
| // Don't updateNodesInserted. Doing so would set m_endOfInsertedContent to be the node containing the leading space, |
| // but m_endOfInsertedContent is supposed to mark the end of pasted content. |
| insertNodeBefore(node, startNode); |
| @@ -1438,7 +1445,7 @@ EditAction ReplaceSelectionCommand::editingAction() const |
| // If the user is inserting a list into an existing list, instead of nesting the list, |
| // we put the list items into the existing list. |
| -Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtrWillBeRawPtr<HTMLElement> prpListElement, Node* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes) |
| +Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtrWillBeRawPtr<HTMLElement> prpListElement, Element* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes) |
| { |
| RefPtrWillBeRawPtr<HTMLElement> listElement = prpListElement; |
| @@ -1503,7 +1510,7 @@ bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f |
| return false; |
| // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" should not be underlined. |
| - if (nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(endingSelection().start())) |
| + if (elementToSplitToAvoidPastingIntoInlineElementsWithStyle(endingSelection().start())) |
| return false; |
| RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = endingSelection().end().downstream().anchorNode(); |
| @@ -1516,7 +1523,7 @@ bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f |
| return false; |
| if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBRElement(*nodeAfterInsertionPos) |
| - && shouldRemoveEndBR(nodeAfterInsertionPos.get(), VisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) |
| + && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), VisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) |
| removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); |
| VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, end); |