Copying can result in span around block elements on the clipboard
[WebKit-https.git] / Source / WebCore / editing / markup.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3  * Copyright (C) 2008, 2009 Google Inc.
4  * Copyright (C) 2011 Igalia S.L.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
26  */
27
28 #include "config.h"
29 #include "markup.h"
30
31 #include "CDATASection.h"
32 #include "CSSComputedStyleDeclaration.h"
33 #include "CSSMutableStyleDeclaration.h"
34 #include "CSSPrimitiveValue.h"
35 #include "CSSProperty.h"
36 #include "CSSPropertyNames.h"
37 #include "CSSRule.h"
38 #include "CSSRuleList.h"
39 #include "CSSStyleRule.h"
40 #include "CSSStyleSelector.h"
41 #include "CSSValue.h"
42 #include "CSSValueKeywords.h"
43 #include "DeleteButtonController.h"
44 #include "DocumentFragment.h"
45 #include "DocumentType.h"
46 #include "Editor.h"
47 #include "Frame.h"
48 #include "HTMLBodyElement.h"
49 #include "HTMLElement.h"
50 #include "HTMLNames.h"
51 #include "KURL.h"
52 #include "MarkupAccumulator.h"
53 #include "Range.h"
54 #include "RenderObject.h"
55 #include "TextIterator.h"
56 #include "VisibleSelection.h"
57 #include "XMLNSNames.h"
58 #include "htmlediting.h"
59 #include "visible_units.h"
60 #include <wtf/StdLibExtras.h>
61 #include <wtf/unicode/CharacterNames.h>
62
63 using namespace std;
64
65 namespace WebCore {
66
67 using namespace HTMLNames;
68
69 static bool propertyMissingOrEqualToNone(CSSStyleDeclaration*, int propertyID);
70
71 class AttributeChange {
72 public:
73     AttributeChange()
74         : m_name(nullAtom, nullAtom, nullAtom)
75     {
76     }
77
78     AttributeChange(PassRefPtr<Element> element, const QualifiedName& name, const String& value)
79         : m_element(element), m_name(name), m_value(value)
80     {
81     }
82
83     void apply()
84     {
85         m_element->setAttribute(m_name, m_value);
86     }
87
88 private:
89     RefPtr<Element> m_element;
90     QualifiedName m_name;
91     String m_value;
92 };
93
94 static void completeURLs(Node* node, const String& baseURL)
95 {
96     Vector<AttributeChange> changes;
97
98     KURL parsedBaseURL(ParsedURLString, baseURL);
99
100     Node* end = node->traverseNextSibling();
101     for (Node* n = node; n != end; n = n->traverseNextNode()) {
102         if (n->isElementNode()) {
103             Element* e = static_cast<Element*>(n);
104             NamedNodeMap* attributes = e->attributes();
105             unsigned length = attributes->length();
106             for (unsigned i = 0; i < length; i++) {
107                 Attribute* attribute = attributes->attributeItem(i);
108                 if (e->isURLAttribute(attribute))
109                     changes.append(AttributeChange(e, attribute->name(), KURL(parsedBaseURL, attribute->value()).string()));
110             }
111         }
112     }
113
114     size_t numChanges = changes.size();
115     for (size_t i = 0; i < numChanges; ++i)
116         changes[i].apply();
117 }
118     
119 class StyledMarkupAccumulator : public MarkupAccumulator {
120 public:
121     enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
122
123     StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs, EAnnotateForInterchange, const Range*, Node* highestNodeToBeSerialized = 0);
124     Node* serializeNodes(Node* startNode, Node* pastEnd);
125     virtual void appendString(const String& s) { return MarkupAccumulator::appendString(s); }
126     void wrapWithNode(Node*, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
127     void wrapWithStyleNode(CSSStyleDeclaration*, Document*, bool isBlock = false);
128     String takeResults();
129
130 private:
131     void appendStyleNodeOpenTag(Vector<UChar>&, CSSStyleDeclaration*, Document*, bool isBlock = false);
132     const String styleNodeCloseTag(bool isBlock = false);
133     virtual void appendText(Vector<UChar>& out, Text*);
134     String renderedText(const Node*, const Range*);
135     String stringValueForRange(const Node*, const Range*);
136     void appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode);
137     void appendElement(Vector<UChar>& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
138
139     enum NodeTraversalMode { EmitString, DoNotEmitString };
140     Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTraversalMode);
141
142     bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
143     bool shouldApplyWrappingStyle(Node* node) const
144     {
145         return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() == node->parentNode()
146             && m_wrappingStyle && m_wrappingStyle->style();
147     }
148
149     Vector<String> m_reversedPrecedingMarkup;
150     const EAnnotateForInterchange m_shouldAnnotate;
151     Node* m_highestNodeToBeSerialized;
152     RefPtr<EditingStyle> m_wrappingStyle;
153 };
154
155 inline StyledMarkupAccumulator::StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate,
156     const Range* range, Node* highestNodeToBeSerialized)
157     : MarkupAccumulator(nodes, shouldResolveURLs, range)
158     , m_shouldAnnotate(shouldAnnotate)
159     , m_highestNodeToBeSerialized(highestNodeToBeSerialized)
160 {
161 }
162
163 void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
164 {
165     Vector<UChar> markup;
166     if (node->isElementNode())
167         appendElement(markup, static_cast<Element*>(node), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), rangeFullySelectsNode);
168     else
169         appendStartMarkup(markup, node, 0);
170     m_reversedPrecedingMarkup.append(String::adopt(markup));
171     appendEndTag(node);
172     if (m_nodes)
173         m_nodes->append(node);
174 }
175
176 void StyledMarkupAccumulator::wrapWithStyleNode(CSSStyleDeclaration* style, Document* document, bool isBlock)
177 {
178     Vector<UChar> openTag;
179     appendStyleNodeOpenTag(openTag, style, document, isBlock);
180     m_reversedPrecedingMarkup.append(String::adopt(openTag));
181     appendString(styleNodeCloseTag(isBlock));
182 }
183
184 void StyledMarkupAccumulator::appendStyleNodeOpenTag(Vector<UChar>& out, CSSStyleDeclaration* style, Document* document, bool isBlock)
185 {
186     // All text-decoration-related elements should have been treated as special ancestors
187     // If we ever hit this ASSERT, we should export StyleChange in ApplyStyleCommand and use it here
188     ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyTextDecoration) && propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsInEffect));
189     DEFINE_STATIC_LOCAL(const String, divStyle, ("<div style=\""));
190     DEFINE_STATIC_LOCAL(const String, styleSpanOpen, ("<span class=\"" AppleStyleSpanClass "\" style=\""));
191     append(out, isBlock ? divStyle : styleSpanOpen);
192     appendAttributeValue(out, style->cssText(), document->isHTMLDocument());
193     out.append('\"');
194     out.append('>');
195 }
196
197 const String StyledMarkupAccumulator::styleNodeCloseTag(bool isBlock)
198 {
199     DEFINE_STATIC_LOCAL(const String, divClose, ("</div>"));
200     DEFINE_STATIC_LOCAL(const String, styleSpanClose, ("</span>"));
201     return isBlock ? divClose : styleSpanClose;
202 }
203
204 String StyledMarkupAccumulator::takeResults()
205 {
206     Vector<UChar> result;
207     result.reserveInitialCapacity(totalLength(m_reversedPrecedingMarkup) + length());
208
209     for (size_t i = m_reversedPrecedingMarkup.size(); i > 0; --i)
210         append(result, m_reversedPrecedingMarkup[i - 1]);
211
212     concatenateMarkup(result);
213
214     // We remove '\0' characters because they are not visibly rendered to the user.
215     return String::adopt(result).replace(0, "");
216 }
217
218 void StyledMarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
219 {    
220     const bool parentIsTextarea = text->parentElement() && text->parentElement()->tagQName() == textareaTag;
221     const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextarea;
222     if (wrappingSpan) {
223         RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy();
224         // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
225         // Make sure spans are inline style in paste side e.g. span { display: block }.
226         wrappingStyle->forceInline();
227         // FIXME: Should this be included in forceInline?
228         wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
229
230         Vector<UChar> openTag;
231         appendStyleNodeOpenTag(openTag, wrappingStyle->style(), text->document());
232         append(out, String::adopt(openTag));
233     }
234
235     if (!shouldAnnotate() || parentIsTextarea)
236         MarkupAccumulator::appendText(out, text);
237     else {
238         const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(text), selectTag);
239         String content = useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range);
240         Vector<UChar> buffer;
241         appendCharactersReplacingEntities(buffer, content.characters(), content.length(), EntityMaskInPCDATA);
242         append(out, convertHTMLTextToInterchangeFormat(String::adopt(buffer), text));
243     }
244
245     if (wrappingSpan)
246         append(out, styleNodeCloseTag());
247 }
248     
249 String StyledMarkupAccumulator::renderedText(const Node* node, const Range* range)
250 {
251     if (!node->isTextNode())
252         return String();
253
254     ExceptionCode ec;
255     const Text* textNode = static_cast<const Text*>(node);
256     unsigned startOffset = 0;
257     unsigned endOffset = textNode->length();
258
259     if (range && node == range->startContainer(ec))
260         startOffset = range->startOffset(ec);
261     if (range && node == range->endContainer(ec))
262         endOffset = range->endOffset(ec);
263
264     Position start = createLegacyEditingPosition(const_cast<Node*>(node), startOffset);
265     Position end = createLegacyEditingPosition(const_cast<Node*>(node), endOffset);
266     return plainText(Range::create(node->document(), start, end).get());
267 }
268
269 String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Range* range)
270 {
271     if (!range)
272         return node->nodeValue();
273
274     String str = node->nodeValue();
275     ExceptionCode ec;
276     if (node == range->endContainer(ec))
277         str.truncate(range->endOffset(ec));
278     if (node == range->startContainer(ec))
279         str.remove(0, range->startOffset(ec));
280     return str;
281 }
282
283 void StyledMarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
284 {
285     const bool documentIsHTML = element->document()->isHTMLDocument();
286     appendOpenTag(out, element, 0);
287
288     NamedNodeMap* attributes = element->attributes();
289     const unsigned length = attributes->length();
290     const bool shouldAnnotateOrForceInline = element->isHTMLElement() && (shouldAnnotate() || addDisplayInline);
291     const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element);
292     for (unsigned int i = 0; i < length; i++) {
293         Attribute* attribute = attributes->attributeItem(i);
294         // We'll handle the style attribute separately, below.
295         if (attribute->name() == styleAttr && shouldOverrideStyleAttr)
296             continue;
297         appendAttribute(out, element, *attribute, 0);
298     }
299
300     if (shouldOverrideStyleAttr) {
301         RefPtr<EditingStyle> newInlineStyle;
302
303         if (shouldApplyWrappingStyle(element)) {
304             newInlineStyle = m_wrappingStyle->copy();
305             newInlineStyle->removePropertiesInElementDefaultStyle(element);
306             newInlineStyle->removeStyleConflictingWithStyleOfNode(element);
307         } else
308             newInlineStyle = EditingStyle::create();
309
310         if (element->isStyledElement() && static_cast<StyledElement*>(element)->inlineStyleDecl())
311             newInlineStyle->overrideWithStyle(static_cast<StyledElement*>(element)->inlineStyleDecl());
312
313         if (shouldAnnotateOrForceInline) {
314             if (shouldAnnotate())
315                 newInlineStyle->mergeStyleFromRulesForSerialization(toHTMLElement(element));
316
317             if (addDisplayInline)
318                 newInlineStyle->forceInline();
319
320             // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
321             // only the ones that affect it and the nodes within it.
322             if (rangeFullySelectsNode == DoesNotFullySelectNode && newInlineStyle->style())
323                 newInlineStyle->style()->removeProperty(CSSPropertyFloat);
324         }
325
326         if (!newInlineStyle->isEmpty()) {
327             DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));
328             append(out, stylePrefix);
329             appendAttributeValue(out, newInlineStyle->style()->cssText(), documentIsHTML);
330             out.append('\"');
331         }
332     }
333
334     appendCloseTag(out, element);
335 }
336
337 Node* StyledMarkupAccumulator::serializeNodes(Node* startNode, Node* pastEnd)
338 {
339     if (!m_highestNodeToBeSerialized) {
340         Node* lastClosed = traverseNodesForSerialization(startNode, pastEnd, DoNotEmitString);
341         m_highestNodeToBeSerialized = lastClosed;
342     }
343
344     Node* parentOfHighestNode = m_highestNodeToBeSerialized ? m_highestNodeToBeSerialized->parentNode() : 0;
345     if (parentOfHighestNode) {
346         m_wrappingStyle = EditingStyle::create(parentOfHighestNode, EditingStyle::EditingInheritablePropertiesAndBackgroundColorInEffect);
347
348         // Styles that Mail blockquotes contribute should only be placed on the Mail blockquote,
349         // to help us differentiate those styles from ones that the user has applied.
350         // This helps us get the color of content pasted into blockquotes right.
351         m_wrappingStyle->removeStyleAddedByNode(enclosingNodeOfType(firstPositionInOrBeforeNode(parentOfHighestNode), isMailBlockquote, CanCrossEditingBoundary));
352
353         // Call collapseTextDecorationProperties first or otherwise it'll copy the value over from in-effect to text-decorations.
354         m_wrappingStyle->collapseTextDecorationProperties();
355     }
356
357     return traverseNodesForSerialization(startNode, pastEnd, EmitString);
358 }
359
360 Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTraversalMode traversalMode)
361 {
362     const bool shouldEmit = traversalMode == EmitString;
363     Vector<Node*> ancestorsToClose;
364     Node* next;
365     Node* lastClosed = 0;
366     for (Node* n = startNode; n != pastEnd; n = next) {
367         // According to <rdar://problem/5730668>, it is possible for n to blow
368         // past pastEnd and become null here. This shouldn't be possible.
369         // This null check will prevent crashes (but create too much markup)
370         // and the ASSERT will hopefully lead us to understanding the problem.
371         ASSERT(n);
372         if (!n)
373             break;
374         
375         next = n->traverseNextNode();
376         bool openedTag = false;
377
378         if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd)
379             // Don't write out empty block containers that aren't fully selected.
380             continue;
381
382         if (!n->renderer() && !enclosingNodeWithTag(firstPositionInOrBeforeNode(n), selectTag)) {
383             next = n->traverseNextSibling();
384             // Don't skip over pastEnd.
385             if (pastEnd && pastEnd->isDescendantOf(n))
386                 next = pastEnd;
387         } else {
388             // Add the node to the markup if we're not skipping the descendants
389             if (shouldEmit)
390                 appendStartTag(n);
391
392             // If node has no children, close the tag now.
393             if (!n->childNodeCount()) {
394                 if (shouldEmit)
395                     appendEndTag(n);
396                 lastClosed = n;
397             } else {
398                 openedTag = true;
399                 ancestorsToClose.append(n);
400             }
401         }
402
403         // If we didn't insert open tag and there's no more siblings or we're at the end of the traversal, take care of ancestors.
404         // FIXME: What happens if we just inserted open tag and reached the end?
405         if (!openedTag && (!n->nextSibling() || next == pastEnd)) {
406             // Close up the ancestors.
407             while (!ancestorsToClose.isEmpty()) {
408                 Node* ancestor = ancestorsToClose.last();
409                 if (next != pastEnd && next->isDescendantOf(ancestor))
410                     break;
411                 // Not at the end of the range, close ancestors up to sibling of next node.
412                 if (shouldEmit)
413                     appendEndTag(ancestor);
414                 lastClosed = ancestor;
415                 ancestorsToClose.removeLast();
416             }
417
418             // Surround the currently accumulated markup with markup for ancestors we never opened as we leave the subtree(s) rooted at those ancestors.
419             ContainerNode* nextParent = next ? next->parentNode() : 0;
420             if (next != pastEnd && n != nextParent) {
421                 Node* lastAncestorClosedOrSelf = n->isDescendantOf(lastClosed) ? lastClosed : n;
422                 for (ContainerNode* parent = lastAncestorClosedOrSelf->parentNode(); parent && parent != nextParent; parent = parent->parentNode()) {
423                     // All ancestors that aren't in the ancestorsToClose list should either be a) unrendered:
424                     if (!parent->renderer())
425                         continue;
426                     // or b) ancestors that we never encountered during a pre-order traversal starting at startNode:
427                     ASSERT(startNode->isDescendantOf(parent));
428                     if (shouldEmit)
429                         wrapWithNode(parent);
430                     lastClosed = parent;
431                 }
432             }
433         }
434     }
435
436     return lastClosed;
437 }
438
439 static Node* ancestorToRetainStructureAndAppearance(Node* commonAncestor)
440 {
441     Node* commonAncestorBlock = enclosingBlock(commonAncestor);
442
443     if (!commonAncestorBlock)
444         return 0;
445
446     if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) {
447         ContainerNode* table = commonAncestorBlock->parentNode();
448         while (table && !table->hasTagName(tableTag))
449             table = table->parentNode();
450
451         return table;
452     }
453
454     if (commonAncestorBlock->hasTagName(listingTag)
455         || commonAncestorBlock->hasTagName(olTag)
456         || commonAncestorBlock->hasTagName(preTag)
457         || commonAncestorBlock->hasTagName(tableTag)
458         || commonAncestorBlock->hasTagName(ulTag)
459         || commonAncestorBlock->hasTagName(xmpTag)
460         || commonAncestorBlock->hasTagName(h1Tag)
461         || commonAncestorBlock->hasTagName(h2Tag)
462         || commonAncestorBlock->hasTagName(h3Tag)
463         || commonAncestorBlock->hasTagName(h4Tag)
464         || commonAncestorBlock->hasTagName(h5Tag))
465         return commonAncestorBlock;
466
467     return 0;
468 }
469
470 static bool propertyMissingOrEqualToNone(CSSStyleDeclaration* style, int propertyID)
471 {
472     if (!style)
473         return false;
474     RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
475     if (!value)
476         return true;
477     if (!value->isPrimitiveValue())
478         return false;
479     return static_cast<CSSPrimitiveValue*>(value.get())->getIdent() == CSSValueNone;
480 }
481
482 static bool needInterchangeNewlineAfter(const VisiblePosition& v)
483 {
484     VisiblePosition next = v.next();
485     Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode();
486     Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode();
487     // Add an interchange newline if a paragraph break is selected and a br won't already be added to the markup to represent it.
488     return isEndOfParagraph(v) && isStartOfParagraph(next) && !(upstreamNode->hasTagName(brTag) && upstreamNode == downstreamNode);
489 }
490
491 static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* node)
492 {
493     if (!node->isHTMLElement())
494         return 0;
495
496     // FIXME: Having to const_cast here is ugly, but it is quite a bit of work to untangle
497     // the non-const-ness of styleFromMatchedRulesForElement.
498     HTMLElement* element = const_cast<HTMLElement*>(static_cast<const HTMLElement*>(node));
499     RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyleDecl());
500     style->mergeStyleFromRules(element);
501     return style.release();
502 }
503
504 static bool isElementPresentational(const Node* node)
505 {
506     if (node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName(strikeTag)
507         || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName(bTag) || node->hasTagName(strongTag))
508         return true;
509     RefPtr<EditingStyle> style = styleFromMatchedRulesAndInlineDecl(node);
510     return style && style->style() && !propertyMissingOrEqualToNone(style->style(), CSSPropertyTextDecoration);
511 }
512
513 static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot)
514 {
515     if (fullySelectedRoot->isElementNode() && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
516         return true;
517     
518     RefPtr<EditingStyle> style = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
519     if (!style || !style->style())
520         return false;
521
522     return style->style()->getPropertyCSSValue(CSSPropertyBackgroundImage) || style->style()->getPropertyCSSValue(CSSPropertyBackgroundColor);
523 }
524
525 static Node* highestAncestorToWrapMarkup(const Range* range, Node* fullySelectedRoot, EAnnotateForInterchange shouldAnnotate)
526 {
527     ExceptionCode ec;
528     Node* commonAncestor = range->commonAncestorContainer(ec);
529     ASSERT(commonAncestor);
530     Node* specialCommonAncestor = 0;
531     if (shouldAnnotate == AnnotateForInterchange) {
532         // Include ancestors that aren't completely inside the range but are required to retain 
533         // the structure and appearance of the copied markup.
534         specialCommonAncestor = ancestorToRetainStructureAndAppearance(commonAncestor);
535
536         // Retain the Mail quote level by including all ancestor mail block quotes.
537         if (Node* highestMailBlockquote = highestEnclosingNodeOfType(firstPositionInOrBeforeNode(range->firstNode()), isMailBlockquote, CanCrossEditingBoundary))
538             specialCommonAncestor = highestMailBlockquote;
539     }
540
541     Node* checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor;
542     if (checkAncestor->renderer()) {
543         Node* newSpecialCommonAncestor = highestEnclosingNodeOfType(firstPositionInNode(checkAncestor), &isElementPresentational);
544         if (newSpecialCommonAncestor)
545             specialCommonAncestor = newSpecialCommonAncestor;
546     }
547
548     // If a single tab is selected, commonAncestor will be a text node inside a tab span.
549     // If two or more tabs are selected, commonAncestor will be the tab span.
550     // In either case, if there is a specialCommonAncestor already, it will necessarily be above 
551     // any tab span that needs to be included.
552     if (!specialCommonAncestor && isTabSpanTextNode(commonAncestor))
553         specialCommonAncestor = commonAncestor->parentNode();
554     if (!specialCommonAncestor && isTabSpanNode(commonAncestor))
555         specialCommonAncestor = commonAncestor;
556
557     if (Node *enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(specialCommonAncestor ? specialCommonAncestor : commonAncestor), aTag))
558         specialCommonAncestor = enclosingAnchor;
559
560     if (shouldAnnotate == AnnotateForInterchange && fullySelectedRoot && shouldIncludeWrapperForFullySelectedRoot(fullySelectedRoot))
561         specialCommonAncestor = fullySelectedRoot;
562
563     return specialCommonAncestor;
564 }
565
566 // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange? 
567 // FIXME: At least, annotation and style info should probably not be included in range.markupString()
568 String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
569 {
570     DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">"));
571
572     if (!range)
573         return "";
574
575     Document* document = range->ownerDocument();
576     if (!document)
577         return "";
578
579     // Disable the delete button so it's elements are not serialized into the markup,
580     // but make sure neither endpoint is inside the delete user interface.
581     Frame* frame = document->frame();
582     DeleteButtonController* deleteButton = frame ? frame->editor()->deleteButtonController() : 0;
583     RefPtr<Range> updatedRange = avoidIntersectionWithNode(range, deleteButton ? deleteButton->containerElement() : 0);
584     if (!updatedRange)
585         return "";
586
587     if (deleteButton)
588         deleteButton->disable();
589
590     ExceptionCode ec = 0;
591     bool collapsed = updatedRange->collapsed(ec);
592     ASSERT(!ec);
593     if (collapsed)
594         return "";
595     Node* commonAncestor = updatedRange->commonAncestorContainer(ec);
596     ASSERT(!ec);
597     if (!commonAncestor)
598         return "";
599
600     document->updateLayoutIgnorePendingStylesheets();
601
602     Node* body = enclosingNodeWithTag(firstPositionInNode(commonAncestor), bodyTag);
603     Node* fullySelectedRoot = 0;
604     // FIXME: Do this for all fully selected blocks, not just the body.
605     if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), range))
606         fullySelectedRoot = body;
607     Node* specialCommonAncestor = highestAncestorToWrapMarkup(updatedRange.get(), fullySelectedRoot, shouldAnnotate);
608     StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange.get(), specialCommonAncestor);
609     Node* pastEnd = updatedRange->pastLastNode();
610
611     Node* startNode = updatedRange->firstNode();
612     VisiblePosition visibleStart(updatedRange->startPosition(), VP_DEFAULT_AFFINITY);
613     VisiblePosition visibleEnd(updatedRange->endPosition(), VP_DEFAULT_AFFINITY);
614     if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleStart)) {
615         if (visibleStart == visibleEnd.previous()) {
616             if (deleteButton)
617                 deleteButton->enable();
618             return interchangeNewlineString;
619         }
620
621         accumulator.appendString(interchangeNewlineString);
622         startNode = visibleStart.next().deepEquivalent().deprecatedNode();
623
624         ExceptionCode ec = 0;
625         if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, ec) >= 0) {
626             ASSERT(!ec);
627             if (deleteButton)
628                 deleteButton->enable();
629             return interchangeNewlineString;
630         }
631         ASSERT(!ec);
632     }
633
634     Node* lastClosed = accumulator.serializeNodes(startNode, pastEnd);
635
636     if (specialCommonAncestor && lastClosed) {
637         // Also include all of the ancestors of lastClosed up to this special ancestor.
638         for (ContainerNode* ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
639             if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
640                 RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
641
642                 // Bring the background attribute over, but not as an attribute because a background attribute on a div
643                 // appears to have no effect.
644                 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundImage))
645                     && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
646                     fullySelectedRootStyle->style()->setProperty(CSSPropertyBackgroundImage, "url('" + static_cast<Element*>(fullySelectedRoot)->getAttribute(backgroundAttr) + "')");
647
648                 if (fullySelectedRootStyle->style()) {
649                     // Reset the CSS properties to avoid an assertion error in addStyleMarkup().
650                     // This assertion is caused at least when we select all text of a <body> element whose
651                     // 'text-decoration' property is "inherit", and copy it.
652                     if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyTextDecoration))
653                         fullySelectedRootStyle->style()->setProperty(CSSPropertyTextDecoration, CSSValueNone);
654                     if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyWebkitTextDecorationsInEffect))
655                         fullySelectedRootStyle->style()->setProperty(CSSPropertyWebkitTextDecorationsInEffect, CSSValueNone);
656                     accumulator.wrapWithStyleNode(fullySelectedRootStyle->style(), document, true);
657                 }
658             } else {
659                 // Since this node and all the other ancestors are not in the selection we want to set RangeFullySelectsNode to DoesNotFullySelectNode
660                 // so that styles that affect the exterior of the node are not included.
661                 accumulator.wrapWithNode(ancestor, convertBlocksToInlines, StyledMarkupAccumulator::DoesNotFullySelectNode);
662             }
663             if (nodes)
664                 nodes->append(ancestor);
665             
666             lastClosed = ancestor;
667             
668             if (ancestor == specialCommonAncestor)
669                 break;
670         }
671     }
672
673     // FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.
674     if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleEnd.previous()))
675         accumulator.appendString(interchangeNewlineString);
676
677     if (deleteButton)
678         deleteButton->enable();
679
680     return accumulator.takeResults();
681 }
682
683 PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL, FragmentScriptingPermission scriptingPermission)
684 {
685     // We use a fake body element here to trick the HTML parser to using the
686     // InBody insertion mode.  Really, all this code is wrong and need to be
687     // changed not to use deprecatedCreateContextualFragment.
688     RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
689     // FIXME: This should not use deprecatedCreateContextualFragment
690     RefPtr<DocumentFragment> fragment = fakeBody->deprecatedCreateContextualFragment(markup, scriptingPermission);
691
692     if (fragment && !baseURL.isEmpty() && baseURL != blankURL() && baseURL != document->baseURL())
693         completeURLs(fragment.get(), baseURL);
694
695     return fragment.release();
696 }
697
698 String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs)
699 {
700     if (!node)
701         return "";
702
703     HTMLElement* deleteButtonContainerElement = 0;
704     if (Frame* frame = node->document()->frame()) {
705         deleteButtonContainerElement = frame->editor()->deleteButtonController()->containerElement();
706         if (node->isDescendantOf(deleteButtonContainerElement))
707             return "";
708     }
709
710     MarkupAccumulator accumulator(nodes, shouldResolveURLs);
711     return accumulator.serializeNodes(const_cast<Node*>(node), deleteButtonContainerElement, childrenOnly);
712 }
713
714 static void fillContainerFromString(ContainerNode* paragraph, const String& string)
715 {
716     Document* document = paragraph->document();
717
718     ExceptionCode ec = 0;
719     if (string.isEmpty()) {
720         paragraph->appendChild(createBlockPlaceholderElement(document), ec);
721         ASSERT(!ec);
722         return;
723     }
724
725     ASSERT(string.find('\n') == notFound);
726
727     Vector<String> tabList;
728     string.split('\t', true, tabList);
729     String tabText = "";
730     bool first = true;
731     size_t numEntries = tabList.size();
732     for (size_t i = 0; i < numEntries; ++i) {
733         const String& s = tabList[i];
734
735         // append the non-tab textual part
736         if (!s.isEmpty()) {
737             if (!tabText.isEmpty()) {
738                 paragraph->appendChild(createTabSpanElement(document, tabText), ec);
739                 ASSERT(!ec);
740                 tabText = "";
741             }
742             RefPtr<Node> textNode = document->createTextNode(stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));
743             paragraph->appendChild(textNode.release(), ec);
744             ASSERT(!ec);
745         }
746
747         // there is a tab after every entry, except the last entry
748         // (if the last character is a tab, the list gets an extra empty entry)
749         if (i + 1 != numEntries)
750             tabText.append('\t');
751         else if (!tabText.isEmpty()) {
752             paragraph->appendChild(createTabSpanElement(document, tabText), ec);
753             ASSERT(!ec);
754         }
755         
756         first = false;
757     }
758 }
759
760 bool isPlainTextMarkup(Node *node)
761 {
762     if (!node->isElementNode() || !node->hasTagName(divTag) || static_cast<Element*>(node)->attributes()->length())
763         return false;
764     
765     if (node->childNodeCount() == 1 && (node->firstChild()->isTextNode() || (node->firstChild()->firstChild())))
766         return true;
767     
768     return (node->childNodeCount() == 2 && isTabSpanTextNode(node->firstChild()->firstChild()) && node->firstChild()->nextSibling()->isTextNode());
769 }
770
771 PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text)
772 {
773     if (!context)
774         return 0;
775
776     Node* styleNode = context->firstNode();
777     if (!styleNode) {
778         styleNode = context->startPosition().deprecatedNode();
779         if (!styleNode)
780             return 0;
781     }
782
783     Document* document = styleNode->document();
784     RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
785     
786     if (text.isEmpty())
787         return fragment.release();
788
789     String string = text;
790     string.replace("\r\n", "\n");
791     string.replace('\r', '\n');
792
793     ExceptionCode ec = 0;
794     RenderObject* renderer = styleNode->renderer();
795     if (renderer && renderer->style()->preserveNewline()) {
796         fragment->appendChild(document->createTextNode(string), ec);
797         ASSERT(!ec);
798         if (string.endsWith("\n")) {
799             RefPtr<Element> element = createBreakElement(document);
800             element->setAttribute(classAttr, AppleInterchangeNewline);            
801             fragment->appendChild(element.release(), ec);
802             ASSERT(!ec);
803         }
804         return fragment.release();
805     }
806
807     // A string with no newlines gets added inline, rather than being put into a paragraph.
808     if (string.find('\n') == notFound) {
809         fillContainerFromString(fragment.get(), string);
810         return fragment.release();
811     }
812
813     // Break string into paragraphs. Extra line breaks turn into empty paragraphs.
814     Node* blockNode = enclosingBlock(context->firstNode());
815     Element* block = static_cast<Element*>(blockNode);
816     bool useClonesOfEnclosingBlock = blockNode
817         && blockNode->isElementNode()
818         && !block->hasTagName(bodyTag)
819         && !block->hasTagName(htmlTag)
820         && block != editableRootForPosition(context->startPosition());
821     
822     Vector<String> list;
823     string.split('\n', true, list); // true gets us empty strings in the list
824     size_t numLines = list.size();
825     for (size_t i = 0; i < numLines; ++i) {
826         const String& s = list[i];
827
828         RefPtr<Element> element;
829         if (s.isEmpty() && i + 1 == numLines) {
830             // For last line, use the "magic BR" rather than a P.
831             element = createBreakElement(document);
832             element->setAttribute(classAttr, AppleInterchangeNewline);            
833         } else {
834             if (useClonesOfEnclosingBlock)
835                 element = block->cloneElementWithoutChildren();
836             else
837                 element = createDefaultParagraphElement(document);
838             fillContainerFromString(element.get(), s);
839         }
840         fragment->appendChild(element.release(), ec);
841         ASSERT(!ec);
842     }
843     return fragment.release();
844 }
845
846 PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const Vector<Node*>& nodes)
847 {
848     if (!document)
849         return 0;
850
851     // disable the delete button so it's elements are not serialized into the markup
852     if (document->frame())
853         document->frame()->editor()->deleteButtonController()->disable();
854
855     RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
856
857     ExceptionCode ec = 0;
858     size_t size = nodes.size();
859     for (size_t i = 0; i < size; ++i) {
860         RefPtr<Element> element = createDefaultParagraphElement(document);
861         element->appendChild(nodes[i], ec);
862         ASSERT(!ec);
863         fragment->appendChild(element.release(), ec);
864         ASSERT(!ec);
865     }
866
867     if (document->frame())
868         document->frame()->editor()->deleteButtonController()->enable();
869
870     return fragment.release();
871 }
872
873 String createFullMarkup(const Node* node)
874 {
875     if (!node)
876         return String();
877         
878     Document* document = node->document();
879     if (!document)
880         return String();
881         
882     Frame* frame = document->frame();
883     if (!frame)
884         return String();
885
886     // FIXME: This is never "for interchange". Is that right?    
887     String markupString = createMarkup(node, IncludeNode, 0);
888     Node::NodeType nodeType = node->nodeType();
889     if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE)
890         markupString = frame->documentTypeString() + markupString;
891
892     return markupString;
893 }
894
895 String createFullMarkup(const Range* range)
896 {
897     if (!range)
898         return String();
899
900     Node* node = range->startContainer();
901     if (!node)
902         return String();
903         
904     Document* document = node->document();
905     if (!document)
906         return String();
907         
908     Frame* frame = document->frame();
909     if (!frame)
910         return String();
911
912     // FIXME: This is always "for interchange". Is that right? See the previous method.
913     return frame->documentTypeString() + createMarkup(range, 0, AnnotateForInterchange);        
914 }
915
916 String urlToMarkup(const KURL& url, const String& title)
917 {
918     Vector<UChar> markup;
919     append(markup, "<a href=\"");
920     append(markup, url.string());
921     append(markup, "\">");
922     appendCharactersReplacingEntities(markup, title.characters(), title.length(), EntityMaskInPCDATA);
923     append(markup, "</a>");
924     return String::adopt(markup);
925 }
926
927 }