| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 InlineRunToApplyStyle(Node* start, Node* end, Node* pastEndNode) | 797 InlineRunToApplyStyle(Node* start, Node* end, Node* pastEndNode) |
| 798 : start(start) | 798 : start(start) |
| 799 , end(end) | 799 , end(end) |
| 800 , pastEndNode(pastEndNode) | 800 , pastEndNode(pastEndNode) |
| 801 { | 801 { |
| 802 DCHECK_EQ(start->parentNode(), end->parentNode()); | 802 DCHECK_EQ(start->parentNode(), end->parentNode()); |
| 803 } | 803 } |
| 804 | 804 |
| 805 bool startAndEndAreStillInDocument() | 805 bool startAndEndAreStillInDocument() |
| 806 { | 806 { |
| 807 return start && end && start->inShadowIncludingDocument() && end->inShad
owIncludingDocument(); | 807 return start && end && start->isConnected() && end->isConnected(); |
| 808 } | 808 } |
| 809 | 809 |
| 810 DEFINE_INLINE_TRACE() | 810 DEFINE_INLINE_TRACE() |
| 811 { | 811 { |
| 812 visitor->trace(start); | 812 visitor->trace(start); |
| 813 visitor->trace(end); | 813 visitor->trace(end); |
| 814 visitor->trace(pastEndNode); | 814 visitor->trace(pastEndNode); |
| 815 visitor->trace(positionForStyleComputation); | 815 visitor->trace(positionForStyleComputation); |
| 816 visitor->trace(dummyElement); | 816 visitor->trace(dummyElement); |
| 817 } | 817 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 return true; | 946 return true; |
| 947 } | 947 } |
| 948 return false; | 948 return false; |
| 949 } | 949 } |
| 950 | 950 |
| 951 void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style,
Member<Node>& runStart, Member<Node>& runEnd, Node* pastEndNode, EditingState*
editingState) | 951 void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style,
Member<Node>& runStart, Member<Node>& runEnd, Node* pastEndNode, EditingState*
editingState) |
| 952 { | 952 { |
| 953 DCHECK(runStart); | 953 DCHECK(runStart); |
| 954 DCHECK(runEnd); | 954 DCHECK(runEnd); |
| 955 Node* next = runStart; | 955 Node* next = runStart; |
| 956 for (Node* node = next; node && node->inShadowIncludingDocument() && node !=
pastEndNode; node = next) { | 956 for (Node* node = next; node && node->isConnected() && node != pastEndNode;
node = next) { |
| 957 if (editingIgnoresContent(node)) { | 957 if (editingIgnoresContent(node)) { |
| 958 DCHECK(!node->contains(pastEndNode)) << node << " " << pastEndNode; | 958 DCHECK(!node->contains(pastEndNode)) << node << " " << pastEndNode; |
| 959 next = NodeTraversal::nextSkippingChildren(*node); | 959 next = NodeTraversal::nextSkippingChildren(*node); |
| 960 } else { | 960 } else { |
| 961 next = NodeTraversal::next(*node); | 961 next = NodeTraversal::next(*node); |
| 962 } | 962 } |
| 963 if (!node->isHTMLElement()) | 963 if (!node->isHTMLElement()) |
| 964 continue; | 964 continue; |
| 965 | 965 |
| 966 HTMLElement& element = toHTMLElement(*node); | 966 HTMLElement& element = toHTMLElement(*node); |
| 967 Node* previousSibling = element.previousSibling(); | 967 Node* previousSibling = element.previousSibling(); |
| 968 Node* nextSibling = element.nextSibling(); | 968 Node* nextSibling = element.nextSibling(); |
| 969 ContainerNode* parent = element.parentNode(); | 969 ContainerNode* parent = element.parentNode(); |
| 970 removeInlineStyleFromElement(style, &element, editingState, RemoveAlways
); | 970 removeInlineStyleFromElement(style, &element, editingState, RemoveAlways
); |
| 971 if (editingState->isAborted()) | 971 if (editingState->isAborted()) |
| 972 return; | 972 return; |
| 973 if (!element.inShadowIncludingDocument()) { | 973 if (!element.isConnected()) { |
| 974 // FIXME: We might need to update the start and the end of current s
election here but need a test. | 974 // FIXME: We might need to update the start and the end of current s
election here but need a test. |
| 975 if (runStart == element) | 975 if (runStart == element) |
| 976 runStart = previousSibling ? previousSibling->nextSibling() : pa
rent->firstChild(); | 976 runStart = previousSibling ? previousSibling->nextSibling() : pa
rent->firstChild(); |
| 977 if (runEnd == element) | 977 if (runEnd == element) |
| 978 runEnd = nextSibling ? nextSibling->previousSibling() : parent->
lastChild(); | 978 runEnd = nextSibling ? nextSibling->previousSibling() : parent->
lastChild(); |
| 979 } | 979 } |
| 980 } | 980 } |
| 981 } | 981 } |
| 982 | 982 |
| 983 bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, HTMLEl
ement* element, EditingState* editingState, InlineStyleRemovalMode mode, Editing
Style* extractedStyle) | 983 bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, HTMLEl
ement* element, EditingState* editingState, InlineStyleRemovalMode mode, Editing
Style* extractedStyle) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 995 removeNodePreservingChildren(element, editingState); | 995 removeNodePreservingChildren(element, editingState); |
| 996 if (editingState->isAborted()) | 996 if (editingState->isAborted()) |
| 997 return false; | 997 return false; |
| 998 return true; | 998 return true; |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 bool removed = removeImplicitlyStyledElement(style, element, mode, extracted
Style, editingState); | 1001 bool removed = removeImplicitlyStyledElement(style, element, mode, extracted
Style, editingState); |
| 1002 if (editingState->isAborted()) | 1002 if (editingState->isAborted()) |
| 1003 return false; | 1003 return false; |
| 1004 | 1004 |
| 1005 if (!element->inShadowIncludingDocument()) | 1005 if (!element->isConnected()) |
| 1006 return removed; | 1006 return removed; |
| 1007 | 1007 |
| 1008 // If the node was converted to a span, the span may still contain relevant | 1008 // If the node was converted to a span, the span may still contain relevant |
| 1009 // styles which must be removed (e.g. <b style='font-weight: bold'>) | 1009 // styles which must be removed (e.g. <b style='font-weight: bold'>) |
| 1010 if (removeCSSStyle(style, element, editingState, mode, extractedStyle)) | 1010 if (removeCSSStyle(style, element, editingState, mode, extractedStyle)) |
| 1011 removed = true; | 1011 removed = true; |
| 1012 if (editingState->isAborted()) | 1012 if (editingState->isAborted()) |
| 1013 return false; | 1013 return false; |
| 1014 | 1014 |
| 1015 return removed; | 1015 return removed; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1190 if (child == targetNode || child->contains(targetNode)) | 1190 if (child == targetNode || child->contains(targetNode)) |
| 1191 current = child; | 1191 current = child; |
| 1192 } | 1192 } |
| 1193 } | 1193 } |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s
tart, const Position &end, EditingState* editingState) | 1196 void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s
tart, const Position &end, EditingState* editingState) |
| 1197 { | 1197 { |
| 1198 DCHECK(start.isNotNull()); | 1198 DCHECK(start.isNotNull()); |
| 1199 DCHECK(end.isNotNull()); | 1199 DCHECK(end.isNotNull()); |
| 1200 DCHECK(start.inShadowIncludingDocument()) << start; | 1200 DCHECK(start.isConnected()) << start; |
| 1201 DCHECK(end.inShadowIncludingDocument()) << end; | 1201 DCHECK(end.isConnected()) << end; |
| 1202 DCHECK(Position::commonAncestorTreeScope(start, end)) << start << " " << end
; | 1202 DCHECK(Position::commonAncestorTreeScope(start, end)) << start << " " << end
; |
| 1203 DCHECK_LE(start, end); | 1203 DCHECK_LE(start, end); |
| 1204 // FIXME: We should assert that start/end are not in the middle of a text no
de. | 1204 // FIXME: We should assert that start/end are not in the middle of a text no
de. |
| 1205 | 1205 |
| 1206 Position pushDownStart = mostForwardCaretPosition(start); | 1206 Position pushDownStart = mostForwardCaretPosition(start); |
| 1207 // If the pushDownStart is at the end of a text node, then this node is not
fully selected. | 1207 // If the pushDownStart is at the end of a text node, then this node is not
fully selected. |
| 1208 // Move it to the next deep quivalent position to avoid removing the style f
rom this node. | 1208 // Move it to the next deep quivalent position to avoid removing the style f
rom this node. |
| 1209 // e.g. if pushDownStart was at Position("hello", 5) in <b>hello<div>world</
div></b>, we want Position("world", 0) instead. | 1209 // e.g. if pushDownStart was at Position("hello", 5) in <b>hello<div>world</
div></b>, we want Position("world", 0) instead. |
| 1210 Node* pushDownStartContainer = pushDownStart.computeContainerNode(); | 1210 Node* pushDownStartContainer = pushDownStart.computeContainerNode(); |
| 1211 if (pushDownStartContainer && pushDownStartContainer->isTextNode() | 1211 if (pushDownStartContainer && pushDownStartContainer->isTextNode() |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 EditingStyle* styleToPushDown = nullptr; | 1254 EditingStyle* styleToPushDown = nullptr; |
| 1255 Node* childNode = nullptr; | 1255 Node* childNode = nullptr; |
| 1256 if (isStyledInlineElementToRemove(elem)) { | 1256 if (isStyledInlineElementToRemove(elem)) { |
| 1257 styleToPushDown = EditingStyle::create(); | 1257 styleToPushDown = EditingStyle::create(); |
| 1258 childNode = elem->firstChild(); | 1258 childNode = elem->firstChild(); |
| 1259 } | 1259 } |
| 1260 | 1260 |
| 1261 removeInlineStyleFromElement(style, elem, editingState, RemoveIfNeed
ed, styleToPushDown); | 1261 removeInlineStyleFromElement(style, elem, editingState, RemoveIfNeed
ed, styleToPushDown); |
| 1262 if (editingState->isAborted()) | 1262 if (editingState->isAborted()) |
| 1263 return; | 1263 return; |
| 1264 if (!elem->inShadowIncludingDocument()) { | 1264 if (!elem->isConnected()) { |
| 1265 if (s.anchorNode() == elem) { | 1265 if (s.anchorNode() == elem) { |
| 1266 // Since elem must have been fully selected, and it is at th
e start | 1266 // Since elem must have been fully selected, and it is at th
e start |
| 1267 // of the selection, it is clear we can set the new s offset
to 0. | 1267 // of the selection, it is clear we can set the new s offset
to 0. |
| 1268 DCHECK(s.isBeforeAnchor() || s.isBeforeChildren() || s.offse
tInContainerNode() <= 0) << s; | 1268 DCHECK(s.isBeforeAnchor() || s.isBeforeChildren() || s.offse
tInContainerNode() <= 0) << s; |
| 1269 s = firstPositionInOrBeforeNode(next); | 1269 s = firstPositionInOrBeforeNode(next); |
| 1270 } | 1270 } |
| 1271 if (e.anchorNode() == elem) { | 1271 if (e.anchorNode() == elem) { |
| 1272 // Since elem must have been fully selected, and it is at th
e end | 1272 // Since elem must have been fully selected, and it is at th
e end |
| 1273 // of the selection, it is clear we can set the new e offset
to | 1273 // of the selection, it is clear we can set the new e offset
to |
| 1274 // the max range offset of prev. | 1274 // the max range offset of prev. |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1526 if (const StylePropertySet* decl = block->inlineStyle()) { | 1526 if (const StylePropertySet* decl = block->inlineStyle()) { |
| 1527 if (!cssStyle.isEmpty()) | 1527 if (!cssStyle.isEmpty()) |
| 1528 cssText.append(' '); | 1528 cssText.append(' '); |
| 1529 cssText.append(decl->asText()); | 1529 cssText.append(decl->asText()); |
| 1530 } | 1530 } |
| 1531 setNodeAttribute(block, styleAttr, cssText.toAtomicString()); | 1531 setNodeAttribute(block, styleAttr, cssText.toAtomicString()); |
| 1532 } | 1532 } |
| 1533 | 1533 |
| 1534 void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, Node* passed
Start, Node* passedEnd, EditingState* editingState) | 1534 void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, Node* passed
Start, Node* passedEnd, EditingState* editingState) |
| 1535 { | 1535 { |
| 1536 if (!passedStart || !passedEnd || !passedStart->inShadowIncludingDocument()
|| !passedEnd->inShadowIncludingDocument()) | 1536 if (!passedStart || !passedEnd || !passedStart->isConnected() || !passedEnd-
>isConnected()) |
| 1537 return; | 1537 return; |
| 1538 | 1538 |
| 1539 Node* start = passedStart; | 1539 Node* start = passedStart; |
| 1540 Member<HTMLSpanElement> dummyElement = nullptr; | 1540 Member<HTMLSpanElement> dummyElement = nullptr; |
| 1541 StyleChange styleChange(style, positionToComputeInlineStyleChange(start, dum
myElement, editingState)); | 1541 StyleChange styleChange(style, positionToComputeInlineStyleChange(start, dum
myElement, editingState)); |
| 1542 if (editingState->isAborted()) | 1542 if (editingState->isAborted()) |
| 1543 return; | 1543 return; |
| 1544 | 1544 |
| 1545 if (dummyElement) { | 1545 if (dummyElement) { |
| 1546 removeNode(dummyElement, editingState); | 1546 removeNode(dummyElement, editingState); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1562 return Position::beforeNode(dummyElement); | 1562 return Position::beforeNode(dummyElement); |
| 1563 } | 1563 } |
| 1564 | 1564 |
| 1565 return firstPositionInOrBeforeNode(startNode); | 1565 return firstPositionInOrBeforeNode(startNode); |
| 1566 } | 1566 } |
| 1567 | 1567 |
| 1568 void ApplyStyleCommand::applyInlineStyleChange(Node* passedStart, Node* passedEn
d, StyleChange& styleChange, EAddStyledElement addStyledElement, EditingState* e
ditingState) | 1568 void ApplyStyleCommand::applyInlineStyleChange(Node* passedStart, Node* passedEn
d, StyleChange& styleChange, EAddStyledElement addStyledElement, EditingState* e
ditingState) |
| 1569 { | 1569 { |
| 1570 Node* startNode = passedStart; | 1570 Node* startNode = passedStart; |
| 1571 Node* endNode = passedEnd; | 1571 Node* endNode = passedEnd; |
| 1572 DCHECK(startNode->inShadowIncludingDocument()) << startNode; | 1572 DCHECK(startNode->isConnected()) << startNode; |
| 1573 DCHECK(endNode->inShadowIncludingDocument()) << endNode; | 1573 DCHECK(endNode->isConnected()) << endNode; |
| 1574 | 1574 |
| 1575 // Find appropriate font and span elements top-down. | 1575 // Find appropriate font and span elements top-down. |
| 1576 HTMLFontElement* fontContainer = nullptr; | 1576 HTMLFontElement* fontContainer = nullptr; |
| 1577 HTMLElement* styleContainer = nullptr; | 1577 HTMLElement* styleContainer = nullptr; |
| 1578 for (Node* container = startNode; container && startNode == endNode; contain
er = container->firstChild()) { | 1578 for (Node* container = startNode; container && startNode == endNode; contain
er = container->firstChild()) { |
| 1579 if (isHTMLFontElement(*container)) | 1579 if (isHTMLFontElement(*container)) |
| 1580 fontContainer = toHTMLFontElement(container); | 1580 fontContainer = toHTMLFontElement(container); |
| 1581 bool styleContainerIsNotSpan = !isHTMLSpanElement(styleContainer); | 1581 bool styleContainerIsNotSpan = !isHTMLSpanElement(styleContainer); |
| 1582 if (container->isHTMLElement()) { | 1582 if (container->isHTMLElement()) { |
| 1583 HTMLElement* containerElement = toHTMLElement(container); | 1583 HTMLElement* containerElement = toHTMLElement(container); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1731 DEFINE_TRACE(ApplyStyleCommand) | 1731 DEFINE_TRACE(ApplyStyleCommand) |
| 1732 { | 1732 { |
| 1733 visitor->trace(m_style); | 1733 visitor->trace(m_style); |
| 1734 visitor->trace(m_start); | 1734 visitor->trace(m_start); |
| 1735 visitor->trace(m_end); | 1735 visitor->trace(m_end); |
| 1736 visitor->trace(m_styledInlineElement); | 1736 visitor->trace(m_styledInlineElement); |
| 1737 CompositeEditCommand::trace(visitor); | 1737 CompositeEditCommand::trace(visitor); |
| 1738 } | 1738 } |
| 1739 | 1739 |
| 1740 } // namespace blink | 1740 } // namespace blink |
| OLD | NEW |