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

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

Issue 2653523003: Make DOMSelection cache Range (Closed)
Patch Set: Clear cached Range considering Shadow Created 3 years, 10 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2012 Google Inc. All rights 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 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 if (selection.isNone()) 168 if (selection.isNone())
169 return "None"; 169 return "None";
170 if (selection.isCaret()) 170 if (selection.isCaret())
171 return "Caret"; 171 return "Caret";
172 return "Range"; 172 return "Range";
173 } 173 }
174 174
175 int DOMSelection::rangeCount() const { 175 int DOMSelection::rangeCount() const {
176 if (!isAvailable()) 176 if (!isAvailable())
177 return 0; 177 return 0;
178 if (m_Range)
179 return 1;
178 return frame()->selection().isNone() ? 0 : 1; 180 return frame()->selection().isNone() ? 0 : 1;
179 } 181 }
180 182
181 void DOMSelection::collapse(Node* node, 183 void DOMSelection::collapse(Node* node,
182 int offset, 184 int offset,
183 ExceptionState& exceptionState) { 185 ExceptionState& exceptionState) {
184 if (!isAvailable()) 186 if (!isAvailable())
185 return; 187 return;
186 188
187 if (!node) { 189 if (!node) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 408
407 if (index < 0 || index >= rangeCount()) { 409 if (index < 0 || index >= rangeCount()) {
408 exceptionState.throwDOMException( 410 exceptionState.throwDOMException(
409 IndexSizeError, String::number(index) + " is not a valid index."); 411 IndexSizeError, String::number(index) + " is not a valid index.");
410 return nullptr; 412 return nullptr;
411 } 413 }
412 414
413 // If you're hitting this, you've added broken multi-range selection support 415 // If you're hitting this, you've added broken multi-range selection support
414 DCHECK_EQ(rangeCount(), 1); 416 DCHECK_EQ(rangeCount(), 1);
415 417
418 if (m_Range)
419 return m_Range;
420
421 Range* newRange = createRangeFromSelectionEditor();
422 if (!areRangesEqual(newRange, m_Range))
tkent 2017/01/25 07:59:12 m_Range is always nullptr. Is this code equivalent
yoichio 2017/01/27 08:33:04 Right.
423 m_Range = newRange;
424
425 return m_Range;
426 }
427
428 Range* DOMSelection::createRangeFromSelectionEditor() {
416 Position anchor = anchorPosition(visibleSelection()); 429 Position anchor = anchorPosition(visibleSelection());
417 if (!anchor.anchorNode()->isInShadowTree()) 430 if (!anchor.anchorNode()->isInShadowTree())
418 return frame()->selection().firstRange(); 431 return frame()->selection().firstRange();
419 432
420 Node* node = shadowAdjustedNode(anchor); 433 Node* node = shadowAdjustedNode(anchor);
421 if (!node) // crbug.com/595100 434 if (!node) // crbug.com/595100
422 return nullptr; 435 return nullptr;
423 if (!visibleSelection().isBaseFirst()) 436 if (!visibleSelection().isBaseFirst())
424 return Range::create(*anchor.document(), focusNode(), focusOffset(), node, 437 return Range::create(*anchor.document(), focusNode(), focusOffset(), node,
425 anchorOffset()); 438 anchorOffset());
426 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(), 439 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(),
427 focusOffset()); 440 focusOffset());
428 } 441 }
429 442
443 void DOMSelection::markRangeDirty() {
444 m_Range = nullptr;
445 }
446
430 void DOMSelection::removeAllRanges() { 447 void DOMSelection::removeAllRanges() {
448 m_Range = nullptr;
431 if (!isAvailable()) 449 if (!isAvailable())
432 return; 450 return;
433 frame()->selection().clear(); 451 frame()->selection().clear();
434 } 452 }
435 453
436 void DOMSelection::addRange(Range* newRange) { 454 void DOMSelection::addRange(Range* newRange) {
437 DCHECK(newRange); 455 DCHECK(newRange);
438 456
439 if (!isAvailable()) 457 if (!isAvailable())
440 return; 458 return;
(...skipping 15 matching lines...) Expand all
456 474
457 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 475 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
458 // needs to be audited. See http://crbug.com/590369 for more details. 476 // needs to be audited. See http://crbug.com/590369 for more details.
459 // In the long term, we should change FrameSelection::setSelection to take a 477 // In the long term, we should change FrameSelection::setSelection to take a
460 // parameter that does not require clean layout, so that modifying selection 478 // parameter that does not require clean layout, so that modifying selection
461 // no longer performs synchronous layout by itself. 479 // no longer performs synchronous layout by itself.
462 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets(); 480 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets();
463 481
464 if (selection.isNone()) { 482 if (selection.isNone()) {
465 selection.setSelectedRange(EphemeralRange(newRange), VP_DEFAULT_AFFINITY); 483 selection.setSelectedRange(EphemeralRange(newRange), VP_DEFAULT_AFFINITY);
484 m_Range = newRange;
466 return; 485 return;
467 } 486 }
468 487
469 Range* originalRange = selection.firstRange(); 488 Range* originalRange = selection.firstRange();
470 489
471 if (originalRange->startContainer()->document() != 490 if (originalRange->startContainer()->document() !=
472 newRange->startContainer()->document()) { 491 newRange->startContainer()->document()) {
473 addConsoleError( 492 addConsoleError(
474 "The given range does not belong to the current selection's document."); 493 "The given range does not belong to the current selection's document.");
475 return; 494 return;
(...skipping 27 matching lines...) Expand all
503 ? originalRange 522 ? originalRange
504 : newRange; 523 : newRange;
505 Range* end = originalRange->compareBoundaryPoints(Range::kEndToEnd, newRange, 524 Range* end = originalRange->compareBoundaryPoints(Range::kEndToEnd, newRange,
506 ASSERT_NO_EXCEPTION) < 0 525 ASSERT_NO_EXCEPTION) < 0
507 ? newRange 526 ? newRange
508 : originalRange; 527 : originalRange;
509 const EphemeralRange merged = 528 const EphemeralRange merged =
510 EphemeralRange(start->startPosition(), end->endPosition()); 529 EphemeralRange(start->startPosition(), end->endPosition());
511 TextAffinity affinity = selection.selection().affinity(); 530 TextAffinity affinity = selection.selection().affinity();
512 selection.setSelectedRange(merged, affinity); 531 selection.setSelectedRange(merged, affinity);
532 m_Range = createRange(merged);
513 } 533 }
514 534
515 void DOMSelection::deleteFromDocument() { 535 void DOMSelection::deleteFromDocument() {
516 if (!isAvailable()) 536 if (!isAvailable())
517 return; 537 return;
518 538
519 FrameSelection& selection = frame()->selection(); 539 FrameSelection& selection = frame()->selection();
520 540
521 if (selection.isNone()) 541 if (selection.isNone())
522 return; 542 return;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 } 682 }
663 683
664 void DOMSelection::addConsoleError(const String& message) { 684 void DOMSelection::addConsoleError(const String& message) {
665 if (m_treeScope) 685 if (m_treeScope)
666 m_treeScope->document().addConsoleMessage( 686 m_treeScope->document().addConsoleMessage(
667 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message)); 687 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message));
668 } 688 }
669 689
670 DEFINE_TRACE(DOMSelection) { 690 DEFINE_TRACE(DOMSelection) {
671 visitor->trace(m_treeScope); 691 visitor->trace(m_treeScope);
692 visitor->trace(m_Range);
672 ContextClient::trace(visitor); 693 ContextClient::trace(visitor);
673 } 694 }
674 695
675 } // namespace blink 696 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698