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

Side by Side Diff: third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp

Issue 2397963002: Reflow comments in //third_party/WebKit/Source/core/editing/commands (Closed)
Patch Set: . Created 4 years, 2 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) 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2008 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
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (IndentOutdentCommandINCLUDING, BUT NOT L IMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/editing/commands/IndentOutdentCommand.h" 26 #include "core/editing/commands/IndentOutdentCommand.h"
27 27
28 #include "core/HTMLNames.h" 28 #include "core/HTMLNames.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 64
65 bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start, 65 bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start,
66 const Position& end, 66 const Position& end,
67 EditingState* editingState) { 67 EditingState* editingState) {
68 // If our selection is not inside a list, bail out. 68 // If our selection is not inside a list, bail out.
69 Node* lastNodeInSelectedParagraph = start.anchorNode(); 69 Node* lastNodeInSelectedParagraph = start.anchorNode();
70 HTMLElement* listElement = enclosingList(lastNodeInSelectedParagraph); 70 HTMLElement* listElement = enclosingList(lastNodeInSelectedParagraph);
71 if (!listElement) 71 if (!listElement)
72 return false; 72 return false;
73 73
74 // Find the block that we want to indent. If it's not a list item (e.g., a di v inside a list item), we bail out. 74 // Find the block that we want to indent. If it's not a list item (e.g., a
75 // div inside a list item), we bail out.
75 Element* selectedListItem = enclosingBlock(lastNodeInSelectedParagraph); 76 Element* selectedListItem = enclosingBlock(lastNodeInSelectedParagraph);
76 77
77 // FIXME: we need to deal with the case where there is no li (malformed HTML) 78 // FIXME: we need to deal with the case where there is no li (malformed HTML)
78 if (!isHTMLLIElement(selectedListItem)) 79 if (!isHTMLLIElement(selectedListItem))
79 return false; 80 return false;
80 81
81 // FIXME: previousElementSibling does not ignore non-rendered content like <sp an></span>. Should we? 82 // FIXME: previousElementSibling does not ignore non-rendered content like
83 // <span></span>. Should we?
82 Element* previousList = ElementTraversal::previousSibling(*selectedListItem); 84 Element* previousList = ElementTraversal::previousSibling(*selectedListItem);
83 Element* nextList = ElementTraversal::nextSibling(*selectedListItem); 85 Element* nextList = ElementTraversal::nextSibling(*selectedListItem);
84 86
85 // We should calculate visible range in list item because inserting new 87 // We should calculate visible range in list item because inserting new
86 // list element will change visibility of list item, e.g. :first-child 88 // list element will change visibility of list item, e.g. :first-child
87 // CSS selector. 89 // CSS selector.
88 HTMLElement* newList = toHTMLElement( 90 HTMLElement* newList = toHTMLElement(
89 document().createElement(listElement->tagQName(), CreatedByCloneNode)); 91 document().createElement(listElement->tagQName(), CreatedByCloneNode));
90 insertNodeBefore(newList, selectedListItem, editingState); 92 insertNodeBefore(newList, selectedListItem, editingState);
91 if (editingState->isAborted()) 93 if (editingState->isAborted())
92 return false; 94 return false;
93 95
94 document().updateStyleAndLayoutIgnorePendingStylesheets(); 96 document().updateStyleAndLayoutIgnorePendingStylesheets();
95 97
96 // We should clone all the children of the list item for indenting purposes. H owever, in case the current 98 // We should clone all the children of the list item for indenting purposes.
97 // selection does not encompass all its children, we need to explicitally hand le the same. The original 99 // However, in case the current selection does not encompass all its children,
98 // list item too would require proper deletion in that case. 100 // we need to explicitally handle the same. The original list item too would
101 // require proper deletion in that case.
99 if (end.anchorNode() == selectedListItem || 102 if (end.anchorNode() == selectedListItem ||
100 end.anchorNode()->isDescendantOf(selectedListItem->lastChild())) { 103 end.anchorNode()->isDescendantOf(selectedListItem->lastChild())) {
101 moveParagraphWithClones(createVisiblePosition(start), 104 moveParagraphWithClones(createVisiblePosition(start),
102 createVisiblePosition(end), newList, 105 createVisiblePosition(end), newList,
103 selectedListItem, editingState); 106 selectedListItem, editingState);
104 } else { 107 } else {
105 moveParagraphWithClones( 108 moveParagraphWithClones(
106 createVisiblePosition(start), 109 createVisiblePosition(start),
107 VisiblePosition::afterNode(selectedListItem->lastChild()), newList, 110 VisiblePosition::afterNode(selectedListItem->lastChild()), newList,
108 selectedListItem, editingState); 111 selectedListItem, editingState);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 return; 147 return;
145 148
146 Node* outerBlock = 149 Node* outerBlock =
147 (start.computeContainerNode() == elementToSplitTo) 150 (start.computeContainerNode() == elementToSplitTo)
148 ? start.computeContainerNode() 151 ? start.computeContainerNode()
149 : splitTreeToNode(start.computeContainerNode(), elementToSplitTo); 152 : splitTreeToNode(start.computeContainerNode(), elementToSplitTo);
150 153
151 document().updateStyleAndLayoutIgnorePendingStylesheets(); 154 document().updateStyleAndLayoutIgnorePendingStylesheets();
152 VisiblePosition startOfContents = createVisiblePosition(start); 155 VisiblePosition startOfContents = createVisiblePosition(start);
153 if (!targetBlockquote) { 156 if (!targetBlockquote) {
154 // Create a new blockquote and insert it as a child of the root editable ele ment. We accomplish 157 // Create a new blockquote and insert it as a child of the root editable
155 // this by splitting all parents of the current paragraph up to that point. 158 // element. We accomplish this by splitting all parents of the current
159 // paragraph up to that point.
156 targetBlockquote = createBlockElement(); 160 targetBlockquote = createBlockElement();
157 if (outerBlock == start.computeContainerNode()) { 161 if (outerBlock == start.computeContainerNode()) {
158 // When we apply indent to an empty <blockquote>, we should call insertNod eAfter(). 162 // When we apply indent to an empty <blockquote>, we should call
159 // See http://crbug.com/625802 for more details. 163 // insertNodeAfter(). See http://crbug.com/625802 for more details.
160 if (outerBlock->hasTagName(blockquoteTag)) 164 if (outerBlock->hasTagName(blockquoteTag))
161 insertNodeAfter(targetBlockquote, outerBlock, editingState); 165 insertNodeAfter(targetBlockquote, outerBlock, editingState);
162 else 166 else
163 insertNodeAt(targetBlockquote, start, editingState); 167 insertNodeAt(targetBlockquote, start, editingState);
164 } else 168 } else
165 insertNodeBefore(targetBlockquote, outerBlock, editingState); 169 insertNodeBefore(targetBlockquote, outerBlock, editingState);
166 if (editingState->isAborted()) 170 if (editingState->isAborted())
167 return; 171 return;
168 document().updateStyleAndLayoutIgnorePendingStylesheets(); 172 document().updateStyleAndLayoutIgnorePendingStylesheets();
169 startOfContents = VisiblePosition::inParentAfterNode(*targetBlockquote); 173 startOfContents = VisiblePosition::inParentAfterNode(*targetBlockquote);
170 } 174 }
171 175
172 VisiblePosition endOfContents = createVisiblePosition(end); 176 VisiblePosition endOfContents = createVisiblePosition(end);
173 if (startOfContents.isNull() || endOfContents.isNull()) 177 if (startOfContents.isNull() || endOfContents.isNull())
174 return; 178 return;
175 moveParagraphWithClones(startOfContents, endOfContents, targetBlockquote, 179 moveParagraphWithClones(startOfContents, endOfContents, targetBlockquote,
176 outerBlock, editingState); 180 outerBlock, editingState);
177 } 181 }
178 182
179 void IndentOutdentCommand::outdentParagraph(EditingState* editingState) { 183 void IndentOutdentCommand::outdentParagraph(EditingState* editingState) {
180 VisiblePosition visibleStartOfParagraph = 184 VisiblePosition visibleStartOfParagraph =
181 startOfParagraph(endingSelection().visibleStart()); 185 startOfParagraph(endingSelection().visibleStart());
182 VisiblePosition visibleEndOfParagraph = 186 VisiblePosition visibleEndOfParagraph =
183 endOfParagraph(visibleStartOfParagraph); 187 endOfParagraph(visibleStartOfParagraph);
184 188
185 HTMLElement* enclosingElement = toHTMLElement( 189 HTMLElement* enclosingElement = toHTMLElement(
186 enclosingNodeOfType(visibleStartOfParagraph.deepEquivalent(), 190 enclosingNodeOfType(visibleStartOfParagraph.deepEquivalent(),
187 &isHTMLListOrBlockquoteElement)); 191 &isHTMLListOrBlockquoteElement));
188 if (!enclosingElement || 192 // We can't outdent if there is no place to go!
189 !hasEditableStyle( 193 if (!enclosingElement || !hasEditableStyle(*enclosingElement->parentNode()))
190 *enclosingElement
191 ->parentNode())) // We can't outdent if there is no place to go!
192 return; 194 return;
193 195
194 // Use InsertListCommand to remove the selection from the list 196 // Use InsertListCommand to remove the selection from the list
195 if (isHTMLOListElement(*enclosingElement)) { 197 if (isHTMLOListElement(*enclosingElement)) {
196 applyCommandToComposite( 198 applyCommandToComposite(
197 InsertListCommand::create(document(), InsertListCommand::OrderedList), 199 InsertListCommand::create(document(), InsertListCommand::OrderedList),
198 editingState); 200 editingState);
199 return; 201 return;
200 } 202 }
201 if (isHTMLUListElement(*enclosingElement)) { 203 if (isHTMLUListElement(*enclosingElement)) {
202 applyCommandToComposite( 204 applyCommandToComposite(
203 InsertListCommand::create(document(), InsertListCommand::UnorderedList), 205 InsertListCommand::create(document(), InsertListCommand::UnorderedList),
204 editingState); 206 editingState);
205 return; 207 return;
206 } 208 }
207 209
208 // The selection is inside a blockquote i.e. enclosingNode is a blockquote 210 // The selection is inside a blockquote i.e. enclosingNode is a blockquote
209 VisiblePosition positionInEnclosingBlock = 211 VisiblePosition positionInEnclosingBlock =
210 VisiblePosition::firstPositionInNode(enclosingElement); 212 VisiblePosition::firstPositionInNode(enclosingElement);
211 // If the blockquote is inline, the start of the enclosing block coincides wit h 213 // If the blockquote is inline, the start of the enclosing block coincides
212 // positionInEnclosingBlock. 214 // with positionInEnclosingBlock.
213 VisiblePosition startOfEnclosingBlock = 215 VisiblePosition startOfEnclosingBlock =
214 (enclosingElement->layoutObject() && 216 (enclosingElement->layoutObject() &&
215 enclosingElement->layoutObject()->isInline()) 217 enclosingElement->layoutObject()->isInline())
216 ? positionInEnclosingBlock 218 ? positionInEnclosingBlock
217 : startOfBlock(positionInEnclosingBlock); 219 : startOfBlock(positionInEnclosingBlock);
218 VisiblePosition lastPositionInEnclosingBlock = 220 VisiblePosition lastPositionInEnclosingBlock =
219 VisiblePosition::lastPositionInNode(enclosingElement); 221 VisiblePosition::lastPositionInNode(enclosingElement);
220 VisiblePosition endOfEnclosingBlock = 222 VisiblePosition endOfEnclosingBlock =
221 endOfBlock(lastPositionInEnclosingBlock); 223 endOfBlock(lastPositionInEnclosingBlock);
222 if (visibleStartOfParagraph.deepEquivalent() == 224 if (visibleStartOfParagraph.deepEquivalent() ==
223 startOfEnclosingBlock.deepEquivalent() && 225 startOfEnclosingBlock.deepEquivalent() &&
224 visibleEndOfParagraph.deepEquivalent() == 226 visibleEndOfParagraph.deepEquivalent() ==
225 endOfEnclosingBlock.deepEquivalent()) { 227 endOfEnclosingBlock.deepEquivalent()) {
226 // The blockquote doesn't contain anything outside the paragraph, so it can be totally removed. 228 // The blockquote doesn't contain anything outside the paragraph, so it can
229 // be totally removed.
227 Node* splitPoint = enclosingElement->nextSibling(); 230 Node* splitPoint = enclosingElement->nextSibling();
228 removeNodePreservingChildren(enclosingElement, editingState); 231 removeNodePreservingChildren(enclosingElement, editingState);
229 if (editingState->isAborted()) 232 if (editingState->isAborted())
230 return; 233 return;
231 // outdentRegion() assumes it is operating on the first paragraph of an encl osing blockquote, but if there are multiply nested blockquotes and we've 234 // outdentRegion() assumes it is operating on the first paragraph of an
232 // just removed one, then this assumption isn't true. By splitting the next containing blockquote after this node, we keep this assumption true 235 // enclosing blockquote, but if there are multiply nested blockquotes and
236 // we've just removed one, then this assumption isn't true. By splitting the
237 // next containing blockquote after this node, we keep this assumption true
233 if (splitPoint) { 238 if (splitPoint) {
234 if (Element* splitPointParent = splitPoint->parentElement()) { 239 if (Element* splitPointParent = splitPoint->parentElement()) {
240 // We can't outdent if there is no place to go!
235 if (splitPointParent->hasTagName(blockquoteTag) && 241 if (splitPointParent->hasTagName(blockquoteTag) &&
236 !splitPoint->hasTagName(blockquoteTag) && 242 !splitPoint->hasTagName(blockquoteTag) &&
237 hasEditableStyle( 243 hasEditableStyle(*splitPointParent->parentNode()))
238 *splitPointParent
239 ->parentNode())) // We can't outdent if there is no place to go!
240 splitElement(splitPointParent, splitPoint); 244 splitElement(splitPointParent, splitPoint);
241 } 245 }
242 } 246 }
243 247
244 document().updateStyleAndLayoutIgnorePendingStylesheets(); 248 document().updateStyleAndLayoutIgnorePendingStylesheets();
245 visibleStartOfParagraph = 249 visibleStartOfParagraph =
246 createVisiblePosition(visibleStartOfParagraph.deepEquivalent()); 250 createVisiblePosition(visibleStartOfParagraph.deepEquivalent());
247 if (visibleStartOfParagraph.isNotNull() && 251 if (visibleStartOfParagraph.isNotNull() &&
248 !isStartOfParagraph(visibleStartOfParagraph)) { 252 !isStartOfParagraph(visibleStartOfParagraph)) {
249 insertNodeAt(HTMLBRElement::create(document()), 253 insertNodeAt(HTMLBRElement::create(document()),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 insertNodeBefore(placeholder, splitBlockquoteNode, editingState); 304 insertNodeBefore(placeholder, splitBlockquoteNode, editingState);
301 if (editingState->isAborted()) 305 if (editingState->isAborted())
302 return; 306 return;
303 307
304 document().updateStyleAndLayoutIgnorePendingStylesheets(); 308 document().updateStyleAndLayoutIgnorePendingStylesheets();
305 moveParagraph(startOfParagraphToMove, endOfParagraphToMove, 309 moveParagraph(startOfParagraphToMove, endOfParagraphToMove,
306 VisiblePosition::beforeNode(placeholder), editingState, 310 VisiblePosition::beforeNode(placeholder), editingState,
307 PreserveSelection); 311 PreserveSelection);
308 } 312 }
309 313
310 // FIXME: We should merge this function with ApplyBlockElementCommand::formatSel ection 314 // FIXME: We should merge this function with
315 // ApplyBlockElementCommand::formatSelection
311 void IndentOutdentCommand::outdentRegion( 316 void IndentOutdentCommand::outdentRegion(
312 const VisiblePosition& startOfSelection, 317 const VisiblePosition& startOfSelection,
313 const VisiblePosition& endOfSelection, 318 const VisiblePosition& endOfSelection,
314 EditingState* editingState) { 319 EditingState* editingState) {
315 VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection); 320 VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection);
316 VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection); 321 VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection);
317 322
318 if (endOfCurrentParagraph.deepEquivalent() == 323 if (endOfCurrentParagraph.deepEquivalent() ==
319 endOfLastParagraph.deepEquivalent()) { 324 endOfLastParagraph.deepEquivalent()) {
320 outdentParagraph(editingState); 325 outdentParagraph(editingState);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 else 388 else
384 indentIntoBlockquote(start, end, blockquoteForNextIndent, editingState); 389 indentIntoBlockquote(start, end, blockquoteForNextIndent, editingState);
385 } 390 }
386 391
387 InputEvent::InputType IndentOutdentCommand::inputType() const { 392 InputEvent::InputType IndentOutdentCommand::inputType() const {
388 return m_typeOfAction == Indent ? InputEvent::InputType::Indent 393 return m_typeOfAction == Indent ? InputEvent::InputType::Indent
389 : InputEvent::InputType::Outdent; 394 : InputEvent::InputType::Outdent;
390 } 395 }
391 396
392 } // namespace blink 397 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698