| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 } | 249 } |
| 250 | 250 |
| 251 template <typename Strategy> | 251 template <typename Strategy> |
| 252 static EphemeralRangeTemplate<Strategy> normalizeRangeAlgorithm(const EphemeralR
angeTemplate<Strategy>& range) | 252 static EphemeralRangeTemplate<Strategy> normalizeRangeAlgorithm(const EphemeralR
angeTemplate<Strategy>& range) |
| 253 { | 253 { |
| 254 ASSERT(range.isNotNull()); | 254 ASSERT(range.isNotNull()); |
| 255 range.document().updateLayoutIgnorePendingStylesheets(); | 255 range.document().updateLayoutIgnorePendingStylesheets(); |
| 256 | 256 |
| 257 // TODO(yosin) We should not call |parentAnchoredEquivalent()|, it is | 257 // TODO(yosin) We should not call |parentAnchoredEquivalent()|, it is |
| 258 // redundant. | 258 // redundant. |
| 259 const PositionAlgorithm<Strategy> normalizedStart = range.startPosition().do
wnstream().parentAnchoredEquivalent(); | 259 const PositionAlgorithm<Strategy> normalizedStart = mostForwardCaretPosition
(range.startPosition()).parentAnchoredEquivalent(); |
| 260 const PositionAlgorithm<Strategy> normalizedEnd = range.endPosition().upstre
am().parentAnchoredEquivalent(); | 260 const PositionAlgorithm<Strategy> normalizedEnd = mostBackwardCaretPosition(
range.endPosition()).parentAnchoredEquivalent(); |
| 261 // The order of the positions of |start| and |end| can be swapped after | 261 // The order of the positions of |start| and |end| can be swapped after |
| 262 // upstream/downstream. e.g. editing/pasteboard/copy-display-none.html | 262 // upstream/downstream. e.g. editing/pasteboard/copy-display-none.html |
| 263 if (normalizedStart.compareTo(normalizedEnd) > 0) | 263 if (normalizedStart.compareTo(normalizedEnd) > 0) |
| 264 return EphemeralRangeTemplate<Strategy>(normalizedEnd, normalizedStart); | 264 return EphemeralRangeTemplate<Strategy>(normalizedEnd, normalizedStart); |
| 265 return EphemeralRangeTemplate<Strategy>(normalizedStart, normalizedEnd); | 265 return EphemeralRangeTemplate<Strategy>(normalizedStart, normalizedEnd); |
| 266 } | 266 } |
| 267 | 267 |
| 268 EphemeralRange VisibleSelection::normalizeRange(const EphemeralRange& range) | 268 EphemeralRange VisibleSelection::normalizeRange(const EphemeralRange& range) |
| 269 { | 269 { |
| 270 return normalizeRangeAlgorithm<EditingStrategy>(range); | 270 return normalizeRangeAlgorithm<EditingStrategy>(range); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 287 m_start.document()->updateLayout(); | 287 m_start.document()->updateLayout(); |
| 288 | 288 |
| 289 // Check again, because updating layout can clear the selection. | 289 // Check again, because updating layout can clear the selection. |
| 290 if (isNone()) | 290 if (isNone()) |
| 291 return EphemeralRange(); | 291 return EphemeralRange(); |
| 292 | 292 |
| 293 if (isCaret()) { | 293 if (isCaret()) { |
| 294 // If the selection is a caret, move the range start upstream. This | 294 // If the selection is a caret, move the range start upstream. This |
| 295 // helps us match the conventions of text editors tested, which make | 295 // helps us match the conventions of text editors tested, which make |
| 296 // style determinations based on the character before the caret, if any. | 296 // style determinations based on the character before the caret, if any. |
| 297 const Position start = m_start.upstream().parentAnchoredEquivalent(); | 297 const Position start = mostBackwardCaretPosition(m_start).parentAnchored
Equivalent(); |
| 298 return EphemeralRange(start, start); | 298 return EphemeralRange(start, start); |
| 299 } | 299 } |
| 300 // If the selection is a range, select the minimum range that encompasses | 300 // If the selection is a range, select the minimum range that encompasses |
| 301 // the selection. Again, this is to match the conventions of text editors | 301 // the selection. Again, this is to match the conventions of text editors |
| 302 // tested, which make style determinations based on the first character of | 302 // tested, which make style determinations based on the first character of |
| 303 // the selection. For instance, this operation helps to make sure that the | 303 // the selection. For instance, this operation helps to make sure that the |
| 304 // "X" selected below is the only thing selected. The range should not be | 304 // "X" selected below is the only thing selected. The range should not be |
| 305 // allowed to "leak" out to the end of the previous text node, or to the | 305 // allowed to "leak" out to the end of the previous text node, or to the |
| 306 // beginning of the next text node, each of which has a different style. | 306 // beginning of the next text node, each of which has a different style. |
| 307 // | 307 // |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 m_end = m_baseIsFirst ? m_extent : m_base; | 574 m_end = m_baseIsFirst ? m_extent : m_base; |
| 575 resetPositionsInComposedTree(); | 575 resetPositionsInComposedTree(); |
| 576 } | 576 } |
| 577 | 577 |
| 578 SelectionType VisibleSelection::selectionType(const Position& start, const Posit
ion& end) | 578 SelectionType VisibleSelection::selectionType(const Position& start, const Posit
ion& end) |
| 579 { | 579 { |
| 580 if (start.isNull()) { | 580 if (start.isNull()) { |
| 581 ASSERT(end.isNull()); | 581 ASSERT(end.isNull()); |
| 582 return NoSelection; | 582 return NoSelection; |
| 583 } | 583 } |
| 584 if (start == end || start.upstream() == end.upstream()) | 584 if (start == end || mostBackwardCaretPosition(start) == mostBackwardCaretPos
ition(end)) |
| 585 return CaretSelection; | 585 return CaretSelection; |
| 586 return RangeSelection; | 586 return RangeSelection; |
| 587 } | 587 } |
| 588 | 588 |
| 589 SelectionType VisibleSelection::selectionType(const PositionInComposedTree& star
t, const PositionInComposedTree& end) | 589 SelectionType VisibleSelection::selectionType(const PositionInComposedTree& star
t, const PositionInComposedTree& end) |
| 590 { | 590 { |
| 591 if (start.isNull()) { | 591 if (start.isNull()) { |
| 592 ASSERT(end.isNull()); | 592 ASSERT(end.isNull()); |
| 593 return NoSelection; | 593 return NoSelection; |
| 594 } | 594 } |
| 595 if (start == end || start.upstream() == end.upstream()) | 595 if (start == end || mostBackwardCaretPosition(start) == mostBackwardCaretPos
ition(end)) |
| 596 return CaretSelection; | 596 return CaretSelection; |
| 597 return RangeSelection; | 597 return RangeSelection; |
| 598 } | 598 } |
| 599 | 599 |
| 600 void VisibleSelection::updateSelectionType() | 600 void VisibleSelection::updateSelectionType() |
| 601 { | 601 { |
| 602 m_selectionType = selectionType(m_start, m_end); | 602 m_selectionType = selectionType(m_start, m_end); |
| 603 | 603 |
| 604 // Affinity only makes sense for a caret | 604 // Affinity only makes sense for a caret |
| 605 if (m_selectionType != CaretSelection) | 605 if (m_selectionType != CaretSelection) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 | 692 |
| 693 if (selectionType() == RangeSelection) { | 693 if (selectionType() == RangeSelection) { |
| 694 // "Constrain" the selection to be the smallest equivalent range of node
s. | 694 // "Constrain" the selection to be the smallest equivalent range of node
s. |
| 695 // This is a somewhat arbitrary choice, but experience shows that it is | 695 // This is a somewhat arbitrary choice, but experience shows that it is |
| 696 // useful to make to make the selection "canonical" (if only for | 696 // useful to make to make the selection "canonical" (if only for |
| 697 // purposes of comparing selections). This is an ideal point of the code | 697 // purposes of comparing selections). This is an ideal point of the code |
| 698 // to do this operation, since all selection changes that result in a RA
NGE | 698 // to do this operation, since all selection changes that result in a RA
NGE |
| 699 // come through here before anyone uses it. | 699 // come through here before anyone uses it. |
| 700 // FIXME: Canonicalizing is good, but haven't we already done it (when w
e | 700 // FIXME: Canonicalizing is good, but haven't we already done it (when w
e |
| 701 // set these two positions to VisiblePosition deepEquivalent()s above)? | 701 // set these two positions to VisiblePosition deepEquivalent()s above)? |
| 702 m_start = m_start.downstream(); | 702 m_start = mostForwardCaretPosition(m_start); |
| 703 m_end = m_end.upstream(); | 703 m_end = mostBackwardCaretPosition(m_end); |
| 704 | 704 |
| 705 // Even by downstreaming, |m_start| can be moved to the upper place from | 705 // Even by downstreaming, |m_start| can be moved to the upper place from |
| 706 // the original position, same as |m_end|. | 706 // the original position, same as |m_end|. |
| 707 // e.g.) editing/shadow/select-contenteditable-shadowhost.html | 707 // e.g.) editing/shadow/select-contenteditable-shadowhost.html |
| 708 m_startInComposedTree = m_startInComposedTree.downstream(); | 708 m_startInComposedTree = mostForwardCaretPosition(m_startInComposedTree); |
| 709 m_endInComposedTree = m_endInComposedTree.upstream(); | 709 m_endInComposedTree = mostBackwardCaretPosition(m_endInComposedTree); |
| 710 adjustStartAndEndInComposedTree(); | 710 adjustStartAndEndInComposedTree(); |
| 711 | 711 |
| 712 if (isCrossingSelectionBoundary(m_startInComposedTree, m_endInComposedTr
ee)) | 712 if (isCrossingSelectionBoundary(m_startInComposedTree, m_endInComposedTr
ee)) |
| 713 resetPositionsInComposedTree(); | 713 resetPositionsInComposedTree(); |
| 714 | 714 |
| 715 // FIXME: Position::downstream() or Position::upStream() might violate e
diting boundaries | 715 // FIXME: Position::downstream() or Position::upStream() might violate e
diting boundaries |
| 716 // if an anchor node has a Shadow DOM. So we adjust selection to avoid c
rossing editing | 716 // if an anchor node has a Shadow DOM. So we adjust selection to avoid c
rossing editing |
| 717 // boundaries again. See https://bugs.webkit.org/show_bug.cgi?id=87463 | 717 // boundaries again. See https://bugs.webkit.org/show_bug.cgi?id=87463 |
| 718 origExtent = m_extent; | 718 origExtent = m_extent; |
| 719 origEnd = m_end; | 719 origEnd = m_end; |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 sel.showTreeForThis(); | 1252 sel.showTreeForThis(); |
| 1253 } | 1253 } |
| 1254 | 1254 |
| 1255 void showTree(const blink::VisibleSelection* sel) | 1255 void showTree(const blink::VisibleSelection* sel) |
| 1256 { | 1256 { |
| 1257 if (sel) | 1257 if (sel) |
| 1258 sel->showTreeForThis(); | 1258 sel->showTreeForThis(); |
| 1259 } | 1259 } |
| 1260 | 1260 |
| 1261 #endif | 1261 #endif |
| OLD | NEW |