| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2008, 2009, 2010 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 217 |
| 218 newSelection.setIsDirectional(isDirectional); // Adjusting base and extent w
ill make newSelection always directional | 218 newSelection.setIsDirectional(isDirectional); // Adjusting base and extent w
ill make newSelection always directional |
| 219 if (Strategy::equalSelections(m_selection, newSelection)) | 219 if (Strategy::equalSelections(m_selection, newSelection)) |
| 220 return; | 220 return; |
| 221 | 221 |
| 222 setSelection(newSelection, granularity); | 222 setSelection(newSelection, granularity); |
| 223 } | 223 } |
| 224 | 224 |
| 225 void FrameSelection::setNonDirectionalSelectionIfNeeded(const VisibleSelection&
passedNewSelection, TextGranularity granularity, EndPointsAdjustmentMode endpoin
tsAdjustmentMode) | 225 void FrameSelection::setNonDirectionalSelectionIfNeeded(const VisibleSelection&
passedNewSelection, TextGranularity granularity, EndPointsAdjustmentMode endpoin
tsAdjustmentMode) |
| 226 { | 226 { |
| 227 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 228 return setNonDirectionalSelectionIfNeededAlgorithm<VisibleSelection::InC
omposedTree>(passedNewSelection, granularity, endpointsAdjustmentMode); |
| 227 setNonDirectionalSelectionIfNeededAlgorithm<VisibleSelection::InDOMTree>(pas
sedNewSelection, granularity, endpointsAdjustmentMode); | 229 setNonDirectionalSelectionIfNeededAlgorithm<VisibleSelection::InDOMTree>(pas
sedNewSelection, granularity, endpointsAdjustmentMode); |
| 228 } | 230 } |
| 229 | 231 |
| 232 static bool areEquivalentSelections(const VisibleSelection& selection1, const Vi
sibleSelection& selection2) |
| 233 { |
| 234 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 235 return VisibleSelection::InComposedTree::equalSelections(selection1, sel
ection2); |
| 236 return VisibleSelection::InDOMTree::equalSelections(selection1, selection2); |
| 237 } |
| 238 |
| 230 void FrameSelection::setSelection(const VisibleSelection& newSelection, SetSelec
tionOptions options, CursorAlignOnScroll align, TextGranularity granularity) | 239 void FrameSelection::setSelection(const VisibleSelection& newSelection, SetSelec
tionOptions options, CursorAlignOnScroll align, TextGranularity granularity) |
| 231 { | 240 { |
| 232 if (m_granularityStrategy && (options & FrameSelection::DoNotClearStrategy)
== 0) | 241 if (m_granularityStrategy && (options & FrameSelection::DoNotClearStrategy)
== 0) |
| 233 m_granularityStrategy->Clear(); | 242 m_granularityStrategy->Clear(); |
| 234 bool closeTyping = options & CloseTyping; | 243 bool closeTyping = options & CloseTyping; |
| 235 bool shouldClearTypingStyle = options & ClearTypingStyle; | 244 bool shouldClearTypingStyle = options & ClearTypingStyle; |
| 236 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); | 245 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); |
| 237 | 246 |
| 238 VisibleSelection s = validateSelection(newSelection); | 247 VisibleSelection s = validateSelection(newSelection); |
| 239 if (shouldAlwaysUseDirectionalSelection(m_frame)) | 248 if (shouldAlwaysUseDirectionalSelection(m_frame)) |
| 240 s.setIsDirectional(true); | 249 s.setIsDirectional(true); |
| 241 | 250 |
| 242 if (!m_frame) { | 251 if (!m_frame) { |
| 243 m_selection = s; | 252 m_selection = s; |
| 244 return; | 253 return; |
| 245 } | 254 } |
| 246 | 255 |
| 247 // <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at Fra
meSelection::setSelection | 256 // <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at Fra
meSelection::setSelection |
| 248 // if document->frame() == m_frame we can get into an infinite loop | 257 // if document->frame() == m_frame we can get into an infinite loop |
| 249 if (s.base().anchorNode()) { | 258 if (s.base().anchorNode()) { |
| 250 Document& document = *s.base().document(); | 259 Document& document = *s.base().document(); |
| 260 // TODO(hajimehoshi): validateSelection already checks if the selection |
| 261 // is valid, thus we don't need this 'if' clause any more. |
| 251 if (document.frame() && document.frame() != m_frame && document != m_fra
me->document()) { | 262 if (document.frame() && document.frame() != m_frame && document != m_fra
me->document()) { |
| 252 RefPtrWillBeRawPtr<LocalFrame> guard(document.frame()); | 263 RefPtrWillBeRawPtr<LocalFrame> guard(document.frame()); |
| 253 document.frame()->selection().setSelection(s, options, align, granul
arity); | 264 document.frame()->selection().setSelection(s, options, align, granul
arity); |
| 254 // It's possible that during the above set selection, this FrameSele
ction has been modified by | 265 // It's possible that during the above set selection, this FrameSele
ction has been modified by |
| 255 // selectFrameElementInParentIfFullySelected, but that the selection
is no longer valid since | 266 // selectFrameElementInParentIfFullySelected, but that the selection
is no longer valid since |
| 256 // the frame is about to be destroyed. If this is the case, clear ou
r selection. | 267 // the frame is about to be destroyed. If this is the case, clear ou
r selection. |
| 257 if (!guard->host() && !m_selection.isNonOrphanedCaretOrRange()) | 268 if (!guard->host() && !m_selection.isNonOrphanedCaretOrRange()) |
| 258 clear(); | 269 clear(); |
| 259 return; | 270 return; |
| 260 } | 271 } |
| 261 } | 272 } |
| 262 | 273 |
| 263 m_granularity = granularity; | 274 m_granularity = granularity; |
| 264 | 275 |
| 265 if (closeTyping) | 276 if (closeTyping) |
| 266 TypingCommand::closeTyping(m_frame); | 277 TypingCommand::closeTyping(m_frame); |
| 267 | 278 |
| 268 if (shouldClearTypingStyle) | 279 if (shouldClearTypingStyle) |
| 269 clearTypingStyle(); | 280 clearTypingStyle(); |
| 270 | 281 |
| 271 if (m_selection == s) { | 282 if (areEquivalentSelections(m_selection, s)) { |
| 272 // Even if selection was not changed, selection offsets may have been ch
anged. | 283 // Even if selection was not changed, selection offsets may have been ch
anged. |
| 273 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid()
; | 284 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid()
; |
| 274 notifyLayoutObjectOfSelectionChange(userTriggered); | 285 notifyLayoutObjectOfSelectionChange(userTriggered); |
| 275 return; | 286 return; |
| 276 } | 287 } |
| 277 | 288 |
| 278 VisibleSelection oldSelection = m_selection; | 289 VisibleSelection oldSelection = m_selection; |
| 279 | 290 |
| 280 m_selection = s; | 291 m_selection = s; |
| 281 setCaretRectNeedsUpdate(); | 292 setCaretRectNeedsUpdate(); |
| 282 | 293 |
| 283 if (!s.isNone() && !(options & DoNotSetFocus)) | 294 if (!s.isNone() && !(options & DoNotSetFocus)) |
| 284 setFocusedNodeIfNeeded(); | 295 setFocusedNodeIfNeeded(); |
| 285 | 296 |
| 286 if (!(options & DoNotUpdateAppearance)) { | 297 if (!(options & DoNotUpdateAppearance)) { |
| 287 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr
olling-contents.html | 298 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr
olling-contents.html |
| 288 DisableCompositingQueryAsserts disabler; | 299 DisableCompositingQueryAsserts disabler; |
| 289 updateAppearance(ResetCaretBlink); | 300 updateAppearance(ResetCaretBlink); |
| 290 } | 301 } |
| 291 | 302 |
| 292 // Always clear the x position used for vertical arrow navigation. | 303 // Always clear the x position used for vertical arrow navigation. |
| 293 // It will be restored by the vertical arrow navigation code if necessary. | 304 // It will be restored by the vertical arrow navigation code if necessary. |
| 294 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); | 305 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); |
| 295 selectFrameElementInParentIfFullySelected(); | 306 selectFrameElementInParentIfFullySelected(); |
| 296 notifyLayoutObjectOfSelectionChange(userTriggered); | 307 notifyLayoutObjectOfSelectionChange(userTriggered); |
| 308 // If the selections are same in the DOM tree but not in the composed tree, |
| 309 // don't fire events. For example, if the selection crosses shadow tree |
| 310 // boundary, selection for the DOM tree is shrunk while that for the |
| 311 // composed tree is not. Additionally, this case occurs in some edge cases. |
| 312 // See also: editing/pasteboard/4076267-3.html |
| 313 if (VisibleSelection::InDOMTree::equalSelections(oldSelection, m_selection)) |
| 314 return; |
| 297 m_frame->editor().respondToChangedSelection(oldSelection, options); | 315 m_frame->editor().respondToChangedSelection(oldSelection, options); |
| 298 if (userTriggered == UserTriggered) { | 316 if (userTriggered == UserTriggered) { |
| 299 ScrollAlignment alignment; | 317 ScrollAlignment alignment; |
| 300 | 318 |
| 301 if (m_frame->editor().behavior().shouldCenterAlignWhenSelectionIsReveale
d()) | 319 if (m_frame->editor().behavior().shouldCenterAlignWhenSelectionIsReveale
d()) |
| 302 alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::
alignCenterAlways : ScrollAlignment::alignCenterIfNeeded; | 320 alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::
alignCenterAlways : ScrollAlignment::alignCenterIfNeeded; |
| 303 else | 321 else |
| 304 alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::
alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded; | 322 alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::
alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded; |
| 305 | 323 |
| 306 revealSelection(alignment, RevealExtent); | 324 revealSelection(alignment, RevealExtent); |
| (...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 return false; | 1347 return false; |
| 1330 | 1348 |
| 1331 PositionType start(Strategy::toPositionType(visibleStart.deepEquivalent())); | 1349 PositionType start(Strategy::toPositionType(visibleStart.deepEquivalent())); |
| 1332 PositionType end(Strategy::toPositionType(visibleEnd.deepEquivalent())); | 1350 PositionType end(Strategy::toPositionType(visibleEnd.deepEquivalent())); |
| 1333 PositionType pos(Strategy::toPositionType(visiblePos.deepEquivalent())); | 1351 PositionType pos(Strategy::toPositionType(visiblePos.deepEquivalent())); |
| 1334 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; | 1352 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; |
| 1335 } | 1353 } |
| 1336 | 1354 |
| 1337 bool FrameSelection::contains(const LayoutPoint& point) | 1355 bool FrameSelection::contains(const LayoutPoint& point) |
| 1338 { | 1356 { |
| 1357 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 1358 return containsAlgorithm<VisibleSelection::InComposedTree>(point); |
| 1339 return containsAlgorithm<VisibleSelection::InDOMTree>(point); | 1359 return containsAlgorithm<VisibleSelection::InDOMTree>(point); |
| 1340 } | 1360 } |
| 1341 | 1361 |
| 1342 // Workaround for the fact that it's hard to delete a frame. | 1362 // Workaround for the fact that it's hard to delete a frame. |
| 1343 // Call this after doing user-triggered selections to make it easy to delete the
frame you entirely selected. | 1363 // Call this after doing user-triggered selections to make it easy to delete the
frame you entirely selected. |
| 1344 // Can't do this implicitly as part of every setSelection call because in some c
ontexts it might not be good | 1364 // Can't do this implicitly as part of every setSelection call because in some c
ontexts it might not be good |
| 1345 // for the focus to move to another frame. So instead we call it from places whe
re we are selecting with the | 1365 // for the focus to move to another frame. So instead we call it from places whe
re we are selecting with the |
| 1346 // mouse or the keyboard after setting the selection. | 1366 // mouse or the keyboard after setting the selection. |
| 1347 void FrameSelection::selectFrameElementInParentIfFullySelected() | 1367 void FrameSelection::selectFrameElementInParentIfFullySelected() |
| 1348 { | 1368 { |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 PositionType start; | 1706 PositionType start; |
| 1687 PositionType end; | 1707 PositionType end; |
| 1688 VisibleSelection visibleSelection = selection.selection(); | 1708 VisibleSelection visibleSelection = selection.selection(); |
| 1689 VisibleSelection::normalizePositions(Strategy::selectionStart(visibleSelecti
on), Strategy::selectionEnd(visibleSelection), &start, &end); | 1709 VisibleSelection::normalizePositions(Strategy::selectionStart(visibleSelecti
on), Strategy::selectionEnd(visibleSelection), &start, &end); |
| 1690 // We remove '\0' characters because they are not visibly rendered to the us
er. | 1710 // We remove '\0' characters because they are not visibly rendered to the us
er. |
| 1691 return plainText(start, end, behavior).replace(0, ""); | 1711 return plainText(start, end, behavior).replace(0, ""); |
| 1692 } | 1712 } |
| 1693 | 1713 |
| 1694 static String extractSelectedText(const FrameSelection& selection, TextIteratorB
ehavior behavior) | 1714 static String extractSelectedText(const FrameSelection& selection, TextIteratorB
ehavior behavior) |
| 1695 { | 1715 { |
| 1716 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 1717 return extractSelectedTextAlgorithm<VisibleSelection::InComposedTree>(se
lection, behavior); |
| 1696 return extractSelectedTextAlgorithm<VisibleSelection::InDOMTree>(selection,
behavior); | 1718 return extractSelectedTextAlgorithm<VisibleSelection::InDOMTree>(selection,
behavior); |
| 1697 } | 1719 } |
| 1698 | 1720 |
| 1699 template <typename Strategy> | 1721 template <typename Strategy> |
| 1700 static String extractSelectedHTMLAlgorithm(const FrameSelection& selection) | 1722 static String extractSelectedHTMLAlgorithm(const FrameSelection& selection) |
| 1701 { | 1723 { |
| 1702 using PositionType = typename Strategy::PositionType; | 1724 using PositionType = typename Strategy::PositionType; |
| 1703 PositionType start; | 1725 PositionType start; |
| 1704 PositionType end; | 1726 PositionType end; |
| 1705 VisibleSelection visibleSelection = selection.selection(); | 1727 VisibleSelection visibleSelection = selection.selection(); |
| 1706 VisibleSelection::normalizePositions(Strategy::selectionStart(visibleSelecti
on), Strategy::selectionEnd(visibleSelection), &start, &end); | 1728 VisibleSelection::normalizePositions(Strategy::selectionStart(visibleSelecti
on), Strategy::selectionEnd(visibleSelection), &start, &end); |
| 1707 return createMarkup(start, end, AnnotateForInterchange, ConvertBlocksToInlin
es::NotConvert, ResolveNonLocalURLs); | 1729 return createMarkup(start, end, AnnotateForInterchange, ConvertBlocksToInlin
es::NotConvert, ResolveNonLocalURLs); |
| 1708 } | 1730 } |
| 1709 | 1731 |
| 1710 String FrameSelection::selectedHTMLForClipboard() const | 1732 String FrameSelection::selectedHTMLForClipboard() const |
| 1711 { | 1733 { |
| 1712 return extractSelectedHTMLAlgorithm<VisibleSelection::InDOMTree>(*this); | 1734 if (!RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 1735 return extractSelectedHTMLAlgorithm<VisibleSelection::InDOMTree>(*this); |
| 1736 return extractSelectedHTMLAlgorithm<VisibleSelection::InComposedTree>(*this)
; |
| 1713 } | 1737 } |
| 1714 | 1738 |
| 1715 String FrameSelection::selectedText() const | 1739 String FrameSelection::selectedText() const |
| 1716 { | 1740 { |
| 1717 return extractSelectedText(*this, TextIteratorDefaultBehavior); | 1741 return extractSelectedText(*this, TextIteratorDefaultBehavior); |
| 1718 } | 1742 } |
| 1719 | 1743 |
| 1720 String FrameSelection::selectedTextForClipboard() const | 1744 String FrameSelection::selectedTextForClipboard() const |
| 1721 { | 1745 { |
| 1722 if (m_frame->settings() && m_frame->settings()->selectionIncludesAltImageTex
t()) | 1746 if (m_frame->settings() && m_frame->settings()->selectionIncludesAltImageTex
t()) |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 | 2035 |
| 2012 void showTree(const blink::FrameSelection* sel) | 2036 void showTree(const blink::FrameSelection* sel) |
| 2013 { | 2037 { |
| 2014 if (sel) | 2038 if (sel) |
| 2015 sel->showTreeForThis(); | 2039 sel->showTreeForThis(); |
| 2016 else | 2040 else |
| 2017 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n"); | 2041 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n"); |
| 2018 } | 2042 } |
| 2019 | 2043 |
| 2020 #endif | 2044 #endif |
| OLD | NEW |