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

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

Issue 2701363002: Move code for SelectionEditor in FrameSelection.cpp to SelectionEditor.cpp (Closed)
Patch Set: 2017-02-20T16:41:49 Rebase 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
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/editing/SelectionEditor.cpp » ('j') | 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, 2008, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 SetSelectionOptions options, 336 SetSelectionOptions options,
337 CursorAlignOnScroll align, 337 CursorAlignOnScroll align,
338 TextGranularity granularity) { 338 TextGranularity granularity) {
339 setSelection( 339 setSelection(
340 SelectionInFlatTree::Builder(newSelection.asSelection()) 340 SelectionInFlatTree::Builder(newSelection.asSelection())
341 .setIsHandleVisible(handleVisibility == HandleVisibility::Visible) 341 .setIsHandleVisible(handleVisibility == HandleVisibility::Visible)
342 .build(), 342 .build(),
343 options, align, granularity); 343 options, align, granularity);
344 } 344 }
345 345
346 // TODO(yosin): We should move |computePositionForChildrenRemoval()| to
347 // "SelectionEditor.cpp" since it used only in
348 // |SelectionEditor::nodeChildrenWillBeRemoved()|.
349 static Position computePositionForChildrenRemoval(const Position& position,
350 ContainerNode& container) {
351 Node* node = position.computeContainerNode();
352 if (container.containsIncludingHostElements(*node))
353 return Position::firstPositionInNode(&container);
354 return position;
355 }
356
357 void FrameSelection::nodeChildrenWillBeRemoved(ContainerNode& container) { 346 void FrameSelection::nodeChildrenWillBeRemoved(ContainerNode& container) {
358 if (!container.inActiveDocument()) 347 if (!container.inActiveDocument())
359 return; 348 return;
360 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 349 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
361 // |Editor| class. 350 // |Editor| class.
362 if (!document().isRunningExecCommand()) 351 if (!document().isRunningExecCommand())
363 TypingCommand::closeTyping(m_frame); 352 TypingCommand::closeTyping(m_frame);
364 } 353 }
365 354
366 // TODO(yosin): We should move |SelectionEditor::nodeChildrenWillBeRemoved()|
367 // to "SelectionEditor.cpp".
368 void SelectionEditor::nodeChildrenWillBeRemoved(ContainerNode& container) {
369 if (m_selection.isNone())
370 return;
371 const Position oldBase = m_selection.m_base;
372 const Position oldExtent = m_selection.m_extent;
373 const Position& newBase =
374 computePositionForChildrenRemoval(oldBase, container);
375 const Position& newExtent =
376 computePositionForChildrenRemoval(oldExtent, container);
377 if (newBase == oldBase && newExtent == oldExtent)
378 return;
379 m_selection = SelectionInDOMTree::Builder()
380 .setBaseAndExtent(newBase, newExtent)
381 .build();
382 markCacheDirty();
383 }
384
385 // TODO(yosin): We should move |computePositionForChildrenRemoval()| with
386 // |nodeWillBeRemoved()| to "SelectionEditor.cpp".
387 static Position computePositionForNodeRemoval(const Position& position,
388 Node& nodeToBeRemoved) {
389 Position result = position;
390 // TODO(yosin): We should rename |updatePositionForNodeRemoval()|
391 // to |computePositionForNodeRemoval()| to avoid using output parameter.
392 updatePositionForNodeRemoval(result, nodeToBeRemoved);
393 return result;
394 }
395
396 // TODO(yosin): We should move |nodeWillBeRemoved()| to
397 // "SelectionEditor.cpp".
398 void SelectionEditor::nodeWillBeRemoved(Node& nodeToBeRemoved) {
399 if (m_selection.isNone())
400 return;
401 const Position oldBase = m_selection.m_base;
402 const Position oldExtent = m_selection.m_extent;
403 const Position& newBase =
404 computePositionForNodeRemoval(oldBase, nodeToBeRemoved);
405 const Position& newExtent =
406 computePositionForNodeRemoval(oldExtent, nodeToBeRemoved);
407 if (newBase == oldBase && newExtent == oldExtent)
408 return;
409 m_selection = SelectionInDOMTree::Builder()
410 .setBaseAndExtent(newBase, newExtent)
411 .build();
412 markCacheDirty();
413 }
414
415 void FrameSelection::nodeWillBeRemoved(Node& node) { 355 void FrameSelection::nodeWillBeRemoved(Node& node) {
416 // There can't be a selection inside a fragment, so if a fragment's node is 356 // There can't be a selection inside a fragment, so if a fragment's node is
417 // being removed, the selection in the document that created the fragment 357 // being removed, the selection in the document that created the fragment
418 // needs no adjustment. 358 // needs no adjustment.
419 if (!node.inActiveDocument()) 359 if (!node.inActiveDocument())
420 return; 360 return;
421 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 361 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
422 // |Editor| class. 362 // |Editor| class.
423 if (!document().isRunningExecCommand()) 363 if (!document().isRunningExecCommand())
424 TypingCommand::closeTyping(m_frame); 364 TypingCommand::closeTyping(m_frame);
425 } 365 }
426 366
427 // TODO(yosin): We should move |updatePositionAfterAdoptingTextReplacement()|
428 // to "SelectionEditor.cpp" since it used only in
429 // |SelectionEditor::didUpdateCharacterData()|.
430 static Position updatePositionAfterAdoptingTextReplacement(
431 const Position& position,
432 CharacterData* node,
433 unsigned offset,
434 unsigned oldLength,
435 unsigned newLength) {
436 if (position.anchorNode() != node)
437 return position;
438
439 if (position.isBeforeAnchor()) {
440 return updatePositionAfterAdoptingTextReplacement(
441 Position(node, 0), node, offset, oldLength, newLength);
442 }
443 if (position.isAfterAnchor()) {
444 return updatePositionAfterAdoptingTextReplacement(
445 Position(node, oldLength), node, offset, oldLength, newLength);
446 }
447
448 // See:
449 // http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range- Mutation
450 DCHECK_GE(position.offsetInContainerNode(), 0);
451 unsigned positionOffset =
452 static_cast<unsigned>(position.offsetInContainerNode());
453 // Replacing text can be viewed as a deletion followed by insertion.
454 if (positionOffset >= offset && positionOffset <= offset + oldLength)
455 positionOffset = offset;
456
457 // Adjust the offset if the position is after the end of the deleted contents
458 // (positionOffset > offset + oldLength) to avoid having a stale offset.
459 if (positionOffset > offset + oldLength)
460 positionOffset = positionOffset - oldLength + newLength;
461
462 // Due to case folding
463 // (http://unicode.org/Public/UCD/latest/ucd/CaseFolding.txt), LayoutText
464 // length may be different from Text length. A correct implementation would
465 // translate the LayoutText offset to a Text offset; this is just a safety
466 // precaution to avoid offset values that run off the end of the Text.
467 if (positionOffset > node->length())
468 positionOffset = node->length();
469
470 return Position(node, positionOffset);
471 }
472
473 // TODO(yosin): We should move |didUpdateCharacterData()| to
474 // "SelectionEditor.cpp".
475 void SelectionEditor::didUpdateCharacterData(CharacterData* node,
476 unsigned offset,
477 unsigned oldLength,
478 unsigned newLength) {
479 // The fragment check is a performance optimization. See
480 // http://trac.webkit.org/changeset/30062.
481 if (m_selection.isNone() || !node || !node->isConnected()) {
482 didFinishDOMMutation();
483 return;
484 }
485 const Position& newBase = updatePositionAfterAdoptingTextReplacement(
486 m_selection.m_base, node, offset, oldLength, newLength);
487 const Position& newExtent = updatePositionAfterAdoptingTextReplacement(
488 m_selection.m_extent, node, offset, oldLength, newLength);
489 didFinishTextChange(newBase, newExtent);
490 }
491
492 // TODO(yosin): We should move |updatePostionAfterAdoptingTextNodesMerged()|
493 // to "SelectionEditor.cpp" since it used only in
494 // |SelectionEditor::didMergeTextNodes()|.
495 // TODO(yosin): We should introduce |Position(const Text&, int)| to avoid
496 // |const_cast<Text*>|.
497 static Position updatePostionAfterAdoptingTextNodesMerged(
498 const Position& position,
499 const Text& mergedNode,
500 const NodeWithIndex& nodeToBeRemovedWithIndex,
501 unsigned oldLength) {
502 Node* const anchorNode = position.anchorNode();
503 const Node& nodeToBeRemoved = nodeToBeRemovedWithIndex.node();
504 switch (position.anchorType()) {
505 case PositionAnchorType::BeforeChildren:
506 case PositionAnchorType::AfterChildren:
507 return position;
508 case PositionAnchorType::BeforeAnchor:
509 if (anchorNode == nodeToBeRemoved)
510 return Position(const_cast<Text*>(&mergedNode), mergedNode.length());
511 return position;
512 case PositionAnchorType::AfterAnchor:
513 if (anchorNode == nodeToBeRemoved)
514 return Position(const_cast<Text*>(&mergedNode), mergedNode.length());
515 if (anchorNode == mergedNode)
516 return Position(const_cast<Text*>(&mergedNode), oldLength);
517 return position;
518 case PositionAnchorType::OffsetInAnchor: {
519 const int offset = position.offsetInContainerNode();
520 if (anchorNode == nodeToBeRemoved)
521 return Position(const_cast<Text*>(&mergedNode), oldLength + offset);
522 if (anchorNode == nodeToBeRemoved.parentNode() &&
523 offset == nodeToBeRemovedWithIndex.index()) {
524 return Position(const_cast<Text*>(&mergedNode), oldLength);
525 }
526 return position;
527 }
528 }
529 NOTREACHED() << position;
530 return position;
531 }
532
533 // TODO(yosin): We should move |SelectionEditor::didMergeTextNodes()| to
534 // "SelectionEditor.cpp".
535 void SelectionEditor::didMergeTextNodes(
536 const Text& mergedNode,
537 const NodeWithIndex& nodeToBeRemovedWithIndex,
538 unsigned oldLength) {
539 if (m_selection.isNone()) {
540 didFinishDOMMutation();
541 return;
542 }
543 const Position& newBase = updatePostionAfterAdoptingTextNodesMerged(
544 m_selection.m_base, mergedNode, nodeToBeRemovedWithIndex, oldLength);
545 const Position& newExtent = updatePostionAfterAdoptingTextNodesMerged(
546 m_selection.m_extent, mergedNode, nodeToBeRemovedWithIndex, oldLength);
547 didFinishTextChange(newBase, newExtent);
548 }
549
550 // TODO(yosin): We should move |updatePostionAfterAdoptingTextNodeSplit()|
551 // to "SelectionEditor.cpp" since it used only in
552 // |SelectionEditor::didSplitTextNode()|.
553 static Position updatePostionAfterAdoptingTextNodeSplit(
554 const Position& position,
555 const Text& oldNode) {
556 if (!position.anchorNode() || position.anchorNode() != &oldNode ||
557 !position.isOffsetInAnchor())
558 return position;
559 // See:
560 // http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range- Mutation
561 DCHECK_GE(position.offsetInContainerNode(), 0);
562 unsigned positionOffset =
563 static_cast<unsigned>(position.offsetInContainerNode());
564 unsigned oldLength = oldNode.length();
565 if (positionOffset <= oldLength)
566 return position;
567 return Position(toText(oldNode.nextSibling()), positionOffset - oldLength);
568 }
569
570 // TODO(yosin): We should move |SelectionEditor::didSplitTextNode()| to
571 // "SelectionEditor.cpp".
572 void SelectionEditor::didSplitTextNode(const Text& oldNode) {
573 if (m_selection.isNone() || !oldNode.isConnected()) {
574 didFinishDOMMutation();
575 return;
576 }
577 const Position& newBase =
578 updatePostionAfterAdoptingTextNodeSplit(m_selection.m_base, oldNode);
579 const Position& newExtent =
580 updatePostionAfterAdoptingTextNodeSplit(m_selection.m_extent, oldNode);
581 didFinishTextChange(newBase, newExtent);
582 }
583
584 void FrameSelection::didChangeFocus() { 367 void FrameSelection::didChangeFocus() {
585 // Hits in 368 // Hits in
586 // virtual/gpu/compositedscrolling/scrollbars/scrollbar-miss-mousemove-disable d.html 369 // virtual/gpu/compositedscrolling/scrollbars/scrollbar-miss-mousemove-disable d.html
587 DisableCompositingQueryAsserts disabler; 370 DisableCompositingQueryAsserts disabler;
588 updateAppearance(); 371 updateAppearance();
589 } 372 }
590 373
591 static DispatchEventResult dispatchSelectStart( 374 static DispatchEventResult dispatchSelectStart(
592 const VisibleSelection& selection) { 375 const VisibleSelection& selection) {
593 Node* selectStartTarget = selection.extent().computeContainerNode(); 376 Node* selectStartTarget = selection.extent().computeContainerNode();
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 } 1187 }
1405 1188
1406 void showTree(const blink::FrameSelection* sel) { 1189 void showTree(const blink::FrameSelection* sel) {
1407 if (sel) 1190 if (sel)
1408 sel->showTreeForThis(); 1191 sel->showTreeForThis();
1409 else 1192 else
1410 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; 1193 LOG(INFO) << "Cannot showTree for <null> FrameSelection.";
1411 } 1194 }
1412 1195
1413 #endif 1196 #endif
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/editing/SelectionEditor.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698