18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
25af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLViewSourceDocument.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DOMImplementation.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLAnchorElement.h"
315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "HTMLBaseElement.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLBodyElement.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLDivElement.h"
345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLHtmlElement.h"
355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLNames.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTableCellElement.h"
375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLTableElement.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTableRowElement.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTableSectionElement.h"
40f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "HTMLToken.h"
41f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "HTMLViewSourceParser.h"
42f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "SegmentedString.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h"
445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "TextViewSourceParser.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenHTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const KURL& url, const String& mimeType)
5106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    : HTMLDocument(frame, url)
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_type(mimeType)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setUsesBeforeAfterRules(true);
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setUsesViewSourceStyles(true);
5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setCompatibilityMode(QuirksMode);
585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    lockCompatibilityMode();
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
61e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockPassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_type)
640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(XHTMLMP)
650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        || m_type == "application/vnd.wap.xhtml+xml"
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
67f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        )
68e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return HTMLViewSourceParser::create(this);
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return TextViewSourceParser::create(this);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLViewSourceDocument::createContainingTable()
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(this);
76dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    parserAddChild(html);
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    html->attach();
785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(this);
79dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    html->parserAddChild(body);
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    body->attach();
81dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create a line gutter div that can be used to make sure the gutter extends down the height of the whole
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // document.
845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RefPtr<HTMLDivElement> div = HTMLDivElement::create(this);
85e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
86e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs->addAttribute(Attribute::createMapped(classAttr, "webkit-line-gutter-backdrop"));
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    div->setAttributeMap(attrs.release());
88dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    body->parserAddChild(div);
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    div->attach();
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RefPtr<HTMLTableElement> table = HTMLTableElement::create(this);
92dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    body->parserAddChild(table);
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    table->attach();
945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    m_tbody = HTMLTableSectionElement::create(tbodyTag, this);
95dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    table->parserAddChild(m_tbody);
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_tbody->attach();
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_current = m_tbody;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
100f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_current)
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        createContainingTable();
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
105f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    switch (token.type()) {
106f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    case HTMLToken::Uninitialized:
107f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        ASSERT_NOT_REACHED();
108f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        break;
109f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    case HTMLToken::DOCTYPE:
110f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        processDoctypeToken(source, token);
111f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        break;
112f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    case HTMLToken::EndOfFile:
113f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        break;
114f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    case HTMLToken::StartTag:
115f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    case HTMLToken::EndTag:
116f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        processTagToken(source, token);
117f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        break;
118f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    case HTMLToken::Comment:
119f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        processCommentToken(source, token);
120f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        break;
121f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    case HTMLToken::Character:
122f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        processCharacterToken(source, token);
123f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        break;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
127f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid HTMLViewSourceDocument::processDoctypeToken(const String& source, HTMLToken&)
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_current)
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        createContainingTable();
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_current = addSpanWithClassName("webkit-html-doctype");
132f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    addText(source, "webkit-html-doctype");
133f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    m_current = m_td;
134f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
135f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
136f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token)
137f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
1385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_current = addSpanWithClassName("webkit-html-tag");
139f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
140f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    AtomicString tagName(token.name().data(), token.name().size());
141f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
142f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    unsigned index = 0;
143f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    HTMLToken::AttributeList::const_iterator iter = token.attributes().begin();
144f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    while (index < source.length()) {
145f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (iter == token.attributes().end()) {
146f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            // We want to show the remaining characters in the token.
147f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            index = addRange(source, index, source.length(), "");
148f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT(index == source.length());
149f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            break;
150f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        }
151f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
152f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        AtomicString name(iter->m_name.data(), iter->m_name.size());
153f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        String value(iter->m_value.data(), iter->m_value.size());
154f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
155f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        index = addRange(source, index, iter->m_nameRange.m_start - token.startIndex(), "");
156f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        index = addRange(source, index, iter->m_nameRange.m_end - token.startIndex(), "webkit-html-attribute-name");
157f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
1585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (tagName == baseTag && name == hrefAttr)
1595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            m_current = addBase(value);
160f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
161f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        index = addRange(source, index, iter->m_valueRange.m_start - token.startIndex(), "");
162f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
163f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        bool isLink = name == srcAttr || name == hrefAttr;
164f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        index = addRange(source, index, iter->m_valueRange.m_end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag);
165f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
166f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        ++iter;
167f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
168f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    m_current = m_td;
169f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
170f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
171f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid HTMLViewSourceDocument::processCommentToken(const String& source, HTMLToken&)
172f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
173f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    m_current = addSpanWithClassName("webkit-html-comment");
174f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    addText(source, "webkit-html-comment");
175f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    m_current = m_td;
176f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
177f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
178f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&)
179f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
180f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    addText(source, "");
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_current == m_tbody) {
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addLine(className);
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_current;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<HTMLElement> span = HTMLElement::create(spanTag, this);
191e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
192e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs->addAttribute(Attribute::createMapped(classAttr, className));
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    span->setAttributeMap(attrs.release());
194dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_current->parserAddChild(span);
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    span->attach();
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return span.release();
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLViewSourceDocument::addLine(const AtomicString& className)
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create a table row.
2025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(this);
203dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_tbody->parserAddChild(trow);
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    trow->attach();
205dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create a cell that will hold the line number (it is generated in the stylesheet using counters).
2075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, this);
208e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
209e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs->addAttribute(Attribute::createMapped(classAttr, "webkit-line-number"));
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    td->setAttributeMap(attrs.release());
211dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    trow->parserAddChild(td);
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    td->attach();
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create a second cell for the line contents
2155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    td = HTMLTableCellElement::create(tdTag, this);
216e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs = NamedNodeMap::create();
217e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs->addAttribute(Attribute::createMapped(classAttr, "webkit-line-content"));
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    td->setAttributeMap(attrs.release());
219dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    trow->parserAddChild(td);
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    td->attach();
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_current = m_td = td;
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef DEBUG_LINE_NUMBERS
224545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RefPtr<Text> lineNumberText = Text::create(this, String::number(parser()->lineNumber() + 1) + " ");
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    td->addChild(lineNumberText);
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    lineNumberText->attach();
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Open up the needed spans.
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!className.isEmpty()) {
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (className == "webkit-html-attribute-name" || className == "webkit-html-attribute-value")
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_current = addSpanWithClassName("webkit-html-tag");
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_current = addSpanWithClassName(className);
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLViewSourceDocument::addText(const String& text, const AtomicString& className)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (text.isEmpty())
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add in the content, splitting on newlines.
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<String> lines;
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    text.split('\n', true, lines);
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned size = lines.size();
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < size; i++) {
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String substring = lines[i];
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (substring.isEmpty()) {
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (i == size - 1)
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            substring = " ";
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_current == m_tbody)
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            addLine(className);
255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        RefPtr<Text> t = Text::create(this, substring);
256dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        m_current->parserAddChild(t);
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        t->attach();
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (i < size - 1)
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_current = m_tbody;
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
261dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Set current to m_tbody if the last character was a newline.
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (text[text.length() - 1] == '\n')
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_current = m_tbody;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
267f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickint HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor)
268f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
269f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    ASSERT(start <= end);
270f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (start == end)
271f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return start;
272f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
273f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    String text = source.substring(start, end - start);
274f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (!className.isEmpty()) {
275f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (isLink)
276f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            m_current = addLink(text, isAnchor);
277f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        else
278f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            m_current = addSpanWithClassName(className);
279f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
280f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    addText(text, className);
281f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (!className.isEmpty() && m_current != m_tbody)
2826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        m_current = static_cast<Element*>(m_current->parentNode());
283f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    return end;
284f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
285f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
2865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
2875ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
2885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(baseTag, this);
2895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RefPtr<NamedNodeMap> attributeMap = NamedNodeMap::create();
2905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    attributeMap->addAttribute(Attribute::createMapped(hrefAttr, href));
2915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    base->setAttributeMap(attributeMap.release());
2925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_current->parserAddChild(base);
2935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    base->attach();
2945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return base.release();
2955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
2965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor)
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_current == m_tbody)
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addLine("webkit-html-tag");
301dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now create a link for the attribute value instead of a span.
303231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(this);
304e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char* classValue;
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isAnchor)
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        classValue = "webkit-html-attribute-value webkit-html-external-link";
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        classValue = "webkit-html-attribute-value webkit-html-resource-link";
310e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs->addAttribute(Attribute::createMapped(classAttr, classValue));
311e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs->addAttribute(Attribute::createMapped(targetAttr, "_blank"));
312e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    attrs->addAttribute(Attribute::createMapped(hrefAttr, url));
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    anchor->setAttributeMap(attrs.release());
314dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_current->parserAddChild(anchor);
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    anchor->attach();
316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return anchor.release();
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
320