summaryrefslogtreecommitdiffstats
path: root/WebCore/dom
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit9364f22aed35e1a1e9d07c121510f80be3ab0502 (patch)
treed49911209b132da58d838efa852daf28d516df21 /WebCore/dom
parent87eb0cb35bad8784770ebc807e6c982432e47107 (diff)
downloadexternal_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.zip
external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.gz
external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.bz2
Initial Contribution
Diffstat (limited to 'WebCore/dom')
-rw-r--r--WebCore/dom/Attr.cpp12
-rw-r--r--WebCore/dom/Attr.h4
-rw-r--r--WebCore/dom/Attribute.h6
-rw-r--r--WebCore/dom/CharacterData.cpp10
-rw-r--r--WebCore/dom/CharacterData.h4
-rwxr-xr-xWebCore/dom/Clipboard.cpp3
-rw-r--r--WebCore/dom/Comment.cpp2
-rw-r--r--WebCore/dom/ContainerNode.cpp43
-rw-r--r--WebCore/dom/ContainerNode.h1
-rw-r--r--WebCore/dom/DOMImplementation.cpp14
-rw-r--r--WebCore/dom/DOMImplementation.h3
-rw-r--r--WebCore/dom/Document.cpp300
-rw-r--r--WebCore/dom/Document.h87
-rw-r--r--WebCore/dom/Document.idl4
-rw-r--r--WebCore/dom/DocumentType.cpp64
-rw-r--r--WebCore/dom/DocumentType.h5
-rw-r--r--WebCore/dom/Element.cpp212
-rw-r--r--WebCore/dom/Element.h14
-rw-r--r--WebCore/dom/Event.cpp6
-rw-r--r--WebCore/dom/EventListener.h1
-rw-r--r--WebCore/dom/EventTargetNode.cpp36
-rw-r--r--WebCore/dom/EventTargetNode.h9
-rw-r--r--WebCore/dom/ExceptionBase.cpp1
-rw-r--r--WebCore/dom/NamedAttrMap.cpp8
-rw-r--r--WebCore/dom/NamedAttrMap.h5
-rw-r--r--WebCore/dom/NamedNodeMap.h2
-rw-r--r--WebCore/dom/Node.cpp84
-rw-r--r--WebCore/dom/Node.h13
-rw-r--r--WebCore/dom/NodeFilter.cpp17
-rw-r--r--WebCore/dom/NodeFilter.h12
-rw-r--r--WebCore/dom/NodeFilter.idl4
-rw-r--r--WebCore/dom/NodeFilterCondition.cpp10
-rw-r--r--WebCore/dom/NodeFilterCondition.h11
-rw-r--r--WebCore/dom/NodeIterator.cpp173
-rw-r--r--WebCore/dom/NodeIterator.h54
-rw-r--r--WebCore/dom/NodeIterator.idl6
-rw-r--r--WebCore/dom/NodeList.h2
-rw-r--r--WebCore/dom/Position.cpp77
-rw-r--r--WebCore/dom/ProcessingInstruction.cpp15
-rw-r--r--WebCore/dom/ProcessingInstruction.h2
-rw-r--r--WebCore/dom/QualifiedName.cpp8
-rw-r--r--WebCore/dom/QualifiedName.h18
-rw-r--r--WebCore/dom/Range.cpp131
-rw-r--r--WebCore/dom/Range.h2
-rw-r--r--WebCore/dom/RegisteredEventListener.cpp3
-rw-r--r--WebCore/dom/StyleElement.cpp17
-rw-r--r--WebCore/dom/StyledElement.cpp4
-rw-r--r--WebCore/dom/StyledElement.h4
-rw-r--r--WebCore/dom/Text.cpp96
-rw-r--r--WebCore/dom/Text.h4
-rw-r--r--WebCore/dom/Text.idl4
-rw-r--r--WebCore/dom/Traversal.cpp28
-rw-r--r--WebCore/dom/Traversal.h15
-rw-r--r--WebCore/dom/TreeWalker.cpp258
-rw-r--r--WebCore/dom/TreeWalker.h36
-rw-r--r--WebCore/dom/TreeWalker.idl14
-rw-r--r--WebCore/dom/XMLTokenizer.cpp51
-rw-r--r--WebCore/dom/XMLTokenizer.h117
-rw-r--r--WebCore/dom/xml_expat_tokenizer.cpp1025
59 files changed, 2051 insertions, 1120 deletions
diff --git a/WebCore/dom/Attr.cpp b/WebCore/dom/Attr.cpp
index 52a2581..24ea6b9 100644
--- a/WebCore/dom/Attr.cpp
+++ b/WebCore/dom/Attr.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
-Attr::Attr(Element* element, Document* docPtr, PassRefPtr<Attribute> a)
+Attr::Attr(Element* element, Document* docPtr, Attribute* a)
: ContainerNode(docPtr),
m_element(element),
m_attribute(a),
@@ -51,7 +51,7 @@ void Attr::createTextChild()
{
ASSERT(refCount());
if (!m_attribute->value().isEmpty()) {
- RefPtr<Text> textNode = document()->createTextNode(m_attribute->value().string());
+ RefPtr<Text> textNode = document()->createTextNode(m_attribute->value().domString());
// This does everything appendChild() would do in this situation (assuming m_ignoreChildrenChanged was set),
// but much more efficiently.
@@ -149,13 +149,13 @@ bool Attr::childTypeAllowed(NodeType type)
}
}
-void Attr::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+void Attr::childrenChanged(bool changedByParser)
{
+ Node::childrenChanged(changedByParser);
+
if (m_ignoreChildrenChanged > 0)
return;
-
- Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
-
+
// FIXME: We should include entity references in the value
String val = "";
diff --git a/WebCore/dom/Attr.h b/WebCore/dom/Attr.h
index d71a79e..9ade207 100644
--- a/WebCore/dom/Attr.h
+++ b/WebCore/dom/Attr.h
@@ -46,7 +46,7 @@ class Attr : public ContainerNode {
friend class NamedAttrMap;
public:
- Attr(Element*, Document*, PassRefPtr<Attribute>);
+ Attr(Element*, Document*, Attribute*);
~Attr();
// Call this after calling the constructor so the
@@ -77,7 +77,7 @@ public:
virtual bool isAttributeNode() const { return true; }
virtual bool childTypeAllowed(NodeType);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false);
virtual String toString() const;
Attribute* attr() const { return m_attribute.get(); }
diff --git a/WebCore/dom/Attribute.h b/WebCore/dom/Attribute.h
index d515ea7..266003b 100644
--- a/WebCore/dom/Attribute.h
+++ b/WebCore/dom/Attribute.h
@@ -48,11 +48,11 @@ class Attribute : public RefCounted<Attribute> {
public:
// null value is forbidden !
Attribute(const QualifiedName& name, const AtomicString& value)
- : RefCounted<Attribute>(0), m_name(name), m_value(value), m_impl(0)
+ : m_name(name), m_value(value), m_impl(0)
{}
Attribute(const AtomicString& name, const AtomicString& value)
- : RefCounted<Attribute>(0), m_name(nullAtom, name, nullAtom), m_value(value), m_impl(0)
+ : m_name(nullAtom, name, nullAtom), m_value(value), m_impl(0)
{}
virtual ~Attribute() { }
@@ -70,7 +70,7 @@ public:
bool isNull() const { return m_value.isNull(); }
bool isEmpty() const { return m_value.isEmpty(); }
- virtual Attribute* clone(bool preserveDecl = true) const;
+ virtual Attribute* clone(bool preserveDecl=true) const;
// An extension to get the style information for presentational attributes.
virtual CSSStyleDeclaration* style() const { return 0; }
diff --git a/WebCore/dom/CharacterData.cpp b/WebCore/dom/CharacterData.cpp
index 1228c98..d525650 100644
--- a/WebCore/dom/CharacterData.cpp
+++ b/WebCore/dom/CharacterData.cpp
@@ -26,6 +26,7 @@
#include "Document.h"
#include "EventNames.h"
#include "ExceptionCode.h"
+#include "TextStream.h"
#include "MutationEvent.h"
#include "RenderText.h"
@@ -258,4 +259,13 @@ bool CharacterData::offsetInCharacters() const
return true;
}
+#ifndef NDEBUG
+void CharacterData::dump(TextStream *stream, DeprecatedString ind) const
+{
+ *stream << " m_data=\"" << String(m_data).utf8().data() << "\"";
+
+ EventTargetNode::dump(stream, ind);
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/dom/CharacterData.h b/WebCore/dom/CharacterData.h
index da89a95..fdb65e2 100644
--- a/WebCore/dom/CharacterData.h
+++ b/WebCore/dom/CharacterData.h
@@ -61,6 +61,10 @@ public:
virtual bool offsetInCharacters() const;
virtual bool rendererIsNeeded(RenderStyle*);
+#ifndef NDEBUG
+ virtual void dump(TextStream*, DeprecatedString indent = "") const;
+#endif
+
protected:
RefPtr<StringImpl> m_data;
diff --git a/WebCore/dom/Clipboard.cpp b/WebCore/dom/Clipboard.cpp
index 4c808d1..152f403 100755
--- a/WebCore/dom/Clipboard.cpp
+++ b/WebCore/dom/Clipboard.cpp
@@ -35,8 +35,7 @@
namespace WebCore {
Clipboard::Clipboard(ClipboardAccessPolicy policy, bool isForDragging)
- : RefCounted<Clipboard>(0)
- , m_policy(policy)
+ : m_policy(policy)
, m_dragStarted(false)
, m_forDragging(isForDragging)
, m_dragImage(0)
diff --git a/WebCore/dom/Comment.cpp b/WebCore/dom/Comment.cpp
index 18bd89f..96b557f 100644
--- a/WebCore/dom/Comment.cpp
+++ b/WebCore/dom/Comment.cpp
@@ -44,7 +44,7 @@ Comment::~Comment()
String Comment::nodeName() const
{
- return commentAtom.string();
+ return commentAtom.domString();
}
Node::NodeType Comment::nodeType() const
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 7103d72..66bdc5c 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -162,9 +162,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
return true;
RefPtr<Node> next = refChild;
- RefPtr<Node> prev = refChild->previousSibling();
- int childCountDelta = 0;
RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
while (child) {
RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
@@ -192,8 +190,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
ASSERT(!child->nextSibling());
ASSERT(!child->previousSibling());
- childCountDelta++;
-
// Add child before "next".
forbidEventDispatch();
Node* prev = next->previousSibling();
@@ -223,8 +219,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
}
document()->setDocumentChanged(true);
- if (childCountDelta)
- childrenChanged(false, prev.get(), next.get(), childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -240,6 +234,16 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
if (oldChild == newChild) // nothing to do
return true;
+#ifdef ANDROID_FIX
+ // if oldChild is null, it will cause crash in checkReplaceChild(). We
+ // should check null first.
+ // Fix Android bug, http://b/issue?id=847893
+ if (!oldChild) {
+ ec = NOT_FOUND_ERR;
+ return false;
+ }
+#endif
+
// Make sure replacing the old child with the new is ok
checkReplaceChild(newChild.get(), oldChild, ec);
if (ec)
@@ -252,7 +256,6 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
}
RefPtr<Node> prev = oldChild->previousSibling();
- RefPtr<Node> next = oldChild->nextSibling();
// Remove the node we're replacing
RefPtr<Node> removedChild = oldChild;
@@ -268,7 +271,6 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE;
// Add the new child(ren)
- int childCountDelta = 0;
RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
while (child) {
// If the new child is already in the right place, we're done.
@@ -293,8 +295,6 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
if (child->parentNode())
break;
- childCountDelta++;
-
ASSERT(!child->nextSibling());
ASSERT(!child->previousSibling());
@@ -334,8 +334,6 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
}
document()->setDocumentChanged(true);
- if (childCountDelta)
- childrenChanged(false, prev.get(), next.get(), childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -438,7 +436,6 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
document()->setDocumentChanged(true);
// Dispatch post-removal mutation events
- childrenChanged(false, prev, next, -1);
dispatchSubtreeModifiedEvent();
if (child->inDocument())
@@ -467,10 +464,7 @@ bool ContainerNode::removeChildren()
document()->removeFocusedNodeOfSubtree(this, true);
forbidEventDispatch();
- int childCountDelta = 0;
while ((n = m_firstChild) != 0) {
- childCountDelta--;
-
Node *next = n->nextSibling();
n->ref();
@@ -495,7 +489,6 @@ bool ContainerNode::removeChildren()
allowEventDispatch();
// Dispatch a single post-removal mutation event denoting a modified subtree.
- childrenChanged(false, 0, 0, childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
@@ -525,8 +518,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
return true;
// Now actually add the child(ren)
- int childCountDelta = 0;
- RefPtr<Node> prev = lastChild();
RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
while (child) {
// For a fragment we have more children to do.
@@ -546,7 +537,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
}
// Append child to the end of the list
- childCountDelta++;
forbidEventDispatch();
child->setParent(this);
if (m_lastChild) {
@@ -568,7 +558,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
}
document()->setDocumentChanged(true);
- childrenChanged(false, prev.get(), 0, childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -589,7 +578,6 @@ ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
forbidEventDispatch();
newChild->setParent(this);
- Node* last = m_lastChild;
if (m_lastChild) {
newChild->setPreviousSibling(m_lastChild);
m_lastChild->setNextSibling(newChild.get());
@@ -601,7 +589,9 @@ ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
document()->incDOMTreeVersion();
if (inDocument())
newChild->insertedIntoDocument();
- childrenChanged(true, last, 0, 1);
+ if (document()->hasNodeLists())
+ notifyNodeListsChildrenChanged();
+ childrenChanged(true);
if (newChild->isElementNode())
return static_cast<ContainerNode*>(newChild.get());
@@ -694,13 +684,6 @@ void ContainerNode::removedFromTree(bool deep)
}
}
-void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
-{
- Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (document()->hasNodeLists())
- notifyNodeListsChildrenChanged();
-}
-
void ContainerNode::cloneChildNodes(ContainerNode *clone)
{
// disable the delete button so it's elements are not serialized into the markup
diff --git a/WebCore/dom/ContainerNode.h b/WebCore/dom/ContainerNode.h
index 9bc4634..9384f6a 100644
--- a/WebCore/dom/ContainerNode.h
+++ b/WebCore/dom/ContainerNode.h
@@ -59,7 +59,6 @@ public:
virtual void removedFromDocument();
virtual void insertedIntoTree(bool deep);
virtual void removedFromTree(bool deep);
- virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual bool removeChildren();
diff --git a/WebCore/dom/DOMImplementation.cpp b/WebCore/dom/DOMImplementation.cpp
index db277d5..49f732e 100644
--- a/WebCore/dom/DOMImplementation.cpp
+++ b/WebCore/dom/DOMImplementation.cpp
@@ -284,8 +284,10 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceUR
doc = new Document(this, 0);
// now get the interesting parts of the doctype
- if (doctype)
- doc->addChild(doctype);
+ if (doctype) {
+ doc->setDocType(doctype);
+ doctype->setDocument(doc.get());
+ }
if (!qualifiedName.isEmpty())
doc->addChild(doc->createElementNS(namespaceURI, qualifiedName, ec));
@@ -325,8 +327,10 @@ bool DOMImplementation::isXMLMIMEType(const String& mimeType)
if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
return true;
static const char* validChars = "[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]"; // per RFCs: 3023, 2045
- static RegularExpression xmlTypeRegExp(String("^") + validChars + "+/" + validChars + "+\\+xml$");
- return xmlTypeRegExp.match(mimeType) > -1;
+ static RegularExpression xmlTypeRegExp(DeprecatedString("^") + validChars + "+/" + validChars + "+\\+xml$");
+ if (xmlTypeRegExp.match(mimeType.deprecatedString()) > -1)
+ return true;
+ return false;
}
bool DOMImplementation::isTextMIMEType(const String& mimeType)
@@ -343,7 +347,7 @@ PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& tit
{
RefPtr<HTMLDocument> d = new HTMLDocument(this, 0);
d->open();
- d->write("<!doctype html><html><head><title>" + title + "</title></head><body></body></html>");
+ d->write("<html><head><title>" + title + "</title></head><body></body></html>");
return d.release();
}
diff --git a/WebCore/dom/DOMImplementation.h b/WebCore/dom/DOMImplementation.h
index 80b921c..736ca7b 100644
--- a/WebCore/dom/DOMImplementation.h
+++ b/WebCore/dom/DOMImplementation.h
@@ -42,8 +42,7 @@ typedef int ExceptionCode;
class DOMImplementation : public RefCounted<DOMImplementation> {
public:
- DOMImplementation() : RefCounted<DOMImplementation>(0) { }
- virtual ~DOMImplementation();
+ virtual ~DOMImplementation();
// DOM methods & attributes for DOMImplementation
bool hasFeature(const String& feature, const String& version) const;
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index f6de5de..4b3e8ad 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,7 +26,6 @@
#include "AXObjectCache.h"
#include "CDATASection.h"
-#include "CachedCSSStyleSheet.h"
#include "CSSHelper.h"
#include "CSSStyleSelector.h"
#include "CSSStyleSheet.h"
@@ -35,12 +34,12 @@
#include "ClassNodeList.h"
#include "Comment.h"
#include "CookieJar.h"
+#include "Database.h"
#include "DOMImplementation.h"
#include "DocLoader.h"
#include "DocumentFragment.h"
#include "DocumentLoader.h"
#include "DocumentType.h"
-#include "DOMWindow.h"
#include "EditingText.h"
#include "Editor.h"
#include "EditorClient.h"
@@ -109,14 +108,9 @@
#include "kjs_proxy.h"
#if ENABLE(DATABASE)
-#include "Database.h"
#include "DatabaseThread.h"
#endif
-#if ENABLE(CROSS_DOCUMENT_MESSAGING)
-#include "MessageEvent.h"
-#endif
-
#if ENABLE(XPATH)
#include "XPathEvaluator.h"
#include "XPathExpression.h"
@@ -140,6 +134,21 @@
#include "TimeScheduler.h"
#endif
+#ifdef ANDROID_INSTRUMENT
+#undef LOG
+#include <utils/Log.h>
+#endif
+
+#ifdef ANDROID_META_SUPPORT
+#include "Settings.h"
+#endif
+
+#ifdef ANDROID_RESET_SELECTION
+#include "CacheBuilder.h"
+#include "FrameAndroid.h"
+#include "HTMLTextAreaElement.h"
+#endif
+
using namespace std;
using namespace WTF;
using namespace Unicode;
@@ -300,6 +309,9 @@ Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML)
#if USE(LOW_BANDWIDTH_DISPLAY)
, m_inLowBandwidthDisplay(false)
#endif
+#ifdef ANDROID_MOBILE
+ , mExtraLayoutDelay(0)
+#endif
{
m_document.resetSkippingRef(this);
@@ -319,8 +331,8 @@ Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML)
m_tokenizer = 0;
m_wellFormed = false;
- setParseMode(Strict);
-
+ pMode = Strict;
+ hMode = XHtml;
m_textColor = Color::black;
m_listenerTypes = 0;
m_inDocument = true;
@@ -331,8 +343,12 @@ Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML)
m_usesFirstLineRules = false;
m_usesFirstLetterRules = false;
m_gotoAnchorNeededAfterStylesheetsLoad = false;
-
- m_styleSelector = 0;
+
+ bool matchAuthorAndUserStyles = true;
+ if (Settings* settings = this->settings())
+ matchAuthorAndUserStyles = settings->authorAndUserStylesEnabled();
+ m_styleSelector = new CSSStyleSelector(this, userStyleSheet(), m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
+
m_didCalculateStyleSelector = false;
m_pendingStylesheets = 0;
m_ignorePendingStylesheets = false;
@@ -409,7 +425,7 @@ Document::~Document()
XMLHttpRequest::detachRequests(this);
{
KJS::JSLock lock;
- ScriptInterpreter::forgetAllDOMNodesForDocument(this);
+ KJS::ScriptInterpreter::forgetAllDOMNodesForDocument(this);
}
if (m_docChanged && changedDocuments)
@@ -472,15 +488,12 @@ void Document::resetActiveLinkColor()
void Document::setDocType(PassRefPtr<DocumentType> docType)
{
- // This should never be called more than once.
- // Note: This is not a public DOM method and can only be called by the parser.
- ASSERT(!m_docType || !docType);
- if (m_docType && docType)
- return;
m_docType = docType;
- if (m_docType)
- m_docType->setDocument(this);
- determineParseMode();
+}
+
+DocumentType *Document::doctype() const
+{
+ return m_docType.get();
}
DOMImplementation* Document::implementation() const
@@ -488,11 +501,9 @@ DOMImplementation* Document::implementation() const
return m_implementation.get();
}
-void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+void Document::childrenChanged(bool changedByParser)
{
- ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
-
- // Invalidate the document element we have cached in case it was replaced.
+ // invalidate the document element we have cached in case it was replaced
m_documentElement = 0;
}
@@ -680,12 +691,7 @@ PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
ec = NOT_SUPPORTED_ERR;
return 0;
}
-
- if (source->isReadOnlyNode()) {
- ec = NO_MODIFICATION_ALLOWED_ERR;
- return 0;
- }
-
+
switch (source->nodeType()) {
case ENTITY_NODE:
case NOTATION_NODE:
@@ -834,19 +840,19 @@ void Document::setXMLStandalone(bool standalone, ExceptionCode& ec)
m_xmlStandalone = standalone;
}
-KURL Document::documentURI() const
+String Document::documentURI() const
{
return m_baseURL;
}
-void Document::setDocumentURI(const String& uri)
+void Document::setDocumentURI(const String &uri)
{
- m_baseURL = KURL(uri);
+ m_baseURL = uri.deprecatedString();
}
-KURL Document::baseURI() const
+String Document::baseURI() const
{
- return m_baseURL;
+ return documentURI();
}
Element* Document::elementFromPoint(int x, int y) const
@@ -1012,7 +1018,7 @@ PassRefPtr<Range> Document::createRange()
}
PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow,
- PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
+ NodeFilter* filter, bool expandEntityReferences, ExceptionCode& ec)
{
if (!root) {
ec = NOT_SUPPORTED_ERR;
@@ -1022,7 +1028,7 @@ PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatT
}
PassRefPtr<TreeWalker> Document::createTreeWalker(Node *root, unsigned whatToShow,
- PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
+ NodeFilter* filter, bool expandEntityReferences, ExceptionCode& ec)
{
if (!root) {
ec = NOT_SUPPORTED_ERR;
@@ -1051,6 +1057,23 @@ void Document::setDocumentChanged(bool b)
m_docChanged = b;
}
+#ifdef ANDROID_INSTRUMENT
+static uint32_t sTotalTimeUsed = 0;
+static uint32_t sCounter = 0;
+
+void Frame::resetCalculateStyleTimeCounter()
+{
+ sTotalTimeUsed = 0;
+ sCounter = 0;
+}
+
+void Frame::reportCalculateStyleTimeCounter()
+{
+ LOG(LOG_DEBUG, "WebCore", "*-* Total calcStyle time: %d ms called %d times\n",
+ sTotalTimeUsed, sCounter);
+}
+#endif
+
void Document::recalcStyle(StyleChange change)
{
// we should not enter style recalc while painting
@@ -1065,6 +1088,10 @@ void Document::recalcStyle(StyleChange change)
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
+#ifdef ANDROID_INSTRUMENT
+ uint32_t time = get_thread_msec();
+#endif
+
ASSERT(!renderer() || renderArena());
if (!renderer() || !renderArena())
goto bail_out;
@@ -1117,6 +1144,14 @@ void Document::recalcStyle(StyleChange change)
if (change >= Inherit || n->hasChangedChild() || n->changed())
n->recalcStyle(change);
+#ifdef ANDROID_INSTRUMENT
+ time = get_thread_msec() - time;
+ sTotalTimeUsed += time;
+ sCounter++;
+ if (time > 1000)
+ LOGW("***** Document::recalcStyle() used %d ms\n", time);
+#endif
+
if (changed() && view())
view()->layout();
@@ -1210,14 +1245,6 @@ void Document::attach()
// Create the rendering tree
setRenderer(new (m_renderArena) RenderView(this, view()));
- if (!m_styleSelector) {
- bool matchAuthorAndUserStyles = true;
- if (Settings* docSettings = settings())
- matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
- m_styleSelector = new CSSStyleSelector(this, userStyleSheet(), m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
- m_styleSelector->setEncodedURL(m_url);
- }
-
recalcStyle(Force);
RenderObject* render = renderer();
@@ -1337,10 +1364,10 @@ void Document::open()
{
// This is work that we should probably do in clear(), but we can't have it
// happen when implicitOpen() is called unless we reorganize Frame code.
- if (Document* parent = parentDocument()) {
- if (m_url.isEmpty() || m_url == blankURL())
+ if (Document *parent = parentDocument()) {
+ if (m_url.isEmpty() || m_url == "about:blank")
setURL(parent->baseURL());
- if (m_baseURL.isEmpty() || m_baseURL == blankURL())
+ if (m_baseURL.isEmpty() || m_baseURL == "about:blank")
setBaseURL(parent->baseURL());
}
@@ -1464,6 +1491,11 @@ void Document::implicitClose()
delete m_tokenizer;
m_tokenizer = 0;
+#ifdef ANDROID_PRELOAD_CHANGES
+ // Parser should have picked up all preloads by now
+ m_docLoader->clearPreloads();
+#endif
+
// Create a body element if we don't already have one. See Radar 3758785.
if (!this->body() && isHTMLDocument()) {
if (Node* documentElement = this->documentElement()) {
@@ -1630,21 +1662,21 @@ void Document::clear()
m_windowEventListeners.clear();
}
-void Document::setURL(const KURL& url)
+void Document::setURL(const DeprecatedString& url)
{
if (url == m_url)
return;
m_url = url;
if (m_styleSelector)
- m_styleSelector->setEncodedURL(url);
+ m_styleSelector->setEncodedURL(m_url);
m_isAllowedToLoadLocalResources = shouldBeAllowedToLoadLocalResources();
}
bool Document::shouldBeAllowedToLoadLocalResources() const
{
- if (FrameLoader::shouldTreatURLAsLocal(m_url.string()))
+ if (FrameLoader::shouldTreatURLAsLocal(m_url))
return true;
Frame* frame = this->frame();
@@ -1655,23 +1687,23 @@ bool Document::shouldBeAllowedToLoadLocalResources() const
if (!documentLoader)
return false;
- if (m_url == blankURL() && frame->loader()->opener() && frame->loader()->opener()->document()->isAllowedToLoadLocalResources())
+ if (m_url == "about:blank" && frame->loader()->opener() && frame->loader()->opener()->document()->isAllowedToLoadLocalResources())
return true;
return documentLoader->substituteData().isValid();
}
-void Document::setBaseURL(const KURL& baseURL)
+void Document::setBaseURL(const DeprecatedString& baseURL)
{
- m_baseURL = baseURL;
+ m_baseURL = baseURL;
if (m_elemSheet)
- m_elemSheet->setHref(baseURL.string());
+ m_elemSheet->setHref(m_baseURL);
}
-void Document::setCSSStyleSheet(const String &url, const String& charset, const CachedCSSStyleSheet* sheet)
+void Document::setCSSStyleSheet(const String &url, const String& charset, const String &sheet)
{
m_sheet = new CSSStyleSheet(this, url, charset);
- m_sheet->parseString(sheet->sheetText());
+ m_sheet->parseString(sheet);
updateStyleSelector();
}
@@ -1701,17 +1733,25 @@ String Document::userStyleSheet() const
CSSStyleSheet* Document::elementSheet()
{
if (!m_elemSheet)
- m_elemSheet = new CSSStyleSheet(this, baseURL().string());
+ m_elemSheet = new CSSStyleSheet(this, baseURL());
return m_elemSheet.get();
}
CSSStyleSheet* Document::mappedElementSheet()
{
if (!m_mappedElementSheet)
- m_mappedElementSheet = new CSSStyleSheet(this, baseURL().string());
+ m_mappedElementSheet = new CSSStyleSheet(this, baseURL());
return m_mappedElementSheet.get();
}
+void Document::determineParseMode(const String&)
+{
+ // For XML documents use strict parse mode.
+ // HTML overrides this method to determine the parse mode.
+ pMode = Strict;
+ hMode = XHtml;
+}
+
static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
{
// Search is inclusive of start
@@ -1830,6 +1870,64 @@ Node *Document::nodeWithAbsIndex(int absIndex)
return n;
}
+#ifdef ANDROID_META_SUPPORT
+// Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
+static bool isSeparator(::UChar c)
+{
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
+}
+
+void Document::processMetadataSettings(const String& content)
+{
+ ASSERT(!content.isNull());
+
+ int keyBegin, keyEnd, valueBegin, valueEnd;
+ int i = 0;
+ int length = content.length();
+ String buffer = content.lower();
+ while (i < length) {
+ // skip to first non-separator, but don't skip past the end of the string
+ while (isSeparator(buffer[i])) {
+ if (i >= length)
+ break;
+ i++;
+ }
+ keyBegin = i;
+
+ // skip to first separator
+ while (!isSeparator(buffer[i]))
+ i++;
+ keyEnd = i;
+
+ // skip to first '=', but don't skip past a ',' or the end of the string
+ while (buffer[i] != '=') {
+ if (buffer[i] == ',' || i >= length)
+ break;
+ i++;
+ }
+
+ // skip to first non-separator, but don't skip past a ',' or the end of the string
+ while (isSeparator(buffer[i])) {
+ if (buffer[i] == ',' || i >= length)
+ break;
+ i++;
+ }
+ valueBegin = i;
+
+ // skip to first separator
+ while (!isSeparator(buffer[i]))
+ i++;
+ valueEnd = i;
+
+ ASSERT(i <= length);
+
+ String key(buffer.substring(keyBegin, keyEnd - keyBegin));
+ String value(buffer.substring(valueBegin, valueEnd - valueBegin));
+ frame()->settings()->setMetadataSettings(key, value);
+ }
+}
+#endif
+
void Document::processHttpEquiv(const String &equiv, const String &content)
{
ASSERT(!equiv.isNull() && !content.isNull());
@@ -1853,7 +1951,7 @@ void Document::processHttpEquiv(const String &equiv, const String &content)
if (url.isEmpty())
url = frame->loader()->url().string();
else
- url = completeURL(url).string();
+ url = completeURL(url);
frame->loader()->scheduleHTTPRedirection(delay, url);
}
} else if (equalIgnoringCase(equiv, "set-cookie")) {
@@ -2145,7 +2243,7 @@ void Document::recalcStyleSelector()
// it is loading but we should still decide which style sheet set to use
if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSet.isEmpty()) {
const AtomicString& rel = e->getAttribute(relAttr);
- if (!rel.contains("alternate")) {
+ if (!rel.domString().contains("alternate")) {
m_preferredStylesheetSet = title;
m_selectedStylesheetSet = title;
}
@@ -2186,6 +2284,11 @@ void Document::recalcStyleSelector()
if (title != m_preferredStylesheetSet)
sheet = 0;
+
+#if ENABLE(SVG)
+ if (!n->isHTMLElement())
+ title = title.deprecatedString().replace('&', "&&");
+#endif
}
}
@@ -2287,6 +2390,20 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
if (m_inPageCache)
return false;
+#ifdef ANDROID_RESET_SELECTION
+ WebCore::FrameAndroid* frameAndroid = static_cast<WebCore::FrameAndroid*>(frame());
+ WebCore::Node* oldFocus = frameAndroid->getCacheBuilder().currentFocus();
+ if (oldFocus) {
+ if (oldFocus->hasTagName(WebCore::HTMLNames::inputTag)) {
+ WebCore::HTMLInputElement* input = static_cast<WebCore::HTMLInputElement*>(oldFocus);
+ if (input->isTextField())
+ input->setSelectionRange(-1, -1);
+ } else if (oldFocus->hasTagName(WebCore::HTMLNames::textareaTag)) {
+ WebCore::HTMLTextAreaElement* textArea = static_cast<WebCore::HTMLTextAreaElement*>(oldFocus);
+ textArea->setSelectionRange(-1, -1);
+ }
+ }
+#endif
bool focusChangeBlocked = false;
RefPtr<Node> oldFocusedNode = m_focusedNode;
m_focusedNode = 0;
@@ -2428,7 +2545,7 @@ DOMWindow* Document::defaultView() const
return frame()->domWindow();
}
-PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec)
+PassRefPtr<Event> Document::createEvent(const String &eventType, ExceptionCode& ec)
{
if (eventType == "UIEvents" || eventType == "UIEvent")
return new UIEvent;
@@ -2454,10 +2571,6 @@ PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode&
if (eventType == "SVGZoomEvents")
return new SVGZoomEvent;
#endif
-#if ENABLE(CROSS_DOCUMENT_MESSAGING)
- if (eventType == "MessageEvent")
- return new MessageEvent;
-#endif
ec = NOT_SUPPORTED_ERR;
return 0;
}
@@ -2548,7 +2661,7 @@ PassRefPtr<EventListener> Document::createHTMLEventListener(const String& functi
void Document::setHTMLWindowEventListener(const AtomicString& eventType, Attribute* attr)
{
setHTMLWindowEventListener(eventType,
- createHTMLEventListener(attr->localName().string(), attr->value(), 0));
+ createHTMLEventListener(attr->localName().domString(), attr->value(), 0));
}
void Document::dispatchImageLoadEventSoon(HTMLImageLoader *image)
@@ -2612,7 +2725,7 @@ String Document::cookie() const
void Document::setCookie(const String& value)
{
- setCookies(this, url(), policyBaseURL(), value);
+ setCookies(this, url(), policyBaseURL().deprecatedString(), value);
}
String Document::referrer() const
@@ -2774,7 +2887,7 @@ HTMLMapElement *Document::getImageMap(const String& url) const
return 0;
int hashPos = url.find('#');
String name = (hashPos < 0 ? url : url.substring(hashPos + 1)).impl();
- AtomicString mapName = isHTMLDocument() ? name.lower() : name;
+ AtomicString mapName = hMode == XHtml ? name : name.lower();
return m_imageMapsByName.get(mapName.impl());
}
@@ -2790,18 +2903,27 @@ UChar Document::backslashAsCurrencySymbol() const
return m_decoder->encoding().backslashAsCurrencySymbol();
}
-KURL Document::completeURL(const String& url)
+DeprecatedString Document::completeURL(const DeprecatedString& url)
{
- // Always return a null URL when passed a null string.
- // FIXME: Should we change the KURL constructor to have this behavior?
- if (url.isNull())
- return KURL();
- KURL base = m_baseURL;
- if (base.isEmpty())
- base = m_url;
+ // FIXME: This treats null URLs the same as empty URLs, unlike the String function below.
+
+ // If both the URL and base URL are empty, like they are for documents
+ // created using DOMImplementation::createDocument, just return the passed in URL.
+ // (We do this because url() returns "about:blank" for empty URLs.
+ if (m_url.isEmpty() && m_baseURL.isEmpty())
+ return url;
if (!m_decoder)
- return KURL(base, url);
- return KURL(base, url, m_decoder->encoding());
+ return KURL(baseURL(), url).deprecatedString();
+ return KURL(baseURL(), url, m_decoder->encoding()).deprecatedString();
+}
+
+String Document::completeURL(const String& url)
+{
+ // FIXME: This always returns null when passed a null URL, unlike the DeprecatedString function above.
+ // Code relies on this behavior, namely the href property of <a> and the data property of <object>.
+ if (url.isNull())
+ return url;
+ return completeURL(url.deprecatedString());
}
bool Document::inPageCache()
@@ -3342,7 +3464,7 @@ void Document::shiftMarkers(Node *node, unsigned startOffset, int delta, Documen
void Document::applyXSLTransform(ProcessingInstruction* pi)
{
- RefPtr<XSLTProcessor> processor = XSLTProcessor::create();
+ RefPtr<XSLTProcessor> processor = new XSLTProcessor;
processor->setXSLStylesheet(static_cast<XSLStyleSheet*>(pi->sheet()));
String resultMIMEType;
@@ -3539,8 +3661,8 @@ Vector<String> Document::formElementsState() const
HTMLFormControlElementWithState* e = *it;
String value;
if (e->saveState(value)) {
- stateVector.append(e->name().string());
- stateVector.append(e->type().string());
+ stateVector.append(e->name().domString());
+ stateVector.append(e->type().domString());
stateVector.append(value);
}
}
@@ -3554,14 +3676,14 @@ PassRefPtr<XPathExpression> Document::createExpression(const String& expression,
ExceptionCode& ec)
{
if (!m_xpathEvaluator)
- m_xpathEvaluator = XPathEvaluator::create();
+ m_xpathEvaluator = new XPathEvaluator;
return m_xpathEvaluator->createExpression(expression, resolver, ec);
}
PassRefPtr<XPathNSResolver> Document::createNSResolver(Node* nodeResolver)
{
if (!m_xpathEvaluator)
- m_xpathEvaluator = XPathEvaluator::create();
+ m_xpathEvaluator = new XPathEvaluator;
return m_xpathEvaluator->createNSResolver(nodeResolver);
}
@@ -3573,7 +3695,7 @@ PassRefPtr<XPathResult> Document::evaluate(const String& expression,
ExceptionCode& ec)
{
if (!m_xpathEvaluator)
- m_xpathEvaluator = XPathEvaluator::create();
+ m_xpathEvaluator = new XPathEvaluator;
return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec);
}
@@ -3770,12 +3892,6 @@ void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
element->updateFocusAppearance(false);
}
-// FF method for accessing the selection added for compatability.
-DOMSelection* Document::getSelection() const
-{
- return frame() ? frame()->domWindow()->getSelection() : 0;
-}
-
#if ENABLE(DATABASE)
void Document::addOpenDatabase(Database* database)
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 14277ea..a4c935b 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,7 +32,6 @@
#include "DocumentMarker.h"
#include "HTMLCollection.h"
#include "HTMLFormElement.h"
-#include "KURL.h"
#include "StringHash.h"
#include "Timer.h"
#include <wtf/HashCountedSet.h>
@@ -53,14 +52,12 @@ namespace WebCore {
class Attr;
class Attribute;
class CDATASection;
- class CachedCSSStyleSheet;
class CSSStyleDeclaration;
class CSSStyleSelector;
class CSSStyleSheet;
class Comment;
class Database;
class DOMImplementation;
- class DOMSelection;
class DOMWindow;
class DatabaseThread;
class DocLoader;
@@ -180,10 +177,11 @@ public:
// DOM methods & attributes for Document
- DocumentType* doctype() const { return m_docType.get(); }
+ virtual DocumentType* doctype() const; // May return 0 for HTML documents
+ DocumentType* realDocType() const { return m_docType.get(); }
DOMImplementation* implementation() const;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false);
Element* documentElement() const;
virtual PassRefPtr<Element> createElement(const String& tagName, ExceptionCode&);
PassRefPtr<DocumentFragment> createDocumentFragment ();
@@ -220,10 +218,10 @@ public:
void setXMLVersion(const String&, ExceptionCode&);
void setXMLStandalone(bool, ExceptionCode&);
- KURL documentURI() const;
+ String documentURI() const;
void setDocumentURI(const String&);
- virtual KURL baseURI() const;
+ virtual String baseURI() const;
PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionCode&);
@@ -333,10 +331,10 @@ public:
PassRefPtr<Range> createRange();
PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow,
- PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
+ NodeFilter*, bool expandEntityReferences, ExceptionCode&);
PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow,
- PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
+ NodeFilter*, bool expandEntityReferences, ExceptionCode&);
// Special support for editing
PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
@@ -373,19 +371,20 @@ public:
bool wellFormed() const { return m_wellFormed; }
- const KURL& url() const { return m_url.isEmpty() ? blankURL() : m_url; }
- void setURL(const KURL&);
+ DeprecatedString url() const { return m_url.isEmpty() ? "about:blank" : m_url; }
+ void setURL(const DeprecatedString& url);
- const KURL& baseURL() const { return m_baseURL.isEmpty() ? url() : m_baseURL; }
- void setBaseURL(const KURL&);
+ DeprecatedString baseURL() const { return m_baseURL.isEmpty() ? url() : m_baseURL; }
+ void setBaseURL(const DeprecatedString& baseURL);
- const String& baseTarget() const { return m_baseTarget; }
+ String baseTarget() const { return m_baseTarget; }
void setBaseTarget(const String& baseTarget) { m_baseTarget = baseTarget; }
- KURL completeURL(const String&);
+ DeprecatedString completeURL(const DeprecatedString &);
+ String completeURL(const String&);
// from cachedObjectClient
- virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
+ virtual void setCSSStyleSheet(const String& url, const String& charset, const String& sheetStr);
#if FRAME_LOADS_USER_STYLESHEET
void setUserStyleSheet(const String& sheet);
@@ -402,18 +401,20 @@ public:
void setPrinting(bool p) { m_printing = p; }
enum ParseMode { Compat, AlmostStrict, Strict };
-
-private:
- virtual void determineParseMode() {}
-public:
- void setParseMode(ParseMode m) { m_parseMode = m; }
- ParseMode parseMode() const { return m_parseMode; }
+ virtual void determineParseMode(const String&);
+ void setParseMode(ParseMode m) { pMode = m; }
+ ParseMode parseMode() const { return pMode; }
- bool inCompatMode() const { return m_parseMode == Compat; }
- bool inAlmostStrictMode() const { return m_parseMode == AlmostStrict; }
- bool inStrictMode() const { return m_parseMode == Strict; }
+ bool inCompatMode() const { return pMode == Compat; }
+ bool inAlmostStrictMode() const { return pMode == AlmostStrict; }
+ bool inStrictMode() const { return pMode == Strict; }
+ enum HTMLMode { Html3, Html4, XHtml };
+
+ void setHTMLMode(HTMLMode m) { hMode = m; }
+ HTMLMode htmlMode() const { return hMode; }
+
void setParsing(bool);
bool parsing() const { return m_bParsing; }
int minimumLayoutDelay();
@@ -547,6 +548,14 @@ public:
*/
void processHttpEquiv(const String& equiv, const String& content);
+#ifdef ANDROID_META_SUPPORT
+ /**
+ * Handles viewport like <meta name = "viewport" content = "width = device-width">
+ * or format-detection like <meta name = "format-detection" content = "telephone=no">
+ */
+ void processMetadataSettings(const String& content);
+#endif
+
void dispatchImageLoadEventSoon(HTMLImageLoader*);
void dispatchImageLoadEventsNow();
void removeImage(HTMLImageLoader*);
@@ -569,8 +578,8 @@ public:
String lastModified() const;
- const KURL& policyBaseURL() const { return m_policyBaseURL; }
- void setPolicyBaseURL(const KURL& url) { m_policyBaseURL = url; }
+ String policyBaseURL() const { return m_policyBaseURL; }
+ void setPolicyBaseURL(const String& s) { m_policyBaseURL = s; }
// The following implements the rule from HTML 4 for what valid names are.
// To get this right for all the XML cases, we probably have to improve this or move it
@@ -691,9 +700,11 @@ public:
void updateFocusAppearanceSoon();
void cancelFocusAppearanceUpdate();
- // FF method for accessing the selection added for compatability.
- DOMSelection* getSelection() const;
-
+#ifdef ANDROID_MOBILE
+ void setExtraLayoutDelay(int delay) { mExtraLayoutDelay = delay; }
+ int extraLayoutDelay() { return mExtraLayoutDelay; }
+#endif
+
private:
CSSStyleSelector* m_styleSelector;
bool m_didCalculateStyleSelector;
@@ -702,8 +713,8 @@ private:
DocLoader* m_docLoader;
Tokenizer* m_tokenizer;
bool m_wellFormed;
- KURL m_url;
- KURL m_baseURL;
+ DeprecatedString m_url;
+ DeprecatedString m_baseURL;
String m_baseTarget;
RefPtr<DocumentType> m_docType;
@@ -736,7 +747,8 @@ private:
bool m_printing;
- ParseMode m_parseMode;
+ ParseMode pMode;
+ HTMLMode hMode;
Color m_textColor;
@@ -752,6 +764,7 @@ private:
unsigned short m_listenerTypes;
RefPtr<StyleSheetList> m_styleSheets;
+ typedef DeprecatedValueList<RefPtr<RegisteredEventListener> > RegisteredEventListenerList;
RegisteredEventListenerList m_windowEventListeners;
typedef HashMap<FormElementKey, Vector<String>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap;
@@ -813,7 +826,7 @@ private:
typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName;
ImageMapsByName m_imageMapsByName;
- KURL m_policyBaseURL;
+ String m_policyBaseURL;
HashSet<Node*> m_disconnectedNodesWithEventListeners;
@@ -953,6 +966,10 @@ private:
#if USE(LOW_BANDWIDTH_DISPLAY)
bool m_inLowBandwidthDisplay;
#endif
+#ifdef ANDROID_MOBILE
+ int mExtraLayoutDelay;
+#endif
+
};
} // namespace WebCore
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index ddc25f3..e77da2e 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -193,9 +193,7 @@ module core {
Element elementFromPoint(in long x, in long y);
// Mozilla extensions
-#if defined(LANGUAGE_JAVASCRIPT)
- DOMSelection getSelection();
-#endif
+
readonly attribute [ConvertNullStringTo=Null] DOMString characterSet;
// WebKit extensions
diff --git a/WebCore/dom/DocumentType.cpp b/WebCore/dom/DocumentType.cpp
index f051363..2c4f060 100644
--- a/WebCore/dom/DocumentType.cpp
+++ b/WebCore/dom/DocumentType.cpp
@@ -1,8 +1,10 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,30 +31,19 @@
namespace WebCore {
-DocumentType::DocumentType(DOMImplementation* i, Document* document, const String& n, const String& p, const String& s)
- : Node(document)
- , m_implementation(i)
- , m_name(n)
- , m_publicId(p)
- , m_systemId(s)
+DocumentType::DocumentType(DOMImplementation *i, Document *doc, const String &n, const String &p, const String &s)
+ : Node(doc), m_implementation(i), m_name(n), m_publicId(p), m_systemId(s)
{
}
-DocumentType::DocumentType(Document* document, const String& n, const String& p, const String& s)
- : Node(document)
- , m_name(n)
- , m_publicId(p)
- , m_systemId(s)
+DocumentType::DocumentType(Document *doc, const String &n, const String &p, const String &s)
+ : Node(doc), m_name(n), m_publicId(p), m_systemId(s)
{
}
-DocumentType::DocumentType(Document* document, const DocumentType &t)
- : Node(document)
- , m_implementation(t.m_implementation)
- , m_name(t.m_name)
- , m_publicId(t.m_publicId)
- , m_systemId(t.m_systemId)
- , m_subset(t.m_subset)
+DocumentType::DocumentType(Document *doc, const DocumentType &t)
+ : Node(doc), m_implementation(t.m_implementation)
+ , m_name(t.m_name), m_publicId(t.m_publicId), m_systemId(t.m_systemId), m_subset(t.m_subset)
{
}
@@ -66,12 +57,9 @@ String DocumentType::toString() const
if (!m_publicId.isEmpty()) {
result += " PUBLIC \"";
result += m_publicId;
+ result += "\" \"";
+ result += m_systemId;
result += "\"";
- if (!m_systemId.isEmpty()) {
- result += " \"";
- result += m_systemId;
- result += "\"";
- }
} else if (!m_systemId.isEmpty()) {
result += " SYSTEM \"";
result += m_systemId;
@@ -86,9 +74,9 @@ String DocumentType::toString() const
return result;
}
-KURL DocumentType::baseURI() const
+String DocumentType::baseURI() const
{
- return KURL();
+ return String();
}
String DocumentType::nodeName() const
@@ -103,26 +91,8 @@ Node::NodeType DocumentType::nodeType() const
PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
{
- return new DocumentType(document(), m_name, m_publicId, m_systemId);
-}
-
-void DocumentType::insertedIntoDocument()
-{
- // Our document node can be null if we were created by a DOMImplementation. We use the parent() instead.
- ASSERT(parent() && parent()->isDocumentNode());
- if (parent() && parent()->isDocumentNode()) {
- Document* doc = static_cast<Document*>(parent());
- if (!doc->doctype())
- doc->setDocType(this);
- }
- Node::insertedIntoDocument();
-}
-
-void DocumentType::removedFromDocument()
-{
- if (document() && document()->doctype() == this)
- document()->setDocType(0);
- Node::removedFromDocument();
+ // The DOM Level 2 specification says cloning DocumentType nodes is "implementation dependent" so for now we do not support it.
+ return 0;
}
}
diff --git a/WebCore/dom/DocumentType.h b/WebCore/dom/DocumentType.h
index c348c4c..63cfc25 100644
--- a/WebCore/dom/DocumentType.h
+++ b/WebCore/dom/DocumentType.h
@@ -48,7 +48,7 @@ public:
String systemId() const { return m_systemId; }
String internalSubset() const { return m_subset; }
- virtual KURL baseURI() const;
+ virtual String baseURI() const;
// Other methods (not part of DOM)
DOMImplementation *implementation() const { return m_implementation.get(); }
@@ -58,9 +58,6 @@ public:
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual String toString() const;
- virtual void insertedIntoDocument();
- virtual void removedFromDocument();
-
private:
RefPtr<DOMImplementation> m_implementation;
RefPtr<NamedNodeMap> m_entities;
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 8af84e2..808696a 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -4,7 +4,7 @@
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* (C) 2007 Eric Seidel (eric@webkit.org)
*
* This library is free software; you can redistribute it and/or
@@ -27,7 +27,6 @@
#include "Element.h"
#include "CSSStyleSelector.h"
-#include "CString.h"
#include "ClassNames.h"
#include "ClassNodeList.h"
#include "Document.h"
@@ -38,13 +37,14 @@
#include "FrameView.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
+#include "KURL.h"
#include "NamedAttrMap.h"
#include "NodeList.h"
#include "Page.h"
-#include "PlatformString.h"
#include "RenderBlock.h"
#include "SelectionController.h"
#include "TextIterator.h"
+#include "TextStream.h"
#include "XMLNames.h"
namespace WebCore {
@@ -562,21 +562,18 @@ void Element::setPrefix(const AtomicString &_prefix, ExceptionCode& ec)
m_tagName.setPrefix(_prefix);
}
-KURL Element::baseURI() const
+String Element::baseURI() const
{
- KURL base(getAttribute(baseAttr));
- if (!base.protocol().isEmpty())
- return base;
+ KURL xmlbase(getAttribute(baseAttr).deprecatedString());
- Node* parent = parentNode();
- if (!parent)
- return base;
+ if (!xmlbase.protocol().isEmpty())
+ return xmlbase.string();
- KURL parentBase = parent->baseURI();
- if (parentBase.isNull())
- return base;
+ Node* parent = parentNode();
+ if (parent)
+ return KURL(parent->baseURI().deprecatedString(), xmlbase.deprecatedString()).string();
- return KURL(parentBase, base.string());
+ return xmlbase.string();
}
Node* Element::insertAdjacentElement(const String& where, Node* newChild, int& exception)
@@ -706,7 +703,8 @@ void Element::recalcStyle(StyleChange change)
{
RenderStyle* currentStyle = renderStyle();
bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
- bool hasPositionalRules = changed() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
+ bool hasPositionalChildren = currentStyle && (currentStyle->childrenAffectedByFirstChildRules() || currentStyle->childrenAffectedByLastChildRules() ||
+ currentStyle->childrenAffectedByForwardPositionalRules() || currentStyle->childrenAffectedByBackwardPositionalRules());
#if ENABLE(SVG)
if (!hasParentStyle && isShadowNode() && isSVGElement())
@@ -732,7 +730,7 @@ void Element::recalcStyle(StyleChange change)
return;
}
- if (currentStyle) {
+ if (currentStyle && newStyle) {
// Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
// style change (e.g., only inline style changed).
if (currentStyle->affectedByHoverRules())
@@ -749,13 +747,12 @@ void Element::recalcStyle(StyleChange change)
newStyle->setChildrenAffectedByFirstChildRules();
if (currentStyle->childrenAffectedByLastChildRules())
newStyle->setChildrenAffectedByLastChildRules();
- if (currentStyle->childrenAffectedByDirectAdjacentRules())
- newStyle->setChildrenAffectedByDirectAdjacentRules();
}
- if (ch != NoChange)
- setRenderStyle(newStyle);
- else if (changed() && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
+ if (ch != NoChange) {
+ if (newStyle)
+ setRenderStyle(newStyle);
+ } else if (changed() && newStyle && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
// Although no change occurred, we use the new style so that the cousin style sharing code won't get
// fooled into believing this style is the same. This is only necessary if the document actually uses
// sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of
@@ -769,7 +766,7 @@ void Element::recalcStyle(StyleChange change)
newStyle->deref(document()->renderArena());
if (change != Force) {
- if ((document()->usesDescendantRules() || hasPositionalRules) && styleChangeType() == FullStyleChange)
+ if ((document()->usesDescendantRules() || hasPositionalChildren) && styleChangeType() == FullStyleChange)
change = Force;
else
change = ch;
@@ -801,98 +798,81 @@ bool Element::childTypeAllowed(NodeType type)
}
}
-static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
- Node* beforeChange, Node* afterChange, int childCountDelta)
-{
- if (!style || (e->changed() && style->childrenAffectedByPositionalRules()))
- return;
-
- // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
- if (style->childrenAffectedByFirstChildRules() && afterChange) {
- // Find our new first child.
- Node* newFirstChild = 0;
- for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
-
- // Find the first element node following |afterChange|
- Node* firstElementAfterInsertion = 0;
- for (firstElementAfterInsertion = afterChange;
- firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
- firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
-
- // This is the insert/append case.
- if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
- firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
- firstElementAfterInsertion->setChanged();
-
- // We also have to handle node removal.
- if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())
- newFirstChild->setChanged();
+static void checkFirstChildRules(Element* e, RenderStyle* style)
+{
+ if (style->childrenAffectedByFirstChildRules()) {
+ // Check our first two children. They need to be true and false respectively.
+ bool checkingFirstChild = true;
+ for (Node* n = e->firstChild(); n; n = n->nextSibling()) {
+ if (n->isElementNode()) {
+ if (checkingFirstChild) {
+ if (n->attached() && n->renderStyle() && !n->renderStyle()->firstChildState())
+ n->setChanged();
+ checkingFirstChild = false;
+ } else {
+ if (n->attached() && n->renderStyle() && n->renderStyle()->firstChildState())
+ n->setChanged();
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void checkLastChildRules(Element* e, RenderStyle* style)
+{
+ if (style->childrenAffectedByLastChildRules()) {
+ // Check our last two children. They need to be true and false respectively.
+ bool checkingLastChild = true;
+ for (Node* n = e->lastChild(); n; n = n->previousSibling()) {
+ if (n->isElementNode()) {
+ if (checkingLastChild) {
+ if (n->attached() && n->renderStyle() && !n->renderStyle()->lastChildState())
+ n->setChanged();
+ checkingLastChild = false;
+ } else {
+ if (n->attached() && n->renderStyle() && n->renderStyle()->lastChildState())
+ n->setChanged();
+ break;
+ }
+ }
+ }
}
+}
- // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- if (style->childrenAffectedByLastChildRules() && beforeChange) {
- // Find our new last child.
- Node* newLastChild = 0;
- for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
-
- // Find the last element node going backwards from |beforeChange|
- Node* lastElementBeforeInsertion = 0;
- for (lastElementBeforeInsertion = beforeChange;
- lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
- lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
-
- if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
- lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
- lastElementBeforeInsertion->setChanged();
-
- // We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
- // to match now.
- if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !newLastChild->renderStyle()->lastChildState())
- newLastChild->setChanged();
- }
+static bool checkEmptyRules(Element* e, RenderStyle* style)
+{
+ return style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes());
+}
- // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
- // that could be affected by this DOM change.
- if (style->childrenAffectedByDirectAdjacentRules() && afterChange) {
- Node* firstElementAfterInsertion = 0;
- for (firstElementAfterInsertion = afterChange;
- firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
- firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
- if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
- firstElementAfterInsertion->setChanged();
- }
+static void checkStyleRules(Element* e, RenderStyle* style, bool changedByParser)
+{
+ if (e->changed() || !style)
+ return;
- // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
- // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
- // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
- // backward case.
- // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
- // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
- // here. recalcStyle will then force a walk of the children when it sees that this has happened.
- if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
- (style->childrenAffectedByBackwardPositionalRules() && beforeChange))
- e->setChanged();
-
- // :empty selector.
- if (style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes()))
+ if (style->childrenAffectedByBackwardPositionalRules() ||
+ (!changedByParser && style->childrenAffectedByForwardPositionalRules()) ||
+ checkEmptyRules(e, style)) {
e->setChanged();
+ return;
+ }
+
+ checkFirstChildRules(e, style);
+ checkLastChildRules(e, style);
}
-void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+void Element::childrenChanged(bool changedByParser)
{
- ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+ ContainerNode::childrenChanged(changedByParser);
if (!changedByParser)
- checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
+ checkStyleRules(this, renderStyle(), false);
}
void Element::finishParsingChildren()
{
ContainerNode::finishParsingChildren();
m_parsingChildrenFinished = true;
- checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
+ checkStyleRules(this, renderStyle(), true);
}
void Element::dispatchAttrRemovalEvent(Attribute*)
@@ -981,7 +961,23 @@ void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
}
#ifndef NDEBUG
-void Element::formatForDebugger(char* buffer, unsigned length) const
+void Element::dump(TextStream *stream, DeprecatedString ind) const
+{
+ updateStyleAttributeIfNeeded();
+ if (namedAttrMap) {
+ for (unsigned i = 0; i < namedAttrMap->length(); i++) {
+ Attribute *attr = namedAttrMap->attributeItem(i);
+ *stream << " " << attr->name().localName().deprecatedString().ascii()
+ << "=\"" << attr->value().deprecatedString().ascii() << "\"";
+ }
+ }
+
+ ContainerNode::dump(stream,ind);
+}
+#endif
+
+#ifndef NDEBUG
+void Element::formatForDebugger(char *buffer, unsigned length) const
{
String result;
String s;
@@ -1007,7 +1003,7 @@ void Element::formatForDebugger(char* buffer, unsigned length) const
result += s;
}
- strncpy(buffer, result.utf8().data(), length - 1);
+ strncpy(buffer, result.deprecatedString().latin1(), length - 1);
}
#endif
@@ -1143,13 +1139,27 @@ void Element::updateFocusAppearance(bool restorePreviousSelection)
frame->selectionController()->setSelection(newSelection);
frame->revealSelection();
}
+#ifdef ANDROID_SCROLL_FIX
+ // We handle the scrolling the screen with our navigation code,
+ // so ignore this call to put the rectangle on screen.
+ }
+#else
} else if (renderer() && !renderer()->isWidget())
renderer()->enclosingLayer()->scrollRectToVisible(getRect());
+#endif
}
void Element::blur()
{
cancelFocusAppearanceUpdate();
+#ifdef ANDROID_IGNORE_BLUR
+ // Since we control the focus anyway, there is no need to do blur events
+ // unless the element has a blur event.
+ NamedAttrMap* map = attributes();
+ Node* blur = (map->getNamedItem(HTMLNames::onblurAttr)).get();
+ if (!blur)
+ return;
+#endif
Document* doc = document();
if (doc->focusedNode() == this) {
if (doc->frame())
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index 33727cd..e85cd1b 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -109,7 +109,7 @@ public:
virtual void setPrefix(const AtomicString &_prefix, ExceptionCode&);
virtual const AtomicString& namespaceURI() const { return m_tagName.namespaceURI(); }
- virtual KURL baseURI() const;
+ virtual String baseURI() const;
// DOM methods overridden from parent classes
virtual NodeType nodeType() const;
@@ -118,7 +118,7 @@ public:
virtual bool isElementNode() const { return true; }
virtual void insertedIntoDocument();
virtual void removedFromDocument();
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false);
virtual bool isInputTypeHidden() const { return false; }
@@ -161,12 +161,20 @@ public:
virtual bool isURLAttribute(Attribute*) const;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual String target() const { return String(); }
-
+#ifdef ANDROID_DO_NOT_RESTORE_PREVIOUS_SELECTION
+ // Set the default to not restore the previous selection, since
+ // we want the selection to cover the whole textfield.
+ // FIXME: Would it be a better fix to simply ignore the input
+ // value in the implementation?
+ virtual void focus(bool restorePreviousSelection = false);
+#else
virtual void focus(bool restorePreviousSelection = true);
+#endif
virtual void updateFocusAppearance(bool restorePreviousSelection);
void blur();
#ifndef NDEBUG
+ virtual void dump(TextStream* , DeprecatedString ind = "") const;
virtual void formatForDebugger(char* buffer, unsigned length) const;
#endif
diff --git a/WebCore/dom/Event.cpp b/WebCore/dom/Event.cpp
index 543dfff..2f3313d 100644
--- a/WebCore/dom/Event.cpp
+++ b/WebCore/dom/Event.cpp
@@ -30,8 +30,7 @@
namespace WebCore {
Event::Event()
- : RefCounted<Event>(0)
- , m_canBubble(false)
+ : m_canBubble(false)
, m_cancelable(false)
, m_propagationStopped(false)
, m_defaultPrevented(false)
@@ -44,8 +43,7 @@ Event::Event()
}
Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
- : RefCounted<Event>(0)
- , m_type(eventType)
+ : m_type(eventType)
, m_canBubble(canBubbleArg)
, m_cancelable(cancelableArg)
, m_propagationStopped(false)
diff --git a/WebCore/dom/EventListener.h b/WebCore/dom/EventListener.h
index 0938041..1bc4283 100644
--- a/WebCore/dom/EventListener.h
+++ b/WebCore/dom/EventListener.h
@@ -29,7 +29,6 @@ namespace WebCore {
class EventListener : public RefCounted<EventListener> {
public:
- EventListener() : RefCounted<EventListener>(0) { }
virtual ~EventListener() { }
virtual void handleEvent(Event*, bool isWindowEvent = false) = 0;
virtual bool isHTMLEventListener() const { return false; }
diff --git a/WebCore/dom/EventTargetNode.cpp b/WebCore/dom/EventTargetNode.cpp
index 146ee8b..bae16f4 100644
--- a/WebCore/dom/EventTargetNode.cpp
+++ b/WebCore/dom/EventTargetNode.cpp
@@ -42,6 +42,7 @@
#include "ProgressEvent.h"
#include "RegisteredEventListener.h"
#include "TextEvent.h"
+#include "TextStream.h"
#include "WheelEvent.h"
namespace WebCore {
@@ -114,13 +115,18 @@ bool EventTargetNode::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool
return dispatchGenericEvent(eventTarget, evt.release(), ec, tempEvent);
}
-bool EventTargetNode::dispatchSubtreeModifiedEvent()
+bool EventTargetNode::dispatchSubtreeModifiedEvent(bool sendChildrenChanged)
{
ASSERT(!eventDispatchForbidden());
document()->incDOMTreeVersion();
- notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing.
+ // FIXME: Pull this whole if clause out of this function.
+ if (sendChildrenChanged) {
+ notifyNodeListsChildrenChanged();
+ childrenChanged();
+ } else
+ notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing.
if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
return false;
@@ -387,6 +393,20 @@ EventListener *EventTargetNode::getHTMLEventListener(const AtomicString &eventTy
return 0;
}
+#ifdef ANDROID
+EventListener *EventTargetNode::getEventListener(const AtomicString &eventType)
+{
+ if (!m_regdListeners)
+ return 0;
+
+ RegisteredEventListenerList::Iterator end = m_regdListeners->end();
+ for (RegisteredEventListenerList::Iterator it = m_regdListeners->begin(); it != end; ++it)
+ if ((*it)->eventType() == eventType)
+ return (*it)->listener();
+ return 0;
+}
+#endif
+
bool EventTargetNode::disabled() const
{
return false;
@@ -415,4 +435,16 @@ void EventTargetNode::defaultEventHandler(Event* event)
}
}
+#ifndef NDEBUG
+
+void EventTargetNode::dump(TextStream* stream, DeprecatedString ind) const
+{
+ if (m_regdListeners)
+ *stream << " #regdListeners=" << m_regdListeners->count(); // ### more detail
+
+ Node::dump(stream,ind);
+}
+
+#endif
+
} // namespace WebCore
diff --git a/WebCore/dom/EventTargetNode.h b/WebCore/dom/EventTargetNode.h
index 9a0647b..b499b7e 100644
--- a/WebCore/dom/EventTargetNode.h
+++ b/WebCore/dom/EventTargetNode.h
@@ -48,8 +48,11 @@ public:
void removeHTMLEventListener(const AtomicString& eventType);
bool dispatchHTMLEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
EventListener* getHTMLEventListener(const AtomicString& eventType);
+#ifdef ANDROID
+ EventListener* getEventListener(const AtomicString& eventType);
+#endif
- bool dispatchSubtreeModifiedEvent();
+ bool dispatchSubtreeModifiedEvent(bool childrenChanged = true);
void dispatchWindowEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
bool dispatchUIEvent(const AtomicString& eventType, int detail = 0, PassRefPtr<Event> underlyingEvent = 0);
bool dispatchKeyEvent(const PlatformKeyboardEvent&);
@@ -82,6 +85,10 @@ public:
* to event listeners, and prevents DOMActivate events from being sent at all.
*/
virtual bool disabled() const;
+
+#ifndef NDEBUG
+ virtual void dump(TextStream*, DeprecatedString indent = "") const;
+#endif
RegisteredEventListenerList* localEventListeners() const { return m_regdListeners; }
diff --git a/WebCore/dom/ExceptionBase.cpp b/WebCore/dom/ExceptionBase.cpp
index d2526bd..92a14f5 100644
--- a/WebCore/dom/ExceptionBase.cpp
+++ b/WebCore/dom/ExceptionBase.cpp
@@ -32,7 +32,6 @@
namespace WebCore {
ExceptionBase::ExceptionBase(const ExceptionCodeDescription& description)
- : RefCounted<ExceptionBase>(0)
{
m_code = description.code;
if (description.name) {
diff --git a/WebCore/dom/NamedAttrMap.cpp b/WebCore/dom/NamedAttrMap.cpp
index ee89bcc..d1a39a7 100644
--- a/WebCore/dom/NamedAttrMap.cpp
+++ b/WebCore/dom/NamedAttrMap.cpp
@@ -99,7 +99,11 @@ PassRefPtr<Node> NamedAttrMap::getNamedItem(const QualifiedName& name) const
PassRefPtr<Node> NamedAttrMap::setNamedItem(Node* arg, ExceptionCode& ec)
{
+#ifdef ANDROID_FIX
+ if (!element || !arg) {
+#else
if (!element) {
+#endif
ec = NOT_FOUND_ERR;
return 0;
}
@@ -282,7 +286,7 @@ void NamedAttrMap::addAttribute(PassRefPtr<Attribute> prpAttribute)
// Because of our updateStyleAttributeIfNeeded() style modification events are never sent at the right time, so don't bother sending them.
if (attribute->name() != styleAttr) {
element->dispatchAttrAdditionEvent(attribute);
- element->dispatchSubtreeModifiedEvent();
+ element->dispatchSubtreeModifiedEvent(false);
}
}
}
@@ -328,7 +332,7 @@ void NamedAttrMap::removeAttribute(const QualifiedName& name)
}
if (element) {
element->dispatchAttrRemovalEvent(attr);
- element->dispatchSubtreeModifiedEvent();
+ element->dispatchSubtreeModifiedEvent(false);
}
attr->deref();
}
diff --git a/WebCore/dom/NamedAttrMap.h b/WebCore/dom/NamedAttrMap.h
index dd57284..21e8ce8 100644
--- a/WebCore/dom/NamedAttrMap.h
+++ b/WebCore/dom/NamedAttrMap.h
@@ -68,8 +68,7 @@ public:
// used during parsing: only inserts if not already there
// no error checking!
- void insertAttribute(PassRefPtr<Attribute> newAttribute, bool allowDuplicates)
- {
+ void insertAttribute(PassRefPtr<Attribute> newAttribute, bool allowDuplicates) {
ASSERT(!element);
if (allowDuplicates || !getAttributeItem(newAttribute->name()))
addAttribute(newAttribute);
@@ -84,7 +83,7 @@ public:
protected:
// this method is internal, does no error checking at all
- void addAttribute(PassRefPtr<Attribute>);
+ void addAttribute(PassRefPtr<Attribute> newAttribute);
// this method is internal, does no error checking at all
void removeAttribute(const QualifiedName& name);
virtual void clearAttributes();
diff --git a/WebCore/dom/NamedNodeMap.h b/WebCore/dom/NamedNodeMap.h
index cc70bea..b8d5fff 100644
--- a/WebCore/dom/NamedNodeMap.h
+++ b/WebCore/dom/NamedNodeMap.h
@@ -41,7 +41,7 @@ typedef int ExceptionCode;
// Other classes implement this for more specific situations e.g. attributes of an element.
class NamedNodeMap : public RefCounted<NamedNodeMap> {
public:
- NamedNodeMap() : RefCounted<NamedNodeMap>(0) { }
+ NamedNodeMap() { }
virtual ~NamedNodeMap() { }
virtual PassRefPtr<Node> getNamedItem(const String& name) const = 0;
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 8a52e0e..52e43e4 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2007 Trolltech ASA
*
* This library is free software; you can redistribute it and/or
@@ -42,6 +42,7 @@
#include "Frame.h"
#include "HTMLNames.h"
#include "HTMLNames.h"
+#include "KURL.h"
#include "Logging.h"
#include "NameNodeList.h"
#include "NamedAttrMap.h"
@@ -49,6 +50,7 @@
#include "SelectorNodeList.h"
#include "TagNodeList.h"
#include "Text.h"
+#include "TextStream.h"
#include "XMLNames.h"
#include "htmlediting.h"
#include "kjs_binding.h"
@@ -150,7 +152,7 @@ void Node::setDocument(Document* doc)
{
KJS::JSLock lock;
- ScriptInterpreter::updateDOMNodeDocument(this, m_document.get(), doc);
+ KJS::ScriptInterpreter::updateDOMNodeDocument(this, m_document.get(), doc);
}
m_document = doc;
@@ -484,17 +486,23 @@ Node *Node::childNode(unsigned /*index*/) const
Node *Node::traverseNextNode(const Node *stayWithin) const
{
- if (firstChild())
+ if (firstChild()) {
+ ASSERT(!stayWithin || firstChild()->isDescendantOf(stayWithin));
return firstChild();
+ }
if (this == stayWithin)
return 0;
- if (nextSibling())
+ if (nextSibling()) {
+ ASSERT(!stayWithin || nextSibling()->isDescendantOf(stayWithin));
return nextSibling();
+ }
const Node *n = this;
while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
- if (n)
+ if (n) {
+ ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
return n->nextSibling();
+ }
return 0;
}
@@ -502,13 +510,17 @@ Node *Node::traverseNextSibling(const Node *stayWithin) const
{
if (this == stayWithin)
return 0;
- if (nextSibling())
+ if (nextSibling()) {
+ ASSERT(!stayWithin || nextSibling()->isDescendantOf(stayWithin));
return nextSibling();
+ }
const Node *n = this;
while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
- if (n)
+ if (n) {
+ ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
return n->nextSibling();
+ }
return 0;
}
@@ -527,31 +539,23 @@ Node *Node::traversePreviousNode(const Node *stayWithin) const
Node *Node::traversePreviousNodePostOrder(const Node *stayWithin) const
{
- if (lastChild())
+ if (lastChild()) {
+ ASSERT(!stayWithin || lastChild()->isDescendantOf(stayWithin));
return lastChild();
+ }
if (this == stayWithin)
return 0;
- if (previousSibling())
- return previousSibling();
- const Node *n = this;
- while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
- n = n->parentNode();
- if (n)
- return n->previousSibling();
- return 0;
-}
-
-Node* Node::traversePreviousSiblingPostOrder(const Node* stayWithin) const
-{
- if (this == stayWithin)
- return 0;
- if (previousSibling())
+ if (previousSibling()) {
+ ASSERT(!stayWithin || previousSibling()->isDescendantOf(stayWithin));
return previousSibling();
+ }
const Node *n = this;
while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
- if (n)
+ if (n) {
+ ASSERT(!stayWithin || !n->previousSibling() || n->previousSibling()->isDescendantOf(stayWithin));
return n->previousSibling();
+ }
return 0;
}
@@ -735,7 +739,7 @@ bool Node::isDescendantOf(const Node *other) const
return false;
}
-bool Node::childAllowed(Node* newChild)
+bool Node::childAllowed( Node *newChild )
{
return childTypeAllowed(newChild->nodeType());
}
@@ -784,6 +788,24 @@ Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 ) const
return ch;
}
+#ifndef NDEBUG
+void Node::dump(TextStream* stream, DeprecatedString ind) const
+{
+ if (m_hasId) { *stream << " hasId"; }
+ if (m_hasClass) { *stream << " hasClass"; }
+ if (m_focused) { *stream << " focused"; }
+ if (m_active) { *stream << " active"; }
+
+ *stream << " tabIndex=" << m_tabIndex;
+ *stream << endl;
+
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ *stream << ind << child->nodeName() << ": ";
+ child->dump(stream, ind + " ");
+ }
+}
+#endif
+
void Node::attach()
{
ASSERT(!attached());
@@ -1262,14 +1284,18 @@ bool Node::hasAttributes() const
return false;
}
-NamedAttrMap* Node::attributes() const
+NamedAttrMap *Node::attributes() const
{
return 0;
}
-KURL Node::baseURI() const
+String Node::baseURI() const
{
- return parentNode() ? parentNode()->baseURI() : KURL();
+ Node* parent = parentNode();
+ if (parent)
+ return parent->baseURI();
+
+ return String();
}
bool Node::isEqualNode(Node *other) const
@@ -1522,7 +1548,7 @@ String Node::textContent(bool convertBRsToNewlines) const
case DOCUMENT_TYPE_NODE:
case NOTATION_NODE:
default:
- return String();
+ return String();
}
}
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index 3abdfc0..e63ec4b 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -24,6 +24,7 @@
#ifndef Node_h
#define Node_h
+#include "DeprecatedString.h"
#include "DocPtr.h"
#include "PlatformString.h"
#include "TreeShared.h"
@@ -43,7 +44,6 @@ class Event;
class EventListener;
class IntRect;
class KeyboardEvent;
-class KURL;
class NamedAttrMap;
class NodeList;
class PlatformKeyboardEvent;
@@ -54,7 +54,7 @@ class RegisteredEventListener;
class RenderArena;
class RenderObject;
class RenderStyle;
-
+class TextStream;
struct NodeListsNodeData;
typedef int ExceptionCode;
@@ -106,7 +106,7 @@ public:
virtual bool hasAttributes() const;
virtual NamedAttrMap* attributes() const;
- virtual KURL baseURI() const;
+ virtual String baseURI() const;
// These should all actually return a node, but this is only important for language bindings,
// which will already know and hold a ref on the right node to return. Returning bool allows
@@ -329,7 +329,6 @@ public:
/* Like traversePreviousNode, but visits nodes before their children. */
Node* traversePreviousNodePostOrder(const Node *stayWithin = 0) const;
- Node* traversePreviousSiblingPostOrder(const Node *stayWithin = 0) const;
/**
* Finds previous or next editable leaf node.
@@ -368,6 +367,10 @@ public:
// Whether or not a selection can be started in this object
virtual bool canStartSelection() const;
+#ifndef NDEBUG
+ virtual void dump(TextStream*, DeprecatedString indent = "") const;
+#endif
+
// -----------------------------------------------------------------------------
// Integration with rendering tree
@@ -432,7 +435,7 @@ public:
* Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
* node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
*/
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) {};
+ virtual void childrenChanged(bool changedByParser = false) {};
virtual String toString() const = 0;
diff --git a/WebCore/dom/NodeFilter.cpp b/WebCore/dom/NodeFilter.cpp
index 1844a2d..ff5ad92 100644
--- a/WebCore/dom/NodeFilter.cpp
+++ b/WebCore/dom/NodeFilter.cpp
@@ -1,9 +1,11 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,14 +27,17 @@
#include "config.h"
#include "NodeFilter.h"
-using namespace KJS;
-
namespace WebCore {
-short NodeFilter::acceptNode(Node* node, JSValue*& exception) const
+NodeFilter::NodeFilter(NodeFilterCondition* condition)
+ : m_condition(condition)
+{
+}
+
+short NodeFilter::acceptNode(Node* node) const
{
// cast to short silences "enumeral and non-enumeral types in return" warning
- return m_condition ? m_condition->acceptNode(node, exception) : static_cast<short>(FILTER_ACCEPT);
+ return m_condition ? m_condition->acceptNode(node) : static_cast<short>(FILTER_ACCEPT);
}
} // namespace WebCore
diff --git a/WebCore/dom/NodeFilter.h b/WebCore/dom/NodeFilter.h
index 2f7c822..66b175d 100644
--- a/WebCore/dom/NodeFilter.h
+++ b/WebCore/dom/NodeFilter.h
@@ -1,9 +1,11 @@
/*
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,7 +28,6 @@
#define NodeFilter_h
#include "NodeFilterCondition.h"
-#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -65,13 +66,10 @@ namespace WebCore {
SHOW_NOTATION = 0x00000800
};
- NodeFilter(PassRefPtr<NodeFilterCondition> condition) : RefCounted<NodeFilter>(0), m_condition(condition) { }
- short acceptNode(Node*, KJS::JSValue*& exception) const;
+ NodeFilter(NodeFilterCondition*);
+ short acceptNode(Node*) const;
void mark() { m_condition->mark(); };
- // For non-JS bindings. Silently ignores the JavaScript exception if any.
- short acceptNode(Node* node) const { KJS::JSValue* exception; return acceptNode(node, exception); }
-
private:
RefPtr<NodeFilterCondition> m_condition;
};
diff --git a/WebCore/dom/NodeFilter.idl b/WebCore/dom/NodeFilter.idl
index 3cc5e86..1e0eac0 100644
--- a/WebCore/dom/NodeFilter.idl
+++ b/WebCore/dom/NodeFilter.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* This library is free software; you can redistribute it and/or
@@ -43,7 +43,7 @@ module traversal {
const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x00000400;
const unsigned long SHOW_NOTATION = 0x00000800;
- [Custom] short acceptNode(in Node n);
+ short acceptNode(in Node n);
};
diff --git a/WebCore/dom/NodeFilterCondition.cpp b/WebCore/dom/NodeFilterCondition.cpp
index 48bdcb4..5ee81c3 100644
--- a/WebCore/dom/NodeFilterCondition.cpp
+++ b/WebCore/dom/NodeFilterCondition.cpp
@@ -1,9 +1,11 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,11 +29,9 @@
#include "NodeFilter.h"
-using namespace KJS;
-
namespace WebCore {
-short NodeFilterCondition::acceptNode(Node*, JSValue*&) const
+short NodeFilterCondition::acceptNode(Node*) const
{
return NodeFilter::FILTER_ACCEPT;
}
diff --git a/WebCore/dom/NodeFilterCondition.h b/WebCore/dom/NodeFilterCondition.h
index 7596684..74fa2fa 100644
--- a/WebCore/dom/NodeFilterCondition.h
+++ b/WebCore/dom/NodeFilterCondition.h
@@ -1,9 +1,11 @@
/*
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,19 +29,14 @@
#include <wtf/RefCounted.h>
-namespace KJS {
- class JSValue;
-}
-
namespace WebCore {
class Node;
class NodeFilterCondition : public RefCounted<NodeFilterCondition> {
public:
- NodeFilterCondition() : RefCounted<NodeFilterCondition>(0) { }
virtual ~NodeFilterCondition() { }
- virtual short acceptNode(Node*, KJS::JSValue*& exception) const;
+ virtual short acceptNode(Node*) const;
virtual void mark() { }
};
diff --git a/WebCore/dom/NodeIterator.cpp b/WebCore/dom/NodeIterator.cpp
index 502d393..47117b2 100644
--- a/WebCore/dom/NodeIterator.cpp
+++ b/WebCore/dom/NodeIterator.cpp
@@ -1,9 +1,11 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,197 +31,148 @@
#include "ExceptionCode.h"
#include "NodeFilter.h"
-using namespace KJS;
-
namespace WebCore {
-NodeIterator::NodePointer::NodePointer()
-{
-}
-
-NodeIterator::NodePointer::NodePointer(PassRefPtr<Node> n, bool b)
- : node(n)
- , isPointerBeforeNode(b)
-{
-}
-
-void NodeIterator::NodePointer::clear()
-{
- node.clear();
-}
-
-bool NodeIterator::NodePointer::moveToNext(Node* root)
-{
- if (!node)
- return false;
- if (isPointerBeforeNode) {
- isPointerBeforeNode = false;
- return true;
- }
- node = node->traverseNextNode(root);
- return node;
-}
-
-bool NodeIterator::NodePointer::moveToPrevious(Node* root)
-{
- if (!node)
- return false;
- if (!isPointerBeforeNode) {
- isPointerBeforeNode = true;
- return true;
- }
- node = node->traversePreviousNode(root);
- return node;
-}
-
-NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
+NodeIterator::NodeIterator(Node* rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
: Traversal(rootNode, whatToShow, filter, expandEntityReferences)
- , m_referenceNode(root(), true)
+ , m_beforeReferenceNode(true)
, m_detached(false)
+ , m_doc(rootNode ? rootNode->document() : 0)
{
- root()->document()->attachNodeIterator(this);
+ if (document())
+ document()->attachNodeIterator(this);
}
NodeIterator::~NodeIterator()
{
- root()->document()->detachNodeIterator(this);
+ if (document())
+ document()->detachNodeIterator(this);
}
-Node* NodeIterator::nextNode(ExceptionCode& ec, JSValue*& exception)
+Node* NodeIterator::findNextNode(Node* node) const
{
- if (m_detached) {
- ec = INVALID_STATE_ERR;
- return 0;
- }
-
- Node* result = 0;
-
- m_candidateNode = m_referenceNode;
- while (m_candidateNode.moveToNext(root())) {
+ while ((node = node->traverseNextNode(root()))) {
// NodeIterators treat the DOM tree as a flat list of nodes.
// In other words, FILTER_REJECT does not pass over descendants
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
- exception = 0;
- bool nodeWasAccepted = acceptNode(m_candidateNode.node.get(), exception) == NodeFilter::FILTER_ACCEPT;
- if (exception)
- break;
- if (nodeWasAccepted) {
- m_referenceNode = m_candidateNode;
- result = m_referenceNode.node.get();
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT)
break;
- }
}
-
- m_candidateNode.clear();
- return result;
+ return node;
}
-Node* NodeIterator::previousNode(ExceptionCode& ec, JSValue*& exception)
+Node* NodeIterator::nextNode(ExceptionCode& ec)
{
- if (m_detached) {
+ if (detached()) {
ec = INVALID_STATE_ERR;
return 0;
}
- Node* result = 0;
+ Node* node = referenceNode() ? referenceNode() : root();
+ if (!pointerBeforeReferenceNode() || acceptNode(node) != NodeFilter::FILTER_ACCEPT)
+ node = findNextNode(node);
+ if (node)
+ setReferenceNode(node);
+ setPointerBeforeReferenceNode(false);
+ return node;
+}
- m_candidateNode = m_referenceNode;
- while (m_candidateNode.moveToPrevious(root())) {
+Node* NodeIterator::findPreviousNode(Node* node) const
+{
+ while ((node = node->traversePreviousNode(root()))) {
// NodeIterators treat the DOM tree as a flat list of nodes.
// In other words, FILTER_REJECT does not pass over descendants
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
- exception = 0;
- bool nodeWasAccepted = acceptNode(m_candidateNode.node.get(), exception) == NodeFilter::FILTER_ACCEPT;
- if (exception)
- break;
- if (nodeWasAccepted) {
- m_referenceNode = m_candidateNode;
- result = m_referenceNode.node.get();
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT)
break;
- }
}
+ return node;
+}
- m_candidateNode.clear();
- return result;
+Node* NodeIterator::previousNode(ExceptionCode&)
+{
+ Node* node = referenceNode() ? referenceNode() : root();
+ if (pointerBeforeReferenceNode() || acceptNode(node) != NodeFilter::FILTER_ACCEPT)
+ node = findPreviousNode(node);
+ if (node)
+ setReferenceNode(node);
+ setPointerBeforeReferenceNode();
+ return node;
}
void NodeIterator::detach()
{
- root()->document()->detachNodeIterator(this);
- m_detached = true;
- m_referenceNode.node.clear();
+ if (!detached() && document())
+ document()->detachNodeIterator(this);
+ setDetached();
}
-void NodeIterator::notifyBeforeNodeRemoval(Node* removedNode)
+void NodeIterator::setReferenceNode(Node* node)
{
- updateForNodeRemoval(removedNode, m_referenceNode);
+ m_referenceNode = node;
}
-void NodeIterator::updateForNodeRemoval(Node* removedNode, NodePointer& referenceNode) const
+void NodeIterator::notifyBeforeNodeRemoval(Node* removedNode)
{
- ASSERT(!m_detached);
- ASSERT(removedNode);
- ASSERT(root()->document() == removedNode->document());
-
// Iterator is not affected if the removed node is the reference node and is the root.
// or if removed node is not the reference node, or the ancestor of the reference node.
- if (!removedNode->isDescendantOf(root()))
+ if (!removedNode || removedNode == root() || !removedNode->isDescendantOf(root()))
return;
- bool willRemoveReferenceNode = removedNode == referenceNode.node;
- bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(removedNode);
+ bool willRemoveReferenceNode = removedNode == referenceNode();
+ bool willRemoveReferenceNodeAncestor = referenceNode() && referenceNode()->isDescendantOf(removedNode);
if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
return;
- if (referenceNode.isPointerBeforeNode) {
- Node* node = removedNode->traverseNextNode(root());
+ if (pointerBeforeReferenceNode()) {
+ Node* node = findNextNode(removedNode);
if (node) {
// Move out from under the node being removed if the reference node is
// a descendant of the node being removed.
if (willRemoveReferenceNodeAncestor) {
while (node && node->isDescendantOf(removedNode))
- node = node->traverseNextNode(root());
+ node = findNextNode(node);
}
if (node)
- referenceNode.node = node;
+ setReferenceNode(node);
} else {
- node = removedNode->traversePreviousNode(root());
+ node = findPreviousNode(removedNode);
if (node) {
// Move out from under the node being removed if the reference node is
// a descendant of the node being removed.
if (willRemoveReferenceNodeAncestor) {
while (node && node->isDescendantOf(removedNode))
- node = node->traversePreviousNode(root());
+ node = findPreviousNode(node);
}
if (node) {
// Removing last node.
// Need to move the pointer after the node preceding the
// new reference node.
- referenceNode.node = node;
- referenceNode.isPointerBeforeNode = false;
+ setReferenceNode(node);
+ setPointerBeforeReferenceNode(false);
}
}
}
} else {
- Node* node = removedNode->traversePreviousNode(root());
+ Node* node = findPreviousNode(removedNode);
if (node) {
// Move out from under the node being removed if the reference node is
// a descendant of the node being removed.
if (willRemoveReferenceNodeAncestor) {
while (node && node->isDescendantOf(removedNode))
- node = node->traversePreviousNode(root());
+ node = findPreviousNode(node);
}
if (node)
- referenceNode.node = node;
+ setReferenceNode(node);
} else {
- node = removedNode->traverseNextNode(root());
+ node = findNextNode(removedNode);
// Move out from under the node being removed if the reference node is
// a descendant of the node being removed.
if (willRemoveReferenceNodeAncestor) {
while (node && node->isDescendantOf(removedNode))
- node = node->traversePreviousNode(root());
+ node = findPreviousNode(node);
}
if (node)
- referenceNode.node = node;
+ setReferenceNode(node);
}
}
}
diff --git a/WebCore/dom/NodeIterator.h b/WebCore/dom/NodeIterator.h
index b2a7c70..b737e57 100644
--- a/WebCore/dom/NodeIterator.h
+++ b/WebCore/dom/NodeIterator.h
@@ -1,9 +1,11 @@
/*
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,47 +28,45 @@
#define NodeIterator_h
#include "Traversal.h"
-#include <wtf/PassRefPtr.h>
namespace WebCore {
+ class Document;
+
typedef int ExceptionCode;
class NodeIterator : public Traversal {
public:
- NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
- virtual ~NodeIterator();
+ NodeIterator(Node*, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
+ ~NodeIterator();
- Node* nextNode(ExceptionCode&, KJS::JSValue*& exception);
- Node* previousNode(ExceptionCode&, KJS::JSValue*& exception);
+ Node* nextNode(ExceptionCode&);
+ Node* previousNode(ExceptionCode&);
void detach();
- Node* referenceNode() const { return m_referenceNode.node.get(); }
- bool pointerBeforeReferenceNode() const { return m_referenceNode.isPointerBeforeNode; }
+ Node* referenceNode() const { return m_referenceNode.get(); }
+ bool pointerBeforeReferenceNode() const { return m_beforeReferenceNode; }
- // This function is called before any node is removed from the document tree.
- void notifyBeforeNodeRemoval(Node* nodeToBeRemoved);
-
- // For non-JS bindings. Silently ignores the JavaScript exception if any.
- Node* nextNode(ExceptionCode& ec) { KJS::JSValue* exception; return nextNode(ec, exception); }
- Node* previousNode(ExceptionCode& ec) { KJS::JSValue* exception; return previousNode(ec, exception); }
+ /**
+ * This function has to be called if you delete a node from the
+ * document tree and you want the Iterator to react if there
+ * are any changes concerning it.
+ */
+ void notifyBeforeNodeRemoval(Node* removed);
private:
- struct NodePointer {
- RefPtr<Node> node;
- bool isPointerBeforeNode;
- NodePointer();
- NodePointer(PassRefPtr<Node>, bool);
- void clear();
- bool moveToNext(Node* root);
- bool moveToPrevious(Node* root);
- };
-
- void updateForNodeRemoval(Node* nodeToBeRemoved, NodePointer&) const;
+ void setReferenceNode(Node*);
+ void setPointerBeforeReferenceNode(bool flag = true) { m_beforeReferenceNode = flag; }
+ bool detached() const { return m_detached; }
+ void setDetached(bool flag = true) { m_detached = flag; }
+ Document* document() const { return m_doc.get(); }
+ Node* findNextNode(Node*) const;
+ Node* findPreviousNode(Node*) const;
- NodePointer m_referenceNode;
- NodePointer m_candidateNode;
+ RefPtr<Node> m_referenceNode;
+ bool m_beforeReferenceNode;
bool m_detached;
+ RefPtr<Document> m_doc;
};
} // namespace WebCore
diff --git a/WebCore/dom/NodeIterator.idl b/WebCore/dom/NodeIterator.idl
index e129de3..4c82cc0 100644
--- a/WebCore/dom/NodeIterator.idl
+++ b/WebCore/dom/NodeIterator.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* This library is free software; you can redistribute it and/or
@@ -29,9 +29,9 @@ module traversal {
readonly attribute Node referenceNode;
readonly attribute boolean pointerBeforeReferenceNode;
- [Custom] Node nextNode()
+ Node nextNode()
raises (DOMException);
- [Custom] Node previousNode()
+ Node previousNode()
raises (DOMException);
void detach();
};
diff --git a/WebCore/dom/NodeList.h b/WebCore/dom/NodeList.h
index 2bc1443..bbb20f4 100644
--- a/WebCore/dom/NodeList.h
+++ b/WebCore/dom/NodeList.h
@@ -33,7 +33,7 @@ namespace WebCore {
class NodeList : public RefCounted<NodeList> {
public:
- NodeList() : RefCounted<NodeList>(0) { }
+ NodeList() { }
virtual ~NodeList() { }
// DOM methods & attributes for NodeList
diff --git a/WebCore/dom/Position.cpp b/WebCore/dom/Position.cpp
index 84ff856..ce60e68 100644
--- a/WebCore/dom/Position.cpp
+++ b/WebCore/dom/Position.cpp
@@ -26,20 +26,18 @@
#include "config.h"
#include "Position.h"
-#include "CSSComputedStyleDeclaration.h"
-#include "CString.h"
#include "CharacterNames.h"
#include "Document.h"
#include "Element.h"
-#include "HTMLNames.h"
#include "Logging.h"
-#include "PositionIterator.h"
#include "RenderBlock.h"
+#include "CSSComputedStyleDeclaration.h"
+#include "htmlediting.h"
+#include "HTMLNames.h"
+#include "PositionIterator.h"
#include "Text.h"
#include "TextIterator.h"
-#include "htmlediting.h"
#include "visible_units.h"
-#include <stdio.h>
namespace WebCore {
@@ -296,16 +294,6 @@ static bool isStreamer(const PositionIterator& pos)
return pos.atStartOfNode();
}
-// enclosingBlock does some expensive editability checks, upstream and downstream
-// can avoid those because they do their own editability checking.
-static Node* enclosingBlockIgnoringEditability(Node* node)
-{
- while (node && !isBlock(node))
- node = node->parentNode();
-
- return node;
-}
-
// p.upstream() returns the start of the range of positions that map to the same VisiblePosition as P.
Position Position::upstream() const
{
@@ -314,27 +302,19 @@ Position Position::upstream() const
return Position();
// iterate backward from there, looking for a qualified position
- Node* originalBlock = enclosingBlockIgnoringEditability(startNode);
+ Node* block = enclosingBlock(startNode);
PositionIterator lastVisible = *this;
PositionIterator currentPos = lastVisible;
- bool startEditable = startNode->isContentEditable();
- Node* lastNode = startNode;
+ Node* originalRoot = node()->rootEditableElement();
for (; !currentPos.atStart(); currentPos.decrement()) {
Node* currentNode = currentPos.node();
- // Don't check for an editability change if we haven't moved to a different node,
- // to avoid the expense of computing isContentEditable().
- if (currentNode != lastNode) {
- // Don't change editability.
- bool currentEditable = currentNode->isContentEditable();
- if (startEditable != currentEditable)
- break;
- lastNode = currentNode;
- }
+ if (currentNode->rootEditableElement() != originalRoot)
+ break;
// Don't enter a new enclosing block flow or table element. There is code below that
- // terminates early if we're about to leave a block.
- if (isBlock(currentNode) && currentNode != originalBlock)
+ // terminates early if we're about to leave an enclosing block flow or table element.
+ if (block != enclosingBlock(currentNode))
return lastVisible;
// skip position in unrendered or invisible node
@@ -347,8 +327,8 @@ Position Position::upstream() const
lastVisible = currentPos;
// Don't leave a block flow or table element. We could rely on code above to terminate and
- // return lastVisible on the next iteration, but we terminate early to avoid doing a nodeIndex() call.
- if (isBlock(currentNode) && currentPos.atStartOfNode())
+ // return lastVisible on the next iteration, but we terminate early.
+ if (currentNode == enclosingBlock(currentNode) && currentPos.atStartOfNode())
return lastVisible;
// Return position after tables and nodes which have content that can be ignored.
@@ -394,36 +374,23 @@ Position Position::downstream() const
return Position();
// iterate forward from there, looking for a qualified position
- Node* originalBlock = enclosingBlockIgnoringEditability(startNode);
+ Node* block = enclosingBlock(startNode);
PositionIterator lastVisible = *this;
PositionIterator currentPos = lastVisible;
- bool startEditable = startNode->isContentEditable();
- Node* lastNode = startNode;
+ Node* originalRoot = node()->rootEditableElement();
for (; !currentPos.atEnd(); currentPos.increment()) {
Node* currentNode = currentPos.node();
- // Don't check for an editability change if we haven't moved to a different node,
- // to avoid the expense of computing isContentEditable().
- if (currentNode != lastNode) {
- // Don't change editability.
- bool currentEditable = currentNode->isContentEditable();
- if (startEditable != currentEditable)
- break;
- lastNode = currentNode;
- }
+ if (currentNode->rootEditableElement() != originalRoot)
+ break;
// stop before going above the body, up into the head
// return the last visible streamer position
if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
break;
- // Do not enter a new enclosing block.
- if (isBlock(currentNode) && currentNode != originalBlock)
- return lastVisible;
- // Do not leave the original enclosing block.
- // Note: The first position after the last one in the original block
- // will be [originalBlock->parentNode(), originalBlock->nodeIndex() + 1].
- if (originalBlock && originalBlock->parentNode() == currentNode)
+ // Do not enter a new enclosing block flow or table element, and don't leave the original one.
+ if (block != enclosingBlock(currentNode))
return lastVisible;
// skip position in unrendered or invisible node
@@ -693,17 +660,17 @@ Position Position::trailingWhitespacePosition(EAffinity affinity, bool considerN
return Position();
}
-void Position::debugPosition(const char* msg) const
+void Position::debugPosition(const char *msg) const
{
if (isNull())
fprintf(stderr, "Position [%s]: null\n", msg);
else
- fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, node()->nodeName().utf8().data(), node(), offset());
+ fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, node()->nodeName().deprecatedString().latin1(), node(), offset());
}
#ifndef NDEBUG
-void Position::formatForDebugger(char* buffer, unsigned length) const
+void Position::formatForDebugger(char *buffer, unsigned length) const
{
String result;
@@ -718,7 +685,7 @@ void Position::formatForDebugger(char* buffer, unsigned length) const
result += s;
}
- strncpy(buffer, result.utf8().data(), length - 1);
+ strncpy(buffer, result.deprecatedString().latin1(), length - 1);
}
void Position::showTreeForThis() const
diff --git a/WebCore/dom/ProcessingInstruction.cpp b/WebCore/dom/ProcessingInstruction.cpp
index 34b00d4..7486e9a 100644
--- a/WebCore/dom/ProcessingInstruction.cpp
+++ b/WebCore/dom/ProcessingInstruction.cpp
@@ -1,6 +1,8 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -17,7 +19,6 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
-
#include "config.h"
#include "ProcessingInstruction.h"
@@ -155,7 +156,7 @@ bool ProcessingInstruction::checkStyleSheet()
m_cachedSheet->deref(this);
#if ENABLE(XSLT)
if (m_isXSL)
- m_cachedSheet = document()->docLoader()->requestXSLStyleSheet(document()->completeURL(href).string());
+ m_cachedSheet = document()->docLoader()->requestXSLStyleSheet(document()->completeURL(href));
else
#endif
{
@@ -163,7 +164,7 @@ bool ProcessingInstruction::checkStyleSheet()
if (charset.isEmpty())
charset = document()->frame()->loader()->encoding();
- m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(document()->completeURL(href).string(), charset);
+ m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(document()->completeURL(href), charset);
}
if (m_cachedSheet)
m_cachedSheet->ref(this);
@@ -196,13 +197,13 @@ bool ProcessingInstruction::sheetLoaded()
return false;
}
-void ProcessingInstruction::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet)
+void ProcessingInstruction::setCSSStyleSheet(const String& url, const String& charset, const String& sheet)
{
#if ENABLE(XSLT)
ASSERT(!m_isXSL);
#endif
m_sheet = new CSSStyleSheet(this, url, charset);
- parseStyleSheet(sheet->sheetText());
+ parseStyleSheet(sheet);
}
#if ENABLE(XSLT)
diff --git a/WebCore/dom/ProcessingInstruction.h b/WebCore/dom/ProcessingInstruction.h
index be4a63e..f4ee819 100644
--- a/WebCore/dom/ProcessingInstruction.h
+++ b/WebCore/dom/ProcessingInstruction.h
@@ -57,7 +57,7 @@ public:
String localHref() const { return m_localHref; }
StyleSheet* sheet() const { return m_sheet.get(); }
bool checkStyleSheet();
- virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
+ virtual void setCSSStyleSheet(const String& url, const String& charset, const String& sheet);
#if ENABLE(XSLT)
virtual void setXSLStyleSheet(const String& url, const String& sheet);
#endif
diff --git a/WebCore/dom/QualifiedName.cpp b/WebCore/dom/QualifiedName.cpp
index c9d7e28..ebc63a2 100644
--- a/WebCore/dom/QualifiedName.cpp
+++ b/WebCore/dom/QualifiedName.cpp
@@ -97,7 +97,7 @@ struct QNameComponentsTranslator {
return c.m_prefix == name->m_prefix.impl() && c.m_localName == name->m_localName.impl() && c.m_namespace == name->m_namespace.impl();
}
static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameComponents& components, unsigned hash) {
- location = QualifiedName::QualifiedNameImpl::create(components.m_prefix, components.m_localName, components.m_namespace).releaseRef();
+ location = new QualifiedName::QualifiedNameImpl(components.m_prefix, components.m_localName, components.m_namespace);
}
};
@@ -109,10 +109,8 @@ QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const
if (!gNameCache)
gNameCache = new QNameSet;
QualifiedNameComponents components = { p.impl(), l.impl(), n.impl() };
- pair<QNameSet::iterator, bool> addResult = gNameCache->add<QualifiedNameComponents, QNameComponentsTranslator>(components);
- m_impl = *addResult.first;
- if (!addResult.second)
- m_impl->ref();
+ m_impl = *gNameCache->add<QualifiedNameComponents, QNameComponentsTranslator>(components).first;
+ ref();
}
QualifiedName::~QualifiedName()
diff --git a/WebCore/dom/QualifiedName.h b/WebCore/dom/QualifiedName.h
index 5aa8abf..60826b2 100644
--- a/WebCore/dom/QualifiedName.h
+++ b/WebCore/dom/QualifiedName.h
@@ -30,22 +30,11 @@ class QualifiedName {
public:
class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
public:
- static PassRefPtr<QualifiedNameImpl> create(const AtomicString& p, const AtomicString& l, const AtomicString& n)
- {
- return adoptRef(new QualifiedNameImpl(p, l, n));
- }
-
+ QualifiedNameImpl(const AtomicString& p, const AtomicString& l, const AtomicString& n) :m_prefix(p), m_localName(l), m_namespace(n) {}
+
AtomicString m_prefix;
AtomicString m_localName;
AtomicString m_namespace;
-
- private:
- QualifiedNameImpl(const AtomicString& p, const AtomicString& l, const AtomicString& n)
- : m_prefix(p)
- , m_localName(l)
- , m_namespace(n)
- {
- }
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
@@ -77,7 +66,8 @@ public:
static void init();
private:
- void ref() { m_impl->ref(); }
+
+ void ref() { m_impl->ref(); }
void deref();
QualifiedNameImpl* m_impl;
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index 88292c3..176c07b 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -24,7 +24,6 @@
#include "config.h"
#include "Range.h"
-#include "CString.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "ExceptionCode.h"
@@ -37,7 +36,6 @@
#include "TextIterator.h"
#include "markup.h"
#include "visible_units.h"
-#include <stdio.h>
namespace WebCore {
@@ -59,8 +57,7 @@ static RangeCounter rangeCounter;
#endif
Range::Range(Document* ownerDocument)
- : RefCounted<Range>(0)
- , m_ownerDocument(ownerDocument)
+ : m_ownerDocument(ownerDocument)
, m_startContainer(ownerDocument)
, m_startOffset(0)
, m_endContainer(ownerDocument)
@@ -75,8 +72,7 @@ Range::Range(Document* ownerDocument)
Range::Range(Document* ownerDocument,
Node* startContainer, int startOffset,
Node* endContainer, int endOffset)
- : RefCounted<Range>(0)
- , m_ownerDocument(ownerDocument)
+ : m_ownerDocument(ownerDocument)
, m_startContainer(ownerDocument)
, m_startOffset(0)
, m_endContainer(ownerDocument)
@@ -96,8 +92,7 @@ Range::Range(Document* ownerDocument,
}
Range::Range(Document* ownerDocument, const Position& start, const Position& end)
- : RefCounted<Range>(0)
- , m_ownerDocument(ownerDocument)
+ : m_ownerDocument(ownerDocument)
, m_startContainer(ownerDocument)
, m_startOffset(0)
, m_endContainer(ownerDocument)
@@ -366,11 +361,12 @@ short Range::comparePoint(Node* refNode, int offset, ExceptionCode& ec)
return -1;
// compare to end, and point comes after
- if (compareBoundaryPoints(refNode, offset, m_endContainer.get(), m_endOffset) == 1)
+ else if (compareBoundaryPoints(refNode, offset, m_endContainer.get(), m_endOffset) == 1)
return 1;
-
+
// point is in the middle of this range, or on the boundary points
- return 0;
+ else
+ return 0;
}
Range::CompareResults Range::compareNode(Node* refNode, ExceptionCode& ec)
@@ -1169,36 +1165,34 @@ bool Range::isDetached() const
void Range::checkNodeWOffset(Node* n, int offset, ExceptionCode& ec) const
{
+ if (offset < 0)
+ ec = INDEX_SIZE_ERR;
+ // no return here
+
switch (n->nodeType()) {
- case Node::DOCUMENT_TYPE_NODE:
case Node::ENTITY_NODE:
case Node::NOTATION_NODE:
+ case Node::DOCUMENT_TYPE_NODE:
ec = RangeException::INVALID_NODE_TYPE_ERR;
- return;
- case Node::CDATA_SECTION_NODE:
- case Node::COMMENT_NODE:
+ break;
case Node::TEXT_NODE:
- if (static_cast<unsigned>(offset) > static_cast<CharacterData*>(n)->length())
+ case Node::COMMENT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ if ((unsigned)offset > static_cast<CharacterData*>(n)->length())
ec = INDEX_SIZE_ERR;
- return;
+ break;
case Node::PROCESSING_INSTRUCTION_NODE:
- if (static_cast<unsigned>(offset) > static_cast<ProcessingInstruction*>(n)->data().length())
+ if ((unsigned)offset > static_cast<ProcessingInstruction*>(n)->data().length())
ec = INDEX_SIZE_ERR;
- return;
- case Node::ATTRIBUTE_NODE:
- case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::DOCUMENT_NODE:
- case Node::ELEMENT_NODE:
- case Node::ENTITY_REFERENCE_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- if (static_cast<unsigned>(offset) > n->childNodeCount())
+ break;
+ default:
+ if ((unsigned)offset > n->childNodeCount())
ec = INDEX_SIZE_ERR;
- return;
+ break;
}
- ASSERT_NOT_REACHED();
}
-void Range::checkNodeBA(Node* n, ExceptionCode& ec) const
+void Range::checkNodeBA( Node *n, ExceptionCode& ec) const
{
// INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is not an
// Attr, Document or DocumentFragment node or part of a shadow DOM tree
@@ -1206,7 +1200,6 @@ void Range::checkNodeBA(Node* n, ExceptionCode& ec) const
Node *root = n;
while (root->parentNode())
root = root->parentNode();
-
if (!(root->nodeType() == Node::ATTRIBUTE_NODE ||
root->nodeType() == Node::DOCUMENT_NODE ||
root->nodeType() == Node::DOCUMENT_FRAGMENT_NODE ||
@@ -1381,7 +1374,7 @@ void Range::selectNodeContents( Node *refNode, ExceptionCode& ec)
m_startContainer = refNode;
m_startOffset = 0;
m_endContainer = refNode;
- m_endOffset = maxEndOffset();
+ m_endOffset = refNode->offsetInCharacters() ? refNode->maxCharacterOffset() : refNode->childNodeCount();
}
void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
@@ -1400,23 +1393,14 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
// INVALID_NODE_TYPE_ERR: Raised if node is an Attr, Entity, DocumentType, Notation,
// Document, or DocumentFragment node.
- switch (newParent->nodeType()) {
- case Node::ATTRIBUTE_NODE:
- case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::DOCUMENT_NODE:
- case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- ec = RangeException::INVALID_NODE_TYPE_ERR;
- return;
- case Node::CDATA_SECTION_NODE:
- case Node::COMMENT_NODE:
- case Node::ELEMENT_NODE:
- case Node::ENTITY_REFERENCE_NODE:
- case Node::PROCESSING_INSTRUCTION_NODE:
- case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- break;
+ if( newParent->nodeType() == Node::ATTRIBUTE_NODE ||
+ newParent->nodeType() == Node::ENTITY_NODE ||
+ newParent->nodeType() == Node::NOTATION_NODE ||
+ newParent->nodeType() == Node::DOCUMENT_TYPE_NODE ||
+ newParent->nodeType() == Node::DOCUMENT_NODE ||
+ newParent->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) {
+ ec = RangeException::INVALID_NODE_TYPE_ERR;
+ return;
}
// NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of
@@ -1433,20 +1417,6 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
return;
}
- // BAD_BOUNDARYPOINTS_ERR: Raised if the Range partially selects a non-Text node.
- if (m_startContainer->nodeType() != Node::TEXT_NODE) {
- if (m_startOffset > 0 && m_startOffset < maxStartOffset()) {
- ec = RangeException::BAD_BOUNDARYPOINTS_ERR;
- return;
- }
- }
- if (m_endContainer->nodeType() != Node::TEXT_NODE) {
- if (m_endOffset > 0 && m_endOffset < maxEndOffset()) {
- ec = RangeException::BAD_BOUNDARYPOINTS_ERR;
- return;
- }
- }
-
// Raise a HIERARCHY_REQUEST_ERR if m_startContainer doesn't accept children like newParent.
Node* parentOfNewParent = m_startContainer.get();
// If m_startContainer is a textNode, it will be split and it will be its parent that will
@@ -1463,8 +1433,21 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
return;
}
- // FIXME: Do we need a check if the node would end up with a child node of a type not
- // allowed by the type of node?
+ // ### check if node would end up with a child node of a type not allowed by the type of node
+
+ // BAD_BOUNDARYPOINTS_ERR: Raised if the Range partially selects a non-text node.
+ if (!m_startContainer->offsetInCharacters()) {
+ if (m_startOffset > 0 && m_startOffset < m_startContainer->childNodeCount()) {
+ ec = RangeException::BAD_BOUNDARYPOINTS_ERR;
+ return;
+ }
+ }
+ if (!m_endContainer->offsetInCharacters()) {
+ if (m_endOffset > 0 && m_endOffset < m_endContainer->childNodeCount()) {
+ ec = RangeException::BAD_BOUNDARYPOINTS_ERR;
+ return;
+ }
+ }
ec = 0;
while (Node* n = newParent->firstChild()) {
@@ -1663,7 +1646,7 @@ void Range::formatForDebugger(char *buffer, unsigned length) const
result += s;
}
- strncpy(buffer, result.utf8().data(), length - 1);
+ strncpy(buffer, result.deprecatedString().latin1(), length - 1);
}
#undef FormatBufferSize
#endif
@@ -1697,22 +1680,4 @@ PassRefPtr<Range> rangeOfContents(Node* node)
return range.release();
}
-unsigned Range::maxStartOffset() const
-{
- if (!m_startContainer)
- return 0;
- if (!m_startContainer->offsetInCharacters())
- return m_startContainer->childNodeCount();
- return m_startContainer->maxCharacterOffset();
-}
-
-unsigned Range::maxEndOffset() const
-{
- if (!m_endContainer)
- return 0;
- if (!m_endContainer->offsetInCharacters())
- return m_endContainer->childNodeCount();
- return m_endContainer->maxCharacterOffset();
-}
-
}
diff --git a/WebCore/dom/Range.h b/WebCore/dom/Range.h
index 7568748..b3c516c 100644
--- a/WebCore/dom/Range.h
+++ b/WebCore/dom/Range.h
@@ -131,8 +131,6 @@ private:
void checkNodeBA(Node*, ExceptionCode&) const;
void checkDeleteExtract(ExceptionCode&);
bool containedByReadOnly() const;
- unsigned maxStartOffset() const;
- unsigned maxEndOffset() const;
};
PassRefPtr<Range> rangeOfContents(Node*);
diff --git a/WebCore/dom/RegisteredEventListener.cpp b/WebCore/dom/RegisteredEventListener.cpp
index e995bd0..927a728 100644
--- a/WebCore/dom/RegisteredEventListener.cpp
+++ b/WebCore/dom/RegisteredEventListener.cpp
@@ -30,8 +30,7 @@
namespace WebCore {
RegisteredEventListener::RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
- : RefCounted<RegisteredEventListener>(0)
- , m_eventType(eventType)
+ : m_eventType(eventType)
, m_listener(listener)
, m_useCapture(useCapture)
, m_removed(false)
diff --git a/WebCore/dom/StyleElement.cpp b/WebCore/dom/StyleElement.cpp
index 8280880..322808d 100644
--- a/WebCore/dom/StyleElement.cpp
+++ b/WebCore/dom/StyleElement.cpp
@@ -1,6 +1,7 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 2006, 2007 Rob Buis
- * Copyright (C) 2008 Apple, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -17,7 +18,6 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
-
#include "config.h"
#include "StyleElement.h"
@@ -56,13 +56,13 @@ void StyleElement::process(Element* e)
if (!e || !e->inDocument())
return;
- Vector<UChar> text;
+ String text = "";
for (Node* c = e->firstChild(); c; c = c->nextSibling())
if (c->nodeType() == Node::TEXT_NODE || c->nodeType() == Node::CDATA_SECTION_NODE || c->nodeType() == Node::COMMENT_NODE)
- append(text, c->nodeValue());
+ text += c->nodeValue();
- createSheet(e, String::adopt(text));
+ createSheet(e, text);
}
void StyleElement::createSheet(Element* e, const String& text)
@@ -74,9 +74,8 @@ void StyleElement::createSheet(Element* e, const String& text)
m_sheet = 0;
}
- // If type is empty or CSS, this is a CSS style sheet.
- const AtomicString& type = this->type();
- if (type.isEmpty() || (e->isHTMLElement() ? equalIgnoringCase(type, "text/css") : (type == "text/css"))) {
+ String typeValue = e->isHTMLElement() ? type().deprecatedString().lower() : type();
+ if (typeValue.isEmpty() || typeValue == "text/css") { // Type must be empty or CSS
RefPtr<MediaList> mediaList = new MediaList((CSSStyleSheet*)0, media(), e->isHTMLElement());
MediaQueryEvaluator screenEval("screen", true);
MediaQueryEvaluator printEval("print", true);
diff --git a/WebCore/dom/StyledElement.cpp b/WebCore/dom/StyledElement.cpp
index 6d9a7d7..8792ba8 100644
--- a/WebCore/dom/StyledElement.cpp
+++ b/WebCore/dom/StyledElement.cpp
@@ -172,7 +172,7 @@ void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
if (needToParse)
parseMappedAttribute(mappedAttr);
- if (entry == eNone && ownerDocument()->attached() && ownerDocument()->styleSelector()->hasSelectorForAttribute(attr->name().localName()))
+ if (entry == eNone && ownerDocument()->styleSelector()->hasSelectorForAttribute(attr->name().localName()))
setChanged();
if (checkDecl && mappedAttr->decl()) {
@@ -203,7 +203,7 @@ void StyledElement::parseMappedAttribute(MappedAttribute *attr)
if (attr->isNull())
namedAttrMap->setID(nullAtom);
else if (document()->inCompatMode() && !attr->value().impl()->isLower())
- namedAttrMap->setID(AtomicString(attr->value().string().lower()));
+ namedAttrMap->setID(AtomicString(attr->value().domString().lower()));
else
namedAttrMap->setID(attr->value());
}
diff --git a/WebCore/dom/StyledElement.h b/WebCore/dom/StyledElement.h
index 82df0bf..e7766b2 100644
--- a/WebCore/dom/StyledElement.h
+++ b/WebCore/dom/StyledElement.h
@@ -68,8 +68,8 @@ public:
virtual void updateStyleAttributeIfNeeded() const;
virtual const ClassNames* getClassNames() const;
- virtual void attributeChanged(Attribute*, bool preserveDecls = false);
- virtual void parseMappedAttribute(MappedAttribute*);
+ virtual void attributeChanged(Attribute* attr, bool preserveDecls = false);
+ virtual void parseMappedAttribute(MappedAttribute* attr);
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
virtual void createAttributeMap() const;
virtual Attribute* createAttribute(const QualifiedName& name, StringImpl* value);
diff --git a/WebCore/dom/Text.cpp b/WebCore/dom/Text.cpp
index d61214f..0ba7d70 100644
--- a/WebCore/dom/Text.cpp
+++ b/WebCore/dom/Text.cpp
@@ -22,7 +22,6 @@
#include "config.h"
#include "Text.h"
-#include "CString.h"
#include "Document.h"
#include "ExceptionCode.h"
#include "RenderText.h"
@@ -88,100 +87,9 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
return newText.release();
}
-static const Text* earliestLogicallyAdjacentTextNode(const Text* t)
-{
- const Node* n = t;
- while ((n = n->previousSibling())) {
- Node::NodeType type = n->nodeType();
- if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
- t = static_cast<const Text*>(n);
- continue;
- }
-
- // We would need to visit EntityReference child text nodes if they existed
- ASSERT(type != Node::ENTITY_REFERENCE_NODE || !n->hasChildNodes());
- break;
- }
- return t;
-}
-
-static const Text* latestLogicallyAdjacentTextNode(const Text* t)
-{
- const Node* n = t;
- while ((n = n->nextSibling())) {
- Node::NodeType type = n->nodeType();
- if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
- t = static_cast<const Text*>(n);
- continue;
- }
-
- // We would need to visit EntityReference child text nodes if they existed
- ASSERT(type != Node::ENTITY_REFERENCE_NODE || !n->hasChildNodes());
- break;
- }
- return t;
-}
-
-String Text::wholeText() const
-{
- const Text* startText = earliestLogicallyAdjacentTextNode(this);
- const Text* endText = latestLogicallyAdjacentTextNode(this);
-
- Vector<UChar> result;
- Node* onePastEndText = endText->nextSibling();
- for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) {
- if (!n->isTextNode())
- continue;
- const Text* t = static_cast<const Text*>(n);
- const String& data = t->data();
- result.append(data.characters(), data.length());
- }
-
- return String::adopt(result);
-}
-
-PassRefPtr<Text> Text::replaceWholeText(const String& newText, ExceptionCode&)
-{
- // We don't support "read-only" text nodes (no Entity node support)
- // Thus, we remove all adjacent text nodes, and replace the contents of this one.
- ASSERT(!isReadOnlyNode());
- // This method only raises exceptions when dealing with Entity nodes (which we don't support)
-
- // Protect startText and endText against mutation event handlers removing the last ref
- RefPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this));
- RefPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this));
-
- RefPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away
- Node* parent = parentNode(); // Protect against mutation handlers moving this node during traversal
- ExceptionCode ignored = 0;
- for (RefPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) {
- RefPtr<Node> nodeToRemove(n.release());
- n = nodeToRemove->nextSibling();
- parent->removeChild(nodeToRemove.get(), ignored);
- }
-
- if (this != endText) {
- Node* onePastEndText = endText->nextSibling();
- for (RefPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) {
- RefPtr<Node> nodeToRemove(n.release());
- n = nodeToRemove->nextSibling();
- parent->removeChild(nodeToRemove.get(), ignored);
- }
- }
-
- if (newText.isEmpty()) {
- if (parent && parentNode() == parent)
- parent->removeChild(this, ignored);
- return 0;
- }
-
- setData(newText, ignored);
- return protectedThis.release();
-}
-
String Text::nodeName() const
{
- return textAtom.string();
+ return textAtom.domString();
}
Node::NodeType Text::nodeType() const
@@ -323,7 +231,7 @@ void Text::formatForDebugger(char *buffer, unsigned length) const
result += s;
}
- strncpy(buffer, result.utf8().data(), length - 1);
+ strncpy(buffer, result.deprecatedString().latin1(), length - 1);
}
#endif
diff --git a/WebCore/dom/Text.h b/WebCore/dom/Text.h
index e5282d5..c9b73c1 100644
--- a/WebCore/dom/Text.h
+++ b/WebCore/dom/Text.h
@@ -39,10 +39,6 @@ public:
PassRefPtr<Text> splitText(unsigned offset, ExceptionCode&);
- // DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1312295772
- String wholeText() const;
- PassRefPtr<Text> replaceWholeText(const String&, ExceptionCode&);
-
// DOM methods overridden from parent classes
virtual String nodeName() const;
diff --git a/WebCore/dom/Text.idl b/WebCore/dom/Text.idl
index 1b0009d..c0426ea 100644
--- a/WebCore/dom/Text.idl
+++ b/WebCore/dom/Text.idl
@@ -30,10 +30,6 @@ module core {
Text splitText(in [IsIndex] unsigned long offset)
raises (DOMException);
- // Introduced in DOM Level 3:
- readonly attribute DOMString wholeText;
- Text replaceWholeText(in DOMString content)
- raises(DOMException);
};
}
diff --git a/WebCore/dom/Traversal.cpp b/WebCore/dom/Traversal.cpp
index d9dd0a7..5e1aa03 100644
--- a/WebCore/dom/Traversal.cpp
+++ b/WebCore/dom/Traversal.cpp
@@ -1,9 +1,11 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,14 +29,12 @@
#include "Node.h"
#include "NodeFilter.h"
-
-using namespace KJS;
+#include <wtf/PassRefPtr.h>
namespace WebCore {
-Traversal::Traversal(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter, bool expandEntityReferences)
- : RefCounted<Traversal>(0)
- , m_root(rootNode)
+Traversal::Traversal(Node* rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter, bool expandEntityReferences)
+ : m_root(rootNode)
, m_whatToShow(whatToShow)
, m_filter(nodeFilter)
, m_expandEntityReferences(expandEntityReferences)
@@ -45,17 +45,15 @@ Traversal::~Traversal()
{
}
-short Traversal::acceptNode(Node* node, JSValue*& exception) const
+short Traversal::acceptNode(Node* node) const
{
- // FIXME: To handle XML properly we would have to check m_expandEntityReferences.
-
+ // FIXME: If XML is implemented we have to check expandEntityRerefences in this function.
// The bid twiddling here is done to map DOM node types, which are given as integers from
// 1 through 12, to whatToShow bit masks.
- if (!(((1 << (node->nodeType() - 1)) & m_whatToShow)))
- return NodeFilter::FILTER_SKIP;
- if (!m_filter)
- return NodeFilter::FILTER_ACCEPT;
- return m_filter->acceptNode(node, exception);
+ if (node && ((1 << (node->nodeType()-1)) & m_whatToShow))
+ // cast to short silences "enumeral and non-enumeral types in return" warning
+ return m_filter ? m_filter->acceptNode(node) : static_cast<short>(NodeFilter::FILTER_ACCEPT);
+ return NodeFilter::FILTER_SKIP;
}
} // namespace WebCore
diff --git a/WebCore/dom/Traversal.h b/WebCore/dom/Traversal.h
index 78265e0..7611145 100644
--- a/WebCore/dom/Traversal.h
+++ b/WebCore/dom/Traversal.h
@@ -1,9 +1,11 @@
/*
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,14 +27,10 @@
#ifndef Traversal_h
#define Traversal_h
-#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
+#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
-namespace KJS {
- class JSValue;
-}
-
namespace WebCore {
class Node;
@@ -40,7 +38,7 @@ namespace WebCore {
class Traversal : public RefCounted<Traversal> {
public:
- Traversal(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
+ Traversal(Node*, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
virtual ~Traversal();
Node* root() const { return m_root.get(); }
@@ -48,8 +46,7 @@ namespace WebCore {
NodeFilter* filter() const { return m_filter.get(); }
bool expandEntityReferences() const { return m_expandEntityReferences; }
- protected:
- short acceptNode(Node*, KJS::JSValue*& jsException) const;
+ short acceptNode(Node*) const;
private:
RefPtr<Node> m_root;
diff --git a/WebCore/dom/TreeWalker.cpp b/WebCore/dom/TreeWalker.cpp
index 09c1c95..ffa8ae7 100644
--- a/WebCore/dom/TreeWalker.cpp
+++ b/WebCore/dom/TreeWalker.cpp
@@ -1,9 +1,11 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,17 +32,15 @@
#include "NodeFilter.h"
#include <wtf/PassRefPtr.h>
-using namespace KJS;
-
namespace WebCore {
-TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
+TreeWalker::TreeWalker(Node* rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
: Traversal(rootNode, whatToShow, filter, expandEntityReferences)
- , m_current(root())
+ , m_current(rootNode)
{
}
-void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionCode& ec)
+void TreeWalker::setCurrentNode(Node* node, ExceptionCode& ec)
{
if (!node) {
ec = NOT_SUPPORTED_ERR;
@@ -49,237 +49,97 @@ void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionCode& ec)
m_current = node;
}
-inline Node* TreeWalker::setCurrent(PassRefPtr<Node> node)
+void TreeWalker::setCurrentNode(Node* node)
{
- m_current = node;
- return m_current.get();
+ ASSERT(node);
+ int dummy;
+ setCurrentNode(node, dummy);
}
-Node* TreeWalker::parentNode(JSValue*& exception)
+Node* TreeWalker::parentNode()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- while (node != root()) {
- node = node->parentNode();
- if (!node)
- return 0;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
+ for (Node* node = currentNode()->parentNode(); node && (node == root() || node->isDescendantOf(root())); node = node->parentNode()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
+ }
}
return 0;
}
-Node* TreeWalker::firstChild(JSValue*& exception)
+Node* TreeWalker::firstChild()
{
- exception = 0;
- for (RefPtr<Node> node = m_current->firstChild(); node; ) {
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = node.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (node->firstChild()) {
- node = node->firstChild();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
+ for (Node* node = currentNode()->firstChild(); node && (node == root() || node->isDescendantOf(root())); node = node->nextSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- do {
- if (node->nextSibling()) {
- node = node->nextSibling();
- break;
- }
- Node* parent = node->parentNode();
- if (!parent || parent == root() || parent == m_current)
- return 0;
- node = parent;
- } while (node);
}
return 0;
}
-Node* TreeWalker::lastChild(JSValue*& exception)
+Node* TreeWalker::lastChild()
{
- exception = 0;
- for (RefPtr<Node> node = m_current->lastChild(); node; ) {
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = node.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (node->lastChild()) {
- node = node->lastChild();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
+ for (Node* node = currentNode()->lastChild(); node && (node == root() || node->isDescendantOf(root())); node = node->previousSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- do {
- if (node->previousSibling()) {
- node = node->previousSibling();
- break;
- }
- Node* parent = node->parentNode();
- if (!parent || parent == root() || parent == m_current)
- return 0;
- node = parent;
- } while (node);
}
return 0;
}
-Node* TreeWalker::previousSibling(JSValue*& exception)
+Node* TreeWalker::previousSibling()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- if (node == root())
- return 0;
- while (1) {
- for (RefPtr<Node> sibling = node->previousSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(sibling.get(), exception);
- if (exception)
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = sibling.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (sibling->firstChild()) {
- sibling = sibling->firstChild();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
- }
- sibling = sibling->previousSibling();
+ for (Node* node = currentNode()->previousSibling(); node && (node == root() || node->isDescendantOf(root())); node = node->previousSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- node = node->parentNode();
- if (!node || node == root())
- return 0;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return 0;
}
+ return 0;
}
-Node* TreeWalker::nextSibling(JSValue*& exception)
+Node* TreeWalker::nextSibling()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- if (node == root())
- return 0;
- while (1) {
- for (RefPtr<Node> sibling = node->nextSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(sibling.get(), exception);
- if (exception)
- return 0;
- switch (acceptNodeResult) {
- case NodeFilter::FILTER_ACCEPT:
- m_current = sibling.release();
- return m_current.get();
- case NodeFilter::FILTER_SKIP:
- if (sibling->firstChild()) {
- sibling = sibling->firstChild();
- continue;
- }
- break;
- case NodeFilter::FILTER_REJECT:
- break;
- }
- sibling = sibling->nextSibling();
+ for (Node* node = currentNode()->nextSibling(); node && (node == root() || node->isDescendantOf(root())); node = node->nextSibling()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT) {
+ setCurrentNode(node);
+ return node;
}
- node = node->parentNode();
- if (!node || node == root())
- return 0;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return 0;
}
+ return 0;
}
-Node* TreeWalker::previousNode(JSValue*& exception)
+Node* TreeWalker::previousNode()
{
- exception = 0;
- RefPtr<Node> node = m_current;
- while (node != root()) {
- while (Node* previousSibling = node->previousSibling()) {
- node = previousSibling;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_REJECT)
- continue;
- while (Node* lastChild = node->lastChild()) {
- node = lastChild;
- acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- continue;
- }
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT) {
- m_current = node.release();
- return m_current.get();
- }
+ for (Node* node = currentNode()->traversePreviousNode(); node && (node == root() || node->isDescendantOf(root())); node = node->traversePreviousNode()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT && !ancestorRejected(node)) {
+ setCurrentNode(node);
+ return node;
}
- if (node == root())
- return 0;
- Node* parent = node->parentNode();
- if (!parent)
- return 0;
- node = parent;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
}
return 0;
}
-Node* TreeWalker::nextNode(JSValue*& exception)
+Node* TreeWalker::nextNode()
{
- exception = 0;
- RefPtr<Node> node = m_current;
-Children:
- while (Node* firstChild = node->firstChild()) {
- node = firstChild;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
- if (acceptNodeResult == NodeFilter::FILTER_REJECT)
- break;
- }
- while (Node* nextSibling = node->traverseNextSibling(root())) {
- node = nextSibling;
- short acceptNodeResult = acceptNode(node.get(), exception);
- if (exception)
- return 0;
- if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
- return setCurrent(node.release());
- if (acceptNodeResult == NodeFilter::FILTER_SKIP)
- goto Children;
+ for (Node* node = currentNode()->traverseNextNode(); node && (node == root() || node->isDescendantOf(root())); node = node->traverseNextNode()) {
+ if (acceptNode(node) == NodeFilter::FILTER_ACCEPT && !ancestorRejected(node)) {
+ setCurrentNode(node);
+ return node;
+ }
}
return 0;
}
+bool TreeWalker::ancestorRejected(const Node* node) const
+{
+ for (Node* a = node->parentNode(); a && a != root(); a = a->parentNode()) {
+ if (acceptNode(a) == NodeFilter::FILTER_REJECT)
+ return true;
+ }
+ return false;
+}
+
} // namespace WebCore
diff --git a/WebCore/dom/TreeWalker.h b/WebCore/dom/TreeWalker.h
index 8b0ea98..206d8ac 100644
--- a/WebCore/dom/TreeWalker.h
+++ b/WebCore/dom/TreeWalker.h
@@ -1,9 +1,11 @@
/*
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,6 +28,7 @@
#define TreeWalker_h
#include "Traversal.h"
+#include <wtf/RefPtr.h>
namespace WebCore {
@@ -33,30 +36,23 @@ namespace WebCore {
class TreeWalker : public Traversal {
public:
- TreeWalker(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
+ TreeWalker(Node*, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
Node* currentNode() const { return m_current.get(); }
- void setCurrentNode(PassRefPtr<Node>, ExceptionCode&);
-
- Node* parentNode(KJS::JSValue*& exception);
- Node* firstChild(KJS::JSValue*& exception);
- Node* lastChild(KJS::JSValue*& exception);
- Node* previousSibling(KJS::JSValue*& exception);
- Node* nextSibling(KJS::JSValue*& exception);
- Node* previousNode(KJS::JSValue*& exception);
- Node* nextNode(KJS::JSValue*& exception);
+ void setCurrentNode(Node*, ExceptionCode&);
- // For non-JS bindings. Silently ignores the JavaScript exception if any.
- Node* parentNode() { KJS::JSValue* exception; return parentNode(exception); }
- Node* firstChild() { KJS::JSValue* exception; return firstChild(exception); }
- Node* lastChild() { KJS::JSValue* exception; return lastChild(exception); }
- Node* previousSibling() { KJS::JSValue* exception; return previousSibling(exception); }
- Node* nextSibling() { KJS::JSValue* exception; return nextSibling(exception); }
- Node* previousNode() { KJS::JSValue* exception; return previousNode(exception); }
- Node* nextNode() { KJS::JSValue* exception; return nextNode(exception); }
+ Node* parentNode();
+ Node* firstChild();
+ Node* lastChild();
+ Node* previousSibling();
+ Node* nextSibling();
+ Node* previousNode();
+ Node* nextNode();
private:
- Node* setCurrent(PassRefPtr<Node>);
+ // convenience for when it is known there will be no exception
+ void setCurrentNode(Node*);
+ bool ancestorRejected(const Node*) const;
RefPtr<Node> m_current;
};
diff --git a/WebCore/dom/TreeWalker.idl b/WebCore/dom/TreeWalker.idl
index 4f98d3a..bc983c3 100644
--- a/WebCore/dom/TreeWalker.idl
+++ b/WebCore/dom/TreeWalker.idl
@@ -29,13 +29,13 @@ module traversal {
attribute Node currentNode
setter raises(DOMException);
- [Custom] Node parentNode();
- [Custom] Node firstChild();
- [Custom] Node lastChild();
- [Custom] Node previousSibling();
- [Custom] Node nextSibling();
- [Custom] Node previousNode();
- [Custom] Node nextNode();
+ Node parentNode();
+ Node firstChild();
+ Node lastChild();
+ Node previousSibling();
+ Node nextSibling();
+ Node previousNode();
+ Node nextNode();
};
}
diff --git a/WebCore/dom/XMLTokenizer.cpp b/WebCore/dom/XMLTokenizer.cpp
index fe7c95a..7ba424c 100644
--- a/WebCore/dom/XMLTokenizer.cpp
+++ b/WebCore/dom/XMLTokenizer.cpp
@@ -1,6 +1,8 @@
-/*
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006 Apple Computer, Inc.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2007 Trolltech ASA
@@ -42,7 +44,6 @@
#include "HTMLStyleElement.h"
#include "HTMLTokenizer.h"
#include "ProcessingInstruction.h"
-#include "ResourceError.h"
#include "ResourceHandle.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
@@ -54,7 +55,6 @@
#endif
#include <wtf/Platform.h>
#include <wtf/StringExtras.h>
-#include <wtf/Threading.h>
#include <wtf/Vector.h>
#if ENABLE(XSLT)
@@ -340,16 +340,14 @@ public:
// --------------------------------
static int globalDescriptor = 0;
-static DocLoader* globalDocLoader = 0;
-static ThreadIdentifier libxmlLoaderThread = 0;
static int matchFunc(const char* uri)
{
- // Only match loads initiated due to uses of libxml2 from within XMLTokenizer to avoid
- // interfering with client applications that also use libxml2. http://bugs.webkit.org/show_bug.cgi?id=17353
- return globalDocLoader && currentThread() == libxmlLoaderThread;
+ return 1; // Match everything.
}
+static DocLoader* globalDocLoader = 0;
+
class OffsetBuffer {
public:
OffsetBuffer(const Vector<char>& b) : m_buffer(b), m_currentOffset(0) { }
@@ -379,24 +377,15 @@ static bool shouldAllowExternalLoad(const char* inURI)
}
static void* openFunc(const char* uri)
{
- ASSERT(globalDocLoader);
- ASSERT(currentThread() == libxmlLoaderThread);
-
- if (!shouldAllowExternalLoad(uri))
+ if (!globalDocLoader || !shouldAllowExternalLoad(uri))
return &globalDescriptor;
ResourceError error;
ResourceResponse response;
Vector<char> data;
- DocLoader* docLoader = globalDocLoader;
- globalDocLoader = 0;
- // FIXME: We should restore the original global error handler as well.
-
- if (docLoader->frame())
- docLoader->frame()->loader()->loadResourceSynchronously(KURL(uri), error, response, data);
-
- globalDocLoader = docLoader;
+ if (globalDocLoader->frame())
+ globalDocLoader->frame()->loader()->loadResourceSynchronously(KURL(uri), error, response, data);
return new OffsetBuffer(data);
}
@@ -443,7 +432,6 @@ static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* user
xmlInitParser();
xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc);
xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc);
- libxmlLoaderThread = currentThread();
didInit = true;
}
@@ -862,7 +850,7 @@ void XMLTokenizer::endElementNs()
if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE)
scriptCode += static_cast<CharacterData*>(child)->data();
}
- m_view->frame()->loader()->executeScript(m_doc->url().string(), m_scriptStartLine - 1, scriptCode);
+ m_view->frame()->loader()->executeScript(m_doc->url(), m_scriptStartLine - 1, scriptCode);
}
m_requestingScript = false;
@@ -1009,8 +997,11 @@ void XMLTokenizer::internalSubset(const xmlChar* name, const xmlChar* externalID
return;
}
- if (m_doc)
- m_doc->addChild(new DocumentType(m_doc, toString(name), toString(externalID), toString(systemID)));
+ Document* doc = m_doc;
+ if (!doc)
+ return;
+
+ doc->setDocType(new DocumentType(doc, toString(name), toString(externalID), toString(systemID)));
}
static inline XMLTokenizer* getTokenizer(void* closure)
@@ -1288,7 +1279,7 @@ void XMLTokenizer::end()
{
#if ENABLE(XSLT)
if (m_sawXSLTransform) {
- m_doc->setTransformSource(xmlDocPtrForString(m_doc->docLoader(), m_originalSourceForTransform, m_doc->url().string()));
+ m_doc->setTransformSource(xmlDocPtrForString(m_doc->docLoader(), m_originalSourceForTransform, m_doc->url()));
m_doc->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
m_doc->updateStyleSelector();
@@ -1437,7 +1428,7 @@ bool XMLTokenizer::isWaitingForScripts() const
}
#if ENABLE(XSLT)
-void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const String& url)
+void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const DeprecatedString& url)
{
if (source.isEmpty())
return 0;
@@ -1456,7 +1447,7 @@ void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const Strin
xmlDocPtr sourceDoc = xmlReadMemory(reinterpret_cast<const char*>(source.characters()),
source.length() * sizeof(UChar),
- url.latin1().data(),
+ url.ascii(),
BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE",
XSLT_PARSE_OPTIONS);
@@ -1935,7 +1926,7 @@ void XMLTokenizer::parseEndElement()
if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE)
scriptCode += static_cast<CharacterData*>(child)->data();
}
- m_view->frame()->loader()->executeScript(m_doc->url().string(), m_scriptStartLine - 1, scriptCode);
+ m_view->frame()->loader()->executeScript(m_doc->url(), m_scriptStartLine - 1, scriptCode);
}
m_requestingScript = false;
}
@@ -2096,7 +2087,7 @@ void XMLTokenizer::parseDtd()
setIsXHTMLDocument(true); // controls if we replace entities or not.
}
if (!m_parsingFragment)
- m_doc->addChild(new DocumentType(m_doc, name, publicId, systemId));
+ m_doc->setDocType(new DocumentType(m_doc, name, publicId, systemId));
}
#endif
diff --git a/WebCore/dom/XMLTokenizer.h b/WebCore/dom/XMLTokenizer.h
index e754e84..d7dff71 100644
--- a/WebCore/dom/XMLTokenizer.h
+++ b/WebCore/dom/XMLTokenizer.h
@@ -1,6 +1,8 @@
/*
+ * This file is part of the DOM implementation for KDE.
+ *
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006 Apple Computer, Inc.
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2007 Trolltech ASA
*
@@ -24,6 +26,115 @@
#ifndef XMLTokenizer_h
#define XMLTokenizer_h
+#if USE(EXPAT)
+
+#include "CachedResourceClient.h"
+#include "SegmentedString.h"
+#include "StringHash.h"
+#include "Tokenizer.h"
+#include <libexpat/expat.h>
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+ class Node;
+ class CachedScript;
+ class DocumentFragment;
+ class Document;
+ class Element;
+ class FrameView;
+ class PendingCallbacks;
+
+ class XMLTokenizer : public Tokenizer, public CachedResourceClient {
+ public:
+ XMLTokenizer(Document *, FrameView * = 0);
+ XMLTokenizer(DocumentFragment *, Element *);
+ ~XMLTokenizer();
+
+ enum ErrorType { warning, nonFatal, fatal };
+
+ // from Tokenizer
+ virtual bool write(const SegmentedString &str, bool);
+ virtual void finish();
+ virtual bool isWaitingForScripts() const;
+ virtual void stopParsing();
+ virtual bool wellFormed() const { return !m_sawError; }
+ virtual int lineNumber() const;
+ virtual int columnNumber() const;
+
+ // from CachedObjectClient
+ virtual void notifyFinished(CachedResource *finishedObj);
+
+ // callbacks from parser expat
+ void startElementNs(const XML_Char *name, const XML_Char **atts);
+ void endElementNs();
+ void characters(const XML_Char *s, int len);
+ void processingInstruction(const XML_Char *target, const XML_Char *data);
+ void comment(const XML_Char *s);
+ void startCdata();
+ void endCdata();
+
+ void error(ErrorType type, const char* m, int lineNumber, int columnNumber);
+
+ // utilities
+ XML_Parser getXMLParser() const { return m_parser; }
+ void setXMLParser(XML_Parser parser) { m_parser = parser; }
+
+ private:
+ void setCurrentNode(Node*);
+
+ void end();
+
+ void pauseParsing();
+ void resumeParsing();
+
+ void reportError();
+ void insertErrorMessageBlock();
+
+ bool enterText();
+ void exitText();
+
+ Document *m_doc;
+ FrameView *m_view;
+
+ XML_Parser m_parser;
+
+ Node *m_currentNode;
+ bool m_currentNodeIsReferenced;
+
+ bool m_sawError;
+ bool m_sawXSLTransform;
+ bool m_sawFirstElement;
+
+ bool m_parserPaused;
+ bool m_requestingScript;
+ bool m_finishCalled;
+
+ int m_errorCount;
+ String m_errorMessages;
+
+ CachedScript *m_pendingScript;
+ RefPtr<Element> m_scriptElement;
+ int m_scriptStartLine;
+
+ bool m_parsingFragment;
+ String m_defaultNamespaceURI;
+
+ typedef HashMap<String, String> PrefixForNamespaceMap;
+ PrefixForNamespaceMap m_prefixToNamespaceMap;
+
+ OwnPtr<PendingCallbacks> m_pendingCallbacks;
+ SegmentedString m_pendingSrc;
+ };
+
+HashMap<String, String> parseAttributes(const String&, bool& attrsOK);
+bool parseXMLDocumentFragment(const String&, DocumentFragment*, Element* parent = 0);
+
+} // namespace WebCore
+
+#else // USE(EXPAT)
+
#include "CachedResourceClient.h"
#include "SegmentedString.h"
#include "StringHash.h"
@@ -168,7 +279,7 @@ namespace WebCore {
};
#if ENABLE(XSLT)
-void* xmlDocPtrForString(DocLoader*, const String& source, const String& url);
+void* xmlDocPtrForString(DocLoader*, const String& source, const DeprecatedString& url);
void setLoaderForLibXMLCallbacks(DocLoader*);
#endif
@@ -177,4 +288,6 @@ bool parseXMLDocumentFragment(const String&, DocumentFragment*, Element* parent
} // namespace WebCore
+#endif // USE(EXPAT)
+
#endif // XMLTokenizer_h
diff --git a/WebCore/dom/xml_expat_tokenizer.cpp b/WebCore/dom/xml_expat_tokenizer.cpp
new file mode 100644
index 0000000..cf9ab93
--- /dev/null
+++ b/WebCore/dom/xml_expat_tokenizer.cpp
@@ -0,0 +1,1025 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 2000 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "XMLTokenizer.h"
+
+#include "CDATASection.h"
+#include "CachedScript.h"
+#include "Comment.h"
+#include "CString.h"
+#include "DocLoader.h"
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameView.h"
+#include "HTMLNames.h"
+#include "HTMLScriptElement.h"
+#include "HTMLTableSectionElement.h"
+#include "HTMLTokenizer.h"
+#include "ProcessingInstruction.h"
+#include "EventNames.h"
+
+// strndup is not available everywhere, so here is a portable version <reed>
+static char* portable_strndup(const char src[], size_t len)
+{
+ char* origDst = (char*)malloc(len + 1);
+ if (NULL == origDst)
+ return NULL;
+
+ char* dst = origDst;
+ while (len-- > 0) {
+ if ((*dst++ = *src++) == 0)
+ return origDst;
+ }
+ *dst = 0;
+ return origDst;
+}
+
+namespace WebCore {
+
+using namespace EventNames;
+using namespace HTMLNames;
+
+const int maxErrors = 25;
+
+class PendingCallbacks {
+public:
+ PendingCallbacks() {
+ m_callbacks.setAutoDelete(true);
+ }
+
+ void appendStartElementNSCallback(const XML_Char* name, const XML_Char** atts) {
+ PendingStartElementNSCallback* callback = new PendingStartElementNSCallback;
+
+ callback->name = strdup(name);
+ callback->count = 0;
+ while (atts[callback->count])
+ callback->count++;
+ callback->atts = (XML_Char**)malloc(sizeof(XML_Char*) * (callback->count+1));
+ for (int i=0; i<callback->count; i++)
+ callback->atts[i] = strdup(atts[i]);
+ callback->atts[callback->count] = NULL;
+
+ m_callbacks.append(callback);
+ }
+
+ void appendEndElementNSCallback() {
+ PendingEndElementNSCallback* callback = new PendingEndElementNSCallback;
+
+ m_callbacks.append(callback);
+ }
+
+ void appendCharactersCallback(const XML_Char* s, int len) {
+ PendingCharactersCallback* callback = new PendingCharactersCallback;
+
+ callback->s = portable_strndup(s, len);
+ callback->len = len;
+
+ m_callbacks.append(callback);
+ }
+
+ void appendProcessingInstructionCallback(const XML_Char* target, const XML_Char* data) {
+ PendingProcessingInstructionCallback* callback = new PendingProcessingInstructionCallback;
+
+ callback->target = strdup(target);
+ callback->data = strdup(data);
+
+ m_callbacks.append(callback);
+ }
+
+ void appendStartCDATABlockCallback() {
+ PendingStartCDATABlockCallback* callback = new PendingStartCDATABlockCallback;
+
+ m_callbacks.append(callback);
+ }
+
+ void appendEndCDATABlockCallback() {
+ PendingEndCDATABlockCallback* callback = new PendingEndCDATABlockCallback;
+
+ m_callbacks.append(callback);
+ }
+
+ void appendCommentCallback(const XML_Char* s) {
+ PendingCommentCallback* callback = new PendingCommentCallback;
+
+ callback->s = strdup(s);
+
+ m_callbacks.append(callback);
+ }
+
+ void appendErrorCallback(XMLTokenizer::ErrorType type, const char* message, int lineNumber, int columnNumber) {
+ PendingErrorCallback* callback = new PendingErrorCallback;
+
+ callback->message = strdup(message);
+ callback->type = type;
+ callback->lineNumber = lineNumber;
+ callback->columnNumber = columnNumber;
+
+ m_callbacks.append(callback);
+ }
+
+ void callAndRemoveFirstCallback(XMLTokenizer* tokenizer) {
+ PendingCallback* cb = m_callbacks.getFirst();
+
+ cb->call(tokenizer);
+ m_callbacks.removeFirst();
+ }
+
+ bool isEmpty() const { return m_callbacks.isEmpty(); }
+
+private:
+ struct PendingCallback {
+
+ virtual ~PendingCallback() { }
+
+ virtual void call(XMLTokenizer* tokenizer) = 0;
+ };
+
+ struct PendingStartElementNSCallback : public PendingCallback {
+ virtual ~PendingStartElementNSCallback() {
+ free(name);
+ for (int i=0; i<count; i++)
+ free(atts[i]);
+ free(atts);
+ }
+
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->startElementNs(name, (const XML_Char**)(atts));
+ }
+
+ XML_Char* name;
+ int count;
+ XML_Char** atts;
+ };
+
+ struct PendingEndElementNSCallback : public PendingCallback {
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->endElementNs();
+ }
+ };
+
+ struct PendingCharactersCallback : public PendingCallback {
+ virtual ~PendingCharactersCallback() {
+ free(s);
+ }
+
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->characters(s, len);
+ }
+
+ XML_Char* s;
+ int len;
+ };
+
+ struct PendingProcessingInstructionCallback : public PendingCallback {
+ virtual ~PendingProcessingInstructionCallback() {
+ free(target);
+ free(data);
+ }
+
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->processingInstruction(target, data);
+ }
+
+ XML_Char* target;
+ XML_Char* data;
+ };
+
+ struct PendingStartCDATABlockCallback : public PendingCallback {
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->startCdata();
+ }
+ };
+
+ struct PendingEndCDATABlockCallback : public PendingCallback {
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->endCdata();
+ }
+ };
+
+ struct PendingCommentCallback : public PendingCallback {
+ virtual ~PendingCommentCallback() {
+ free(s);
+ }
+
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->comment(s);
+ }
+
+ XML_Char* s;
+ };
+
+ struct PendingErrorCallback: public PendingCallback {
+ virtual ~PendingErrorCallback() {
+ free (message);
+ }
+
+ virtual void call(XMLTokenizer* tokenizer) {
+ tokenizer->error(type, message, lineNumber, columnNumber);
+ }
+
+ XMLTokenizer::ErrorType type;
+ char* message;
+ int lineNumber;
+ int columnNumber;
+ };
+
+public:
+ DeprecatedPtrList<PendingCallback> m_callbacks;
+};
+
+// --------------------------------
+
+XMLTokenizer::XMLTokenizer(Document *_doc, FrameView *_view)
+ : m_doc(_doc)
+ , m_view(_view)
+ , m_parser(0)
+ , m_currentNode(_doc)
+ , m_currentNodeIsReferenced(false)
+ , m_sawError(false)
+ , m_sawXSLTransform(false)
+ , m_sawFirstElement(false)
+ , m_parserPaused(false)
+ , m_requestingScript(false)
+ , m_finishCalled(false)
+ , m_errorCount(0)
+ , m_pendingScript(0)
+ , m_scriptStartLine(0)
+ , m_parsingFragment(false)
+ , m_pendingCallbacks(new PendingCallbacks)
+{
+}
+
+XMLTokenizer::XMLTokenizer(DocumentFragment *fragment, Element *parentElement)
+ : m_doc(fragment->document())
+ , m_view(0)
+ , m_parser(0)
+ , m_currentNode(fragment)
+ , m_currentNodeIsReferenced(fragment)
+ , m_sawError(false)
+ , m_sawXSLTransform(false)
+ , m_sawFirstElement(false)
+ , m_parserPaused(false)
+ , m_requestingScript(false)
+ , m_finishCalled(false)
+ , m_errorCount(0)
+ , m_pendingScript(0)
+ , m_scriptStartLine(0)
+ , m_parsingFragment(true)
+ , m_pendingCallbacks(new PendingCallbacks)
+{
+ if (fragment)
+ fragment->ref();
+ if (m_doc)
+ m_doc->ref();
+
+ // Add namespaces based on the parent node
+ Vector<Element*> elemStack;
+ while (parentElement) {
+ elemStack.append(parentElement);
+
+ Node* n = parentElement->parentNode();
+ if (!n || !n->isElementNode())
+ break;
+ parentElement = static_cast<Element*>(n);
+ }
+
+ if (elemStack.isEmpty())
+ return;
+
+ for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
+ if (NamedAttrMap* attrs = element->attributes()) {
+ for (unsigned i = 0; i < attrs->length(); i++) {
+ Attribute* attr = attrs->attributeItem(i);
+ if (attr->localName() == "xmlns")
+ m_defaultNamespaceURI = attr->value();
+ else if (attr->prefix() == "xmlns")
+ m_prefixToNamespaceMap.set(attr->localName(), attr->value());
+ }
+ }
+ }
+}
+
+XMLTokenizer::~XMLTokenizer()
+{
+ setCurrentNode(0);
+ if (m_parsingFragment && m_doc)
+ m_doc->deref();
+ if (m_pendingScript)
+ m_pendingScript->deref(this);
+}
+
+void XMLTokenizer::setCurrentNode(Node* n)
+{
+ bool nodeNeedsReference = n && n != m_doc;
+ if (nodeNeedsReference)
+ n->ref();
+ if (m_currentNodeIsReferenced)
+ m_currentNode->deref();
+ m_currentNode = n;
+ m_currentNodeIsReferenced = nodeNeedsReference;
+}
+
+// use space instead of ':' as separator because ':' can be inside an uri
+const XML_Char tripletSep=' ';
+
+inline DeprecatedString toQString(const XML_Char* str, unsigned int len)
+{
+ return DeprecatedString::fromUtf8(reinterpret_cast<const char *>(str), len);
+}
+
+inline DeprecatedString toQString(const XML_Char* str)
+{
+ return DeprecatedString::fromUtf8(str ? reinterpret_cast<const char *>(str) : "");
+}
+
+// triplet is formatted as URI + sep + local_name + sep + prefix.
+static inline void splitTriplet(const XML_Char *name, String &uri, String &localname, String &prefix)
+{
+ String string[3];
+ int found = 0;
+ const char *start = reinterpret_cast<const char *>(name);
+
+ while(start && (found < 3)) {
+ char *next = strchr(start, tripletSep);
+ if (next) {
+ string[found++] = toQString(start, (next-start));
+ start = next+1;
+ } else {
+ string[found++] = toQString(start);
+ break;
+ }
+ }
+
+ switch(found) {
+ case 1:
+ localname = string[0];
+ break;
+ case 2:
+ uri = string[0];
+ localname = string[1];
+ break;
+ case 3:
+ uri = string[0];
+ localname = string[1];
+ prefix = string[2];
+ break;
+ }
+}
+
+static inline void handleElementNamespaces(Element *newElement, const String &uri, const String &prefix, ExceptionCode &exceptioncode)
+{
+ if (uri.isEmpty())
+ return;
+
+ String namespaceQName("xmlns");
+ if(!prefix.isEmpty())
+ namespaceQName += String(":")+ prefix;
+ newElement->setAttributeNS(String("http://www.w3.org/2000/xmlns/"), namespaceQName, uri, exceptioncode);
+}
+
+static inline void handleElementAttributes(Element *newElement, const XML_Char **atts, ExceptionCode &exceptioncode)
+{
+ for (int i = 0; atts[i]; i += 2) {
+ String attrURI, attrLocalName, attrPrefix;
+ splitTriplet(atts[i], attrURI, attrLocalName, attrPrefix);
+ String attrQName = attrPrefix.isEmpty() ? attrLocalName : attrPrefix + String(":") + attrLocalName;
+ String attrValue = toQString(atts[i+1]);
+ newElement->setAttributeNS(attrURI, attrQName, attrValue, exceptioncode);
+ if (exceptioncode) // exception while setting attributes
+ return;
+ }
+}
+
+void XMLTokenizer::startElementNs(const XML_Char *name, const XML_Char **atts)
+{
+ if (m_parserStopped)
+ return;
+
+ if (m_parserPaused) {
+ m_pendingCallbacks->appendStartElementNSCallback(name, atts);
+ return;
+ }
+
+ m_sawFirstElement = true;
+
+ exitText();
+
+ String uri, localName, prefix;
+ splitTriplet(name, uri, localName, prefix);
+ String qName = prefix.isEmpty() ? localName : prefix + ":" + localName;
+
+ if (m_parsingFragment && uri.isEmpty()) {
+ if (!prefix.isEmpty())
+ uri = String(m_prefixToNamespaceMap.get(prefix.impl()));
+ else
+ uri = m_defaultNamespaceURI;
+ }
+
+ ExceptionCode ec = 0;
+ RefPtr<Element> newElement = m_doc->createElementNS(uri, qName, ec);
+ if (!newElement) {
+ stopParsing();
+ return;
+ }
+
+ handleElementNamespaces(newElement.get(), uri, prefix, ec);
+ if (ec) {
+ stopParsing();
+ return;
+ }
+
+ handleElementAttributes(newElement.get(), atts, ec);
+ if (ec) {
+ stopParsing();
+ return;
+ }
+
+ if (newElement->hasTagName(scriptTag))
+ static_cast<HTMLScriptElement*>(newElement.get())->setCreatedByParser(true);
+
+ if (newElement->hasTagName(HTMLNames::scriptTag))
+ m_scriptStartLine = lineNumber();
+
+ if (!m_currentNode->addChild(newElement.get())) {
+ stopParsing();
+ return;
+ }
+
+ setCurrentNode(newElement.get());
+ if (m_view && !newElement->attached())
+ newElement->attach();
+}
+
+void XMLTokenizer::endElementNs()
+{
+ if (m_parserStopped)
+ return;
+
+ if (m_parserPaused) {
+ m_pendingCallbacks->appendEndElementNSCallback();
+ return;
+ }
+
+ exitText();
+
+ Node* n = m_currentNode;
+ RefPtr<Node> parent = n->parentNode();
+ n->finishedParsing();
+
+ // don't load external scripts for standalone documents (for now)
+ if (n->isElementNode() && m_view && static_cast<Element*>(n)->hasTagName(scriptTag)) {
+ ASSERT(!m_pendingScript);
+
+ m_requestingScript = true;
+
+ Element* scriptElement = static_cast<Element*>(n);
+ String scriptHref;
+
+ if (static_cast<Element*>(n)->hasTagName(scriptTag))
+ scriptHref = scriptElement->getAttribute(srcAttr);
+
+ if (!scriptHref.isEmpty()) {
+ // we have a src attribute
+ const AtomicString& charset = scriptElement->getAttribute(charsetAttr);
+ if ((m_pendingScript = m_doc->docLoader()->requestScript(scriptHref, charset))) {
+ m_scriptElement = scriptElement;
+ m_pendingScript->ref(this);
+
+ // m_pendingScript will be 0 if script was already loaded and ref() executed it
+ if (m_pendingScript)
+ pauseParsing();
+ } else
+ m_scriptElement = 0;
+
+ } else {
+ String scriptCode = "";
+ for (Node* child = scriptElement->firstChild(); child; child = child->nextSibling()) {
+ if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE)
+ scriptCode += static_cast<CharacterData*>(child)->data();
+ }
+ m_view->frame()->loader()->executeScript(m_doc->URL(), m_scriptStartLine - 1, scriptCode);
+ }
+
+ m_requestingScript = false;
+ }
+
+ setCurrentNode(parent.get());
+}
+
+void XMLTokenizer::characters(const XML_Char *s, int len)
+{
+ if (m_parserStopped)
+ return;
+
+ if (m_parserPaused) {
+ m_pendingCallbacks->appendCharactersCallback(s, len);
+ return;
+ }
+
+ if (m_currentNode->isTextNode() || enterText()) {
+ ExceptionCode ec = 0;
+ static_cast<Text*>(m_currentNode)->appendData(toQString(s, len), ec);
+ }
+}
+
+bool XMLTokenizer::enterText()
+{
+ RefPtr<Node> newNode = new Text(m_doc, "");
+ if (!m_currentNode->addChild(newNode.get()))
+ return false;
+ setCurrentNode(newNode.get());
+ return true;
+}
+
+void XMLTokenizer::exitText()
+{
+ if (m_parserStopped)
+ return;
+
+ if (!m_currentNode || !m_currentNode->isTextNode())
+ return;
+
+ if (m_view && m_currentNode && !m_currentNode->attached())
+ m_currentNode->attach();
+
+ // FIXME: What's the right thing to do if the parent is really 0?
+ // Just leaving the current node set to the text node doesn't make much sense.
+ if (Node* par = m_currentNode->parentNode())
+ setCurrentNode(par);
+}
+
+void XMLTokenizer::processingInstruction(const XML_Char *target, const XML_Char *data)
+{
+ if (m_parserStopped)
+ return;
+
+ if (m_parserPaused) {
+ m_pendingCallbacks->appendProcessingInstructionCallback(target, data);
+ return;
+ }
+
+ exitText();
+
+ // ### handle exceptions
+ int exception = 0;
+ RefPtr<ProcessingInstruction> pi = m_doc->createProcessingInstruction(
+ toQString(target), toQString(data), exception);
+ if (exception)
+ return;
+
+ if (!m_currentNode->addChild(pi.get()))
+ return;
+ if (m_view && !pi->attached())
+ pi->attach();
+
+ // don't load stylesheets for standalone documents
+ if (m_doc->frame()) {
+ m_sawXSLTransform = !m_sawFirstElement && !pi->checkStyleSheet();
+ if (m_sawXSLTransform)
+ stopParsing();
+ }
+}
+
+void XMLTokenizer::comment(const XML_Char *s)
+{
+ if (m_parserStopped)
+ return;
+
+ if (m_parserPaused) {
+ m_pendingCallbacks->appendCommentCallback(s);
+ return;
+ }
+
+ exitText();
+
+ RefPtr<Node> newNode = m_doc->createComment(toQString(s));
+ m_currentNode->addChild(newNode.get());
+ if (m_view && !newNode->attached())
+ newNode->attach();
+}
+
+void XMLTokenizer::startCdata()
+{
+ if (m_parserStopped)
+ return;
+
+ if (m_parserPaused) {
+ m_pendingCallbacks->appendStartCDATABlockCallback();
+ return;
+ }
+
+ exitText();
+
+ RefPtr<Node> newNode = new CDATASection(m_doc, "");
+ if (!m_currentNode->addChild(newNode.get()))
+ return;
+ if (m_view && !newNode->attached())
+ newNode->attach();
+ setCurrentNode(newNode.get());
+}
+
+void XMLTokenizer::endCdata()
+{
+ if (m_parserStopped)
+ return;
+
+ if (m_parserPaused) {
+ m_pendingCallbacks->appendEndCDATABlockCallback();
+ return;
+ }
+
+ if (m_currentNode->parentNode() != 0)
+ setCurrentNode(m_currentNode->parentNode());
+}
+
+static void XMLCALL startElementHandler(void *userdata, const XML_Char *name, const XML_Char **atts)
+{
+ XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
+ tokenizer->startElementNs(name, atts);
+}
+
+static void XMLCALL endElementHandler(void *userdata, const XML_Char *name)
+{
+ XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
+ tokenizer->endElementNs();
+}
+
+static void charactersHandler(void *userdata, const XML_Char *s, int len)
+{
+ XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
+ tokenizer->characters(s, len);
+}
+
+static void processingInstructionHandler(void *userdata, const XML_Char *target, const XML_Char *data)
+{
+ XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
+ tokenizer->processingInstruction(target, data);
+}
+
+static void commentHandler(void *userdata, const XML_Char *comment)
+{
+ XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
+ tokenizer->comment(comment);
+}
+
+static void startCdataHandler(void *userdata)
+{
+ XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
+ tokenizer->startCdata();
+}
+
+static void endCdataHandler(void *userdata)
+{
+ XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
+ tokenizer->endCdata();
+}
+
+static int unknownEncodingHandler(void *userdata, const XML_Char *name, XML_Encoding *info)
+{
+ // Expat doesn't like latin1 so we have to build this map
+ // to do conversion correctly.
+ // FIXME: Create a wrapper for expat that looks like libxml.
+ if (strcasecmp(name, "latin1") == 0)
+ {
+ for (int i=0; i<256; i++) {
+ info->map[i] = i;
+ }
+ return XML_STATUS_OK;
+ }
+ return XML_STATUS_ERROR;
+}
+
+bool XMLTokenizer::write(const SegmentedString&s, bool /*appendData*/ )
+{
+ String parseString = s.toString();
+
+ if (m_parserStopped || m_sawXSLTransform)
+ return false;
+
+ if (m_parserPaused) {
+ m_pendingSrc.append(s);
+ return false;
+ }
+
+ if (!m_parser) {
+ static const UChar BOM = 0xFEFF;
+ static const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
+ m_parser = XML_ParserCreateNS(BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", tripletSep);
+ XML_SetUserData(m_parser, (void *)this);
+ XML_SetReturnNSTriplet(m_parser, true);
+
+ XML_SetStartElementHandler(m_parser, startElementHandler);
+ XML_SetEndElementHandler(m_parser, endElementHandler);
+ XML_SetCharacterDataHandler(m_parser, charactersHandler);
+ XML_SetProcessingInstructionHandler(m_parser, processingInstructionHandler);
+ XML_SetCommentHandler(m_parser, commentHandler);
+ XML_SetStartCdataSectionHandler(m_parser, startCdataHandler);
+ XML_SetEndCdataSectionHandler(m_parser, endCdataHandler);
+ XML_SetUnknownEncodingHandler(m_parser, unknownEncodingHandler, NULL);
+ }
+
+ enum XML_Status result = XML_Parse(m_parser, (const char*)parseString.characters(), sizeof(UChar) * parseString.length(), false);
+ if (result == XML_STATUS_ERROR) {
+ reportError();
+ return false;
+ }
+
+ return true;
+}
+
+void XMLTokenizer::end()
+{
+ if (m_parser) {
+ XML_Parse(m_parser, 0, 0, true);
+ XML_ParserFree(m_parser);
+ m_parser = 0;
+ }
+
+ if (m_sawError)
+ insertErrorMessageBlock();
+ else {
+ exitText();
+ m_doc->updateStyleSelector();
+ }
+
+ setCurrentNode(0);
+ m_doc->finishedParsing();
+}
+
+void XMLTokenizer::finish()
+{
+ if (m_parserPaused)
+ m_finishCalled = true;
+ else
+ end();
+}
+
+void XMLTokenizer::reportError()
+{
+ ErrorType type = nonFatal;
+ enum XML_Error code = XML_GetErrorCode(m_parser);
+ switch (code) {
+ case XML_ERROR_NO_MEMORY:
+ type = fatal;
+ break;
+ case XML_ERROR_FINISHED:
+ type = warning;
+ break;
+ default:
+ type = nonFatal;
+ }
+ error(type, XML_ErrorString(code), lineNumber(), columnNumber());
+}
+
+void XMLTokenizer::error(ErrorType type, const char* m, int lineNumber, int columnNumber)
+{
+ if (type == fatal || m_errorCount < maxErrors) {
+ switch (type) {
+ case warning:
+ m_errorMessages += String::format("warning on line %d at column %d: %s", lineNumber, columnNumber, m);
+ break;
+ case fatal:
+ case nonFatal:
+ m_errorMessages += String::format("error on line %d at column %d: %s", lineNumber, columnNumber, m);
+ }
+ ++m_errorCount;
+ }
+
+ if (type != warning)
+ m_sawError = true;
+
+ if (type == fatal)
+ stopParsing();
+}
+
+static inline RefPtr<Element> createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
+{
+ ExceptionCode ec = 0;
+ RefPtr<Element> reportElement = doc->createElementNS(xhtmlNamespaceURI, "parsererror", ec);
+ reportElement->setAttribute(styleAttr, "display:block; pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black");
+
+ RefPtr<Element> h3 = doc->createElementNS(xhtmlNamespaceURI, "h3", ec);
+ reportElement->appendChild(h3.get(), ec);
+ h3->appendChild(doc->createTextNode("This page contains the following errors:"), ec);
+
+ RefPtr<Element> fixed = doc->createElementNS(xhtmlNamespaceURI, "div", ec);
+ reportElement->appendChild(fixed.get(), ec);
+ fixed->setAttribute(styleAttr, "font-family:monospace;font-size:12px");
+ fixed->appendChild(doc->createTextNode(errorMessages), ec);
+
+ h3 = doc->createElementNS(xhtmlNamespaceURI, "h3", ec);
+ reportElement->appendChild(h3.get(), ec);
+ h3->appendChild(doc->createTextNode("Below is a rendering of the page up to the first error."), ec);
+
+ return reportElement;
+}
+
+void XMLTokenizer::insertErrorMessageBlock()
+{
+ // One or more errors occurred during parsing of the code. Display an error block to the user above
+ // the normal content (the DOM tree is created manually and includes line/col info regarding
+ // where the errors are located)
+
+ // Create elements for display
+ ExceptionCode ec = 0;
+ Document* doc = m_doc;
+ Node* documentElement = doc->documentElement();
+ if (!documentElement) {
+ RefPtr<Node> rootElement = doc->createElementNS(xhtmlNamespaceURI, "html", ec);
+ doc->appendChild(rootElement, ec);
+ RefPtr<Node> body = doc->createElementNS(xhtmlNamespaceURI, "body", ec);
+ rootElement->appendChild(body, ec);
+ documentElement = body.get();
+ }
+
+ RefPtr<Element> reportElement = createXHTMLParserErrorHeader(doc, m_errorMessages);
+ documentElement->insertBefore(reportElement, documentElement->firstChild(), ec);
+ doc->updateRendering();
+}
+
+void XMLTokenizer::notifyFinished(CachedResource *finishedObj)
+{
+ ASSERT(m_pendingScript == finishedObj);
+
+ String cachedScriptUrl = m_pendingScript->url();
+ String scriptSource = m_pendingScript->script();
+ bool errorOccurred = m_pendingScript->errorOccurred();
+ m_pendingScript->deref(this);
+ m_pendingScript = 0;
+
+ RefPtr<Element> e = m_scriptElement;
+ m_scriptElement = 0;
+
+ if (errorOccurred)
+ EventTargetNodeCast(e.get())->dispatchHTMLEvent(errorEvent, true, false);
+ else {
+ m_view->frame()->loader()->executeScript(cachedScriptUrl, 0, scriptSource);
+ EventTargetNodeCast(e.get())->dispatchHTMLEvent(loadEvent, false, false);
+ }
+
+ m_scriptElement = 0;
+
+ if (!m_requestingScript)
+ resumeParsing();
+}
+
+bool XMLTokenizer::isWaitingForScripts() const
+{
+ return m_pendingScript != 0;
+}
+
+Tokenizer *newXMLTokenizer(Document *d, FrameView *v)
+{
+ return new XMLTokenizer(d, v);
+}
+
+int XMLTokenizer::lineNumber() const
+{
+ return XML_GetCurrentLineNumber(m_parser);
+}
+
+int XMLTokenizer::columnNumber() const
+{
+ return XML_GetCurrentColumnNumber(m_parser);
+}
+
+void XMLTokenizer::stopParsing()
+{
+ Tokenizer::stopParsing();
+ if (m_parser)
+ XML_StopParser(m_parser, 0);
+}
+
+void XMLTokenizer::pauseParsing()
+{
+ if (m_parsingFragment)
+ return;
+
+ m_parserPaused = true;
+}
+
+void XMLTokenizer::resumeParsing()
+{
+ ASSERT(m_parserPaused);
+
+ m_parserPaused = false;
+
+ // First, execute any pending callbacks
+ while (!m_pendingCallbacks->isEmpty()) {
+ m_pendingCallbacks->callAndRemoveFirstCallback(this);
+
+ // A callback paused the parser
+ if (m_parserPaused)
+ return;
+ }
+
+ // Then, write any pending data
+ SegmentedString rest = m_pendingSrc;
+ m_pendingSrc.clear();
+ write(rest, false);
+
+ // Finally, if finish() has been called and write() didn't result
+ // in any further callbacks being queued, call end()
+ if (m_finishCalled && m_pendingCallbacks->isEmpty())
+ end();
+}
+
+// --------------------------------
+
+bool parseXMLDocumentFragment(const String &string, DocumentFragment *fragment, Element *parent)
+{
+ XMLTokenizer tokenizer(fragment, parent);
+
+ XML_Parser parser = XML_ParserCreateNS(NULL, tripletSep);
+ tokenizer.setXMLParser(parser);
+
+ XML_SetUserData(parser, (void *)&tokenizer);
+ XML_SetReturnNSTriplet(parser, true);
+
+ XML_SetStartElementHandler(parser, startElementHandler);
+ XML_SetEndElementHandler(parser, endElementHandler);
+ XML_SetCharacterDataHandler(parser, charactersHandler);
+ XML_SetProcessingInstructionHandler(parser, processingInstructionHandler);
+ XML_SetCommentHandler(parser, commentHandler);
+ XML_SetStartCdataSectionHandler(parser, startCdataHandler);
+ XML_SetEndCdataSectionHandler(parser, endCdataHandler);
+
+ CString cString = string.utf8();
+ int result = XML_Parse(parser, cString.data(), cString.length(), true);
+
+ XML_ParserFree(parser);
+ tokenizer.setXMLParser(0);
+
+ return result != XML_STATUS_ERROR;
+}
+
+// --------------------------------
+
+struct AttributeParseState {
+ HashMap<String, String> attributes;
+ bool gotAttributes;
+};
+
+static void attributesStartElementHandler(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ if (strcmp(name, "attrs") != 0)
+ return;
+
+ if (atts[0] == 0 )
+ return;
+
+ AttributeParseState *state = static_cast<AttributeParseState *>(userData);
+ state->gotAttributes = true;
+
+ for (int i = 0; atts[i]; i += 2) {
+ DeprecatedString attrName = toQString(atts[i]);
+ DeprecatedString attrValue = toQString(atts[i+1]);
+ state->attributes.set(attrName, attrValue);
+ }
+}
+
+HashMap<String, String> parseAttributes(const String& string, bool& attrsOK)
+{
+ AttributeParseState state;
+ state.gotAttributes = false;
+
+ XML_Parser parser = XML_ParserCreateNS(NULL, tripletSep);
+ XML_SetUserData(parser, (void *)&state);
+ XML_SetReturnNSTriplet(parser, true);
+
+ XML_SetStartElementHandler(parser, attributesStartElementHandler);
+ String input = "<?xml version=\"1.0\"?><attrs " + string.deprecatedString() + " />";
+ CString cString = input.deprecatedString().utf8();
+ if ( XML_Parse(parser, cString.data(), cString.length(), true) != XML_STATUS_ERROR )
+ attrsOK = state.gotAttributes;
+ XML_ParserFree(parser);
+
+ return state.attributes;
+}
+
+}