#include "config.h"
#include "dom_xmlimpl.h"
#include "CachedCSSStyleSheet.h"
#include "CachedXSLStyleSheet.h"
#include "DocLoader.h"
#include "Document.h"
#include "ExceptionCode.h"
#include "xml_tokenizer.h"
#if KHTML_XSLT
#include "XSLStyleSheet.h"
#endif
#include "css_stylesheetimpl.h"
namespace WebCore {
Entity::Entity(Document* doc) : ContainerNode(doc)
{
}
Entity::Entity(Document* doc, const String& name) : ContainerNode(doc), m_name(name.impl())
{
}
Entity::Entity(Document* doc, const String& publicId, const String& systemId, const String& notationName)
: ContainerNode(doc), m_publicId(publicId.impl()), m_systemId(systemId.impl()), m_notationName(notationName.impl())
{
}
String Entity::nodeName() const
{
return m_name.get();
}
Node::NodeType Entity::nodeType() const
{
return ENTITY_NODE;
}
PassRefPtr<Node> Entity::cloneNode(bool )
{
return 0;
}
bool Entity::childTypeAllowed(NodeType type)
{
switch (type) {
case ELEMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
case COMMENT_NODE:
case TEXT_NODE:
case CDATA_SECTION_NODE:
case ENTITY_REFERENCE_NODE:
return true;
break;
default:
return false;
}
}
String Entity::toString() const
{
String result = "<!ENTITY' ";
if (m_name && m_name->length()) {
result += " ";
result += m_name.get();
}
if (m_publicId && m_publicId->length()) {
result += " PUBLIC \"";
result += m_publicId.get();
result += "\" \"";
result += m_systemId.get();
result += "\"";
} else if (m_systemId && m_systemId->length()) {
result += " SYSTEM \"";
result += m_systemId.get();
result += "\"";
}
if (m_notationName && m_notationName->length()) {
result += " NDATA ";
result += m_notationName.get();
}
result += ">";
return result;
}
EntityReference::EntityReference(Document* doc) : ContainerNode(doc)
{
}
EntityReference::EntityReference(Document* doc, StringImpl* entityName)
: ContainerNode(doc), m_entityName(entityName)
{
}
String EntityReference::nodeName() const
{
return m_entityName.get();
}
Node::NodeType EntityReference::nodeType() const
{
return ENTITY_REFERENCE_NODE;
}
PassRefPtr<Node> EntityReference::cloneNode(bool deep)
{
RefPtr<EntityReference> clone = new EntityReference(document(), m_entityName.get());
if (deep)
cloneChildNodes(clone.get());
return clone.release();
}
bool EntityReference::childTypeAllowed(NodeType type)
{
switch (type) {
case ELEMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
case COMMENT_NODE:
case TEXT_NODE:
case CDATA_SECTION_NODE:
case ENTITY_REFERENCE_NODE:
return true;
break;
default:
return false;
}
}
String EntityReference::toString() const
{
String result = "&";
result += m_entityName.get();
result += ";";
return result;
}
Notation::Notation(Document* doc) : ContainerNode(doc)
{
}
Notation::Notation(Document* doc, const String& name, const String& publicId, const String& systemId)
: ContainerNode(doc), m_name(name.impl()), m_publicId(publicId.impl()), m_systemId(systemId.impl())
{
}
String Notation::nodeName() const
{
return m_name.get();
}
Node::NodeType Notation::nodeType() const
{
return NOTATION_NODE;
}
PassRefPtr<Node> Notation::cloneNode(bool )
{
return 0;
}
bool Notation::childTypeAllowed(NodeType)
{
return false;
}
ProcessingInstruction::ProcessingInstruction(Document* doc)
: ContainerNode(doc), m_cachedSheet(0), m_loading(false)
{
#if KHTML_XSLT
m_isXSL = false;
#endif
}
ProcessingInstruction::ProcessingInstruction(Document* doc, const String& target, const String& data)
: ContainerNode(doc), m_target(target.impl()), m_data(data.impl()), m_cachedSheet(0), m_loading(false)
{
#if KHTML_XSLT
m_isXSL = false;
#endif
}
ProcessingInstruction::~ProcessingInstruction()
{
if (m_cachedSheet)
m_cachedSheet->deref(this);
}
void ProcessingInstruction::setData(const String& data, ExceptionCode& ec)
{
if (isReadOnlyNode()) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
m_data = data.impl();
}
String ProcessingInstruction::nodeName() const
{
return m_target.get();
}
Node::NodeType ProcessingInstruction::nodeType() const
{
return PROCESSING_INSTRUCTION_NODE;
}
String ProcessingInstruction::nodeValue() const
{
return m_data.get();
}
void ProcessingInstruction::setNodeValue(const String& nodeValue, ExceptionCode& ec)
{
setData(nodeValue, ec);
}
PassRefPtr<Node> ProcessingInstruction::cloneNode(bool )
{
return new ProcessingInstruction(document(), m_target.get(), m_data.get());
}
bool ProcessingInstruction::childTypeAllowed(NodeType)
{
return false;
}
bool ProcessingInstruction::checkStyleSheet()
{
if (String(m_target.get()) == "xml-stylesheet") {
bool attrsOk;
const HashMap<String, String> attrs = parseAttributes(m_data.get(), attrsOk);
if (!attrsOk)
return true;
HashMap<String, String>::const_iterator i = attrs.find("type");
String type;
if (i != attrs.end())
type = i->second;
bool isCSS = type.isEmpty() || type == "text/css";
#if KHTML_XSLT
m_isXSL = (type == "text/xml" || type == "text/xsl" || type == "application/xml" ||
type == "application/xhtml+xml" || type == "application/rss+xml" || type == "application/atom=xml");
if (!isCSS && !m_isXSL)
#else
if (!isCSS)
#endif
return true;
String href = attrs.get("href");
if (href.length() > 1) {
if (href[0] == '#') {
m_localHref = href.substring(1).impl();
#if KHTML_XSLT
if (m_isXSL) {
m_sheet = new XSLStyleSheet(this, m_localHref.get(), true);
m_loading = false;
}
return !m_isXSL;
#endif
}
else
{
if (document()->frame()) {
m_loading = true;
document()->addPendingSheet();
if (m_cachedSheet)
m_cachedSheet->deref(this);
#if KHTML_XSLT
if (m_isXSL)
m_cachedSheet = document()->docLoader()->requestXSLStyleSheet(document()->completeURL(href));
else
#endif
m_cachedSheet = document()->docLoader()->requestStyleSheet(document()->completeURL(href), DeprecatedString::null);
if (m_cachedSheet)
m_cachedSheet->ref( this );
#if KHTML_XSLT
return !m_isXSL;
#endif
}
}
}
}
return true;
}
bool ProcessingInstruction::isLoading() const
{
if (m_loading)
return true;
if (!m_sheet)
return false;
return m_sheet->isLoading();
}
void ProcessingInstruction::sheetLoaded()
{
if (!isLoading())
document()->stylesheetLoaded();
}
void ProcessingInstruction::setStyleSheet(const String &url, const String &sheet)
{
#if KHTML_XSLT
if (m_isXSL)
m_sheet = new XSLStyleSheet(this, url);
else
#endif
m_sheet = new CSSStyleSheet(this, url);
m_sheet->parseString(sheet);
if (m_cachedSheet)
m_cachedSheet->deref(this);
m_cachedSheet = 0;
m_loading = false;
if (!isLoading() && m_sheet)
document()->stylesheetLoaded();
}
String ProcessingInstruction::toString() const
{
String result = "<?";
result += m_target.get();
result += " ";
result += m_data.get();
result += "?>";
return result;
}
void ProcessingInstruction::setStyleSheet(StyleSheet* sheet)
{
m_sheet = sheet;
}
bool ProcessingInstruction::offsetInCharacters() const
{
return true;
}
}