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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 new_selected_map.block_map.erase(block); | 285 new_selected_map.block_map.erase(block); |
286 } | 286 } |
287 } | 287 } |
288 | 288 |
289 // Any new blocks that remain were not found in the old blocks dict, and so | 289 // Any new blocks that remain were not found in the old blocks dict, and so |
290 // they need to be updated. | 290 // they need to be updated. |
291 for (auto layout_object : new_selected_map.block_map.Keys()) | 291 for (auto layout_object : new_selected_map.block_map.Keys()) |
292 layout_object->SetShouldInvalidateSelection(); | 292 layout_object->SetShouldInvalidateSelection(); |
293 } | 293 } |
294 | 294 |
295 static LayoutBlockFlow* MostRecentLayoutBlockFlow(LayoutObject* layout_object) { | |
296 for (LayoutObject* runner = layout_object; runner && !runner->IsLayoutView(); | |
297 runner = runner->ContainingBlock()) { | |
kojii
2017/06/21 10:10:09
Parent()
| |
298 if (runner->IsLayoutBlockFlow()) | |
299 return ToLayoutBlockFlow(runner); | |
300 } | |
301 return nullptr; | |
302 } | |
303 | |
304 static int GetOffsetInMixedTree(LayoutObject* layout_object, int offset) { | |
305 LayoutBlockFlow* start_block_flow = MostRecentLayoutBlockFlow(layout_object); | |
306 if (!start_block_flow || !start_block_flow->IsLayoutNGBlockFlow()) | |
307 return offset; // Legay. Return DOM offset; | |
308 | |
309 // TODO(yoichio): How about caching? Create takes | |
310 // O(<LayoutNGBlockflow.Data.text_content_>). | |
311 const NGTextOffsetMap& offset_map = | |
312 NGTextOffsetMap::Create(*ToLayoutNGBlockFlowOrDie(start_block_flow)); | |
313 const Optional<int> ng_offset = | |
314 offset_map.Get(layout_object->GetNode(), offset); | |
315 return ng_offset.value(); | |
316 } | |
317 | |
295 std::pair<int, int> LayoutSelection::SelectionStartEnd() { | 318 std::pair<int, int> LayoutSelection::SelectionStartEnd() { |
296 Commit(); | 319 Commit(); |
297 if (paint_range_.IsNull()) | 320 if (paint_range_.IsNull()) |
298 return std::make_pair(-1, -1); | 321 return std::make_pair(-1, -1); |
299 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); | 322 if (!RuntimeEnabledFeatures::LayoutNGEnabled()) { |
323 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); | |
324 } | |
325 // Layout NG mapping | |
326 const int start_offset_mixed = GetOffsetInMixedTree( | |
327 paint_range_.StartLayoutObject(), paint_range_.StartOffset()); | |
328 const int end_offset_mixed = GetOffsetInMixedTree( | |
329 paint_range_.EndLayoutObject(), paint_range_.EndOffset()); | |
330 return std::make_pair(start_offset_mixed, end_offset_mixed); | |
300 } | 331 } |
301 | 332 |
302 void LayoutSelection::ClearSelection() { | 333 void LayoutSelection::ClearSelection() { |
303 // For querying Layer::compositingState() | 334 // For querying Layer::compositingState() |
304 // This is correct, since destroying layout objects needs to cause eager paint | 335 // This is correct, since destroying layout objects needs to cause eager paint |
305 // invalidations. | 336 // invalidations. |
306 DisableCompositingQueryAsserts disabler; | 337 DisableCompositingQueryAsserts disabler; |
307 | 338 |
308 // Just return if the selection is already empty. | 339 // Just return if the selection is already empty. |
309 if (paint_range_.IsNull()) | 340 if (paint_range_.IsNull()) |
310 return; | 341 return; |
311 | 342 |
312 for (auto layout_object : paint_range_) { | 343 for (auto layout_object : paint_range_) { |
313 const SelectionState old_state = layout_object->GetSelectionState(); | 344 const SelectionState old_state = layout_object->GetSelectionState(); |
314 layout_object->SetSelectionStateIfNeeded(SelectionState::kNone); | 345 layout_object->SetSelectionStateIfNeeded(SelectionState::kNone); |
315 if (layout_object->GetSelectionState() == old_state) | 346 if (layout_object->GetSelectionState() == old_state) |
316 continue; | 347 continue; |
317 layout_object->SetShouldInvalidateSelection(); | 348 layout_object->SetShouldInvalidateSelection(); |
318 } | 349 } |
319 | 350 |
320 // Reset selection. | 351 // Reset selection. |
321 paint_range_ = SelectionPaintRange(); | 352 paint_range_ = SelectionPaintRange(); |
322 } | 353 } |
323 | 354 |
355 static SelectionPaintRange CalcSelectionNG( | |
yoichio
2017/06/27 07:54:52
Its strange that we have 3 code pass for legacy, n
| |
356 const FrameSelection& frame_selection) { | |
357 const SelectionInDOMTree& selection_in_dom = | |
358 frame_selection.GetSelectionInDOMTree(); | |
359 if (selection_in_dom.IsNone()) | |
360 return SelectionPaintRange(); | |
361 | |
362 // yoichio: Tthis should be on FlatTree. | |
363 const Position& start = selection_in_dom.ComputeStartPosition(); | |
364 const Position& end = selection_in_dom.ComputeEndPosition(); | |
365 LayoutObject* const start_layout_object = | |
366 start.AnchorNode()->GetLayoutObject(); | |
367 LayoutObject* const end_layout_object = end.AnchorNode()->GetLayoutObject(); | |
368 | |
369 Node* start_node = nullptr; | |
370 LayoutObject* paint_range_start = nullptr; | |
371 int paint_range_start_offset = -1; | |
372 // Seek the first text node. | |
373 for (LayoutObject* runner = start_layout_object; | |
374 runner && runner != end_layout_object->NextInPreOrder(); | |
375 runner = runner->NextInPreOrder()) { | |
376 if (runner->IsText() && runner->GetNode()->IsTextNode()) { | |
yoichio
2017/06/27 07:54:52
LayoutText will gone.
| |
377 start_node = runner->GetNode(); | |
378 paint_range_start = runner; | |
379 if (runner == start_layout_object) { | |
380 paint_range_start_offset = start.ComputeEditingOffset(); | |
381 break; | |
382 } | |
383 paint_range_start_offset = 0; | |
384 break; | |
385 } | |
yoichio
2017/06/27 07:54:52
br is LayouObject.isText().
| |
386 } | |
387 DCHECK(paint_range_start); | |
388 // Should consider block cursor painting. | |
389 Node* end_node = nullptr; | |
390 LayoutObject* paint_range_end = nullptr; | |
391 int paint_range_end_offset = -1; | |
392 for (LayoutObject* runner = end_layout_object; | |
393 runner && runner != start_layout_object->PreviousInPreOrder(); | |
394 runner = runner->PreviousInPreOrder()) { | |
395 if (runner->IsText() && runner->GetNode()->IsTextNode()) { | |
396 end_node = runner->GetNode(); | |
397 paint_range_end = runner; | |
398 if (runner == end_layout_object) { | |
399 paint_range_end_offset = end.ComputeEditingOffset(); | |
400 break; | |
401 } | |
402 LayoutText* text = ToLayoutText(runner); | |
403 paint_range_end_offset = text->TextLength(); | |
404 break; | |
405 } | |
406 } | |
407 DCHECK(paint_range_end); | |
408 | |
409 return SelectionPaintRange(paint_range_start, paint_range_start_offset, | |
410 paint_range_end, paint_range_end_offset); | |
411 } | |
412 | |
324 static SelectionPaintRange CalcSelectionPaintRange( | 413 static SelectionPaintRange CalcSelectionPaintRange( |
325 const FrameSelection& frame_selection) { | 414 const FrameSelection& frame_selection) { |
326 const SelectionInDOMTree& selection_in_dom = | 415 const SelectionInDOMTree& selection_in_dom = |
327 frame_selection.GetSelectionInDOMTree(); | 416 frame_selection.GetSelectionInDOMTree(); |
328 if (selection_in_dom.IsNone()) | 417 if (selection_in_dom.IsNone()) |
329 return SelectionPaintRange(); | 418 return SelectionPaintRange(); |
330 | 419 |
420 if (RuntimeEnabledFeatures::LayoutNGEnabled()) | |
421 return CalcSelectionNG(frame_selection); | |
422 | |
423 // NGMemo: ComputeVisibleSelectionInFlatTree depends on offsetmapping from | |
424 // DOM->NG. | |
331 const VisibleSelectionInFlatTree& original_selection = | 425 const VisibleSelectionInFlatTree& original_selection = |
332 frame_selection.ComputeVisibleSelectionInFlatTree(); | 426 frame_selection.ComputeVisibleSelectionInFlatTree(); |
333 // Construct a new VisibleSolution, since visibleSelection() is not | 427 // Construct a new VisibleSolution, since visibleSelection() is not |
334 // necessarily valid, and the following steps assume a valid selection. See | 428 // necessarily valid, and the following steps assume a valid selection. See |
335 // <https://bugs.webkit.org/show_bug.cgi?id=69563> and | 429 // <https://bugs.webkit.org/show_bug.cgi?id=69563> and |
336 // <rdar://problem/10232866>. | 430 // <rdar://problem/10232866>. |
337 const SelectionInFlatTree& new_selection = CalcSelection( | 431 const SelectionInFlatTree& new_selection = CalcSelection( |
338 original_selection, frame_selection.ShouldShowBlockCursor()); | 432 original_selection, frame_selection.ShouldShowBlockCursor()); |
339 const VisibleSelectionInFlatTree& selection = | 433 const VisibleSelectionInFlatTree& selection = |
340 CreateVisibleSelection(new_selection); | 434 CreateVisibleSelection(new_selection); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 int ng_offset = offset_mapping[begin + i - 1]; | 582 int ng_offset = offset_mapping[begin + i - 1]; |
489 builder.Add(text, i, ng_offset); | 583 builder.Add(text, i, ng_offset); |
490 } | 584 } |
491 | 585 |
492 last_object = layout_object; | 586 last_object = layout_object; |
493 } | 587 } |
494 return builder.Build(); | 588 return builder.Build(); |
495 } | 589 } |
496 | 590 |
497 } // namespace blink | 591 } // namespace blink |
OLD | NEW |