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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 SelectedMap() = default; | 155 SelectedMap() = default; |
156 SelectedMap(SelectedMap&& other) { | 156 SelectedMap(SelectedMap&& other) { |
157 object_map = std::move(other.object_map); | 157 object_map = std::move(other.object_map); |
158 block_map = std::move(other.block_map); | 158 block_map = std::move(other.block_map); |
159 } | 159 } |
160 | 160 |
161 private: | 161 private: |
162 DISALLOW_COPY_AND_ASSIGN(SelectedMap); | 162 DISALLOW_COPY_AND_ASSIGN(SelectedMap); |
163 }; | 163 }; |
164 | 164 |
165 static SelectedMap CollectSelectedMap( | 165 enum class CollectSelectedMapOption { |
166 const SelectionPaintRange& range, | 166 kCollectBlock, |
167 LayoutSelection::SelectionPaintInvalidationMode | 167 kNotCollectBlock, |
168 block_paint_invalidation_mode) { | 168 }; |
169 static SelectedMap CollectSelectedMap(const SelectionPaintRange& range, | |
yosin_UTC9
2017/05/29 07:59:37
nit: Could you add a blank line between enum and f
yoichio
2017/05/30 04:15:03
Done.
| |
170 CollectSelectedMapOption option) { | |
169 if (range.IsNull()) | 171 if (range.IsNull()) |
170 return SelectedMap(); | 172 return SelectedMap(); |
171 | 173 |
172 SelectedMap selected_map; | 174 SelectedMap selected_map; |
173 | 175 |
174 LayoutObject* const stop = | 176 LayoutObject* const stop = |
175 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); | 177 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); |
176 for (LayoutObject* runner = range.StartLayoutObject(); | 178 for (LayoutObject* runner = range.StartLayoutObject(); |
177 runner && (runner != stop); runner = runner->NextInPreOrder()) { | 179 runner && (runner != stop); runner = runner->NextInPreOrder()) { |
178 if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() && | 180 if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() && |
179 runner != range.EndLayoutObject()) | 181 runner != range.EndLayoutObject()) |
180 continue; | 182 continue; |
181 if (runner->GetSelectionState() == SelectionNone) | 183 if (runner->GetSelectionState() == SelectionNone) |
182 continue; | 184 continue; |
183 | 185 |
184 // Blocks are responsible for painting line gaps and margin gaps. They | 186 // Blocks are responsible for painting line gaps and margin gaps. They |
185 // must be examined as well. | 187 // must be examined as well. |
186 selected_map.object_map.Set(runner, runner->GetSelectionState()); | 188 selected_map.object_map.Set(runner, runner->GetSelectionState()); |
187 if (block_paint_invalidation_mode == | 189 if (option == CollectSelectedMapOption::kCollectBlock) { |
188 LayoutSelection::kPaintInvalidationNewXOROld) { | |
189 LayoutBlock* containing_block = runner->ContainingBlock(); | 190 LayoutBlock* containing_block = runner->ContainingBlock(); |
190 while (containing_block && !containing_block->IsLayoutView()) { | 191 while (containing_block && !containing_block->IsLayoutView()) { |
191 SelectedBlockMap::AddResult result = selected_map.block_map.insert( | 192 SelectedBlockMap::AddResult result = selected_map.block_map.insert( |
192 containing_block, containing_block->GetSelectionState()); | 193 containing_block, containing_block->GetSelectionState()); |
193 if (!result.is_new_entry) | 194 if (!result.is_new_entry) |
194 break; | 195 break; |
195 containing_block = containing_block->ContainingBlock(); | 196 containing_block = containing_block->ContainingBlock(); |
196 } | 197 } |
197 } | 198 } |
198 } | 199 } |
(...skipping 15 matching lines...) Expand all Loading... | |
214 LayoutObject* const stop = | 215 LayoutObject* const stop = |
215 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); | 216 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); |
216 for (LayoutObject* runner = range.StartLayoutObject(); | 217 for (LayoutObject* runner = range.StartLayoutObject(); |
217 runner && runner != stop; runner = runner->NextInPreOrder()) { | 218 runner && runner != stop; runner = runner->NextInPreOrder()) { |
218 if (runner != range.StartLayoutObject() && | 219 if (runner != range.StartLayoutObject() && |
219 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf()) | 220 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf()) |
220 runner->SetSelectionStateIfNeeded(SelectionInside); | 221 runner->SetSelectionStateIfNeeded(SelectionInside); |
221 } | 222 } |
222 } | 223 } |
223 | 224 |
224 void LayoutSelection::SetSelection( | 225 static void SetSelectionStateAndShouldInvalidateSelection( |
yosin_UTC9
2017/05/29 07:59:37
nit: s/SetSelectionStateAndShouldInvalidateSelecti
yoichio
2017/05/29 08:36:26
Fmm, actually we don't invalidate LayoutObject yet
yosin_UTC9
2017/05/29 09:38:15
How about SetSelectionStateAndPaintInvalidationFla
yoichio
2017/05/30 04:15:03
Sine this is a local function and used only once,
| |
225 const SelectionPaintRange& new_range, | 226 const SelectionPaintRange& new_range, |
226 SelectionPaintInvalidationMode block_paint_invalidation_mode) { | 227 const SelectionPaintRange& old_range) { |
227 DCHECK(!new_range.IsNull()); | |
228 | |
229 // Just return if the selection hasn't changed. | |
230 if (paint_range_ == new_range) | |
231 return; | |
232 | |
233 DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView()); | |
234 DCHECK(!frame_selection_->GetDocument().NeedsLayoutTreeUpdate()); | |
235 | |
236 SelectedMap old_selected_map = | 228 SelectedMap old_selected_map = |
237 CollectSelectedMap(paint_range_, block_paint_invalidation_mode); | 229 CollectSelectedMap(old_range, CollectSelectedMapOption::kCollectBlock); |
238 | 230 |
239 // Now clear the selection. | 231 // Now clear the selection. |
240 for (auto layout_object : old_selected_map.object_map.Keys()) | 232 for (auto layout_object : old_selected_map.object_map.Keys()) |
241 layout_object->SetSelectionStateIfNeeded(SelectionNone); | 233 layout_object->SetSelectionStateIfNeeded(SelectionNone); |
242 | 234 |
243 SetSelectionState(new_range); | 235 SetSelectionState(new_range); |
244 | 236 |
245 // Now that the selection state has been updated for the new objects, walk | 237 // Now that the selection state has been updated for the new objects, walk |
246 // them again and put them in the new objects list. | 238 // them again and put them in the new objects list. |
247 // TODO(editing-dev): |new_selected_map| doesn't really need to store the | 239 // TODO(editing-dev): |new_selected_map| doesn't really need to store the |
248 // SelectionState, it's just more convenient to have it use the same data | 240 // SelectionState, it's just more convenient to have it use the same data |
249 // structure as |old_selected_map|. | 241 // structure as |old_selected_map|. |
250 SelectedMap new_selected_map = | 242 SelectedMap new_selected_map = |
251 CollectSelectedMap(new_range, kPaintInvalidationNewXOROld); | 243 CollectSelectedMap(new_range, CollectSelectedMapOption::kCollectBlock); |
252 | 244 |
253 // Have any of the old selected objects changed compared to the new selection? | 245 // Have any of the old selected objects changed compared to the new selection? |
254 for (const auto& pair : old_selected_map.object_map) { | 246 for (const auto& pair : old_selected_map.object_map) { |
255 LayoutObject* obj = pair.key; | 247 LayoutObject* obj = pair.key; |
256 SelectionState new_selection_state = obj->GetSelectionState(); | 248 SelectionState new_selection_state = obj->GetSelectionState(); |
257 SelectionState old_selection_state = pair.value; | 249 SelectionState old_selection_state = pair.value; |
258 if (new_selection_state != old_selection_state || | 250 if (new_selection_state != old_selection_state || |
259 (new_range.StartLayoutObject() == obj && | 251 (new_range.StartLayoutObject() == obj && |
260 new_range.StartOffset() != paint_range_.StartOffset()) || | 252 new_range.StartOffset() != old_range.StartOffset()) || |
261 (new_range.EndLayoutObject() == obj && | 253 (new_range.EndLayoutObject() == obj && |
262 new_range.EndOffset() != paint_range_.EndOffset())) { | 254 new_range.EndOffset() != old_range.EndOffset())) { |
263 obj->SetShouldInvalidateSelection(); | 255 obj->SetShouldInvalidateSelection(); |
264 new_selected_map.object_map.erase(obj); | 256 new_selected_map.object_map.erase(obj); |
265 } | 257 } |
266 } | 258 } |
267 | 259 |
268 // Any new objects that remain were not found in the old objects dict, and so | 260 // Any new objects that remain were not found in the old objects dict, and so |
269 // they need to be updated. | 261 // they need to be updated. |
270 for (auto layout_object : new_selected_map.object_map.Keys()) | 262 for (auto layout_object : new_selected_map.object_map.Keys()) |
271 layout_object->SetShouldInvalidateSelection(); | 263 layout_object->SetShouldInvalidateSelection(); |
272 | 264 |
273 // Have any of the old blocks changed? | 265 // Have any of the old blocks changed? |
274 for (const auto& pair : old_selected_map.block_map) { | 266 for (const auto& pair : old_selected_map.block_map) { |
275 LayoutBlock* block = pair.key; | 267 LayoutBlock* block = pair.key; |
276 SelectionState new_selection_state = block->GetSelectionState(); | 268 SelectionState new_selection_state = block->GetSelectionState(); |
277 SelectionState old_selection_state = pair.value; | 269 SelectionState old_selection_state = pair.value; |
278 if (new_selection_state != old_selection_state) { | 270 if (new_selection_state != old_selection_state) { |
279 block->SetShouldInvalidateSelection(); | 271 block->SetShouldInvalidateSelection(); |
280 new_selected_map.block_map.erase(block); | 272 new_selected_map.block_map.erase(block); |
281 } | 273 } |
282 } | 274 } |
283 | 275 |
284 // Any new blocks that remain were not found in the old blocks dict, and so | 276 // Any new blocks that remain were not found in the old blocks dict, and so |
285 // they need to be updated. | 277 // they need to be updated. |
286 for (auto layout_object : new_selected_map.block_map.Keys()) | 278 for (auto layout_object : new_selected_map.block_map.Keys()) |
287 layout_object->SetShouldInvalidateSelection(); | 279 layout_object->SetShouldInvalidateSelection(); |
288 | |
289 paint_range_ = new_range; | |
290 } | 280 } |
291 | 281 |
292 std::pair<int, int> LayoutSelection::SelectionStartEnd() { | 282 std::pair<int, int> LayoutSelection::SelectionStartEnd() { |
293 Commit(); | 283 Commit(); |
294 if (paint_range_.IsNull()) | 284 if (paint_range_.IsNull()) |
295 return std::make_pair(-1, -1); | 285 return std::make_pair(-1, -1); |
296 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); | 286 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); |
297 } | 287 } |
298 | 288 |
299 void LayoutSelection::ClearSelection() { | 289 void LayoutSelection::ClearSelection() { |
300 // For querying Layer::compositingState() | 290 // For querying Layer::compositingState() |
301 // This is correct, since destroying layout objects needs to cause eager paint | 291 // This is correct, since destroying layout objects needs to cause eager paint |
302 // invalidations. | 292 // invalidations. |
303 DisableCompositingQueryAsserts disabler; | 293 DisableCompositingQueryAsserts disabler; |
304 | 294 |
305 // Just return if the selection is already empty. | 295 // Just return if the selection is already empty. |
306 if (paint_range_.IsNull()) | 296 if (paint_range_.IsNull()) |
307 return; | 297 return; |
308 | 298 |
309 const SelectedMap& old_selected_map = | 299 const SelectedMap& old_selected_map = CollectSelectedMap( |
310 CollectSelectedMap(paint_range_, kPaintInvalidationNewMinusOld); | 300 paint_range_, CollectSelectedMapOption::kNotCollectBlock); |
311 // Clear SelectionState and invalidation. | 301 // Clear SelectionState and invalidation. |
312 for (auto layout_object : old_selected_map.object_map.Keys()) { | 302 for (auto layout_object : old_selected_map.object_map.Keys()) { |
313 const SelectionState old_state = layout_object->GetSelectionState(); | 303 const SelectionState old_state = layout_object->GetSelectionState(); |
314 layout_object->SetSelectionStateIfNeeded(SelectionNone); | 304 layout_object->SetSelectionStateIfNeeded(SelectionNone); |
315 if (layout_object->GetSelectionState() == old_state) | 305 if (layout_object->GetSelectionState() == old_state) |
316 continue; | 306 continue; |
317 layout_object->SetShouldInvalidateSelection(); | 307 layout_object->SetShouldInvalidateSelection(); |
318 } | 308 } |
319 | 309 |
320 // Reset selection. | 310 // Reset selection. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 if (start_pos.IsNull() || end_pos.IsNull() || | 352 if (start_pos.IsNull() || end_pos.IsNull() || |
363 selection.VisibleStart().DeepEquivalent() == | 353 selection.VisibleStart().DeepEquivalent() == |
364 selection.VisibleEnd().DeepEquivalent()) | 354 selection.VisibleEnd().DeepEquivalent()) |
365 return; | 355 return; |
366 DCHECK_LE(start_pos, end_pos); | 356 DCHECK_LE(start_pos, end_pos); |
367 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); | 357 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); |
368 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); | 358 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); |
369 if (!start_layout_object || !end_layout_object) | 359 if (!start_layout_object || !end_layout_object) |
370 return; | 360 return; |
371 DCHECK(start_layout_object->View() == end_layout_object->View()); | 361 DCHECK(start_layout_object->View() == end_layout_object->View()); |
372 SetSelection( | 362 |
373 SelectionPaintRange(start_layout_object, start_pos.ComputeEditingOffset(), | 363 SelectionPaintRange new_range( |
374 end_layout_object, end_pos.ComputeEditingOffset())); | 364 start_layout_object, start_pos.ComputeEditingOffset(), end_layout_object, |
365 end_pos.ComputeEditingOffset()); | |
366 // Just return if the selection hasn't changed. | |
367 if (paint_range_ == new_range) | |
368 return; | |
369 | |
370 DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView()); | |
371 DCHECK(!frame_selection_->GetDocument().NeedsLayoutTreeUpdate()); | |
372 SetSelectionStateAndShouldInvalidateSelection(new_range, paint_range_); | |
373 paint_range_ = new_range; | |
375 } | 374 } |
376 | 375 |
377 void LayoutSelection::OnDocumentShutdown() { | 376 void LayoutSelection::OnDocumentShutdown() { |
378 has_pending_selection_ = false; | 377 has_pending_selection_ = false; |
379 paint_range_ = SelectionPaintRange(); | 378 paint_range_ = SelectionPaintRange(); |
380 } | 379 } |
381 | 380 |
382 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { | 381 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { |
383 if (!object->IsRooted()) | 382 if (!object->IsRooted()) |
384 return LayoutRect(); | 383 return LayoutRect(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
443 | 442 |
444 o->SetShouldInvalidateSelection(); | 443 o->SetShouldInvalidateSelection(); |
445 } | 444 } |
446 } | 445 } |
447 | 446 |
448 DEFINE_TRACE(LayoutSelection) { | 447 DEFINE_TRACE(LayoutSelection) { |
449 visitor->Trace(frame_selection_); | 448 visitor->Trace(frame_selection_); |
450 } | 449 } |
451 | 450 |
452 } // namespace blink | 451 } // namespace blink |
OLD | NEW |