~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/xml/parser/XMLDocumentParserQt.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2000 Peter Kelly (pmk@post.com)
 
3
 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
 
4
 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
 
5
 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
 
6
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
 
7
 * Copyright (C) 2008 Holger Hans Peter Freyther
 
8
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
 
9
 *
 
10
 * This library is free software; you can redistribute it and/or
 
11
 * modify it under the terms of the GNU Library General Public
 
12
 * License as published by the Free Software Foundation; either
 
13
 * version 2 of the License, or (at your option) any later version.
 
14
 *
 
15
 * This library is distributed in the hope that it will be useful,
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
18
 * Library General Public License for more details.
 
19
 *
 
20
 * You should have received a copy of the GNU Library General Public License
 
21
 * along with this library; see the file COPYING.LIB.  If not, write to
 
22
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
23
 * Boston, MA 02110-1301, USA.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "XMLDocumentParser.h"
 
28
 
 
29
#include "CDATASection.h"
 
30
#include "CachedScript.h"
 
31
#include "Comment.h"
 
32
#include "CachedResourceLoader.h"
 
33
#include "Document.h"
 
34
#include "DocumentFragment.h"
 
35
#include "DocumentType.h"
 
36
#include "Frame.h"
 
37
#include "FrameLoader.h"
 
38
#include "FrameView.h"
 
39
#include "HTMLEntityParser.h"
 
40
#include "HTMLHtmlElement.h"
 
41
#include "HTMLLinkElement.h"
 
42
#include "HTMLNames.h"
 
43
#include "HTMLStyleElement.h"
 
44
#include "ProcessingInstruction.h"
 
45
#include "ResourceError.h"
 
46
#include "ResourceHandle.h"
 
47
#include "ResourceRequest.h"
 
48
#include "ResourceResponse.h"
 
49
#include "ScriptableDocumentParser.h"
 
50
#include "ScriptElement.h"
 
51
#include "ScriptSourceCode.h"
 
52
#include "ScriptValue.h"
 
53
#include "TextResourceDecoder.h"
 
54
#include "TransformSource.h"
 
55
#include "XMLNSNames.h"
 
56
#include <QDebug>
 
57
#include <wtf/StringExtras.h>
 
58
#include <wtf/Threading.h>
 
59
#include <wtf/Vector.h>
 
60
#include <wtf/text/CString.h>
 
61
 
 
62
using namespace std;
 
63
 
 
64
namespace WebCore {
 
65
 
 
66
class EntityResolver : public QXmlStreamEntityResolver {
 
67
    virtual QString resolveUndeclaredEntity(const QString &name);
 
68
};
 
69
 
 
70
QString EntityResolver::resolveUndeclaredEntity(const QString &name)
 
71
{
 
72
    UChar c = decodeNamedEntity(name.toUtf8().constData());
 
73
    return QString(c);
 
74
}
 
75
 
 
76
// --------------------------------
 
77
 
 
78
bool XMLDocumentParser::supportsXMLVersion(const String& version)
 
79
{
 
80
    return version == "1.0";
 
81
}
 
82
 
 
83
XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
 
84
    : ScriptableDocumentParser(document)
 
85
    , m_view(frameView)
 
86
    , m_wroteText(false)
 
87
    , m_currentNode(document)
 
88
    , m_sawError(false)
 
89
    , m_sawCSS(false)
 
90
    , m_sawXSLTransform(false)
 
91
    , m_sawFirstElement(false)
 
92
    , m_isXHTMLDocument(false)
 
93
    , m_parserPaused(false)
 
94
    , m_requestingScript(false)
 
95
    , m_finishCalled(false)
 
96
    , m_xmlErrors(document)
 
97
    , m_pendingScript(0)
 
98
    , m_scriptStartPosition(TextPosition::belowRangePosition())
 
99
    , m_parsingFragment(false)
 
100
    , m_scriptingPermission(AllowScriptingContent)
 
101
{
 
102
    m_stream.setEntityResolver(new EntityResolver);
 
103
}
 
104
 
 
105
XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, FragmentScriptingPermission permission)
 
106
    : ScriptableDocumentParser(fragment->document())
 
107
    , m_view(0)
 
108
    , m_wroteText(false)
 
109
    , m_currentNode(fragment)
 
110
    , m_sawError(false)
 
111
    , m_sawCSS(false)
 
112
    , m_sawXSLTransform(false)
 
113
    , m_sawFirstElement(false)
 
114
    , m_isXHTMLDocument(false)
 
115
    , m_parserPaused(false)
 
116
    , m_requestingScript(false)
 
117
    , m_finishCalled(false)
 
118
    , m_xmlErrors(fragment->document())
 
119
    , m_pendingScript(0)
 
120
    , m_scriptStartPosition(TextPosition::belowRangePosition())
 
121
    , m_parsingFragment(true)
 
122
    , m_scriptingPermission(permission)
 
123
{
 
124
    fragment->ref();
 
125
 
 
126
    // Add namespaces based on the parent node
 
127
    Vector<Element*> elemStack;
 
128
    while (parentElement) {
 
129
        elemStack.append(parentElement);
 
130
 
 
131
        Node* n = parentElement->parentNode();
 
132
        if (!n || !n->isElementNode())
 
133
            break;
 
134
        parentElement = static_cast<Element*>(n);
 
135
    }
 
136
 
 
137
    if (elemStack.isEmpty())
 
138
        return;
 
139
 
 
140
    QXmlStreamNamespaceDeclarations namespaces;
 
141
    for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
 
142
        if (const ElementAttributeData* attrs = element->updatedAttributeData()) {
 
143
            for (unsigned i = 0; i < attrs->length(); i++) {
 
144
                const Attribute* attr = attrs->attributeItem(i);
 
145
                if (attr->localName() == "xmlns")
 
146
                    m_defaultNamespaceURI = attr->value();
 
147
                else if (attr->prefix() == "xmlns")
 
148
                    namespaces.append(QXmlStreamNamespaceDeclaration(attr->localName(), attr->value()));
 
149
            }
 
150
        }
 
151
    }
 
152
    m_stream.addExtraNamespaceDeclarations(namespaces);
 
153
    m_stream.setEntityResolver(new EntityResolver);
 
154
 
 
155
    // If the parent element is not in document tree, there may be no xmlns attribute; just default to the parent's namespace.
 
156
    if (m_defaultNamespaceURI.isNull() && !parentElement->inDocument())
 
157
        m_defaultNamespaceURI = parentElement->namespaceURI();
 
158
}
 
159
 
 
160
XMLDocumentParser::~XMLDocumentParser()
 
161
{
 
162
    clearCurrentNodeStack();
 
163
    if (m_pendingScript)
 
164
        m_pendingScript->removeClient(this);
 
165
    delete m_stream.entityResolver();
 
166
}
 
167
 
 
168
void XMLDocumentParser::doWrite(const String& parseString)
 
169
{
 
170
    m_wroteText = true;
 
171
 
 
172
    if (document()->decoder() && document()->decoder()->sawError()) {
 
173
        // If the decoder saw an error, report it as fatal (stops parsing)
 
174
        handleError(XMLErrors::fatal, "Encoding error", textPosition());
 
175
        return;
 
176
    }
 
177
 
 
178
    QString data(parseString);
 
179
    if (!data.isEmpty()) {
 
180
        // JavaScript may cause the parser to detach,
 
181
        // keep this alive until this function is done.
 
182
        RefPtr<XMLDocumentParser> protect(this);
 
183
 
 
184
        m_stream.addData(data);
 
185
        parse();
 
186
    }
 
187
 
 
188
    return;
 
189
}
 
190
 
 
191
void XMLDocumentParser::initializeParserContext(const CString&)
 
192
{
 
193
    DocumentParser::startParsing();
 
194
    m_sawError = false;
 
195
    m_sawCSS = false;
 
196
    m_sawXSLTransform = false;
 
197
    m_sawFirstElement = false;
 
198
}
 
199
 
 
200
void XMLDocumentParser::doEnd()
 
201
{
 
202
#if ENABLE(XSLT)
 
203
    if (m_sawXSLTransform) {
 
204
        document()->setTransformSource(adoptPtr(new TransformSource(m_originalSourceForTransform.toString())));
 
205
        document()->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
 
206
        document()->styleResolverChanged(RecalcStyleImmediately);
 
207
 
 
208
        // styleResolverChanged() call can detach the parser and null out its document.
 
209
        // In that case, we just bail out.
 
210
        if (isDetached())
 
211
            return;
 
212
 
 
213
        document()->setParsing(true);
 
214
        DocumentParser::stopParsing();
 
215
    }
 
216
#endif
 
217
 
 
218
    if (m_stream.error() == QXmlStreamReader::PrematureEndOfDocumentError
 
219
        || (m_wroteText && !m_sawFirstElement && !m_sawXSLTransform && !m_sawError))
 
220
        handleError(XMLErrors::fatal, qPrintable(m_stream.errorString()), textPosition());
 
221
}
 
222
 
 
223
OrdinalNumber XMLDocumentParser::lineNumber() const
 
224
{
 
225
    return OrdinalNumber::fromOneBasedInt(m_stream.lineNumber());
 
226
}
 
227
 
 
228
OrdinalNumber XMLDocumentParser::columnNumber() const
 
229
{
 
230
    return OrdinalNumber::fromOneBasedInt(m_stream.columnNumber());
 
231
}
 
232
 
 
233
TextPosition XMLDocumentParser::textPosition() const
 
234
{
 
235
    return TextPosition(lineNumber(), columnNumber());
 
236
}
 
237
 
 
238
void XMLDocumentParser::stopParsing()
 
239
{
 
240
    ScriptableDocumentParser::stopParsing();
 
241
}
 
242
 
 
243
void XMLDocumentParser::resumeParsing()
 
244
{
 
245
    ASSERT(m_parserPaused);
 
246
 
 
247
    m_parserPaused = false;
 
248
 
 
249
    // First, execute any pending callbacks
 
250
    parse();
 
251
    if (m_parserPaused)
 
252
        return;
 
253
 
 
254
    // Then, write any pending data
 
255
    SegmentedString rest = m_pendingSrc;
 
256
    m_pendingSrc.clear();
 
257
    append(rest);
 
258
 
 
259
    // Finally, if finish() has been called and append() didn't result
 
260
    // in any further callbacks being queued, call end()
 
261
    if (m_finishCalled && !m_parserPaused && !m_pendingScript)
 
262
        end();
 
263
}
 
264
 
 
265
bool XMLDocumentParser::appendFragmentSource(const String& source)
 
266
{
 
267
    ASSERT(!m_sawFirstElement);
 
268
    append(String("<qxmlstreamdummyelement>"));
 
269
    append(source);
 
270
    append(String("</qxmlstreamdummyelement>"));
 
271
    return !hasError();
 
272
}
 
273
 
 
274
// --------------------------------
 
275
 
 
276
struct AttributeParseState {
 
277
    HashMap<String, String> attributes;
 
278
    bool gotAttributes;
 
279
};
 
280
 
 
281
static void attributesStartElementNsHandler(AttributeParseState* state, const QXmlStreamAttributes& attrs)
 
282
{
 
283
    if (attrs.count() <= 0)
 
284
        return;
 
285
 
 
286
    state->gotAttributes = true;
 
287
 
 
288
    for (int i = 0; i < attrs.count(); i++) {
 
289
        const QXmlStreamAttribute& attr = attrs[i];
 
290
        String attrLocalName = attr.name();
 
291
        String attrValue     = attr.value();
 
292
        String attrURI       = attr.namespaceUri();
 
293
        String attrQName     = attr.qualifiedName();
 
294
        state->attributes.set(attrQName, attrValue);
 
295
    }
 
296
}
 
297
 
 
298
HashMap<String, String> parseAttributes(const String& string, bool& attrsOK)
 
299
{
 
300
    AttributeParseState state;
 
301
    state.gotAttributes = false;
 
302
 
 
303
    QXmlStreamReader stream;
 
304
    QString dummy = QString(QLatin1String("<?xml version=\"1.0\"?><attrs %1 />")).arg(string);
 
305
    stream.addData(dummy);
 
306
    while (!stream.atEnd()) {
 
307
        stream.readNext();
 
308
        if (stream.isStartElement()) {
 
309
            attributesStartElementNsHandler(&state, stream.attributes());
 
310
        }
 
311
    }
 
312
    attrsOK = state.gotAttributes;
 
313
    return state.attributes;
 
314
}
 
315
 
 
316
static inline String prefixFromQName(const QString& qName)
 
317
{
 
318
    const int offset = qName.indexOf(QLatin1Char(':'));
 
319
    if (offset <= 0)
 
320
        return String();
 
321
    else
 
322
        return qName.left(offset);
 
323
}
 
324
 
 
325
static inline void handleNamespaceAttributes(Vector<Attribute, 8>& prefixedAttributes, const QXmlStreamNamespaceDeclarations &ns, ExceptionCode& ec)
 
326
{
 
327
    for (int i = 0; i < ns.count(); ++i) {
 
328
        const QXmlStreamNamespaceDeclaration &decl = ns[i];
 
329
        String namespaceURI = decl.namespaceUri();
 
330
        String namespaceQName = decl.prefix().isEmpty() ? String("xmlns") : String("xmlns:");
 
331
        namespaceQName.append(decl.prefix());
 
332
 
 
333
        QualifiedName parsedName = anyName;
 
334
        if (!Element::parseAttributeName(parsedName, XMLNSNames::xmlnsNamespaceURI, namespaceQName, ec))
 
335
            return;
 
336
 
 
337
        prefixedAttributes.append(Attribute(parsedName, namespaceURI));
 
338
    }
 
339
}
 
340
 
 
341
static inline void handleElementAttributes(Vector<Attribute, 8>& prefixedAttributes, const QXmlStreamAttributes &attrs, ExceptionCode& ec)
 
342
{
 
343
    for (int i = 0; i < attrs.count(); ++i) {
 
344
        const QXmlStreamAttribute &attr = attrs[i];
 
345
        String attrLocalName = attr.name();
 
346
        String attrValue     = attr.value();
 
347
        String attrURI       = attr.namespaceUri().isEmpty() ? String() : String(attr.namespaceUri());
 
348
        String attrQName     = attr.qualifiedName();
 
349
 
 
350
        QualifiedName parsedName = anyName;
 
351
        if (!Element::parseAttributeName(parsedName, attrURI, attrQName, ec))
 
352
            return;
 
353
 
 
354
        prefixedAttributes.append(Attribute(parsedName, attrValue));
 
355
    }
 
356
}
 
357
 
 
358
void XMLDocumentParser::parse()
 
359
{
 
360
    while (!isStopped() && !m_parserPaused && !m_stream.atEnd()) {
 
361
        m_stream.readNext();
 
362
        switch (m_stream.tokenType()) {
 
363
        case QXmlStreamReader::StartDocument:
 
364
            startDocument();
 
365
            break;
 
366
        case QXmlStreamReader::EndDocument:
 
367
            endDocument();
 
368
            break;
 
369
        case QXmlStreamReader::StartElement:
 
370
            parseStartElement();
 
371
            break;
 
372
        case QXmlStreamReader::EndElement:
 
373
            parseEndElement();
 
374
            break;
 
375
        case QXmlStreamReader::Characters: {
 
376
            if (m_stream.isCDATA()) {
 
377
                //cdata
 
378
                parseCdata();
 
379
            } else {
 
380
                //characters
 
381
                parseCharacters();
 
382
            }
 
383
            break;
 
384
        }
 
385
        case QXmlStreamReader::Comment:
 
386
            parseComment();
 
387
            break;
 
388
        case QXmlStreamReader::DTD:
 
389
            //qDebug()<<"------------- DTD";
 
390
            parseDtd();
 
391
            break;
 
392
        case QXmlStreamReader::EntityReference: {
 
393
            //qDebug()<<"---------- ENTITY = "<<m_stream.name().toString()
 
394
            //        <<", t = "<<m_stream.text().toString();
 
395
            if (isXHTMLDocument()) {
 
396
                QString entity = m_stream.name().toString();
 
397
                UChar c = decodeNamedEntity(entity.toUtf8().constData());
 
398
                if (!m_leafTextNode)
 
399
                    enterText();
 
400
                ExceptionCode ec = 0;
 
401
                String str(&c, 1);
 
402
                // qDebug()<<" ------- adding entity "<<str;
 
403
                m_leafTextNode->appendData(str, ec);
 
404
            }
 
405
            break;
 
406
        }
 
407
        case QXmlStreamReader::ProcessingInstruction:
 
408
            parseProcessingInstruction();
 
409
            break;
 
410
        default: {
 
411
            if (m_stream.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
 
412
                XMLErrors::ErrorType type = (m_stream.error() == QXmlStreamReader::NotWellFormedError) ?
 
413
                                 XMLErrors::fatal : XMLErrors::warning;
 
414
                handleError(type, qPrintable(m_stream.errorString()), textPosition());
 
415
            }
 
416
            break;
 
417
        }
 
418
        }
 
419
    }
 
420
}
 
421
 
 
422
void XMLDocumentParser::startDocument()
 
423
{
 
424
    initializeParserContext();
 
425
    ExceptionCode ec = 0;
 
426
 
 
427
    if (!m_parsingFragment) {
 
428
        document()->setXMLStandalone(m_stream.isStandaloneDocument(), ec);
 
429
 
 
430
        QStringRef version = m_stream.documentVersion();
 
431
        if (!version.isEmpty())
 
432
            document()->setXMLVersion(version, ec);
 
433
        QStringRef encoding = m_stream.documentEncoding();
 
434
        if (!encoding.isEmpty())
 
435
            document()->setXMLEncoding(encoding);
 
436
        document()->setHasXMLDeclaration(!version.isEmpty());
 
437
    }
 
438
}
 
439
 
 
440
void XMLDocumentParser::parseStartElement()
 
441
{
 
442
    if (!m_sawFirstElement && m_parsingFragment) {
 
443
        // skip dummy element for fragments
 
444
        m_sawFirstElement = true;
 
445
        return;
 
446
    }
 
447
 
 
448
    exitText();
 
449
 
 
450
    String localName = m_stream.name();
 
451
    String uri       = m_stream.namespaceUri();
 
452
    String prefix    = prefixFromQName(m_stream.qualifiedName().toString());
 
453
 
 
454
    if (m_parsingFragment && uri.isNull()) {
 
455
        Q_ASSERT(prefix.isNull());
 
456
        uri = m_defaultNamespaceURI;
 
457
    }
 
458
 
 
459
    QualifiedName qName(prefix, localName, uri);
 
460
    RefPtr<Element> newElement = document()->createElement(qName, true);
 
461
    if (!newElement) {
 
462
        stopParsing();
 
463
        return;
 
464
    }
 
465
 
 
466
    bool isFirstElement = !m_sawFirstElement;
 
467
    m_sawFirstElement = true;
 
468
 
 
469
    Vector<Attribute, 8> prefixedAttributes;
 
470
    ExceptionCode ec = 0;
 
471
    handleNamespaceAttributes(prefixedAttributes, m_stream.namespaceDeclarations(), ec);
 
472
    if (ec) {
 
473
        newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
 
474
        stopParsing();
 
475
        return;
 
476
    }
 
477
 
 
478
    handleElementAttributes(prefixedAttributes, m_stream.attributes(), ec);
 
479
    newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
 
480
    if (ec) {
 
481
        stopParsing();
 
482
        return;
 
483
    }
 
484
 
 
485
    ScriptElement* scriptElement = toScriptElement(newElement.get());
 
486
    if (scriptElement)
 
487
        m_scriptStartPosition = textPosition();
 
488
 
 
489
    m_currentNode->parserAppendChild(newElement.get());
 
490
 
 
491
    pushCurrentNode(newElement.get());
 
492
    if (m_view && !newElement->attached())
 
493
        newElement->attach();
 
494
 
 
495
    if (newElement->hasTagName(HTMLNames::htmlTag))
 
496
        static_cast<HTMLHtmlElement*>(newElement.get())->insertedByParser();
 
497
 
 
498
    if (isFirstElement && document()->frame())
 
499
        document()->frame()->loader()->dispatchDocumentElementAvailable();
 
500
}
 
501
 
 
502
void XMLDocumentParser::parseEndElement()
 
503
{
 
504
    exitText();
 
505
 
 
506
    RefPtr<ContainerNode> n = m_currentNode;
 
507
    n->finishParsingChildren();
 
508
 
 
509
    if (m_scriptingPermission == DisallowScriptingContent && n->isElementNode() && toScriptElement(static_cast<Element*>(n.get()))) {
 
510
        popCurrentNode();
 
511
        ExceptionCode ec;
 
512
        n->remove(ec);
 
513
        return;
 
514
    }
 
515
 
 
516
    if (!n->isElementNode() || !m_view) {
 
517
        if (!m_currentNodeStack.isEmpty())
 
518
            popCurrentNode();
 
519
        return;
 
520
    }
 
521
 
 
522
    Element* element = static_cast<Element*>(n.get());
 
523
 
 
524
    // The element's parent may have already been removed from document.
 
525
    // Parsing continues in this case, but scripts aren't executed.
 
526
    if (!element->inDocument()) {
 
527
        popCurrentNode();
 
528
        return;
 
529
    }
 
530
 
 
531
    ScriptElement* scriptElement = toScriptElement(element);
 
532
    if (!scriptElement) {
 
533
        popCurrentNode();
 
534
        return;
 
535
    }
 
536
 
 
537
    // don't load external scripts for standalone documents (for now)
 
538
    ASSERT(!m_pendingScript);
 
539
    m_requestingScript = true;
 
540
 
 
541
    if (scriptElement->prepareScript(m_scriptStartPosition, ScriptElement::AllowLegacyTypeInTypeAttribute)) {
 
542
        if (scriptElement->readyToBeParserExecuted())
 
543
            scriptElement->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartPosition));
 
544
        else if (scriptElement->willBeParserExecuted()) {
 
545
            m_pendingScript = scriptElement->cachedScript();
 
546
            m_scriptElement = element;
 
547
            m_pendingScript->addClient(this);
 
548
 
 
549
            // m_pendingScript will be 0 if script was already loaded and addClient() executed it.
 
550
            if (m_pendingScript)
 
551
                pauseParsing();
 
552
        } else
 
553
            m_scriptElement = 0;
 
554
    }
 
555
    m_requestingScript = false;
 
556
    popCurrentNode();
 
557
}
 
558
 
 
559
void XMLDocumentParser::parseCharacters()
 
560
{
 
561
    if (!m_leafTextNode)
 
562
        enterText();
 
563
    ExceptionCode ec = 0;
 
564
    m_leafTextNode->appendData(m_stream.text(), ec);
 
565
}
 
566
 
 
567
void XMLDocumentParser::parseProcessingInstruction()
 
568
{
 
569
    exitText();
 
570
 
 
571
    // ### handle exceptions
 
572
    int exception = 0;
 
573
    RefPtr<ProcessingInstruction> pi = document()->createProcessingInstruction(
 
574
        m_stream.processingInstructionTarget(),
 
575
        m_stream.processingInstructionData(), exception);
 
576
    if (exception)
 
577
        return;
 
578
 
 
579
    pi->setCreatedByParser(true);
 
580
 
 
581
    m_currentNode->parserAppendChild(pi.get());
 
582
    if (m_view && !pi->attached())
 
583
        pi->attach();
 
584
 
 
585
    pi->finishParsingChildren();
 
586
 
 
587
    if (pi->isCSS())
 
588
        m_sawCSS = true;
 
589
#if ENABLE(XSLT)
 
590
    m_sawXSLTransform = !m_sawFirstElement && pi->isXSL();
 
591
    if (m_sawXSLTransform && !document()->transformSourceDocument())
 
592
        stopParsing();
 
593
#endif
 
594
}
 
595
 
 
596
void XMLDocumentParser::parseCdata()
 
597
{
 
598
    exitText();
 
599
 
 
600
    RefPtr<CDATASection> newNode = CDATASection::create(document(), m_stream.text());
 
601
 
 
602
    m_currentNode->parserAppendChild(newNode.get());
 
603
    if (m_view && !newNode->attached())
 
604
        newNode->attach();
 
605
}
 
606
 
 
607
void XMLDocumentParser::parseComment()
 
608
{
 
609
    exitText();
 
610
 
 
611
    RefPtr<Comment> newNode = Comment::create(document(), m_stream.text());
 
612
 
 
613
    m_currentNode->parserAppendChild(newNode.get());
 
614
    if (m_view && !newNode->attached())
 
615
        newNode->attach();
 
616
}
 
617
 
 
618
void XMLDocumentParser::endDocument()
 
619
{
 
620
}
 
621
 
 
622
bool XMLDocumentParser::hasError() const
 
623
{
 
624
    return m_stream.hasError();
 
625
}
 
626
 
 
627
void XMLDocumentParser::parseDtd()
 
628
{
 
629
    QStringRef name = m_stream.dtdName();
 
630
    QStringRef publicId = m_stream.dtdPublicId();
 
631
    QStringRef systemId = m_stream.dtdSystemId();
 
632
 
 
633
    //qDebug() << dtd << name << publicId << systemId;
 
634
    if ((publicId == QLatin1String("-//W3C//DTD XHTML 1.0 Transitional//EN"))
 
635
        || (publicId == QLatin1String("-//W3C//DTD XHTML 1.1//EN"))
 
636
        || (publicId == QLatin1String("-//W3C//DTD XHTML 1.0 Strict//EN"))
 
637
        || (publicId == QLatin1String("-//W3C//DTD XHTML 1.0 Frameset//EN"))
 
638
        || (publicId == QLatin1String("-//W3C//DTD XHTML Basic 1.0//EN"))
 
639
        || (publicId == QLatin1String("-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"))
 
640
        || (publicId == QLatin1String("-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"))
 
641
        || (publicId == QLatin1String("-//WAPFORUM//DTD XHTML Mobile 1.0//EN"))
 
642
       )
 
643
        setIsXHTMLDocument(true); // controls if we replace entities or not.
 
644
    if (!m_parsingFragment)
 
645
        document()->parserAppendChild(DocumentType::create(document(), name, publicId, systemId));
 
646
 
 
647
}
 
648
}