OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. |
4 * Copyright (C) 2011 Igalia S.L. | 4 * Copyright (C) 2011 Igalia S.L. |
5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. | 5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. |
6 * | 6 * |
7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
9 * are met: | 9 * are met: |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 VisiblePosition next = v.next(); | 470 VisiblePosition next = v.next(); |
471 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode(); | 471 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode(); |
472 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode(); | 472 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode(); |
473 // Add an interchange newline if a paragraph break is selected and a br won'
t already be added to the markup to represent it. | 473 // Add an interchange newline if a paragraph break is selected and a br won'
t already be added to the markup to represent it. |
474 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(upstreamNode->ha
sTagName(brTag) && upstreamNode == downstreamNode); | 474 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(upstreamNode->ha
sTagName(brTag) && upstreamNode == downstreamNode); |
475 } | 475 } |
476 | 476 |
477 static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* n
ode) | 477 static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* n
ode) |
478 { | 478 { |
479 if (!node->isHTMLElement()) | 479 if (!node->isHTMLElement()) |
480 return 0; | 480 return nullptr; |
481 | 481 |
482 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t
o untangle | 482 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t
o untangle |
483 // the non-const-ness of styleFromMatchedRulesForElement. | 483 // the non-const-ness of styleFromMatchedRulesForElement. |
484 HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node)); | 484 HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node)); |
485 RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle()); | 485 RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle()); |
486 style->mergeStyleFromRules(element); | 486 style->mergeStyleFromRules(element); |
487 return style.release(); | 487 return style.release(); |
488 } | 488 } |
489 | 489 |
490 static bool isElementPresentational(const Node* node) | 490 static bool isElementPresentational(const Node* node) |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 RefPtr<Document> taggedDocument = Document::create(); | 703 RefPtr<Document> taggedDocument = Document::create(); |
704 taggedDocument->setContextFeatures(document.contextFeatures()); | 704 taggedDocument->setContextFeatures(document.contextFeatures()); |
705 | 705 |
706 // FIXME: It's not clear what this code is trying to do. It puts nodes as di
rect children of a | 706 // FIXME: It's not clear what this code is trying to do. It puts nodes as di
rect children of a |
707 // Document that are not normally allowed by using the parser machinery. | 707 // Document that are not normally allowed by using the parser machinery. |
708 taggedDocument->parserTakeAllChildrenFrom(*taggedFragment); | 708 taggedDocument->parserTakeAllChildrenFrom(*taggedFragment); |
709 | 709 |
710 RefPtr<Node> nodeBeforeContext; | 710 RefPtr<Node> nodeBeforeContext; |
711 RefPtr<Node> nodeAfterContext; | 711 RefPtr<Node> nodeAfterContext; |
712 if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, no
deAfterContext)) | 712 if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, no
deAfterContext)) |
713 return 0; | 713 return nullptr; |
714 | 714 |
715 RefPtr<Range> range = Range::create(*taggedDocument.get(), | 715 RefPtr<Range> range = Range::create(*taggedDocument.get(), |
716 positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(), | 716 positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(), |
717 positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent()); | 717 positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent()); |
718 | 718 |
719 Node* commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEPTION); | 719 Node* commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEPTION); |
720 Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRe
nderer(commonAncestor); | 720 Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRe
nderer(commonAncestor); |
721 | 721 |
722 // When there's a special common ancestor outside of the fragment, we must i
nclude it as well to | 722 // When there's a special common ancestor outside of the fragment, we must i
nclude it as well to |
723 // preserve the structure and appearance of the fragment. For example, if th
e fragment contains | 723 // preserve the structure and appearance of the fragment. For example, if th
e fragment contains |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 if (RenderObject* renderer = node->renderer()) | 808 if (RenderObject* renderer = node->renderer()) |
809 return renderer->style()->preserveNewline(); | 809 return renderer->style()->preserveNewline(); |
810 } | 810 } |
811 | 811 |
812 return false; | 812 return false; |
813 } | 813 } |
814 | 814 |
815 PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
& text) | 815 PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
& text) |
816 { | 816 { |
817 if (!context) | 817 if (!context) |
818 return 0; | 818 return nullptr; |
819 | 819 |
820 Document& document = context->ownerDocument(); | 820 Document& document = context->ownerDocument(); |
821 RefPtr<DocumentFragment> fragment = document.createDocumentFragment(); | 821 RefPtr<DocumentFragment> fragment = document.createDocumentFragment(); |
822 | 822 |
823 if (text.isEmpty()) | 823 if (text.isEmpty()) |
824 return fragment.release(); | 824 return fragment.release(); |
825 | 825 |
826 String string = text; | 826 String string = text; |
827 string.replace("\r\n", "\n"); | 827 string.replace("\r\n", "\n"); |
828 string.replace('\r', '\n'); | 828 string.replace('\r', '\n'); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document); | 914 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document); |
915 | 915 |
916 if (document.isHTMLDocument()) { | 916 if (document.isHTMLDocument()) { |
917 fragment->parseHTML(markup, contextElement, parserContentPolicy); | 917 fragment->parseHTML(markup, contextElement, parserContentPolicy); |
918 return fragment; | 918 return fragment; |
919 } | 919 } |
920 | 920 |
921 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli
cy); | 921 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli
cy); |
922 if (!wasValid) { | 922 if (!wasValid) { |
923 exceptionState.throwDOMException(SyntaxError, "The provided markup is in
valid XML, and therefore cannot be inserted into an XML document."); | 923 exceptionState.throwDOMException(SyntaxError, "The provided markup is in
valid XML, and therefore cannot be inserted into an XML document."); |
924 return 0; | 924 return nullptr; |
925 } | 925 } |
926 return fragment.release(); | 926 return fragment.release(); |
927 } | 927 } |
928 | 928 |
929 PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String&
sourceString, const String& sourceMIMEType, Document& outputDoc) | 929 PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String&
sourceString, const String& sourceMIMEType, Document& outputDoc) |
930 { | 930 { |
931 RefPtr<DocumentFragment> fragment = outputDoc.createDocumentFragment(); | 931 RefPtr<DocumentFragment> fragment = outputDoc.createDocumentFragment(); |
932 | 932 |
933 if (sourceMIMEType == "text/html") { | 933 if (sourceMIMEType == "text/html") { |
934 // As far as I can tell, there isn't a spec for how transformToFragment
is supposed to work. | 934 // As far as I can tell, there isn't a spec for how transformToFragment
is supposed to work. |
935 // Based on the documentation I can find, it looks like we want to start
parsing the fragment in the InBody insertion mode. | 935 // Based on the documentation I can find, it looks like we want to start
parsing the fragment in the InBody insertion mode. |
936 // Unfortunately, that's an implementation detail of the parser. | 936 // Unfortunately, that's an implementation detail of the parser. |
937 // We achieve that effect here by passing in a fake body element as cont
ext for the fragment. | 937 // We achieve that effect here by passing in a fake body element as cont
ext for the fragment. |
938 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc); | 938 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc); |
939 fragment->parseHTML(sourceString, fakeBody.get()); | 939 fragment->parseHTML(sourceString, fakeBody.get()); |
940 } else if (sourceMIMEType == "text/plain") { | 940 } else if (sourceMIMEType == "text/plain") { |
941 fragment->parserAppendChild(Text::create(outputDoc, sourceString)); | 941 fragment->parserAppendChild(Text::create(outputDoc, sourceString)); |
942 } else { | 942 } else { |
943 bool successfulParse = fragment->parseXML(sourceString, 0); | 943 bool successfulParse = fragment->parseXML(sourceString, 0); |
944 if (!successfulParse) | 944 if (!successfulParse) |
945 return 0; | 945 return nullptr; |
946 } | 946 } |
947 | 947 |
948 // FIXME: Do we need to mess with URLs here? | 948 // FIXME: Do we need to mess with URLs here? |
949 | 949 |
950 return fragment.release(); | 950 return fragment.release(); |
951 } | 951 } |
952 | 952 |
953 static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment>
fragment, HTMLElement* element) | 953 static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment>
fragment, HTMLElement* element) |
954 { | 954 { |
955 RefPtr<Node> nextChild; | 955 RefPtr<Node> nextChild; |
956 for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) { | 956 for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) { |
957 nextChild = child->nextSibling(); | 957 nextChild = child->nextSibling(); |
958 element->removeChild(child.get()); | 958 element->removeChild(child.get()); |
959 fragment->insertBefore(child, element); | 959 fragment->insertBefore(child, element); |
960 } | 960 } |
961 fragment->removeChild(element); | 961 fragment->removeChild(element); |
962 } | 962 } |
963 | 963 |
964 PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTML
Element* element, ParserContentPolicy parserContentPolicy, ExceptionState& excep
tionState) | 964 PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTML
Element* element, ParserContentPolicy parserContentPolicy, ExceptionState& excep
tionState) |
965 { | 965 { |
966 ASSERT(element); | 966 ASSERT(element); |
967 if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || eleme
nt->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag) | 967 if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || eleme
nt->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag) |
968 || element->hasLocalName(headTag) || element->hasLocalName(styleTag) ||
element->hasLocalName(titleTag)) { | 968 || element->hasLocalName(headTag) || element->hasLocalName(styleTag) ||
element->hasLocalName(titleTag)) { |
969 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er is '" + element->localName() + "', which is not supported."); | 969 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er is '" + element->localName() + "', which is not supported."); |
970 return 0; | 970 return nullptr; |
971 } | 971 } |
972 | 972 |
973 RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup,
element, parserContentPolicy, "createContextualFragment", exceptionState); | 973 RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup,
element, parserContentPolicy, "createContextualFragment", exceptionState); |
974 if (!fragment) | 974 if (!fragment) |
975 return 0; | 975 return nullptr; |
976 | 976 |
977 // We need to pop <html> and <body> elements and remove <head> to | 977 // We need to pop <html> and <body> elements and remove <head> to |
978 // accommodate folks passing complete HTML documents to make the | 978 // accommodate folks passing complete HTML documents to make the |
979 // child of an element. | 979 // child of an element. |
980 | 980 |
981 RefPtr<Node> nextNode; | 981 RefPtr<Node> nextNode; |
982 for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) { | 982 for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) { |
983 nextNode = node->nextSibling(); | 983 nextNode = node->nextSibling(); |
984 if (node->hasTagName(htmlTag) || node->hasTagName(headTag) || node->hasT
agName(bodyTag)) { | 984 if (node->hasTagName(htmlTag) || node->hasTagName(headTag) || node->hasT
agName(bodyTag)) { |
985 HTMLElement* element = toHTMLElement(node); | 985 HTMLElement* element = toHTMLElement(node); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 return; | 1048 return; |
1049 | 1049 |
1050 RefPtr<Text> textNode = toText(node.get()); | 1050 RefPtr<Text> textNode = toText(node.get()); |
1051 RefPtr<Text> textNext = toText(next); | 1051 RefPtr<Text> textNext = toText(next); |
1052 textNode->appendData(textNext->data()); | 1052 textNode->appendData(textNext->data()); |
1053 if (textNext->parentNode()) // Might have been removed by mutation event. | 1053 if (textNext->parentNode()) // Might have been removed by mutation event. |
1054 textNext->remove(exceptionState); | 1054 textNext->remove(exceptionState); |
1055 } | 1055 } |
1056 | 1056 |
1057 } | 1057 } |
OLD | NEW |