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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 const bool parentIsTextarea = text->parentElement() && text->parentElement()
->tagQName() == textareaTag; | 218 const bool parentIsTextarea = text->parentElement() && text->parentElement()
->tagQName() == textareaTag; |
219 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare
a; | 219 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare
a; |
220 if (wrappingSpan) { | 220 if (wrappingSpan) { |
221 RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy(); | 221 RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy(); |
222 // FIXME: <rdar://problem/5371536> Style rules that match pasted content
can change it's appearance | 222 // FIXME: <rdar://problem/5371536> Style rules that match pasted content
can change it's appearance |
223 // Make sure spans are inline style in paste side e.g. span { display: b
lock }. | 223 // Make sure spans are inline style in paste side e.g. span { display: b
lock }. |
224 wrappingStyle->forceInline(); | 224 wrappingStyle->forceInline(); |
225 // FIXME: Should this be included in forceInline? | 225 // FIXME: Should this be included in forceInline? |
226 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone); | 226 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone); |
227 | 227 |
228 appendStyleNodeOpenTag(out, wrappingStyle->style(), text->document()); | 228 appendStyleNodeOpenTag(out, wrappingStyle->style(), &text->document()); |
229 } | 229 } |
230 | 230 |
231 if (!shouldAnnotate() || parentIsTextarea) | 231 if (!shouldAnnotate() || parentIsTextarea) |
232 MarkupAccumulator::appendText(out, text); | 232 MarkupAccumulator::appendText(out, text); |
233 else { | 233 else { |
234 const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(t
ext), selectTag); | 234 const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(t
ext), selectTag); |
235 String content = useRenderedText ? renderedText(text, m_range) : stringV
alueForRange(text, m_range); | 235 String content = useRenderedText ? renderedText(text, m_range) : stringV
alueForRange(text, m_range); |
236 StringBuilder buffer; | 236 StringBuilder buffer; |
237 appendCharactersReplacingEntities(buffer, content, 0, content.length(),
EntityMaskInPCDATA); | 237 appendCharactersReplacingEntities(buffer, content, 0, content.length(),
EntityMaskInPCDATA); |
238 out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text)); | 238 out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text)); |
(...skipping 12 matching lines...) Expand all Loading... |
251 unsigned startOffset = 0; | 251 unsigned startOffset = 0; |
252 unsigned endOffset = textNode->length(); | 252 unsigned endOffset = textNode->length(); |
253 | 253 |
254 if (range && node == range->startContainer()) | 254 if (range && node == range->startContainer()) |
255 startOffset = range->startOffset(); | 255 startOffset = range->startOffset(); |
256 if (range && node == range->endContainer()) | 256 if (range && node == range->endContainer()) |
257 endOffset = range->endOffset(); | 257 endOffset = range->endOffset(); |
258 | 258 |
259 Position start = createLegacyEditingPosition(const_cast<Node*>(node), startO
ffset); | 259 Position start = createLegacyEditingPosition(const_cast<Node*>(node), startO
ffset); |
260 Position end = createLegacyEditingPosition(const_cast<Node*>(node), endOffse
t); | 260 Position end = createLegacyEditingPosition(const_cast<Node*>(node), endOffse
t); |
261 return plainText(Range::create(node->document(), start, end).get()); | 261 return plainText(Range::create(&node->document(), start, end).get()); |
262 } | 262 } |
263 | 263 |
264 String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Rang
e* range) | 264 String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Rang
e* range) |
265 { | 265 { |
266 if (!range) | 266 if (!range) |
267 return node->nodeValue(); | 267 return node->nodeValue(); |
268 | 268 |
269 String str = node->nodeValue(); | 269 String str = node->nodeValue(); |
270 if (node == range->endContainer()) | 270 if (node == range->endContainer()) |
271 str.truncate(range->endOffset()); | 271 str.truncate(range->endOffset()); |
272 if (node == range->startContainer()) | 272 if (node == range->startContainer()) |
273 str.remove(0, range->startOffset()); | 273 str.remove(0, range->startOffset()); |
274 return str; | 274 return str; |
275 } | 275 } |
276 | 276 |
277 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element* element
, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode) | 277 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element* element
, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode) |
278 { | 278 { |
279 const bool documentIsHTML = element->document()->isHTMLDocument(); | 279 const bool documentIsHTML = element->document().isHTMLDocument(); |
280 appendOpenTag(out, element, 0); | 280 appendOpenTag(out, element, 0); |
281 | 281 |
282 const unsigned length = element->hasAttributes() ? element->attributeCount()
: 0; | 282 const unsigned length = element->hasAttributes() ? element->attributeCount()
: 0; |
283 const bool shouldAnnotateOrForceInline = element->isHTMLElement() && (should
Annotate() || addDisplayInline); | 283 const bool shouldAnnotateOrForceInline = element->isHTMLElement() && (should
Annotate() || addDisplayInline); |
284 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp
plyWrappingStyle(element); | 284 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp
plyWrappingStyle(element); |
285 for (unsigned i = 0; i < length; ++i) { | 285 for (unsigned i = 0; i < length; ++i) { |
286 const Attribute* attribute = element->attributeItem(i); | 286 const Attribute* attribute = element->attributeItem(i); |
287 // We'll handle the style attribute separately, below. | 287 // We'll handle the style attribute separately, below. |
288 if (attribute->name() == styleAttr && shouldOverrideStyleAttr) | 288 if (attribute->name() == styleAttr && shouldOverrideStyleAttr) |
289 continue; | 289 continue; |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 { | 742 { |
743 if (!node) | 743 if (!node) |
744 return ""; | 744 return ""; |
745 | 745 |
746 MarkupAccumulator accumulator(nodes, shouldResolveURLs); | 746 MarkupAccumulator accumulator(nodes, shouldResolveURLs); |
747 return accumulator.serializeNodes(const_cast<Node*>(node), childrenOnly, tag
NamesToSkip); | 747 return accumulator.serializeNodes(const_cast<Node*>(node), childrenOnly, tag
NamesToSkip); |
748 } | 748 } |
749 | 749 |
750 static void fillContainerFromString(ContainerNode* paragraph, const String& stri
ng) | 750 static void fillContainerFromString(ContainerNode* paragraph, const String& stri
ng) |
751 { | 751 { |
752 Document* document = paragraph->document(); | 752 Document& document = paragraph->document(); |
753 | 753 |
754 if (string.isEmpty()) { | 754 if (string.isEmpty()) { |
755 paragraph->appendChild(createBlockPlaceholderElement(document)); | 755 paragraph->appendChild(createBlockPlaceholderElement(&document)); |
756 return; | 756 return; |
757 } | 757 } |
758 | 758 |
759 ASSERT(string.find('\n') == notFound); | 759 ASSERT(string.find('\n') == notFound); |
760 | 760 |
761 Vector<String> tabList; | 761 Vector<String> tabList; |
762 string.split('\t', true, tabList); | 762 string.split('\t', true, tabList); |
763 String tabText = emptyString(); | 763 String tabText = emptyString(); |
764 bool first = true; | 764 bool first = true; |
765 size_t numEntries = tabList.size(); | 765 size_t numEntries = tabList.size(); |
766 for (size_t i = 0; i < numEntries; ++i) { | 766 for (size_t i = 0; i < numEntries; ++i) { |
767 const String& s = tabList[i]; | 767 const String& s = tabList[i]; |
768 | 768 |
769 // append the non-tab textual part | 769 // append the non-tab textual part |
770 if (!s.isEmpty()) { | 770 if (!s.isEmpty()) { |
771 if (!tabText.isEmpty()) { | 771 if (!tabText.isEmpty()) { |
772 paragraph->appendChild(createTabSpanElement(document, tabText)); | 772 paragraph->appendChild(createTabSpanElement(&document, tabText))
; |
773 tabText = emptyString(); | 773 tabText = emptyString(); |
774 } | 774 } |
775 RefPtr<Node> textNode = document->createTextNode(stringWithRebalance
dWhitespace(s, first, i + 1 == numEntries)); | 775 RefPtr<Node> textNode = document.createTextNode(stringWithRebalanced
Whitespace(s, first, i + 1 == numEntries)); |
776 paragraph->appendChild(textNode.release()); | 776 paragraph->appendChild(textNode.release()); |
777 } | 777 } |
778 | 778 |
779 // there is a tab after every entry, except the last entry | 779 // there is a tab after every entry, except the last entry |
780 // (if the last character is a tab, the list gets an extra empty entry) | 780 // (if the last character is a tab, the list gets an extra empty entry) |
781 if (i + 1 != numEntries) | 781 if (i + 1 != numEntries) |
782 tabText.append('\t'); | 782 tabText.append('\t'); |
783 else if (!tabText.isEmpty()) | 783 else if (!tabText.isEmpty()) |
784 paragraph->appendChild(createTabSpanElement(document, tabText)); | 784 paragraph->appendChild(createTabSpanElement(&document, tabText)); |
785 | 785 |
786 first = false; | 786 first = false; |
787 } | 787 } |
788 } | 788 } |
789 | 789 |
790 bool isPlainTextMarkup(Node *node) | 790 bool isPlainTextMarkup(Node *node) |
791 { | 791 { |
792 if (!node->isElementNode() || !node->hasTagName(divTag) || toElement(node)->
hasAttributes()) | 792 if (!node->isElementNode() || !node->hasTagName(divTag) || toElement(node)->
hasAttributes()) |
793 return false; | 793 return false; |
794 | 794 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 } | 895 } |
896 | 896 |
897 return fragment.release(); | 897 return fragment.release(); |
898 } | 898 } |
899 | 899 |
900 String createFullMarkup(const Node* node) | 900 String createFullMarkup(const Node* node) |
901 { | 901 { |
902 if (!node) | 902 if (!node) |
903 return String(); | 903 return String(); |
904 | 904 |
905 Frame* frame = node->document()->frame(); | 905 Frame* frame = node->document().frame(); |
906 if (!frame) | 906 if (!frame) |
907 return String(); | 907 return String(); |
908 | 908 |
909 // FIXME: This is never "for interchange". Is that right? | 909 // FIXME: This is never "for interchange". Is that right? |
910 String markupString = createMarkup(node, IncludeNode, 0); | 910 String markupString = createMarkup(node, IncludeNode, 0); |
911 Node::NodeType nodeType = node->nodeType(); | 911 Node::NodeType nodeType = node->nodeType(); |
912 if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE) | 912 if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE) |
913 markupString = frame->documentTypeString() + markupString; | 913 markupString = frame->documentTypeString() + markupString; |
914 | 914 |
915 return markupString; | 915 return markupString; |
916 } | 916 } |
917 | 917 |
918 String createFullMarkup(const Range* range) | 918 String createFullMarkup(const Range* range) |
919 { | 919 { |
920 if (!range) | 920 if (!range) |
921 return String(); | 921 return String(); |
922 | 922 |
923 Node* node = range->startContainer(); | 923 Node* node = range->startContainer(); |
924 if (!node) | 924 if (!node) |
925 return String(); | 925 return String(); |
926 | 926 |
927 Frame* frame = node->document()->frame(); | 927 Frame* frame = node->document().frame(); |
928 if (!frame) | 928 if (!frame) |
929 return String(); | 929 return String(); |
930 | 930 |
931 // FIXME: This is always "for interchange". Is that right? See the previous
method. | 931 // FIXME: This is always "for interchange". Is that right? See the previous
method. |
932 return frame->documentTypeString() + createMarkup(range, 0, AnnotateForInter
change); | 932 return frame->documentTypeString() + createMarkup(range, 0, AnnotateForInter
change); |
933 } | 933 } |
934 | 934 |
935 String urlToMarkup(const KURL& url, const String& title) | 935 String urlToMarkup(const KURL& url, const String& title) |
936 { | 936 { |
937 StringBuilder markup; | 937 StringBuilder markup; |
938 markup.append("<a href=\""); | 938 markup.append("<a href=\""); |
939 markup.append(url.string()); | 939 markup.append(url.string()); |
940 markup.append("\">"); | 940 markup.append("\">"); |
941 MarkupAccumulator::appendCharactersReplacingEntities(markup, title, 0, title
.length(), EntityMaskInPCDATA); | 941 MarkupAccumulator::appendCharactersReplacingEntities(markup, title, 0, title
.length(), EntityMaskInPCDATA); |
942 markup.append("</a>"); | 942 markup.append("</a>"); |
943 return markup.toString(); | 943 return markup.toString(); |
944 } | 944 } |
945 | 945 |
946 PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& marku
p, Element* contextElement, ParserContentPolicy parserContentPolicy, ExceptionSt
ate& es) | 946 PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& marku
p, Element* contextElement, ParserContentPolicy parserContentPolicy, ExceptionSt
ate& es) |
947 { | 947 { |
948 Document* document = contextElement->hasTagName(templateTag) ? contextElemen
t->document()->ensureTemplateDocument() : contextElement->document(); | 948 Document* document = contextElement->hasTagName(templateTag) ? contextElemen
t->document().ensureTemplateDocument() : &contextElement->document(); |
949 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document); | 949 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document); |
950 | 950 |
951 if (document->isHTMLDocument()) { | 951 if (document->isHTMLDocument()) { |
952 fragment->parseHTML(markup, contextElement, parserContentPolicy); | 952 fragment->parseHTML(markup, contextElement, parserContentPolicy); |
953 return fragment; | 953 return fragment; |
954 } | 954 } |
955 | 955 |
956 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli
cy); | 956 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli
cy); |
957 if (!wasValid) { | 957 if (!wasValid) { |
958 es.throwDOMException(SyntaxError); | 958 es.throwDOMException(SyntaxError); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 { | 1060 { |
1061 RefPtr<ContainerNode> containerNode(container); | 1061 RefPtr<ContainerNode> containerNode(container); |
1062 | 1062 |
1063 ChildListMutationScope mutation(containerNode.get()); | 1063 ChildListMutationScope mutation(containerNode.get()); |
1064 | 1064 |
1065 if (containerNode->hasOneTextChild()) { | 1065 if (containerNode->hasOneTextChild()) { |
1066 toText(containerNode->firstChild())->setData(text); | 1066 toText(containerNode->firstChild())->setData(text); |
1067 return; | 1067 return; |
1068 } | 1068 } |
1069 | 1069 |
1070 RefPtr<Text> textNode = Text::create(containerNode->document(), text); | 1070 RefPtr<Text> textNode = Text::create(&containerNode->document(), text); |
1071 | 1071 |
1072 if (containerNode->hasOneChild()) { | 1072 if (containerNode->hasOneChild()) { |
1073 containerNode->replaceChild(textNode.release(), containerNode->firstChil
d(), es); | 1073 containerNode->replaceChild(textNode.release(), containerNode->firstChil
d(), es); |
1074 return; | 1074 return; |
1075 } | 1075 } |
1076 | 1076 |
1077 containerNode->removeChildren(); | 1077 containerNode->removeChildren(); |
1078 containerNode->appendChild(textNode.release(), es); | 1078 containerNode->appendChild(textNode.release(), es); |
1079 } | 1079 } |
1080 | 1080 |
1081 } | 1081 } |
OLD | NEW |