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

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

Issue 2653523003: Make DOMSelection cache Range (Closed)
Patch Set: update 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 m_range = createRangeFromSelectionEditor();
422 return m_range;
423 }
424
425 Range* DOMSelection::createRangeFromSelectionEditor() {
416 Position anchor = anchorPosition(visibleSelection()); 426 Position anchor = anchorPosition(visibleSelection());
417 if (!anchor.anchorNode()->isInShadowTree()) 427 if (!anchor.anchorNode()->isInShadowTree())
418 return frame()->selection().firstRange(); 428 return frame()->selection().firstRange();
419 429
420 Node* node = shadowAdjustedNode(anchor); 430 Node* node = shadowAdjustedNode(anchor);
421 if (!node) // crbug.com/595100 431 if (!node) // crbug.com/595100
422 return nullptr; 432 return nullptr;
423 if (!visibleSelection().isBaseFirst()) 433 if (!visibleSelection().isBaseFirst())
424 return Range::create(*anchor.document(), focusNode(), focusOffset(), node, 434 return Range::create(*anchor.document(), focusNode(), focusOffset(), node,
425 anchorOffset()); 435 anchorOffset());
426 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(), 436 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(),
427 focusOffset()); 437 focusOffset());
428 } 438 }
429 439
440 void DOMSelection::markRangeDirty() {
441 m_range = nullptr;
442 }
443
430 void DOMSelection::removeAllRanges() { 444 void DOMSelection::removeAllRanges() {
445 m_range = nullptr;
431 if (!isAvailable()) 446 if (!isAvailable())
432 return; 447 return;
433 frame()->selection().clear(); 448 frame()->selection().clear();
434 } 449 }
435 450
436 void DOMSelection::addRange(Range* newRange) { 451 void DOMSelection::addRange(Range* newRange) {
437 DCHECK(newRange); 452 DCHECK(newRange);
438 453
439 if (!isAvailable()) 454 if (!isAvailable())
440 return; 455 return;
(...skipping 15 matching lines...) Expand all
456 471
457 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 472 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
458 // needs to be audited. See http://crbug.com/590369 for more details. 473 // 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 474 // In the long term, we should change FrameSelection::setSelection to take a
460 // parameter that does not require clean layout, so that modifying selection 475 // parameter that does not require clean layout, so that modifying selection
461 // no longer performs synchronous layout by itself. 476 // no longer performs synchronous layout by itself.
462 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets(); 477 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets();
463 478
464 if (selection.isNone()) { 479 if (selection.isNone()) {
465 selection.setSelectedRange(EphemeralRange(newRange), VP_DEFAULT_AFFINITY); 480 selection.setSelectedRange(EphemeralRange(newRange), VP_DEFAULT_AFFINITY);
481 m_range = newRange;
466 return; 482 return;
467 } 483 }
468 484
469 Range* originalRange = selection.firstRange(); 485 Range* originalRange = selection.firstRange();
470 486
471 if (originalRange->startContainer()->document() != 487 if (originalRange->startContainer()->document() !=
472 newRange->startContainer()->document()) { 488 newRange->startContainer()->document()) {
473 addConsoleError( 489 addConsoleError(
474 "The given range does not belong to the current selection's document."); 490 "The given range does not belong to the current selection's document.");
475 return; 491 return;
(...skipping 27 matching lines...) Expand all
503 ? originalRange 519 ? originalRange
504 : newRange; 520 : newRange;
505 Range* end = originalRange->compareBoundaryPoints(Range::kEndToEnd, newRange, 521 Range* end = originalRange->compareBoundaryPoints(Range::kEndToEnd, newRange,
506 ASSERT_NO_EXCEPTION) < 0 522 ASSERT_NO_EXCEPTION) < 0
507 ? newRange 523 ? newRange
508 : originalRange; 524 : originalRange;
509 const EphemeralRange merged = 525 const EphemeralRange merged =
510 EphemeralRange(start->startPosition(), end->endPosition()); 526 EphemeralRange(start->startPosition(), end->endPosition());
511 TextAffinity affinity = selection.selection().affinity(); 527 TextAffinity affinity = selection.selection().affinity();
512 selection.setSelectedRange(merged, affinity); 528 selection.setSelectedRange(merged, affinity);
529 m_range = createRange(merged);
513 } 530 }
514 531
515 void DOMSelection::deleteFromDocument() { 532 void DOMSelection::deleteFromDocument() {
516 if (!isAvailable()) 533 if (!isAvailable())
517 return; 534 return;
518 535
519 FrameSelection& selection = frame()->selection(); 536 FrameSelection& selection = frame()->selection();
520 537
521 if (selection.isNone()) 538 if (selection.isNone())
522 return; 539 return;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 } 681 }
665 682
666 void DOMSelection::addConsoleError(const String& message) { 683 void DOMSelection::addConsoleError(const String& message) {
667 if (m_treeScope) 684 if (m_treeScope)
668 m_treeScope->document().addConsoleMessage( 685 m_treeScope->document().addConsoleMessage(
669 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message)); 686 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message));
670 } 687 }
671 688
672 DEFINE_TRACE(DOMSelection) { 689 DEFINE_TRACE(DOMSelection) {
673 visitor->trace(m_treeScope); 690 visitor->trace(m_treeScope);
691 visitor->trace(m_range);
674 ContextClient::trace(visitor); 692 ContextClient::trace(visitor);
675 } 693 }
676 694
677 } // namespace blink 695 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698