/*
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2008, 2014 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
#include "config.h"
#include "core/xml/parser/XMLDocumentParser.h"
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/ScriptSourceCode.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionStatePlaceholder.h"
+#include "bindings/core/v8/ScriptController.h"
+#include "bindings/core/v8/ScriptSourceCode.h"
+#include "bindings/core/v8/V8Document.h"
#include "core/FetchInitiatorTypeNames.h"
#include "core/HTMLNames.h"
#include "core/XMLNSNames.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/ImageLoader.h"
#include "core/svg/graphics/SVGImage.h"
-#include "core/xml/XMLTreeViewer.h"
#include "core/xml/parser/SharedBufferReader.h"
#include "core/xml/parser/XMLDocumentParserScope.h"
#include "core/xml/parser/XMLParserInput.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/SharedBuffer.h"
+#include "platform/TraceEvent.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
#include <libxml/parserInternals.h>
#include <libxslt/xslt.h>
-namespace WebCore {
+namespace blink {
using namespace HTMLNames;
return true;
}
-class PendingStartElementNSCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingStartElementNSCallback final : public XMLDocumentParser::PendingCallback {
public:
PendingStartElementNSCallback(const AtomicString& localName, const AtomicString& prefix, const AtomicString& uri,
int namespaceCount, const xmlChar** namespaces, int attributeCount, int defaultedCount, const xmlChar** attributes)
xmlFree(m_attributes);
}
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->startElementNs(m_localName, m_prefix, m_uri,
m_namespaceCount, const_cast<const xmlChar**>(m_namespaces),
xmlChar** m_attributes;
};
-class PendingEndElementNSCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingEndElementNSCallback final : public XMLDocumentParser::PendingCallback {
public:
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->endElementNs();
}
};
-class PendingCharactersCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingCharactersCallback final : public XMLDocumentParser::PendingCallback {
public:
PendingCharactersCallback(const xmlChar* chars, int length)
: m_chars(xmlStrndup(chars, length))
xmlFree(m_chars);
}
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->characters(m_chars, m_length);
}
int m_length;
};
-class PendingProcessingInstructionCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingProcessingInstructionCallback final : public XMLDocumentParser::PendingCallback {
public:
PendingProcessingInstructionCallback(const String& target, const String& data)
: m_target(target)
{
}
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->processingInstruction(m_target, m_data);
}
String m_data;
};
-class PendingCDATABlockCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingCDATABlockCallback final : public XMLDocumentParser::PendingCallback {
public:
explicit PendingCDATABlockCallback(const String& text) : m_text(text) { }
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->cdataBlock(m_text);
}
String m_text;
};
-class PendingCommentCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingCommentCallback final : public XMLDocumentParser::PendingCallback {
public:
explicit PendingCommentCallback(const String& text) : m_text(text) { }
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->comment(m_text);
}
String m_text;
};
-class PendingInternalSubsetCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingInternalSubsetCallback final : public XMLDocumentParser::PendingCallback {
public:
PendingInternalSubsetCallback(const String& name, const String& externalID, const String& systemID)
: m_name(name)
{
}
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->internalSubset(m_name, m_externalID, m_systemID);
}
String m_systemID;
};
-class PendingErrorCallback FINAL : public XMLDocumentParser::PendingCallback {
+class PendingErrorCallback final : public XMLDocumentParser::PendingCallback {
public:
PendingErrorCallback(XMLErrors::ErrorType type, const xmlChar* message, OrdinalNumber lineNumber, OrdinalNumber columnNumber)
: m_type(type)
xmlFree(m_message);
}
- virtual void call(XMLDocumentParser* parser) OVERRIDE
+ virtual void call(XMLDocumentParser* parser) override
{
parser->handleError(m_type, reinterpret_cast<char*>(m_message), TextPosition(m_lineNumber, m_columnNumber));
}
void XMLDocumentParser::end()
{
+ TRACE_EVENT0("blink", "XMLDocumentParser::end");
// XMLDocumentParserLibxml2 will do bad things to the document if doEnd() is called.
// I don't believe XMLDocumentParserQt needs doEnd called in the fragment case.
ASSERT(!m_parsingFragment);
// makes sense to call any methods on DocumentParser once it's been stopped.
// However, FrameLoader::stop calls DocumentParser::finish unconditionally.
+ // flush may ending up executing arbitrary script, and possibly detach the parser.
+ RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
+ flush();
+ if (isDetached())
+ return;
+
if (m_parserPaused)
m_finishCalled = true;
else
// FIXME: We need to implement the HTML5 XML Fragment parsing algorithm:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#xml-fragment-parsing-algorithm
// For now we have a hack for script/style innerHTML support:
- if (contextElement && (contextElement->hasLocalName(HTMLNames::scriptTag) || contextElement->hasLocalName(HTMLNames::styleTag))) {
+ if (contextElement && (contextElement->hasLocalName(scriptTag.localName()) || contextElement->hasLocalName(styleTag.localName()))) {
fragment->parserAppendChild(fragment->document().createTextNode(chunk));
return true;
}
if (!shouldAllowExternalLoad(finalURL))
return &globalDescriptor;
+ UseCounter::count(XMLDocumentParserScope::currentFetcher->document(), UseCounter::XMLExternalResourceLoad);
+
return new SharedBufferReader(data);
}
while (parentElement) {
elemStack.append(parentElement);
- ContainerNode* n = parentElement->parentNode();
- if (!n || !n->isElementNode())
+ Element* grandParentElement = parentElement->parentElement();
+ if (!grandParentElement)
break;
- parentElement = toElement(n);
+ parentElement = grandParentElement;
}
if (elemStack.isEmpty())
for (; !elemStack.isEmpty(); elemStack.removeLast()) {
Element* element = elemStack.last();
- if (element->hasAttributes()) {
- AttributeCollection attributes = element->attributes();
- AttributeCollection::const_iterator end = attributes.end();
- for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
- if (it->localName() == xmlnsAtom)
- m_defaultNamespaceURI = it->value();
- else if (it->prefix() == xmlnsAtom)
- m_prefixToNamespaceMap.set(it->localName(), it->value());
- }
+ AttributeCollection attributes = element->attributes();
+ AttributeCollection::iterator end = attributes.end();
+ for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
+ if (it->localName() == xmlnsAtom)
+ m_defaultNamespaceURI = it->value();
+ else if (it->prefix() == xmlnsAtom)
+ m_prefixToNamespaceMap.set(it->localName(), it->value());
}
}
void XMLDocumentParser::doWrite(const String& parseString)
{
+ TRACE_EVENT0("blink", "XMLDocumentParser::doWrite");
ASSERT(!isDetached());
if (!m_context)
initializeParserContext();
AtomicString namespaceQName = xmlnsAtom;
AtomicString namespaceURI = toAtomicString(namespaces[i].uri);
if (namespaces[i].prefix)
- namespaceQName = "xmlns:" + toString(namespaces[i].prefix);
+ namespaceQName = WTF::xmlnsWithColon + namespaces[i].prefix;
QualifiedName parsedName = anyName;
if (!Element::parseAttributeName(parsedName, XMLNSNames::xmlnsNamespaceURI, namespaceQName, exceptionState))
m_currentNode->parserAppendChild(newElement.get());
+ // Event handlers may synchronously trigger removal of the
+ // document and cancellation of this parser.
+ if (isStopped()) {
+ stopParsing();
+ return;
+ }
+
if (isHTMLTemplateElement(*newElement))
pushCurrentNode(toHTMLTemplateElement(*newElement).content());
else
sax.ignorableWhitespace = ignorableWhitespaceHandler;
sax.entityDecl = xmlSAX2EntityDecl;
sax.initialized = XML_SAX2_MAGIC;
- DocumentParser::startParsing();
m_sawError = false;
m_sawCSS = false;
m_sawXSLTransform = false;
bool xmlViewerMode = !m_sawError && !m_sawCSS && !m_sawXSLTransform && hasNoStyleInformation(document());
if (xmlViewerMode) {
- XMLTreeViewer xmlTreeViewer(document());
- xmlTreeViewer.transformDocumentToTreeView();
+ const char noStyleMessage[] = "This XML file does not appear to have any style information associated with it. The document tree is shown below.";
+ document()->setIsViewSource(true);
+ V8Document::PrivateScript::transformDocumentToTreeViewMethod(document()->frame(), document(), noStyleMessage);
} else if (m_sawXSLTransform) {
xmlDocPtr doc = xmlDocPtrForString(document()->fetcher(), m_originalSourceForTransform.toString(), document()->url().string());
document()->setTransformSource(adoptPtr(new TransformSource(doc)));
if (chunkAsUtf8.length() > INT_MAX)
return false;
+ TRACE_EVENT0("blink", "XMLDocumentParser::appendFragmentSource");
initializeParserContext(chunkAsUtf8);
xmlParseContent(context());
endDocument(); // Close any open text nodes.
return state.attributes;
}
-} // namespace WebCore
+} // namespace blink