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