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

Side by Side Diff: Source/core/editing/ApplyStyleCommand.cpp

Issue 1245843003: [CodeHealth] Use Position::anchorNode instead of deprecatedNode. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 5 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) 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2008, 2009 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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 252
253 VisiblePosition visibleStart(start); 253 VisiblePosition visibleStart(start);
254 VisiblePosition visibleEnd(end); 254 VisiblePosition visibleEnd(end);
255 255
256 if (visibleStart.isNull() || visibleStart.isOrphan() || visibleEnd.isNull() || visibleEnd.isOrphan()) 256 if (visibleStart.isNull() || visibleStart.isOrphan() || visibleEnd.isNull() || visibleEnd.isOrphan())
257 return; 257 return;
258 258
259 // Save and restore the selection endpoints using their indices in the docum ent, since 259 // Save and restore the selection endpoints using their indices in the docum ent, since
260 // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoint s. 260 // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoint s.
261 // Calculate start and end indices from the start of the tree that they're i n. 261 // Calculate start and end indices from the start of the tree that they're i n.
262 Node& scope = NodeTraversal::highestAncestorOrSelf(*visibleStart.deepEquival ent().deprecatedNode()); 262 Node& scope = NodeTraversal::highestAncestorOrSelf(*visibleStart.deepEquival ent().anchorNode());
263 RefPtrWillBeRawPtr<Range> startRange = Range::create(document(), firstPositi onInNode(&scope), visibleStart.deepEquivalent().parentAnchoredEquivalent()); 263 RefPtrWillBeRawPtr<Range> startRange = Range::create(document(), firstPositi onInNode(&scope), visibleStart.deepEquivalent().parentAnchoredEquivalent());
264 RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), firstPosition InNode(&scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent()); 264 RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), firstPosition InNode(&scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
265 int startIndex = TextIterator::rangeLength(startRange->startPosition(), star tRange->endPosition(), true); 265 int startIndex = TextIterator::rangeLength(startRange->startPosition(), star tRange->endPosition(), true);
266 int endIndex = TextIterator::rangeLength(endRange->startPosition(), endRange ->endPosition(), true); 266 int endIndex = TextIterator::rangeLength(endRange->startPosition(), endRange ->endPosition(), true);
267 267
268 VisiblePosition paragraphStart(startOfParagraph(visibleStart)); 268 VisiblePosition paragraphStart(startOfParagraph(visibleStart));
269 VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next()); 269 VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next());
270 VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next()); 270 VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next());
271 while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) { 271 while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) {
272 StyleChange styleChange(style, paragraphStart.deepEquivalent()); 272 StyleChange styleChange(style, paragraphStart.deepEquivalent());
273 if (styleChange.cssStyle().length() || m_removeOnly) { 273 if (styleChange.cssStyle().length() || m_removeOnly) {
274 RefPtrWillBeRawPtr<Element> block = enclosingBlock(paragraphStart.de epEquivalent().deprecatedNode()); 274 RefPtrWillBeRawPtr<Element> block = enclosingBlock(paragraphStart.de epEquivalent().anchorNode());
275 const Position& paragraphStartToMove = paragraphStart.deepEquivalent (); 275 const Position& paragraphStartToMove = paragraphStart.deepEquivalent ();
276 if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) { 276 if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) {
277 RefPtrWillBeRawPtr<HTMLElement> newBlock = moveParagraphContents ToNewBlockIfNecessary(paragraphStartToMove); 277 RefPtrWillBeRawPtr<HTMLElement> newBlock = moveParagraphContents ToNewBlockIfNecessary(paragraphStartToMove);
278 if (newBlock) 278 if (newBlock)
279 block = newBlock; 279 block = newBlock;
280 } 280 }
281 if (block && block->isHTMLElement()) { 281 if (block && block->isHTMLElement()) {
282 removeCSSStyle(style, toHTMLElement(block)); 282 removeCSSStyle(style, toHTMLElement(block));
283 if (!m_removeOnly) 283 if (!m_removeOnly)
284 addBlockStyle(styleChange, toHTMLElement(block)); 284 addBlockStyle(styleChange, toHTMLElement(block));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 317
318 Position start = startPosition(); 318 Position start = startPosition();
319 Position end = endPosition(); 319 Position end = endPosition();
320 if (comparePositions(end, start) < 0) { 320 if (comparePositions(end, start) < 0) {
321 Position swap = start; 321 Position swap = start;
322 start = end; 322 start = end;
323 end = swap; 323 end = swap;
324 } 324 }
325 325
326 // Join up any adjacent text nodes. 326 // Join up any adjacent text nodes.
327 if (start.deprecatedNode()->isTextNode()) { 327 if (start.anchorNode()->isTextNode()) {
328 joinChildTextNodes(start.deprecatedNode()->parentNode(), start, end); 328 joinChildTextNodes(start.anchorNode()->parentNode(), start, end);
329 start = startPosition(); 329 start = startPosition();
330 end = endPosition(); 330 end = endPosition();
331 } 331 }
332 332
333 if (start.isNull() || end.isNull()) 333 if (start.isNull() || end.isNull())
334 return; 334 return;
335 335
336 if (end.deprecatedNode()->isTextNode() && start.deprecatedNode()->parentNode () != end.deprecatedNode()->parentNode()) { 336 if (end.anchorNode()->isTextNode() && start.anchorNode()->parentNode() != en d.anchorNode()->parentNode()) {
337 joinChildTextNodes(end.deprecatedNode()->parentNode(), start, end); 337 joinChildTextNodes(end.anchorNode()->parentNode(), start, end);
338 start = startPosition(); 338 start = startPosition();
339 end = endPosition(); 339 end = endPosition();
340 } 340 }
341 341
342 if (start.isNull() || end.isNull()) 342 if (start.isNull() || end.isNull())
343 return; 343 return;
344 344
345 // Split the start text nodes if needed to apply style. 345 // Split the start text nodes if needed to apply style.
346 if (isValidCaretPositionInTextNode(start)) { 346 if (isValidCaretPositionInTextNode(start)) {
347 splitTextAtStart(start, end); 347 splitTextAtStart(start, end);
348 start = startPosition(); 348 start = startPosition();
349 end = endPosition(); 349 end = endPosition();
350 } 350 }
351 351
352 if (isValidCaretPositionInTextNode(end)) { 352 if (isValidCaretPositionInTextNode(end)) {
353 splitTextAtEnd(start, end); 353 splitTextAtEnd(start, end);
354 start = startPosition(); 354 start = startPosition();
355 end = endPosition(); 355 end = endPosition();
356 } 356 }
357 357
358 // Calculate loop end point. 358 // Calculate loop end point.
359 // If the end node is before the start node (can only happen if the end node is 359 // If the end node is before the start node (can only happen if the end node is
360 // an ancestor of the start node), we gather nodes up to the next sibling of the end node 360 // an ancestor of the start node), we gather nodes up to the next sibling of the end node
361 Node* beyondEnd; 361 Node* beyondEnd;
362 ASSERT(start.deprecatedNode()); 362 ASSERT(start.anchorNode());
363 ASSERT(end.deprecatedNode()); 363 ASSERT(end.anchorNode());
364 if (start.deprecatedNode()->isDescendantOf(end.deprecatedNode())) 364 if (start.anchorNode()->isDescendantOf(end.anchorNode()))
365 beyondEnd = NodeTraversal::nextSkippingChildren(*end.deprecatedNode()); 365 beyondEnd = NodeTraversal::nextSkippingChildren(*end.anchorNode());
366 else 366 else
367 beyondEnd = NodeTraversal::next(*end.deprecatedNode()); 367 beyondEnd = NodeTraversal::next(*end.anchorNode());
368 368
369 start = start.upstream(); // Move upstream to ensure we do not add redundant spans. 369 start = start.upstream(); // Move upstream to ensure we do not add redundant spans.
370 Node* startNode = start.deprecatedNode(); 370 Node* startNode = start.anchorNode();
371 ASSERT(startNode); 371 ASSERT(startNode);
372 372
373 // Make sure we're not already at the end or the next NodeTraversal::next() will traverse 373 // Make sure we're not already at the end or the next NodeTraversal::next() will traverse
374 // past it. 374 // past it.
375 if (startNode == beyondEnd) 375 if (startNode == beyondEnd)
376 return; 376 return;
377 377
378 if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOf fset(startNode)) { 378 if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOf fset(startNode)) {
379 // Move out of text node if range does not include its characters. 379 // Move out of text node if range does not include its characters.
380 startNode = NodeTraversal::next(*startNode); 380 startNode = NodeTraversal::next(*startNode);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 576
577 if (comparePositions(end, start) < 0) { 577 if (comparePositions(end, start) < 0) {
578 Position swap = start; 578 Position swap = start;
579 start = end; 579 start = end;
580 end = swap; 580 end = swap;
581 } 581 }
582 582
583 // split the start node and containing element if the selection starts insid e of it 583 // split the start node and containing element if the selection starts insid e of it
584 bool splitStart = isValidCaretPositionInTextNode(start); 584 bool splitStart = isValidCaretPositionInTextNode(start);
585 if (splitStart) { 585 if (splitStart) {
586 if (shouldSplitTextElement(start.deprecatedNode()->parentElement(), styl e)) 586 if (shouldSplitTextElement(start.anchorNode()->parentElement(), style))
587 splitTextElementAtStart(start, end); 587 splitTextElementAtStart(start, end);
588 else 588 else
589 splitTextAtStart(start, end); 589 splitTextAtStart(start, end);
590 start = startPosition(); 590 start = startPosition();
591 end = endPosition(); 591 end = endPosition();
592 if (start.isNull() || end.isNull()) 592 if (start.isNull() || end.isNull())
593 return; 593 return;
594 startDummySpanAncestor = dummySpanAncestorForNode(start.deprecatedNode() ); 594 startDummySpanAncestor = dummySpanAncestorForNode(start.anchorNode());
595 } 595 }
596 596
597 // split the end node and containing element if the selection ends inside of it 597 // split the end node and containing element if the selection ends inside of it
598 bool splitEnd = isValidCaretPositionInTextNode(end); 598 bool splitEnd = isValidCaretPositionInTextNode(end);
599 if (splitEnd) { 599 if (splitEnd) {
600 if (shouldSplitTextElement(end.deprecatedNode()->parentElement(), style) ) 600 if (shouldSplitTextElement(end.anchorNode()->parentElement(), style))
601 splitTextElementAtEnd(start, end); 601 splitTextElementAtEnd(start, end);
602 else 602 else
603 splitTextAtEnd(start, end); 603 splitTextAtEnd(start, end);
604 start = startPosition(); 604 start = startPosition();
605 end = endPosition(); 605 end = endPosition();
606 if (start.isNull() || end.isNull()) 606 if (start.isNull() || end.isNull())
607 return; 607 return;
608 endDummySpanAncestor = dummySpanAncestorForNode(end.deprecatedNode()); 608 endDummySpanAncestor = dummySpanAncestorForNode(end.anchorNode());
609 } 609 }
610 610
611 // Remove style from the selection. 611 // Remove style from the selection.
612 // Use the upstream position of the start for removing style. 612 // Use the upstream position of the start for removing style.
613 // This will ensure we remove all traces of the relevant styles from the sel ection 613 // This will ensure we remove all traces of the relevant styles from the sel ection
614 // and prevent us from adding redundant ones, as described in: 614 // and prevent us from adding redundant ones, as described in:
615 // <rdar://problem/3724344> Bolding and unbolding creates extraneous tags 615 // <rdar://problem/3724344> Bolding and unbolding creates extraneous tags
616 Position removeStart = start.upstream(); 616 Position removeStart = start.upstream();
617 WritingDirection textDirection = NaturalWritingDirection; 617 WritingDirection textDirection = NaturalWritingDirection;
618 bool hasTextDirection = style->textDirection(textDirection); 618 bool hasTextDirection = style->textDirection(textDirection);
619 RefPtrWillBeRawPtr<EditingStyle> styleWithoutEmbedding = nullptr; 619 RefPtrWillBeRawPtr<EditingStyle> styleWithoutEmbedding = nullptr;
620 RefPtrWillBeRawPtr<EditingStyle> embeddingStyle = nullptr; 620 RefPtrWillBeRawPtr<EditingStyle> embeddingStyle = nullptr;
621 if (hasTextDirection) { 621 if (hasTextDirection) {
622 // Leave alone an ancestor that provides the desired single level embedd ing, if there is one. 622 // Leave alone an ancestor that provides the desired single level embedd ing, if there is one.
623 HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start. deprecatedNode(), true, textDirection); 623 HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start. anchorNode(), true, textDirection);
624 HTMLElement* endUnsplitAncestor = splitAncestorsWithUnicodeBidi(end.depr ecatedNode(), false, textDirection); 624 HTMLElement* endUnsplitAncestor = splitAncestorsWithUnicodeBidi(end.anch orNode(), false, textDirection);
625 removeEmbeddingUpToEnclosingBlock(start.deprecatedNode(), startUnsplitAn cestor); 625 removeEmbeddingUpToEnclosingBlock(start.anchorNode(), startUnsplitAncest or);
626 removeEmbeddingUpToEnclosingBlock(end.deprecatedNode(), endUnsplitAncest or); 626 removeEmbeddingUpToEnclosingBlock(end.anchorNode(), endUnsplitAncestor);
627 627
628 // Avoid removing the dir attribute and the unicode-bidi and direction p roperties from the unsplit ancestors. 628 // Avoid removing the dir attribute and the unicode-bidi and direction p roperties from the unsplit ancestors.
629 Position embeddingRemoveStart = removeStart; 629 Position embeddingRemoveStart = removeStart;
630 if (startUnsplitAncestor && elementFullySelected(*startUnsplitAncestor, removeStart, end)) 630 if (startUnsplitAncestor && elementFullySelected(*startUnsplitAncestor, removeStart, end))
631 embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncest or); 631 embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncest or);
632 632
633 Position embeddingRemoveEnd = end; 633 Position embeddingRemoveEnd = end;
634 if (endUnsplitAncestor && elementFullySelected(*endUnsplitAncestor, remo veStart, end)) 634 if (endUnsplitAncestor && elementFullySelected(*endUnsplitAncestor, remo veStart, end))
635 embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor) .downstream(); 635 embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor) .downstream();
636 636
(...skipping 24 matching lines...) Expand all
661 } 661 }
662 662
663 // update document layout once before running the rest of the function 663 // update document layout once before running the rest of the function
664 // so that we avoid the expense of updating before each and every call 664 // so that we avoid the expense of updating before each and every call
665 // to check a computed style 665 // to check a computed style
666 document().updateLayoutIgnorePendingStylesheets(); 666 document().updateLayoutIgnorePendingStylesheets();
667 667
668 RefPtrWillBeRawPtr<EditingStyle> styleToApply = style; 668 RefPtrWillBeRawPtr<EditingStyle> styleToApply = style;
669 if (hasTextDirection) { 669 if (hasTextDirection) {
670 // Avoid applying the unicode-bidi and direction properties beneath ance stors that already have them. 670 // Avoid applying the unicode-bidi and direction properties beneath ance stors that already have them.
671 HTMLElement* embeddingStartElement = highestEmbeddingAncestor(start.depr ecatedNode(), enclosingBlock(start.deprecatedNode())); 671 HTMLElement* embeddingStartElement = highestEmbeddingAncestor(start.anch orNode(), enclosingBlock(start.anchorNode()));
672 HTMLElement* embeddingEndElement = highestEmbeddingAncestor(end.deprecat edNode(), enclosingBlock(end.deprecatedNode())); 672 HTMLElement* embeddingEndElement = highestEmbeddingAncestor(end.anchorNo de(), enclosingBlock(end.anchorNode()));
673 673
674 if (embeddingStartElement || embeddingEndElement) { 674 if (embeddingStartElement || embeddingEndElement) {
675 Position embeddingApplyStart = embeddingStartElement ? positionInPar entAfterNode(*embeddingStartElement) : start; 675 Position embeddingApplyStart = embeddingStartElement ? positionInPar entAfterNode(*embeddingStartElement) : start;
676 Position embeddingApplyEnd = embeddingEndElement ? positionInParentB eforeNode(*embeddingEndElement) : end; 676 Position embeddingApplyEnd = embeddingEndElement ? positionInParentB eforeNode(*embeddingEndElement) : end;
677 ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNul l()); 677 ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNul l());
678 678
679 if (!embeddingStyle) { 679 if (!embeddingStyle) {
680 styleWithoutEmbedding = style->copy(); 680 styleWithoutEmbedding = style->copy();
681 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDire ction(); 681 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDire ction();
682 } 682 }
683 fixRangeAndApplyInlineStyle(embeddingStyle.get(), embeddingApplyStar t, embeddingApplyEnd); 683 fixRangeAndApplyInlineStyle(embeddingStyle.get(), embeddingApplyStar t, embeddingApplyEnd);
684 684
685 styleToApply = styleWithoutEmbedding; 685 styleToApply = styleWithoutEmbedding;
686 } 686 }
687 } 687 }
688 688
689 fixRangeAndApplyInlineStyle(styleToApply.get(), start, end); 689 fixRangeAndApplyInlineStyle(styleToApply.get(), start, end);
690 690
691 // Remove dummy style spans created by splitting text elements. 691 // Remove dummy style spans created by splitting text elements.
692 cleanupUnstyledAppleStyleSpans(startDummySpanAncestor.get()); 692 cleanupUnstyledAppleStyleSpans(startDummySpanAncestor.get());
693 if (endDummySpanAncestor != startDummySpanAncestor) 693 if (endDummySpanAncestor != startDummySpanAncestor)
694 cleanupUnstyledAppleStyleSpans(endDummySpanAncestor.get()); 694 cleanupUnstyledAppleStyleSpans(endDummySpanAncestor.get());
695 } 695 }
696 696
697 void ApplyStyleCommand::fixRangeAndApplyInlineStyle(EditingStyle* style, const P osition& start, const Position& end) 697 void ApplyStyleCommand::fixRangeAndApplyInlineStyle(EditingStyle* style, const P osition& start, const Position& end)
698 { 698 {
699 Node* startNode = start.deprecatedNode(); 699 Node* startNode = start.anchorNode();
700 ASSERT(startNode); 700 ASSERT(startNode);
701 701
702 if (start.deprecatedEditingOffset() >= caretMaxOffset(start.deprecatedNode() )) { 702 if (start.deprecatedEditingOffset() >= caretMaxOffset(start.anchorNode())) {
703 startNode = NodeTraversal::next(*startNode); 703 startNode = NodeTraversal::next(*startNode);
704 if (!startNode || comparePositions(end, firstPositionInOrBeforeNode(star tNode)) < 0) 704 if (!startNode || comparePositions(end, firstPositionInOrBeforeNode(star tNode)) < 0)
705 return; 705 return;
706 } 706 }
707 707
708 Node* pastEndNode = end.deprecatedNode(); 708 Node* pastEndNode = end.anchorNode();
709 if (end.deprecatedEditingOffset() >= caretMaxOffset(end.deprecatedNode())) 709 if (end.deprecatedEditingOffset() >= caretMaxOffset(end.anchorNode()))
710 pastEndNode = NodeTraversal::nextSkippingChildren(*end.deprecatedNode()) ; 710 pastEndNode = NodeTraversal::nextSkippingChildren(*end.anchorNode());
711 711
712 // FIXME: Callers should perform this operation on a Range that includes the br 712 // FIXME: Callers should perform this operation on a Range that includes the br
713 // if they want style applied to the empty line. 713 // if they want style applied to the empty line.
714 if (start == end && isHTMLBRElement(*start.deprecatedNode())) 714 if (start == end && isHTMLBRElement(*start.anchorNode()))
715 pastEndNode = NodeTraversal::next(*start.deprecatedNode()); 715 pastEndNode = NodeTraversal::next(*start.anchorNode());
716 716
717 // Start from the highest fully selected ancestor so that we can modify the fully selected node. 717 // Start from the highest fully selected ancestor so that we can modify the fully selected node.
718 // e.g. When applying font-size: large on <font color="blue">hello</font>, w e need to include the font element in our run 718 // e.g. When applying font-size: large on <font color="blue">hello</font>, w e need to include the font element in our run
719 // to generate <font color="blue" size="4">hello</font> instead of <font col or="blue"><font size="4">hello</font></font> 719 // to generate <font color="blue" size="4">hello</font> instead of <font col or="blue"><font size="4">hello</font></font>
720 RefPtrWillBeRawPtr<Range> range = Range::create(startNode->document(), start , end); 720 RefPtrWillBeRawPtr<Range> range = Range::create(startNode->document(), start , end);
721 Element* editableRoot = startNode->rootEditableElement(); 721 Element* editableRoot = startNode->rootEditableElement();
722 if (startNode != editableRoot) { 722 if (startNode != editableRoot) {
723 while (editableRoot && startNode->parentNode() != editableRoot && isNode VisiblyContainedWithin(*startNode->parentNode(), *range)) 723 while (editableRoot && startNode->parentNode() != editableRoot && isNode VisiblyContainedWithin(*startNode->parentNode(), *range))
724 startNode = startNode->parentNode(); 724 startNode = startNode->parentNode();
725 } 725 }
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 if (pushDownStartContainer && pushDownStartContainer->isTextNode() 1129 if (pushDownStartContainer && pushDownStartContainer->isTextNode()
1130 && pushDownStart.computeOffsetInContainerNode() == pushDownStartContaine r->maxCharacterOffset()) 1130 && pushDownStart.computeOffsetInContainerNode() == pushDownStartContaine r->maxCharacterOffset())
1131 pushDownStart = nextVisuallyDistinctCandidate(pushDownStart); 1131 pushDownStart = nextVisuallyDistinctCandidate(pushDownStart);
1132 Position pushDownEnd = end.upstream(); 1132 Position pushDownEnd = end.upstream();
1133 // If pushDownEnd is at the start of a text node, then this node is not full y selected. 1133 // If pushDownEnd is at the start of a text node, then this node is not full y selected.
1134 // Move it to the previous deep equivalent position to avoid removing the st yle from this node. 1134 // Move it to the previous deep equivalent position to avoid removing the st yle from this node.
1135 Node* pushDownEndContainer = pushDownEnd.containerNode(); 1135 Node* pushDownEndContainer = pushDownEnd.containerNode();
1136 if (pushDownEndContainer && pushDownEndContainer->isTextNode() && !pushDownE nd.computeOffsetInContainerNode()) 1136 if (pushDownEndContainer && pushDownEndContainer->isTextNode() && !pushDownE nd.computeOffsetInContainerNode())
1137 pushDownEnd = previousVisuallyDistinctCandidate(pushDownEnd); 1137 pushDownEnd = previousVisuallyDistinctCandidate(pushDownEnd);
1138 1138
1139 pushDownInlineStyleAroundNode(style, pushDownStart.deprecatedNode()); 1139 pushDownInlineStyleAroundNode(style, pushDownStart.anchorNode());
1140 pushDownInlineStyleAroundNode(style, pushDownEnd.deprecatedNode()); 1140 pushDownInlineStyleAroundNode(style, pushDownEnd.anchorNode());
1141 1141
1142 // The s and e variables store the positions used to set the ending selectio n after style removal 1142 // The s and e variables store the positions used to set the ending selectio n after style removal
1143 // takes place. This will help callers to recognize when either the start no de or the end node 1143 // takes place. This will help callers to recognize when either the start no de or the end node
1144 // are removed from the document during the work of this function. 1144 // are removed from the document during the work of this function.
1145 // If pushDownInlineStyleAroundNode has pruned start.deprecatedNode() or end .deprecatedNode(), 1145 // If pushDownInlineStyleAroundNode has pruned start.anchorNode() or end.anc horNode(),
1146 // use pushDownStart or pushDownEnd instead, which pushDownInlineStyleAround Node won't prune. 1146 // use pushDownStart or pushDownEnd instead, which pushDownInlineStyleAround Node won't prune.
1147 Position s = start.isNull() || start.isOrphan() ? pushDownStart : start; 1147 Position s = start.isNull() || start.isOrphan() ? pushDownStart : start;
1148 Position e = end.isNull() || end.isOrphan() ? pushDownEnd : end; 1148 Position e = end.isNull() || end.isOrphan() ? pushDownEnd : end;
1149 1149
1150 // Current ending selection resetting algorithm assumes |start| and |end| 1150 // Current ending selection resetting algorithm assumes |start| and |end|
1151 // are in a same DOM tree even if they are not in document. 1151 // are in a same DOM tree even if they are not in document.
1152 if (!Position::commonAncestorTreeScope(start, end)) 1152 if (!Position::commonAncestorTreeScope(start, end))
1153 return; 1153 return;
1154 1154
1155 RefPtrWillBeRawPtr<Node> node = start.deprecatedNode(); 1155 RefPtrWillBeRawPtr<Node> node = start.anchorNode();
1156 while (node) { 1156 while (node) {
1157 RefPtrWillBeRawPtr<Node> next = nullptr; 1157 RefPtrWillBeRawPtr<Node> next = nullptr;
1158 if (editingIgnoresContent(node.get())) { 1158 if (editingIgnoresContent(node.get())) {
1159 ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecate dNode())); 1159 ASSERT(node == end.anchorNode() || !node->contains(end.anchorNode()) );
1160 next = NodeTraversal::nextSkippingChildren(*node); 1160 next = NodeTraversal::nextSkippingChildren(*node);
1161 } else { 1161 } else {
1162 next = NodeTraversal::next(*node); 1162 next = NodeTraversal::next(*node);
1163 } 1163 }
1164 if (node->isHTMLElement() && elementFullySelected(toHTMLElement(*node), start, end)) { 1164 if (node->isHTMLElement() && elementFullySelected(toHTMLElement(*node), start, end)) {
1165 RefPtrWillBeRawPtr<HTMLElement> elem = toHTMLElement(node); 1165 RefPtrWillBeRawPtr<HTMLElement> elem = toHTMLElement(node);
1166 RefPtrWillBeRawPtr<Node> prev = NodeTraversal::previousPostOrder(*el em); 1166 RefPtrWillBeRawPtr<Node> prev = NodeTraversal::previousPostOrder(*el em);
1167 RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*elem); 1167 RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*elem);
1168 RefPtrWillBeRawPtr<EditingStyle> styleToPushDown = nullptr; 1168 RefPtrWillBeRawPtr<EditingStyle> styleToPushDown = nullptr;
1169 RefPtrWillBeRawPtr<Node> childNode = nullptr; 1169 RefPtrWillBeRawPtr<Node> childNode = nullptr;
1170 if (isStyledInlineElementToRemove(elem.get())) { 1170 if (isStyledInlineElementToRemove(elem.get())) {
1171 styleToPushDown = EditingStyle::create(); 1171 styleToPushDown = EditingStyle::create();
1172 childNode = elem->firstChild(); 1172 childNode = elem->firstChild();
1173 } 1173 }
1174 1174
1175 removeInlineStyleFromElement(style, elem.get(), RemoveIfNeeded, styl eToPushDown.get()); 1175 removeInlineStyleFromElement(style, elem.get(), RemoveIfNeeded, styl eToPushDown.get());
1176 if (!elem->inDocument()) { 1176 if (!elem->inDocument()) {
1177 if (s.deprecatedNode() == elem) { 1177 if (s.anchorNode() == elem) {
1178 // Since elem must have been fully selected, and it is at th e start 1178 // Since elem must have been fully selected, and it is at th e start
1179 // of the selection, it is clear we can set the new s offset to 0. 1179 // of the selection, it is clear we can set the new s offset to 0.
1180 ASSERT(s.anchorType() == PositionAnchorType::BeforeAnchor || s.anchorType() == PositionAnchorType::BeforeChildren || s.offsetInContainerNode () <= 0); 1180 ASSERT(s.anchorType() == PositionAnchorType::BeforeAnchor || s.anchorType() == PositionAnchorType::BeforeChildren || s.offsetInContainerNode () <= 0);
1181 s = firstPositionInOrBeforeNode(next.get()); 1181 s = firstPositionInOrBeforeNode(next.get());
1182 } 1182 }
1183 if (e.deprecatedNode() == elem) { 1183 if (e.anchorNode() == elem) {
1184 // Since elem must have been fully selected, and it is at th e end 1184 // Since elem must have been fully selected, and it is at th e end
1185 // of the selection, it is clear we can set the new e offset to 1185 // of the selection, it is clear we can set the new e offset to
1186 // the max range offset of prev. 1186 // the max range offset of prev.
1187 ASSERT(s.anchorType() == PositionAnchorType::AfterAnchor || !offsetIsBeforeLastNodeOffset(s.offsetInContainerNode(), s.containerNode())); 1187 ASSERT(s.anchorType() == PositionAnchorType::AfterAnchor || !offsetIsBeforeLastNodeOffset(s.offsetInContainerNode(), s.containerNode()));
1188 e = lastPositionInOrAfterNode(prev.get()); 1188 e = lastPositionInOrAfterNode(prev.get());
1189 } 1189 }
1190 } 1190 }
1191 1191
1192 if (styleToPushDown) { 1192 if (styleToPushDown) {
1193 for (; childNode; childNode = childNode->nextSibling()) 1193 for (; childNode; childNode = childNode->nextSibling())
1194 applyInlineStyleToPushDown(childNode.get(), styleToPushDown. get()); 1194 applyInlineStyleToPushDown(childNode.get(), styleToPushDown. get());
1195 } 1195 }
1196 } 1196 }
1197 if (node == end.deprecatedNode()) 1197 if (node == end.anchorNode())
1198 break; 1198 break;
1199 node = next; 1199 node = next;
1200 } 1200 }
1201 1201
1202 updateStartEnd(s, e); 1202 updateStartEnd(s, e);
1203 } 1203 }
1204 1204
1205 bool ApplyStyleCommand::elementFullySelected(HTMLElement& element, const Positio n& start, const Position& end) const 1205 bool ApplyStyleCommand::elementFullySelected(HTMLElement& element, const Positio n& start, const Position& end) const
1206 { 1206 {
1207 // The tree may have changed and Position::upstream() relies on an up-to-dat e layout. 1207 // The tree may have changed and Position::upstream() relies on an up-to-dat e layout.
(...skipping 16 matching lines...) Expand all
1224 RefPtrWillBeRawPtr<Text> text = start.containerText(); 1224 RefPtrWillBeRawPtr<Text> text = start.containerText();
1225 splitTextNode(text, start.offsetInContainerNode()); 1225 splitTextNode(text, start.offsetInContainerNode());
1226 updateStartEnd(firstPositionInNode(text.get()), newEnd); 1226 updateStartEnd(firstPositionInNode(text.get()), newEnd);
1227 } 1227 }
1228 1228
1229 void ApplyStyleCommand::splitTextAtEnd(const Position& start, const Position& en d) 1229 void ApplyStyleCommand::splitTextAtEnd(const Position& start, const Position& en d)
1230 { 1230 {
1231 ASSERT(end.containerNode()->isTextNode()); 1231 ASSERT(end.containerNode()->isTextNode());
1232 1232
1233 bool shouldUpdateStart = start.anchorType() == PositionAnchorType::OffsetInA nchor && start.containerNode() == end.containerNode(); 1233 bool shouldUpdateStart = start.anchorType() == PositionAnchorType::OffsetInA nchor && start.containerNode() == end.containerNode();
1234 Text* text = toText(end.deprecatedNode()); 1234 Text* text = toText(end.anchorNode());
1235 splitTextNode(text, end.offsetInContainerNode()); 1235 splitTextNode(text, end.offsetInContainerNode());
1236 1236
1237 Node* prevNode = text->previousSibling(); 1237 Node* prevNode = text->previousSibling();
1238 if (!prevNode || !prevNode->isTextNode()) 1238 if (!prevNode || !prevNode->isTextNode())
1239 return; 1239 return;
1240 1240
1241 Position newStart = shouldUpdateStart ? Position(toText(prevNode), start.off setInContainerNode()) : start; 1241 Position newStart = shouldUpdateStart ? Position(toText(prevNode), start.off setInContainerNode()) : start;
1242 updateStartEnd(newStart, lastPositionInNode(prevNode)); 1242 updateStartEnd(newStart, lastPositionInNode(prevNode));
1243 } 1243 }
1244 1244
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 Node* previousSibling = startNode->previousSibling(); 1315 Node* previousSibling = startNode->previousSibling();
1316 1316
1317 if (previousSibling && areIdenticalElements(startNode, previousSibling)) { 1317 if (previousSibling && areIdenticalElements(startNode, previousSibling)) {
1318 Element* previousElement = toElement(previousSibling); 1318 Element* previousElement = toElement(previousSibling);
1319 Element* element = toElement(startNode); 1319 Element* element = toElement(startNode);
1320 Node* startChild = element->firstChild(); 1320 Node* startChild = element->firstChild();
1321 ASSERT(startChild); 1321 ASSERT(startChild);
1322 mergeIdenticalElements(previousElement, element); 1322 mergeIdenticalElements(previousElement, element);
1323 1323
1324 int startOffsetAdjustment = startChild->nodeIndex(); 1324 int startOffsetAdjustment = startChild->nodeIndex();
1325 int endOffsetAdjustment = startNode == end.deprecatedNode() ? startOffse tAdjustment : 0; 1325 int endOffsetAdjustment = startNode == end.anchorNode() ? startOffsetAdj ustment : 0;
1326 updateStartEnd(Position(startNode, startOffsetAdjustment), 1326 updateStartEnd(Position(startNode, startOffsetAdjustment),
1327 Position(end.deprecatedNode(), end.deprecatedEditingOffset() + endOf fsetAdjustment)); 1327 Position(end.anchorNode(), end.deprecatedEditingOffset() + endOffset Adjustment));
1328 return true; 1328 return true;
1329 } 1329 }
1330 1330
1331 return false; 1331 return false;
1332 } 1332 }
1333 1333
1334 bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const Position& end) 1334 bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const Position& end)
1335 { 1335 {
1336 Node* endNode = end.containerNode(); 1336 Node* endNode = end.containerNode();
1337 1337
1338 if (isAtomicNode(endNode)) { 1338 if (isAtomicNode(endNode)) {
1339 int endOffset = end.computeOffsetInContainerNode(); 1339 int endOffset = end.computeOffsetInContainerNode();
1340 if (offsetIsBeforeLastNodeOffset(endOffset, endNode)) 1340 if (offsetIsBeforeLastNodeOffset(endOffset, endNode))
1341 return false; 1341 return false;
1342 1342
1343 if (end.deprecatedNode()->nextSibling()) 1343 if (end.anchorNode()->nextSibling())
1344 return false; 1344 return false;
1345 1345
1346 endNode = end.deprecatedNode()->parentNode(); 1346 endNode = end.anchorNode()->parentNode();
1347 } 1347 }
1348 1348
1349 if (!endNode->isElementNode() || isHTMLBRElement(*endNode)) 1349 if (!endNode->isElementNode() || isHTMLBRElement(*endNode))
1350 return false; 1350 return false;
1351 1351
1352 Node* nextSibling = endNode->nextSibling(); 1352 Node* nextSibling = endNode->nextSibling();
1353 if (nextSibling && areIdenticalElements(endNode, nextSibling)) { 1353 if (nextSibling && areIdenticalElements(endNode, nextSibling)) {
1354 Element* nextElement = toElement(nextSibling); 1354 Element* nextElement = toElement(nextSibling);
1355 Element* element = toElement(endNode); 1355 Element* element = toElement(endNode);
1356 Node* nextChild = nextElement->firstChild(); 1356 Node* nextChild = nextElement->firstChild();
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 DEFINE_TRACE(ApplyStyleCommand) 1594 DEFINE_TRACE(ApplyStyleCommand)
1595 { 1595 {
1596 visitor->trace(m_style); 1596 visitor->trace(m_style);
1597 visitor->trace(m_start); 1597 visitor->trace(m_start);
1598 visitor->trace(m_end); 1598 visitor->trace(m_end);
1599 visitor->trace(m_styledInlineElement); 1599 visitor->trace(m_styledInlineElement);
1600 CompositeEditCommand::trace(visitor); 1600 CompositeEditCommand::trace(visitor);
1601 } 1601 }
1602 1602
1603 } 1603 }
OLDNEW
« no previous file with comments | « Source/core/editing/ApplyBlockElementCommand.cpp ('k') | Source/core/editing/BreakBlockquoteCommand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698