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

Side by Side Diff: WebCore/dom/Range.cpp

Issue 6129003: Merge 73799 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/597/
Patch Set: Created 9 years, 11 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 | « LayoutTests/fast/dom/Range/range-extractContents-expected.txt ('k') | no next file » | 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 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
5 * (C) 2001 Peter Kelly (pmk@post.com) 5 * (C) 2001 Peter Kelly (pmk@post.com)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 23 matching lines...) Expand all
34 #include "ProcessingInstruction.h" 34 #include "ProcessingInstruction.h"
35 #include "Text.h" 35 #include "Text.h"
36 #include "TextIterator.h" 36 #include "TextIterator.h"
37 #include "VisiblePosition.h" 37 #include "VisiblePosition.h"
38 #include "htmlediting.h" 38 #include "htmlediting.h"
39 #include "markup.h" 39 #include "markup.h"
40 #include "visible_units.h" 40 #include "visible_units.h"
41 #include <stdio.h> 41 #include <stdio.h>
42 #include <wtf/text/CString.h> 42 #include <wtf/text/CString.h>
43 #include <wtf/RefCountedLeakCounter.h> 43 #include <wtf/RefCountedLeakCounter.h>
44 #include <wtf/Vector.h>
44 45
45 namespace WebCore { 46 namespace WebCore {
46 47
48 typedef Vector<RefPtr<Node> > NodeVector;
49
47 using namespace std; 50 using namespace std;
48 51
49 #ifndef NDEBUG 52 #ifndef NDEBUG
50 static WTF::RefCountedLeakCounter rangeCounter("Range"); 53 static WTF::RefCountedLeakCounter rangeCounter("Range");
51 #endif 54 #endif
52 55
53 inline Range::Range(PassRefPtr<Document> ownerDocument) 56 inline Range::Range(PassRefPtr<Document> ownerDocument)
54 : m_ownerDocument(ownerDocument) 57 : m_ownerDocument(ownerDocument)
55 , m_start(m_ownerDocument) 58 , m_start(m_ownerDocument)
56 , m_end(m_ownerDocument) 59 , m_end(m_ownerDocument)
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 } else if (comparePoint(parentNode, nodeIndex, ec) > 0 && // starts after en d 591 } else if (comparePoint(parentNode, nodeIndex, ec) > 0 && // starts after en d
589 comparePoint(parentNode, nodeIndex + 1, ec) > 0) { // ends after end 592 comparePoint(parentNode, nodeIndex + 1, ec) > 0) { // ends after end
590 return false; 593 return false;
591 } 594 }
592 595
593 return true; // all other cases 596 return true; // all other cases
594 } 597 }
595 598
596 PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception Code& ec) 599 PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception Code& ec)
597 { 600 {
598 // FIXME: To work properly with mutation events, we will have to take into a ccount
599 // situations where the tree is being transformed while we work on it - ugh!
600
601 RefPtr<DocumentFragment> fragment; 601 RefPtr<DocumentFragment> fragment;
602 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) 602 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
603 fragment = DocumentFragment::create(m_ownerDocument.get()); 603 fragment = DocumentFragment::create(m_ownerDocument.get());
604 604
605 ec = 0; 605 ec = 0;
606 if (collapsed(ec)) 606 if (collapsed(ec))
607 return fragment.release(); 607 return fragment.release();
608 if (ec) 608 if (ec)
609 return 0; 609 return 0;
610 610
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 c->setData(c->data().substring(m_start.offset(), m_end.offset() - m_start.offset()), ec); 648 c->setData(c->data().substring(m_start.offset(), m_end.offset() - m_start.offset()), ec);
649 fragment->appendChild(c.release(), ec); 649 fragment->appendChild(c.release(), ec);
650 } 650 }
651 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { 651 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
652 ProcessingInstruction* pi = static_cast<ProcessingInstruction*>( m_start.container()); 652 ProcessingInstruction* pi = static_cast<ProcessingInstruction*>( m_start.container());
653 String data(pi->data()); 653 String data(pi->data());
654 data.remove(m_start.offset(), m_end.offset() - m_start.offset()) ; 654 data.remove(m_start.offset(), m_end.offset() - m_start.offset()) ;
655 pi->setData(data, ec); 655 pi->setData(data, ec);
656 } 656 }
657 } else { 657 } else {
658 Node* n = m_start.container()->firstChild(); 658 RefPtr<Node> n = m_start.container()->firstChild();
659 int i; 659 int i;
660 for (i = 0; n && i < m_start.offset(); i++) // skip until start offs et 660 for (i = 0; n && i < m_start.offset(); i++) // skip until start offs et
661 n = n->nextSibling(); 661 n = n->nextSibling();
662 int endOffset = m_end.offset(); 662 int endOffset = m_end.offset();
663 while (n && i < endOffset) { // delete until end offset 663 RefPtr<Node> next;
664 Node* next = n->nextSibling(); 664 for (; n && i < endOffset; n = next, i++) { // delete until end offs et
665 next = n->nextSibling();
665 if (action == EXTRACT_CONTENTS) 666 if (action == EXTRACT_CONTENTS)
666 fragment->appendChild(n, ec); // will remove n from its pare nt 667 fragment->appendChild(n, ec); // will remove n from its pare nt
667 else if (action == CLONE_CONTENTS) 668 else if (action == CLONE_CONTENTS)
668 fragment->appendChild(n->cloneNode(true), ec); 669 fragment->appendChild(n->cloneNode(true), ec);
669 else 670 else
670 toContainerNode(m_start.container())->removeChild(n, ec); 671 toContainerNode(m_start.container())->removeChild(n.get(), e c);
671 n = next;
672 i++;
673 } 672 }
674 } 673 }
675 return fragment.release(); 674 return fragment.release();
676 } 675 }
677 676
678 // Complex case: Start and end containers are different. 677 // Complex case: Start and end containers are different.
679 // There are three possibilities here: 678 // There are three possibilities here:
680 // 1. Start container == commonRoot (End container must be a descendant) 679 // 1. Start container == commonRoot (End container must be a descendant)
681 // 2. End container == commonRoot (Start container must be a descendant) 680 // 2. End container == commonRoot (Start container must be a descendant)
682 // 3. Neither is commonRoot, they are both descendants 681 // 3. Neither is commonRoot, they are both descendants
(...skipping 30 matching lines...) Expand all
713 leftContents = c.release(); 712 leftContents = c.release();
714 } 713 }
715 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { 714 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
716 ProcessingInstruction* pi = static_cast<ProcessingInstruction*>( m_start.container()); 715 ProcessingInstruction* pi = static_cast<ProcessingInstruction*>( m_start.container());
717 String data(pi->data()); 716 String data(pi->data());
718 pi->setData(data.left(m_start.offset()), ec); 717 pi->setData(data.left(m_start.offset()), ec);
719 } 718 }
720 } else { 719 } else {
721 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) 720 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
722 leftContents = m_start.container()->cloneNode(false); 721 leftContents = m_start.container()->cloneNode(false);
722 NodeVector nodes;
723 Node* n = m_start.container()->firstChild(); 723 Node* n = m_start.container()->firstChild();
724 for (int i = 0; n && i < m_start.offset(); i++) // skip until start offset 724 for (int i = 0; n; n = n->nextSibling(), i++) {
725 n = n->nextSibling(); 725 if (i < m_start.offset())
726 while (n) { // process until end 726 continue; // Skip until start offset.
727 Node* next = n->nextSibling(); 727 nodes.append(n);
728 }
729 for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end( ); it++) {
730 Node* n = it->get();
728 if (action == EXTRACT_CONTENTS) 731 if (action == EXTRACT_CONTENTS)
729 leftContents->appendChild(n, ec); // will remove n from star t container 732 leftContents->appendChild(n, ec); // Will remove n from star t container.
730 else if (action == CLONE_CONTENTS) 733 else if (action == CLONE_CONTENTS)
731 leftContents->appendChild(n->cloneNode(true), ec); 734 leftContents->appendChild(n->cloneNode(true), ec);
732 else 735 else
733 toContainerNode(m_start.container())->removeChild(n, ec); 736 toContainerNode(m_start.container())->removeChild(n, ec);
734 n = next;
735 } 737 }
736 } 738 }
737 739
738 ContainerNode* leftParent = m_start.container()->parentNode(); 740 NodeVector ancestorNodes;
739 Node* n = m_start.container()->nextSibling(); 741 for (ContainerNode* n = m_start.container()->parentNode(); n && n != com monRoot; n = n->parentNode())
740 for (; leftParent != commonRoot; leftParent = leftParent->parentNode()) { 742 ancestorNodes.append(n);
743 RefPtr<Node> n = m_start.container()->nextSibling();
744 for (NodeVector::const_iterator it = ancestorNodes.begin(); it != ancest orNodes.end(); it++) {
745 Node* leftParent = it->get();
741 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { 746 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
742 RefPtr<Node> leftContentsParent = leftParent->cloneNode(false); 747 RefPtr<Node> leftContentsParent = leftParent->cloneNode(false);
743 leftContentsParent->appendChild(leftContents, ec); 748 if (leftContentsParent) { // Might have been removed already dur ing mutation event.
744 leftContents = leftContentsParent; 749 leftContentsParent->appendChild(leftContents, ec);
750 leftContents = leftContentsParent;
751 }
745 } 752 }
746 753
747 Node* next; 754 RefPtr<Node> next;
748 for (; n; n = next) { 755 for (; n; n = next) {
749 next = n->nextSibling(); 756 next = n->nextSibling();
750 if (action == EXTRACT_CONTENTS) 757 if (action == EXTRACT_CONTENTS)
751 leftContents->appendChild(n, ec); // will remove n from left Parent 758 leftContents->appendChild(n.get(), ec); // will remove n fro m leftParent
752 else if (action == CLONE_CONTENTS) 759 else if (action == CLONE_CONTENTS)
753 leftContents->appendChild(n->cloneNode(true), ec); 760 leftContents->appendChild(n->cloneNode(true), ec);
754 else 761 else
755 leftParent->removeChild(n, ec); 762 leftParent->removeChild(n.get(), ec);
756 } 763 }
757 n = leftParent->nextSibling(); 764 n = leftParent->nextSibling();
758 } 765 }
759 } 766 }
760 767
761 RefPtr<Node> rightContents; 768 RefPtr<Node> rightContents;
762 if (m_end.container() != commonRoot) { 769 if (m_end.container() != commonRoot) {
763 // delete the right-hand side of the range, up until the last ancestor o f 770 // delete the right-hand side of the range, up until the last ancestor o f
764 // end container before commonRoot 771 // end container before commonRoot
765 Node::NodeType endNodeType = m_end.container()->nodeType(); 772 Node::NodeType endNodeType = m_end.container()->nodeType();
(...skipping 13 matching lines...) Expand all
779 } 786 }
780 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { 787 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
781 ProcessingInstruction* pi = static_cast<ProcessingInstruction*>( m_end.container()); 788 ProcessingInstruction* pi = static_cast<ProcessingInstruction*>( m_end.container());
782 pi->setData(pi->data().substring(m_end.offset()), ec); 789 pi->setData(pi->data().substring(m_end.offset()), ec);
783 } 790 }
784 } else { 791 } else {
785 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) 792 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
786 rightContents = m_end.container()->cloneNode(false); 793 rightContents = m_end.container()->cloneNode(false);
787 Node* n = m_end.container()->firstChild(); 794 Node* n = m_end.container()->firstChild();
788 if (n && m_end.offset()) { 795 if (n && m_end.offset()) {
789 for (int i = 0; i + 1 < m_end.offset(); i++) { // skip to end.of fset() 796 NodeVector nodes;
790 Node* next = n->nextSibling(); 797 for (int i = 0; i + 1 < m_end.offset() && n; i++, n = n->nextSib ling()) {
791 if (!next) 798 nodes.append(n);
792 break;
793 n = next;
794 } 799 }
795 Node* prev; 800 for (int i = nodes.size() - 1; i >= 0; i--) {
796 for (; n; n = prev) { 801 Node* n = nodes[i].get();
797 prev = n->previousSibling();
798 if (action == EXTRACT_CONTENTS) 802 if (action == EXTRACT_CONTENTS)
799 rightContents->insertBefore(n, rightContents->firstChild (), ec); // will remove n from its parent 803 rightContents->insertBefore(n, rightContents->firstChild (), ec); // will remove n from its parent
800 else if (action == CLONE_CONTENTS) 804 else if (action == CLONE_CONTENTS)
801 rightContents->insertBefore(n->cloneNode(true), rightCon tents->firstChild(), ec); 805 rightContents->insertBefore(n->cloneNode(true), rightCon tents->firstChild(), ec);
802 else 806 else
803 toContainerNode(m_end.container())->removeChild(n, ec); 807 toContainerNode(m_end.container())->removeChild(n, ec);
804 } 808 }
805 } 809 }
806 } 810 }
807 811
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 return 0; 865 return 0;
862 m_end = m_start; 866 m_end = m_start;
863 } 867 }
864 868
865 // Now add leftContents, stuff in between, and rightContents to the fragment 869 // Now add leftContents, stuff in between, and rightContents to the fragment
866 // (or just delete the stuff in between) 870 // (or just delete the stuff in between)
867 871
868 if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents ) 872 if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents )
869 fragment->appendChild(leftContents, ec); 873 fragment->appendChild(leftContents, ec);
870 874
871 Node* next;
872 Node* n;
873 if (processStart) { 875 if (processStart) {
874 for (n = processStart; n && n != processEnd; n = next) { 876 NodeVector nodes;
875 next = n->nextSibling(); 877 for (Node* n = processStart; n && n != processEnd; n = n->nextSibling())
878 nodes.append(n);
879 for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); i t++) {
880 Node* n = it->get();
876 if (action == EXTRACT_CONTENTS) 881 if (action == EXTRACT_CONTENTS)
877 fragment->appendChild(n, ec); // will remove from commonRoot 882 fragment->appendChild(n, ec); // will remove from commonRoot
878 else if (action == CLONE_CONTENTS) 883 else if (action == CLONE_CONTENTS)
879 fragment->appendChild(n->cloneNode(true), ec); 884 fragment->appendChild(n->cloneNode(true), ec);
880 else 885 else
881 commonRoot->removeChild(n, ec); 886 commonRoot->removeChild(n, ec);
882 } 887 }
883 } 888 }
884 889
885 if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && rightContent s) 890 if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && rightContent s)
(...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 { 1984 {
1980 if (range && range->boundaryPointsValid()) { 1985 if (range && range->boundaryPointsValid()) {
1981 WebCore::Position start = range->startPosition(); 1986 WebCore::Position start = range->startPosition();
1982 WebCore::Position end = range->endPosition(); 1987 WebCore::Position end = range->endPosition();
1983 start.node()->showTreeAndMark(start.node(), "S", end.node(), "E"); 1988 start.node()->showTreeAndMark(start.node(), "S", end.node(), "E");
1984 fprintf(stderr, "start offset: %d, end offset: %d\n", start.deprecatedEd itingOffset(), end.deprecatedEditingOffset()); 1989 fprintf(stderr, "start offset: %d, end offset: %d\n", start.deprecatedEd itingOffset(), end.deprecatedEditingOffset());
1985 } 1990 }
1986 } 1991 }
1987 1992
1988 #endif 1993 #endif
OLDNEW
« no previous file with comments | « LayoutTests/fast/dom/Range/range-extractContents-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698