| 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 |