Chromium Code Reviews| 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 m_removeOnly(true), | 182 m_removeOnly(true), |
| 183 m_isInlineElementToRemoveFunction(isInlineElementToRemoveFunction) {} | 183 m_isInlineElementToRemoveFunction(isInlineElementToRemoveFunction) {} |
| 184 | 184 |
| 185 void ApplyStyleCommand::updateStartEnd(const Position& newStart, | 185 void ApplyStyleCommand::updateStartEnd(const Position& newStart, |
| 186 const Position& newEnd) { | 186 const Position& newEnd) { |
| 187 DCHECK_GE(comparePositions(newEnd, newStart), 0); | 187 DCHECK_GE(comparePositions(newEnd, newStart), 0); |
| 188 | 188 |
| 189 if (!m_useEndingSelection && (newStart != m_start || newEnd != m_end)) | 189 if (!m_useEndingSelection && (newStart != m_start || newEnd != m_end)) |
| 190 m_useEndingSelection = true; | 190 m_useEndingSelection = true; |
| 191 | 191 |
| 192 setEndingSelection( | 192 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 193 createVisibleSelectionDeprecated(newStart, newEnd, VP_DEFAULT_AFFINITY, | 193 setEndingSelection(createVisibleSelection(newStart, newEnd, |
|
yosin_UTC9
2016/10/06 04:51:50
BTW, we would like to have SelectionForUndoStep or
Xiaocheng
2016/10/06 05:04:45
If I understand correctly, a VisibleSelection shou
| |
| 194 endingSelection().isDirectional())); | 194 VP_DEFAULT_AFFINITY, |
| 195 endingSelection().isDirectional())); | |
| 195 m_start = newStart; | 196 m_start = newStart; |
| 196 m_end = newEnd; | 197 m_end = newEnd; |
| 197 } | 198 } |
| 198 | 199 |
| 199 Position ApplyStyleCommand::startPosition() { | 200 Position ApplyStyleCommand::startPosition() { |
| 200 if (m_useEndingSelection) | 201 if (m_useEndingSelection) |
| 201 return endingSelection().start(); | 202 return endingSelection().start(); |
| 202 | 203 |
| 203 return m_start; | 204 return m_start; |
| 204 } | 205 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 | 253 |
| 253 // get positions we want to use for applying style | 254 // get positions we want to use for applying style |
| 254 Position start = startPosition(); | 255 Position start = startPosition(); |
| 255 Position end = endPosition(); | 256 Position end = endPosition(); |
| 256 if (comparePositions(end, start) < 0) { | 257 if (comparePositions(end, start) < 0) { |
| 257 Position swap = start; | 258 Position swap = start; |
| 258 start = end; | 259 start = end; |
| 259 end = swap; | 260 end = swap; |
| 260 } | 261 } |
| 261 | 262 |
| 262 VisiblePosition visibleStart = createVisiblePositionDeprecated(start); | 263 VisiblePosition visibleStart = createVisiblePosition(start); |
| 263 VisiblePosition visibleEnd = createVisiblePositionDeprecated(end); | 264 VisiblePosition visibleEnd = createVisiblePosition(end); |
| 264 | 265 |
| 265 if (visibleStart.isNull() || visibleStart.isOrphan() || visibleEnd.isNull() || | 266 if (visibleStart.isNull() || visibleStart.isOrphan() || visibleEnd.isNull() || |
| 266 visibleEnd.isOrphan()) | 267 visibleEnd.isOrphan()) |
| 267 return; | 268 return; |
| 268 | 269 |
| 269 // Save and restore the selection endpoints using their indices in the documen t, since | 270 // Save and restore the selection endpoints using their indices in the documen t, since |
| 270 // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints. | 271 // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints. |
| 271 // Calculate start and end indices from the start of the tree that they're in. | 272 // Calculate start and end indices from the start of the tree that they're in. |
| 272 Node& scope = NodeTraversal::highestAncestorOrSelf( | 273 Node& scope = NodeTraversal::highestAncestorOrSelf( |
| 273 *visibleStart.deepEquivalent().anchorNode()); | 274 *visibleStart.deepEquivalent().anchorNode()); |
| 274 Range* startRange = | 275 Range* startRange = |
| 275 Range::create(document(), Position::firstPositionInNode(&scope), | 276 Range::create(document(), Position::firstPositionInNode(&scope), |
| 276 visibleStart.deepEquivalent().parentAnchoredEquivalent()); | 277 visibleStart.deepEquivalent().parentAnchoredEquivalent()); |
| 277 Range* endRange = | 278 Range* endRange = |
| 278 Range::create(document(), Position::firstPositionInNode(&scope), | 279 Range::create(document(), Position::firstPositionInNode(&scope), |
| 279 visibleEnd.deepEquivalent().parentAnchoredEquivalent()); | 280 visibleEnd.deepEquivalent().parentAnchoredEquivalent()); |
| 280 int startIndex = TextIterator::rangeLength(startRange->startPosition(), | 281 int startIndex = TextIterator::rangeLength(startRange->startPosition(), |
| 281 startRange->endPosition(), true); | 282 startRange->endPosition(), true); |
| 282 int endIndex = TextIterator::rangeLength(endRange->startPosition(), | 283 int endIndex = TextIterator::rangeLength(endRange->startPosition(), |
| 283 endRange->endPosition(), true); | 284 endRange->endPosition(), true); |
| 284 | 285 |
| 285 VisiblePosition paragraphStart(startOfParagraphDeprecated(visibleStart)); | 286 VisiblePosition paragraphStart(startOfParagraph(visibleStart)); |
| 286 VisiblePosition nextParagraphStart( | 287 VisiblePosition nextParagraphStart( |
| 287 nextPositionOf(endOfParagraphDeprecated(paragraphStart))); | 288 nextPositionOf(endOfParagraph(paragraphStart))); |
| 288 VisiblePosition beyondEnd( | 289 Position beyondEnd = |
| 289 nextPositionOf(endOfParagraphDeprecated(visibleEnd))); | 290 nextPositionOf(endOfParagraph(visibleEnd)).deepEquivalent(); |
| 291 // TODO(xiaochengh): Use a saner approach (e.g., temporary Ranges) to keep | |
| 292 // these positions in document instead of iteratively performing orphan checks | |
| 293 // and recalculating them when they become orphans. | |
| 290 while (paragraphStart.isNotNull() && | 294 while (paragraphStart.isNotNull() && |
| 291 paragraphStart.deepEquivalent() != beyondEnd.deepEquivalent()) { | 295 paragraphStart.deepEquivalent() != beyondEnd) { |
| 292 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; | 296 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; |
| 293 StyleChange styleChange(style, paragraphStart.deepEquivalent()); | 297 StyleChange styleChange(style, paragraphStart.deepEquivalent()); |
| 294 if (styleChange.cssStyle().length() || m_removeOnly) { | 298 if (styleChange.cssStyle().length() || m_removeOnly) { |
| 295 Element* block = | 299 Element* block = |
| 296 enclosingBlock(paragraphStart.deepEquivalent().anchorNode()); | 300 enclosingBlock(paragraphStart.deepEquivalent().anchorNode()); |
| 297 const Position& paragraphStartToMove = paragraphStart.deepEquivalent(); | 301 const Position& paragraphStartToMove = paragraphStart.deepEquivalent(); |
| 298 if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) { | 302 if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) { |
| 299 HTMLElement* newBlock = moveParagraphContentsToNewBlockIfNecessary( | 303 HTMLElement* newBlock = moveParagraphContentsToNewBlockIfNecessary( |
| 300 paragraphStartToMove, editingState); | 304 paragraphStartToMove, editingState); |
| 301 if (editingState->isAborted()) | 305 if (editingState->isAborted()) |
| 302 return; | 306 return; |
| 303 if (newBlock) { | 307 if (newBlock) { |
| 304 block = newBlock; | 308 block = newBlock; |
| 305 if (paragraphStart.isOrphan()) | 309 if (paragraphStart.isOrphan()) { |
| 306 paragraphStart = createVisiblePositionDeprecated( | 310 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 307 Position::firstPositionInNode(newBlock)); | 311 paragraphStart = |
| 312 createVisiblePosition(Position::firstPositionInNode(newBlock)); | |
| 313 } | |
| 308 } | 314 } |
| 309 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; | 315 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; |
| 310 } | 316 } |
| 311 if (block && block->isHTMLElement()) { | 317 if (block && block->isHTMLElement()) { |
| 312 removeCSSStyle(style, toHTMLElement(block), editingState); | 318 removeCSSStyle(style, toHTMLElement(block), editingState); |
| 313 if (editingState->isAborted()) | 319 if (editingState->isAborted()) |
| 314 return; | 320 return; |
| 315 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; | 321 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; |
| 316 if (!m_removeOnly) { | 322 if (!m_removeOnly) { |
| 317 addBlockStyle(styleChange, toHTMLElement(block)); | 323 addBlockStyle(styleChange, toHTMLElement(block)); |
| 318 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; | 324 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; |
| 319 } | 325 } |
| 320 } | 326 } |
| 321 | 327 |
| 328 document().updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 329 | |
| 330 // Make the VisiblePositions valid again after style changes. | |
| 331 // TODO(xiaochengh): We shouldn't store VisiblePositions and inspect their | |
| 332 // properties after they have been invalidated by mutations. | |
| 322 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; | 333 DCHECK(!paragraphStart.isOrphan()) << paragraphStart; |
| 323 if (nextParagraphStart.isOrphan()) | 334 paragraphStart = |
| 335 createVisiblePosition(paragraphStart.toPositionWithAffinity()); | |
| 336 if (nextParagraphStart.isOrphan()) { | |
| 337 nextParagraphStart = nextPositionOf(endOfParagraph(paragraphStart)); | |
| 338 } else { | |
| 324 nextParagraphStart = | 339 nextParagraphStart = |
| 325 nextPositionOf(endOfParagraphDeprecated(paragraphStart)); | 340 createVisiblePosition(nextParagraphStart.toPositionWithAffinity()); |
| 341 } | |
| 326 } | 342 } |
| 327 | 343 |
| 328 DCHECK(!nextParagraphStart.isOrphan()) << nextParagraphStart; | 344 DCHECK(!nextParagraphStart.isOrphan()) << nextParagraphStart; |
| 329 paragraphStart = nextParagraphStart; | 345 paragraphStart = nextParagraphStart; |
| 330 nextParagraphStart = | 346 nextParagraphStart = nextPositionOf(endOfParagraph(paragraphStart)); |
| 331 nextPositionOf(endOfParagraphDeprecated(paragraphStart)); | |
| 332 } | 347 } |
| 333 | 348 |
| 334 // Update style and layout again, since added or removed styles could have | 349 // Update style and layout again, since added or removed styles could have |
| 335 // affected the layout. We need clean layout in order to compute | 350 // affected the layout. We need clean layout in order to compute |
| 336 // plain-text ranges below. | 351 // plain-text ranges below. |
| 337 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 352 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 338 | 353 |
| 339 EphemeralRange startEphemeralRange = | 354 EphemeralRange startEphemeralRange = |
| 340 PlainTextRange(startIndex) | 355 PlainTextRange(startIndex) |
| 341 .createRangeForSelection(toContainerNode(scope)); | 356 .createRangeForSelection(toContainerNode(scope)); |
| (...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1974 | 1989 |
| 1975 DEFINE_TRACE(ApplyStyleCommand) { | 1990 DEFINE_TRACE(ApplyStyleCommand) { |
| 1976 visitor->trace(m_style); | 1991 visitor->trace(m_style); |
| 1977 visitor->trace(m_start); | 1992 visitor->trace(m_start); |
| 1978 visitor->trace(m_end); | 1993 visitor->trace(m_end); |
| 1979 visitor->trace(m_styledInlineElement); | 1994 visitor->trace(m_styledInlineElement); |
| 1980 CompositeEditCommand::trace(visitor); | 1995 CompositeEditCommand::trace(visitor); |
| 1981 } | 1996 } |
| 1982 | 1997 |
| 1983 } // namespace blink | 1998 } // namespace blink |
| OLD | NEW |