Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: Source/core/editing/commands/ApplyStyleCommand.cpp

Issue 1302353002: Get rid of redundant member function PositionAlgorithm<Strategy>::{upstream,downstream} (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-08-22T04:51:20 Rebase Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 PassRefPtrWillBeRawPtr<HTMLSpanElement> createStyleSpanElement(Document& documen t) 121 PassRefPtrWillBeRawPtr<HTMLSpanElement> createStyleSpanElement(Document& documen t)
122 { 122 {
123 return toHTMLSpanElement(createHTMLElement(document, spanTag).get()); 123 return toHTMLSpanElement(createHTMLElement(document, spanTag).get());
124 } 124 }
125 125
126 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, EditAction editingAction, EPropertyLevel propertyLevel) 126 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, EditAction editingAction, EPropertyLevel propertyLevel)
127 : CompositeEditCommand(document) 127 : CompositeEditCommand(document)
128 , m_style(style->copy()) 128 , m_style(style->copy())
129 , m_editingAction(editingAction) 129 , m_editingAction(editingAction)
130 , m_propertyLevel(propertyLevel) 130 , m_propertyLevel(propertyLevel)
131 , m_start(endingSelection().start().downstream()) 131 , m_start(mostForwardCaretPosition(endingSelection().start()))
132 , m_end(endingSelection().end().upstream()) 132 , m_end(mostBackwardCaretPosition(endingSelection().end()))
133 , m_useEndingSelection(true) 133 , m_useEndingSelection(true)
134 , m_styledInlineElement(nullptr) 134 , m_styledInlineElement(nullptr)
135 , m_removeOnly(false) 135 , m_removeOnly(false)
136 , m_isInlineElementToRemoveFunction(0) 136 , m_isInlineElementToRemoveFunction(0)
137 { 137 {
138 } 138 }
139 139
140 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, const Position& start, const Position& end, EditAction editingAction, EPrope rtyLevel propertyLevel) 140 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, const Position& start, const Position& end, EditAction editingAction, EPrope rtyLevel propertyLevel)
141 : CompositeEditCommand(document) 141 : CompositeEditCommand(document)
142 , m_style(style->copy()) 142 , m_style(style->copy())
143 , m_editingAction(editingAction) 143 , m_editingAction(editingAction)
144 , m_propertyLevel(propertyLevel) 144 , m_propertyLevel(propertyLevel)
145 , m_start(start) 145 , m_start(start)
146 , m_end(end) 146 , m_end(end)
147 , m_useEndingSelection(false) 147 , m_useEndingSelection(false)
148 , m_styledInlineElement(nullptr) 148 , m_styledInlineElement(nullptr)
149 , m_removeOnly(false) 149 , m_removeOnly(false)
150 , m_isInlineElementToRemoveFunction(0) 150 , m_isInlineElementToRemoveFunction(0)
151 { 151 {
152 } 152 }
153 153
154 ApplyStyleCommand::ApplyStyleCommand(PassRefPtrWillBeRawPtr<Element> element, bo ol removeOnly, EditAction editingAction) 154 ApplyStyleCommand::ApplyStyleCommand(PassRefPtrWillBeRawPtr<Element> element, bo ol removeOnly, EditAction editingAction)
155 : CompositeEditCommand(element->document()) 155 : CompositeEditCommand(element->document())
156 , m_style(EditingStyle::create()) 156 , m_style(EditingStyle::create())
157 , m_editingAction(editingAction) 157 , m_editingAction(editingAction)
158 , m_propertyLevel(PropertyDefault) 158 , m_propertyLevel(PropertyDefault)
159 , m_start(endingSelection().start().downstream()) 159 , m_start(mostForwardCaretPosition(endingSelection().start()))
160 , m_end(endingSelection().end().upstream()) 160 , m_end(mostBackwardCaretPosition(endingSelection().end()))
161 , m_useEndingSelection(true) 161 , m_useEndingSelection(true)
162 , m_styledInlineElement(element) 162 , m_styledInlineElement(element)
163 , m_removeOnly(removeOnly) 163 , m_removeOnly(removeOnly)
164 , m_isInlineElementToRemoveFunction(0) 164 , m_isInlineElementToRemoveFunction(0)
165 { 165 {
166 } 166 }
167 167
168 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, IsInlineElementToRemoveFunction isInlineElementToRemoveFunction, EditAction editingAction) 168 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, IsInlineElementToRemoveFunction isInlineElementToRemoveFunction, EditAction editingAction)
169 : CompositeEditCommand(document) 169 : CompositeEditCommand(document)
170 , m_style(style->copy()) 170 , m_style(style->copy())
171 , m_editingAction(editingAction) 171 , m_editingAction(editingAction)
172 , m_propertyLevel(PropertyDefault) 172 , m_propertyLevel(PropertyDefault)
173 , m_start(endingSelection().start().downstream()) 173 , m_start(mostForwardCaretPosition(endingSelection().start()))
174 , m_end(endingSelection().end().upstream()) 174 , m_end(mostBackwardCaretPosition(endingSelection().end()))
175 , m_useEndingSelection(true) 175 , m_useEndingSelection(true)
176 , m_styledInlineElement(nullptr) 176 , m_styledInlineElement(nullptr)
177 , m_removeOnly(true) 177 , m_removeOnly(true)
178 , m_isInlineElementToRemoveFunction(isInlineElementToRemoveFunction) 178 , m_isInlineElementToRemoveFunction(isInlineElementToRemoveFunction)
179 { 179 {
180 } 180 }
181 181
182 void ApplyStyleCommand::updateStartEnd(const Position& newStart, const Position& newEnd) 182 void ApplyStyleCommand::updateStartEnd(const Position& newStart, const Position& newEnd)
183 { 183 {
184 ASSERT(comparePositions(newEnd, newStart) >= 0); 184 ASSERT(comparePositions(newEnd, newStart) >= 0);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 // If the end node is before the start node (can only happen if the end node is 359 // If the end node is before the start node (can only happen if the end node is
360 // an ancestor of the start node), we gather nodes up to the next sibling of the end node 360 // an ancestor of the start node), we gather nodes up to the next sibling of the end node
361 Node* beyondEnd; 361 Node* beyondEnd;
362 ASSERT(start.anchorNode()); 362 ASSERT(start.anchorNode());
363 ASSERT(end.anchorNode()); 363 ASSERT(end.anchorNode());
364 if (start.anchorNode()->isDescendantOf(end.anchorNode())) 364 if (start.anchorNode()->isDescendantOf(end.anchorNode()))
365 beyondEnd = NodeTraversal::nextSkippingChildren(*end.anchorNode()); 365 beyondEnd = NodeTraversal::nextSkippingChildren(*end.anchorNode());
366 else 366 else
367 beyondEnd = NodeTraversal::next(*end.anchorNode()); 367 beyondEnd = NodeTraversal::next(*end.anchorNode());
368 368
369 start = start.upstream(); // Move upstream to ensure we do not add redundant spans. 369 start = mostBackwardCaretPosition(start); // Move upstream to ensure we do n ot add redundant spans.
370 Node* startNode = start.anchorNode(); 370 Node* startNode = start.anchorNode();
371 ASSERT(startNode); 371 ASSERT(startNode);
372 372
373 // Make sure we're not already at the end or the next NodeTraversal::next() will traverse 373 // Make sure we're not already at the end or the next NodeTraversal::next() will traverse
374 // past it. 374 // past it.
375 if (startNode == beyondEnd) 375 if (startNode == beyondEnd)
376 return; 376 return;
377 377
378 if (startNode->isTextNode() && start.computeOffsetInContainerNode() >= caret MaxOffset(startNode)) { 378 if (startNode->isTextNode() && start.computeOffsetInContainerNode() >= caret MaxOffset(startNode)) {
379 // Move out of text node if range does not include its characters. 379 // Move out of text node if range does not include its characters.
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 if (start.isNull() || end.isNull()) 606 if (start.isNull() || end.isNull())
607 return; 607 return;
608 endDummySpanAncestor = dummySpanAncestorForNode(end.anchorNode()); 608 endDummySpanAncestor = dummySpanAncestorForNode(end.anchorNode());
609 } 609 }
610 610
611 // Remove style from the selection. 611 // Remove style from the selection.
612 // Use the upstream position of the start for removing style. 612 // Use the upstream position of the start for removing style.
613 // This will ensure we remove all traces of the relevant styles from the sel ection 613 // This will ensure we remove all traces of the relevant styles from the sel ection
614 // and prevent us from adding redundant ones, as described in: 614 // and prevent us from adding redundant ones, as described in:
615 // <rdar://problem/3724344> Bolding and unbolding creates extraneous tags 615 // <rdar://problem/3724344> Bolding and unbolding creates extraneous tags
616 Position removeStart = start.upstream(); 616 Position removeStart = mostBackwardCaretPosition(start);
617 WritingDirection textDirection = NaturalWritingDirection; 617 WritingDirection textDirection = NaturalWritingDirection;
618 bool hasTextDirection = style->textDirection(textDirection); 618 bool hasTextDirection = style->textDirection(textDirection);
619 RefPtrWillBeRawPtr<EditingStyle> styleWithoutEmbedding = nullptr; 619 RefPtrWillBeRawPtr<EditingStyle> styleWithoutEmbedding = nullptr;
620 RefPtrWillBeRawPtr<EditingStyle> embeddingStyle = nullptr; 620 RefPtrWillBeRawPtr<EditingStyle> embeddingStyle = nullptr;
621 if (hasTextDirection) { 621 if (hasTextDirection) {
622 // Leave alone an ancestor that provides the desired single level embedd ing, if there is one. 622 // Leave alone an ancestor that provides the desired single level embedd ing, if there is one.
623 HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start. anchorNode(), true, textDirection); 623 HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start. anchorNode(), true, textDirection);
624 HTMLElement* endUnsplitAncestor = splitAncestorsWithUnicodeBidi(end.anch orNode(), false, textDirection); 624 HTMLElement* endUnsplitAncestor = splitAncestorsWithUnicodeBidi(end.anch orNode(), false, textDirection);
625 removeEmbeddingUpToEnclosingBlock(start.anchorNode(), startUnsplitAncest or); 625 removeEmbeddingUpToEnclosingBlock(start.anchorNode(), startUnsplitAncest or);
626 removeEmbeddingUpToEnclosingBlock(end.anchorNode(), endUnsplitAncestor); 626 removeEmbeddingUpToEnclosingBlock(end.anchorNode(), endUnsplitAncestor);
627 627
628 // Avoid removing the dir attribute and the unicode-bidi and direction p roperties from the unsplit ancestors. 628 // Avoid removing the dir attribute and the unicode-bidi and direction p roperties from the unsplit ancestors.
629 Position embeddingRemoveStart = removeStart; 629 Position embeddingRemoveStart = removeStart;
630 if (startUnsplitAncestor && elementFullySelected(*startUnsplitAncestor, removeStart, end)) 630 if (startUnsplitAncestor && elementFullySelected(*startUnsplitAncestor, removeStart, end))
631 embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncest or); 631 embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncest or);
632 632
633 Position embeddingRemoveEnd = end; 633 Position embeddingRemoveEnd = end;
634 if (endUnsplitAncestor && elementFullySelected(*endUnsplitAncestor, remo veStart, end)) 634 if (endUnsplitAncestor && elementFullySelected(*endUnsplitAncestor, remo veStart, end))
635 embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor) .downstream(); 635 embeddingRemoveEnd = mostForwardCaretPosition(positionInParentBefore Node(*endUnsplitAncestor));
636 636
637 if (embeddingRemoveEnd != removeStart || embeddingRemoveEnd != end) { 637 if (embeddingRemoveEnd != removeStart || embeddingRemoveEnd != end) {
638 styleWithoutEmbedding = style->copy(); 638 styleWithoutEmbedding = style->copy();
639 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDirectio n(); 639 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDirectio n();
640 640
641 if (comparePositions(embeddingRemoveStart, embeddingRemoveEnd) <= 0) 641 if (comparePositions(embeddingRemoveStart, embeddingRemoveEnd) <= 0)
642 removeInlineStyle(embeddingStyle.get(), embeddingRemoveStart, em beddingRemoveEnd); 642 removeInlineStyle(embeddingStyle.get(), embeddingRemoveStart, em beddingRemoveEnd);
643 } 643 }
644 } 644 }
645 645
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s tart, const Position &end) 1114 void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s tart, const Position &end)
1115 { 1115 {
1116 ASSERT(start.isNotNull()); 1116 ASSERT(start.isNotNull());
1117 ASSERT(end.isNotNull()); 1117 ASSERT(end.isNotNull());
1118 ASSERT(start.inDocument()); 1118 ASSERT(start.inDocument());
1119 ASSERT(end.inDocument()); 1119 ASSERT(end.inDocument());
1120 ASSERT(Position::commonAncestorTreeScope(start, end)); 1120 ASSERT(Position::commonAncestorTreeScope(start, end));
1121 ASSERT(comparePositions(start, end) <= 0); 1121 ASSERT(comparePositions(start, end) <= 0);
1122 // FIXME: We should assert that start/end are not in the middle of a text no de. 1122 // FIXME: We should assert that start/end are not in the middle of a text no de.
1123 1123
1124 Position pushDownStart = start.downstream(); 1124 Position pushDownStart = mostForwardCaretPosition(start);
1125 // If the pushDownStart is at the end of a text node, then this node is not fully selected. 1125 // If the pushDownStart is at the end of a text node, then this node is not fully selected.
1126 // Move it to the next deep quivalent position to avoid removing the style f rom this node. 1126 // Move it to the next deep quivalent position to avoid removing the style f rom this node.
1127 // e.g. if pushDownStart was at Position("hello", 5) in <b>hello<div>world</ div></b>, we want Position("world", 0) instead. 1127 // e.g. if pushDownStart was at Position("hello", 5) in <b>hello<div>world</ div></b>, we want Position("world", 0) instead.
1128 Node* pushDownStartContainer = pushDownStart.computeContainerNode(); 1128 Node* pushDownStartContainer = pushDownStart.computeContainerNode();
1129 if (pushDownStartContainer && pushDownStartContainer->isTextNode() 1129 if (pushDownStartContainer && pushDownStartContainer->isTextNode()
1130 && pushDownStart.computeOffsetInContainerNode() == pushDownStartContaine r->maxCharacterOffset()) 1130 && pushDownStart.computeOffsetInContainerNode() == pushDownStartContaine r->maxCharacterOffset())
1131 pushDownStart = nextVisuallyDistinctCandidate(pushDownStart); 1131 pushDownStart = nextVisuallyDistinctCandidate(pushDownStart);
1132 Position pushDownEnd = end.upstream(); 1132 Position pushDownEnd = mostBackwardCaretPosition(end);
1133 // If pushDownEnd is at the start of a text node, then this node is not full y selected. 1133 // If pushDownEnd is at the start of a text node, then this node is not full y selected.
1134 // Move it to the previous deep equivalent position to avoid removing the st yle from this node. 1134 // Move it to the previous deep equivalent position to avoid removing the st yle from this node.
1135 Node* pushDownEndContainer = pushDownEnd.computeContainerNode(); 1135 Node* pushDownEndContainer = pushDownEnd.computeContainerNode();
1136 if (pushDownEndContainer && pushDownEndContainer->isTextNode() && !pushDownE nd.computeOffsetInContainerNode()) 1136 if (pushDownEndContainer && pushDownEndContainer->isTextNode() && !pushDownE nd.computeOffsetInContainerNode())
1137 pushDownEnd = previousVisuallyDistinctCandidate(pushDownEnd); 1137 pushDownEnd = previousVisuallyDistinctCandidate(pushDownEnd);
1138 1138
1139 pushDownInlineStyleAroundNode(style, pushDownStart.anchorNode()); 1139 pushDownInlineStyleAroundNode(style, pushDownStart.anchorNode());
1140 pushDownInlineStyleAroundNode(style, pushDownEnd.anchorNode()); 1140 pushDownInlineStyleAroundNode(style, pushDownEnd.anchorNode());
1141 1141
1142 // The s and e variables store the positions used to set the ending selectio n after style removal 1142 // The s and e variables store the positions used to set the ending selectio n after style removal
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 1201
1202 updateStartEnd(s, e); 1202 updateStartEnd(s, e);
1203 } 1203 }
1204 1204
1205 bool ApplyStyleCommand::elementFullySelected(HTMLElement& element, const Positio n& start, const Position& end) const 1205 bool ApplyStyleCommand::elementFullySelected(HTMLElement& element, const Positio n& start, const Position& end) const
1206 { 1206 {
1207 // The tree may have changed and Position::upstream() relies on an up-to-dat e layout. 1207 // The tree may have changed and Position::upstream() relies on an up-to-dat e layout.
1208 element.document().updateLayoutIgnorePendingStylesheets(); 1208 element.document().updateLayoutIgnorePendingStylesheets();
1209 1209
1210 return comparePositions(firstPositionInOrBeforeNode(&element), start) >= 0 1210 return comparePositions(firstPositionInOrBeforeNode(&element), start) >= 0
1211 && comparePositions(lastPositionInOrAfterNode(&element).upstream(), end) <= 0; 1211 && comparePositions(mostBackwardCaretPosition(lastPositionInOrAfterNode( &element)), end) <= 0;
1212 } 1212 }
1213 1213
1214 void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end) 1214 void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end)
1215 { 1215 {
1216 ASSERT(start.computeContainerNode()->isTextNode()); 1216 ASSERT(start.computeContainerNode()->isTextNode());
1217 1217
1218 Position newEnd; 1218 Position newEnd;
1219 if (end.isOffsetInAnchor() && start.computeContainerNode() == end.computeCon tainerNode()) 1219 if (end.isOffsetInAnchor() && start.computeContainerNode() == end.computeCon tainerNode())
1220 newEnd = Position(end.computeContainerNode(), end.offsetInContainerNode( ) - start.offsetInContainerNode()); 1220 newEnd = Position(end.computeContainerNode(), end.offsetInContainerNode( ) - start.offsetInContainerNode());
1221 else 1221 else
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 DEFINE_TRACE(ApplyStyleCommand) 1594 DEFINE_TRACE(ApplyStyleCommand)
1595 { 1595 {
1596 visitor->trace(m_style); 1596 visitor->trace(m_style);
1597 visitor->trace(m_start); 1597 visitor->trace(m_start);
1598 visitor->trace(m_end); 1598 visitor->trace(m_end);
1599 visitor->trace(m_styledInlineElement); 1599 visitor->trace(m_styledInlineElement);
1600 CompositeEditCommand::trace(visitor); 1600 CompositeEditCommand::trace(visitor);
1601 } 1601 }
1602 1602
1603 } 1603 }
OLDNEW
« no previous file with comments | « Source/core/editing/commands/ApplyBlockElementCommand.cpp ('k') | Source/core/editing/commands/BreakBlockquoteCommand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698