Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(750)

Side by Side Diff: third_party/WebKit/Source/core/editing/VisibleUnits.cpp

Issue 2908083002: Move LeftWordPosition/RightWordPosition() to SelectionModifierWord.cpp (Closed)
Patch Set: 2017-05-29T16:51:51 Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/editing/VisibleUnits.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 if (!highest_root) 192 if (!highest_root)
193 return PositionWithAffinityTemplate<Strategy>(); 193 return PositionWithAffinityTemplate<Strategy>();
194 194
195 // Return the last position before |pos| that is in the same editable region 195 // Return the last position before |pos| that is in the same editable region
196 // as this position 196 // as this position
197 return LastEditablePositionBeforePositionInRoot(pos.GetPosition(), 197 return LastEditablePositionBeforePositionInRoot(pos.GetPosition(),
198 *highest_root); 198 *highest_root);
199 } 199 }
200 200
201 template <typename Strategy> 201 template <typename Strategy>
202 static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrBefore( 202 VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrBeforeAlgorithm(
203 const VisiblePositionTemplate<Strategy>& pos, 203 const VisiblePositionTemplate<Strategy>& pos,
204 const PositionTemplate<Strategy>& anchor) { 204 const PositionTemplate<Strategy>& anchor) {
205 DCHECK(pos.IsValid()) << pos; 205 DCHECK(pos.IsValid()) << pos;
206 return CreateVisiblePosition( 206 return CreateVisiblePosition(
207 HonorEditingBoundaryAtOrBefore(pos.ToPositionWithAffinity(), anchor)); 207 HonorEditingBoundaryAtOrBefore(pos.ToPositionWithAffinity(), anchor));
208 } 208 }
209 209
210 VisiblePosition HonorEditingBoundaryAtOrBefore(
211 const VisiblePosition& visiblePosition,
212 const Position& anchor) {
213 return HonorEditingBoundaryAtOrBeforeAlgorithm(visiblePosition, anchor);
214 }
215
216 VisiblePositionInFlatTree HonorEditingBoundaryAtOrBefore(
217 const VisiblePositionInFlatTree& visiblePosition,
218 const PositionInFlatTree& anchor) {
219 return HonorEditingBoundaryAtOrBeforeAlgorithm(visiblePosition, anchor);
220 }
221
210 template <typename Strategy> 222 template <typename Strategy>
211 static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrAfter( 223 static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrAfter(
212 const VisiblePositionTemplate<Strategy>& pos, 224 const VisiblePositionTemplate<Strategy>& pos,
213 const PositionTemplate<Strategy>& anchor) { 225 const PositionTemplate<Strategy>& anchor) {
214 DCHECK(pos.IsValid()) << pos; 226 DCHECK(pos.IsValid()) << pos;
215 if (pos.IsNull()) 227 if (pos.IsNull())
216 return pos; 228 return pos;
217 229
218 ContainerNode* highest_root = HighestEditableRoot(anchor); 230 ContainerNode* highest_root = HighestEditableRoot(anchor);
219 231
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 node = NextAtomicLeafNode(*node); 322 node = NextAtomicLeafNode(*node);
311 while (node) { 323 while (node) {
312 if (editable == HasEditableStyle(*node, editable_type)) 324 if (editable == HasEditableStyle(*node, editable_type))
313 return node; 325 return node;
314 node = NextAtomicLeafNode(*node); 326 node = NextAtomicLeafNode(*node);
315 } 327 }
316 return 0; 328 return 0;
317 } 329 }
318 330
319 // FIXME: consolidate with code in previousLinePosition. 331 // FIXME: consolidate with code in previousLinePosition.
320 static Position PreviousRootInlineBoxCandidatePosition( 332 Position PreviousRootInlineBoxCandidatePosition(
321 Node* node, 333 Node* node,
322 const VisiblePosition& visible_position, 334 const VisiblePosition& visible_position,
323 EditableType editable_type) { 335 EditableType editable_type) {
324 DCHECK(visible_position.IsValid()) << visible_position; 336 DCHECK(visible_position.IsValid()) << visible_position;
325 ContainerNode* highest_root = 337 ContainerNode* highest_root =
326 HighestEditableRoot(visible_position.DeepEquivalent(), editable_type); 338 HighestEditableRoot(visible_position.DeepEquivalent(), editable_type);
327 Node* previous_node = PreviousLeafWithSameEditability(node, editable_type); 339 Node* previous_node = PreviousLeafWithSameEditability(node, editable_type);
328 340
329 while (previous_node && 341 while (previous_node &&
330 (!previous_node->GetLayoutObject() || 342 (!previous_node->GetLayoutObject() ||
(...skipping 15 matching lines...) Expand all
346 358
347 if (IsVisuallyEquivalentCandidate(pos)) 359 if (IsVisuallyEquivalentCandidate(pos))
348 return pos; 360 return pos;
349 361
350 previous_node = 362 previous_node =
351 PreviousLeafWithSameEditability(previous_node, editable_type); 363 PreviousLeafWithSameEditability(previous_node, editable_type);
352 } 364 }
353 return Position(); 365 return Position();
354 } 366 }
355 367
356 static Position NextRootInlineBoxCandidatePosition( 368 Position NextRootInlineBoxCandidatePosition(
357 Node* node, 369 Node* node,
358 const VisiblePosition& visible_position, 370 const VisiblePosition& visible_position,
359 EditableType editable_type) { 371 EditableType editable_type) {
360 DCHECK(visible_position.IsValid()) << visible_position; 372 DCHECK(visible_position.IsValid()) << visible_position;
361 ContainerNode* highest_root = 373 ContainerNode* highest_root =
362 HighestEditableRoot(visible_position.DeepEquivalent(), editable_type); 374 HighestEditableRoot(visible_position.DeepEquivalent(), editable_type);
363 Node* next_node = NextLeafWithSameEditability(node, editable_type); 375 Node* next_node = NextLeafWithSameEditability(node, editable_type);
364 while (next_node && (!next_node->GetLayoutObject() || 376 while (next_node && (!next_node->GetLayoutObject() ||
365 InSameLine(CreateVisiblePosition( 377 InSameLine(CreateVisiblePosition(
366 FirstPositionInOrBeforeNode(next_node)), 378 FirstPositionInOrBeforeNode(next_node)),
367 visible_position))) 379 visible_position)))
368 next_node = NextLeafWithSameEditability(next_node, kContentIsEditable); 380 next_node = NextLeafWithSameEditability(next_node, kContentIsEditable);
369 381
370 while (next_node && !next_node->IsShadowRoot()) { 382 while (next_node && !next_node->IsShadowRoot()) {
371 if (HighestEditableRoot(FirstPositionInOrBeforeNode(next_node), 383 if (HighestEditableRoot(FirstPositionInOrBeforeNode(next_node),
372 editable_type) != highest_root) 384 editable_type) != highest_root)
373 break; 385 break;
374 386
375 Position pos; 387 Position pos;
376 pos = Position::EditingPositionOf(next_node, CaretMinOffset(next_node)); 388 pos = Position::EditingPositionOf(next_node, CaretMinOffset(next_node));
377 389
378 if (IsVisuallyEquivalentCandidate(pos)) 390 if (IsVisuallyEquivalentCandidate(pos))
379 return pos; 391 return pos;
380 392
381 next_node = NextLeafWithSameEditability(next_node, editable_type); 393 next_node = NextLeafWithSameEditability(next_node, editable_type);
382 } 394 }
383 return Position(); 395 return Position();
384 } 396 }
385 397
386 class CachedLogicallyOrderedLeafBoxes {
387 public:
388 CachedLogicallyOrderedLeafBoxes();
389
390 const InlineTextBox* PreviousTextBox(const RootInlineBox*,
391 const InlineTextBox*);
392 const InlineTextBox* NextTextBox(const RootInlineBox*, const InlineTextBox*);
393
394 size_t size() const { return leaf_boxes_.size(); }
395 const InlineBox* FirstBox() const { return leaf_boxes_[0]; }
396
397 private:
398 const Vector<InlineBox*>& CollectBoxes(const RootInlineBox*);
399 int BoxIndexInLeaves(const InlineTextBox*) const;
400
401 const RootInlineBox* root_inline_box_;
402 Vector<InlineBox*> leaf_boxes_;
403 };
404
405 CachedLogicallyOrderedLeafBoxes::CachedLogicallyOrderedLeafBoxes()
406 : root_inline_box_(0) {}
407
408 const InlineTextBox* CachedLogicallyOrderedLeafBoxes::PreviousTextBox(
409 const RootInlineBox* root,
410 const InlineTextBox* box) {
411 if (!root)
412 return 0;
413
414 CollectBoxes(root);
415
416 // If box is null, root is box's previous RootInlineBox, and previousBox is
417 // the last logical box in root.
418 int box_index = leaf_boxes_.size() - 1;
419 if (box)
420 box_index = BoxIndexInLeaves(box) - 1;
421
422 for (int i = box_index; i >= 0; --i) {
423 if (leaf_boxes_[i]->IsInlineTextBox())
424 return ToInlineTextBox(leaf_boxes_[i]);
425 }
426
427 return 0;
428 }
429
430 const InlineTextBox* CachedLogicallyOrderedLeafBoxes::NextTextBox(
431 const RootInlineBox* root,
432 const InlineTextBox* box) {
433 if (!root)
434 return 0;
435
436 CollectBoxes(root);
437
438 // If box is null, root is box's next RootInlineBox, and nextBox is the first
439 // logical box in root. Otherwise, root is box's RootInlineBox, and nextBox is
440 // the next logical box in the same line.
441 size_t next_box_index = 0;
442 if (box)
443 next_box_index = BoxIndexInLeaves(box) + 1;
444
445 for (size_t i = next_box_index; i < leaf_boxes_.size(); ++i) {
446 if (leaf_boxes_[i]->IsInlineTextBox())
447 return ToInlineTextBox(leaf_boxes_[i]);
448 }
449
450 return 0;
451 }
452
453 const Vector<InlineBox*>& CachedLogicallyOrderedLeafBoxes::CollectBoxes(
454 const RootInlineBox* root) {
455 if (root_inline_box_ != root) {
456 root_inline_box_ = root;
457 leaf_boxes_.clear();
458 root->CollectLeafBoxesInLogicalOrder(leaf_boxes_);
459 }
460 return leaf_boxes_;
461 }
462
463 int CachedLogicallyOrderedLeafBoxes::BoxIndexInLeaves(
464 const InlineTextBox* box) const {
465 for (size_t i = 0; i < leaf_boxes_.size(); ++i) {
466 if (box == leaf_boxes_[i])
467 return i;
468 }
469 return 0;
470 }
471
472 static const InlineTextBox* LogicallyPreviousBox(
473 const VisiblePosition& visible_position,
474 const InlineTextBox* text_box,
475 bool& previous_box_in_different_block,
476 CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
477 DCHECK(visible_position.IsValid()) << visible_position;
478 const InlineBox* start_box = text_box;
479
480 const InlineTextBox* previous_box =
481 leaf_boxes.PreviousTextBox(&start_box->Root(), text_box);
482 if (previous_box)
483 return previous_box;
484
485 previous_box = leaf_boxes.PreviousTextBox(start_box->Root().PrevRootBox(), 0);
486 if (previous_box)
487 return previous_box;
488
489 while (1) {
490 Node* start_node = start_box->GetLineLayoutItem().NonPseudoNode();
491 if (!start_node)
492 break;
493
494 Position position = PreviousRootInlineBoxCandidatePosition(
495 start_node, visible_position, kContentIsEditable);
496 if (position.IsNull())
497 break;
498
499 RenderedPosition rendered_position(position, TextAffinity::kDownstream);
500 RootInlineBox* previous_root = rendered_position.RootBox();
501 if (!previous_root)
502 break;
503
504 previous_box = leaf_boxes.PreviousTextBox(previous_root, 0);
505 if (previous_box) {
506 previous_box_in_different_block = true;
507 return previous_box;
508 }
509
510 if (!leaf_boxes.size())
511 break;
512 start_box = leaf_boxes.FirstBox();
513 }
514 return 0;
515 }
516
517 static const InlineTextBox* LogicallyNextBox(
518 const VisiblePosition& visible_position,
519 const InlineTextBox* text_box,
520 bool& next_box_in_different_block,
521 CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
522 DCHECK(visible_position.IsValid()) << visible_position;
523 const InlineBox* start_box = text_box;
524
525 const InlineTextBox* next_box =
526 leaf_boxes.NextTextBox(&start_box->Root(), text_box);
527 if (next_box)
528 return next_box;
529
530 next_box = leaf_boxes.NextTextBox(start_box->Root().NextRootBox(), 0);
531 if (next_box)
532 return next_box;
533
534 while (1) {
535 Node* start_node = start_box->GetLineLayoutItem().NonPseudoNode();
536 if (!start_node)
537 break;
538
539 Position position = NextRootInlineBoxCandidatePosition(
540 start_node, visible_position, kContentIsEditable);
541 if (position.IsNull())
542 break;
543
544 RenderedPosition rendered_position(position, TextAffinity::kDownstream);
545 RootInlineBox* next_root = rendered_position.RootBox();
546 if (!next_root)
547 break;
548
549 next_box = leaf_boxes.NextTextBox(next_root, 0);
550 if (next_box) {
551 next_box_in_different_block = true;
552 return next_box;
553 }
554
555 if (!leaf_boxes.size())
556 break;
557 start_box = leaf_boxes.FirstBox();
558 }
559 return 0;
560 }
561
562 static TextBreakIterator* WordBreakIteratorForMinOffsetBoundary(
563 const VisiblePosition& visible_position,
564 const InlineTextBox* text_box,
565 int& previous_box_length,
566 bool& previous_box_in_different_block,
567 Vector<UChar, 1024>& string,
568 CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
569 DCHECK(visible_position.IsValid()) << visible_position;
570 previous_box_in_different_block = false;
571
572 // FIXME: Handle the case when we don't have an inline text box.
573 const InlineTextBox* previous_box = LogicallyPreviousBox(
574 visible_position, text_box, previous_box_in_different_block, leaf_boxes);
575
576 int len = 0;
577 string.clear();
578 if (previous_box) {
579 previous_box_length = previous_box->Len();
580 previous_box->GetLineLayoutItem().GetText().AppendTo(
581 string, previous_box->Start(), previous_box_length);
582 len += previous_box_length;
583 }
584 text_box->GetLineLayoutItem().GetText().AppendTo(string, text_box->Start(),
585 text_box->Len());
586 len += text_box->Len();
587
588 return WordBreakIterator(string.data(), len);
589 }
590
591 static TextBreakIterator* WordBreakIteratorForMaxOffsetBoundary(
592 const VisiblePosition& visible_position,
593 const InlineTextBox* text_box,
594 bool& next_box_in_different_block,
595 Vector<UChar, 1024>& string,
596 CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
597 DCHECK(visible_position.IsValid()) << visible_position;
598 next_box_in_different_block = false;
599
600 // FIXME: Handle the case when we don't have an inline text box.
601 const InlineTextBox* next_box = LogicallyNextBox(
602 visible_position, text_box, next_box_in_different_block, leaf_boxes);
603
604 int len = 0;
605 string.clear();
606 text_box->GetLineLayoutItem().GetText().AppendTo(string, text_box->Start(),
607 text_box->Len());
608 len += text_box->Len();
609 if (next_box) {
610 next_box->GetLineLayoutItem().GetText().AppendTo(string, next_box->Start(),
611 next_box->Len());
612 len += next_box->Len();
613 }
614
615 return WordBreakIterator(string.data(), len);
616 }
617
618 static bool IsLogicalStartOfWord(TextBreakIterator* iter,
619 int position,
620 bool hard_line_break) {
621 bool boundary = hard_line_break ? true : iter->isBoundary(position);
622 if (!boundary)
623 return false;
624
625 iter->following(position);
626 // isWordTextBreak returns true after moving across a word and false after
627 // moving across a punctuation/space.
628 return IsWordTextBreak(iter);
629 }
630
631 static bool IslogicalEndOfWord(TextBreakIterator* iter,
632 int position,
633 bool hard_line_break) {
634 bool boundary = iter->isBoundary(position);
635 return (hard_line_break || boundary) && IsWordTextBreak(iter);
636 }
637
638 enum CursorMovementDirection { kMoveLeft, kMoveRight };
639
640 static VisiblePosition VisualWordPosition(
641 const VisiblePosition& visible_position,
642 CursorMovementDirection direction,
643 bool skips_space_when_moving_right) {
644 DCHECK(visible_position.IsValid()) << visible_position;
645 if (visible_position.IsNull())
646 return VisiblePosition();
647
648 TextDirection block_direction =
649 DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
650 InlineBox* previously_visited_box = 0;
651 VisiblePosition current = visible_position;
652 TextBreakIterator* iter = 0;
653
654 CachedLogicallyOrderedLeafBoxes leaf_boxes;
655 Vector<UChar, 1024> string;
656
657 while (1) {
658 VisiblePosition adjacent_character_position = direction == kMoveRight
659 ? RightPositionOf(current)
660 : LeftPositionOf(current);
661 if (adjacent_character_position.DeepEquivalent() ==
662 current.DeepEquivalent() ||
663 adjacent_character_position.IsNull())
664 return VisiblePosition();
665
666 InlineBoxPosition box_position = ComputeInlineBoxPosition(
667 adjacent_character_position.DeepEquivalent(), TextAffinity::kUpstream);
668 InlineBox* box = box_position.inline_box;
669 int offset_in_box = box_position.offset_in_box;
670
671 if (!box)
672 break;
673 if (!box->IsInlineTextBox()) {
674 current = adjacent_character_position;
675 continue;
676 }
677
678 InlineTextBox* text_box = ToInlineTextBox(box);
679 int previous_box_length = 0;
680 bool previous_box_in_different_block = false;
681 bool next_box_in_different_block = false;
682 bool moving_into_new_box = previously_visited_box != box;
683
684 if (offset_in_box == box->CaretMinOffset()) {
685 iter = WordBreakIteratorForMinOffsetBoundary(
686 visible_position, text_box, previous_box_length,
687 previous_box_in_different_block, string, leaf_boxes);
688 } else if (offset_in_box == box->CaretMaxOffset()) {
689 iter = WordBreakIteratorForMaxOffsetBoundary(visible_position, text_box,
690 next_box_in_different_block,
691 string, leaf_boxes);
692 } else if (moving_into_new_box) {
693 iter = WordBreakIterator(text_box->GetLineLayoutItem().GetText(),
694 text_box->Start(), text_box->Len());
695 previously_visited_box = box;
696 }
697
698 if (!iter)
699 break;
700
701 iter->first();
702 int offset_in_iterator =
703 offset_in_box - text_box->Start() + previous_box_length;
704
705 bool is_word_break;
706 bool box_has_same_directionality_as_block =
707 box->Direction() == block_direction;
708 bool moving_backward =
709 (direction == kMoveLeft && box->Direction() == TextDirection::kLtr) ||
710 (direction == kMoveRight && box->Direction() == TextDirection::kRtl);
711 if ((skips_space_when_moving_right &&
712 box_has_same_directionality_as_block) ||
713 (!skips_space_when_moving_right && moving_backward)) {
714 bool logical_start_in_layout_object =
715 offset_in_box == static_cast<int>(text_box->Start()) &&
716 previous_box_in_different_block;
717 is_word_break = IsLogicalStartOfWord(iter, offset_in_iterator,
718 logical_start_in_layout_object);
719 } else {
720 bool logical_end_in_layout_object =
721 offset_in_box ==
722 static_cast<int>(text_box->Start() + text_box->Len()) &&
723 next_box_in_different_block;
724 is_word_break = IslogicalEndOfWord(iter, offset_in_iterator,
725 logical_end_in_layout_object);
726 }
727
728 if (is_word_break)
729 return adjacent_character_position;
730
731 current = adjacent_character_position;
732 }
733 return VisiblePosition();
734 }
735
736 VisiblePosition LeftWordPosition(const VisiblePosition& visible_position,
737 bool skips_space_when_moving_right) {
738 DCHECK(visible_position.IsValid()) << visible_position;
739 VisiblePosition left_word_break = VisualWordPosition(
740 visible_position, kMoveLeft, skips_space_when_moving_right);
741 left_word_break = HonorEditingBoundaryAtOrBefore(
742 left_word_break, visible_position.DeepEquivalent());
743
744 // FIXME: How should we handle a non-editable position?
745 if (left_word_break.IsNull() &&
746 IsEditablePosition(visible_position.DeepEquivalent())) {
747 TextDirection block_direction =
748 DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
749 left_word_break = block_direction == TextDirection::kLtr
750 ? StartOfEditableContent(visible_position)
751 : EndOfEditableContent(visible_position);
752 }
753 return left_word_break;
754 }
755
756 VisiblePosition RightWordPosition(const VisiblePosition& visible_position,
757 bool skips_space_when_moving_right) {
758 DCHECK(visible_position.IsValid()) << visible_position;
759 VisiblePosition right_word_break = VisualWordPosition(
760 visible_position, kMoveRight, skips_space_when_moving_right);
761 right_word_break = HonorEditingBoundaryAtOrBefore(
762 right_word_break, visible_position.DeepEquivalent());
763
764 // FIXME: How should we handle a non-editable position?
765 if (right_word_break.IsNull() &&
766 IsEditablePosition(visible_position.DeepEquivalent())) {
767 TextDirection block_direction =
768 DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
769 right_word_break = block_direction == TextDirection::kLtr
770 ? EndOfEditableContent(visible_position)
771 : StartOfEditableContent(visible_position);
772 }
773 return right_word_break;
774 }
775
776 template <typename Strategy> 398 template <typename Strategy>
777 static ContainerNode* NonShadowBoundaryParentNode(Node* node) { 399 static ContainerNode* NonShadowBoundaryParentNode(Node* node) {
778 ContainerNode* parent = Strategy::Parent(*node); 400 ContainerNode* parent = Strategy::Parent(*node);
779 return parent && !parent->IsShadowRoot() ? parent : nullptr; 401 return parent && !parent->IsShadowRoot() ? parent : nullptr;
780 } 402 }
781 403
782 template <typename Strategy> 404 template <typename Strategy>
783 static Node* ParentEditingBoundary(const PositionTemplate<Strategy>& position) { 405 static Node* ParentEditingBoundary(const PositionTemplate<Strategy>& position) {
784 Node* const anchor_node = position.AnchorNode(); 406 Node* const anchor_node = position.AnchorNode();
785 if (!anchor_node) 407 if (!anchor_node)
(...skipping 3361 matching lines...) Expand 10 before | Expand all | Expand 10 after
4147 3769
4148 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { 3770 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) {
4149 return EnclosingIntRect(ComputeTextRectTemplate(range)); 3771 return EnclosingIntRect(ComputeTextRectTemplate(range));
4150 } 3772 }
4151 3773
4152 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { 3774 FloatRect ComputeTextFloatRect(const EphemeralRange& range) {
4153 return ComputeTextRectTemplate(range); 3775 return ComputeTextRectTemplate(range);
4154 } 3776 }
4155 3777
4156 } // namespace blink 3778 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/VisibleUnits.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698