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

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 (documentCachedRange())
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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 return; 281 return;
280 } 282 }
281 if (!extentNode) { 283 if (!extentNode) {
282 UseCounter::count(frame(), UseCounter::SelectionSetBaseAndExtentNull); 284 UseCounter::count(frame(), UseCounter::SelectionSetBaseAndExtentNull);
283 extentOffset = 0; 285 extentOffset = 0;
284 } 286 }
285 287
286 if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode)) 288 if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode))
287 return; 289 return;
288 290
291 clearCachedRangeIfSelectionOfDocument();
292
289 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets 293 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
290 // needs to be audited. See http://crbug.com/590369 for more details. 294 // needs to be audited. See http://crbug.com/590369 for more details.
291 // In the long term, we should change FrameSelection::setSelection to take a 295 // In the long term, we should change FrameSelection::setSelection to take a
292 // parameter that does not require clean layout, so that modifying selection 296 // parameter that does not require clean layout, so that modifying selection
293 // no longer performs synchronous layout by itself. 297 // no longer performs synchronous layout by itself.
294 // TODO(editing-dev): Once SVG USE element doesn't modifies DOM tree, we 298 // TODO(editing-dev): Once SVG USE element doesn't modifies DOM tree, we
295 // should get rid of this update layout call. 299 // should get rid of this update layout call.
296 // See http://crbug.com/566281 300 // See http://crbug.com/566281
297 // See "svg/text/textpath-reference-crash.html" 301 // See "svg/text/textpath-reference-crash.html"
298 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets(); 302 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 if (static_cast<unsigned>(offset) > node->lengthOfContents()) { 380 if (static_cast<unsigned>(offset) > node->lengthOfContents()) {
377 exceptionState.throwDOMException( 381 exceptionState.throwDOMException(
378 IndexSizeError, 382 IndexSizeError,
379 String::number(offset) + " is larger than the given node's length."); 383 String::number(offset) + " is larger than the given node's length.");
380 return; 384 return;
381 } 385 }
382 386
383 if (!isValidForPosition(node)) 387 if (!isValidForPosition(node))
384 return; 388 return;
385 389
390 clearCachedRangeIfSelectionOfDocument();
386 const Position& base = frame()->selection().base(); 391 const Position& base = frame()->selection().base();
387 if (base.isNull()) { 392 if (base.isNull()) {
388 // TODO(editing-dev): We should throw |InvalidStateError| if selection is 393 // TODO(editing-dev): We should throw |InvalidStateError| if selection is
389 // none to follow the spec. 394 // none to follow the spec.
390 frame()->selection().setSelection(SelectionInDOMTree::Builder() 395 frame()->selection().setSelection(SelectionInDOMTree::Builder()
391 .collapse(Position(node, offset)) 396 .collapse(Position(node, offset))
392 .setIsDirectional(true) 397 .setIsDirectional(true)
393 .build()); 398 .build());
394 return; 399 return;
395 } 400 }
(...skipping 10 matching lines...) Expand all
406 411
407 if (index < 0 || index >= rangeCount()) { 412 if (index < 0 || index >= rangeCount()) {
408 exceptionState.throwDOMException( 413 exceptionState.throwDOMException(
409 IndexSizeError, String::number(index) + " is not a valid index."); 414 IndexSizeError, String::number(index) + " is not a valid index.");
410 return nullptr; 415 return nullptr;
411 } 416 }
412 417
413 // If you're hitting this, you've added broken multi-range selection support 418 // If you're hitting this, you've added broken multi-range selection support
414 DCHECK_EQ(rangeCount(), 1); 419 DCHECK_EQ(rangeCount(), 1);
415 420
421 if (Range* cachedRange = documentCachedRange())
422 return cachedRange;
423
424 Range* range = createRangeFromSelectionEditor();
425 cacheRangeIfSelectionOfDocument(range);
426 return range;
427 }
428
429 Range* DOMSelection::createRangeFromSelectionEditor() {
416 Position anchor = anchorPosition(visibleSelection()); 430 Position anchor = anchorPosition(visibleSelection());
417 if (!anchor.anchorNode()->isInShadowTree()) 431 if (!anchor.anchorNode()->isInShadowTree())
418 return frame()->selection().firstRange(); 432 return frame()->selection().firstRange();
419 433
420 Node* node = shadowAdjustedNode(anchor); 434 Node* node = shadowAdjustedNode(anchor);
421 if (!node) // crbug.com/595100 435 if (!node) // crbug.com/595100
422 return nullptr; 436 return nullptr;
423 if (!visibleSelection().isBaseFirst()) 437 if (!visibleSelection().isBaseFirst())
424 return Range::create(*anchor.document(), focusNode(), focusOffset(), node, 438 return Range::create(*anchor.document(), focusNode(), focusOffset(), node,
425 anchorOffset()); 439 anchorOffset());
426 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(), 440 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(),
427 focusOffset()); 441 focusOffset());
428 } 442 }
429 443
444 bool DOMSelection::isSelectionOfDocument() const {
445 return m_treeScope == m_treeScope->document();
446 }
447
448 void DOMSelection::cacheRangeIfSelectionOfDocument(Range* range) {
449 if (!isSelectionOfDocument())
450 return;
451
yosin_UTC9 2017/02/09 09:32:09 nit: Please get rid of an extra blank line.
yoichio 2017/02/09 09:36:04 Done.
452 frame()->selection().cacheRangeOfDocument(range);
453 }
454
455 Range* DOMSelection::documentCachedRange() const {
456 if (!isSelectionOfDocument())
457 return nullptr;
458
yosin_UTC9 2017/02/09 09:32:09 nit: Please get rid of an extra blank line.
yoichio 2017/02/09 09:36:04 Done.
459 return frame()->selection().documentCachedRange();
460 }
461
462 void DOMSelection::clearCachedRangeIfSelectionOfDocument() {
463 if (!isSelectionOfDocument())
464 return;
465
yosin_UTC9 2017/02/09 09:32:09 nit: Please get rid of an extra blank line.
yoichio 2017/02/09 09:36:04 Done.
466 frame()->selection().clearDocumentCachedRange();
467 }
468
430 void DOMSelection::removeAllRanges() { 469 void DOMSelection::removeAllRanges() {
431 if (!isAvailable()) 470 if (!isAvailable())
432 return; 471 return;
433 frame()->selection().clear(); 472 frame()->selection().clear();
434 } 473 }
435 474
436 void DOMSelection::addRange(Range* newRange) { 475 void DOMSelection::addRange(Range* newRange) {
437 DCHECK(newRange); 476 DCHECK(newRange);
438 477
439 if (!isAvailable()) 478 if (!isAvailable())
(...skipping 16 matching lines...) Expand all
456 495
457 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 496 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
458 // needs to be audited. See http://crbug.com/590369 for more details. 497 // 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 498 // In the long term, we should change FrameSelection::setSelection to take a
460 // parameter that does not require clean layout, so that modifying selection 499 // parameter that does not require clean layout, so that modifying selection
461 // no longer performs synchronous layout by itself. 500 // no longer performs synchronous layout by itself.
462 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets(); 501 frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets();
463 502
464 if (selection.isNone()) { 503 if (selection.isNone()) {
465 selection.setSelectedRange(EphemeralRange(newRange), VP_DEFAULT_AFFINITY); 504 selection.setSelectedRange(EphemeralRange(newRange), VP_DEFAULT_AFFINITY);
505 cacheRangeIfSelectionOfDocument(newRange);
466 return; 506 return;
467 } 507 }
468 508
469 Range* originalRange = selection.firstRange(); 509 Range* originalRange = selection.firstRange();
470 510
471 if (originalRange->startContainer()->document() != 511 if (originalRange->startContainer()->document() !=
472 newRange->startContainer()->document()) { 512 newRange->startContainer()->document()) {
473 addConsoleError( 513 addConsoleError(
474 "The given range does not belong to the current selection's document."); 514 "The given range does not belong to the current selection's document.");
475 return; 515 return;
(...skipping 27 matching lines...) Expand all
503 ? originalRange 543 ? originalRange
504 : newRange; 544 : newRange;
505 Range* end = originalRange->compareBoundaryPoints(Range::kEndToEnd, newRange, 545 Range* end = originalRange->compareBoundaryPoints(Range::kEndToEnd, newRange,
506 ASSERT_NO_EXCEPTION) < 0 546 ASSERT_NO_EXCEPTION) < 0
507 ? newRange 547 ? newRange
508 : originalRange; 548 : originalRange;
509 const EphemeralRange merged = 549 const EphemeralRange merged =
510 EphemeralRange(start->startPosition(), end->endPosition()); 550 EphemeralRange(start->startPosition(), end->endPosition());
511 TextAffinity affinity = selection.selection().affinity(); 551 TextAffinity affinity = selection.selection().affinity();
512 selection.setSelectedRange(merged, affinity); 552 selection.setSelectedRange(merged, affinity);
553 cacheRangeIfSelectionOfDocument(createRange(merged));
513 } 554 }
514 555
515 void DOMSelection::deleteFromDocument() { 556 void DOMSelection::deleteFromDocument() {
516 if (!isAvailable()) 557 if (!isAvailable())
517 return; 558 return;
518 559
519 FrameSelection& selection = frame()->selection(); 560 FrameSelection& selection = frame()->selection();
520 561
521 if (selection.isNone()) 562 if (selection.isNone())
522 return; 563 return;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 m_treeScope->document().addConsoleMessage( 709 m_treeScope->document().addConsoleMessage(
669 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message)); 710 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message));
670 } 711 }
671 712
672 DEFINE_TRACE(DOMSelection) { 713 DEFINE_TRACE(DOMSelection) {
673 visitor->trace(m_treeScope); 714 visitor->trace(m_treeScope);
674 ContextClient::trace(visitor); 715 ContextClient::trace(visitor);
675 } 716 }
676 717
677 } // namespace blink 718 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/DOMSelection.h ('k') | third_party/WebKit/Source/core/editing/FrameSelection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698