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); |