| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 return; | 162 return; |
| 163 | 163 |
| 164 Element* shadowAncestorElement; | 164 Element* shadowAncestorElement; |
| 165 if (editableRoot->isInShadowTree()) | 165 if (editableRoot->isInShadowTree()) |
| 166 shadowAncestorElement = editableRoot->shadowHost(); | 166 shadowAncestorElement = editableRoot->shadowHost(); |
| 167 else | 167 else |
| 168 shadowAncestorElement = editableRoot.get(); | 168 shadowAncestorElement = editableRoot.get(); |
| 169 | 169 |
| 170 if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTex
tInserted) | 170 if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTex
tInserted) |
| 171 // FIXME: Remove these checks once textareas and textfields actually reg
ister an event handler. | 171 // FIXME: Remove these checks once textareas and textfields actually reg
ister an event handler. |
| 172 && !(shadowAncestorElement && shadowAncestorElement->renderer() && shado
wAncestorElement->renderer()->isTextControl()) | 172 && !(shadowAncestorElement && shadowAncestorElement->layoutObject() && s
hadowAncestorElement->layoutObject()->isTextControl()) |
| 173 && editableRoot->layoutObjectIsRichlyEditable()) { | 173 && editableRoot->layoutObjectIsRichlyEditable()) { |
| 174 removeInterchangeNodes(m_fragment.get()); | 174 removeInterchangeNodes(m_fragment.get()); |
| 175 return; | 175 return; |
| 176 } | 176 } |
| 177 | 177 |
| 178 RefPtrWillBeRawPtr<HTMLElement> holder = insertFragmentForTestRendering(edit
ableRoot.get()); | 178 RefPtrWillBeRawPtr<HTMLElement> holder = insertFragmentForTestRendering(edit
ableRoot.get()); |
| 179 if (!holder) { | 179 if (!holder) { |
| 180 removeInterchangeNodes(m_fragment.get()); | 180 removeInterchangeNodes(m_fragment.get()); |
| 181 return; | 181 return; |
| 182 } | 182 } |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 // There are other styles that style rules can give to style spans, | 564 // There are other styles that style rules can give to style spans, |
| 565 // but these are the two important ones because they'll prevent | 565 // but these are the two important ones because they'll prevent |
| 566 // inserted content from appearing in the right paragraph. | 566 // inserted content from appearing in the right paragraph. |
| 567 // FIXME: Hyatt is concerned that selectively using display:inline w
ill give inconsistent | 567 // FIXME: Hyatt is concerned that selectively using display:inline w
ill give inconsistent |
| 568 // results. We already know one issue because td elements ignore the
ir display property | 568 // results. We already know one issue because td elements ignore the
ir display property |
| 569 // in quirks mode (which Mail.app is always in). We should look for
an alternative. | 569 // in quirks mode (which Mail.app is always in). We should look for
an alternative. |
| 570 | 570 |
| 571 // Mutate using the CSSOM wrapper so we get the same event behavior
as a script. | 571 // Mutate using the CSSOM wrapper so we get the same event behavior
as a script. |
| 572 if (isBlock(element)) | 572 if (isBlock(element)) |
| 573 element->style()->setPropertyInternal(CSSPropertyDisplay, "inlin
e", false, IGNORE_EXCEPTION); | 573 element->style()->setPropertyInternal(CSSPropertyDisplay, "inlin
e", false, IGNORE_EXCEPTION); |
| 574 if (element->renderer() && element->renderer()->style()->isFloating(
)) | 574 if (element->layoutObject() && element->layoutObject()->style()->isF
loating()) |
| 575 element->style()->setPropertyInternal(CSSPropertyFloat, "none",
false, IGNORE_EXCEPTION); | 575 element->style()->setPropertyInternal(CSSPropertyFloat, "none",
false, IGNORE_EXCEPTION); |
| 576 } | 576 } |
| 577 } | 577 } |
| 578 } | 578 } |
| 579 | 579 |
| 580 static bool isProhibitedParagraphChild(const AtomicString& name) | 580 static bool isProhibitedParagraphChild(const AtomicString& name) |
| 581 { | 581 { |
| 582 // https://dvcs.w3.org/hg/editing/raw-file/57abe6d3cb60/editing.html#prohibi
ted-paragraph-child | 582 // https://dvcs.w3.org/hg/editing/raw-file/57abe6d3cb60/editing.html#prohibi
ted-paragraph-child |
| 583 DEFINE_STATIC_LOCAL(HashSet<AtomicString>, elements, ()); | 583 DEFINE_STATIC_LOCAL(HashSet<AtomicString>, elements, ()); |
| 584 if (elements.isEmpty()) { | 584 if (elements.isEmpty()) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(),
ancestor.get(), true); | 677 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(),
ancestor.get(), true); |
| 678 removeNode(element); | 678 removeNode(element); |
| 679 insertNodeBefore(element, nodeToSplitTo); | 679 insertNodeBefore(element, nodeToSplitTo); |
| 680 } | 680 } |
| 681 if (!ancestor->hasChildren()) | 681 if (!ancestor->hasChildren()) |
| 682 removeNode(ancestor.release()); | 682 removeNode(ancestor.release()); |
| 683 } | 683 } |
| 684 | 684 |
| 685 static inline bool nodeHasVisibleRenderText(Text& text) | 685 static inline bool nodeHasVisibleRenderText(Text& text) |
| 686 { | 686 { |
| 687 return text.renderer() && text.renderer()->renderedTextLength() > 0; | 687 return text.layoutObject() && text.layoutObject()->renderedTextLength() > 0; |
| 688 } | 688 } |
| 689 | 689 |
| 690 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins
ertedNodes) | 690 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins
ertedNodes) |
| 691 { | 691 { |
| 692 document().updateLayoutIgnorePendingStylesheets(); | 692 document().updateLayoutIgnorePendingStylesheets(); |
| 693 | 693 |
| 694 Node* lastLeafInserted = insertedNodes.lastLeafInserted(); | 694 Node* lastLeafInserted = insertedNodes.lastLeafInserted(); |
| 695 if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleRen
derText(toText(*lastLeafInserted)) | 695 if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleRen
derText(toText(*lastLeafInserted)) |
| 696 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted
), selectTag) | 696 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted
), selectTag) |
| 697 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted
), scriptTag)) { | 697 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted
), scriptTag)) { |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 return; | 925 return; |
| 926 | 926 |
| 927 if (!selection.rootEditableElement()) | 927 if (!selection.rootEditableElement()) |
| 928 return; | 928 return; |
| 929 | 929 |
| 930 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio
n); | 930 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio
n); |
| 931 if (performTrivialReplace(fragment)) | 931 if (performTrivialReplace(fragment)) |
| 932 return; | 932 return; |
| 933 | 933 |
| 934 // We can skip matching the style if the selection is plain text. | 934 // We can skip matching the style if the selection is plain text. |
| 935 if ((selection.start().deprecatedNode()->renderer() && selection.start().dep
recatedNode()->renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY) | 935 if ((selection.start().deprecatedNode()->layoutObject() && selection.start()
.deprecatedNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT
_ONLY) |
| 936 && (selection.end().deprecatedNode()->renderer() && selection.end().depr
ecatedNode()->renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY)) | 936 && (selection.end().deprecatedNode()->layoutObject() && selection.end().
deprecatedNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_
ONLY)) |
| 937 m_matchStyle = false; | 937 m_matchStyle = false; |
| 938 | 938 |
| 939 if (m_matchStyle) { | 939 if (m_matchStyle) { |
| 940 m_insertionStyle = EditingStyle::create(selection.start()); | 940 m_insertionStyle = EditingStyle::create(selection.start()); |
| 941 m_insertionStyle->mergeTypingStyle(&document()); | 941 m_insertionStyle->mergeTypingStyle(&document()); |
| 942 } | 942 } |
| 943 | 943 |
| 944 VisiblePosition visibleStart = selection.visibleStart(); | 944 VisiblePosition visibleStart = selection.visibleStart(); |
| 945 VisiblePosition visibleEnd = selection.visibleEnd(); | 945 VisiblePosition visibleEnd = selection.visibleEnd(); |
| 946 | 946 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 | 1104 |
| 1105 InsertedNodes insertedNodes; | 1105 InsertedNodes insertedNodes; |
| 1106 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); | 1106 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); |
| 1107 ASSERT(refNode); | 1107 ASSERT(refNode); |
| 1108 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); | 1108 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); |
| 1109 | 1109 |
| 1110 fragment.removeNode(refNode); | 1110 fragment.removeNode(refNode); |
| 1111 | 1111 |
| 1112 Element* blockStart = enclosingBlock(insertionPos.deprecatedNode()); | 1112 Element* blockStart = enclosingBlock(insertionPos.deprecatedNode()); |
| 1113 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo
de.get()) && isHTMLListElement(refNode->firstChild()))) | 1113 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo
de.get()) && isHTMLListElement(refNode->firstChild()))) |
| 1114 && blockStart && blockStart->renderer()->isListItem()) | 1114 && blockStart && blockStart->layoutObject()->isListItem()) |
| 1115 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio
nPos, insertedNodes); | 1115 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio
nPos, insertedNodes); |
| 1116 else { | 1116 else { |
| 1117 insertNodeAt(refNode, insertionPos); | 1117 insertNodeAt(refNode, insertionPos); |
| 1118 insertedNodes.respondToNodeInsertion(*refNode); | 1118 insertedNodes.respondToNodeInsertion(*refNode); |
| 1119 } | 1119 } |
| 1120 | 1120 |
| 1121 // Mutation events (bug 22634) may have already removed the inserted content | 1121 // Mutation events (bug 22634) may have already removed the inserted content |
| 1122 if (!refNode->inDocument()) | 1122 if (!refNode->inDocument()) |
| 1123 return; | 1123 return; |
| 1124 | 1124 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 Position endUpstream = endOfInsertedContent.deepEquivalent().upstream(); | 1310 Position endUpstream = endOfInsertedContent.deepEquivalent().upstream(); |
| 1311 Node* endNode = endUpstream.computeNodeBeforePosition(); | 1311 Node* endNode = endUpstream.computeNodeBeforePosition(); |
| 1312 int endOffset = endNode && endNode->isTextNode() ? toText(endNode)->length()
: 0; | 1312 int endOffset = endNode && endNode->isTextNode() ? toText(endNode)->length()
: 0; |
| 1313 if (endUpstream.anchorType() == Position::PositionIsOffsetInAnchor) { | 1313 if (endUpstream.anchorType() == Position::PositionIsOffsetInAnchor) { |
| 1314 endNode = endUpstream.containerNode(); | 1314 endNode = endUpstream.containerNode(); |
| 1315 endOffset = endUpstream.offsetInContainerNode(); | 1315 endOffset = endUpstream.offsetInContainerNode(); |
| 1316 } | 1316 } |
| 1317 | 1317 |
| 1318 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar
acterSmartReplaceExemptConsideringNonBreakingSpace(endOfInsertedContent.characte
rAfter(), false); | 1318 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar
acterSmartReplaceExemptConsideringNonBreakingSpace(endOfInsertedContent.characte
rAfter(), false); |
| 1319 if (needsTrailingSpace && endNode) { | 1319 if (needsTrailingSpace && endNode) { |
| 1320 bool collapseWhiteSpace = !endNode->renderer() || endNode->renderer()->s
tyle()->collapseWhiteSpace(); | 1320 bool collapseWhiteSpace = !endNode->layoutObject() || endNode->layoutObj
ect()->style()->collapseWhiteSpace(); |
| 1321 if (endNode->isTextNode()) { | 1321 if (endNode->isTextNode()) { |
| 1322 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ?
nonBreakingSpaceString() : " "); | 1322 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ?
nonBreakingSpaceString() : " "); |
| 1323 if (m_endOfInsertedContent.containerNode() == endNode) | 1323 if (m_endOfInsertedContent.containerNode() == endNode) |
| 1324 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse
tInContainerNode() + 1); | 1324 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse
tInContainerNode() + 1); |
| 1325 } else { | 1325 } else { |
| 1326 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col
lapseWhiteSpace ? nonBreakingSpaceString() : " "); | 1326 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col
lapseWhiteSpace ? nonBreakingSpaceString() : " "); |
| 1327 insertNodeAfter(node, endNode); | 1327 insertNodeAfter(node, endNode); |
| 1328 updateNodesInserted(node.get()); | 1328 updateNodesInserted(node.get()); |
| 1329 } | 1329 } |
| 1330 } | 1330 } |
| 1331 | 1331 |
| 1332 document().updateLayout(); | 1332 document().updateLayout(); |
| 1333 | 1333 |
| 1334 Position startDownstream = startOfInsertedContent.deepEquivalent().downstrea
m(); | 1334 Position startDownstream = startOfInsertedContent.deepEquivalent().downstrea
m(); |
| 1335 Node* startNode = startDownstream.computeNodeAfterPosition(); | 1335 Node* startNode = startDownstream.computeNodeAfterPosition(); |
| 1336 unsigned startOffset = 0; | 1336 unsigned startOffset = 0; |
| 1337 if (startDownstream.anchorType() == Position::PositionIsOffsetInAnchor) { | 1337 if (startDownstream.anchorType() == Position::PositionIsOffsetInAnchor) { |
| 1338 startNode = startDownstream.containerNode(); | 1338 startNode = startDownstream.containerNode(); |
| 1339 startOffset = startDownstream.offsetInContainerNode(); | 1339 startOffset = startDownstream.offsetInContainerNode(); |
| 1340 } | 1340 } |
| 1341 | 1341 |
| 1342 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC
haracterSmartReplaceExemptConsideringNonBreakingSpace(startOfInsertedContent.pre
vious().characterAfter(), true); | 1342 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC
haracterSmartReplaceExemptConsideringNonBreakingSpace(startOfInsertedContent.pre
vious().characterAfter(), true); |
| 1343 if (needsLeadingSpace && startNode) { | 1343 if (needsLeadingSpace && startNode) { |
| 1344 bool collapseWhiteSpace = !startNode->renderer() || startNode->renderer(
)->style()->collapseWhiteSpace(); | 1344 bool collapseWhiteSpace = !startNode->layoutObject() || startNode->layou
tObject()->style()->collapseWhiteSpace(); |
| 1345 if (startNode->isTextNode()) { | 1345 if (startNode->isTextNode()) { |
| 1346 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac
e ? nonBreakingSpaceString() : " "); | 1346 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac
e ? nonBreakingSpaceString() : " "); |
| 1347 if (m_endOfInsertedContent.containerNode() == startNode && m_endOfIn
sertedContent.offsetInContainerNode()) | 1347 if (m_endOfInsertedContent.containerNode() == startNode && m_endOfIn
sertedContent.offsetInContainerNode()) |
| 1348 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse
tInContainerNode() + 1); | 1348 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse
tInContainerNode() + 1); |
| 1349 } else { | 1349 } else { |
| 1350 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col
lapseWhiteSpace ? nonBreakingSpaceString() : " "); | 1350 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col
lapseWhiteSpace ? nonBreakingSpaceString() : " "); |
| 1351 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont
ent to be the node containing the leading space, | 1351 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont
ent to be the node containing the leading space, |
| 1352 // but m_endOfInsertedContent is supposed to mark the end of pasted
content. | 1352 // but m_endOfInsertedContent is supposed to mark the end of pasted
content. |
| 1353 insertNodeBefore(node, startNode); | 1353 insertNodeBefore(node, startNode); |
| 1354 m_startOfInsertedContent = firstPositionInNode(node.get()); | 1354 m_startOfInsertedContent = firstPositionInNode(node.get()); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1542 DEFINE_TRACE(ReplaceSelectionCommand) | 1542 DEFINE_TRACE(ReplaceSelectionCommand) |
| 1543 { | 1543 { |
| 1544 visitor->trace(m_startOfInsertedContent); | 1544 visitor->trace(m_startOfInsertedContent); |
| 1545 visitor->trace(m_endOfInsertedContent); | 1545 visitor->trace(m_endOfInsertedContent); |
| 1546 visitor->trace(m_insertionStyle); | 1546 visitor->trace(m_insertionStyle); |
| 1547 visitor->trace(m_documentFragment); | 1547 visitor->trace(m_documentFragment); |
| 1548 CompositeEditCommand::trace(visitor); | 1548 CompositeEditCommand::trace(visitor); |
| 1549 } | 1549 } |
| 1550 | 1550 |
| 1551 } // namespace blink | 1551 } // namespace blink |
| OLD | NEW |