| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2010 Google Inc. All rights reserved. | 3 * Copyright (C) 2010 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 if (newSelection.isNone()) | 78 if (newSelection.isNone()) |
| 79 return; | 79 return; |
| 80 setEndingSelection(newSelection); | 80 setEndingSelection(newSelection); |
| 81 } | 81 } |
| 82 | 82 |
| 83 VisibleSelection selection = selectionForParagraphIteration(endingSelection(
)); | 83 VisibleSelection selection = selectionForParagraphIteration(endingSelection(
)); |
| 84 VisiblePosition startOfSelection = selection.visibleStart(); | 84 VisiblePosition startOfSelection = selection.visibleStart(); |
| 85 VisiblePosition endOfSelection = selection.visibleEnd(); | 85 VisiblePosition endOfSelection = selection.visibleEnd(); |
| 86 ASSERT(!startOfSelection.isNull()); | 86 ASSERT(!startOfSelection.isNull()); |
| 87 ASSERT(!endOfSelection.isNull()); | 87 ASSERT(!endOfSelection.isNull()); |
| 88 RefPtrWillBeRawPtr<ContainerNode> startScope = nullptr; | 88 RawPtr<ContainerNode> startScope = nullptr; |
| 89 int startIndex = indexForVisiblePosition(startOfSelection, startScope); | 89 int startIndex = indexForVisiblePosition(startOfSelection, startScope); |
| 90 RefPtrWillBeRawPtr<ContainerNode> endScope = nullptr; | 90 RawPtr<ContainerNode> endScope = nullptr; |
| 91 int endIndex = indexForVisiblePosition(endOfSelection, endScope); | 91 int endIndex = indexForVisiblePosition(endOfSelection, endScope); |
| 92 | 92 |
| 93 formatSelection(startOfSelection, endOfSelection, editingState); | 93 formatSelection(startOfSelection, endOfSelection, editingState); |
| 94 if (editingState->isAborted()) | 94 if (editingState->isAborted()) |
| 95 return; | 95 return; |
| 96 | 96 |
| 97 document().updateLayoutIgnorePendingStylesheets(); | 97 document().updateLayoutIgnorePendingStylesheets(); |
| 98 | 98 |
| 99 ASSERT(startScope == endScope); | 99 ASSERT(startScope == endScope); |
| 100 ASSERT(startIndex >= 0); | 100 ASSERT(startIndex >= 0); |
| 101 ASSERT(startIndex <= endIndex); | 101 ASSERT(startIndex <= endIndex); |
| 102 if (startScope == endScope && startIndex >= 0 && startIndex <= endIndex) { | 102 if (startScope == endScope && startIndex >= 0 && startIndex <= endIndex) { |
| 103 VisiblePosition start(visiblePositionForIndex(startIndex, startScope.get
())); | 103 VisiblePosition start(visiblePositionForIndex(startIndex, startScope.get
())); |
| 104 VisiblePosition end(visiblePositionForIndex(endIndex, endScope.get())); | 104 VisiblePosition end(visiblePositionForIndex(endIndex, endScope.get())); |
| 105 if (start.isNotNull() && end.isNotNull()) | 105 if (start.isNotNull() && end.isNotNull()) |
| 106 setEndingSelection(VisibleSelection(start, end, endingSelection().is
Directional())); | 106 setEndingSelection(VisibleSelection(start, end, endingSelection().is
Directional())); |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 | 109 |
| 110 void ApplyBlockElementCommand::formatSelection(const VisiblePosition& startOfSel
ection, const VisiblePosition& endOfSelection, EditingState* editingState) | 110 void ApplyBlockElementCommand::formatSelection(const VisiblePosition& startOfSel
ection, const VisiblePosition& endOfSelection, EditingState* editingState) |
| 111 { | 111 { |
| 112 // Special case empty unsplittable elements because there's nothing to split | 112 // Special case empty unsplittable elements because there's nothing to split |
| 113 // and there's nothing to move. | 113 // and there's nothing to move. |
| 114 Position start = mostForwardCaretPosition(startOfSelection.deepEquivalent())
; | 114 Position start = mostForwardCaretPosition(startOfSelection.deepEquivalent())
; |
| 115 if (isAtUnsplittableElement(start)) { | 115 if (isAtUnsplittableElement(start)) { |
| 116 RefPtrWillBeRawPtr<HTMLElement> blockquote = createBlockElement(); | 116 RawPtr<HTMLElement> blockquote = createBlockElement(); |
| 117 insertNodeAt(blockquote, start, editingState); | 117 insertNodeAt(blockquote, start, editingState); |
| 118 if (editingState->isAborted()) | 118 if (editingState->isAborted()) |
| 119 return; | 119 return; |
| 120 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(do
cument()); | 120 RawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(document()); |
| 121 appendNode(placeholder, blockquote, editingState); | 121 appendNode(placeholder, blockquote, editingState); |
| 122 if (editingState->isAborted()) | 122 if (editingState->isAborted()) |
| 123 return; | 123 return; |
| 124 setEndingSelection(VisibleSelection(positionBeforeNode(placeholder.get()
), TextAffinity::Downstream, endingSelection().isDirectional())); | 124 setEndingSelection(VisibleSelection(positionBeforeNode(placeholder.get()
), TextAffinity::Downstream, endingSelection().isDirectional())); |
| 125 return; | 125 return; |
| 126 } | 126 } |
| 127 | 127 |
| 128 RefPtrWillBeRawPtr<HTMLElement> blockquoteForNextIndent = nullptr; | 128 RawPtr<HTMLElement> blockquoteForNextIndent = nullptr; |
| 129 VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection); | 129 VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection); |
| 130 VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection); | 130 VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection); |
| 131 VisiblePosition endAfterSelection = endOfParagraph(nextPositionOf(endOfLastP
aragraph)); | 131 VisiblePosition endAfterSelection = endOfParagraph(nextPositionOf(endOfLastP
aragraph)); |
| 132 m_endOfLastParagraph = endOfLastParagraph.deepEquivalent(); | 132 m_endOfLastParagraph = endOfLastParagraph.deepEquivalent(); |
| 133 | 133 |
| 134 bool atEnd = false; | 134 bool atEnd = false; |
| 135 Position end; | 135 Position end; |
| 136 while (endOfCurrentParagraph.deepEquivalent() != endAfterSelection.deepEquiv
alent() && !atEnd) { | 136 while (endOfCurrentParagraph.deepEquivalent() != endAfterSelection.deepEquiv
alent() && !atEnd) { |
| 137 if (endOfCurrentParagraph.deepEquivalent() == m_endOfLastParagraph) | 137 if (endOfCurrentParagraph.deepEquivalent() == m_endOfLastParagraph) |
| 138 atEnd = true; | 138 atEnd = true; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 // TODO(yosin) We should use |PositionMoveType::Character| for | 232 // TODO(yosin) We should use |PositionMoveType::Character| for |
| 233 // |previousPositionOf()|. | 233 // |previousPositionOf()|. |
| 234 if (!isNewLineAtPosition(previousPositionOf(end, PositionMoveType::C
odePoint)) && isNewLineAtPosition(end)) | 234 if (!isNewLineAtPosition(previousPositionOf(end, PositionMoveType::C
odePoint)) && isNewLineAtPosition(end)) |
| 235 end = Position(end.computeContainerNode(), endOffset + 1); | 235 end = Position(end.computeContainerNode(), endOffset + 1); |
| 236 if (isEndAndEndOfLastParagraphOnSameNode && end.offsetInContainerNod
e() >= m_endOfLastParagraph.offsetInContainerNode()) | 236 if (isEndAndEndOfLastParagraphOnSameNode && end.offsetInContainerNod
e() >= m_endOfLastParagraph.offsetInContainerNode()) |
| 237 m_endOfLastParagraph = end; | 237 m_endOfLastParagraph = end; |
| 238 } | 238 } |
| 239 | 239 |
| 240 // If end is in the middle of a text node, split. | 240 // If end is in the middle of a text node, split. |
| 241 if (endStyle->userModify() != READ_ONLY && !endStyle->collapseWhiteSpace
() && end.offsetInContainerNode() && end.offsetInContainerNode() < end.computeCo
ntainerNode()->maxCharacterOffset()) { | 241 if (endStyle->userModify() != READ_ONLY && !endStyle->collapseWhiteSpace
() && end.offsetInContainerNode() && end.offsetInContainerNode() < end.computeCo
ntainerNode()->maxCharacterOffset()) { |
| 242 RefPtrWillBeRawPtr<Text> endContainer = toText(end.computeContainerN
ode()); | 242 RawPtr<Text> endContainer = toText(end.computeContainerNode()); |
| 243 splitTextNode(endContainer, end.offsetInContainerNode()); | 243 splitTextNode(endContainer, end.offsetInContainerNode()); |
| 244 if (isStartAndEndOnSameNode) | 244 if (isStartAndEndOnSameNode) |
| 245 start = firstPositionInOrBeforeNode(endContainer->previousSiblin
g()); | 245 start = firstPositionInOrBeforeNode(endContainer->previousSiblin
g()); |
| 246 if (isEndAndEndOfLastParagraphOnSameNode) { | 246 if (isEndAndEndOfLastParagraphOnSameNode) { |
| 247 if (m_endOfLastParagraph.offsetInContainerNode() == end.offsetIn
ContainerNode()) | 247 if (m_endOfLastParagraph.offsetInContainerNode() == end.offsetIn
ContainerNode()) |
| 248 m_endOfLastParagraph = lastPositionInOrAfterNode(endContaine
r->previousSibling()); | 248 m_endOfLastParagraph = lastPositionInOrAfterNode(endContaine
r->previousSibling()); |
| 249 else | 249 else |
| 250 m_endOfLastParagraph = Position(endContainer, m_endOfLastPar
agraph.offsetInContainerNode() - end.offsetInContainerNode()); | 250 m_endOfLastParagraph = Position(endContainer, m_endOfLastPar
agraph.offsetInContainerNode() - end.offsetInContainerNode()); |
| 251 } | 251 } |
| 252 end = lastPositionInNode(endContainer->previousSibling()); | 252 end = lastPositionInNode(endContainer->previousSibling()); |
| 253 } | 253 } |
| 254 } | 254 } |
| 255 } | 255 } |
| 256 | 256 |
| 257 VisiblePosition ApplyBlockElementCommand::endOfNextParagrahSplittingTextNodesIfN
eeded(VisiblePosition& endOfCurrentParagraph, Position& start, Position& end) | 257 VisiblePosition ApplyBlockElementCommand::endOfNextParagrahSplittingTextNodesIfN
eeded(VisiblePosition& endOfCurrentParagraph, Position& start, Position& end) |
| 258 { | 258 { |
| 259 VisiblePosition endOfNextParagraph = endOfParagraph(nextPositionOf(endOfCurr
entParagraph)); | 259 VisiblePosition endOfNextParagraph = endOfParagraph(nextPositionOf(endOfCurr
entParagraph)); |
| 260 Position position = endOfNextParagraph.deepEquivalent(); | 260 Position position = endOfNextParagraph.deepEquivalent(); |
| 261 const ComputedStyle* style = computedStyleOfEnclosingTextNode(position); | 261 const ComputedStyle* style = computedStyleOfEnclosingTextNode(position); |
| 262 if (!style) | 262 if (!style) |
| 263 return endOfNextParagraph; | 263 return endOfNextParagraph; |
| 264 | 264 |
| 265 RefPtrWillBeRawPtr<Text> text = toText(position.computeContainerNode()); | 265 RawPtr<Text> text = toText(position.computeContainerNode()); |
| 266 if (!style->preserveNewline() || !position.offsetInContainerNode() || !isNew
LineAtPosition(firstPositionInNode(text.get()))) | 266 if (!style->preserveNewline() || !position.offsetInContainerNode() || !isNew
LineAtPosition(firstPositionInNode(text.get()))) |
| 267 return endOfNextParagraph; | 267 return endOfNextParagraph; |
| 268 | 268 |
| 269 // \n at the beginning of the text node immediately following the current pa
ragraph is trimmed by moveParagraphWithClones. | 269 // \n at the beginning of the text node immediately following the current pa
ragraph is trimmed by moveParagraphWithClones. |
| 270 // If endOfNextParagraph was pointing at this same text node, endOfNextParag
raph will be shifted by one paragraph. | 270 // If endOfNextParagraph was pointing at this same text node, endOfNextParag
raph will be shifted by one paragraph. |
| 271 // Avoid this by splitting "\n" | 271 // Avoid this by splitting "\n" |
| 272 splitTextNode(text, 1); | 272 splitTextNode(text, 1); |
| 273 | 273 |
| 274 if (text == start.computeContainerNode() && text->previousSibling() && text-
>previousSibling()->isTextNode()) { | 274 if (text == start.computeContainerNode() && text->previousSibling() && text-
>previousSibling()->isTextNode()) { |
| 275 ASSERT(start.offsetInContainerNode() < position.offsetInContainerNode())
; | 275 ASSERT(start.offsetInContainerNode() < position.offsetInContainerNode())
; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 286 && static_cast<unsigned>(m_endOfLastParagraph.offsetInContainerN
ode()) <= toText(text->previousSibling())->length()) | 286 && static_cast<unsigned>(m_endOfLastParagraph.offsetInContainerN
ode()) <= toText(text->previousSibling())->length()) |
| 287 m_endOfLastParagraph = Position(toText(text->previousSibling()),
m_endOfLastParagraph.offsetInContainerNode()); | 287 m_endOfLastParagraph = Position(toText(text->previousSibling()),
m_endOfLastParagraph.offsetInContainerNode()); |
| 288 } else { | 288 } else { |
| 289 m_endOfLastParagraph = Position(text.get(), m_endOfLastParagraph.off
setInContainerNode() - 1); | 289 m_endOfLastParagraph = Position(text.get(), m_endOfLastParagraph.off
setInContainerNode() - 1); |
| 290 } | 290 } |
| 291 } | 291 } |
| 292 | 292 |
| 293 return createVisiblePosition(Position(text.get(), position.offsetInContainer
Node() - 1)); | 293 return createVisiblePosition(Position(text.get(), position.offsetInContainer
Node() - 1)); |
| 294 } | 294 } |
| 295 | 295 |
| 296 PassRefPtrWillBeRawPtr<HTMLElement> ApplyBlockElementCommand::createBlockElement
() const | 296 RawPtr<HTMLElement> ApplyBlockElementCommand::createBlockElement() const |
| 297 { | 297 { |
| 298 RefPtrWillBeRawPtr<HTMLElement> element = createHTMLElement(document(), m_ta
gName); | 298 RawPtr<HTMLElement> element = createHTMLElement(document(), m_tagName); |
| 299 if (m_inlineStyle.length()) | 299 if (m_inlineStyle.length()) |
| 300 element->setAttribute(styleAttr, m_inlineStyle); | 300 element->setAttribute(styleAttr, m_inlineStyle); |
| 301 return element.release(); | 301 return element.release(); |
| 302 } | 302 } |
| 303 | 303 |
| 304 DEFINE_TRACE(ApplyBlockElementCommand) | 304 DEFINE_TRACE(ApplyBlockElementCommand) |
| 305 { | 305 { |
| 306 visitor->trace(m_endOfLastParagraph); | 306 visitor->trace(m_endOfLastParagraph); |
| 307 CompositeEditCommand::trace(visitor); | 307 CompositeEditCommand::trace(visitor); |
| 308 } | 308 } |
| 309 | 309 |
| 310 } // namespace blink | 310 } // namespace blink |
| OLD | NEW |