| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights |
| 4 * reserved. | 4 * reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 102 |
| 103 current_ = nullptr; | 103 current_ = nullptr; |
| 104 return *this; | 104 return *this; |
| 105 } | 105 } |
| 106 | 106 |
| 107 LayoutSelection::LayoutSelection(FrameSelection& frame_selection) | 107 LayoutSelection::LayoutSelection(FrameSelection& frame_selection) |
| 108 : frame_selection_(&frame_selection), | 108 : frame_selection_(&frame_selection), |
| 109 has_pending_selection_(false), | 109 has_pending_selection_(false), |
| 110 paint_range_(SelectionPaintRange()) {} | 110 paint_range_(SelectionPaintRange()) {} |
| 111 | 111 |
| 112 static SelectionInFlatTree CalcSelection( | 112 static bool ShouldShowBlockCursor(const FrameSelection& frame_selection, |
| 113 const VisibleSelectionInFlatTree& original_selection, | 113 const VisibleSelectionInFlatTree& selection) { |
| 114 bool should_show_blok_cursor) { | 114 if (!frame_selection.ShouldShowBlockCursor()) |
| 115 const PositionInFlatTree& start = original_selection.Start(); | 115 return false; |
| 116 const PositionInFlatTree& end = original_selection.End(); | 116 if (selection.GetSelectionType() != SelectionType::kCaretSelection) |
| 117 SelectionType selection_type = original_selection.GetSelectionType(); | 117 return false; |
| 118 const TextAffinity affinity = original_selection.Affinity(); | 118 if (IsLogicalEndOfLine(selection.VisibleEnd())) |
| 119 | 119 return false; |
| 120 bool paint_block_cursor = | 120 return true; |
| 121 should_show_blok_cursor && | |
| 122 selection_type == SelectionType::kCaretSelection && | |
| 123 !IsLogicalEndOfLine(CreateVisiblePosition(end, affinity)); | |
| 124 if (EnclosingTextControl(start.ComputeContainerNode())) { | |
| 125 // TODO(yosin) We should use |PositionMoveType::CodePoint| to avoid | |
| 126 // ending paint at middle of character. | |
| 127 PositionInFlatTree end_position = | |
| 128 paint_block_cursor ? NextPositionOf(original_selection.Extent(), | |
| 129 PositionMoveType::kCodeUnit) | |
| 130 : end; | |
| 131 return SelectionInFlatTree::Builder() | |
| 132 .SetBaseAndExtent(start, end_position) | |
| 133 .Build(); | |
| 134 } | |
| 135 | |
| 136 const VisiblePositionInFlatTree& visible_start = CreateVisiblePosition( | |
| 137 start, selection_type == SelectionType::kRangeSelection | |
| 138 ? TextAffinity::kDownstream | |
| 139 : affinity); | |
| 140 if (visible_start.IsNull()) | |
| 141 return SelectionInFlatTree(); | |
| 142 if (paint_block_cursor) { | |
| 143 const VisiblePositionInFlatTree visible_extent = NextPositionOf( | |
| 144 CreateVisiblePosition(end, affinity), kCanSkipOverEditingBoundary); | |
| 145 if (visible_extent.IsNull()) | |
| 146 return SelectionInFlatTree(); | |
| 147 SelectionInFlatTree::Builder builder; | |
| 148 builder.Collapse(visible_start.ToPositionWithAffinity()); | |
| 149 builder.Extend(visible_extent.DeepEquivalent()); | |
| 150 return builder.Build(); | |
| 151 } | |
| 152 const VisiblePositionInFlatTree visible_end = CreateVisiblePosition( | |
| 153 end, selection_type == SelectionType::kRangeSelection | |
| 154 ? TextAffinity::kUpstream | |
| 155 : affinity); | |
| 156 if (visible_end.IsNull()) | |
| 157 return SelectionInFlatTree(); | |
| 158 SelectionInFlatTree::Builder builder; | |
| 159 builder.Collapse(visible_start.ToPositionWithAffinity()); | |
| 160 builder.Extend(visible_end.DeepEquivalent()); | |
| 161 return builder.Build(); | |
| 162 } | 121 } |
| 163 | 122 |
| 123 static VisibleSelectionInFlatTree CalcSelection( |
| 124 const FrameSelection& frame_selection) { |
| 125 const VisibleSelectionInFlatTree& original_selection = |
| 126 frame_selection.ComputeVisibleSelectionInFlatTree(); |
| 164 | 127 |
| 128 if (!ShouldShowBlockCursor(frame_selection, original_selection)) |
| 129 return original_selection; |
| 130 |
| 131 const PositionInFlatTree end_position = NextPositionOf( |
| 132 original_selection.Start(), PositionMoveType::kGraphemeCluster); |
| 133 return CreateVisibleSelection( |
| 134 SelectionInFlatTree::Builder() |
| 135 .SetBaseAndExtent(original_selection.Start(), end_position) |
| 136 .Build()); |
| 137 } |
| 165 | 138 |
| 166 // Objects each have a single selection rect to examine. | 139 // Objects each have a single selection rect to examine. |
| 167 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>; | 140 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>; |
| 168 // Blocks contain selected objects and fill gaps between them, either on the | 141 // Blocks contain selected objects and fill gaps between them, either on the |
| 169 // left, right, or in between lines and blocks. | 142 // left, right, or in between lines and blocks. |
| 170 // In order to get the visual rect right, we have to examine left, middle, and | 143 // In order to get the visual rect right, we have to examine left, middle, and |
| 171 // right rects individually, since otherwise the union of those rects might | 144 // right rects individually, since otherwise the union of those rects might |
| 172 // remain the same even when changes have occurred. | 145 // remain the same even when changes have occurred. |
| 173 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>; | 146 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>; |
| 174 struct SelectedMap { | 147 struct SelectedMap { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 paint_range_ = SelectionPaintRange(); | 290 paint_range_ = SelectionPaintRange(); |
| 318 } | 291 } |
| 319 | 292 |
| 320 static SelectionPaintRange CalcSelectionPaintRange( | 293 static SelectionPaintRange CalcSelectionPaintRange( |
| 321 const FrameSelection& frame_selection) { | 294 const FrameSelection& frame_selection) { |
| 322 const SelectionInDOMTree& selection_in_dom = | 295 const SelectionInDOMTree& selection_in_dom = |
| 323 frame_selection.GetSelectionInDOMTree(); | 296 frame_selection.GetSelectionInDOMTree(); |
| 324 if (selection_in_dom.IsNone()) | 297 if (selection_in_dom.IsNone()) |
| 325 return SelectionPaintRange(); | 298 return SelectionPaintRange(); |
| 326 | 299 |
| 327 const VisibleSelectionInFlatTree& original_selection = | 300 const VisibleSelectionInFlatTree& selection = CalcSelection(frame_selection); |
| 328 frame_selection.ComputeVisibleSelectionInFlatTree(); | |
| 329 // Construct a new VisibleSolution, since visibleSelection() is not | |
| 330 // necessarily valid, and the following steps assume a valid selection. See | |
| 331 // <https://bugs.webkit.org/show_bug.cgi?id=69563> and | |
| 332 // <rdar://problem/10232866>. | |
| 333 const SelectionInFlatTree& new_selection = CalcSelection( | |
| 334 original_selection, frame_selection.ShouldShowBlockCursor()); | |
| 335 const VisibleSelectionInFlatTree& selection = | |
| 336 CreateVisibleSelection(new_selection); | |
| 337 | |
| 338 if (!selection.IsRange() || frame_selection.IsHidden()) | 301 if (!selection.IsRange() || frame_selection.IsHidden()) |
| 339 return SelectionPaintRange(); | 302 return SelectionPaintRange(); |
| 340 | 303 |
| 341 DCHECK(!selection.IsNone()); | 304 DCHECK(!selection.IsNone()); |
| 342 const PositionInFlatTree start_pos = selection.Start(); | 305 const PositionInFlatTree start_pos = selection.Start(); |
| 343 const PositionInFlatTree end_pos = selection.End(); | 306 const PositionInFlatTree end_pos = selection.End(); |
| 344 DCHECK_LE(start_pos, end_pos); | 307 DCHECK_LE(start_pos, end_pos); |
| 345 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); | 308 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); |
| 346 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); | 309 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); |
| 347 DCHECK(start_layout_object); | 310 DCHECK(start_layout_object); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 | 378 |
| 416 runner->SetShouldInvalidateSelection(); | 379 runner->SetShouldInvalidateSelection(); |
| 417 } | 380 } |
| 418 } | 381 } |
| 419 | 382 |
| 420 DEFINE_TRACE(LayoutSelection) { | 383 DEFINE_TRACE(LayoutSelection) { |
| 421 visitor->Trace(frame_selection_); | 384 visitor->Trace(frame_selection_); |
| 422 } | 385 } |
| 423 | 386 |
| 424 } // namespace blink | 387 } // namespace blink |
| OLD | NEW |