2010-09-08 Adam Barth <abarth@webkit.org>
[WebKit-https.git] / WebCore / html / parser / HTMLViewSourceParser.cpp
1 /*
2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "HTMLViewSourceParser.h"
28
29 #include "HTMLNames.h"
30 #include "HTMLTreeBuilder.h"
31 #include "HTMLViewSourceDocument.h"
32
33 namespace WebCore {
34
35 HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document)
36     : DecodedDataDocumentParser(document)
37     , m_tokenizer(HTMLTokenizer::create())
38 {
39 }
40
41 HTMLViewSourceParser::~HTMLViewSourceParser()
42 {
43 }
44
45 void HTMLViewSourceParser::forcePlaintext()
46 {
47     m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
48 }
49
50 void HTMLViewSourceParser::insert(const SegmentedString&)
51 {
52     ASSERT_NOT_REACHED();
53 }
54
55 void HTMLViewSourceParser::pumpTokenizer()
56 {
57     while (m_tokenizer->nextToken(m_input.current(), m_token)) {
58         m_token.end(m_input.current().numberOfCharactersConsumed());
59         document()->addSource(sourceForToken(), m_token);
60         updateTokenizerState();
61         m_token.clear(m_input.current().numberOfCharactersConsumed());
62     }
63 }
64
65 void HTMLViewSourceParser::append(const SegmentedString& input)
66 {
67     m_input.appendToEnd(input);
68     m_source.append(input);
69     pumpTokenizer();
70 }
71
72 String HTMLViewSourceParser::sourceForToken()
73 {
74     if (m_token.type() == HTMLToken::EndOfFile)
75         return String();
76
77     ASSERT(m_source.numberOfCharactersConsumed() == m_token.startIndex());
78     UChar* data = 0;
79     int length = m_token.endIndex() - m_token.startIndex();
80     String source = String::createUninitialized(length, data);
81     for (int i = 0; i < length; ++i) {
82         data[i] = *m_source;
83         m_source.advance();
84     }
85     return source;
86 }
87
88 void HTMLViewSourceParser::updateTokenizerState()
89 {
90     // FIXME: The tokenizer should do this work for us.
91     if (m_token.type() != HTMLToken::StartTag)
92         return;
93
94     AtomicString tagName(m_token.name().data(), m_token.name().size());
95     m_tokenizer->setState(HTMLTreeBuilder::adjustedLexerState(m_tokenizer->state(), tagName, document()->frame()));
96     if (tagName == HTMLNames::scriptTag) {
97         // The tree builder handles scriptTag separately from the other tokenizer
98         // state adjustments, so we need to handle it separately too.
99         ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
100         m_tokenizer->setState(HTMLTokenizer::ScriptDataState);
101     }
102 }
103
104 void HTMLViewSourceParser::finish()
105 {
106     if (!m_input.haveSeenEndOfFile())
107         m_input.markEndOfFile();
108     pumpTokenizer();
109     document()->finishedParsing();
110 }
111
112 bool HTMLViewSourceParser::finishWasCalled()
113 {
114     return m_input.haveSeenEndOfFile();
115 }
116
117 }