summaryrefslogtreecommitdiffstats
path: root/WebCore/dom
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom')
-rw-r--r--WebCore/dom/ActiveDOMObject.h6
-rw-r--r--WebCore/dom/Attr.cpp27
-rw-r--r--WebCore/dom/Attr.h41
-rw-r--r--WebCore/dom/Attr.idl3
-rw-r--r--WebCore/dom/Attribute.cpp6
-rw-r--r--WebCore/dom/BeforeLoadEvent.h65
-rw-r--r--WebCore/dom/BeforeLoadEvent.idl39
-rw-r--r--WebCore/dom/CDATASection.cpp17
-rw-r--r--WebCore/dom/CDATASection.h12
-rw-r--r--WebCore/dom/CharacterData.cpp25
-rw-r--r--WebCore/dom/CharacterData.h35
-rw-r--r--WebCore/dom/Clipboard.h2
-rw-r--r--WebCore/dom/Comment.cpp23
-rw-r--r--WebCore/dom/Comment.h14
-rw-r--r--WebCore/dom/ContainerNode.cpp75
-rw-r--r--WebCore/dom/ContainerNode.h11
-rw-r--r--WebCore/dom/DOMImplementation.cpp25
-rw-r--r--WebCore/dom/DocPtr.h114
-rw-r--r--WebCore/dom/Document.cpp353
-rw-r--r--WebCore/dom/Document.h339
-rw-r--r--WebCore/dom/Document.idl12
-rw-r--r--WebCore/dom/DocumentFragment.cpp18
-rw-r--r--WebCore/dom/DocumentFragment.h7
-rw-r--r--WebCore/dom/DocumentType.cpp14
-rw-r--r--WebCore/dom/DocumentType.h4
-rw-r--r--WebCore/dom/EditingText.cpp25
-rw-r--r--WebCore/dom/EditingText.h13
-rw-r--r--WebCore/dom/Element.cpp119
-rw-r--r--WebCore/dom/Element.h113
-rw-r--r--WebCore/dom/Element.idl7
-rw-r--r--WebCore/dom/EntityReference.cpp11
-rw-r--r--WebCore/dom/EntityReference.h4
-rw-r--r--WebCore/dom/Event.cpp7
-rw-r--r--WebCore/dom/Event.h3
-rw-r--r--WebCore/dom/EventListener.h29
-rw-r--r--WebCore/dom/EventListener.idl2
-rw-r--r--WebCore/dom/EventNames.h9
-rw-r--r--WebCore/dom/EventTarget.cpp200
-rw-r--r--WebCore/dom/EventTarget.h146
-rw-r--r--WebCore/dom/InputElement.cpp115
-rw-r--r--WebCore/dom/InputElement.h24
-rw-r--r--WebCore/dom/MessageEvent.cpp30
-rw-r--r--WebCore/dom/MessageEvent.h29
-rw-r--r--WebCore/dom/MessageEvent.idl13
-rw-r--r--WebCore/dom/MessagePort.cpp142
-rw-r--r--WebCore/dom/MessagePort.h45
-rw-r--r--WebCore/dom/MessagePort.idl3
-rw-r--r--WebCore/dom/MessagePortChannel.cpp10
-rw-r--r--WebCore/dom/MessagePortChannel.h19
-rw-r--r--WebCore/dom/MutationEvent.h7
-rw-r--r--WebCore/dom/NamedAttrMap.cpp21
-rw-r--r--WebCore/dom/NamedAttrMap.h4
-rw-r--r--WebCore/dom/NamedNodeMap.idl3
-rw-r--r--WebCore/dom/Node.cpp936
-rw-r--r--WebCore/dom/Node.h220
-rw-r--r--WebCore/dom/Node.idl1
-rw-r--r--WebCore/dom/NodeRareData.h12
-rw-r--r--WebCore/dom/Notation.cpp16
-rw-r--r--WebCore/dom/Notation.h17
-rw-r--r--WebCore/dom/PageTransitionEvent.cpp61
-rw-r--r--WebCore/dom/PageTransitionEvent.h64
-rw-r--r--WebCore/dom/PageTransitionEvent.idl37
-rw-r--r--WebCore/dom/Position.cpp26
-rw-r--r--WebCore/dom/Position.h54
-rw-r--r--WebCore/dom/PositionCreationFunctions.h0
-rw-r--r--WebCore/dom/PositionIterator.cpp2
-rw-r--r--WebCore/dom/ProcessingInstruction.cpp69
-rw-r--r--WebCore/dom/ProcessingInstruction.h47
-rw-r--r--WebCore/dom/Range.cpp115
-rw-r--r--WebCore/dom/Range.h17
-rw-r--r--WebCore/dom/Range.idl10
-rw-r--r--WebCore/dom/RegisteredEventListener.cpp8
-rw-r--r--WebCore/dom/RegisteredEventListener.h43
-rw-r--r--WebCore/dom/ScriptElement.cpp3
-rw-r--r--WebCore/dom/ScriptExecutionContext.h2
-rw-r--r--WebCore/dom/SelectElement.cpp24
-rw-r--r--WebCore/dom/StyledElement.cpp37
-rw-r--r--WebCore/dom/StyledElement.h55
-rw-r--r--WebCore/dom/Text.cpp87
-rw-r--r--WebCore/dom/Text.h27
-rw-r--r--WebCore/dom/TransformSource.h51
-rw-r--r--WebCore/dom/TransformSourceLibxslt.cpp43
-rw-r--r--WebCore/dom/TransformSourceQt.cpp34
-rw-r--r--WebCore/dom/XMLTokenizer.cpp2
-rw-r--r--WebCore/dom/XMLTokenizerLibxml2.cpp11
-rw-r--r--WebCore/dom/XMLTokenizerQt.cpp55
-rwxr-xr-xWebCore/dom/make_names.pl377
87 files changed, 2660 insertions, 2343 deletions
diff --git a/WebCore/dom/ActiveDOMObject.h b/WebCore/dom/ActiveDOMObject.h
index e58d3f9..73b52d5 100644
--- a/WebCore/dom/ActiveDOMObject.h
+++ b/WebCore/dom/ActiveDOMObject.h
@@ -53,9 +53,6 @@ namespace WebCore {
virtual void resume();
virtual void stop();
- protected:
- virtual ~ActiveDOMObject();
-
template<class T> void setPendingActivity(T* thisObject)
{
ASSERT(thisObject == this);
@@ -70,6 +67,9 @@ namespace WebCore {
thisObject->deref();
}
+ protected:
+ virtual ~ActiveDOMObject();
+
private:
ScriptExecutionContext* m_scriptExecutionContext;
unsigned m_pendingActivityCount;
diff --git a/WebCore/dom/Attr.cpp b/WebCore/dom/Attr.cpp
index 435c1af..aa5916b 100644
--- a/WebCore/dom/Attr.cpp
+++ b/WebCore/dom/Attr.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009 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
@@ -30,10 +30,10 @@
namespace WebCore {
-Attr::Attr(Element* element, Document* docPtr, PassRefPtr<Attribute> a)
- : ContainerNode(docPtr)
+inline Attr::Attr(Element* element, Document* document, PassRefPtr<Attribute> attribute)
+ : ContainerNode(document)
, m_element(element)
- , m_attribute(a)
+ , m_attribute(attribute)
, m_ignoreChildrenChanged(0)
, m_specified(true)
{
@@ -41,6 +41,13 @@ Attr::Attr(Element* element, Document* docPtr, PassRefPtr<Attribute> a)
m_attribute->m_impl = this;
}
+PassRefPtr<Attr> Attr::create(Element* element, Document* document, PassRefPtr<Attribute> attribute)
+{
+ RefPtr<Attr> attr = adoptRef(new Attr(element, document, attribute));
+ attr->createTextChild();
+ return attr.release();
+}
+
Attr::~Attr()
{
ASSERT(m_attribute->attr() == this);
@@ -86,14 +93,14 @@ const AtomicString& Attr::prefix() const
return m_attribute->prefix();
}
-void Attr::setPrefix(const AtomicString &_prefix, ExceptionCode& ec)
+void Attr::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
{
ec = 0;
- checkSetPrefix(_prefix, ec);
+ checkSetPrefix(prefix, ec);
if (ec)
return;
- m_attribute->setPrefix(_prefix);
+ m_attribute->setPrefix(prefix);
}
String Attr::nodeValue() const
@@ -101,11 +108,11 @@ String Attr::nodeValue() const
return value();
}
-void Attr::setValue(const String& v, ExceptionCode&)
+void Attr::setValue(const AtomicString& value, ExceptionCode&)
{
m_ignoreChildrenChanged++;
removeChildren();
- m_attribute->setValue(v.impl());
+ m_attribute->setValue(value);
createTextChild();
m_ignoreChildrenChanged--;
@@ -120,7 +127,7 @@ void Attr::setNodeValue(const String& v, ExceptionCode& ec)
PassRefPtr<Node> Attr::cloneNode(bool /*deep*/)
{
- RefPtr<Attr> clone = new Attr(0, document(), m_attribute->clone());
+ RefPtr<Attr> clone = adoptRef(new Attr(0, document(), m_attribute->clone()));
cloneChildNodes(clone.get());
return clone.release();
}
diff --git a/WebCore/dom/Attr.h b/WebCore/dom/Attr.h
index ed4dc07..e927a6e 100644
--- a/WebCore/dom/Attr.h
+++ b/WebCore/dom/Attr.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -39,48 +39,47 @@ namespace WebCore {
class Attr : public ContainerNode {
friend class NamedNodeMap;
public:
- Attr(Element*, Document*, PassRefPtr<Attribute>);
- ~Attr();
+ static PassRefPtr<Attr> create(Element*, Document*, PassRefPtr<Attribute>);
+ virtual ~Attr();
- // Call this after calling the constructor so the
- // Attr node isn't floating when we append the text node.
- void createTextChild();
-
- // DOM methods & attributes for Attr
String name() const { return qualifiedName().toString(); }
bool specified() const { return m_specified; }
Element* ownerElement() const { return m_element; }
- String value() const { return m_attribute->value(); }
- void setValue(const String&, ExceptionCode&);
+ const AtomicString& value() const { return m_attribute->value(); }
+ void setValue(const AtomicString&, ExceptionCode&);
+
+ Attribute* attr() const { return m_attribute.get(); }
+ const QualifiedName& qualifiedName() const { return m_attribute->name(); }
+
+ // An extension to get presentational information for attributes.
+ CSSStyleDeclaration* style() { return m_attribute->style(); }
+
+ void setSpecified(bool specified) { m_specified = specified; }
+
+private:
+ Attr(Element*, Document*, PassRefPtr<Attribute>);
+
+ void createTextChild();
- // DOM methods overridden from parent classes
virtual String nodeName() const;
virtual NodeType nodeType() const;
+
const AtomicString& localName() const;
const AtomicString& namespaceURI() const;
const AtomicString& prefix() const;
+
virtual void setPrefix(const AtomicString&, ExceptionCode&);
virtual String nodeValue() const;
virtual void setNodeValue(const String&, ExceptionCode&);
virtual PassRefPtr<Node> cloneNode(bool deep);
- // Other methods (not part of DOM)
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);
- Attribute* attr() const { return m_attribute.get(); }
- const QualifiedName& qualifiedName() const { return m_attribute->name(); }
-
- // An extension to get presentational information for attributes.
- CSSStyleDeclaration* style() { return m_attribute->style(); }
-
- void setSpecified(bool specified) { m_specified = specified; }
-
-private:
virtual const AtomicString& virtualPrefix() const { return prefix(); }
virtual const AtomicString& virtualLocalName() const { return localName(); }
virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
diff --git a/WebCore/dom/Attr.idl b/WebCore/dom/Attr.idl
index 29f4be1..c01f34a 100644
--- a/WebCore/dom/Attr.idl
+++ b/WebCore/dom/Attr.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 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
@@ -21,6 +21,7 @@
module core {
interface [
+ CustomMarkFunction,
GenerateConstructor,
GenerateNativeConverter,
InterfaceUUID=EEE8E22B-22C3-4e50-95F4-5E0B8AAD8231,
diff --git a/WebCore/dom/Attribute.cpp b/WebCore/dom/Attribute.cpp
index 048ac6a..0ab0bb6 100644
--- a/WebCore/dom/Attribute.cpp
+++ b/WebCore/dom/Attribute.cpp
@@ -37,10 +37,8 @@ PassRefPtr<Attribute> Attribute::clone() const
PassRefPtr<Attr> Attribute::createAttrIfNeeded(Element* e)
{
RefPtr<Attr> r = m_impl;
- if (!r) {
- r = new Attr(e, e->document(), this);
- r->createTextChild();
- }
+ if (!r)
+ r = Attr::create(e, e->document(), this);
return r.release();
}
diff --git a/WebCore/dom/BeforeLoadEvent.h b/WebCore/dom/BeforeLoadEvent.h
new file mode 100644
index 0000000..8c86773
--- /dev/null
+++ b/WebCore/dom/BeforeLoadEvent.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef BeforeLoadEvent_h
+#define BeforeLoadEvent_h
+
+#include "Event.h"
+#include "EventNames.h"
+
+namespace WebCore {
+
+class BeforeLoadEvent : public Event {
+public:
+ static PassRefPtr<BeforeLoadEvent> create(const String& url)
+ {
+ return adoptRef(new BeforeLoadEvent(url));
+ }
+
+ void initBeforeLoadEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& url)
+ {
+ if (dispatched())
+ return;
+
+ initEvent(type, canBubble, cancelable);
+
+ m_url = url;
+ }
+
+ const String& url() const { return m_url; }
+
+private:
+ BeforeLoadEvent(const String& url)
+ : Event(eventNames().beforeloadEvent, false, true)
+ , m_url(url)
+ {}
+
+ String m_url;
+};
+
+} // namespace WebCore
+
+#endif // BeforeLoadEvent_h
diff --git a/WebCore/dom/BeforeLoadEvent.idl b/WebCore/dom/BeforeLoadEvent.idl
new file mode 100644
index 0000000..d06a39d
--- /dev/null
+++ b/WebCore/dom/BeforeLoadEvent.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+module events {
+
+ interface [
+ GenerateConstructor
+ ] BeforeLoadEvent : Event {
+ void initBeforeLoadEvent(in DOMString type,
+ in boolean canBubble,
+ in boolean cancelable,
+ in DOMString url);
+ readonly attribute DOMString url;
+ };
+
+}
diff --git a/WebCore/dom/CDATASection.cpp b/WebCore/dom/CDATASection.cpp
index 72faa70..d73054e 100644
--- a/WebCore/dom/CDATASection.cpp
+++ b/WebCore/dom/CDATASection.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2008, 2009 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,13 +26,14 @@
namespace WebCore {
-CDATASection::CDATASection(Document* document, const String& text)
- : Text(document, text)
+inline CDATASection::CDATASection(Document* document, const String& data)
+ : Text(document, data)
{
}
-CDATASection::~CDATASection()
+PassRefPtr<CDATASection> CDATASection::create(Document* document, const String& data)
{
+ return adoptRef(new CDATASection(document, data));
}
String CDATASection::nodeName() const
@@ -47,19 +48,17 @@ Node::NodeType CDATASection::nodeType() const
PassRefPtr<Node> CDATASection::cloneNode(bool /*deep*/)
{
- return new CDATASection(document(), m_data);
+ return create(document(), data());
}
-// DOM Section 1.1.1
bool CDATASection::childTypeAllowed(NodeType)
{
return false;
}
-PassRefPtr<Text> CDATASection::createNew(PassRefPtr<StringImpl> string)
+PassRefPtr<Text> CDATASection::virtualCreate(const String& data)
{
- return new CDATASection(document(), string);
+ return create(document(), data);
}
-
} // namespace WebCore
diff --git a/WebCore/dom/CDATASection.h b/WebCore/dom/CDATASection.h
index 8b7df9d..5cf07e1 100644
--- a/WebCore/dom/CDATASection.h
+++ b/WebCore/dom/CDATASection.h
@@ -1,9 +1,7 @@
/*
- * 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)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 2009 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
@@ -31,16 +29,16 @@ namespace WebCore {
class CDATASection : public Text {
public:
+ static PassRefPtr<CDATASection> create(Document*, const String&);
+
+private:
CDATASection(Document*, const String&);
- virtual ~CDATASection();
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual bool childTypeAllowed(NodeType);
-
-protected:
- virtual PassRefPtr<Text> createNew(PassRefPtr<StringImpl>);
+ virtual PassRefPtr<Text> virtualCreate(const String&);
};
} // namespace WebCore
diff --git a/WebCore/dom/CharacterData.cpp b/WebCore/dom/CharacterData.cpp
index 9a72de9..3c3dc37 100644
--- a/WebCore/dom/CharacterData.cpp
+++ b/WebCore/dom/CharacterData.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -30,20 +30,11 @@
namespace WebCore {
-CharacterData::CharacterData(Document *doc, bool isText)
- : Node(doc, false, false, isText)
- , m_data(StringImpl::empty())
-{
-}
-
-CharacterData::CharacterData(Document* document, const String& text, bool isText)
- : Node(document, false, false, isText)
-{
- m_data = text.impl() ? text.impl() : StringImpl::empty();
-}
-
-CharacterData::~CharacterData()
+CharacterData::CharacterData(Document* document, const String& text, ConstructionType type)
+ : Node(document, type)
+ , m_data(text.impl() ? text.impl() : StringImpl::empty())
{
+ ASSERT(type == CreateOther || type == CreateText);
}
void CharacterData::setData(const String& data, ExceptionCode&)
@@ -196,10 +187,8 @@ void CharacterData::dispatchModifiedEvent(StringImpl* prevValue)
{
if (parentNode())
parentNode()->childrenChanged();
- if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) {
- ExceptionCode ec;
- dispatchMutationEvent(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data, ec);
- }
+ if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
+ dispatchEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data));
dispatchSubtreeModifiedEvent();
}
diff --git a/WebCore/dom/CharacterData.h b/WebCore/dom/CharacterData.h
index d9e55c0..6c31933 100644
--- a/WebCore/dom/CharacterData.h
+++ b/WebCore/dom/CharacterData.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 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
@@ -29,12 +29,6 @@ namespace WebCore {
class CharacterData : public Node {
public:
- CharacterData(Document*, const String& text, bool isText = false);
- CharacterData(Document*, bool isText = false);
- virtual ~CharacterData();
-
- // DOM methods & attributes for CharacterData
-
String data() const { return m_data; }
void setData(const String&, ExceptionCode&);
unsigned length() const { return m_data->length(); }
@@ -42,31 +36,30 @@ public:
void appendData(const String&, ExceptionCode&);
void insertData(unsigned offset, const String&, ExceptionCode&);
void deleteData(unsigned offset, unsigned count, ExceptionCode&);
- void replaceData(unsigned offset, unsigned count, const String &arg, ExceptionCode&);
+ void replaceData(unsigned offset, unsigned count, const String&, ExceptionCode&);
bool containsOnlyWhitespace() const;
- // DOM methods overridden from parent classes
-
- virtual String nodeValue() const;
- virtual void setNodeValue(const String&, ExceptionCode&);
-
- // Other methods (not part of DOM)
+ StringImpl* dataImpl() { return m_data.get(); }
- virtual bool isCharacterDataNode() const { return true; }
- virtual int maxCharacterOffset() const;
- StringImpl* string() { return m_data.get(); }
+protected:
+ CharacterData(Document*, const String&, ConstructionType);
- virtual bool offsetInCharacters() const;
virtual bool rendererIsNeeded(RenderStyle*);
-protected:
- RefPtr<StringImpl> m_data;
-
+ void setDataImpl(PassRefPtr<StringImpl> impl) { m_data = impl; }
void dispatchModifiedEvent(StringImpl* oldValue);
private:
+ virtual String nodeValue() const;
+ virtual void setNodeValue(const String&, ExceptionCode&);
+ virtual bool isCharacterDataNode() const { return true; }
+ virtual int maxCharacterOffset() const;
+ virtual bool offsetInCharacters() const;
+
void checkCharDataOperation(unsigned offset, ExceptionCode&);
+
+ RefPtr<StringImpl> m_data;
};
} // namespace WebCore
diff --git a/WebCore/dom/Clipboard.h b/WebCore/dom/Clipboard.h
index 0fea604..f6c09b2 100644
--- a/WebCore/dom/Clipboard.h
+++ b/WebCore/dom/Clipboard.h
@@ -64,7 +64,9 @@ namespace WebCore {
virtual void setDragImageElement(Node*, const IntPoint&) = 0;
virtual DragImageRef createDragImage(IntPoint& dragLocation) const = 0;
+#if ENABLE(DRAG_SUPPORT)
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*) = 0;
+#endif
virtual void writeURL(const KURL&, const String&, Frame*) = 0;
virtual void writeRange(Range*, Frame*) = 0;
diff --git a/WebCore/dom/Comment.cpp b/WebCore/dom/Comment.cpp
index a36a491..3dcde38 100644
--- a/WebCore/dom/Comment.cpp
+++ b/WebCore/dom/Comment.cpp
@@ -1,9 +1,7 @@
-/**
- * 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)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 2009 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
@@ -24,22 +22,16 @@
#include "config.h"
#include "Comment.h"
-#include "Document.h"
-
namespace WebCore {
-Comment::Comment(Document* doc, const String& text)
- : CharacterData(doc, text)
-{
-}
-
-Comment::Comment(Document* doc)
- : CharacterData(doc)
+inline Comment::Comment(Document* document, const String& text)
+ : CharacterData(document, text, CreateOther)
{
}
-Comment::~Comment()
+PassRefPtr<Comment> Comment::create(Document* document, const String& text)
{
+ return adoptRef(new Comment(document, text));
}
String Comment::nodeName() const
@@ -54,10 +46,9 @@ Node::NodeType Comment::nodeType() const
PassRefPtr<Node> Comment::cloneNode(bool /*deep*/)
{
- return document()->createComment(m_data);
+ return create(document(), data());
}
-// DOM Section 1.1.1
bool Comment::childTypeAllowed(NodeType)
{
return false;
diff --git a/WebCore/dom/Comment.h b/WebCore/dom/Comment.h
index d00ba62..680ffae 100644
--- a/WebCore/dom/Comment.h
+++ b/WebCore/dom/Comment.h
@@ -1,9 +1,7 @@
/*
- * 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)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 2009 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
@@ -31,16 +29,14 @@ namespace WebCore {
class Comment : public CharacterData {
public:
- Comment(Document*, const String &_text);
- Comment(Document*);
- virtual ~Comment();
+ static PassRefPtr<Comment> create(Document*, const String&);
+
+private:
+ Comment(Document*, const String&);
- // DOM methods overridden from parent classes
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
-
- // Other methods (not part of DOM)
virtual bool isCommentNode() const { return true; }
virtual bool childTypeAllowed(NodeType);
};
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 2d79156..99b2c4f 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "ContainerNode.h"
+#include "BeforeLoadEvent.h"
#include "Cache.h"
#include "ContainerNodeAlgorithms.h"
#include "DeleteButtonController.h"
@@ -41,8 +42,8 @@
namespace WebCore {
-static void dispatchChildInsertionEvents(Node*, ExceptionCode&);
-static void dispatchChildRemovalEvents(Node*, ExceptionCode&);
+static void dispatchChildInsertionEvents(Node*);
+static void dispatchChildRemovalEvents(Node*);
typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
static NodeCallbackQueue* s_postAttachCallbackQueue;
@@ -144,7 +145,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
// Dispatch the mutation events.
childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
- dispatchChildInsertionEvents(child.get(), ec);
+ dispatchChildInsertionEvents(child.get());
// Add child to the rendering tree.
if (attached() && !child->attached() && child->parent() == this) {
@@ -255,7 +256,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
allowEventDispatch();
// Dispatch the mutation events
- dispatchChildInsertionEvents(child.get(), ec);
+ dispatchChildInsertionEvents(child.get());
// Add child to the rendering tree
if (attached() && !child->attached() && child->parent() == this) {
@@ -287,7 +288,7 @@ static ExceptionCode willRemoveChild(Node *child)
ExceptionCode ec = 0;
// fire removed from document mutation events.
- dispatchChildRemovalEvents(child, ec);
+ dispatchChildRemovalEvents(child);
if (ec)
return ec;
@@ -480,7 +481,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
// Dispatch the mutation events
childrenChanged(false, prev.get(), 0, 1);
- dispatchChildInsertionEvents(child.get(), ec);
+ dispatchChildInsertionEvents(child.get());
// Add child to the rendering tree
if (attached() && !child->attached() && child->parent() == this) {
@@ -690,7 +691,7 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
point = o->container()->localToAbsolute();
if (o->isText() && toRenderText(o)->firstTextBox()) {
point.move(toRenderText(o)->linesBoundingBox().x(),
- toRenderText(o)->firstTextBox()->root()->topOverflow());
+ toRenderText(o)->firstTextBox()->root()->lineTop());
} else if (o->isBox()) {
RenderBox* box = toRenderBox(o);
point.move(box->x(), box->y());
@@ -864,63 +865,57 @@ Node *ContainerNode::childNode(unsigned index) const
return n;
}
-static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
+static void dispatchChildInsertionEvents(Node* child)
{
ASSERT(!eventDispatchForbidden());
RefPtr<Node> c = child;
- DocPtr<Document> doc = child->document();
+ RefPtr<Document> document = child->document();
if (c->parentNode() && c->parentNode()->inDocument())
c->insertedIntoDocument();
else
c->insertedIntoTree(true);
- doc->incDOMTreeVersion();
+ document->incDOMTreeVersion();
- if (c->parentNode() && doc->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) {
- ec = 0;
- c->dispatchMutationEvent(eventNames().DOMNodeInsertedEvent, true, c->parentNode(), String(), String(), ec);
- if (ec)
- return;
- }
+ if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
// dispatch the DOMNodeInsertedIntoDocument event to all descendants
- if (c->inDocument() && doc->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER))
- for (; c; c = c->traverseNextNode(child)) {
- ec = 0;
- c->dispatchMutationEvent(eventNames().DOMNodeInsertedIntoDocumentEvent, false, 0, String(), String(), ec);
- if (ec)
- return;
- }
+ if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
+ for (; c; c = c->traverseNextNode(child))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
+ }
}
-static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
+static void dispatchChildRemovalEvents(Node* child)
{
RefPtr<Node> c = child;
- DocPtr<Document> doc = child->document();
+ RefPtr<Document> document = child->document();
// update auxiliary doc info (e.g. iterators) to note that node is being removed
- doc->nodeWillBeRemoved(child);
+ document->nodeWillBeRemoved(child);
- doc->incDOMTreeVersion();
+ document->incDOMTreeVersion();
// dispatch pre-removal mutation events
- if (c->parentNode() && doc->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
- ec = 0;
- c->dispatchMutationEvent(eventNames().DOMNodeRemovedEvent, true, c->parentNode(), String(), String(), ec);
- if (ec)
- return;
- }
+ if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
// dispatch the DOMNodeRemovedFromDocument event to all descendants
- if (c->inDocument() && doc->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER))
- for (; c; c = c->traverseNextNode(child)) {
- ec = 0;
- c->dispatchMutationEvent(eventNames().DOMNodeRemovedFromDocumentEvent, false, 0, String(), String(), ec);
- if (ec)
- return;
- }
+ if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
+ for (; c; c = c->traverseNextNode(child))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
+ }
}
+bool ContainerNode::dispatchBeforeLoadEvent(const String& sourceURL)
+{
+ RefPtr<ContainerNode> protector(this);
+ RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
+ dispatchEvent(beforeLoadEvent.get());
+ return inDocument() && !beforeLoadEvent->defaultPrevented();
}
+
+} // namespace WebCore
diff --git a/WebCore/dom/ContainerNode.h b/WebCore/dom/ContainerNode.h
index 3ad932c..9789f1f 100644
--- a/WebCore/dom/ContainerNode.h
+++ b/WebCore/dom/ContainerNode.h
@@ -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 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009 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
@@ -38,7 +38,6 @@ namespace Private {
class ContainerNode : public Node {
public:
- ContainerNode(Document*, bool isElement = false);
virtual ~ContainerNode();
Node* firstChild() const { return m_firstChild; }
@@ -72,8 +71,12 @@ public:
void removeAllChildren();
void cloneChildNodes(ContainerNode* clone);
+
+ bool dispatchBeforeLoadEvent(const String& sourceURL);
protected:
+ ContainerNode(Document*, ConstructionType = CreateContainer);
+
static void queuePostAttachCallback(NodeCallback, Node*);
void suspendPostAttachCallbacks();
void resumePostAttachCallbacks();
@@ -97,8 +100,8 @@ private:
Node* m_lastChild;
};
-inline ContainerNode::ContainerNode(Document* document, bool isElement)
- : Node(document, isElement, true)
+inline ContainerNode::ContainerNode(Document* document, ConstructionType type)
+ : Node(document, type)
, m_firstChild(0)
, m_lastChild(0)
{
diff --git a/WebCore/dom/DOMImplementation.cpp b/WebCore/dom/DOMImplementation.cpp
index 065f708..59b9703 100644
--- a/WebCore/dom/DOMImplementation.cpp
+++ b/WebCore/dom/DOMImplementation.cpp
@@ -223,12 +223,6 @@ DOMImplementation* DOMImplementation::getInterface(const String& /*feature*/)
PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceURI,
const String& qualifiedName, DocumentType* doctype, ExceptionCode& ec)
{
- // WRONG_DOCUMENT_ERR: Raised if doctype has already been used with a different document or was
- // created from a different implementation.
- bool shouldThrowWrongDocErr = false;
- if (doctype && doctype->document())
- shouldThrowWrongDocErr = true;
-
RefPtr<Document> doc;
#if ENABLE(SVG)
if (namespaceURI == SVGNames::svgNamespaceURI)
@@ -245,24 +239,27 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceUR
else
doc = Document::create(0);
- // now get the interesting parts of the doctype
- if (doctype)
- doc->addChild(doctype);
-
+ RefPtr<Node> documentElement;
if (!qualifiedName.isEmpty()) {
- RefPtr<Node> documentElement = doc->createElementNS(namespaceURI, qualifiedName, ec);
+ documentElement = doc->createElementNS(namespaceURI, qualifiedName, ec);
if (ec)
return 0;
- doc->addChild(documentElement.release());
}
+ // WRONG_DOCUMENT_ERR: Raised if doctype has already been used with a different document or was
+ // created from a different implementation.
// Hixie's interpretation of the DOM Core spec suggests we should prefer
- // other exceptions to WRONG_DOCUMENT_ERR (based on order mentioned in spec)
- if (shouldThrowWrongDocErr) {
+ // other exceptions to WRONG_DOCUMENT_ERR (based on order mentioned in spec).
+ if (doctype && doctype->document()) {
ec = WRONG_DOCUMENT_ERR;
return 0;
}
+ if (doctype)
+ doc->addChild(doctype);
+ if (documentElement)
+ doc->addChild(documentElement.release());
+
return doc.release();
}
diff --git a/WebCore/dom/DocPtr.h b/WebCore/dom/DocPtr.h
deleted file mode 100644
index 8b50e8d..0000000
--- a/WebCore/dom/DocPtr.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * This file is part of the DOM implementation for KDE.
- * Copyright (C) 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
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef DocPtr_h
-#define DocPtr_h
-
-namespace WebCore {
-
-template <class T> class DocPtr {
-public:
- DocPtr() : m_ptr(0) {}
- DocPtr(T *ptr) : m_ptr(ptr) { if (ptr) ptr->selfOnlyRef(); }
- DocPtr(const DocPtr &o) : m_ptr(o.m_ptr) { if (T *ptr = m_ptr) ptr->selfOnlyRef(); }
- ~DocPtr() { if (T *ptr = m_ptr) ptr->selfOnlyDeref(); }
-
- template <class U> DocPtr(const DocPtr<U> &o) : m_ptr(o.get()) { if (T *ptr = m_ptr) ptr->selfOnlyRef(); }
-
- void resetSkippingRef(T *o) { m_ptr = o; }
-
- T *get() const { return m_ptr; }
-
- T &operator*() const { return *m_ptr; }
- T *operator->() const { return m_ptr; }
-
- bool operator!() const { return !m_ptr; }
-
- // this type conversion operator allows implicit conversion to
- // bool but not to other integer types
-
- typedef T * (DocPtr::*UnspecifiedBoolType)() const;
- operator UnspecifiedBoolType() const
- {
- return m_ptr ? &DocPtr::get : 0;
- }
-
- DocPtr &operator=(const DocPtr &);
- DocPtr &operator=(T *);
-
- private:
- T *m_ptr;
-};
-
-template <class T> DocPtr<T> &DocPtr<T>::operator=(const DocPtr<T> &o)
-{
- T *optr = o.m_ptr;
- if (optr)
- optr->selfOnlyRef();
- if (T *ptr = m_ptr)
- ptr->selfOnlyDeref();
- m_ptr = optr;
- return *this;
-}
-
-template <class T> inline DocPtr<T> &DocPtr<T>::operator=(T *optr)
-{
- if (optr)
- optr->selfOnlyRef();
- if (T *ptr = m_ptr)
- ptr->selfOnlyDeref();
- m_ptr = optr;
- return *this;
-}
-
-template <class T> inline bool operator==(const DocPtr<T> &a, const DocPtr<T> &b)
-{
- return a.get() == b.get();
-}
-
-template <class T> inline bool operator==(const DocPtr<T> &a, const T *b)
-{
- return a.get() == b;
-}
-
-template <class T> inline bool operator==(const T *a, const DocPtr<T> &b)
-{
- return a == b.get();
-}
-
-template <class T> inline bool operator!=(const DocPtr<T> &a, const DocPtr<T> &b)
-{
- return a.get() != b.get();
-}
-
-template <class T> inline bool operator!=(const DocPtr<T> &a, const T *b)
-{
- return a.get() != b;
-}
-
-template <class T> inline bool operator!=(const T *a, const DocPtr<T> &b)
-{
- return a != b.get();
-}
-
-} // namespace WebCore
-
-#endif // DocPtr_h
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index e4c5741..efa2f7a 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -22,6 +22,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "Document.h"
@@ -79,7 +80,7 @@
#include "HitTestResult.h"
#include "ImageLoader.h"
#include "InspectorController.h"
-#include "ScriptEventListener.h"
+#include "InspectorTimelineAgent.h"
#include "KeyboardEvent.h"
#include "Logging.h"
#include "MappedAttribute.h"
@@ -93,6 +94,8 @@
#include "NodeWithIndex.h"
#include "OverflowEvent.h"
#include "Page.h"
+#include "PageGroup.h"
+#include "PageTransitionEvent.h"
#include "PlatformKeyboardEvent.h"
#include "ProcessingInstruction.h"
#include "ProgressEvent.h"
@@ -103,6 +106,7 @@
#include "RenderWidget.h"
#include "ScriptController.h"
#include "ScriptElement.h"
+#include "ScriptEventListener.h"
#include "SecurityOrigin.h"
#include "SegmentedString.h"
#include "SelectionController.h"
@@ -112,14 +116,17 @@
#include "TextIterator.h"
#include "TextResourceDecoder.h"
#include "Timer.h"
+#include "TransformSource.h"
#include "TreeWalker.h"
#include "UIEvent.h"
+#include "UserContentURLPattern.h"
#include "WebKitAnimationEvent.h"
#include "WebKitTransitionEvent.h"
#include "WheelEvent.h"
#include "XMLHttpRequest.h"
#include "XMLNames.h"
#include "XMLTokenizer.h"
+#include "htmlediting.h"
#include <wtf/CurrentTime.h>
#include <wtf/HashFunctions.h>
#include <wtf/MainThread.h>
@@ -131,6 +138,10 @@
#include "DatabaseThread.h"
#endif
+#if ENABLE(SHARED_WORKERS)
+#include "SharedWorkerRepository.h"
+#endif
+
#if ENABLE(DOM_STORAGE)
#include "StorageEvent.h"
#endif
@@ -153,6 +164,7 @@
#if ENABLE(SVG)
#include "SVGDocumentExtensions.h"
#include "SVGElementFactory.h"
+#include "SVGNames.h"
#include "SVGZoomEvent.h"
#include "SVGStyleElement.h"
#endif
@@ -184,6 +196,12 @@
#include "WMLNames.h"
#endif
+#if ENABLE(MATHML)
+#include "MathMLElement.h"
+#include "MathMLElementFactory.h"
+#include "MathMLNames.h"
+#endif
+
#if ENABLE(XHTMLMP)
#include "HTMLNoScriptElement.h"
#endif
@@ -325,9 +343,6 @@ Document::Document(Frame* frame, bool isXHTML)
, m_titleSetExplicitly(false)
, m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
, m_executeScriptSoonTimer(this, &Document::executeScriptSoonTimerFired)
-#if ENABLE(XSLT)
- , m_transformSource(0)
-#endif
, m_xmlVersion("1.0")
, m_xmlStandalone(false)
#if ENABLE(XBL)
@@ -361,7 +376,9 @@ Document::Document(Frame* frame, bool isXHTML)
, m_containsWMLContent(false)
#endif
{
- m_document.resetSkippingRef(this);
+ m_document = this;
+
+ m_pageGroupUserSheetCacheValid = false;
m_printing = false;
@@ -431,8 +448,7 @@ void Document::removedLastRef()
// want the document to be destructed until after
// removeAllChildren returns, so we guard ourselves with an
// extra self-only ref.
-
- DocPtr<Document> guard(this);
+ selfOnlyRef();
// We must make sure not to be retaining any of our children through
// these extra pointers or we will create a reference cycle.
@@ -456,6 +472,8 @@ void Document::removedLastRef()
#ifndef NDEBUG
m_inRemovedLastRefFunction = false;
#endif
+
+ selfOnlyDeref();
} else {
#ifndef NDEBUG
m_deletionHasBegun = true;
@@ -482,7 +500,7 @@ Document::~Document()
#endif
delete m_tokenizer;
- m_document.resetSkippingRef(0);
+ m_document = 0;
delete m_styleSelector;
delete m_docLoader;
@@ -491,10 +509,6 @@ Document::~Document()
m_renderArena = 0;
}
-#if ENABLE(XSLT)
- xmlFreeDoc((xmlDocPtr)m_transformSource);
-#endif
-
#if ENABLE(XBL)
delete m_bindingManager;
#endif
@@ -518,8 +532,6 @@ Document::~Document()
if (m_styleSheets)
m_styleSheets->documentDestroyed();
-
- m_document = 0;
}
void Document::resetLinkColor()
@@ -599,17 +611,17 @@ PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionC
PassRefPtr<DocumentFragment> Document::createDocumentFragment()
{
- return new DocumentFragment(document());
+ return DocumentFragment::create(document());
}
PassRefPtr<Text> Document::createTextNode(const String& data)
{
- return new Text(this, data);
+ return Text::create(this, data);
}
PassRefPtr<Comment> Document::createComment(const String& data)
{
- return new Comment(this, data);
+ return Comment::create(this, data);
}
PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionCode& ec)
@@ -618,7 +630,7 @@ PassRefPtr<CDATASection> Document::createCDATASection(const String& data, Except
ec = NOT_SUPPORTED_ERR;
return 0;
}
- return new CDATASection(this, data);
+ return CDATASection::create(this, data);
}
PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionCode& ec)
@@ -631,7 +643,7 @@ PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const St
ec = NOT_SUPPORTED_ERR;
return 0;
}
- return new ProcessingInstruction(this, target, data);
+ return ProcessingInstruction::create(this, target, data);
}
PassRefPtr<EntityReference> Document::createEntityReference(const String& name, ExceptionCode& ec)
@@ -644,12 +656,12 @@ PassRefPtr<EntityReference> Document::createEntityReference(const String& name,
ec = NOT_SUPPORTED_ERR;
return 0;
}
- return new EntityReference(this, name);
+ return EntityReference::create(this, name);
}
PassRefPtr<EditingText> Document::createEditingTextNode(const String& text)
{
- return new EditingText(this, text);
+ return EditingText::create(this, text);
}
PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
@@ -714,11 +726,8 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo
return newElement.release();
}
- case ATTRIBUTE_NODE: {
- RefPtr<Attr> newAttr = new Attr(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
- newAttr->createTextChild();
- return newAttr.release();
- }
+ case ATTRIBUTE_NODE:
+ return Attr::create(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
case DOCUMENT_FRAGMENT_NODE: {
DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode);
RefPtr<DocumentFragment> newFragment = createDocumentFragment();
@@ -828,9 +837,13 @@ PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool cre
else if (isWMLDocument())
e = WMLElementFactory::createWMLElement(QualifiedName(nullAtom, qName.localName(), WMLNames::wmlNamespaceURI), this, createdByParser);
#endif
+#if ENABLE(MATHML)
+ else if (qName.namespaceURI() == MathMLNames::mathmlNamespaceURI)
+ e = MathMLElementFactory::createMathMLElement(qName, this, createdByParser);
+#endif
if (!e)
- e = new Element(qName, document());
+ e = Element::create(qName, document());
// <image> uses imgTag so we need a special rule.
#if ENABLE(WML)
@@ -952,16 +965,25 @@ KURL Document::baseURI() const
Element* Document::elementFromPoint(int x, int y) const
{
+ // FIXME: Share code between this and caretRangeFromPoint.
if (!renderer())
return 0;
+ Frame* frame = this->frame();
+ if (!frame)
+ return 0;
+ FrameView* frameView = frame->view();
+ if (!frameView)
+ return 0;
- HitTestRequest request(HitTestRequest::ReadOnly |
- HitTestRequest::Active);
+ float zoomFactor = frame->pageZoomFactor();
+ IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor, y * zoomFactor)) + view()->scrollOffset();
- float zoomFactor = frame() ? frame()->pageZoomFactor() : 1.0f;
+ if (!frameView->visibleContentRect().contains(point))
+ return 0;
- HitTestResult result(roundedIntPoint(FloatPoint(x * zoomFactor, y * zoomFactor)));
- renderView()->layer()->hitTest(request, result);
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
+ HitTestResult result(point);
+ renderView()->layer()->hitTest(request, result);
Node* n = result.innerNode();
while (n && !n->isElementNode())
@@ -971,6 +993,50 @@ Element* Document::elementFromPoint(int x, int y) const
return static_cast<Element*>(n);
}
+PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
+{
+ // FIXME: Share code between this and elementFromPoint.
+ if (!renderer())
+ return 0;
+ Frame* frame = this->frame();
+ if (!frame)
+ return 0;
+ FrameView* frameView = frame->view();
+ if (!frameView)
+ return 0;
+
+ float zoomFactor = frame->pageZoomFactor();
+ IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor, y * zoomFactor)) + view()->scrollOffset();
+
+ if (!frameView->visibleContentRect().contains(point))
+ return 0;
+
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
+ HitTestResult result(point);
+ renderView()->layer()->hitTest(request, result);
+
+ Node* node = result.innerNode();
+ if (!node)
+ return 0;
+
+ Node* shadowAncestorNode = node->shadowAncestorNode();
+ if (shadowAncestorNode != node) {
+ unsigned offset = shadowAncestorNode->nodeIndex();
+ Node* container = shadowAncestorNode->parentNode();
+ return Range::create(this, container, offset, container, offset);
+ }
+
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return 0;
+ VisiblePosition visiblePosition = renderer->positionForPoint(result.localPoint());
+ if (visiblePosition.isNull())
+ return 0;
+
+ Position rangeCompliantPosition = rangeCompliantEquivalent(visiblePosition);
+ return Range::create(this, rangeCompliantPosition, rangeCompliantPosition);
+}
+
void Document::addElementById(const AtomicString& elementId, Element* element)
{
typedef HashMap<AtomicStringImpl*, Element*>::iterator iterator;
@@ -1186,6 +1252,12 @@ void Document::recalcStyle(StyleChange change)
if (m_inStyleRecalc)
return; // Guard against re-entrancy. -dwh
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
+ if (timelineAgent)
+ timelineAgent->willRecalculateStyle();
+#endif
+
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
if (view())
@@ -1266,6 +1338,11 @@ bail_out:
m_closeAfterStyleRecalc = false;
implicitClose();
}
+
+#if ENABLE(INSPECTOR)
+ if (timelineAgent)
+ timelineAgent->didRecalculateStyle();
+#endif
}
void Document::updateStyleIfNeeded()
@@ -1363,7 +1440,8 @@ void Document::attach()
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 = new CSSStyleSelector(this, m_styleSheets.get(), m_mappedElementSheet.get(), pageUserSheet(), pageGroupUserSheets(),
+ !inCompatMode(), matchAuthorAndUserStyles);
}
recalcStyle(Force);
@@ -1389,7 +1467,11 @@ void Document::detach()
// Send out documentWillBecomeInactive() notifications to registered elements,
// in order to stop media elements
documentWillBecomeInactive();
-
+
+#if ENABLE(SHARED_WORKERS)
+ SharedWorkerRepository::documentDetached(this);
+#endif
+
if (m_frame) {
FrameView* view = m_frame->view();
if (view)
@@ -1436,31 +1518,14 @@ void Document::detach()
void Document::removeAllEventListeners()
{
+ EventTarget::removeAllEventListeners();
+
if (DOMWindow* domWindow = this->domWindow())
domWindow->removeAllEventListeners();
- removeAllDisconnectedNodeEventListeners();
- for (Node* node = this; node; node = node->traverseNextNode())
+ for (Node* node = firstChild(); node; node = node->traverseNextNode())
node->removeAllEventListeners();
}
-void Document::registerDisconnectedNodeWithEventListeners(Node* node)
-{
- m_disconnectedNodesWithEventListeners.add(node);
-}
-
-void Document::unregisterDisconnectedNodeWithEventListeners(Node* node)
-{
- m_disconnectedNodesWithEventListeners.remove(node);
-}
-
-void Document::removeAllDisconnectedNodeEventListeners()
-{
- HashSet<Node*>::iterator end = m_disconnectedNodesWithEventListeners.end();
- for (HashSet<Node*>::iterator i = m_disconnectedNodesWithEventListeners.begin(); i != end; ++i)
- (*i)->removeAllEventListeners();
- m_disconnectedNodesWithEventListeners.clear();
-}
-
RenderView* Document::renderView() const
{
return toRenderView(renderer());
@@ -1660,7 +1725,7 @@ void Document::implicitClose()
return;
}
- bool wasLocationChangePending = frame() && frame()->loader()->isScheduledLocationChangePending();
+ bool wasLocationChangePending = frame() && frame()->redirectScheduler()->locationChangePending();
bool doload = !parsing() && m_tokenizer && !m_processingLoadEvent && !wasLocationChangePending;
if (!doload)
@@ -1708,7 +1773,8 @@ void Document::implicitClose()
f->animation()->resumeAnimations(this);
ImageLoader::dispatchPendingLoadEvents();
- dispatchLoadEvent();
+ dispatchWindowLoadEvent();
+ dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, false), this);
if (f)
f->loader()->handledOnloadEvents();
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -1726,7 +1792,7 @@ void Document::implicitClose()
// fires. This will improve onload scores, and other browsers do it.
// If they wanna cheat, we can too. -dwh
- if (frame()->loader()->isScheduledLocationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
+ if (frame()->redirectScheduler()->locationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
// Just bail out. Before or during the onload we were shifted to another page.
// The old i-Bench suite does this. When this happens don't bother painting or laying out.
view()->unscheduleRelayout();
@@ -1755,7 +1821,7 @@ void Document::implicitClose()
// exists in the cache (we ignore the return value because we don't need it here). This is
// only safe to call when a layout is not in progress, so it can not be used in postNotification.
axObjectCache()->getOrCreate(renderObject);
- axObjectCache()->postNotification(renderObject, "AXLoadComplete", true);
+ axObjectCache()->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
}
#endif
@@ -1917,34 +1983,72 @@ String Document::userAgent(const KURL& url) const
return frame() ? frame()->loader()->userAgent(url) : String();
}
-void Document::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet)
+CSSStyleSheet* Document::pageUserSheet()
{
- m_sheet = CSSStyleSheet::create(this, url, charset);
- m_sheet->parseString(sheet->sheetText());
+ if (m_pageUserSheet)
+ return m_pageUserSheet.get();
+
+ Page* owningPage = page();
+ if (!owningPage)
+ return 0;
+
+ String userSheetText = owningPage->userStyleSheet();
+ if (userSheetText.isEmpty())
+ return 0;
+
+ // Parse the sheet and cache it.
+ m_pageUserSheet = CSSStyleSheet::create(this, settings()->userStyleSheetLocation());
+ m_pageUserSheet->setIsUserStyleSheet(true);
+ m_pageUserSheet->parseString(userSheetText, !inCompatMode());
+ return m_pageUserSheet.get();
+}
+void Document::clearPageUserSheet()
+{
+ m_pageUserSheet = 0;
updateStyleSelector();
}
-#if FRAME_LOADS_USER_STYLESHEET
-void Document::setUserStyleSheet(const String& sheet)
+const Vector<RefPtr<CSSStyleSheet> >* Document::pageGroupUserSheets() const
{
- if (m_usersheet != sheet) {
- m_usersheet = sheet;
- updateStyleSelector();
+ if (m_pageGroupUserSheetCacheValid)
+ return m_pageGroupUserSheets.get();
+
+ m_pageGroupUserSheetCacheValid = true;
+
+ Page* owningPage = page();
+ if (!owningPage)
+ return 0;
+
+ const PageGroup& pageGroup = owningPage->group();
+ const UserStyleSheetMap* sheetsMap = pageGroup.userStyleSheets();
+ if (!sheetsMap)
+ return 0;
+
+ UserStyleSheetMap::const_iterator end = sheetsMap->end();
+ for (UserStyleSheetMap::const_iterator it = sheetsMap->begin(); it != end; ++it) {
+ const UserStyleSheetVector* sheets = it->second;
+ for (unsigned i = 0; i < sheets->size(); ++i) {
+ const UserStyleSheet* sheet = sheets->at(i).get();
+ if (!UserContentURLPattern::matchesPatterns(url(), sheet->whitelist(), sheet->blacklist()))
+ continue;
+ RefPtr<CSSStyleSheet> parsedSheet = CSSStyleSheet::create(const_cast<Document*>(this), sheet->url());
+ parsedSheet->setIsUserStyleSheet(true);
+ parsedSheet->parseString(sheet->source(), !inCompatMode());
+ if (!m_pageGroupUserSheets)
+ m_pageGroupUserSheets.set(new Vector<RefPtr<CSSStyleSheet> >);
+ m_pageGroupUserSheets->append(parsedSheet.release());
+ }
}
+
+ return m_pageGroupUserSheets.get();
}
-#endif
-String Document::userStyleSheet() const
+void Document::clearPageGroupUserSheets()
{
-#if FRAME_LOADS_USER_STYLESHEET
- return m_usersheet;
-#else
- Page* page = this->page();
- if (!page)
- return String();
- return page->userStyleSheet();
-#endif
+ m_pageGroupUserSheets.clear();
+ m_pageGroupUserSheetCacheValid = false;
+ updateStyleSelector();
}
CSSStyleSheet* Document::elementSheet()
@@ -2175,7 +2279,7 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
url = frame->loader()->url().string();
else
url = completeURL(url).string();
- frame->loader()->scheduleHTTPRedirection(delay, url);
+ frame->redirectScheduler()->scheduleRedirect(delay, url);
}
} else if (equalIgnoringCase(equiv, "set-cookie")) {
// FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
@@ -2189,7 +2293,7 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
FrameLoader* frameLoader = frame->loader();
if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
frameLoader->stopAllLoaders();
- frameLoader->scheduleHTTPRedirection(0, blankURL());
+ frame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
}
}
}
@@ -2566,7 +2670,8 @@ void Document::recalcStyleSelector()
// Create a new style selector
delete m_styleSelector;
- m_styleSelector = new CSSStyleSelector(this, userStyleSheet(), m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
+ m_styleSelector = new CSSStyleSelector(this, m_styleSheets.get(), m_mappedElementSheet.get(),
+ pageUserSheet(), pageGroupUserSheets(), !inCompatMode(), matchAuthorAndUserStyles);
m_didCalculateStyleSelector = true;
}
@@ -2661,7 +2766,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
// Dispatch a change event for text fields or textareas that have been edited
RenderObject* r = oldFocusedNode->renderer();
if (r && r->isTextControl() && toRenderTextControl(r)->isEdited()) {
- oldFocusedNode->dispatchEvent(eventNames().changeEvent, true, false);
+ oldFocusedNode->dispatchEvent(Event::create(eventNames().changeEvent, true, false));
r = oldFocusedNode->renderer();
if (r && r->isTextControl())
toRenderTextControl(r)->setEdited(false);
@@ -2681,10 +2786,10 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
focusChangeBlocked = true;
newFocusedNode = 0;
}
- if ((oldFocusedNode.get() == this) && oldFocusedNode->hasOneRef())
+ if (oldFocusedNode == this && oldFocusedNode->hasOneRef())
return true;
- if (oldFocusedNode.get() == oldFocusedNode->rootEditableElement())
+ if (oldFocusedNode == oldFocusedNode->rootEditableElement())
frame()->editor()->didEndEditing();
}
@@ -2713,7 +2818,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
}
m_focusedNode->setFocus();
- if (m_focusedNode.get() == m_focusedNode->rootEditableElement())
+ if (m_focusedNode == m_focusedNode->rootEditableElement())
frame()->editor()->didBeginEditing();
// eww, I suck. set the qt focus correctly
@@ -2735,20 +2840,17 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
}
}
-#if PLATFORM(MAC) && !PLATFORM(CHROMIUM)
- if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled())
- axObjectCache()->handleFocusedUIElementChanged();
-#elif PLATFORM(GTK)
+#if ((PLATFORM(MAC) || PLATFORM(WIN)) && !PLATFORM(CHROMIUM)) || PLATFORM(GTK)
if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled()) {
RenderObject* oldFocusedRenderer = 0;
RenderObject* newFocusedRenderer = 0;
if (oldFocusedNode)
- oldFocusedRenderer = oldFocusedNode.get()->renderer();
+ oldFocusedRenderer = oldFocusedNode->renderer();
if (newFocusedNode)
- newFocusedRenderer = newFocusedNode.get()->renderer();
+ newFocusedRenderer = newFocusedNode->renderer();
- axObjectCache()->handleFocusedUIElementChangedWithRenderers(oldFocusedRenderer, newFocusedRenderer);
+ axObjectCache()->handleFocusedUIElementChanged(oldFocusedRenderer, newFocusedRenderer);
}
#endif
@@ -2891,26 +2993,16 @@ EventListener* Document::getWindowAttributeEventListener(const AtomicString& eve
return domWindow->getAttributeEventListener(eventType);
}
-void Document::dispatchWindowEvent(PassRefPtr<Event> event)
-{
- ASSERT(!eventDispatchForbidden());
- DOMWindow* domWindow = this->domWindow();
- if (!domWindow)
- return;
- ExceptionCode ec;
- domWindow->dispatchEvent(event, ec);
-}
-
-void Document::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
+void Document::dispatchWindowEvent(PassRefPtr<Event> event, PassRefPtr<EventTarget> target)
{
ASSERT(!eventDispatchForbidden());
DOMWindow* domWindow = this->domWindow();
if (!domWindow)
return;
- domWindow->dispatchEvent(eventType, canBubbleArg, cancelableArg);
+ domWindow->dispatchEvent(event, target);
}
-void Document::dispatchLoadEvent()
+void Document::dispatchWindowLoadEvent()
{
ASSERT(!eventDispatchForbidden());
DOMWindow* domWindow = this->domWindow();
@@ -2933,6 +3025,8 @@ PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode&
return MutationEvent::create();
if (eventType == "OverflowEvent")
return OverflowEvent::create();
+ if (eventType == "PageTransitionEvent")
+ return PageTransitionEvent::create();
if (eventType == "ProgressEvent")
return ProgressEvent::create();
#if ENABLE(DOM_STORAGE)
@@ -3039,7 +3133,7 @@ String Document::domain() const
return securityOrigin()->domain();
}
-void Document::setDomain(const String& newDomain)
+void Document::setDomain(const String& newDomain, ExceptionCode& ec)
{
// Both NS and IE specify that changing the domain is only allowed when
// the new domain is a suffix of the old domain.
@@ -3062,19 +3156,25 @@ void Document::setDomain(const String& newDomain)
int oldLength = domain().length();
int newLength = newDomain.length();
// e.g. newDomain = webkit.org (10) and domain() = www.webkit.org (14)
- if (newLength >= oldLength)
+ if (newLength >= oldLength) {
+ ec = SECURITY_ERR;
return;
+ }
String test = domain();
// Check that it's a subdomain, not e.g. "ebkit.org"
- if (test[oldLength - newLength - 1] != '.')
+ if (test[oldLength - newLength - 1] != '.') {
+ ec = SECURITY_ERR;
return;
+ }
// Now test is "webkit.org" from domain()
// and we check that it's the same thing as newDomain
test.remove(0, oldLength - newLength);
- if (test != newDomain)
+ if (test != newDomain) {
+ ec = SECURITY_ERR;
return;
+ }
securityOrigin()->setDomainFromDOM(newDomain);
if (m_frame)
@@ -3870,13 +3970,11 @@ void Document::applyXSLTransform(ProcessingInstruction* pi)
processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, frame());
}
-void Document::setTransformSource(void* doc)
+void Document::setTransformSource(PassOwnPtr<TransformSource> source)
{
- if (doc == m_transformSource)
+ if (m_transformSource == source)
return;
-
- xmlFreeDoc((xmlDocPtr)m_transformSource);
- m_transformSource = doc;
+ m_transformSource = source;
}
#endif
@@ -3946,7 +4044,7 @@ PassRefPtr<Attr> Document::createAttributeNS(const String& namespaceURI, const S
// FIXME: Assume this is a mapped attribute, since createAttribute isn't namespace-aware. There's no harm to XML
// documents if we're wrong.
- return new Attr(0, this, MappedAttribute::create(qName, StringImpl::empty()));
+ return Attr::create(0, this, MappedAttribute::create(qName, StringImpl::empty()));
}
#if ENABLE(SVG)
@@ -4040,12 +4138,18 @@ CollectionCache* Document::nameCollectionInfo(CollectionType type, const AtomicS
void Document::finishedParsing()
{
setParsing(false);
+ dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
+ if (Frame* f = frame()) {
+ f->loader()->finishedParsing();
- ExceptionCode ec = 0;
- dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false), ec);
+#if ENABLE(INSPECTOR)
+ if (!page())
+ return;
- if (Frame* f = frame())
- f->loader()->finishedParsing();
+ if (InspectorController* controller = page()->inspectorController())
+ controller->mainResourceFiredDOMContentEvent(f->loader()->documentLoader(), url());
+#endif
+ }
}
Vector<String> Document::formElementsState() const
@@ -4247,7 +4351,7 @@ void Document::initSecurityContext()
if (!m_frame) {
// No source for a security context.
// This can occur via document.implementation.createDocument().
- m_cookieURL = KURL("");
+ m_cookieURL = KURL(ParsedURLString, "");
ScriptExecutionContext::setSecurityOrigin(SecurityOrigin::createEmpty());
return;
}
@@ -4258,7 +4362,7 @@ void Document::initSecurityContext()
m_cookieURL = url;
ScriptExecutionContext::setSecurityOrigin(SecurityOrigin::create(url));
- if (FrameLoader::allowSubstituteDataAccessToLocal()) {
+ if (SecurityOrigin::allowSubstituteDataAccessToLocal()) {
// If this document was loaded with substituteData, then the document can
// load local resources. See https://bugs.webkit.org/show_bug.cgi?id=16756
// and https://bugs.webkit.org/show_bug.cgi?id=19760 for further
@@ -4448,7 +4552,7 @@ void Document::detachRange(Range* range)
m_ranges.remove(range);
}
-CanvasRenderingContext2D* Document::getCSSCanvasContext(const String& type, const String& name, int width, int height)
+CanvasRenderingContext* Document::getCSSCanvasContext(const String& type, const String& name, int width, int height)
{
HTMLCanvasElement* result = getCSSCanvasElement(name);
if (!result)
@@ -4531,10 +4635,12 @@ void Document::reportException(const String& errorMessage, int lineNumber, const
void Document::addMessage(MessageDestination destination, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
{
switch (destination) {
+#if ENABLE(INSPECTOR)
case InspectorControllerDestination:
if (page())
page()->inspectorController()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL);
return;
+#endif
case ConsoleDestination:
if (DOMWindow* window = domWindow())
window->console()->addMessage(source, type, level, message, lineNumber, sourceURL);
@@ -4545,8 +4651,10 @@ void Document::addMessage(MessageDestination destination, MessageSource source,
void Document::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString)
{
+#if ENABLE(INSPECTOR)
if (page())
page()->inspectorController()->resourceRetrievedByXMLHttpRequest(identifier, sourceString);
+#endif
Frame* frame = this->frame();
if (frame) {
FrameLoader* frameLoader = frame->loader();
@@ -4556,8 +4664,13 @@ void Document::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const
void Document::scriptImported(unsigned long identifier, const String& sourceString)
{
+#if ENABLE(INSPECTOR)
if (page())
page()->inspectorController()->scriptImported(identifier, sourceString);
+#else
+ UNUSED_PARAM(identifier);
+ UNUSED_PARAM(sourceString);
+#endif
}
class ScriptExecutionContextTaskTimer : public TimerBase {
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index fc4dc7e..fc2eea0 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -33,18 +33,12 @@
#include "CollectionType.h"
#include "Color.h"
#include "DocumentMarker.h"
+#include "Page.h"
#include "ScriptExecutionContext.h"
#include "Timer.h"
#include <wtf/HashCountedSet.h>
-
-// FIXME: We should move Mac off of the old Frame-based user stylesheet loading
-// code and onto the new code in Page. We can't do that until the code in Page
-// supports non-file: URLs, however.
-#if PLATFORM(MAC) || PLATFORM(QT)
-#define FRAME_LOADS_USER_STYLESHEET 1
-#else
-#define FRAME_LOADS_USER_STYLESHEET 0
-#endif
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -53,7 +47,7 @@ namespace WebCore {
class CDATASection;
class CachedCSSStyleSheet;
class CachedScript;
- class CanvasRenderingContext2D;
+ class CanvasRenderingContext;
class CharacterData;
class CSSStyleDeclaration;
class CSSStyleSelector;
@@ -83,12 +77,12 @@ namespace WebCore {
class HTMLHeadElement;
class HTMLInputElement;
class HTMLMapElement;
+ class InspectorTimelineAgent;
class IntPoint;
class JSNode;
class MouseEventWithHitTestResults;
class NodeFilter;
class NodeIterator;
- class Page;
class PlatformMouseEvent;
class ProcessingInstruction;
class Range;
@@ -111,6 +105,10 @@ namespace WebCore {
class SVGDocumentExtensions;
#endif
+#if ENABLE(XSLT)
+ class TransformSource;
+#endif
+
#if ENABLE(XBL)
class XBLBindingManager;
#endif
@@ -172,19 +170,16 @@ class Document : public ContainerNode, public ScriptExecutionContext {
public:
static PassRefPtr<Document> create(Frame* frame)
{
- return new Document(frame, false);
+ return adoptRef(new Document(frame, false));
}
static PassRefPtr<Document> createXHTML(Frame* frame)
{
- return new Document(frame, true);
+ return adoptRef(new Document(frame, true));
}
virtual ~Document();
- virtual bool isDocument() const { return true; }
-
using ContainerNode::ref;
using ContainerNode::deref;
- virtual void removedLastRef();
// Nodes belonging to this document hold "self-only" references -
// these are enough to keep the document from being destroyed, but
@@ -211,10 +206,52 @@ public:
// DOM methods & attributes for Document
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+
+ // WebKit extensions
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
+
DocumentType* doctype() const { return m_docType.get(); }
DOMImplementation* implementation() const;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
Element* documentElement() const
{
@@ -240,6 +277,8 @@ public:
bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); }
Element* elementFromPoint(int x, int y) const;
+ PassRefPtr<Range> caretRangeFromPoint(int x, int y);
+
String readyState() const;
String defaultCharset() const;
@@ -299,11 +338,6 @@ public:
CollectionCache* nameCollectionInfo(CollectionType, const AtomicString& name);
- // DOM methods overridden from parent classes
-
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
-
// Other methods (not part of DOM)
virtual bool isHTMLDocument() const { return false; }
virtual bool isImageDocument() const { return false; }
@@ -392,6 +426,9 @@ public:
Frame* frame() const { return m_frame; } // can be NULL
Page* page() const; // can be NULL
Settings* settings() const; // can be NULL
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* inspectorTimelineAgent() const; // can be NULL
+#endif
PassRefPtr<Range> createRange();
@@ -455,17 +492,15 @@ public:
virtual String userAgent(const KURL&) const;
- // from cachedObjectClient
- virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
-
-#if FRAME_LOADS_USER_STYLESHEET
- void setUserStyleSheet(const String& sheet);
-#endif
+ CSSStyleSheet* pageUserSheet();
+ void clearPageUserSheet();
- String userStyleSheet() const;
+ const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets() const;
+ void clearPageGroupUserSheets();
CSSStyleSheet* elementSheet();
CSSStyleSheet* mappedElementSheet();
+
virtual Tokenizer* createTokenizer();
Tokenizer* tokenizer() { return m_tokenizer; }
@@ -474,10 +509,6 @@ public:
enum ParseMode { Compat, AlmostStrict, Strict };
-private:
- virtual void determineParseMode() {}
-
-public:
void setParseMode(ParseMode m) { m_parseMode = m; }
ParseMode parseMode() const { return m_parseMode; }
@@ -506,11 +537,6 @@ public:
MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const IntPoint&, const PlatformMouseEvent&);
- virtual bool childTypeAllowed(NodeType);
- virtual PassRefPtr<Node> cloneNode(bool deep);
-
- virtual bool canReplaceChild(Node* newChild, Node* oldChild);
-
StyleSheetList* styleSheets();
/* Newly proposed CSS3 mechanism for selecting alternate
@@ -570,9 +596,8 @@ public:
// Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists.
void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
EventListener* getWindowAttributeEventListener(const AtomicString& eventType);
- void dispatchWindowEvent(PassRefPtr<Event>);
- void dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg);
- void dispatchLoadEvent();
+ void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0);
+ void dispatchWindowLoadEvent();
PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);
@@ -661,7 +686,7 @@ public:
String referrer() const;
String domain() const;
- void setDomain(const String& newDomain);
+ void setDomain(const String& newDomain, ExceptionCode&);
String lastModified() const;
@@ -735,10 +760,11 @@ public:
#if ENABLE(XSLT)
void applyXSLTransform(ProcessingInstruction* pi);
- void setTransformSource(void* doc);
- const void* transformSource() { return m_transformSource; }
PassRefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; }
+
+ void setTransformSource(PassOwnPtr<TransformSource>);
+ TransformSource* transformSource() const { return m_transformSource.get(); }
#endif
#if ENABLE(XBL)
@@ -751,8 +777,6 @@ public:
void setDocType(PassRefPtr<DocumentType>);
- virtual void finishedParsing();
-
#if ENABLE(XPATH)
// XPathEvaluator methods
PassRefPtr<XPathExpression> createExpression(const String& expression,
@@ -785,7 +809,7 @@ public:
void updateFocusAppearanceSoon();
void cancelFocusAppearanceUpdate();
-
+
#ifdef ANDROID_MOBILE
void setExtraLayoutDelay(int delay) { mExtraLayoutDelay = delay; }
int extraLayoutDelay() { return mExtraLayoutDelay; }
@@ -795,11 +819,10 @@ public:
DOMSelection* getSelection() const;
// Extension for manipulating canvas drawing contexts for use in CSS
- CanvasRenderingContext2D* getCSSCanvasContext(const String& type, const String& name, int width, int height);
+ CanvasRenderingContext* getCSSCanvasContext(const String& type, const String& name, int width, int height);
HTMLCanvasElement* getCSSCanvasElement(const String& name);
bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
- void initDNSPrefetch();
void parseDNSPrefetchControlHeader(const String&);
virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
@@ -808,10 +831,92 @@ public:
virtual void scriptImported(unsigned long, const String&);
virtual void postTask(PassRefPtr<Task>); // Executes the task on context's thread asynchronously.
+ typedef HashMap<WebCore::Node*, JSNode*> JSWrapperCache;
+ JSWrapperCache& wrapperCache() { return m_wrapperCache; }
+
+ virtual void finishedParsing();
+
+ bool inPageCache() const { return m_inPageCache; }
+ void setInPageCache(bool flag);
+
+ // Elements can register themselves for the "documentWillBecomeInactive()" and
+ // "documentDidBecomeActive()" callbacks
+ void registerForDocumentActivationCallbacks(Element*);
+ void unregisterForDocumentActivationCallbacks(Element*);
+ void documentWillBecomeInactive();
+ void documentDidBecomeActive();
+
+ void registerForMediaVolumeCallbacks(Element*);
+ void unregisterForMediaVolumeCallbacks(Element*);
+ void mediaVolumeDidChange();
+
+ void setShouldCreateRenderers(bool);
+ bool shouldCreateRenderers();
+
+ void setDecoder(PassRefPtr<TextResourceDecoder>);
+ TextResourceDecoder* decoder() const { return m_decoder.get(); }
+
+ String displayStringModifiedByEncoding(const String&) const;
+ PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl>) const;
+ void displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const;
+
+ // Quirk for the benefit of Apple's Dictionary application.
+ void setFrameElementsShouldIgnoreScrolling(bool ignore) { m_frameElementsShouldIgnoreScrolling = ignore; }
+ bool frameElementsShouldIgnoreScrolling() const { return m_frameElementsShouldIgnoreScrolling; }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ void setDashboardRegionsDirty(bool f) { m_dashboardRegionsDirty = f; }
+ bool dashboardRegionsDirty() const { return m_dashboardRegionsDirty; }
+ bool hasDashboardRegions () const { return m_hasDashboardRegions; }
+ void setHasDashboardRegions(bool f) { m_hasDashboardRegions = f; }
+ const Vector<DashboardRegionValue>& dashboardRegions() const;
+ void setDashboardRegions(const Vector<DashboardRegionValue>&);
+#endif
+
+ virtual void removeAllEventListeners();
+
+ CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+
+#if ENABLE(SVG)
+ const SVGDocumentExtensions* svgExtensions();
+ SVGDocumentExtensions* accessSVGExtensions();
+#endif
+
+ void initSecurityContext();
+
+ // Explicitly override the security origin for this document.
+ // Note: It is dangerous to change the security origin of a document
+ // that already contains content.
+ void setSecurityOrigin(SecurityOrigin*);
+
+ bool processingLoadEvent() const { return m_processingLoadEvent; }
+
+#if ENABLE(DATABASE)
+ void addOpenDatabase(Database*);
+ void removeOpenDatabase(Database*);
+ DatabaseThread* databaseThread(); // Creates the thread as needed, but not if it has been already terminated.
+ void setHasOpenDatabases() { m_hasOpenDatabases = true; }
+ bool hasOpenDatabases() { return m_hasOpenDatabases; }
+ void stopDatabases();
+#endif
+
+ void setUsingGeolocation(bool f) { m_usingGeolocation = f; }
+ bool usingGeolocation() const { return m_usingGeolocation; };
+
+#if ENABLE(WML)
+ void setContainsWMLContent(bool value) { m_containsWMLContent = value; }
+ bool containsWMLContent() const { return m_containsWMLContent; }
+
+ void resetWMLPageState();
+ void initializeWMLPageState();
+#endif
+
protected:
Document(Frame*, bool isXHTML);
- void setStyleSelector(CSSStyleSelector* styleSelector) { m_styleSelector = styleSelector; }
+ void setStyleSelector(CSSStyleSelector* styleSelector) { m_styleSelector = styleSelector; }
+
+ void clearXMLVersion() { m_xmlVersion = String(); }
#if ENABLE(TOUCH_EVENTS) // Android
public:
@@ -826,16 +931,36 @@ private:
#endif // ENABLE(TOUCH_EVENTS)
private:
+ virtual bool isDocument() const { return true; }
+ virtual void removedLastRef();
+ virtual void determineParseMode() { }
+
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ virtual String nodeName() const;
+ virtual NodeType nodeType() const;
+ virtual bool childTypeAllowed(NodeType);
+ virtual PassRefPtr<Node> cloneNode(bool deep);
+ virtual bool canReplaceChild(Node* newChild, Node* oldChild);
+
virtual void refScriptExecutionContext() { ref(); }
virtual void derefScriptExecutionContext() { deref(); }
virtual const KURL& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
+ void initDNSPrefetch();
+
String encoding() const;
void executeScriptSoonTimerFired(Timer<Document>*);
+ void updateTitle();
+ void updateFocusAppearanceTimerFired(Timer<Document>*);
+ void updateBaseURL();
+
+ void cacheDocumentElement() const;
+
CSSStyleSelector* m_styleSelector;
bool m_didCalculateStyleSelector;
@@ -863,11 +988,6 @@ private:
RefPtr<DocumentType> m_docType;
mutable RefPtr<DOMImplementation> m_implementation;
- RefPtr<StyleSheet> m_sheet;
-#if FRAME_LOADS_USER_STYLESHEET
- String m_usersheet;
-#endif
-
// Track the number of currently loading top-level stylesheets. Sheets
// loaded using the @import directive are not included in this count.
// We use this count of pending sheets to detect when we can begin attaching
@@ -887,6 +1007,9 @@ private:
RefPtr<CSSStyleSheet> m_elemSheet;
RefPtr<CSSStyleSheet> m_mappedElementSheet;
+ RefPtr<CSSStyleSheet> m_pageUserSheet;
+ mutable OwnPtr<Vector<RefPtr<CSSStyleSheet> > > m_pageGroupUserSheets;
+ mutable bool m_pageGroupUserSheetCacheValid;
bool m_printing;
@@ -963,7 +1086,7 @@ private:
Timer<Document> m_executeScriptSoonTimer;
#if ENABLE(XSLT)
- void* m_transformSource;
+ OwnPtr<TransformSource> m_transformSource;
RefPtr<Document> m_transformSourceDocument;
#endif
@@ -974,8 +1097,6 @@ private:
typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName;
ImageMapsByName m_imageMapsByName;
- HashSet<Node*> m_disconnectedNodesWithEventListeners;
-
int m_docID; // A unique document identifier used for things like document-specific mapped attributes.
String m_xmlEncoding;
@@ -988,96 +1109,6 @@ private:
bool m_shouldProcessNoScriptElement;
#endif
-public:
- bool inPageCache() const { return m_inPageCache; }
- void setInPageCache(bool flag);
-
- // Elements can register themselves for the "documentWillBecomeInactive()" and
- // "documentDidBecomeActive()" callbacks
- void registerForDocumentActivationCallbacks(Element*);
- void unregisterForDocumentActivationCallbacks(Element*);
- void documentWillBecomeInactive();
- void documentDidBecomeActive();
-
- void registerForMediaVolumeCallbacks(Element*);
- void unregisterForMediaVolumeCallbacks(Element*);
- void mediaVolumeDidChange();
-
- void setShouldCreateRenderers(bool);
- bool shouldCreateRenderers();
-
- void setDecoder(PassRefPtr<TextResourceDecoder>);
- TextResourceDecoder* decoder() const { return m_decoder.get(); }
-
- String displayStringModifiedByEncoding(const String&) const;
- PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl>) const;
- void displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const;
-
- // Quirk for the benefit of Apple's Dictionary application.
- void setFrameElementsShouldIgnoreScrolling(bool ignore) { m_frameElementsShouldIgnoreScrolling = ignore; }
- bool frameElementsShouldIgnoreScrolling() const { return m_frameElementsShouldIgnoreScrolling; }
-
-#if ENABLE(DASHBOARD_SUPPORT)
- void setDashboardRegionsDirty(bool f) { m_dashboardRegionsDirty = f; }
- bool dashboardRegionsDirty() const { return m_dashboardRegionsDirty; }
- bool hasDashboardRegions () const { return m_hasDashboardRegions; }
- void setHasDashboardRegions(bool f) { m_hasDashboardRegions = f; }
- const Vector<DashboardRegionValue>& dashboardRegions() const;
- void setDashboardRegions(const Vector<DashboardRegionValue>&);
-#endif
-
- void removeAllEventListeners();
-
- void registerDisconnectedNodeWithEventListeners(Node*);
- void unregisterDisconnectedNodeWithEventListeners(Node*);
-
- CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
-
-#if ENABLE(SVG)
- const SVGDocumentExtensions* svgExtensions();
- SVGDocumentExtensions* accessSVGExtensions();
-#endif
-
- void initSecurityContext();
-
- // Explicitly override the security origin for this document.
- // Note: It is dangerous to change the security origin of a document
- // that already contains content.
- void setSecurityOrigin(SecurityOrigin*);
-
- bool processingLoadEvent() const { return m_processingLoadEvent; }
-
-#if ENABLE(DATABASE)
- void addOpenDatabase(Database*);
- void removeOpenDatabase(Database*);
- DatabaseThread* databaseThread(); // Creates the thread as needed, but not if it has been already terminated.
- void setHasOpenDatabases() { m_hasOpenDatabases = true; }
- bool hasOpenDatabases() { return m_hasOpenDatabases; }
- void stopDatabases();
-#endif
-
- void setUsingGeolocation(bool f) { m_usingGeolocation = f; }
- bool usingGeolocation() const { return m_usingGeolocation; };
-
-#if ENABLE(WML)
- void setContainsWMLContent(bool value) { m_containsWMLContent = value; }
- bool containsWMLContent() const { return m_containsWMLContent; }
-
- void resetWMLPageState();
- void initializeWMLPageState();
-#endif
-
-protected:
- void clearXMLVersion() { m_xmlVersion = String(); }
-
-private:
- void updateTitle();
- void removeAllDisconnectedNodeEventListeners();
- void updateFocusAppearanceTimerFired(Timer<Document>*);
- void updateBaseURL();
-
- void cacheDocumentElement() const;
-
RenderObject* m_savedRenderer;
int m_secureForms;
@@ -1131,10 +1162,6 @@ private:
unsigned m_numNodeListCaches;
-public:
- typedef HashMap<WebCore::Node*, JSNode*> JSWrapperCache;
- JSWrapperCache& wrapperCache() { return m_wrapperCache; }
-private:
JSWrapperCache m_wrapperCache;
#if ENABLE(DATABASE)
@@ -1163,9 +1190,15 @@ inline bool Document::hasElementWithId(AtomicStringImpl* id) const
inline bool Node::isDocumentNode() const
{
- return this == m_document.get();
+ return this == m_document;
}
+#if ENABLE(INSPECTOR)
+inline InspectorTimelineAgent* Document::inspectorTimelineAgent() const {
+ return page() ? page()->inspectorTimelineAgent() : 0;
+}
+#endif
+
} // namespace WebCore
#endif // Document_h
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index cd3ec77..e7a43c7 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -35,7 +35,7 @@ module core {
readonly attribute [V8Custom] DOMImplementation implementation;
readonly attribute Element documentElement;
- [ReturnsNew] Element createElement(in [ConvertNullToNullString] DOMString tagName)
+ [ReturnsNew] Element createElement(in [ConvertNullToNullString, HintAtomic] DOMString tagName)
raises (DOMException);
DocumentFragment createDocumentFragment();
[ReturnsNew] Text createTextNode(in DOMString data);
@@ -64,7 +64,7 @@ module core {
raises (DOMException);
[OldStyleObjC] NodeList getElementsByTagNameNS(in [ConvertNullToNullString] DOMString namespaceURI,
in DOMString localName);
- Element getElementById(in [V8Custom=HintAtomic] DOMString elementId);
+ Element getElementById(in [HintAtomic] DOMString elementId);
// DOM Level 3 Core
@@ -155,7 +155,8 @@ module core {
attribute [ConvertNullToNullString] DOMString title;
readonly attribute DOMString referrer;
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
- attribute [ConvertNullToNullString] DOMString domain;
+ attribute [ConvertNullToNullString] DOMString domain
+ setter raises (DOMException);
#else
readonly attribute DOMString domain;
#endif
@@ -191,6 +192,9 @@ module core {
readonly attribute [ConvertNullStringTo=Undefined] DOMString readyState;
Element elementFromPoint(in long x, in long y);
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+ Range caretRangeFromPoint(in long x, in long y);
+#endif
// Mozilla extensions
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
@@ -264,6 +268,7 @@ module core {
attribute [DontEnum] EventListener onerror;
attribute [DontEnum] EventListener onfocus;
attribute [DontEnum] EventListener oninput;
+ attribute [DontEnum] EventListener oninvalid;
attribute [DontEnum] EventListener onkeydown;
attribute [DontEnum] EventListener onkeypress;
attribute [DontEnum] EventListener onkeyup;
@@ -291,7 +296,6 @@ module core {
// attribute [DontEnum] EventListener onended;
// attribute [DontEnum] EventListener onformchange;
// attribute [DontEnum] EventListener onforminput;
- // attribute [DontEnum] EventListener oninvalid;
// attribute [DontEnum] EventListener onloadeddata;
// attribute [DontEnum] EventListener onloadedmetadata;
// attribute [DontEnum] EventListener onloadstart;
diff --git a/WebCore/dom/DocumentFragment.cpp b/WebCore/dom/DocumentFragment.cpp
index 7a6174f..3663e99 100644
--- a/WebCore/dom/DocumentFragment.cpp
+++ b/WebCore/dom/DocumentFragment.cpp
@@ -1,10 +1,8 @@
-/**
- * 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 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006, 2009 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
@@ -23,13 +21,18 @@
*/
#include "config.h"
-
#include "DocumentFragment.h"
namespace WebCore {
-DocumentFragment::DocumentFragment(Document *doc) : ContainerNode(doc)
+inline DocumentFragment::DocumentFragment(Document* document)
+ : ContainerNode(document)
+{
+}
+
+PassRefPtr<DocumentFragment> DocumentFragment::create(Document* document)
{
+ return adoptRef(new DocumentFragment(document));
}
String DocumentFragment::nodeName() const
@@ -42,7 +45,6 @@ Node::NodeType DocumentFragment::nodeType() const
return DOCUMENT_FRAGMENT_NODE;
}
-// DOM Section 1.1.1
bool DocumentFragment::childTypeAllowed(NodeType type)
{
switch (type) {
@@ -60,7 +62,7 @@ bool DocumentFragment::childTypeAllowed(NodeType type)
PassRefPtr<Node> DocumentFragment::cloneNode(bool deep)
{
- RefPtr<DocumentFragment> clone = new DocumentFragment(document());
+ RefPtr<DocumentFragment> clone = create(document());
if (deep)
cloneChildNodes(clone.get());
return clone.release();
diff --git a/WebCore/dom/DocumentFragment.h b/WebCore/dom/DocumentFragment.h
index 46d8ecd..e624ee4 100644
--- a/WebCore/dom/DocumentFragment.h
+++ b/WebCore/dom/DocumentFragment.h
@@ -1,10 +1,8 @@
/*
- * 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 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006, 2009 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,6 +30,9 @@ namespace WebCore {
class DocumentFragment : public ContainerNode {
public:
+ static PassRefPtr<DocumentFragment> create(Document*);
+
+private:
DocumentFragment(Document*);
virtual String nodeName() const;
diff --git a/WebCore/dom/DocumentType.cpp b/WebCore/dom/DocumentType.cpp
index 885a65b..b8185e7 100644
--- a/WebCore/dom/DocumentType.cpp
+++ b/WebCore/dom/DocumentType.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, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009 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
@@ -29,11 +29,11 @@
namespace WebCore {
-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* document, const String& name, const String& publicId, const String& systemId)
+ : Node(document, CreateOther)
+ , m_name(name)
+ , m_publicId(publicId)
+ , m_systemId(systemId)
{
}
@@ -54,7 +54,7 @@ Node::NodeType DocumentType::nodeType() const
PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
{
- return new DocumentType(document(), m_name, m_publicId, m_systemId);
+ return create(document(), m_name, m_publicId, m_systemId);
}
void DocumentType::insertedIntoDocument()
diff --git a/WebCore/dom/DocumentType.h b/WebCore/dom/DocumentType.h
index 9fd3c6e..4f89d01 100644
--- a/WebCore/dom/DocumentType.h
+++ b/WebCore/dom/DocumentType.h
@@ -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, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009 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
@@ -34,7 +34,7 @@ class DocumentType : public Node {
public:
static PassRefPtr<DocumentType> create(Document* document, const String& name, const String& publicId, const String& systemId)
{
- return new DocumentType(document, name, publicId, systemId);
+ return adoptRef(new DocumentType(document, name, publicId, systemId));
}
NamedNodeMap* entities() const { return m_entities.get(); }
diff --git a/WebCore/dom/EditingText.cpp b/WebCore/dom/EditingText.cpp
index 40cf97d..b36931a 100644
--- a/WebCore/dom/EditingText.cpp
+++ b/WebCore/dom/EditingText.cpp
@@ -1,9 +1,5 @@
-/**
- * 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)
- * Copyright (C) 2003 Apple Computer, Inc.
+/*
+ * Copyright (C) 2003, 2009 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
@@ -24,24 +20,19 @@
#include "config.h"
#include "EditingText.h"
-// FIXME: does this really require a class? Perhaps any Text node
-// inside an editable element should have the "always create a renderer"
-// behavior.
+// FIXME: Does this really require a class? Perhaps instead any text node
+// inside an editable element could have the "always create a renderer" behavior.
namespace WebCore {
-EditingText::EditingText(Document *impl, const String &text)
- : Text(impl, text)
-{
-}
-
-EditingText::EditingText(Document *impl)
- : Text(impl)
+inline EditingText::EditingText(Document* document, const String& data)
+ : Text(document, data)
{
}
-EditingText::~EditingText()
+PassRefPtr<EditingText> EditingText::create(Document* document, const String& data)
{
+ return adoptRef(new EditingText(document, data));
}
bool EditingText::rendererIsNeeded(RenderStyle*)
diff --git a/WebCore/dom/EditingText.h b/WebCore/dom/EditingText.h
index e114786..08223c2 100644
--- a/WebCore/dom/EditingText.h
+++ b/WebCore/dom/EditingText.h
@@ -1,9 +1,5 @@
/*
- * 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)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 2009 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
@@ -31,11 +27,12 @@ namespace WebCore {
class EditingText : public Text {
public:
- EditingText(Document *impl, const String &text);
- EditingText(Document *impl);
- virtual ~EditingText();
+ static PassRefPtr<EditingText> create(Document*, const String&);
+private:
virtual bool rendererIsNeeded(RenderStyle *);
+
+ EditingText(Document*, const String&);
};
} // namespace WebCore
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 1956be4..50ff033 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -28,6 +28,8 @@
#include "AXObjectCache.h"
#include "Attr.h"
+#include "CSSParser.h"
+#include "CSSSelectorList.h"
#include "CSSStyleSelector.h"
#include "CString.h"
#include "ClientRect.h"
@@ -57,12 +59,17 @@ namespace WebCore {
using namespace HTMLNames;
using namespace XMLNames;
-Element::Element(const QualifiedName& tagName, Document* doc)
- : ContainerNode(doc, true)
+Element::Element(const QualifiedName& tagName, Document* document, ConstructionType type)
+ : ContainerNode(document, type)
, m_tagName(tagName)
{
}
+PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new Element(tagName, document, CreateElement));
+}
+
Element::~Element()
{
if (namedAttrMap)
@@ -275,42 +282,6 @@ static int adjustForLocalZoom(int value, RenderObject* renderer)
return static_cast<int>(value / zoomFactor);
}
-static int adjustForAbsoluteZoom(int value, RenderObject* renderer)
-{
- float zoomFactor = renderer->style()->effectiveZoom();
- if (zoomFactor == 1)
- return value;
- // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
- if (zoomFactor > 1)
- value++;
- return static_cast<int>(value / zoomFactor);
-}
-
-static FloatPoint adjustFloatPointForAbsoluteZoom(const FloatPoint& point, RenderObject* renderer)
-{
- // The result here is in floats, so we don't need the truncation hack from the integer version above.
- float zoomFactor = renderer->style()->effectiveZoom();
- if (zoomFactor == 1)
- return point;
- return FloatPoint(point.x() / zoomFactor, point.y() / zoomFactor);
-}
-
-static void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject* renderer)
-{
- quad.setP1(adjustFloatPointForAbsoluteZoom(quad.p1(), renderer));
- quad.setP2(adjustFloatPointForAbsoluteZoom(quad.p2(), renderer));
- quad.setP3(adjustFloatPointForAbsoluteZoom(quad.p3(), renderer));
- quad.setP4(adjustFloatPointForAbsoluteZoom(quad.p4(), renderer));
-}
-
-static void adjustIntRectForAbsoluteZoom(IntRect& rect, RenderObject* renderer)
-{
- rect.setX(adjustForAbsoluteZoom(rect.x(), renderer));
- rect.setY(adjustForAbsoluteZoom(rect.y(), renderer));
- rect.setWidth(adjustForAbsoluteZoom(rect.width(), renderer));
- rect.setHeight(adjustForAbsoluteZoom(rect.height(), renderer));
-}
-
int Element::offsetLeft()
{
document()->updateLayoutIgnorePendingStylesheets();
@@ -597,16 +568,20 @@ void Element::attributeChanged(Attribute* attr, bool)
void Element::updateAfterAttributeChanged(Attribute* attr)
{
- if (!document()->axObjectCache()->accessibilityEnabled())
+ AXObjectCache* axObjectCache = document()->axObjectCache();
+ if (!axObjectCache->accessibilityEnabled())
return;
const QualifiedName& attrName = attr->name();
if (attrName == aria_activedescendantAttr) {
// any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact
- document()->axObjectCache()->handleActiveDescendantChanged(renderer());
+ axObjectCache->handleActiveDescendantChanged(renderer());
} else if (attrName == roleAttr) {
// the role attribute can change at any time, and the AccessibilityObject must pick up these changes
- document()->axObjectCache()->handleAriaRoleChanged(renderer());
+ axObjectCache->handleAriaRoleChanged(renderer());
+ } else if (attrName == aria_valuenowAttr) {
+ // If the valuenow attribute changes, AX clients need to be notified.
+ axObjectCache->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
}
}
@@ -677,7 +652,7 @@ void Element::setPrefix(const AtomicString &_prefix, ExceptionCode& ec)
KURL Element::baseURI() const
{
- KURL base(getAttribute(baseAttr));
+ KURL base(KURL(), getAttribute(baseAttr));
if (!base.protocol().isEmpty())
return base;
@@ -804,7 +779,8 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS
void Element::recalcStyle(StyleChange change)
{
- RenderStyle* currentStyle = renderStyle();
+ // Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
+ RefPtr<RenderStyle> currentStyle(renderStyle());
bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
bool hasPositionalRules = needsStyleRecalc() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
@@ -820,7 +796,7 @@ void Element::recalcStyle(StyleChange change)
}
if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
- StyleChange ch = diff(currentStyle, newStyle.get());
+ StyleChange ch = diff(currentStyle.get(), newStyle.get());
if (ch == Detach || !currentStyle) {
if (attached())
detach();
@@ -852,9 +828,9 @@ void Element::recalcStyle(StyleChange change)
newStyle->setChildrenAffectedByDirectAdjacentRules();
}
- if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle, newStyle.get())) {
+ if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get())) {
setRenderStyle(newStyle);
- } else if (needsStyleRecalc() && (styleChangeType() != AnimationStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
+ } else if (needsStyleRecalc() && (styleChangeType() != SyntheticStyleChange) && (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
@@ -863,7 +839,7 @@ void Element::recalcStyle(StyleChange change)
renderer()->setStyleInternal(newStyle.get());
else
setRenderStyle(newStyle);
- } else if (styleChangeType() == AnimationStyleChange)
+ } else if (styleChangeType() == SyntheticStyleChange)
setRenderStyle(newStyle);
if (change != Force) {
@@ -1215,14 +1191,24 @@ void Element::focus(bool restorePreviousSelection)
if (doc->focusedNode() == this)
return;
- doc->updateLayoutIgnorePendingStylesheets();
-
if (!supportsFocus())
return;
-
+
+ // If the stylesheets have already been loaded we can reliably check isFocusable.
+ // If not, we continue and set the focused node on the focus controller below so
+ // that it can be updated soon after attach.
+ if (doc->haveStylesheetsLoaded()) {
+ doc->updateLayoutIgnorePendingStylesheets();
+ if (!isFocusable())
+ return;
+ }
+
if (Page* page = doc->page())
page->focusController()->setFocusedNode(this, doc->frame());
+ // Setting the focused node above might have invalidated the layout due to scripts.
+ doc->updateLayoutIgnorePendingStylesheets();
+
if (!isFocusable()) {
ensureRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
return;
@@ -1386,6 +1372,39 @@ unsigned Element::childElementCount() const
return count;
}
+bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
+{
+ if (selector.isEmpty()) {
+ ec = SYNTAX_ERR;
+ return false;
+ }
+
+ bool strictParsing = !document()->inCompatMode();
+ CSSParser p(strictParsing);
+
+ CSSSelectorList selectorList;
+ p.parseSelector(selector, document(), selectorList);
+
+ if (!selectorList.first()) {
+ ec = SYNTAX_ERR;
+ return false;
+ }
+
+ // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
+ if (selectorList.selectorsNeedNamespaceResolution()) {
+ ec = NAMESPACE_ERR;
+ return false;
+ }
+
+ CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing);
+ for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
+ if (selectorChecker.checkSelector(selector, this))
+ return true;
+ }
+
+ return false;
+}
+
KURL Element::getURLAttribute(const QualifiedName& name) const
{
#ifndef NDEBUG
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index 223c26a..d27976a 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -41,8 +41,53 @@ class IntSize;
class Element : public ContainerNode {
public:
- Element(const QualifiedName&, Document*);
- ~Element();
+ static PassRefPtr<Element> create(const QualifiedName&, Document*);
+ virtual ~Element();
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
+
+ // These 4 attribute event handler attributes are overrided by HTMLBodyElement
+ // and HTMLFrameSetElement to forward to the DOMWindow.
+ DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur);
+ DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus);
+ DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load);
+
+ // WebKit extensions
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
const AtomicString& getIDAttribute() const;
bool hasAttribute(const QualifiedName&) const;
@@ -64,7 +109,6 @@ public:
void scrollIntoView(bool alignToTop = true);
void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
- void scrollByUnits(int units, ScrollGranularity);
void scrollByLines(int lines);
void scrollByPages(int pages);
@@ -108,17 +152,11 @@ public:
const AtomicString& localName() const { return m_tagName.localName(); }
const AtomicString& prefix() const { return m_tagName.prefix(); }
- virtual void setPrefix(const AtomicString&, ExceptionCode&);
const AtomicString& namespaceURI() const { return m_tagName.namespaceURI(); }
virtual KURL baseURI() const;
- // DOM methods overridden from parent classes
- virtual NodeType nodeType() const;
virtual String nodeName() const;
- virtual void insertedIntoDocument();
- virtual void removedFromDocument();
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
PassRefPtr<Element> cloneElementWithChildren();
PassRefPtr<Element> cloneElementWithoutChildren();
@@ -136,13 +174,9 @@ public:
// This method is called whenever an attribute is added, changed or removed.
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
- // The implementation of Element::attributeChanged() calls the following two functions.
- // They are separated to allow a different flow of control in StyledElement::attributeChanged().
- void recalcStyleIfNeededAfterAttributeChanged(Attribute*);
- void updateAfterAttributeChanged(Attribute*);
-
// not part of the DOM
void setAttributeMap(PassRefPtr<NamedNodeMap>);
+ NamedNodeMap* attributeMap() const { return namedAttrMap.get(); }
virtual void copyNonAttributeProperties(const Element* /*source*/) { }
@@ -153,10 +187,6 @@ public:
virtual RenderStyle* computedStyle();
- virtual bool childTypeAllowed(NodeType);
-
- virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
-
void dispatchAttrRemovalEvent(Attribute*);
void dispatchAttrAdditionEvent(Attribute*);
@@ -166,16 +196,11 @@ public:
KURL getURLAttribute(const QualifiedName&) const;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual String target() const { return String(); }
+
virtual void focus(bool restorePreviousSelection = true);
virtual void updateFocusAppearance(bool restorePreviousSelection);
void blur();
-#ifndef NDEBUG
- virtual void formatForDebugger(char* buffer, unsigned length) const;
-#endif
-
- bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
-
String innerText() const;
String outerText() const;
@@ -206,13 +231,17 @@ public:
Element* nextElementSibling() const;
unsigned childElementCount() const;
- // FormControlElement API
+ bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
+
virtual bool isFormControlElement() const { return false; }
virtual bool isEnabledFormControl() const { return true; }
virtual bool isReadOnlyFormControl() const { return false; }
virtual bool isTextFormControl() const { return false; }
virtual bool isOptionalFormControl() const { return false; }
virtual bool isRequiredFormControl() const { return false; }
+ virtual bool isDefaultButtonForForm() const { return false; }
+ virtual bool willValidate() const { return false; }
+ virtual bool isValidFormControlElement() { return false; }
virtual bool formControlValueMatchesRenderer() const { return false; }
virtual void setFormControlValueMatchesRenderer(bool) { }
@@ -225,13 +254,39 @@ public:
virtual void dispatchFormControlChangeEvent() { }
+protected:
+ Element(const QualifiedName&, Document*, ConstructionType);
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ // The implementation of Element::attributeChanged() calls the following two functions.
+ // They are separated to allow a different flow of control in StyledElement::attributeChanged().
+ void recalcStyleIfNeededAfterAttributeChanged(Attribute*);
+ void updateAfterAttributeChanged(Attribute*);
+
private:
+ void scrollByUnits(int units, ScrollGranularity);
+
+ virtual void setPrefix(const AtomicString&, ExceptionCode&);
+ virtual NodeType nodeType() const;
+ virtual bool childTypeAllowed(NodeType);
+
+ virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
+
+#ifndef NDEBUG
+ virtual void formatForDebugger(char* buffer, unsigned length) const;
+#endif
+
+ bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
+
virtual void createAttributeMap() const;
- virtual void updateStyleAttribute() const {}
+ virtual void updateStyleAttribute() const { }
#if ENABLE(SVG)
- virtual void updateAnimatedSVGAttribute(const String&) const {}
+ virtual void updateAnimatedSVGAttribute(const String&) const { }
#endif
void updateFocusAppearanceSoonAfterAttach();
@@ -248,10 +303,10 @@ private:
QualifiedName m_tagName;
virtual NodeRareData* createRareData();
-protected:
ElementRareData* rareData() const;
ElementRareData* ensureRareData();
+protected:
mutable RefPtr<NamedNodeMap> namedAttrMap;
};
diff --git a/WebCore/dom/Element.idl b/WebCore/dom/Element.idl
index e8988e1..c24ef65 100644
--- a/WebCore/dom/Element.idl
+++ b/WebCore/dom/Element.idl
@@ -21,6 +21,7 @@
module core {
interface [
+ CustomMarkFunction,
GenerateConstructor,
GenerateNativeConverter,
InlineGetOwnPropertySlot,
@@ -110,6 +111,10 @@ module core {
raises(DOMException);
#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+ // WebKit extension, pending specification.
+ boolean webkitMatchesSelector(in DOMString selectors)
+ raises(DOMException);
+
// ElementTraversal API
readonly attribute Element firstElementChild;
readonly attribute Element lastElementChild;
@@ -148,6 +153,7 @@ module core {
attribute [DontEnum] EventListener onerror;
attribute [DontEnum] EventListener onfocus;
attribute [DontEnum] EventListener oninput;
+ attribute [DontEnum] EventListener oninvalid;
attribute [DontEnum] EventListener onkeydown;
attribute [DontEnum] EventListener onkeypress;
attribute [DontEnum] EventListener onkeyup;
@@ -175,7 +181,6 @@ module core {
// attribute [DontEnum] EventListener onended;
// attribute [DontEnum] EventListener onformchange;
// attribute [DontEnum] EventListener onforminput;
- // attribute [DontEnum] EventListener oninvalid;
// attribute [DontEnum] EventListener onloadeddata;
// attribute [DontEnum] EventListener onloadedmetadata;
// attribute [DontEnum] EventListener onloadstart;
diff --git a/WebCore/dom/EntityReference.cpp b/WebCore/dom/EntityReference.cpp
index 012605c..c4c292a 100644
--- a/WebCore/dom/EntityReference.cpp
+++ b/WebCore/dom/EntityReference.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2009 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
@@ -23,12 +23,17 @@
namespace WebCore {
-EntityReference::EntityReference(Document* document, const String& entityName)
+inline EntityReference::EntityReference(Document* document, const String& entityName)
: ContainerNode(document)
, m_entityName(entityName)
{
}
+PassRefPtr<EntityReference> EntityReference::create(Document* document, const String& entityName)
+{
+ return adoptRef(new EntityReference(document, entityName));
+}
+
String EntityReference::nodeName() const
{
return m_entityName;
@@ -41,7 +46,7 @@ Node::NodeType EntityReference::nodeType() const
PassRefPtr<Node> EntityReference::cloneNode(bool)
{
- return new EntityReference(document(), m_entityName);
+ return create(document(), m_entityName);
}
} // namespace
diff --git a/WebCore/dom/EntityReference.h b/WebCore/dom/EntityReference.h
index 4767a5e..7a6f6c3 100644
--- a/WebCore/dom/EntityReference.h
+++ b/WebCore/dom/EntityReference.h
@@ -28,13 +28,15 @@ namespace WebCore {
class EntityReference : public ContainerNode {
public:
+ static PassRefPtr<EntityReference> create(Document*, const String& entityName);
+
+private:
EntityReference(Document*, const String& entityName);
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
-private:
String m_entityName;
};
diff --git a/WebCore/dom/Event.cpp b/WebCore/dom/Event.cpp
index 4ad090b..cae4122 100644
--- a/WebCore/dom/Event.cpp
+++ b/WebCore/dom/Event.cpp
@@ -124,6 +124,11 @@ bool Event::isOverflowEvent() const
return false;
}
+bool Event::isPageTransitionEvent() const
+{
+ return false;
+}
+
bool Event::isProgressEvent() const
{
return false;
@@ -171,7 +176,7 @@ bool Event::isErrorEvent() const
return false;
}
#endif
-
+
bool Event::storesResultAsString() const
{
return false;
diff --git a/WebCore/dom/Event.h b/WebCore/dom/Event.h
index b6a9c8f..30e5d27 100644
--- a/WebCore/dom/Event.h
+++ b/WebCore/dom/Event.h
@@ -109,6 +109,7 @@ namespace WebCore {
virtual bool isWheelEvent() const;
virtual bool isBeforeTextInsertedEvent() const;
virtual bool isOverflowEvent() const;
+ virtual bool isPageTransitionEvent() const;
virtual bool isProgressEvent() const;
virtual bool isXMLHttpRequestProgressEvent() const;
virtual bool isWebKitAnimationEvent() const;
@@ -125,7 +126,7 @@ namespace WebCore {
#if ENABLE(WORKERS)
virtual bool isErrorEvent() const;
#endif
-
+
bool propagationStopped() const { return m_propagationStopped; }
bool defaultPrevented() const { return m_defaultPrevented; }
diff --git a/WebCore/dom/EventListener.h b/WebCore/dom/EventListener.h
index 7c4812f..da9d179 100644
--- a/WebCore/dom/EventListener.h
+++ b/WebCore/dom/EventListener.h
@@ -31,31 +31,46 @@ namespace JSC {
namespace WebCore {
+ class ScriptExecutionContext;
class Event;
class EventListener : public RefCounted<EventListener> {
public:
+ enum Type { JSEventListenerType,
+ ImageEventListenerType,
+ InspectorDOMAgentType,
+ InspectorDOMStorageResourceType,
+ ObjCEventListenerType,
+ ConditionEventListenerType,
+ GeolocationEventListenerType };
+
virtual ~EventListener() { }
- virtual void handleEvent(Event*, bool isWindowEvent = false) = 0;
+ virtual bool operator==(const EventListener&) = 0;
+ virtual void handleEvent(ScriptExecutionContext*, Event*) = 0;
// Return true to indicate that the error is handled.
- virtual bool reportError(const String& /*message*/, const String& /*url*/, int /*lineNumber*/) { return false; }
+ virtual bool reportError(ScriptExecutionContext*, const String& /*message*/, const String& /*url*/, int /*lineNumber*/) { return false; }
virtual bool wasCreatedFromMarkup() const { return false; }
#if USE(JSC)
- virtual JSC::JSObject* jsFunction() const { return 0; }
+ virtual JSC::JSObject* jsFunction(ScriptExecutionContext*) const { return 0; }
virtual void markJSFunction(JSC::MarkStack&) { }
#endif
bool isAttribute() const { return virtualisAttribute(); }
+ Type type() const { return m_type; }
+
+ protected:
+ EventListener(Type type)
+ : m_type(type)
+ {
+ }
private:
virtual bool virtualisAttribute() const { return false; }
+
+ Type m_type;
};
-#if USE(JSC)
- inline void markIfNotNull(JSC::MarkStack& markStack, EventListener* listener) { if (listener) listener->markJSFunction(markStack); }
-#endif
-
}
#endif
diff --git a/WebCore/dom/EventListener.idl b/WebCore/dom/EventListener.idl
index 9dc2e0a..1edf52f 100644
--- a/WebCore/dom/EventListener.idl
+++ b/WebCore/dom/EventListener.idl
@@ -24,8 +24,8 @@ module events {
interface [
NoStaticTables,
ObjCProtocol,
+ PureInterface,
InterfaceUUID=B04F2AE3-71E2-4ebe-ABFE-EF4938354082,
- ImplementationUUID=DDFDD342-A78B-4f19-8F32-A5DF51B56E08
] EventListener {
void handleEvent(in Event evt);
};
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index d28b154..31c29fb 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -32,6 +32,7 @@ namespace WebCore {
macro(abort) \
macro(beforecopy) \
macro(beforecut) \
+ macro(beforeload) \
macro(beforepaste) \
macro(beforeunload) \
macro(blur) \
@@ -45,6 +46,7 @@ namespace WebCore {
macro(copy) \
macro(cut) \
macro(dblclick) \
+ macro(display) \
macro(downloading) \
macro(drag) \
macro(dragend) \
@@ -57,10 +59,12 @@ namespace WebCore {
macro(focus) \
macro(hashchange) \
macro(input) \
+ macro(invalid) \
macro(keydown) \
macro(keypress) \
macro(keyup) \
macro(load) \
+ macro(loadend) \
macro(loadstart) \
macro(message) \
macro(mousedown) \
@@ -73,7 +77,10 @@ namespace WebCore {
macro(obsolete) \
macro(offline) \
macro(online) \
+ macro(open) \
macro(overflowchanged) \
+ macro(pagehide) \
+ macro(pageshow) \
macro(paste) \
macro(readystatechange) \
macro(reset) \
@@ -137,6 +144,8 @@ namespace WebCore {
\
macro(webkitTransitionEnd) \
\
+ macro(orientationchange) \
+ \
// end of DOM_EVENT_NAMES_FOR_EACH
class EventNames {
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index 7ba0584..ceb5221 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -34,16 +34,49 @@
#include "config.h"
#include "EventTarget.h"
+#include "Event.h"
+#include "EventException.h"
+#include <wtf/StdLibExtras.h>
+
+using namespace WTF;
+
namespace WebCore {
#ifndef NDEBUG
static int gEventDispatchForbidden = 0;
-#endif
+
+void forbidEventDispatch()
+{
+ if (!isMainThread())
+ return;
+ ++gEventDispatchForbidden;
+}
+
+void allowEventDispatch()
+{
+ if (!isMainThread())
+ return;
+ if (gEventDispatchForbidden > 0)
+ --gEventDispatchForbidden;
+}
+
+bool eventDispatchForbidden()
+{
+ if (!isMainThread())
+ return false;
+ return gEventDispatchForbidden > 0;
+}
+#endif // NDEBUG
EventTarget::~EventTarget()
{
}
+EventSource* EventTarget::toEventSource()
+{
+ return 0;
+}
+
Node* EventTarget::toNode()
{
return 0;
@@ -78,6 +111,13 @@ SVGElementInstance* EventTarget::toSVGElementInstance()
}
#endif
+#if ENABLE(WEB_SOCKETS)
+WebSocket* EventTarget::toWebSocket()
+{
+ return 0;
+}
+#endif
+
MessagePort* EventTarget::toMessagePort()
{
return 0;
@@ -106,22 +146,160 @@ SharedWorkerContext* EventTarget::toSharedWorkerContext()
}
#endif
-#ifndef NDEBUG
-void forbidEventDispatch()
+#if ENABLE(NOTIFICATIONS)
+Notification* EventTarget::toNotification()
{
- ++gEventDispatchForbidden;
+ return 0;
}
+#endif
-void allowEventDispatch()
+bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
{
- if (gEventDispatchForbidden > 0)
- --gEventDispatchForbidden;
+ EventTargetData* d = ensureEventTargetData();
+
+ pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, EventListenerVector());
+ EventListenerVector& entry = result.first->second;
+
+ RegisteredEventListener registeredListener(listener, useCapture);
+ if (!result.second) { // pre-existing entry
+ if (entry.find(registeredListener) != notFound) // duplicate listener
+ return false;
+ }
+
+ entry.append(registeredListener);
+ return true;
}
-bool eventDispatchForbidden()
+bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
{
- return gEventDispatchForbidden > 0;
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return false;
+
+ EventListenerMap::iterator result = d->eventListenerMap.find(eventType);
+ if (result == d->eventListenerMap.end())
+ return false;
+ EventListenerVector& entry = result->second;
+
+ RegisteredEventListener registeredListener(listener, useCapture);
+ size_t index = entry.find(registeredListener);
+ if (index == notFound)
+ return false;
+
+ entry.remove(index);
+ if (!entry.size())
+ d->eventListenerMap.remove(result);
+
+ // Notify firing events planning to invoke the listener at 'index' that
+ // they have one less listener to invoke.
+ for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i) {
+ if (eventType == *d->firingEventEndIterators[i].eventType && index < *d->firingEventEndIterators[i].value)
+ --*d->firingEventEndIterators[i].value;
+ }
+
+ return true;
+}
+
+bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+{
+ clearAttributeEventListener(eventType);
+ if (!listener)
+ return false;
+ return addEventListener(eventType, listener, false);
+}
+
+EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
+{
+ const EventListenerVector& entry = getEventListeners(eventType);
+ for (size_t i = 0; i < entry.size(); ++i) {
+ if (entry[i].listener->isAttribute())
+ return entry[i].listener.get();
+ }
+ return 0;
+}
+
+bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
+{
+ EventListener* listener = getAttributeEventListener(eventType);
+ if (!listener)
+ return false;
+ return removeEventListener(eventType, listener, false);
+}
+
+bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
+{
+ if (!event || event->type().isEmpty()) {
+ ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
+ return false;
+ }
+ return dispatchEvent(event);
+}
+
+bool EventTarget::dispatchEvent(PassRefPtr<Event> event)
+{
+ event->setTarget(this);
+ event->setCurrentTarget(this);
+ event->setEventPhase(Event::AT_TARGET);
+ return fireEventListeners(event.get());
+}
+
+bool EventTarget::fireEventListeners(Event* event)
+{
+ ASSERT(!eventDispatchForbidden());
+ ASSERT(event && !event->type().isEmpty());
+
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return true;
+
+ EventListenerMap::iterator result = d->eventListenerMap.find(event->type());
+ if (result == d->eventListenerMap.end())
+ return false;
+ EventListenerVector& entry = result->second;
+
+ RefPtr<EventTarget> protect = this;
+
+ size_t end = entry.size();
+ d->firingEventEndIterators.append(FiringEventEndIterator(&event->type(), &end));
+ for (size_t i = 0; i < end; ++i) {
+ RegisteredEventListener& registeredListener = entry[i];
+ if (event->eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture)
+ continue;
+ if (event->eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture)
+ continue;
+ // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
+ // event listeners, even though that violates some versions of the DOM spec.
+ registeredListener.listener->handleEvent(scriptExecutionContext(), event);
+ }
+ d->firingEventEndIterators.removeLast();
+
+ return !event->defaultPrevented();
+}
+
+const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType)
+{
+ DEFINE_STATIC_LOCAL(EventListenerVector, emptyVector, ());
+
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return emptyVector;
+ EventListenerMap::iterator it = d->eventListenerMap.find(eventType);
+ if (it == d->eventListenerMap.end())
+ return emptyVector;
+ return it->second;
+}
+
+void EventTarget::removeAllEventListeners()
+{
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return;
+ d->eventListenerMap.clear();
+
+ // Notify firing events planning to invoke the listener at 'index' that
+ // they have one less listener to invoke.
+ for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i)
+ *d->firingEventEndIterators[i].value = 0;
}
-#endif // NDEBUG
-} // end namespace
+} // namespace WebCore
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index 2ededda..2d612e1 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -32,6 +32,9 @@
#ifndef EventTarget_h
#define EventTarget_h
+#include "AtomicStringHash.h"
+#include "EventNames.h"
+#include "RegisteredEventListener.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -43,20 +46,47 @@ namespace WebCore {
class DOMWindow;
class Event;
class EventListener;
+ class EventSource;
class MessagePort;
class Node;
+ class Notification;
class SVGElementInstance;
class ScriptExecutionContext;
class SharedWorker;
class SharedWorkerContext;
+ class WebSocket;
class Worker;
class XMLHttpRequest;
class XMLHttpRequestUpload;
typedef int ExceptionCode;
+ struct FiringEventEndIterator {
+ FiringEventEndIterator(const AtomicString* eventType, size_t* value)
+ : eventType(eventType)
+ , value(value)
+ {
+ }
+
+ const AtomicString* eventType;
+ size_t* value;
+ };
+ typedef Vector<FiringEventEndIterator, 1> FiringEventEndIteratorVector;
+
+ typedef Vector<RegisteredEventListener, 1> EventListenerVector;
+ typedef HashMap<AtomicString, EventListenerVector> EventListenerMap;
+
+ struct EventTargetData {
+ EventListenerMap eventListenerMap;
+ FiringEventEndIteratorVector firingEventEndIterators;
+ };
+
class EventTarget {
public:
+ void ref() { refEventTarget(); }
+ void deref() { derefEventTarget(); }
+
+ virtual EventSource* toEventSource();
virtual MessagePort* toMessagePort();
virtual Node* toNode();
virtual DOMWindow* toDOMWindow();
@@ -72,44 +102,132 @@ namespace WebCore {
virtual Worker* toWorker();
virtual DedicatedWorkerContext* toDedicatedWorkerContext();
#endif
-
#if ENABLE(SHARED_WORKERS)
virtual SharedWorker* toSharedWorker();
virtual SharedWorkerContext* toSharedWorkerContext();
#endif
+#if ENABLE(WEB_SOCKETS)
+ virtual WebSocket* toWebSocket();
+#endif
+
+#if ENABLE(NOTIFICATIONS)
+ virtual Notification* toNotification();
+#endif
virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
- virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) = 0;
- virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) = 0;
- virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&) = 0;
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ virtual void removeAllEventListeners();
+ virtual bool dispatchEvent(PassRefPtr<Event>);
+ bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API
- void ref() { refEventTarget(); }
- void deref() { derefEventTarget(); }
+ // Used for legacy "onEvent" attribute APIs.
+ bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+ bool clearAttributeEventListener(const AtomicString& eventType);
+ EventListener* getAttributeEventListener(const AtomicString& eventType);
- // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
- // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch.
- virtual void* preDispatchEventHandler(Event*) { return 0; }
- virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
+ bool hasEventListeners();
+ bool hasEventListeners(const AtomicString& eventType);
+ const EventListenerVector& getEventListeners(const AtomicString& eventType);
+
+ bool fireEventListeners(Event*);
+ bool isFiringEventListeners();
+
+#if USE(JSC)
+ void markEventListeners(JSC::MarkStack&);
+ void invalidateEventListeners();
+#endif
protected:
virtual ~EventTarget();
+
+ virtual EventTargetData* eventTargetData() = 0;
+ virtual EventTargetData* ensureEventTargetData() = 0;
private:
virtual void refEventTarget() = 0;
virtual void derefEventTarget() = 0;
};
- void forbidEventDispatch();
- void allowEventDispatch();
+ #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
+ EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
+
+ #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \
+ virtual EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
+ virtual void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
+
+ #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
+ EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \
+
+ #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
+ EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \
+
+ #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
+ EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \
+ void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \
#ifndef NDEBUG
+ void forbidEventDispatch();
+ void allowEventDispatch();
bool eventDispatchForbidden();
#else
inline void forbidEventDispatch() { }
inline void allowEventDispatch() { }
#endif
-}
-
+#if USE(JSC)
+ inline void EventTarget::markEventListeners(JSC::MarkStack& markStack)
+ {
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return;
+
+ EventListenerMap::iterator end = d->eventListenerMap.end();
+ for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) {
+ EventListenerVector& entry = it->second;
+ for (size_t i = 0; i < entry.size(); ++i)
+ entry[i].listener->markJSFunction(markStack);
+ }
+ }
+
+ inline void EventTarget::invalidateEventListeners()
+ {
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return;
+
+ d->eventListenerMap.clear();
+ }
#endif
+
+ inline bool EventTarget::isFiringEventListeners()
+ {
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return false;
+ return d->firingEventEndIterators.size() != 0;
+ }
+
+ inline bool EventTarget::hasEventListeners()
+ {
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return false;
+ return !d->eventListenerMap.isEmpty();
+ }
+
+ inline bool EventTarget::hasEventListeners(const AtomicString& eventType)
+ {
+ EventTargetData* d = eventTargetData();
+ if (!d)
+ return false;
+ return d->eventListenerMap.contains(eventType);
+ }
+
+} // namespace WebCore
+
+#endif // EventTarget_h
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index 0e2456d..c29cb1c 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -34,7 +34,6 @@
#include "RenderTextControlSingleLine.h"
#include "SelectionController.h"
#include "TextIterator.h"
-#include "TextBreakIterator.h"
#if ENABLE(WML)
#include "WMLInputElement.h"
@@ -46,25 +45,23 @@ namespace WebCore {
using namespace HTMLNames;
// FIXME: According to HTML4, the length attribute's value can be arbitrarily
-// large. However, due to http://bugs.webkit.org/show_bugs.cgi?id=14536 things
+// large. However, due to https://bugs.webkit.org/show_bug.cgi?id=14536 things
// get rather sluggish when a text field has a larger number of characters than
// this, even when just clicking in the text field.
const int InputElement::s_maximumLength = 524288;
const int InputElement::s_defaultSize = 20;
-void InputElement::dispatchFocusEvent(InputElementData& data, InputElement* inputElement, Element* element)
+void InputElement::dispatchFocusEvent(InputElement* inputElement, Element* element)
{
if (!inputElement->isTextField())
return;
- updatePlaceholderVisibility(data, inputElement, element);
-
Document* document = element->document();
if (inputElement->isPasswordField() && document->frame())
document->setUseSecureKeyboardEntryWhenActive(true);
}
-void InputElement::dispatchBlurEvent(InputElementData& data, InputElement* inputElement, Element* element)
+void InputElement::dispatchBlurEvent(InputElement* inputElement, Element* element)
{
if (!inputElement->isTextField())
return;
@@ -74,28 +71,12 @@ void InputElement::dispatchBlurEvent(InputElementData& data, InputElement* input
if (!frame)
return;
- updatePlaceholderVisibility(data, inputElement, element);
-
if (inputElement->isPasswordField())
document->setUseSecureKeyboardEntryWhenActive(false);
frame->textFieldDidEndEditing(element);
}
-void InputElement::updatePlaceholderVisibility(InputElementData& data, InputElement* inputElement, Element* element, bool placeholderValueChanged)
-{
- ASSERT(inputElement->isTextField());
- Document* document = element->document();
-
- bool oldPlaceholderShouldBeVisible = data.placeholderShouldBeVisible();
- data.setPlaceholderShouldBeVisible(inputElement->value().isEmpty()
- && document->focusedNode() != element
- && !inputElement->placeholder().isEmpty());
-
- if ((oldPlaceholderShouldBeVisible != data.placeholderShouldBeVisible() || placeholderValueChanged) && element->renderer())
- toRenderTextControlSingleLine(element->renderer())->updatePlaceholderVisibility();
-}
-
void InputElement::updateFocusAppearance(InputElementData& data, InputElement* inputElement, Element* element, bool restorePreviousSelection)
{
ASSERT(inputElement->isTextField());
@@ -137,11 +118,8 @@ void InputElement::aboutToUnload(InputElement* inputElement, Element* element)
void InputElement::setValueFromRenderer(InputElementData& data, InputElement* inputElement, Element* element, const String& value)
{
- // Renderer and our event handler are responsible for constraining values.
- ASSERT(value == inputElement->constrainValue(value) || inputElement->constrainValue(value).isEmpty());
-
- if (inputElement->isTextField())
- updatePlaceholderVisibility(data, inputElement, element);
+ // Renderer and our event handler are responsible for sanitizing values.
+ ASSERT_UNUSED(inputElement, value == inputElement->sanitizeValue(value) || inputElement->sanitizeValue(value).isEmpty());
// Workaround for bug where trailing \n is included in the result of textContent.
// The assert macro above may also be simplified to: value == constrainValue(value)
@@ -153,84 +131,58 @@ void InputElement::setValueFromRenderer(InputElementData& data, InputElement* in
element->setFormControlValueMatchesRenderer(true);
- // Fire the "input" DOM event
- element->dispatchEvent(eventNames().inputEvent, true, false);
+ element->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
notifyFormStateChanged(element);
}
-static int numCharactersInGraphemeClusters(StringImpl* s, int numGraphemeClusters)
+String InputElement::sanitizeValue(const InputElement* inputElement, const String& proposedValue)
{
- if (!s)
- return 0;
-
- TextBreakIterator* it = characterBreakIterator(s->characters(), s->length());
- if (!it)
- return 0;
-
- for (int i = 0; i < numGraphemeClusters; ++i) {
- if (textBreakNext(it) == TextBreakDone)
- return s->length();
- }
-
- return textBreakCurrent(it);
+ return InputElement::sanitizeUserInputValue(inputElement, proposedValue, s_maximumLength);
}
-String InputElement::constrainValue(const InputElement* inputElement, const String& proposedValue, int maxLength)
+String InputElement::sanitizeUserInputValue(const InputElement* inputElement, const String& proposedValue, int maxLength)
{
- String string = proposedValue;
if (!inputElement->isTextField())
- return string;
+ return proposedValue;
+ String string = proposedValue;
string.replace("\r\n", " ");
string.replace('\r', ' ');
string.replace('\n', ' ');
-
- StringImpl* s = string.impl();
- int newLength = numCharactersInGraphemeClusters(s, maxLength);
- for (int i = 0; i < newLength; ++i) {
- const UChar& current = (*s)[i];
+
+ unsigned newLength = string.numCharactersInGraphemeClusters(maxLength);
+ for (unsigned i = 0; i < newLength; ++i) {
+ const UChar current = string[i];
if (current < ' ' && current != '\t') {
newLength = i;
break;
}
}
-
- if (newLength < static_cast<int>(string.length()))
- return string.left(newLength);
-
- return string;
-}
-
-static int numGraphemeClusters(StringImpl* s)
-{
- if (!s)
- return 0;
-
- TextBreakIterator* it = characterBreakIterator(s->characters(), s->length());
- if (!it)
- return 0;
-
- int num = 0;
- while (textBreakNext(it) != TextBreakDone)
- ++num;
-
- return num;
+ return string.left(newLength);
}
-void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputElement* inputElement, Document* document, Event* event)
+void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputElement* inputElement, Element* element, Event* event)
{
ASSERT(event->isBeforeTextInsertedEvent());
-
// Make sure that the text to be inserted will not violate the maxLength.
- int oldLength = numGraphemeClusters(inputElement->value().impl());
- ASSERT(oldLength <= data.maxLength());
- int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toNormalizedRange().get()).impl());
+
+ // We use RenderTextControlSingleLine::text() instead of InputElement::value()
+ // because they can be mismatched by sanitizeValue() in
+ // RenderTextControlSingleLine::subtreeHasChanged() in some cases.
+ unsigned oldLength = toRenderTextControlSingleLine(element->renderer())->text().numGraphemeClusters();
+
+ // selection() may be a pre-edit text.
+ unsigned selectionLength = plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get()).numGraphemeClusters();
ASSERT(oldLength >= selectionLength);
- int maxNewLength = data.maxLength() - (oldLength - selectionLength);
+
+ // Selected characters will be removed by the next text event.
+ unsigned baseLength = oldLength - selectionLength;
+ unsigned maxLength = static_cast<unsigned>(data.maxLength()); // maxLength() can never be negative.
+ unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0;
// Truncate the inserted text to avoid violating the maxLength and other constraints.
BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event);
- textEvent->setText(constrainValue(inputElement, textEvent->text(), maxNewLength));
+ textEvent->setText(sanitizeUserInputValue(inputElement, textEvent->text(), appendableLength));
}
void InputElement::parseSizeAttribute(InputElementData& data, Element* element, MappedAttribute* attribute)
@@ -259,7 +211,7 @@ void InputElement::parseMaxLengthAttribute(InputElementData& data, InputElement*
void InputElement::updateValueIfNeeded(InputElementData& data, InputElement* inputElement)
{
String oldValue = data.value();
- String newValue = inputElement->constrainValue(oldValue);
+ String newValue = sanitizeValue(inputElement, oldValue);
if (newValue != oldValue)
inputElement->setValue(newValue);
}
@@ -277,8 +229,7 @@ void InputElement::notifyFormStateChanged(Element* element)
// InputElementData
InputElementData::InputElementData()
- : m_placeholderShouldBeVisible(false)
- , m_size(InputElement::s_defaultSize)
+ : m_size(InputElement::s_defaultSize)
, m_maxLength(InputElement::s_maximumLength)
, m_cachedSelectionStart(-1)
, m_cachedSelectionEnd(-1)
diff --git a/WebCore/dom/InputElement.h b/WebCore/dom/InputElement.h
index 7ad3cbd..e0e7110 100644
--- a/WebCore/dom/InputElement.h
+++ b/WebCore/dom/InputElement.h
@@ -44,17 +44,13 @@ public:
virtual bool isSearchField() const = 0;
virtual bool isTextField() const = 0;
- virtual bool placeholderShouldBeVisible() const = 0;
virtual bool searchEventsShouldBeDispatched() const = 0;
virtual int size() const = 0;
virtual String value() const = 0;
virtual void setValue(const String&) = 0;
- virtual String placeholder() const = 0;
- virtual void setPlaceholder(const String&) = 0;
-
- virtual String constrainValue(const String&) const = 0;
+ virtual String sanitizeValue(const String&) const = 0;
virtual void setValueFromRenderer(const String&) = 0;
virtual void cacheSelection(int start, int end) = 0;
@@ -64,15 +60,19 @@ public:
static const int s_defaultSize;
protected:
- static void dispatchFocusEvent(InputElementData&, InputElement*, Element*);
- static void dispatchBlurEvent(InputElementData&, InputElement*, Element*);
- static void updatePlaceholderVisibility(InputElementData&, InputElement*, Element*, bool placeholderValueChanged = false);
+ static void dispatchFocusEvent(InputElement*, Element*);
+ static void dispatchBlurEvent(InputElement*, Element*);
static void updateFocusAppearance(InputElementData&, InputElement*, Element*, bool restorePreviousSelection);
static void updateSelectionRange(InputElement*, Element*, int start, int end);
static void aboutToUnload(InputElement*, Element*);
static void setValueFromRenderer(InputElementData&, InputElement*, Element*, const String&);
- static String constrainValue(const InputElement*, const String& proposedValue, int maxLength);
- static void handleBeforeTextInsertedEvent(InputElementData&, InputElement*, Document*, Event*);
+ // Replaces CRs and LFs, shrinks the value for s_maximumLength.
+ // This should be applied to values from the HTML value attribute and the DOM value property.
+ static String sanitizeValue(const InputElement*, const String&);
+ // Replaces CRs and LFs, shrinks the value for the specified maximum length.
+ // This should be applied to values specified by users.
+ static String sanitizeUserInputValue(const InputElement*, const String&, int);
+ static void handleBeforeTextInsertedEvent(InputElementData&, InputElement*, Element*, Event*);
static void parseSizeAttribute(InputElementData&, Element*, MappedAttribute*);
static void parseMaxLengthAttribute(InputElementData&, InputElement*, Element*, MappedAttribute*);
static void updateValueIfNeeded(InputElementData&, InputElement*);
@@ -85,9 +85,6 @@ class InputElementData {
public:
InputElementData();
- bool placeholderShouldBeVisible() const { return m_placeholderShouldBeVisible; }
- void setPlaceholderShouldBeVisible(bool visible) { m_placeholderShouldBeVisible = visible; }
-
const AtomicString& name() const;
void setName(const AtomicString& value) { m_name = value; }
@@ -107,7 +104,6 @@ public:
void setCachedSelectionEnd(int value) { m_cachedSelectionEnd = value; }
private:
- bool m_placeholderShouldBeVisible;
AtomicString m_name;
String m_value;
int m_size;
diff --git a/WebCore/dom/MessageEvent.cpp b/WebCore/dom/MessageEvent.cpp
index a0af32d..3c84642 100644
--- a/WebCore/dom/MessageEvent.cpp
+++ b/WebCore/dom/MessageEvent.cpp
@@ -34,16 +34,17 @@
namespace WebCore {
MessageEvent::MessageEvent()
+ : m_data(SerializedScriptValue::create())
{
}
-MessageEvent::MessageEvent(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassRefPtr<MessagePort> messagePort)
- : Event(eventNames().messageEvent, false, true)
+MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
+ : Event(eventNames().messageEvent, false, false)
, m_data(data)
, m_origin(origin)
, m_lastEventId(lastEventId)
, m_source(source)
- , m_messagePort(messagePort)
+ , m_ports(ports)
{
}
@@ -51,7 +52,7 @@ MessageEvent::~MessageEvent()
{
}
-void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort* messagePort)
+void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray> ports)
{
if (dispatched())
return;
@@ -62,7 +63,26 @@ void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bo
m_origin = origin;
m_lastEventId = lastEventId;
m_source = source;
- m_messagePort = messagePort;
+ m_ports = ports;
+}
+
+// FIXME: remove this when we update the ObjC bindings (bug #28774).
+MessagePort* MessageEvent::messagePort()
+{
+ if (!m_ports)
+ return 0;
+ ASSERT(m_ports->size() == 1);
+ return (*m_ports)[0].get();
+}
+
+void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort* port)
+{
+ MessagePortArray* ports = 0;
+ if (port) {
+ ports = new MessagePortArray();
+ ports->append(port);
+ }
+ initMessageEvent(type, canBubble, cancelable, data, origin, lastEventId, source, ports);
}
bool MessageEvent::isMessageEvent() const
diff --git a/WebCore/dom/MessageEvent.h b/WebCore/dom/MessageEvent.h
index 87a6745..b7f9b02 100644
--- a/WebCore/dom/MessageEvent.h
+++ b/WebCore/dom/MessageEvent.h
@@ -28,8 +28,10 @@
#ifndef MessageEvent_h
#define MessageEvent_h
+#include "DOMWindow.h"
#include "Event.h"
#include "MessagePort.h"
+#include "SerializedScriptValue.h"
namespace WebCore {
@@ -41,31 +43,36 @@ namespace WebCore {
{
return adoptRef(new MessageEvent);
}
- static PassRefPtr<MessageEvent> create(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassRefPtr<MessagePort> messagePort)
+ static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data = 0, const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
{
- return adoptRef(new MessageEvent(data, origin, lastEventId, source, messagePort));
+ return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
}
virtual ~MessageEvent();
- void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort*);
-
- const String& data() const { return m_data; }
+ void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
+
+ SerializedScriptValue* data() const { return m_data.get(); }
const String& origin() const { return m_origin; }
const String& lastEventId() const { return m_lastEventId; }
DOMWindow* source() const { return m_source.get(); }
- MessagePort* messagePort() const { return m_messagePort.get(); }
-
+ MessagePortArray* ports() const { return m_ports.get(); }
+
+ // FIXME: remove this when we update the ObjC bindings (bug #28774).
+ MessagePort* messagePort();
+ // FIXME: remove this when we update the ObjC bindings (bug #28774).
+ void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort*);
+
virtual bool isMessageEvent() const;
- private:
+ private:
MessageEvent();
- MessageEvent(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassRefPtr<MessagePort> messagePort);
+ MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
- String m_data;
+ RefPtr<SerializedScriptValue> m_data;
String m_origin;
String m_lastEventId;
RefPtr<DOMWindow> m_source;
- RefPtr<MessagePort> m_messagePort;
+ OwnPtr<MessagePortArray> m_ports;
};
} // namespace WebCore
diff --git a/WebCore/dom/MessageEvent.idl b/WebCore/dom/MessageEvent.idl
index 8e8f271..7e497fc 100644
--- a/WebCore/dom/MessageEvent.idl
+++ b/WebCore/dom/MessageEvent.idl
@@ -30,14 +30,21 @@ module events {
GenerateConstructor,
NoStaticTables
] MessageEvent : Event {
+ readonly attribute SerializedScriptValue data;
- readonly attribute DOMString data;
readonly attribute DOMString origin;
readonly attribute DOMString lastEventId;
readonly attribute DOMWindow source;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ readonly attribute [CustomGetter] Array ports;
+
+ [Custom] void initMessageEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in SerializedScriptValue dataArg, in DOMString originArg, in DOMString lastEventIdArg, in DOMWindow sourceArg, in Array messagePorts);
+#else
+ // There's no good way to expose an array via the ObjC bindings, so for now just expose a single port.
readonly attribute MessagePort messagePort;
-
- void initMessageEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg, in DOMString originArg, in DOMString lastEventIdArg, in DOMWindow sourceArg, in MessagePort messagePort);
+
+ void initMessageEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in SerializedScriptValue dataArg, in DOMString originArg, in DOMString lastEventIdArg, in DOMWindow sourceArg, in MessagePort messagePort);
+#endif
};
diff --git a/WebCore/dom/MessagePort.cpp b/WebCore/dom/MessagePort.cpp
index 9f3e4d2..9f6e649 100644
--- a/WebCore/dom/MessagePort.cpp
+++ b/WebCore/dom/MessagePort.cpp
@@ -55,28 +55,41 @@ MessagePort::~MessagePort()
m_scriptExecutionContext->destroyedMessagePort(this);
}
-void MessagePort::postMessage(const String& message, ExceptionCode& ec)
+// FIXME: remove this when we update the ObjC bindings (bug #28774).
+void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, ExceptionCode& ec)
{
- postMessage(message, 0, ec);
+ MessagePortArray ports;
+ if (port)
+ ports.append(port);
+ postMessage(message, &ports, ec);
}
-void MessagePort::postMessage(const String& message, MessagePort* dataPort, ExceptionCode& ec)
+void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode& ec)
+{
+ postMessage(message, static_cast<MessagePortArray*>(0), ec);
+}
+
+void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionCode& ec)
{
if (!m_entangledChannel)
return;
ASSERT(m_scriptExecutionContext);
- OwnPtr<MessagePortChannel> channel;
- if (dataPort) {
- if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) {
- ec = INVALID_STATE_ERR;
- return;
+ OwnPtr<MessagePortChannelArray> channels;
+ // Make sure we aren't connected to any of the passed-in ports.
+ if (ports) {
+ for (unsigned int i = 0; i < ports->size(); ++i) {
+ MessagePort* dataPort = (*ports)[i].get();
+ if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
}
- channel = dataPort->disentangle(ec);
+ channels = MessagePort::disentanglePorts(ports, ec);
if (ec)
return;
}
- m_entangledChannel->postMessageToRemote(MessagePortChannel::EventData::create(message, channel.release()));
+ m_entangledChannel->postMessageToRemote(MessagePortChannel::EventData::create(message, channels.release()));
}
PassOwnPtr<MessagePortChannel> MessagePort::disentangle(ExceptionCode& ec)
@@ -155,20 +168,8 @@ void MessagePort::dispatchMessages()
OwnPtr<MessagePortChannel::EventData> eventData;
while (m_entangledChannel && m_entangledChannel->tryGetMessageFromRemote(eventData)) {
- RefPtr<MessagePort> port;
- OwnPtr<MessagePortChannel> channel = eventData->channel();
- if (channel) {
- // The remote side sent over a MessagePortChannel, so create a MessagePort to wrap it.
- port = MessagePort::create(*m_scriptExecutionContext);
- port->entangle(channel.release());
- }
- RefPtr<Event> evt = MessageEvent::create(eventData->message(), "", "", 0, port.release());
-
- if (m_onMessageListener) {
- evt->setTarget(this);
- evt->setCurrentTarget(this);
- m_onMessageListener->handleEvent(evt.get(), false);
- }
+ OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*m_scriptExecutionContext, eventData->channels());
+ RefPtr<Event> evt = MessageEvent::create(ports.release(), eventData->message());
ExceptionCode ec = 0;
dispatchEvent(evt.release(), ec);
@@ -176,73 +177,68 @@ void MessagePort::dispatchMessages()
}
}
-void MessagePort::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
+bool MessagePort::hasPendingActivity()
{
- EventListenersMap::iterator iter = m_eventListeners.find(eventType);
- if (iter == m_eventListeners.end()) {
- ListenerVector listeners;
- listeners.append(eventListener);
- m_eventListeners.add(eventType, listeners);
- } else {
- ListenerVector& listeners = iter->second;
- for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
- if (*listenerIter == eventListener)
- return;
- }
-
- listeners.append(eventListener);
- m_eventListeners.add(eventType, listeners);
- }
+ // The spec says that entangled message ports should always be treated as if they have a strong reference.
+ // We'll also stipulate that the queue needs to be open (if the app drops its reference to the port before start()-ing it, then it's not really entangled as it's unreachable).
+ return m_started && m_entangledChannel && m_entangledChannel->hasPendingActivity();
}
-void MessagePort::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
+MessagePort* MessagePort::locallyEntangledPort()
{
- EventListenersMap::iterator iter = m_eventListeners.find(eventType);
- if (iter == m_eventListeners.end())
- return;
-
- ListenerVector& listeners = iter->second;
- for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
- if (*listenerIter == eventListener) {
- listeners.remove(listenerIter - listeners.begin());
- return;
- }
- }
+ return m_entangledChannel ? m_entangledChannel->locallyEntangledPort(m_scriptExecutionContext) : 0;
}
-bool MessagePort::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
+PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessagePortArray* ports, ExceptionCode& ec)
{
- if (!event || event->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return true;
+ if (!ports || !ports->size())
+ return 0;
+
+ // HashSet used to efficiently check for duplicates in the passed-in array.
+ HashSet<MessagePort*> portSet;
+
+ // Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
+ for (unsigned int i = 0; i < ports->size(); ++i) {
+ MessagePort* port = (*ports)[i].get();
+ if (!port || !port->isEntangled() || portSet.contains(port)) {
+ ec = INVALID_STATE_ERR;
+ return 0;
+ }
+ portSet.add(port);
}
-
- ListenerVector listenersCopy = m_eventListeners.get(event->type());
- for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
- event->setTarget(this);
- event->setCurrentTarget(this);
- listenerIter->get()->handleEvent(event.get(), false);
+
+ // Passed-in ports passed validity checks, so we can disentangle them.
+ MessagePortChannelArray* portArray = new MessagePortChannelArray(ports->size());
+ for (unsigned int i = 0 ; i < ports->size() ; ++i) {
+ OwnPtr<MessagePortChannel> channel = (*ports)[i]->disentangle(ec);
+ ASSERT(!ec); // Can't generate exception here if passed above checks.
+ (*portArray)[i] = channel.release();
}
-
- return !event->defaultPrevented();
+ return portArray;
}
-void MessagePort::setOnmessage(PassRefPtr<EventListener> eventListener)
+PassOwnPtr<MessagePortArray> MessagePort::entanglePorts(ScriptExecutionContext& context, PassOwnPtr<MessagePortChannelArray> channels)
{
- m_onMessageListener = eventListener;
- start();
+ if (!channels || !channels->size())
+ return 0;
+
+ MessagePortArray* portArray = new MessagePortArray(channels->size());
+ for (unsigned int i = 0; i < channels->size(); ++i) {
+ RefPtr<MessagePort> port = MessagePort::create(context);
+ port->entangle((*channels)[i].release());
+ (*portArray)[i] = port.release();
+ }
+ return portArray;
}
-bool MessagePort::hasPendingActivity()
+EventTargetData* MessagePort::eventTargetData()
{
- // The spec says that entangled message ports should always be treated as if they have a strong reference.
- // We'll also stipulate that the queue needs to be open (if the app drops its reference to the port before start()-ing it, then it's not really entangled as it's unreachable).
- return m_started && m_entangledChannel && m_entangledChannel->hasPendingActivity();
+ return &m_eventTargetData;
}
-MessagePort* MessagePort::locallyEntangledPort()
+EventTargetData* MessagePort::ensureEventTargetData()
{
- return m_entangledChannel ? m_entangledChannel->locallyEntangledPort(m_scriptExecutionContext) : 0;
+ return &m_eventTargetData;
}
} // namespace WebCore
diff --git a/WebCore/dom/MessagePort.h b/WebCore/dom/MessagePort.h
index f416b9b..0ab0f50 100644
--- a/WebCore/dom/MessagePort.h
+++ b/WebCore/dom/MessagePort.h
@@ -29,9 +29,9 @@
#include "AtomicStringHash.h"
#include "EventListener.h"
+#include "EventNames.h"
#include "EventTarget.h"
#include "MessagePortChannel.h"
-
#include <wtf/HashMap.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
@@ -44,22 +44,38 @@ namespace WebCore {
class AtomicStringImpl;
class Event;
class Frame;
+ class MessagePort;
class ScriptExecutionContext;
class String;
+ // The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
+ typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
+
class MessagePort : public RefCounted<MessagePort>, public EventTarget {
public:
static PassRefPtr<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
~MessagePort();
- void postMessage(const String& message, ExceptionCode&);
- void postMessage(const String& message, MessagePort*, ExceptionCode&);
+ void postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode&);
+ void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, ExceptionCode&);
+ // FIXME: remove this when we update the ObjC bindings (bug #28774).
+ void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, ExceptionCode&);
+
void start();
void close();
void entangle(PassOwnPtr<MessagePortChannel>);
PassOwnPtr<MessagePortChannel> disentangle(ExceptionCode&);
+ // Disentangle an array of ports, returning the entangled channels.
+ // Per section 8.3.3 of the HTML5 spec, generates an INVALID_STATE_ERR exception if any of the passed ports are null or not entangled.
+ // Returns 0 if there is an exception, or if the passed-in array is 0/empty.
+ static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionCode&);
+
+ // Entangles an array of channels, returning an array of MessagePorts in matching order.
+ // Returns 0 if the passed array is 0/empty.
+ static PassOwnPtr<MessagePortArray> entanglePorts(ScriptExecutionContext&, PassOwnPtr<MessagePortChannelArray>);
+
void messageAvailable();
bool started() const { return m_started; }
@@ -71,21 +87,17 @@ namespace WebCore {
void dispatchMessages();
- virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
- virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-
- typedef Vector<RefPtr<EventListener> > ListenerVector;
- typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
- EventListenersMap& eventListeners() { return m_eventListeners; }
-
using RefCounted<MessagePort>::ref;
using RefCounted<MessagePort>::deref;
bool hasPendingActivity();
- void setOnmessage(PassRefPtr<EventListener>);
- EventListener* onmessage() const { return m_onMessageListener.get(); }
+ void setOnmessage(PassRefPtr<EventListener> listener)
+ {
+ setAttributeEventListener(eventNames().messageEvent, listener);
+ start();
+ }
+ EventListener* onmessage() { return getAttributeEventListener(eventNames().messageEvent); }
// Returns null if there is no entangled port, or if the entangled port is run by a different thread.
// Returns null otherwise.
@@ -98,16 +110,15 @@ namespace WebCore {
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
+ virtual EventTargetData* eventTargetData();
+ virtual EventTargetData* ensureEventTargetData();
OwnPtr<MessagePortChannel> m_entangledChannel;
bool m_started;
ScriptExecutionContext* m_scriptExecutionContext;
-
- RefPtr<EventListener> m_onMessageListener;
-
- EventListenersMap m_eventListeners;
+ EventTargetData m_eventTargetData;
};
} // namespace WebCore
diff --git a/WebCore/dom/MessagePort.idl b/WebCore/dom/MessagePort.idl
index e5f9ad1..a9149ec 100644
--- a/WebCore/dom/MessagePort.idl
+++ b/WebCore/dom/MessagePort.idl
@@ -28,13 +28,14 @@ module events {
interface [
CustomMarkFunction,
+ EventTarget,
GenerateConstructor,
NoStaticTables
] MessagePort {
// We need to have something as an ObjC binding, because MessagePort is used in MessageEvent, which already has one,
// but we don't want to actually expose the API while it is in flux.
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
- void postMessage(in DOMString message, in [Optional] MessagePort messagePort)
+ [Custom] void postMessage(in DOMString message, in [Optional] Array messagePorts)
raises(DOMException);
void start();
void close();
diff --git a/WebCore/dom/MessagePortChannel.cpp b/WebCore/dom/MessagePortChannel.cpp
index 05134c0..e1a3ac6 100644
--- a/WebCore/dom/MessagePortChannel.cpp
+++ b/WebCore/dom/MessagePortChannel.cpp
@@ -33,14 +33,14 @@
namespace WebCore {
-PassOwnPtr<MessagePortChannel::EventData> MessagePortChannel::EventData::create(const String& message, PassOwnPtr<MessagePortChannel> channel)
+PassOwnPtr<MessagePortChannel::EventData> MessagePortChannel::EventData::create(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
{
- return new EventData(message, channel);
+ return new EventData(message, channels);
}
-MessagePortChannel::EventData::EventData(const String& message, PassOwnPtr<MessagePortChannel> channel)
- : m_message(message.copy())
- , m_channel(channel)
+MessagePortChannel::EventData::EventData(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
+ : m_message(message->release())
+ , m_channels(channels)
{
}
diff --git a/WebCore/dom/MessagePortChannel.h b/WebCore/dom/MessagePortChannel.h
index 93b224b..2321b1f 100644
--- a/WebCore/dom/MessagePortChannel.h
+++ b/WebCore/dom/MessagePortChannel.h
@@ -33,6 +33,8 @@
#include "PlatformString.h"
+#include "SerializedScriptValue.h"
+
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
@@ -42,10 +44,15 @@
namespace WebCore {
class MessagePort;
+ class MessagePortChannel;
class PlatformMessagePortChannel;
class ScriptExecutionContext;
+ class SerializedScriptValue;
class String;
+ // The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
+ typedef Vector<OwnPtr<MessagePortChannel>, 1> MessagePortChannelArray;
+
// MessagePortChannel is a platform-independent interface to the remote side of a message channel.
// It acts as a wrapper around the platform-dependent PlatformMessagePortChannel implementation which ensures that the platform-dependent close() method is invoked before destruction.
class MessagePortChannel : public Noncopyable {
@@ -73,15 +80,15 @@ namespace WebCore {
class EventData {
public:
- static PassOwnPtr<EventData> create(const String&, PassOwnPtr<MessagePortChannel>);
+ static PassOwnPtr<EventData> create(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>);
- const String& message() { return m_message; }
- PassOwnPtr<MessagePortChannel> channel() { return m_channel.release(); }
+ SerializedScriptValue* message() { return m_message.get(); }
+ PassOwnPtr<MessagePortChannelArray> channels() { return m_channels.release(); }
private:
- EventData(const String& message, PassOwnPtr<MessagePortChannel>);
- String m_message;
- OwnPtr<MessagePortChannel> m_channel;
+ EventData(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray>);
+ RefPtr<SerializedScriptValue> m_message;
+ OwnPtr<MessagePortChannelArray> m_channels;
};
// Sends a message and optional cloned port to the remote port.
diff --git a/WebCore/dom/MutationEvent.h b/WebCore/dom/MutationEvent.h
index c5f2d1d..29b978c 100644
--- a/WebCore/dom/MutationEvent.h
+++ b/WebCore/dom/MutationEvent.h
@@ -41,10 +41,11 @@ namespace WebCore {
{
return adoptRef(new MutationEvent);
}
- static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
- const String& prevValue, const String& newValue, const String& attrName, unsigned short attrChange)
+
+ static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode = 0,
+ const String& prevValue = String(), const String& newValue = String(), const String& attrName = String(), unsigned short attrChange = 0)
{
- return adoptRef(new MutationEvent(type, canBubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange));
+ return adoptRef(new MutationEvent(type, canBubble, false, relatedNode, prevValue, newValue, attrName, attrChange));
}
void initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
diff --git a/WebCore/dom/NamedAttrMap.cpp b/WebCore/dom/NamedAttrMap.cpp
index fe631c8..d4ec598 100644
--- a/WebCore/dom/NamedAttrMap.cpp
+++ b/WebCore/dom/NamedAttrMap.cpp
@@ -178,10 +178,8 @@ Attribute* NamedNodeMap::getAttributeItem(const String& name, bool shouldIgnoreA
{
unsigned len = length();
for (unsigned i = 0; i < len; ++i) {
- if (!m_attributes[i]->name().hasPrefix() &&
- m_attributes[i]->name().localName() == name)
- return m_attributes[i].get();
-
+ if (!m_attributes[i]->name().hasPrefix() && m_attributes[i]->name().localName() == name)
+ return m_attributes[i].get();
if (shouldIgnoreAttributeCase ? equalIgnoringCase(m_attributes[i]->name().toString(), name) : name == m_attributes[i]->name().toString())
return m_attributes[i].get();
}
@@ -206,10 +204,12 @@ void NamedNodeMap::clearAttributes()
void NamedNodeMap::detachFromElement()
{
- // we allow a NamedNodeMap w/o an element in case someone still has a reference
- // to if after the element gets deleted - but the map is now invalid
+ // This can't happen if the holder of the map is JavaScript, because we mark the
+ // element if the map is alive. So it has no impact on web page behavior. Because
+ // of that, we can simply clear all the attributes to avoid accessing stale
+ // pointers to do things like create Attr objects.
m_element = 0;
- detachAttributesFromElement();
+ clearAttributes();
}
void NamedNodeMap::setAttributes(const NamedNodeMap& other)
@@ -251,7 +251,7 @@ void NamedNodeMap::addAttribute(PassRefPtr<Attribute> prpAttribute)
attr->m_element = m_element;
// Notify the element that the attribute has been added, and dispatch appropriate mutation events
- // Note that element may be null here if we are called from insertAttr() during parsing
+ // Note that element may be null here if we are called from insertAttribute() during parsing
if (m_element) {
m_element->attributeChanged(attribute.get());
// Because of our updateStyleAttribute() style modification events are never sent at the right time, so don't bother sending them.
@@ -265,12 +265,13 @@ void NamedNodeMap::addAttribute(PassRefPtr<Attribute> prpAttribute)
void NamedNodeMap::removeAttribute(const QualifiedName& name)
{
unsigned len = length();
- unsigned index = len + 1;
- for (unsigned i = 0; i < len; ++i)
+ unsigned index = len;
+ for (unsigned i = 0; i < len; ++i) {
if (m_attributes[i]->name().matches(name)) {
index = i;
break;
}
+ }
if (index >= len)
return;
diff --git a/WebCore/dom/NamedAttrMap.h b/WebCore/dom/NamedAttrMap.h
index 4fb96de..759900b 100644
--- a/WebCore/dom/NamedAttrMap.h
+++ b/WebCore/dom/NamedAttrMap.h
@@ -94,11 +94,11 @@ public:
void addAttribute(PassRefPtr<Attribute>);
void removeAttribute(const QualifiedName&);
+ Element* element() const { return m_element; }
+
protected:
virtual void clearAttributes();
- Element* element() const { return m_element; }
-
private:
void detachAttributesFromElement();
void detachFromElement();
diff --git a/WebCore/dom/NamedNodeMap.idl b/WebCore/dom/NamedNodeMap.idl
index 3310ded..8166853 100644
--- a/WebCore/dom/NamedNodeMap.idl
+++ b/WebCore/dom/NamedNodeMap.idl
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 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
@@ -21,6 +21,7 @@
module core {
interface [
+ CustomMarkFunction,
GenerateConstructor,
HasIndexGetter,
HasNameGetter,
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 18655c6..4b91a40 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -55,6 +55,7 @@
#include "Frame.h"
#include "FrameView.h"
#include "HTMLNames.h"
+#include "InspectorTimelineAgent.h"
#include "KeyboardEvent.h"
#include "Logging.h"
#include "MouseEvent.h"
@@ -337,8 +338,69 @@ Node::StyleChange Node::diff(const RenderStyle* s1, const RenderStyle* s2)
return ch;
}
-Node::Node(Document* doc, bool isElement, bool isContainer, bool isText)
- : m_document(doc)
+inline bool Node::initialRefCount(ConstructionType type)
+{
+ switch (type) {
+ case CreateContainer:
+ case CreateElement:
+ case CreateOther:
+ case CreateText:
+ return 1;
+ case CreateElementZeroRefCount:
+ return 0;
+ }
+ ASSERT_NOT_REACHED();
+ return 1;
+}
+
+inline bool Node::isContainer(ConstructionType type)
+{
+ switch (type) {
+ case CreateContainer:
+ case CreateElement:
+ case CreateElementZeroRefCount:
+ return true;
+ case CreateOther:
+ case CreateText:
+ return false;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+inline bool Node::isElement(ConstructionType type)
+{
+ switch (type) {
+ case CreateContainer:
+ case CreateOther:
+ case CreateText:
+ return false;
+ case CreateElement:
+ case CreateElementZeroRefCount:
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+inline bool Node::isText(ConstructionType type)
+{
+ switch (type) {
+ case CreateContainer:
+ case CreateElement:
+ case CreateElementZeroRefCount:
+ case CreateOther:
+ return false;
+ case CreateText:
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+Node::Node(Document* document, ConstructionType type)
+ : TreeShared<Node>(initialRefCount(type))
+ , m_document(document)
, m_previous(0)
, m_next(0)
, m_renderer(0)
@@ -355,25 +417,27 @@ Node::Node(Document* doc, bool isElement, bool isContainer, bool isText)
, m_inDetach(false)
, m_inSubtreeMark(false)
, m_hasRareData(false)
- , m_isElement(isElement)
- , m_isContainer(isContainer)
- , m_isText(isText)
+ , m_isElement(isElement(type))
+ , m_isContainer(isContainer(type))
+ , m_isText(isText(type))
, m_parsingChildrenFinished(true)
-#if ENABLE(SVG)
- , m_areSVGAttributesValid(true)
-#endif
, m_isStyleAttributeValid(true)
, m_synchronizingStyleAttribute(false)
#if ENABLE(SVG)
+ , m_areSVGAttributesValid(true)
, m_synchronizingSVGAttributes(false)
#endif
{
+ if (m_document)
+ m_document->selfOnlyRef();
+
#ifndef NDEBUG
if (shouldIgnoreLeaks)
ignoreSet.add(this);
else
nodeCounter.increment();
#endif
+
#if DUMP_NODE_STATISTICS
liveNodeSet.add(this);
#endif
@@ -393,9 +457,6 @@ Node::~Node()
liveNodeSet.remove(this);
#endif
- if (!eventListeners().isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
if (!hasRareData())
ASSERT(!NodeRareData::rareDataMap().contains(this));
else {
@@ -416,6 +477,9 @@ Node::~Node()
m_previous->setNextSibling(0);
if (m_next)
m_next->setPreviousSibling(0);
+
+ if (m_document)
+ m_document->selfOnlyDeref();
}
#ifdef NDEBUG
@@ -450,14 +514,19 @@ void Node::setDocument(Document* document)
if (inDocument() || m_document == document)
return;
+ document->selfOnlyRef();
+
setWillMoveToNewOwnerDocumentWasCalled(false);
willMoveToNewOwnerDocument();
ASSERT(willMoveToNewOwnerDocumentWasCalled);
#if USE(JSC)
- updateDOMNodeDocument(this, m_document.get(), document);
+ updateDOMNodeDocument(this, m_document, document);
#endif
+ if (m_document)
+ m_document->selfOnlyDeref();
+
m_document = document;
setDidMoveToNewOwnerDocumentWasCalled(false);
@@ -519,7 +588,8 @@ PassRefPtr<NodeList> Node::childNodes()
NodeRareData* data = ensureRareData();
if (!data->nodeLists()) {
data->setNodeLists(NodeListsNodeData::create());
- document()->addNodeListCache();
+ if (document())
+ document()->addNodeListCache();
}
return ChildNodeList::create(this, data->nodeLists()->m_childNodeListCaches.get());
@@ -699,7 +769,7 @@ void Node::setNeedsStyleRecalc(StyleChangeType changeType)
if ((changeType != NoStyleChange) && !attached()) // changed compared to what?
return;
- if (!(changeType == InlineStyleChange && (m_styleChange == FullStyleChange || m_styleChange == AnimationStyleChange)))
+ if (!(changeType == InlineStyleChange && (m_styleChange == FullStyleChange || m_styleChange == SyntheticStyleChange)))
m_styleChange = changeType;
if (m_styleChange != NoStyleChange) {
@@ -762,10 +832,30 @@ bool Node::rareDataFocused() const
ASSERT(hasRareData());
return rareData()->isFocused();
}
+
+bool Node::supportsFocus() const
+{
+ return hasRareData() && rareData()->tabIndexSetExplicitly();
+}
bool Node::isFocusable() const
{
- return hasRareData() && rareData()->tabIndexSetExplicitly();
+ if (!inDocument() || !supportsFocus())
+ return false;
+
+ if (renderer())
+ ASSERT(!renderer()->needsLayout());
+ else
+ // If the node is in a display:none tree it might say it needs style recalc but
+ // the whole document is atually up to date.
+ ASSERT(!document()->childNeedsStyleRecalc());
+
+ // FIXME: Even if we are not visible, we might have a child that is visible.
+ // Hyatt wants to fix that some day with a "has visible content" flag or the like.
+ if (!renderer() || renderer()->style()->visibility() != VISIBLE)
+ return false;
+
+ return true;
}
bool Node::isKeyboardFocusable(KeyboardEvent*) const
@@ -793,7 +883,7 @@ void Node::registerDynamicNodeList(DynamicNodeList* list)
if (!data->nodeLists()) {
data->setNodeLists(NodeListsNodeData::create());
document()->addNodeListCache();
- } else if (!m_document->hasNodeListCaches()) {
+ } else if (!m_document || !m_document->hasNodeListCaches()) {
// We haven't been receiving notifications while there were no registered lists, so the cache is invalid now.
data->nodeLists()->invalidateCaches();
}
@@ -811,7 +901,8 @@ void Node::unregisterDynamicNodeList(DynamicNodeList* list)
data->nodeLists()->m_listsWithCaches.remove(list);
if (data->nodeLists()->isEmpty()) {
data->clearNodeLists();
- document()->removeNodeListCache();
+ if (document())
+ document()->removeNodeListCache();
}
}
}
@@ -1540,52 +1631,6 @@ PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
return ClassNodeList::create(this, classNames, result.first->second.get());
}
-template <typename Functor>
-static bool forEachTagSelector(Functor& functor, CSSSelector* selector)
-{
- ASSERT(selector);
-
- do {
- if (functor(selector))
- return true;
- if (CSSSelector* simpleSelector = selector->simpleSelector()) {
- if (forEachTagSelector(functor, simpleSelector))
- return true;
- }
- } while ((selector = selector->tagHistory()));
-
- return false;
-}
-
-template <typename Functor>
-static bool forEachSelector(Functor& functor, const CSSSelectorList& selectorList)
-{
- for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
- if (forEachTagSelector(functor, selector))
- return true;
- }
-
- return false;
-}
-
-class SelectorNeedsNamespaceResolutionFunctor {
-public:
- bool operator()(CSSSelector* selector)
- {
- if (selector->hasTag() && selector->m_tag.prefix() != nullAtom && selector->m_tag.prefix() != starAtom)
- return true;
- if (selector->hasAttribute() && selector->attribute().prefix() != nullAtom && selector->attribute().prefix() != starAtom)
- return true;
- return false;
- }
-};
-
-static bool selectorNeedsNamespaceResolution(const CSSSelectorList& selectorList)
-{
- SelectorNeedsNamespaceResolutionFunctor functor;
- return forEachSelector(functor, selectorList);
-}
-
PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec)
{
if (selectors.isEmpty()) {
@@ -1604,7 +1649,7 @@ PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode&
}
// throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
- if (selectorNeedsNamespaceResolution(querySelectorList)) {
+ if (querySelectorList.selectorsNeedNamespaceResolution()) {
ec = NAMESPACE_ERR;
return 0;
}
@@ -1652,7 +1697,7 @@ PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, ExceptionCo
}
// Throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
- if (selectorNeedsNamespaceResolution(querySelectorList)) {
+ if (querySelectorList.selectorsNeedNamespaceResolution()) {
ec = NAMESPACE_ERR;
return 0;
}
@@ -1900,11 +1945,11 @@ void Node::appendTextContent(bool convertBRsToNewlines, StringBuilder& content)
case TEXT_NODE:
case CDATA_SECTION_NODE:
case COMMENT_NODE:
- content.append(static_cast<const CharacterData*>(this)->CharacterData::nodeValue());
+ content.append(static_cast<const CharacterData*>(this)->data());
break;
case PROCESSING_INSTRUCTION_NODE:
- content.append(static_cast<const ProcessingInstruction*>(this)->ProcessingInstruction::nodeValue());
+ content.append(static_cast<const ProcessingInstruction*>(this)->data());
break;
case ELEMENT_NODE:
@@ -2288,16 +2333,28 @@ ContainerNode* Node::eventParentNode()
#ifdef ANDROID_INSTRUMENT
static size_t nodeSize = 0;
-void* Node::operator new(size_t s) throw()
+void* Node::operator new(size_t size)
+{
+ nodeSize += size;
+ return ::operator new(size);
+}
+
+void* Node::operator new[](size_t size)
{
- nodeSize += s;
- return ::operator new(s);
+ nodeSize += size;
+ return ::operator new[](size);
}
-void Node::operator delete(void* ptr, size_t s)
+void Node::operator delete(void* p, size_t size)
{
- nodeSize -= s;
- ::operator delete(ptr);
+ nodeSize -= size;
+ ::operator delete(p);
+}
+
+void Node::operator delete[](void* p, size_t size)
+{
+ nodeSize -= size;
+ ::operator delete[](p);
}
size_t Node::reportDOMNodesSize()
@@ -2313,46 +2370,24 @@ ScriptExecutionContext* Node::scriptExecutionContext() const
return document();
}
-const RegisteredEventListenerVector& Node::eventListeners() const
-{
- if (hasRareData()) {
- if (RegisteredEventListenerVector* listeners = rareData()->listeners())
- return *listeners;
- }
- static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector;
- return *emptyListenersVector;
-}
-
void Node::insertedIntoDocument()
{
- if (!eventListeners().isEmpty())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
setInDocument(true);
}
void Node::removedFromDocument()
{
- if (!eventListeners().isEmpty())
- document()->registerDisconnectedNodeWithEventListeners(this);
-
setInDocument(false);
}
void Node::willMoveToNewOwnerDocument()
{
- if (!eventListeners().isEmpty())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
ASSERT(!willMoveToNewOwnerDocumentWasCalled);
setWillMoveToNewOwnerDocumentWasCalled(true);
}
void Node::didMoveToNewOwnerDocument()
{
- if (!eventListeners().isEmpty())
- document()->registerDisconnectedNodeWithEventListeners(this);
-
ASSERT(!didMoveToNewOwnerDocumentWasCalled);
setDidMoveToNewOwnerDocumentWasCalled(true);
}
@@ -2382,99 +2417,63 @@ static inline void updateSVGElementInstancesAfterEventListenerChange(Node* refer
#endif
}
-void Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
{
- Document* document = this->document();
- if (!document->attached())
- return;
-
- document->addListenerTypeIfNeeded(eventType);
-
- RegisteredEventListenerVector& listeners = ensureRareData()->ensureListeners();
-
- // Remove existing identical listener set with identical arguments.
- // The DOM2 spec says that "duplicate instances are discarded" in this case.
- removeEventListener(eventType, listener.get(), useCapture);
-
- // adding the first one
- if (listeners.isEmpty() && !inDocument())
- document->registerDisconnectedNodeWithEventListeners(this);
+ if (!EventTarget::addEventListener(eventType, listener, useCapture))
+ return false;
- listeners.append(RegisteredEventListener::create(eventType, listener, useCapture));
+ if (Document* document = this->document())
+ document->addListenerTypeIfNeeded(eventType);
updateSVGElementInstancesAfterEventListenerChange(this);
#if ENABLE(TOUCH_EVENTS) // Android
- if (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent)
- document->addTouchEventListener(this);
+ if (this->document() &&
+ (eventType == eventNames().touchstartEvent ||
+ eventType == eventNames().touchendEvent ||
+ eventType == eventNames().touchmoveEvent ||
+ eventType == eventNames().touchcancelEvent))
+ this->document()->addTouchEventListener(this);
#endif
+ return true;
}
-void Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
{
- if (!hasRareData())
- return;
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
- size_t size = listeners->size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *listeners->at(i);
- if (r.eventType() == eventType && r.listener() == listener && r.useCapture() == useCapture) {
- r.setRemoved(true);
- listeners->remove(i);
+ if (!EventTarget::removeEventListener(eventType, listener, useCapture))
+ return false;
- // removed last
- if (listeners->isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
+ updateSVGElementInstancesAfterEventListenerChange(this);
- updateSVGElementInstancesAfterEventListenerChange(this);
#if ENABLE(TOUCH_EVENTS) // Android
- if (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent)
- document()->removeTouchEventListener(this);
+ if (this->document() &&
+ (eventType == eventNames().touchstartEvent ||
+ eventType == eventNames().touchendEvent ||
+ eventType == eventNames().touchmoveEvent ||
+ eventType == eventNames().touchcancelEvent))
+ this->document()->removeTouchEventListener(this);
#endif
- return;
- }
- }
+ return true;
}
-void Node::removeAllEventListenersSlowCase()
+EventTargetData* Node::eventTargetData()
{
- ASSERT(hasRareData());
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
-#if ENABLE(TOUCH_EVENTS) // Android
- document()->removeTouchEventListener(this);
-#endif
+ return hasRareData() ? rareData()->eventTargetData() : 0;
+}
- size_t size = listeners->size();
- for (size_t i = 0; i < size; ++i)
- listeners->at(i)->setRemoved(true);
- listeners->clear();
+EventTargetData* Node::ensureEventTargetData()
+{
+ return ensureRareData()->ensureEventTargetData();
}
-void Node::handleLocalEvents(Event* event, bool useCapture)
+void Node::handleLocalEvents(Event* event)
{
+ if (!hasRareData() || !rareData()->eventTargetData())
+ return;
+
if (disabled() && event->isMouseEvent())
return;
- RegisteredEventListenerVector listenersCopy = eventListeners();
- size_t size = listenersCopy.size();
- for (size_t i = 0; i < size; ++i) {
- const RegisteredEventListener& r = *listenersCopy[i];
- if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
- r.listener()->handleEvent(event, false);
- }
+ fireEventListeners(event);
}
#if ENABLE(SVG)
@@ -2515,19 +2514,29 @@ static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNo
return referenceNode;
}
-bool Node::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
+void Node::eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors)
{
- RefPtr<Event> evt(e);
- ASSERT(!eventDispatchForbidden());
- if (!evt || evt->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return false;
+ if (inDocument()) {
+ for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) {
+#if ENABLE(SVG)
+ // Skip <use> shadow tree elements.
+ if (ancestor->isSVGElement() && ancestor->isShadowNode())
+ continue;
+#endif
+ ancestors.append(ancestor);
+ }
}
+}
+
+bool Node::dispatchEvent(PassRefPtr<Event> prpEvent)
+{
+ RefPtr<EventTarget> protect = this;
+ RefPtr<Event> event = prpEvent;
- evt->setTarget(eventTargetRespectingSVGTargetRules(this));
+ event->setTarget(eventTargetRespectingSVGTargetRules(this));
RefPtr<FrameView> view = document()->view();
- return dispatchGenericEvent(evt.release());
+ return dispatchGenericEvent(event.release());
}
bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
@@ -2538,21 +2547,18 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
ASSERT(event->target());
ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* timelineAgent = document()->inspectorTimelineAgent();
+ if (timelineAgent)
+ timelineAgent->willDispatchDOMEvent(*event);
+#endif
+
// Make a vector of ancestors to send the event to.
// If the node is not in a document just send the event to it.
// Be sure to ref all of nodes since event handlers could result in the last reference going away.
RefPtr<Node> thisNode(this);
Vector<RefPtr<ContainerNode> > ancestors;
- if (inDocument()) {
- for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) {
-#if ENABLE(SVG)
- // Skip <use> shadow tree elements.
- if (ancestor->isSVGElement() && ancestor->isShadowNode())
- continue;
-#endif
- ancestors.append(ancestor);
- }
- }
+ eventAncestors(ancestors);
// Set up a pointer to indicate whether / where to dispatch window events.
// We don't dispatch load events to the window. That quirk was originally
@@ -2574,27 +2580,22 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
if (targetForWindowEvents) {
event->setCurrentTarget(targetForWindowEvents);
- targetForWindowEvents->handleEvent(event.get(), true);
+ targetForWindowEvents->fireEventListeners(event.get());
if (event->propagationStopped())
goto doneDispatching;
}
for (size_t i = ancestors.size(); i; --i) {
ContainerNode* ancestor = ancestors[i - 1].get();
event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
- ancestor->handleLocalEvents(event.get(), true);
+ ancestor->handleLocalEvents(event.get());
if (event->propagationStopped())
goto doneDispatching;
}
event->setEventPhase(Event::AT_TARGET);
- // We do want capturing event listeners to be invoked here, even though
- // that violates some versions of the DOM specification; Mozilla does it.
event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this));
- handleLocalEvents(event.get(), true);
- if (event->propagationStopped())
- goto doneDispatching;
- handleLocalEvents(event.get(), false);
+ handleLocalEvents(event.get());
if (event->propagationStopped())
goto doneDispatching;
@@ -2606,13 +2607,13 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
for (size_t i = 0; i < size; ++i) {
ContainerNode* ancestor = ancestors[i].get();
event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
- ancestor->handleLocalEvents(event.get(), false);
+ ancestor->handleLocalEvents(event.get());
if (event->propagationStopped() || event->cancelBubble())
goto doneDispatching;
}
if (targetForWindowEvents) {
event->setCurrentTarget(targetForWindowEvents);
- targetForWindowEvents->handleEvent(event.get(), false);
+ targetForWindowEvents->fireEventListeners(event.get());
if (event->propagationStopped() || event->cancelBubble())
goto doneDispatching;
}
@@ -2649,6 +2650,11 @@ doneDispatching:
}
doneWithDefault:
+#if ENABLE(INSPECTOR)
+ if (timelineAgent)
+ timelineAgent->didDispatchDOMEvent();
+#endif
+
Document::updateStyleForAllDocuments();
return !event->defaultPrevented();
@@ -2665,8 +2671,7 @@ void Node::dispatchSubtreeModifiedEvent()
if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
return;
- ExceptionCode ec = 0;
- dispatchMutationEvent(eventNames().DOMSubtreeModifiedEvent, true, 0, String(), String(), ec);
+ dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true));
}
void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
@@ -2676,18 +2681,15 @@ void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr
bool cancelable = eventType == eventNames().DOMActivateEvent;
- ExceptionCode ec = 0;
- RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
- evt->setUnderlyingEvent(underlyingEvent);
- dispatchEvent(evt.release(), ec);
+ RefPtr<UIEvent> event = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
+ event->setUnderlyingEvent(underlyingEvent);
+ dispatchEvent(event.release());
}
bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& key)
{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView());
- bool r = dispatchEvent(keyboardEvent, ec);
+ bool r = dispatchEvent(keyboardEvent);
// we want to return false if default is prevented (already taken care of)
// or if the element is default-handled by the DOM. Otherwise we let it just
@@ -2781,8 +2783,6 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det
bool cancelable = eventType != eventNames().mousemoveEvent;
- ExceptionCode ec = 0;
-
bool swallowEvent = false;
// Attempting to dispatch with a non-EventTarget relatedTarget causes the relatedTarget to be silently ignored.
@@ -2807,7 +2807,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det
mouseEvent->setUnderlyingEvent(underlyingEvent.get());
mouseEvent->setAbsoluteLocation(IntPoint(pageX, pageY));
- dispatchEvent(mouseEvent, ec);
+ dispatchEvent(mouseEvent);
bool defaultHandled = mouseEvent->defaultHandled();
bool defaultPrevented = mouseEvent->defaultPrevented();
if (defaultHandled || defaultPrevented)
@@ -2825,7 +2825,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det
doubleClickEvent->setUnderlyingEvent(underlyingEvent.get());
if (defaultHandled)
doubleClickEvent->setDefaultHandled();
- dispatchEvent(doubleClickEvent, ec);
+ dispatchEvent(doubleClickEvent);
if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
swallowEvent = true;
}
@@ -2862,102 +2862,18 @@ void Node::dispatchWheelEvent(PlatformWheelEvent& e)
we->setAbsoluteLocation(IntPoint(pos.x(), pos.y()));
- ExceptionCode ec = 0;
- if (!dispatchEvent(we.release(), ec))
+ if (!dispatchEvent(we.release()))
e.accept();
}
-void Node::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime)
-{
- ASSERT(!eventDispatchForbidden());
-
- ExceptionCode ec = 0;
- dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec);
-}
-
-void Node::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime)
-{
- ASSERT(!eventDispatchForbidden());
-
- ExceptionCode ec = 0;
- dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec);
-}
-
-void Node::dispatchMutationEvent(const AtomicString& eventType, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode& ec)
-{
- ASSERT(!eventDispatchForbidden());
-
- dispatchEvent(MutationEvent::create(eventType, canBubble, false, relatedNode, prevValue, newValue, String(), 0), ec);
-}
-
void Node::dispatchFocusEvent()
{
- dispatchEvent(eventNames().focusEvent, false, false);
+ dispatchEvent(Event::create(eventNames().focusEvent, false, false));
}
void Node::dispatchBlurEvent()
{
- dispatchEvent(eventNames().blurEvent, false, false);
-}
-
-bool Node::dispatchEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec);
-}
-
-void Node::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec);
-}
-
-void Node::clearAttributeEventListener(const AtomicString& eventType)
-{
- if (!hasRareData())
- return;
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
- size_t size = listeners->size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *listeners->at(i);
- if (r.eventType() != eventType || !r.listener()->isAttribute())
- continue;
-
- r.setRemoved(true);
- listeners->remove(i);
-
- // removed last
- if (listeners->isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- updateSVGElementInstancesAfterEventListenerChange(this);
- return;
- }
-}
-
-void Node::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
- clearAttributeEventListener(eventType);
- if (listener)
- addEventListener(eventType, listener, false);
-}
-
-EventListener* Node::getAttributeEventListener(const AtomicString& eventType) const
-{
- const RegisteredEventListenerVector& listeners = eventListeners();
- size_t size = listeners.size();
- for (size_t i = 0; i < size; ++i) {
- const RegisteredEventListener& r = *listeners[i];
- if (r.eventType() == eventType && r.listener()->isAttribute())
- return r.listener();
- }
- return 0;
+ dispatchEvent(Event::create(eventNames().blurEvent, false, false));
}
bool Node::disabled() const
@@ -2977,10 +2893,12 @@ void Node::defaultEventHandler(Event* event)
} else if (eventType == eventNames().clickEvent) {
int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
dispatchUIEvent(eventNames().DOMActivateEvent, detail, event);
+#if ENABLE(CONTEXT_MENUS)
} else if (eventType == eventNames().contextmenuEvent) {
if (Frame* frame = document()->frame())
if (Page* page = frame->page())
page->contextMenuController()->handleContextMenuEvent(event);
+#endif
} else if (eventType == eventNames().textInputEvent) {
if (event->isTextEvent())
if (Frame* frame = document()->frame())
@@ -2988,438 +2906,6 @@ void Node::defaultEventHandler(Event* event)
}
}
-EventListener* Node::onabort() const
-{
- return getAttributeEventListener(eventNames().abortEvent);
-}
-
-void Node::setOnabort(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().abortEvent, eventListener);
-}
-
-EventListener* Node::onblur() const
-{
- return getAttributeEventListener(eventNames().blurEvent);
-}
-
-void Node::setOnblur(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().blurEvent, eventListener);
-}
-
-EventListener* Node::onchange() const
-{
- return getAttributeEventListener(eventNames().changeEvent);
-}
-
-void Node::setOnchange(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().changeEvent, eventListener);
-}
-
-EventListener* Node::onclick() const
-{
- return getAttributeEventListener(eventNames().clickEvent);
-}
-
-void Node::setOnclick(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().clickEvent, eventListener);
-}
-
-EventListener* Node::oncontextmenu() const
-{
- return getAttributeEventListener(eventNames().contextmenuEvent);
-}
-
-void Node::setOncontextmenu(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().contextmenuEvent, eventListener);
-}
-
-EventListener* Node::ondblclick() const
-{
- return getAttributeEventListener(eventNames().dblclickEvent);
-}
-
-void Node::setOndblclick(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dblclickEvent, eventListener);
-}
-
-EventListener* Node::onerror() const
-{
- return getAttributeEventListener(eventNames().errorEvent);
-}
-
-void Node::setOnerror(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* Node::onfocus() const
-{
- return getAttributeEventListener(eventNames().focusEvent);
-}
-
-void Node::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().focusEvent, eventListener);
-}
-
-EventListener* Node::oninput() const
-{
- return getAttributeEventListener(eventNames().inputEvent);
-}
-
-void Node::setOninput(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().inputEvent, eventListener);
-}
-
-EventListener* Node::onkeydown() const
-{
- return getAttributeEventListener(eventNames().keydownEvent);
-}
-
-void Node::setOnkeydown(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().keydownEvent, eventListener);
-}
-
-EventListener* Node::onkeypress() const
-{
- return getAttributeEventListener(eventNames().keypressEvent);
-}
-
-void Node::setOnkeypress(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().keypressEvent, eventListener);
-}
-
-EventListener* Node::onkeyup() const
-{
- return getAttributeEventListener(eventNames().keyupEvent);
-}
-
-void Node::setOnkeyup(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().keyupEvent, eventListener);
-}
-
-EventListener* Node::onload() const
-{
- return getAttributeEventListener(eventNames().loadEvent);
-}
-
-void Node::setOnload(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().loadEvent, eventListener);
-}
-
-EventListener* Node::onmousedown() const
-{
- return getAttributeEventListener(eventNames().mousedownEvent);
-}
-
-void Node::setOnmousedown(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mousedownEvent, eventListener);
-}
-
-EventListener* Node::onmousemove() const
-{
- return getAttributeEventListener(eventNames().mousemoveEvent);
-}
-
-void Node::setOnmousemove(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mousemoveEvent, eventListener);
-}
-
-EventListener* Node::onmouseout() const
-{
- return getAttributeEventListener(eventNames().mouseoutEvent);
-}
-
-void Node::setOnmouseout(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mouseoutEvent, eventListener);
-}
-
-EventListener* Node::onmouseover() const
-{
- return getAttributeEventListener(eventNames().mouseoverEvent);
-}
-
-void Node::setOnmouseover(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mouseoverEvent, eventListener);
-}
-
-EventListener* Node::onmouseup() const
-{
- return getAttributeEventListener(eventNames().mouseupEvent);
-}
-
-void Node::setOnmouseup(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mouseupEvent, eventListener);
-}
-
-EventListener* Node::onmousewheel() const
-{
- return getAttributeEventListener(eventNames().mousewheelEvent);
-}
-
-void Node::setOnmousewheel(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mousewheelEvent, eventListener);
-}
-
-EventListener* Node::ondragenter() const
-{
- return getAttributeEventListener(eventNames().dragenterEvent);
-}
-
-void Node::setOndragenter(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragenterEvent, eventListener);
-}
-
-EventListener* Node::ondragover() const
-{
- return getAttributeEventListener(eventNames().dragoverEvent);
-}
-
-void Node::setOndragover(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragoverEvent, eventListener);
-}
-
-EventListener* Node::ondragleave() const
-{
- return getAttributeEventListener(eventNames().dragleaveEvent);
-}
-
-void Node::setOndragleave(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragleaveEvent, eventListener);
-}
-
-EventListener* Node::ondrop() const
-{
- return getAttributeEventListener(eventNames().dropEvent);
-}
-
-void Node::setOndrop(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dropEvent, eventListener);
-}
-
-EventListener* Node::ondragstart() const
-{
- return getAttributeEventListener(eventNames().dragstartEvent);
-}
-
-void Node::setOndragstart(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragstartEvent, eventListener);
-}
-
-EventListener* Node::ondrag() const
-{
- return getAttributeEventListener(eventNames().dragEvent);
-}
-
-void Node::setOndrag(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragEvent, eventListener);
-}
-
-EventListener* Node::ondragend() const
-{
- return getAttributeEventListener(eventNames().dragendEvent);
-}
-
-void Node::setOndragend(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragendEvent, eventListener);
-}
-
-EventListener* Node::onscroll() const
-{
- return getAttributeEventListener(eventNames().scrollEvent);
-}
-
-void Node::setOnscroll(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().scrollEvent, eventListener);
-}
-
-EventListener* Node::onselect() const
-{
- return getAttributeEventListener(eventNames().selectEvent);
-}
-
-void Node::setOnselect(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().selectEvent, eventListener);
-}
-
-EventListener* Node::onsubmit() const
-{
- return getAttributeEventListener(eventNames().submitEvent);
-}
-
-void Node::setOnsubmit(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().submitEvent, eventListener);
-}
-
-EventListener* Node::onbeforecut() const
-{
- return getAttributeEventListener(eventNames().beforecutEvent);
-}
-
-void Node::setOnbeforecut(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().beforecutEvent, eventListener);
-}
-
-EventListener* Node::oncut() const
-{
- return getAttributeEventListener(eventNames().cutEvent);
-}
-
-void Node::setOncut(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().cutEvent, eventListener);
-}
-
-EventListener* Node::onbeforecopy() const
-{
- return getAttributeEventListener(eventNames().beforecopyEvent);
-}
-
-void Node::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().beforecopyEvent, eventListener);
-}
-
-EventListener* Node::oncopy() const
-{
- return getAttributeEventListener(eventNames().copyEvent);
-}
-
-void Node::setOncopy(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().copyEvent, eventListener);
-}
-
-EventListener* Node::onbeforepaste() const
-{
- return getAttributeEventListener(eventNames().beforepasteEvent);
-}
-
-void Node::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().beforepasteEvent, eventListener);
-}
-
-EventListener* Node::onpaste() const
-{
- return getAttributeEventListener(eventNames().pasteEvent);
-}
-
-void Node::setOnpaste(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().pasteEvent, eventListener);
-}
-
-EventListener* Node::onreset() const
-{
- return getAttributeEventListener(eventNames().resetEvent);
-}
-
-void Node::setOnreset(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().resetEvent, eventListener);
-}
-
-EventListener* Node::onsearch() const
-{
- return getAttributeEventListener(eventNames().searchEvent);
-}
-
-void Node::setOnsearch(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().searchEvent, eventListener);
-}
-
-EventListener* Node::onselectstart() const
-{
- return getAttributeEventListener(eventNames().selectstartEvent);
-}
-
-void Node::setOnselectstart(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().selectstartEvent, eventListener);
-}
-
-EventListener* Node::onunload() const
-{
- return getAttributeEventListener(eventNames().unloadEvent);
-}
-
-void Node::setOnunload(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().unloadEvent, eventListener);
-}
-
-#if ENABLE(TOUCH_EVENTS) // Android
-EventListener* Node::ontouchstart() const
-{
- return getAttributeEventListener(eventNames().touchstartEvent);
-}
-
-void Node::setOntouchstart(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().touchstartEvent, eventListener);
-}
-
-EventListener* Node::ontouchend() const
-{
- return getAttributeEventListener(eventNames().touchendEvent);
-}
-
-void Node::setOntouchend(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().touchendEvent, eventListener);
-}
-
-EventListener* Node::ontouchmove() const
-{
- return getAttributeEventListener(eventNames().touchmoveEvent);
-}
-
-void Node::setOntouchmove(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().touchmoveEvent, eventListener);
-}
-
-EventListener* Node::ontouchcancel() const
-{
- return getAttributeEventListener(eventNames().touchcancelEvent);
-}
-
-void Node::setOntouchcancel(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().touchcancelEvent, eventListener);
-}
-#endif // ENABLE(TOUCH_EVENT)
-
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index f10e830..082ab16 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -25,7 +25,6 @@
#ifndef Node_h
#define Node_h
-#include "DocPtr.h"
#include "EventTarget.h"
#include "KURLHash.h"
#include "PlatformString.h"
@@ -68,7 +67,10 @@ class StringBuilder;
typedef int ExceptionCode;
-enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, AnimationStyleChange };
+// SyntheticStyleChange means that we need to go through the entire style change logic even though
+// no style property has actually changed. It is used to restructure the tree when, for instance,
+// RenderLayers are created or destroyed due to animation changes.
+enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, SyntheticStyleChange };
const unsigned short DOCUMENT_POSITION_EQUIVALENT = 0x00;
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
@@ -108,7 +110,6 @@ public:
enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
static StyleChange diff(const RenderStyle*, const RenderStyle*);
- Node(Document*, bool isElement = false, bool isContainer = false, bool isText = false);
virtual ~Node();
// DOM methods & attributes for Node
@@ -182,6 +183,14 @@ public:
static bool isWMLElement() { return false; }
#endif
+#if ENABLE(MATHML)
+ virtual bool isMathMLElement() const { return false; }
+#else
+ static bool isMathMLElement() { return false; }
+#endif
+
+
+ virtual bool isMediaControlElement() const { return false; }
virtual bool isStyledElement() const { return false; }
virtual bool isFrameOwnerElement() const { return false; }
virtual bool isAttributeNode() const { return false; }
@@ -197,6 +206,9 @@ public:
// The node's parent for the purpose of event capture and bubbling.
virtual ContainerNode* eventParentNode();
+ // Node ancestors when concerned about event flow
+ void eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors);
+
bool isBlockFlow() const;
bool isBlockFlowOrBlockTable() const;
@@ -289,10 +301,10 @@ public:
virtual short tabIndex() const;
- /**
- * Whether this node can receive the keyboard focus.
- */
- virtual bool supportsFocus() const { return isFocusable(); }
+ // Whether this kind of node can receive focus by default. Most nodes are
+ // not focusable but some elements, such as form controls and links are.
+ virtual bool supportsFocus() const;
+ // Whether the node can actually be focused.
virtual bool isFocusable() const;
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
virtual bool isMouseFocusable() const;
@@ -316,7 +328,7 @@ public:
{
ASSERT(this);
ASSERT(m_document || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
- return m_document.get();
+ return m_document;
}
void setDocument(Document*);
@@ -501,44 +513,33 @@ public:
#ifdef ANDROID_INSTRUMENT
// Overridden to prevent the normal new from being called.
- void* operator new(size_t) throw();
+ void* operator new(size_t size);
+ void* operator new[](size_t size);
// Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
+ void operator delete(void* p, size_t size);
+ void operator delete[](void* p, size_t size);
static size_t reportDOMNodesSize();
#endif
-protected:
- virtual void willMoveToNewOwnerDocument();
- virtual void didMoveToNewOwnerDocument();
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
- void setTabIndexExplicitly(short);
-
- bool hasRareData() const { return m_hasRareData; }
-
- NodeRareData* rareData() const;
- NodeRareData* ensureRareData();
-
-public:
virtual Node* toNode() { return this; }
virtual ScriptExecutionContext* scriptExecutionContext() const;
- // Used for standard DOM addEventListener / removeEventListener APIs.
- virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
- // Used for legacy "onEvent" property APIs.
- void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
- void clearAttributeEventListener(const AtomicString& eventType);
- EventListener* getAttributeEventListener(const AtomicString& eventType) const;
+ // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
+ // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch.
+ virtual void* preDispatchEventHandler(Event*) { return 0; }
+ virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
- virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
- bool dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
+ using EventTarget::dispatchEvent;
+ virtual bool dispatchEvent(PassRefPtr<Event>);
- void removeAllEventListeners() { if (hasRareData()) removeAllEventListenersSlowCase(); }
+ bool dispatchGenericEvent(PassRefPtr<Event>);
+ virtual void handleLocalEvents(Event*);
void dispatchSubtreeModifiedEvent();
void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent);
@@ -552,14 +553,6 @@ public:
bool isSimulated, Node* relatedTarget, PassRefPtr<Event> underlyingEvent);
void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent);
void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
- void dispatchProgressEvent(const AtomicString& eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg);
- void dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime);
- void dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime);
- void dispatchMutationEvent(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode&);
-
- bool dispatchGenericEvent(PassRefPtr<Event>);
-
- virtual void handleLocalEvents(Event*, bool useCapture);
virtual void dispatchFocusEvent();
virtual void dispatchBlurEvent();
@@ -575,112 +568,47 @@ public:
*/
virtual bool disabled() const;
- const RegisteredEventListenerVector& eventListeners() const;
-
- // These 4 attribute event handler attributes are overrided by HTMLBodyElement
- // and HTMLFrameSetElement to forward to the DOMWindow.
- virtual EventListener* onblur() const;
- virtual void setOnblur(PassRefPtr<EventListener>);
- virtual EventListener* onerror() const;
- virtual void setOnerror(PassRefPtr<EventListener>);
- virtual EventListener* onfocus() const;
- virtual void setOnfocus(PassRefPtr<EventListener>);
- virtual EventListener* onload() const;
- virtual void setOnload(PassRefPtr<EventListener>);
-
- EventListener* onabort() const;
- void setOnabort(PassRefPtr<EventListener>);
- EventListener* onchange() const;
- void setOnchange(PassRefPtr<EventListener>);
- EventListener* onclick() const;
- void setOnclick(PassRefPtr<EventListener>);
- EventListener* oncontextmenu() const;
- void setOncontextmenu(PassRefPtr<EventListener>);
- EventListener* ondblclick() const;
- void setOndblclick(PassRefPtr<EventListener>);
- EventListener* oninput() const;
- void setOninput(PassRefPtr<EventListener>);
- EventListener* onkeydown() const;
- void setOnkeydown(PassRefPtr<EventListener>);
- EventListener* onkeypress() const;
- void setOnkeypress(PassRefPtr<EventListener>);
- EventListener* onkeyup() const;
- void setOnkeyup(PassRefPtr<EventListener>);
- EventListener* onmousedown() const;
- void setOnmousedown(PassRefPtr<EventListener>);
- EventListener* onmousemove() const;
- void setOnmousemove(PassRefPtr<EventListener>);
- EventListener* onmouseout() const;
- void setOnmouseout(PassRefPtr<EventListener>);
- EventListener* onmouseover() const;
- void setOnmouseover(PassRefPtr<EventListener>);
- EventListener* onmouseup() const;
- void setOnmouseup(PassRefPtr<EventListener>);
- EventListener* onmousewheel() const;
- void setOnmousewheel(PassRefPtr<EventListener>);
- EventListener* ondragenter() const;
- void setOndragenter(PassRefPtr<EventListener>);
- EventListener* ondragover() const;
- void setOndragover(PassRefPtr<EventListener>);
- EventListener* ondragleave() const;
- void setOndragleave(PassRefPtr<EventListener>);
- EventListener* ondrop() const;
- void setOndrop(PassRefPtr<EventListener>);
- EventListener* ondragstart() const;
- void setOndragstart(PassRefPtr<EventListener>);
- EventListener* ondrag() const;
- void setOndrag(PassRefPtr<EventListener>);
- EventListener* ondragend() const;
- void setOndragend(PassRefPtr<EventListener>);
- EventListener* onscroll() const;
- void setOnscroll(PassRefPtr<EventListener>);
- EventListener* onselect() const;
- void setOnselect(PassRefPtr<EventListener>);
- EventListener* onsubmit() const;
- void setOnsubmit(PassRefPtr<EventListener>);
-
- // WebKit extensions
- EventListener* onbeforecut() const;
- void setOnbeforecut(PassRefPtr<EventListener>);
- EventListener* oncut() const;
- void setOncut(PassRefPtr<EventListener>);
- EventListener* onbeforecopy() const;
- void setOnbeforecopy(PassRefPtr<EventListener>);
- EventListener* oncopy() const;
- void setOncopy(PassRefPtr<EventListener>);
- EventListener* onbeforepaste() const;
- void setOnbeforepaste(PassRefPtr<EventListener>);
- EventListener* onpaste() const;
- void setOnpaste(PassRefPtr<EventListener>);
- EventListener* onreset() const;
- void setOnreset(PassRefPtr<EventListener>);
- EventListener* onsearch() const;
- void setOnsearch(PassRefPtr<EventListener>);
- EventListener* onselectstart() const;
- void setOnselectstart(PassRefPtr<EventListener>);
- EventListener* onunload() const;
- void setOnunload(PassRefPtr<EventListener>);
#if ENABLE(TOUCH_EVENTS) // Android
- EventListener* ontouchstart() const;
- void setOntouchstart(PassRefPtr<EventListener>);
- EventListener* ontouchend() const;
- void setOntouchend(PassRefPtr<EventListener>);
- EventListener* ontouchmove() const;
- void setOntouchmove(PassRefPtr<EventListener>);
- EventListener* ontouchcancel() const;
- void setOntouchcancel(PassRefPtr<EventListener>);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
#endif
using TreeShared<Node>::ref;
using TreeShared<Node>::deref;
-
+
+ virtual EventTargetData* eventTargetData();
+ virtual EventTargetData* ensureEventTargetData();
+
+protected:
+ // CreateElementZeroRefCount is deprecated and can be removed once we convert all element
+ // classes to start with a reference count of 1.
+ enum ConstructionType { CreateContainer, CreateElement, CreateOther, CreateText, CreateElementZeroRefCount };
+ Node(Document*, ConstructionType);
+
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
+ void setTabIndexExplicitly(short);
+
+ bool hasRareData() const { return m_hasRareData; }
+
+ NodeRareData* rareData() const;
+ NodeRareData* ensureRareData();
+
private:
+ static bool initialRefCount(ConstructionType);
+ static bool isContainer(ConstructionType);
+ static bool isElement(ConstructionType);
+ static bool isText(ConstructionType);
+
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
void removeAllEventListenersSlowCase();
-private:
virtual NodeRareData* createRareData();
Node* containerChildNode(unsigned index) const;
unsigned containerChildNodeCount() const;
@@ -698,7 +626,7 @@ private:
void appendTextContent(bool convertBRsToNewlines, StringBuilder&) const;
- DocPtr<Document> m_document;
+ Document* m_document;
Node* m_previous;
Node* m_next;
RenderObject* m_renderer;
@@ -721,22 +649,16 @@ private:
const bool m_isText : 1;
protected:
- // These bits are used by the Element derived class, pulled up here so they can
+ // These bits are used by derived classes, pulled up here so they can
// be stored in the same memory word as the Node bits above.
- bool m_parsingChildrenFinished : 1;
-#if ENABLE(SVG)
- mutable bool m_areSVGAttributesValid : 1;
-#endif
- // These bits are used by the StyledElement derived class, and live here for the
- // same reason as above.
- mutable bool m_isStyleAttributeValid : 1;
- mutable bool m_synchronizingStyleAttribute : 1;
+ bool m_parsingChildrenFinished : 1; // Element
+ mutable bool m_isStyleAttributeValid : 1; // StyledElement
+ mutable bool m_synchronizingStyleAttribute : 1; // StyledElement
#if ENABLE(SVG)
- // This bit is used by the SVGElement derived class, and lives here for the same
- // reason as above.
- mutable bool m_synchronizingSVGAttributes : 1;
+ mutable bool m_areSVGAttributesValid : 1; // Element
+ mutable bool m_synchronizingSVGAttributes : 1; // SVGElement
#endif
// 11 bits remaining
diff --git a/WebCore/dom/Node.idl b/WebCore/dom/Node.idl
index 1e31aea..45ea132 100644
--- a/WebCore/dom/Node.idl
+++ b/WebCore/dom/Node.idl
@@ -24,6 +24,7 @@ module core {
CustomMarkFunction,
CustomPushEventHandlerScope,
CustomToJS,
+ EventTarget,
GenerateConstructor,
GenerateNativeConverter,
InlineGetOwnPropertySlot,
diff --git a/WebCore/dom/NodeRareData.h b/WebCore/dom/NodeRareData.h
index 7740344..8b9e1bf 100644
--- a/WebCore/dom/NodeRareData.h
+++ b/WebCore/dom/NodeRareData.h
@@ -93,12 +93,12 @@ public:
void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; }
bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; }
- RegisteredEventListenerVector* listeners() { return m_eventListeners.get(); }
- RegisteredEventListenerVector& ensureListeners()
+ EventTargetData* eventTargetData() { return m_eventTargetData.get(); }
+ EventTargetData* ensureEventTargetData()
{
- if (!m_eventListeners)
- m_eventListeners.set(new RegisteredEventListenerVector);
- return *m_eventListeners;
+ if (!m_eventTargetData)
+ m_eventTargetData.set(new EventTargetData);
+ return m_eventTargetData.get();
}
bool isFocused() const { return m_isFocused; }
@@ -111,7 +111,7 @@ protected:
private:
OwnPtr<NodeListsNodeData> m_nodeLists;
- OwnPtr<RegisteredEventListenerVector > m_eventListeners;
+ OwnPtr<EventTargetData> m_eventTargetData;
short m_tabIndex;
bool m_tabIndexWasSetExplicitly : 1;
bool m_isFocused : 1;
diff --git a/WebCore/dom/Notation.cpp b/WebCore/dom/Notation.cpp
index 7081d98..cade384 100644
--- a/WebCore/dom/Notation.cpp
+++ b/WebCore/dom/Notation.cpp
@@ -1,8 +1,6 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2009 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
@@ -19,17 +17,14 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "Notation.h"
namespace WebCore {
-Notation::Notation(Document* doc) : ContainerNode(doc)
-{
-}
-
-Notation::Notation(Document* doc, const String& name, const String& publicId, const String& systemId)
- : ContainerNode(doc)
+Notation::Notation(Document* document, const String& name, const String& publicId, const String& systemId)
+ : ContainerNode(document)
, m_name(name)
, m_publicId(publicId)
, m_systemId(systemId)
@@ -52,7 +47,6 @@ PassRefPtr<Node> Notation::cloneNode(bool /*deep*/)
return 0;
}
-// DOM Section 1.1.1
bool Notation::childTypeAllowed(NodeType)
{
return false;
diff --git a/WebCore/dom/Notation.h b/WebCore/dom/Notation.h
index 2bd5363..547c9e7 100644
--- a/WebCore/dom/Notation.h
+++ b/WebCore/dom/Notation.h
@@ -1,8 +1,6 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2009 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
@@ -24,26 +22,25 @@
#ifndef Notation_h
#define Notation_h
-#include "CachedResourceClient.h"
#include "ContainerNode.h"
namespace WebCore {
+// FIXME: This class is never instantiated. Maybe it should be removed.
+
class Notation : public ContainerNode {
public:
- Notation(Document*);
- Notation(Document*, const String& name, const String& publicId, const String& systemId);
+ const String& publicId() const { return m_publicId; }
+ const String& systemId() const { return m_systemId; }
- // DOM methods & attributes for Notation
- String publicId() const { return m_publicId; }
- String systemId() const { return m_systemId; }
+private:
+ Notation(Document*, const String& name, const String& publicId, const String& systemId);
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual bool childTypeAllowed(NodeType);
-private:
String m_name;
String m_publicId;
String m_systemId;
diff --git a/WebCore/dom/PageTransitionEvent.cpp b/WebCore/dom/PageTransitionEvent.cpp
new file mode 100644
index 0000000..f9c487d
--- /dev/null
+++ b/WebCore/dom/PageTransitionEvent.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageTransitionEvent.h"
+
+#include "EventNames.h"
+
+namespace WebCore {
+
+PageTransitionEvent::PageTransitionEvent()
+ : m_persisted(false)
+{
+}
+
+PageTransitionEvent::PageTransitionEvent(const AtomicString& type, bool persisted)
+ : Event(type, true, true)
+ , m_persisted(persisted)
+{
+}
+
+PageTransitionEvent::~PageTransitionEvent()
+{
+}
+
+void PageTransitionEvent::initPageTransitionEvent(const AtomicString& type,
+ bool canBubbleArg,
+ bool cancelableArg,
+ bool persisted)
+{
+ if (dispatched())
+ return;
+
+ initEvent(type, canBubbleArg, cancelableArg);
+
+ m_persisted = persisted;
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/PageTransitionEvent.h b/WebCore/dom/PageTransitionEvent.h
new file mode 100644
index 0000000..33c5a0c
--- /dev/null
+++ b/WebCore/dom/PageTransitionEvent.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PageTransitionEvent_h
+#define PageTransitionEvent_h
+
+#include "Event.h"
+
+namespace WebCore {
+
+ class PageTransitionEvent : public Event {
+ public:
+ static PassRefPtr<PageTransitionEvent> create()
+ {
+ return adoptRef(new PageTransitionEvent);
+ }
+ static PassRefPtr<PageTransitionEvent> create(const AtomicString& type, bool persisted)
+ {
+ return adoptRef(new PageTransitionEvent(type, persisted));
+ }
+
+ virtual ~PageTransitionEvent();
+
+ void initPageTransitionEvent(const AtomicString& type,
+ bool canBubbleArg,
+ bool cancelableArg,
+ bool persisted);
+
+ virtual bool isPageTransitionEvent() const { return true; }
+
+ bool persisted() const { return m_persisted; }
+
+ private:
+ PageTransitionEvent();
+ PageTransitionEvent(const AtomicString& type, bool persisted);
+
+ bool m_persisted;
+ };
+
+} // namespace WebCore
+
+#endif // PageTransitionEvent_h
diff --git a/WebCore/dom/PageTransitionEvent.idl b/WebCore/dom/PageTransitionEvent.idl
new file mode 100644
index 0000000..a09f94b
--- /dev/null
+++ b/WebCore/dom/PageTransitionEvent.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module events {
+
+ interface [
+ GenerateConstructor
+ ] PageTransitionEvent : Event {
+
+ readonly attribute boolean persisted;
+
+ void initPageTransitionEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in boolean persisted);
+ };
+
+}
diff --git a/WebCore/dom/Position.cpp b/WebCore/dom/Position.cpp
index 3b4c3e8..060b28c 100644
--- a/WebCore/dom/Position.cpp
+++ b/WebCore/dom/Position.cpp
@@ -138,10 +138,7 @@ int Position::computeOffsetInContainerNode() const
switch (anchorType()) {
case PositionIsOffsetInAnchor:
- {
- int maximumValidOffset = m_anchorNode->offsetInCharacters() ? m_anchorNode->maxCharacterOffset() : m_anchorNode->childNodeCount();
- return std::min(maximumValidOffset, m_offset);
- }
+ return std::min(lastOffsetInNode(m_anchorNode.get()), m_offset);
case PositionIsBeforeAnchor:
return m_anchorNode->nodeIndex();
case PositionIsAfterAnchor:
@@ -1115,28 +1112,7 @@ void Position::showTreeForThis() const
#endif
-Position startPosition(const Range* r)
-{
- return r ? r->startPosition() : Position();
-}
-
-Position endPosition(const Range* r)
-{
- return r ? r->endPosition() : Position();
-}
-// NOTE: first/lastDeepEditingPositionForNode can return "editing positions" (like [img, 0])
-// for elements which editing "ignores". the rest of the editing code will treat [img, 0]
-// as "the last position before the img"
-Position firstDeepEditingPositionForNode(Node* node)
-{
- return Position(node, 0);
-}
-
-Position lastDeepEditingPositionForNode(Node* node)
-{
- return Position(node, lastOffsetForEditing(node));
-}
} // namespace WebCore
diff --git a/WebCore/dom/Position.h b/WebCore/dom/Position.h
index b434ec9..c08872d 100644
--- a/WebCore/dom/Position.h
+++ b/WebCore/dom/Position.h
@@ -28,6 +28,7 @@
#include "TextAffinity.h"
#include "TextDirection.h"
+#include "Node.h" // for position creation functions
#include <wtf/Assertions.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -188,14 +189,53 @@ inline bool operator!=(const Position& a, const Position& b)
return !(a == b);
}
-Position startPosition(const Range*);
-Position endPosition(const Range*);
+// We define position creation functions to make callsites more readable.
+// These are inline to prevent ref-churn when returning a Position object.
+// If we ever add a PassPosition we can make these non-inline.
-// NOTE: first/lastDeepEditingPositionForNode can return "editing positions" (like [img, 0])
-// for elements which editing "ignores". the rest of the editing code will treat [img, 0]
-// as "the last position before the img"
-Position firstDeepEditingPositionForNode(Node*);
-Position lastDeepEditingPositionForNode(Node*);
+inline Position positionInParentBeforeNode(const Node* node)
+{
+ // FIXME: This should ASSERT(node->parentNode())
+ // At least one caller currently hits this ASSERT though, which indicates
+ // that the caller is trying to make a position relative to a disconnected node (which is likely an error)
+ // Specifically, editing/deleting/delete-ligature-001.html crashes with ASSERT(node->parentNode())
+ return Position(node->parentNode(), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
+}
+
+inline Position positionInParentAfterNode(const Node* node)
+{
+ ASSERT(node->parentNode());
+ return Position(node->parentNode(), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
+}
+
+// positionBeforeNode and positionAfterNode return neighbor-anchored positions, construction is O(1)
+inline Position positionBeforeNode(Node* anchorNode)
+{
+ ASSERT(anchorNode);
+ return Position(anchorNode, Position::PositionIsBeforeAnchor);
+}
+
+inline Position positionAfterNode(Node* anchorNode)
+{
+ ASSERT(anchorNode);
+ return Position(anchorNode, Position::PositionIsAfterAnchor);
+}
+
+inline int lastOffsetInNode(Node* node)
+{
+ return node->offsetInCharacters() ? node->maxCharacterOffset() : node->childNodeCount();
+}
+
+// firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to childNodeCount()
+inline Position firstPositionInNode(Node* anchorNode)
+{
+ return Position(anchorNode, 0, Position::PositionIsOffsetInAnchor);
+}
+
+inline Position lastPositionInNode(Node* anchorNode)
+{
+ return Position(anchorNode, lastOffsetInNode(anchorNode), Position::PositionIsOffsetInAnchor);
+}
} // namespace WebCore
diff --git a/WebCore/dom/PositionCreationFunctions.h b/WebCore/dom/PositionCreationFunctions.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/WebCore/dom/PositionCreationFunctions.h
diff --git a/WebCore/dom/PositionIterator.cpp b/WebCore/dom/PositionIterator.cpp
index a029b5e..8d881ba 100644
--- a/WebCore/dom/PositionIterator.cpp
+++ b/WebCore/dom/PositionIterator.cpp
@@ -38,7 +38,7 @@ PositionIterator::operator Position() const
{
if (m_nodeAfterPositionInAnchor) {
ASSERT(m_nodeAfterPositionInAnchor->parentNode() == m_anchorNode);
- return positionBeforeNode(m_nodeAfterPositionInAnchor);
+ return positionInParentBeforeNode(m_nodeAfterPositionInAnchor);
}
if (m_anchorNode->hasChildNodes())
return lastDeepEditingPositionForNode(m_anchorNode);
diff --git a/WebCore/dom/ProcessingInstruction.cpp b/WebCore/dom/ProcessingInstruction.cpp
index 806bf92..8a94864 100644
--- a/WebCore/dom/ProcessingInstruction.cpp
+++ b/WebCore/dom/ProcessingInstruction.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2009 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
@@ -35,8 +35,10 @@
namespace WebCore {
-ProcessingInstruction::ProcessingInstruction(Document* doc)
- : ContainerNode(doc)
+inline ProcessingInstruction::ProcessingInstruction(Document* document, const String& target, const String& data)
+ : ContainerNode(document)
+ , m_target(target)
+ , m_data(data)
, m_cachedSheet(0)
, m_loading(false)
, m_alternate(false)
@@ -46,17 +48,9 @@ ProcessingInstruction::ProcessingInstruction(Document* doc)
{
}
-ProcessingInstruction::ProcessingInstruction(Document* doc, const String& target, const String& data)
- : ContainerNode(doc)
- , m_target(target)
- , m_data(data)
- , m_cachedSheet(0)
- , m_loading(false)
- , m_alternate(false)
-#if ENABLE(XSLT)
- , m_isXSL(false)
-#endif
+PassRefPtr<ProcessingInstruction> ProcessingInstruction::create(Document* document, const String& target, const String& data)
{
+ return adoptRef(new ProcessingInstruction(document, target, data));
}
ProcessingInstruction::~ProcessingInstruction()
@@ -70,6 +64,7 @@ void ProcessingInstruction::setData(const String& data, ExceptionCode&)
int oldLength = m_data.length();
m_data = data;
document()->textRemoved(this, 0, oldLength);
+ checkStyleSheet();
}
String ProcessingInstruction::nodeName() const
@@ -95,8 +90,9 @@ void ProcessingInstruction::setNodeValue(const String& nodeValue, ExceptionCode&
PassRefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
{
- // ### copy m_localHref
- return new ProcessingInstruction(document(), m_target, m_data);
+ // FIXME: Is it a problem that this does not copy m_localHref?
+ // What about other data members?
+ return create(document(), m_target, m_data);
}
// DOM Section 1.1.1
@@ -147,13 +143,21 @@ void ProcessingInstruction::checkStyleSheet()
}
#endif
} else {
+ if (m_cachedSheet) {
+ m_cachedSheet->removeClient(this);
+ m_cachedSheet = 0;
+ }
+
+ String url = document()->completeURL(href).string();
+ if (!dispatchBeforeLoadEvent(url))
+ return;
+
m_loading = true;
document()->addPendingSheet();
- if (m_cachedSheet)
- m_cachedSheet->removeClient(this);
+
#if ENABLE(XSLT)
if (m_isXSL)
- m_cachedSheet = document()->docLoader()->requestXSLStyleSheet(document()->completeURL(href).string());
+ m_cachedSheet = document()->docLoader()->requestXSLStyleSheet(url);
else
#endif
{
@@ -161,10 +165,15 @@ void 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(url, charset);
}
if (m_cachedSheet)
m_cachedSheet->addClient(this);
+ else {
+ // The request may have been denied if (for example) the stylesheet is local and the document is remote.
+ m_loading = false;
+ document()->removePendingSheet();
+ }
}
}
}
@@ -271,4 +280,26 @@ void ProcessingInstruction::finishParsingChildren()
ContainerNode::finishParsingChildren();
}
+#ifdef ANDROID_INSTRUMENT
+void* ProcessingInstruction::operator new(size_t size)
+{
+ return Node::operator new(size);
+}
+
+void* ProcessingInstruction::operator new[](size_t size)
+{
+ return Node::operator new[](size);
+}
+
+void ProcessingInstruction::operator delete(void* p, size_t size)
+{
+ Node::operator delete(p, size);
+}
+
+void ProcessingInstruction::operator delete[](void* p, size_t size)
+{
+ Node::operator delete[](p, size);
+}
+#endif
+
} // namespace
diff --git a/WebCore/dom/ProcessingInstruction.h b/WebCore/dom/ProcessingInstruction.h
index d133019..61af9cf 100644
--- a/WebCore/dom/ProcessingInstruction.h
+++ b/WebCore/dom/ProcessingInstruction.h
@@ -1,8 +1,6 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 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
@@ -35,15 +33,36 @@ class CSSStyleSheet;
class ProcessingInstruction : public ContainerNode, private CachedResourceClient {
public:
- ProcessingInstruction(Document*);
- ProcessingInstruction(Document*, const String& target, const String& data);
+ static PassRefPtr<ProcessingInstruction> create(Document*, const String& target, const String& data);
virtual ~ProcessingInstruction();
- // DOM methods & attributes for Notation
- String target() const { return m_target; }
- String data() const { return m_data; }
+ const String& target() const { return m_target; }
+ const String& data() const { return m_data; }
void setData(const String&, ExceptionCode&);
+ void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; }
+
+ virtual void finishParsingChildren();
+
+ const String& localHref() const { return m_localHref; }
+ StyleSheet* sheet() const { return m_sheet.get(); }
+ void setCSSStyleSheet(PassRefPtr<CSSStyleSheet>);
+
+#if ENABLE(XSLT)
+ bool isXSL() const { return m_isXSL; }
+#endif
+
+private:
+ ProcessingInstruction(Document*, const String& target, const String& data);
+
+#ifdef ANDROID_INSTRUMENT
+ // Overridden to resolve the ambiguous
+ void* operator new(size_t size);
+ void* operator new[](size_t size);
+ void operator delete(void* p, size_t size);
+ void operator delete[](void* p, size_t size);
+#endif
+
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual String nodeValue() const;
@@ -55,28 +74,18 @@ public:
virtual void insertedIntoDocument();
virtual void removedFromDocument();
- void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; }
- virtual void finishParsingChildren();
- // Other methods (not part of DOM)
- String localHref() const { return m_localHref; }
- StyleSheet* sheet() const { return m_sheet.get(); }
void checkStyleSheet();
virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
#if ENABLE(XSLT)
virtual void setXSLStyleSheet(const String& url, const String& sheet);
#endif
- void setCSSStyleSheet(PassRefPtr<CSSStyleSheet>);
+
bool isLoading() const;
virtual bool sheetLoaded();
-#if ENABLE(XSLT)
- bool isXSL() const { return m_isXSL; }
-#endif
-
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-private:
void parseStyleSheet(const String& sheet);
String m_target;
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index edee305..122130d 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -3,7 +3,7 @@
* (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
* (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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,13 +26,17 @@
#include "RangeException.h"
#include "CString.h"
+#include "ClientRect.h"
+#include "ClientRectList.h"
#include "DocumentFragment.h"
+#include "FrameView.h"
#include "HTMLElement.h"
#include "NodeWithIndex.h"
#include "ProcessingInstruction.h"
#include "Text.h"
#include "TextIterator.h"
#include "VisiblePosition.h"
+#include "htmlediting.h"
#include "markup.h"
#include "visible_units.h"
#include <stdio.h>
@@ -586,7 +590,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
RefPtr<DocumentFragment> fragment;
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
- fragment = new DocumentFragment(m_ownerDocument.get());
+ fragment = DocumentFragment::create(m_ownerDocument.get());
ec = 0;
if (collapsed(ec))
@@ -1798,4 +1802,111 @@ void Range::textNodeSplit(Text* oldNode)
boundaryTextNodesSplit(m_end, oldNode);
}
+void Range::expand(const String& unit, ExceptionCode& ec)
+{
+ VisiblePosition start(startPosition());
+ VisiblePosition end(endPosition());
+ if (unit == "word") {
+ start = startOfWord(start);
+ end = endOfWord(end);
+ } else if (unit == "sentence") {
+ start = startOfSentence(start);
+ end = endOfSentence(end);
+ } else if (unit == "block") {
+ start = startOfParagraph(start);
+ end = endOfParagraph(end);
+ } else if (unit == "document") {
+ start = startOfDocument(start);
+ end = endOfDocument(end);
+ } else
+ return;
+ setStart(start.deepEquivalent().containerNode(), start.deepEquivalent().computeOffsetInContainerNode(), ec);
+ setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), ec);
+}
+
+PassRefPtr<ClientRectList> Range::getClientRects() const
+{
+ if (!m_start.container())
+ return 0;
+
+ m_ownerDocument->updateLayoutIgnorePendingStylesheets();
+
+ Vector<FloatQuad> quads;
+ getBorderAndTextQuads(quads);
+
+ return ClientRectList::create(quads);
+}
+
+PassRefPtr<ClientRect> Range::getBoundingClientRect() const
+{
+ if (!m_start.container())
+ return 0;
+
+ m_ownerDocument->updateLayoutIgnorePendingStylesheets();
+
+ Vector<FloatQuad> quads;
+ getBorderAndTextQuads(quads);
+
+ if (quads.isEmpty())
+ return ClientRect::create();
+
+ IntRect result;
+ for (size_t i = 0; i < quads.size(); ++i)
+ result.unite(quads[i].enclosingBoundingBox());
+
+ return ClientRect::create(result);
}
+
+static void adjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>& quads, Document* document, RenderObject* renderer)
+{
+ FrameView* view = document->view();
+ if (!view)
+ return;
+
+ IntRect visibleContentRect = view->visibleContentRect();
+ for (size_t i = 0; i < quads.size(); ++i) {
+ quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
+ adjustFloatQuadForAbsoluteZoom(quads[i], renderer);
+ }
+}
+
+void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
+{
+ Node* startContainer = m_start.container();
+ Node* endContainer = m_end.container();
+ Node* stopNode = pastLastNode();
+
+ HashSet<Node*> nodeSet;
+ for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
+ if (node->isElementNode())
+ nodeSet.add(node);
+ }
+
+ for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
+ if (node->isElementNode()) {
+ if (!nodeSet.contains(node->parentNode())) {
+ if (RenderBoxModelObject* renderBoxModelObject = static_cast<Element*>(node)->renderBoxModelObject()) {
+ Vector<FloatQuad> elementQuads;
+ renderBoxModelObject->absoluteQuads(elementQuads);
+ adjustFloatQuadsForScrollAndAbsoluteZoom(elementQuads, m_ownerDocument.get(), renderBoxModelObject);
+
+ quads.append(elementQuads);
+ }
+ }
+ } else if (node->isTextNode()) {
+ if (RenderObject* renderer = static_cast<Text*>(node)->renderer()) {
+ RenderText* renderText = toRenderText(renderer);
+ int startOffset = (node == startContainer) ? m_start.offset() : 0;
+ int endOffset = (node == endContainer) ? m_end.offset() : INT_MAX;
+
+ Vector<FloatQuad> textQuads;
+ renderText->absoluteQuadsForRange(textQuads, startOffset, endOffset);
+ adjustFloatQuadsForScrollAndAbsoluteZoom(textQuads, m_ownerDocument.get(), renderText);
+
+ quads.append(textQuads);
+ }
+ }
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/Range.h b/WebCore/dom/Range.h
index 1487a7c..e2e282b 100644
--- a/WebCore/dom/Range.h
+++ b/WebCore/dom/Range.h
@@ -3,7 +3,7 @@
* (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
* (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -25,12 +25,15 @@
#ifndef Range_h
#define Range_h
+#include "FloatQuad.h"
#include "RangeBoundaryPoint.h"
+#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
namespace WebCore {
+class ClientRect;
+class ClientRectList;
class DocumentFragment;
class NodeWithIndex;
class Text;
@@ -112,6 +115,14 @@ public:
void textNodesMerged(NodeWithIndex& oldNode, unsigned offset);
void textNodeSplit(Text* oldNode);
+ // Expand range to a unit (word or sentence or block or document) boundary.
+ // Please refer to https://bugs.webkit.org/show_bug.cgi?id=27632 comment #5
+ // for details.
+ void expand(const String&, ExceptionCode&);
+
+ PassRefPtr<ClientRectList> getClientRects() const;
+ PassRefPtr<ClientRect> getBoundingClientRect() const;
+
#ifndef NDEBUG
void formatForDebugger(char* buffer, unsigned length) const;
#endif
@@ -130,6 +141,8 @@ private:
enum ActionType { DELETE_CONTENTS, EXTRACT_CONTENTS, CLONE_CONTENTS };
PassRefPtr<DocumentFragment> processContents(ActionType, ExceptionCode&);
+ void getBorderAndTextQuads(Vector<FloatQuad>&) const;
+
RefPtr<Document> m_ownerDocument;
RangeBoundaryPoint m_start;
RangeBoundaryPoint m_end;
diff --git a/WebCore/dom/Range.idl b/WebCore/dom/Range.idl
index 0750c32..9024e09 100644
--- a/WebCore/dom/Range.idl
+++ b/WebCore/dom/Range.idl
@@ -85,6 +85,13 @@ module ranges {
void detach()
raises(DOMException);
+#if defined(LANGUAGE_JAVASCRIPT) || LANGUAGE_JAVASCRIPT
+ // CSSOM View Module API extensions
+
+ ClientRectList getClientRects();
+ ClientRect getBoundingClientRect();
+#endif
+
// extensions
DocumentFragment createContextualFragment(in DOMString html)
@@ -112,6 +119,9 @@ module ranges {
in long offset)
raises(RangeException, DOMException);
+ void expand(in DOMString unit)
+ raises(RangeException, DOMException);
+
#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
readonly attribute DOMString text;
#endif
diff --git a/WebCore/dom/RegisteredEventListener.cpp b/WebCore/dom/RegisteredEventListener.cpp
index f257e56..e8bc594 100644
--- a/WebCore/dom/RegisteredEventListener.cpp
+++ b/WebCore/dom/RegisteredEventListener.cpp
@@ -27,12 +27,4 @@
namespace WebCore {
-RegisteredEventListener::RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
- : m_eventType(eventType)
- , m_listener(listener)
- , m_useCapture(useCapture)
- , m_removed(false)
-{
-}
-
} // namespace WebCore
diff --git a/WebCore/dom/RegisteredEventListener.h b/WebCore/dom/RegisteredEventListener.h
index 034f6c3..c34a341 100644
--- a/WebCore/dom/RegisteredEventListener.h
+++ b/WebCore/dom/RegisteredEventListener.h
@@ -29,47 +29,22 @@
namespace WebCore {
- class RegisteredEventListener : public RefCounted<RegisteredEventListener> {
+ class RegisteredEventListener {
public:
- static PassRefPtr<RegisteredEventListener> create(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+ RegisteredEventListener(PassRefPtr<EventListener> listener, bool useCapture)
+ : listener(listener)
+ , useCapture(useCapture)
{
- return adoptRef(new RegisteredEventListener(eventType, listener, useCapture));
}
- const AtomicString& eventType() const { return m_eventType; }
- EventListener* listener() const { return m_listener.get(); }
- bool useCapture() const { return m_useCapture; }
-
- bool removed() const { return m_removed; }
- void setRemoved(bool removed) { m_removed = removed; }
-
- private:
- RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-
- AtomicString m_eventType;
- RefPtr<EventListener> m_listener;
- bool m_useCapture;
- bool m_removed;
+ RefPtr<EventListener> listener;
+ bool useCapture;
};
-
- typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector;
-
-#if USE(JSC)
- inline void markEventListeners(JSC::MarkStack& markStack, const RegisteredEventListenerVector& listeners)
- {
- for (size_t i = 0; i < listeners.size(); ++i)
- listeners[i]->listener()->markJSFunction(markStack);
- }
-
- inline void invalidateEventListeners(const RegisteredEventListenerVector& listeners)
+
+ inline bool operator==(const RegisteredEventListener& a, const RegisteredEventListener& b)
{
- // For efficiency's sake, we just set the "removed" bit, instead of
- // actually removing the event listener. The node that owns these
- // listeners is about to be deleted, anyway.
- for (size_t i = 0; i < listeners.size(); ++i)
- listeners[i]->setRemoved(true);
+ return *a.listener == *b.listener && a.useCapture == b.useCapture;
}
-#endif
} // namespace WebCore
diff --git a/WebCore/dom/ScriptElement.cpp b/WebCore/dom/ScriptElement.cpp
index fe38b46..827aff3 100644
--- a/WebCore/dom/ScriptElement.cpp
+++ b/WebCore/dom/ScriptElement.cpp
@@ -151,6 +151,9 @@ void ScriptElementData::requestScript(const String& sourceUrl)
if (!document->frame())
return;
+ if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
+ return;
+
ASSERT(!m_cachedScript);
m_cachedScript = document->docLoader()->requestScript(sourceUrl, scriptCharset());
m_requested = true;
diff --git a/WebCore/dom/ScriptExecutionContext.h b/WebCore/dom/ScriptExecutionContext.h
index 3f8febc..bb78b6f 100644
--- a/WebCore/dom/ScriptExecutionContext.h
+++ b/WebCore/dom/ScriptExecutionContext.h
@@ -44,7 +44,9 @@ namespace WebCore {
class String;
enum MessageDestination {
+#if ENABLE(INSPECTOR)
InspectorControllerDestination,
+#endif
ConsoleDestination,
};
diff --git a/WebCore/dom/SelectElement.cpp b/WebCore/dom/SelectElement.cpp
index 1eb001e..49713ba 100644
--- a/WebCore/dom/SelectElement.cpp
+++ b/WebCore/dom/SelectElement.cpp
@@ -48,11 +48,11 @@
#endif
// Configure platform-specific behavior when focused pop-up receives arrow/space/return keystroke.
-// (PLATFORM(MAC) is always false in Chromium, hence the extra test.)
+// (PLATFORM(MAC) and PLATFORM(GTK) are always false in Chromium, hence the extra tests.)
#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
#define ARROW_KEYS_POP_MENU 1
#define SPACE_OR_RETURN_POP_MENU 0
-#elif PLATFORM(GTK)
+#elif PLATFORM(GTK) || (PLATFORM(CHROMIUM) && PLATFORM(LINUX))
#define ARROW_KEYS_POP_MENU 0
#define SPACE_OR_RETURN_POP_MENU 1
#else
@@ -644,14 +644,16 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element
if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
element->focus();
- if (RenderMenuList* menuList = toRenderMenuList(element->renderer())) {
- if (menuList->popupIsVisible())
- menuList->hidePopup();
- else {
- // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
- // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
- saveLastSelection(data, element);
- menuList->showPopup();
+ if (element->renderer() && element->renderer()->isMenuList()) {
+ if (RenderMenuList* menuList = toRenderMenuList(element->renderer())) {
+ if (menuList->popupIsVisible())
+ menuList->hidePopup();
+ else {
+ // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
+ // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
+ saveLastSelection(data, element);
+ menuList->showPopup();
+ }
}
}
event->setDefaultHandled();
@@ -676,7 +678,7 @@ void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element*
data.setActiveSelectionState(true);
bool multiSelectKeyPressed = false;
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
multiSelectKeyPressed = mouseEvent->metaKey();
#else
multiSelectKeyPressed = mouseEvent->ctrlKey();
diff --git a/WebCore/dom/StyledElement.cpp b/WebCore/dom/StyledElement.cpp
index 456cc52..5212380 100644
--- a/WebCore/dom/StyledElement.cpp
+++ b/WebCore/dom/StyledElement.cpp
@@ -101,11 +101,6 @@ void StyledElement::removeMappedAttributeDecl(MappedAttributeEntry entryType, co
mappedAttributeDecls->remove(MappedAttributeKey(entryType, attrName.localName().impl(), attrValue.impl()));
}
-void StyledElement::invalidateStyleAttribute()
-{
- m_isStyleAttributeValid = false;
-}
-
void StyledElement::updateStyleAttribute() const
{
ASSERT(!m_isStyleAttributeValid);
@@ -116,8 +111,8 @@ void StyledElement::updateStyleAttribute() const
m_synchronizingStyleAttribute = false;
}
-StyledElement::StyledElement(const QualifiedName& name, Document *doc)
- : Element(name, doc)
+StyledElement::StyledElement(const QualifiedName& name, Document* document, ConstructionType type)
+ : Element(name, document, type)
{
}
@@ -280,14 +275,6 @@ CSSStyleDeclaration* StyledElement::style()
return getInlineStyleDecl();
}
-static inline int toHex(UChar c)
-{
- return ((c >= '0' && c <= '9') ? (c - '0')
- : ((c >= 'a' && c <= 'f') ? (c - 'a' + 10)
- : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10)
- : -1)));
-}
-
void StyledElement::addCSSProperty(MappedAttribute* attr, int id, const String &value)
{
if (!attr->decl()) createMappedDecl(attr);
@@ -300,12 +287,6 @@ void StyledElement::addCSSProperty(MappedAttribute* attr, int id, int value)
attr->decl()->setProperty(id, value, false);
}
-void StyledElement::addCSSStringProperty(MappedAttribute* attr, int id, const String &value, CSSPrimitiveValue::UnitTypes type)
-{
- if (!attr->decl()) createMappedDecl(attr);
- attr->decl()->setStringProperty(id, value, type, false);
-}
-
void StyledElement::addCSSImageProperty(MappedAttribute* attr, int id, const String& url)
{
if (!attr->decl()) createMappedDecl(attr);
@@ -393,10 +374,9 @@ void StyledElement::addCSSColor(MappedAttribute* attr, int id, const String& c)
// search forward for digits in the string
int numDigits = 0;
while (pos < (int)color.length() && numDigits < basicLength) {
- int hex = toHex(color[pos]);
- colors[component] = (colors[component] << 4);
- if (hex > 0) {
- colors[component] += hex;
+ colors[component] <<= 4;
+ if (isASCIIHexDigit(color[pos])) {
+ colors[component] += toASCIIHexValue(color[pos]);
maxDigit = min(maxDigit, numDigits);
}
numDigits++;
@@ -410,10 +390,9 @@ void StyledElement::addCSSColor(MappedAttribute* attr, int id, const String& c)
// normalize to 00-ff. The highest filled digit counts, minimum is 2 digits
maxDigit -= 2;
- colors[0] >>= 4*maxDigit;
- colors[1] >>= 4*maxDigit;
- colors[2] >>= 4*maxDigit;
- // ASSERT(colors[0] < 0x100 && colors[1] < 0x100 && colors[2] < 0x100);
+ colors[0] >>= 4 * maxDigit;
+ colors[1] >>= 4 * maxDigit;
+ colors[2] >>= 4 * maxDigit;
color = String::format("#%02x%02x%02x", colors[0], colors[1], colors[2]);
if (attr->decl()->setProperty(id, color, false))
diff --git a/WebCore/dom/StyledElement.h b/WebCore/dom/StyledElement.h
index 158992e..85fa7a7 100644
--- a/WebCore/dom/StyledElement.h
+++ b/WebCore/dom/StyledElement.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -38,54 +38,49 @@ class MappedAttribute;
class StyledElement : public Element {
public:
- StyledElement(const QualifiedName&, Document*);
virtual ~StyledElement();
- virtual bool isStyledElement() const { return true; }
-
NamedMappedAttrMap* mappedAttributes() { return static_cast<NamedMappedAttrMap*>(namedAttrMap.get()); }
const NamedMappedAttrMap* mappedAttributes() const { return static_cast<NamedMappedAttrMap*>(namedAttrMap.get()); }
+
bool hasMappedAttributes() const { return namedAttrMap && mappedAttributes()->hasMappedAttributes(); }
bool isMappedAttribute(const QualifiedName& name) const { MappedAttributeEntry res = eNone; mapToEntry(name, res); return res != eNone; }
- void addCSSLength(MappedAttribute* attr, int id, const String &value);
- void addCSSProperty(MappedAttribute* attr, int id, const String &value);
- void addCSSProperty(MappedAttribute* attr, int id, int value);
- void addCSSStringProperty(MappedAttribute* attr, int id, const String &value, CSSPrimitiveValue::UnitTypes = CSSPrimitiveValue::CSS_STRING);
+ void addCSSLength(MappedAttribute*, int id, const String& value);
+ void addCSSProperty(MappedAttribute*, int id, const String& value);
+ void addCSSProperty(MappedAttribute*, int id, int value);
void addCSSImageProperty(MappedAttribute*, int propertyID, const String& url);
- void addCSSColor(MappedAttribute* attr, int id, const String &c);
- void createMappedDecl(MappedAttribute* attr);
-
- static CSSMappedAttributeDeclaration* getMappedAttributeDecl(MappedAttributeEntry type, const QualifiedName& name, const AtomicString& value);
+ void addCSSColor(MappedAttribute*, int id, const String& color);
+
+ static CSSMappedAttributeDeclaration* getMappedAttributeDecl(MappedAttributeEntry, const QualifiedName& name, const AtomicString& value);
static void setMappedAttributeDecl(MappedAttributeEntry, const QualifiedName& name, const AtomicString& value, CSSMappedAttributeDeclaration*);
- static void removeMappedAttributeDecl(MappedAttributeEntry type, const QualifiedName& name, const AtomicString& value);
+ static void removeMappedAttributeDecl(MappedAttributeEntry, const QualifiedName& name, const AtomicString& value);
static CSSMappedAttributeDeclaration* getMappedAttributeDecl(MappedAttributeEntry, Attribute*);
static void setMappedAttributeDecl(MappedAttributeEntry, Attribute*, CSSMappedAttributeDeclaration*);
-
+
CSSMutableStyleDeclaration* inlineStyleDecl() const { return m_inlineStyleDecl.get(); }
virtual bool canHaveAdditionalAttributeStyleDecls() const { return false; }
virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&) {};
CSSMutableStyleDeclaration* getInlineStyleDecl();
CSSStyleDeclaration* style();
- void createInlineStyleDecl();
- void destroyInlineStyleDecl();
void invalidateStyleAttribute();
- virtual void updateStyleAttribute() const;
-
+
const ClassNames& classNames() const { ASSERT(hasClass()); ASSERT(mappedAttributes()); return mappedAttributes()->classNames(); }
- virtual void attributeChanged(Attribute*, bool preserveDecls = false);
- virtual void parseMappedAttribute(MappedAttribute*);
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
- virtual void createAttributeMap() const;
+
virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
+protected:
+ StyledElement(const QualifiedName&, Document*, ConstructionType);
+
+ virtual void attributeChanged(Attribute*, bool preserveDecls = false);
+ virtual void parseMappedAttribute(MappedAttribute*);
virtual void copyNonAttributeProperties(const Element*);
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-protected:
// classAttributeChanged() exists to share code between
// parseMappedAttribute (called via setAttribute()) and
// svgAttributeChanged (called when element.className.baseValue is set)
@@ -93,9 +88,25 @@ protected:
virtual void didMoveToNewOwnerDocument();
+private:
+ virtual bool isStyledElement() const { return true; }
+
+ void createMappedDecl(MappedAttribute*);
+
+ void createInlineStyleDecl();
+ void destroyInlineStyleDecl();
+ virtual void updateStyleAttribute() const;
+
+ virtual void createAttributeMap() const;
+
RefPtr<CSSMutableStyleDeclaration> m_inlineStyleDecl;
};
+inline void StyledElement::invalidateStyleAttribute()
+{
+ m_isStyleAttributeValid = false;
+}
+
} //namespace
#endif
diff --git a/WebCore/dom/Text.cpp b/WebCore/dom/Text.cpp
index bbd926b..1ce074a 100644
--- a/WebCore/dom/Text.cpp
+++ b/WebCore/dom/Text.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -37,22 +37,18 @@
#include "WMLVariables.h"
#endif
-namespace WebCore {
-
-// DOM Section 1.1.1
+using namespace std;
-Text::Text(Document* document, const String& text)
- : CharacterData(document, text, true)
-{
-}
+namespace WebCore {
-Text::Text(Document* document)
- : CharacterData(document, true)
+Text::Text(Document* document, const String& data)
+ : CharacterData(document, data, CreateText)
{
}
-Text::~Text()
+PassRefPtr<Text> Text::create(Document* document, const String& data)
{
+ return adoptRef(new Text(document, data));
}
PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
@@ -61,14 +57,14 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
// INDEX_SIZE_ERR: Raised if the specified offset is negative or greater than
// the number of 16-bit units in data.
- if (offset > m_data->length()) {
+ if (offset > length()) {
ec = INDEX_SIZE_ERR;
return 0;
}
- RefPtr<StringImpl> oldStr = m_data;
- RefPtr<Text> newText = createNew(oldStr->substring(offset));
- m_data = oldStr->substring(0, offset);
+ RefPtr<StringImpl> oldStr = dataImpl();
+ RefPtr<Text> newText = virtualCreate(oldStr->substring(offset));
+ setDataImpl(oldStr->substring(0, offset));
dispatchModifiedEvent(oldStr.get());
@@ -81,7 +77,7 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
document()->textNodeSplit(this);
if (renderer())
- toRenderText(renderer())->setText(m_data);
+ toRenderText(renderer())->setText(dataImpl());
return newText.release();
}
@@ -199,7 +195,7 @@ Node::NodeType Text::nodeType() const
PassRefPtr<Node> Text::cloneNode(bool /*deep*/)
{
- return document()->createTextNode(m_data);
+ return create(document(), data());
}
bool Text::rendererIsNeeded(RenderStyle *style)
@@ -244,7 +240,7 @@ bool Text::rendererIsNeeded(RenderStyle *style)
return true;
}
-RenderObject *Text::createRenderer(RenderArena* arena, RenderStyle*)
+RenderObject* Text::createRenderer(RenderArena* arena, RenderStyle*)
{
#if ENABLE(SVG)
if (parentNode()->isSVGElement()
@@ -252,17 +248,17 @@ RenderObject *Text::createRenderer(RenderArena* arena, RenderStyle*)
&& !parentNode()->hasTagName(SVGNames::foreignObjectTag)
#endif
)
- return new (arena) RenderSVGInlineText(this, m_data);
+ return new (arena) RenderSVGInlineText(this, dataImpl());
#endif
- return new (arena) RenderText(this, m_data);
+ return new (arena) RenderText(this, dataImpl());
}
void Text::attach()
{
#if ENABLE(WML)
if (document()->isWMLDocument() && !containsOnlyWhitespace()) {
- String text = m_data;
+ String text = data();
ASSERT(!text.isEmpty());
text = substituteVariableReferences(text, document());
@@ -286,7 +282,7 @@ void Text::recalcStyle(StyleChange change)
if (needsStyleRecalc()) {
if (renderer()) {
if (renderer()->isText())
- toRenderText(renderer())->setText(m_data);
+ toRenderText(renderer())->setText(dataImpl());
} else {
if (attached())
detach();
@@ -296,40 +292,47 @@ void Text::recalcStyle(StyleChange change)
setNeedsStyleRecalc(NoStyleChange);
}
-// DOM Section 1.1.1
bool Text::childTypeAllowed(NodeType)
{
return false;
}
-PassRefPtr<Text> Text::createNew(PassRefPtr<StringImpl> string)
+PassRefPtr<Text> Text::virtualCreate(const String& data)
{
- return new Text(document(), string);
+ return create(document(), data);
}
-PassRefPtr<Text> Text::createWithLengthLimit(Document* doc, const String& text, unsigned& charsLeft, unsigned maxChars)
+PassRefPtr<Text> Text::createWithLengthLimit(Document* document, const String& data, unsigned& charsLeft, unsigned maxChars)
{
- if (charsLeft == text.length() && charsLeft <= maxChars) {
+ unsigned dataLength = data.length();
+
+ if (charsLeft == dataLength && charsLeft <= maxChars) {
charsLeft = 0;
- return new Text(doc, text);
+ return create(document, data);
}
+
+ unsigned start = dataLength - charsLeft;
+ unsigned end = start + min(charsLeft, maxChars);
- unsigned start = text.length() - charsLeft;
- unsigned end = start + std::min(charsLeft, maxChars);
+ // Check we are not on an unbreakable boundary.
+ // Some text break iterator implementations work best if the passed buffer is as small as possible,
+ // see <https://bugs.webkit.org/show_bug.cgi?id=29092>.
+ // We need at least two characters look-ahead to account for UTF-16 surrogates.
+ if (end < dataLength) {
+ TextBreakIterator* it = characterBreakIterator(data.characters() + start, (end + 2 > dataLength) ? dataLength - start : end - start + 2);
+ if (!isTextBreak(it, end - start))
+ end = textBreakPreceding(it, end - start) + start;
+ }
- // check we are not on an unbreakable boundary
- TextBreakIterator* it = characterBreakIterator(text.characters(), text.length());
- if (end < text.length() && !isTextBreak(it, end))
- end = textBreakPreceding(it, end);
-
- // maxChars of unbreakable characters could lead to infinite loop
+ // If we have maxChars of unbreakable characters the above could lead to
+ // an infinite loop.
+ // FIXME: It would be better to just have the old value of end before calling
+ // textBreakPreceding rather than this, because this exceeds the length limit.
if (end <= start)
- end = text.length();
+ end = dataLength;
- String nodeText = text.substring(start, end - start);
- charsLeft = text.length() - end;
-
- return new Text(doc, nodeText);
+ charsLeft = dataLength - end;
+ return create(document, data.substring(start, end - start));
}
#ifndef NDEBUG
@@ -343,7 +346,7 @@ void Text::formatForDebugger(char *buffer, unsigned length) const
result += s;
}
- s = nodeValue();
+ s = data();
if (s.length() > 0) {
if (result.length() > 0)
result += "; ";
diff --git a/WebCore/dom/Text.h b/WebCore/dom/Text.h
index e5a6e69..4722736 100644
--- a/WebCore/dom/Text.h
+++ b/WebCore/dom/Text.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -27,44 +27,39 @@
namespace WebCore {
-const unsigned cTextNodeLengthLimit = 1 << 16;
-
class Text : public CharacterData {
public:
- Text(Document *impl, const String &_text);
- Text(Document *impl);
- virtual ~Text();
+ static const unsigned defaultLengthLimit = 1 << 16;
- // DOM methods & attributes for CharacterData
+ static PassRefPtr<Text> create(Document*, const String&);
+ static PassRefPtr<Text> createWithLengthLimit(Document*, const String&, unsigned& charsLeft, unsigned lengthLimit = defaultLengthLimit);
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 void attach();
+
+protected:
+ Text(Document*, const String&);
+private:
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
-
- // Other methods (not part of DOM)
-
- virtual void attach();
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual void recalcStyle(StyleChange = NoChange);
virtual bool childTypeAllowed(NodeType);
- static PassRefPtr<Text> createWithLengthLimit(Document*, const String&, unsigned& charsLeft, unsigned maxChars = cTextNodeLengthLimit);
+ virtual PassRefPtr<Text> virtualCreate(const String&);
#ifndef NDEBUG
virtual void formatForDebugger(char* buffer, unsigned length) const;
#endif
-
-protected:
- virtual PassRefPtr<Text> createNew(PassRefPtr<StringImpl>);
};
} // namespace WebCore
diff --git a/WebCore/dom/TransformSource.h b/WebCore/dom/TransformSource.h
new file mode 100644
index 0000000..f97afcf
--- /dev/null
+++ b/WebCore/dom/TransformSource.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TransformSource_h
+#define TransformSource_h
+
+#if ENABLE(XSLT)
+
+#include "PlatformString.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+#if USE(QXMLQUERY)
+ typedef String PlatformTransformSource;
+#else
+ typedef void* PlatformTransformSource;
+#endif
+
+ class TransformSource : public Noncopyable {
+ public:
+ TransformSource(const PlatformTransformSource& source);
+ ~TransformSource();
+
+ PlatformTransformSource platformSource() const { return m_source; }
+
+ private:
+ PlatformTransformSource m_source;
+ };
+
+} // namespace WebCore
+
+#endif
+
+#endif // TransformSource_h
diff --git a/WebCore/dom/TransformSourceLibxslt.cpp b/WebCore/dom/TransformSourceLibxslt.cpp
new file mode 100644
index 0000000..33a85e8
--- /dev/null
+++ b/WebCore/dom/TransformSourceLibxslt.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TransformSource.h"
+
+#include <libxml/tree.h>
+
+namespace WebCore {
+
+TransformSource::TransformSource(const PlatformTransformSource& source)
+ : m_source(source)
+{
+}
+
+TransformSource::~TransformSource()
+{
+ xmlFreeDoc((xmlDocPtr)m_source);
+}
+
+}
diff --git a/WebCore/dom/TransformSourceQt.cpp b/WebCore/dom/TransformSourceQt.cpp
new file mode 100644
index 0000000..074f2cb
--- /dev/null
+++ b/WebCore/dom/TransformSourceQt.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "TransformSource.h"
+
+namespace WebCore {
+
+TransformSource::TransformSource(const PlatformTransformSource& source)
+ : m_source(source)
+{
+}
+
+TransformSource::~TransformSource()
+{
+}
+
+}
diff --git a/WebCore/dom/XMLTokenizer.cpp b/WebCore/dom/XMLTokenizer.cpp
index 1747c3c..4d06343 100644
--- a/WebCore/dom/XMLTokenizer.cpp
+++ b/WebCore/dom/XMLTokenizer.cpp
@@ -136,7 +136,7 @@ bool XMLTokenizer::enterText()
#if !USE(QXMLSTREAM)
ASSERT(m_bufferedText.size() == 0);
#endif
- RefPtr<Node> newNode = new Text(m_doc, "");
+ RefPtr<Node> newNode = Text::create(m_doc, "");
if (!m_currentNode->addChild(newNode.get()))
return false;
setCurrentNode(newNode.get());
diff --git a/WebCore/dom/XMLTokenizerLibxml2.cpp b/WebCore/dom/XMLTokenizerLibxml2.cpp
index 4387a66..e4a98d5 100644
--- a/WebCore/dom/XMLTokenizerLibxml2.cpp
+++ b/WebCore/dom/XMLTokenizerLibxml2.cpp
@@ -50,6 +50,7 @@
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "TextResourceDecoder.h"
+#include "TransformSource.h"
#include "XMLTokenizerScope.h"
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
@@ -850,7 +851,8 @@ void XMLTokenizer::endElementNs()
if (!scriptHref.isEmpty()) {
// we have a src attribute
String scriptCharset = scriptElement->scriptCharset();
- if ((m_pendingScript = m_doc->docLoader()->requestScript(scriptHref, scriptCharset))) {
+ if (element->dispatchBeforeLoadEvent(scriptHref) &&
+ (m_pendingScript = m_doc->docLoader()->requestScript(scriptHref, scriptCharset))) {
m_scriptElement = element;
m_pendingScript->addClient(this);
@@ -951,7 +953,7 @@ void XMLTokenizer::cdataBlock(const xmlChar* s, int len)
exitText();
- RefPtr<Node> newNode = new CDATASection(m_doc, toString(s, len));
+ RefPtr<Node> newNode = CDATASection::create(m_doc, toString(s, len));
if (!m_currentNode->addChild(newNode.get()))
return;
if (m_view && !newNode->attached())
@@ -970,7 +972,7 @@ void XMLTokenizer::comment(const xmlChar* s)
exitText();
- RefPtr<Node> newNode = new Comment(m_doc, toString(s));
+ RefPtr<Node> newNode = Comment::create(m_doc, toString(s));
m_currentNode->addChild(newNode.get());
if (m_view && !newNode->attached())
newNode->attach();
@@ -1280,7 +1282,8 @@ void XMLTokenizer::doEnd()
{
#if ENABLE(XSLT)
if (m_sawXSLTransform) {
- m_doc->setTransformSource(xmlDocPtrForString(m_doc->docLoader(), m_originalSourceForTransform, m_doc->url().string()));
+ void* doc = xmlDocPtrForString(m_doc->docLoader(), m_originalSourceForTransform, m_doc->url().string());
+ m_doc->setTransformSource(new TransformSource(doc));
m_doc->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
m_doc->updateStyleSelector();
diff --git a/WebCore/dom/XMLTokenizerQt.cpp b/WebCore/dom/XMLTokenizerQt.cpp
index 16c637f..04405d6 100644
--- a/WebCore/dom/XMLTokenizerQt.cpp
+++ b/WebCore/dom/XMLTokenizerQt.cpp
@@ -50,6 +50,7 @@
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "TextResourceDecoder.h"
+#include "TransformSource.h"
#include <QDebug>
#include <wtf/Platform.h>
#include <wtf/StringExtras.h>
@@ -237,7 +238,7 @@ void XMLTokenizer::doWrite(const String& parseString)
return;
}
-void XMLTokenizer::initializeParserContext(const char* chunk)
+void XMLTokenizer::initializeParserContext(const char*)
{
m_parserStopped = false;
m_sawError = false;
@@ -248,45 +249,19 @@ void XMLTokenizer::initializeParserContext(const char* chunk)
void XMLTokenizer::doEnd()
{
#if ENABLE(XSLT)
- #warning Look at XMLTokenizerLibXml.cpp
-#endif
-
- if (m_stream.error() == QXmlStreamReader::PrematureEndOfDocumentError || (m_wroteText && !m_sawFirstElement)) {
- handleError(fatal, qPrintable(m_stream.errorString()), lineNumber(),
- columnNumber());
+ if (m_sawXSLTransform) {
+ m_doc->setTransformSource(new TransformSource(m_originalSourceForTransform));
+ m_doc->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
+ m_doc->updateStyleSelector();
+ m_doc->setParsing(true);
+ m_parserStopped = true;
}
-}
-
-#if ENABLE(XSLT)
-void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const String& url)
-{
- if (source.isEmpty())
- return 0;
-
- // Parse in a single chunk into an xmlDocPtr
- // FIXME: Hook up error handlers so that a failure to parse the main document results in
- // good error messages.
- const UChar BOM = 0xFEFF;
- const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
-
- xmlGenericErrorFunc oldErrorFunc = xmlGenericError;
- void* oldErrorContext = xmlGenericErrorContext;
-
- setLoaderForLibXMLCallbacks(docLoader);
- xmlSetGenericErrorFunc(0, errorFunc);
-
- xmlDocPtr sourceDoc = xmlReadMemory(reinterpret_cast<const char*>(source.characters()),
- source.length() * sizeof(UChar),
- url.latin1().data(),
- BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE",
- XSLT_PARSE_OPTIONS);
-
- setLoaderForLibXMLCallbacks(0);
- xmlSetGenericErrorFunc(oldErrorContext, oldErrorFunc);
+#endif
- return sourceDoc;
+ if (m_stream.error() == QXmlStreamReader::PrematureEndOfDocumentError
+ || (m_wroteText && !m_sawFirstElement && !m_sawXSLTransform))
+ handleError(fatal, qPrintable(m_stream.errorString()), lineNumber(), columnNumber());
}
-#endif
int XMLTokenizer::lineNumber() const
{
@@ -683,7 +658,7 @@ void XMLTokenizer::parseProcessingInstruction()
#if ENABLE(XSLT)
m_sawXSLTransform = !m_sawFirstElement && pi->isXSL();
- if (m_sawXSLTransform && !m_doc->transformSourceDocument()))
+ if (m_sawXSLTransform && !m_doc->transformSourceDocument())
stopParsing();
#endif
}
@@ -692,7 +667,7 @@ void XMLTokenizer::parseCdata()
{
exitText();
- RefPtr<Node> newNode = new CDATASection(m_doc, m_stream.text());
+ RefPtr<Node> newNode = CDATASection::create(m_doc, m_stream.text());
if (!m_currentNode->addChild(newNode.get()))
return;
if (m_view && !newNode->attached())
@@ -703,7 +678,7 @@ void XMLTokenizer::parseComment()
{
exitText();
- RefPtr<Node> newNode = new Comment(m_doc, m_stream.text());
+ RefPtr<Node> newNode = Comment::create(m_doc, m_stream.text());
m_currentNode->addChild(newNode.get());
if (m_view && !newNode->attached())
newNode->attach();
diff --git a/WebCore/dom/make_names.pl b/WebCore/dom/make_names.pl
index e6d59a0..6b5ddb4 100755
--- a/WebCore/dom/make_names.pl
+++ b/WebCore/dom/make_names.pl
@@ -48,28 +48,30 @@ my %parameters = ();
my $extraDefines = 0;
my $preprocessor = "/usr/bin/gcc -E -P -x c++";
-GetOptions('tags=s' => \$tagsFile,
+GetOptions(
+ 'tags=s' => \$tagsFile,
'attrs=s' => \$attrsFile,
'factory' => \$printFactory,
'outputDir=s' => \$outputDir,
'extraDefines=s' => \$extraDefines,
'preprocessor=s' => \$preprocessor,
- 'wrapperFactory' => \$printWrapperFactory);
+ 'wrapperFactory' => \$printWrapperFactory
+);
die "You must specify at least one of --tags <file> or --attrs <file>" unless (length($tagsFile) || length($attrsFile));
readNames($tagsFile, "tags") if length($tagsFile);
readNames($attrsFile, "attrs") if length($attrsFile);
-die "You must specify a namespace (e.g. SVG) for <namespace>Names.h" unless $parameters{'namespace'};
-die "You must specify a namespaceURI (e.g. http://www.w3.org/2000/svg)" unless $parameters{'namespaceURI'};
+die "You must specify a namespace (e.g. SVG) for <namespace>Names.h" unless $parameters{namespace};
+die "You must specify a namespaceURI (e.g. http://www.w3.org/2000/svg)" unless $parameters{namespaceURI};
-$parameters{'namespacePrefix'} = $parameters{'namespace'} unless $parameters{'namespacePrefix'};
+$parameters{namespacePrefix} = $parameters{namespace} unless $parameters{namespacePrefix};
mkpath($outputDir);
-my $namesBasePath = "$outputDir/$parameters{'namespace'}Names";
-my $factoryBasePath = "$outputDir/$parameters{'namespace'}ElementFactory";
-my $wrapperFactoryBasePath = "$outputDir/JS$parameters{'namespace'}ElementWrapperFactory";
+my $namesBasePath = "$outputDir/$parameters{namespace}Names";
+my $factoryBasePath = "$outputDir/$parameters{namespace}ElementFactory";
+my $wrapperFactoryBasePath = "$outputDir/JS$parameters{namespace}ElementWrapperFactory";
printNamesHeaderFile("$namesBasePath.h");
printNamesCppFile("$namesBasePath.cpp");
@@ -86,39 +88,44 @@ if ($printWrapperFactory) {
### Hash initialization
-sub initializeTagPropertyHash
+sub defaultTagPropertyHash
{
- return ('constructorNeedsCreatedByParser' => 0,
- 'constructorNeedsFormElement' => 0,
- 'exportString' => 0,
- 'interfaceName' => defaultInterfaceName($_[0]),
- # By default, the JSInterfaceName is the same as the interfaceName.
- 'JSInterfaceName' => defaultInterfaceName($_[0]),
- 'mapToTagName' => '',
- 'wrapperOnlyIfMediaIsAvailable' => 0,
- 'conditional' => 0);
+ return (
+ 'constructorNeedsCreatedByParser' => 0,
+ 'constructorNeedsFormElement' => 0,
+ 'createWithNew' => 0,
+ 'exportString' => 0,
+ 'interfaceName' => defaultInterfaceName($_[0]),
+ # By default, the JSInterfaceName is the same as the interfaceName.
+ 'JSInterfaceName' => defaultInterfaceName($_[0]),
+ 'mapToTagName' => '',
+ 'wrapperOnlyIfMediaIsAvailable' => 0,
+ 'conditional' => 0
+ );
}
-sub initializeAttrPropertyHash
+sub defaultAttrPropertyHash
{
return ('exportString' => 0);
}
-sub initializeParametersHash
+sub defaultParametersHash
{
- return ('namespace' => '',
- 'namespacePrefix' => '',
- 'namespaceURI' => '',
- 'guardFactoryWith' => '',
- 'tagsNullNamespace' => 0,
- 'attrsNullNamespace' => 0,
- 'exportStrings' => 0);
+ return (
+ 'namespace' => '',
+ 'namespacePrefix' => '',
+ 'namespaceURI' => '',
+ 'guardFactoryWith' => '',
+ 'tagsNullNamespace' => 0,
+ 'attrsNullNamespace' => 0,
+ 'exportStrings' => 0
+ );
}
sub defaultInterfaceName
{
- die "No namespace found" if !$parameters{'namespace'};
- return $parameters{'namespace'} . upperCaseName($_[0]) . "Element"
+ die "No namespace found" if !$parameters{namespace};
+ return $parameters{namespace} . upperCaseName($_[0]) . "Element"
}
### Parsing handlers
@@ -129,16 +136,16 @@ sub tagsHandler
$tag =~ s/-/_/g;
- # Initialize default properties' values.
- $tags{$tag} = { initializeTagPropertyHash($tag) } if !defined($tags{$tag});
+ # Initialize default property values.
+ $tags{$tag} = { defaultTagPropertyHash($tag) } if !defined($tags{$tag});
if ($property) {
die "Unknown property $property for tag $tag\n" if !defined($tags{$tag}{$property});
- # The code rely on JSInterfaceName deriving from interfaceName to check for custom JSInterfaceName.
- # So just override JSInterfaceName if it was not already set.
- if ($property eq "interfaceName" && $tags{$tag}{'JSInterfaceName'} eq $tags{$tag}{'interfaceName'}) {
- $tags{$tag}{'JSInterfaceName'} = $value;
- }
+
+ # The code relies on JSInterfaceName deriving from interfaceName to check for custom JSInterfaceName.
+ # So override JSInterfaceName if it was not already set.
+ $tags{$tag}{JSInterfaceName} = $value if $property eq "interfaceName" && $tags{$tag}{JSInterfaceName} eq $tags{$tag}{interfaceName};
+
$tags{$tag}{$property} = $value;
}
}
@@ -150,7 +157,7 @@ sub attrsHandler
$attr =~ s/-/_/g;
# Initialize default properties' values.
- $attrs{$attr} = { initializeAttrPropertyHash($attr) } if !defined($attrs{$attr});
+ $attrs{$attr} = { defaultAttrPropertyHash($attr) } if !defined($attrs{$attr});
if ($property) {
die "Unknown property $property for attribute $attr\n" if !defined($attrs{$attr}{$property});
@@ -163,7 +170,7 @@ sub parametersHandler
my ($parameter, $value) = @_;
# Initialize default properties' values.
- %parameters = initializeParametersHash() if !(keys %parameters);
+ %parameters = defaultParametersHash() if !(keys %parameters);
die "Unknown parameter $parameter for tags/attrs\n" if !defined($parameters{$parameter});
$parameters{$parameter} = $value;
@@ -214,7 +221,7 @@ sub printMacros
for my $name (sort keys %$namesRef) {
print F "$macro $name","$suffix;\n";
- if ($parameters{'exportStrings'} or $names{$name}{"exportString"}) {
+ if ($parameters{exportStrings} or $names{$name}{exportString}) {
print F "extern char $name", "${suffix}String[];\n";
}
}
@@ -223,7 +230,7 @@ sub printMacros
sub usesDefaultWrapper
{
my $tagName = shift;
- return $tagName eq $parameters{'namespace'} . "Element";
+ return $tagName eq $parameters{namespace} . "Element";
}
# Build a direct mapping from the tags to the Element to create, excluding
@@ -232,16 +239,16 @@ sub buildConstructorMap
{
my %tagConstructorMap = ();
for my $tagName (keys %tags) {
- my $interfaceName = $tags{$tagName}{'interfaceName'};
+ my $interfaceName = $tags{$tagName}{interfaceName};
next if (usesDefaultWrapper($interfaceName));
- if ($tags{$tagName}{'mapToTagName'}) {
- die "Cannot handle multiple mapToTagName for $tagName\n" if $tags{$tags{$tagName}{'mapToTagName'}}{'mapToTagName'};
- $interfaceName = $tags{ $tags{$tagName}{'mapToTagName'} }{'interfaceName'};
+ if ($tags{$tagName}{mapToTagName}) {
+ die "Cannot handle multiple mapToTagName for $tagName\n" if $tags{$tags{$tagName}{mapToTagName}}{mapToTagName};
+ $interfaceName = $tags{ $tags{$tagName}{mapToTagName} }{interfaceName};
}
# Chop the string to keep the interesting part.
- $interfaceName =~ s/$parameters{'namespace'}(.*)Element/$1/;
+ $interfaceName =~ s/$parameters{namespace}(.*)Element/$1/;
$tagConstructorMap{$tagName} = lc($interfaceName);
}
@@ -254,17 +261,13 @@ sub printConstructorSignature
{
my ($F, $tagName, $constructorName, $constructorTagName) = @_;
- print F "static PassRefPtr<$parameters{'namespace'}Element> ${constructorName}Constructor(const QualifiedName& $constructorTagName, Document* doc";
- if ($parameters{'namespace'} eq "HTML") {
+ print F "static PassRefPtr<$parameters{namespace}Element> ${constructorName}Constructor(const QualifiedName& $constructorTagName, Document* document";
+ if ($parameters{namespace} eq "HTML") {
print F ", HTMLFormElement*";
- if ($tags{$tagName}{'constructorNeedsFormElement'}) {
- print F " formElement";
- }
+ print F " formElement" if $tags{$tagName}{constructorNeedsFormElement};
}
print F ", bool";
- if ($tags{$tagName}{'constructorNeedsCreatedByParser'}) {
- print F " createdByParser";
- }
+ print F " createdByParser" if $tags{$tagName}{constructorNeedsCreatedByParser};
print F ")\n{\n";
}
@@ -276,22 +279,26 @@ sub printConstructorInterior
my ($F, $tagName, $interfaceName, $constructorTagName) = @_;
# Handle media elements.
- if ($tags{$tagName}{'wrapperOnlyIfMediaIsAvailable'}) {
+ if ($tags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
print F <<END
if (!MediaPlayer::isAvailable())
- return new HTMLElement($constructorTagName, doc);
+ return HTMLElement::create($constructorTagName, document);
END
;
}
- # Now call the constructor with the right parameters.
- print F " return new ${interfaceName}($constructorTagName, doc";
- if ($tags{$tagName}{'constructorNeedsFormElement'}) {
- print F ", formElement";
- }
- if ($tags{$tagName}{'constructorNeedsCreatedByParser'}) {
- print F ", createdByParser";
+ my $newPrefix = "";
+ my $createSuffix = "::create";
+
+ if ($tags{$tagName}{createWithNew}) {
+ $newPrefix = "new ";
+ $createSuffix = "";
}
+
+ # Call the constructor with the right parameters.
+ print F " return $newPrefix$interfaceName${createSuffix}($constructorTagName, document";
+ print F ", formElement" if $tags{$tagName}{constructorNeedsFormElement};
+ print F ", createdByParser" if $tags{$tagName}{constructorNeedsCreatedByParser};
print F ");\n}\n\n";
}
@@ -300,20 +307,20 @@ sub printConstructors
my ($F, $tagConstructorMapRef) = @_;
my %tagConstructorMap = %$tagConstructorMapRef;
- print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
+ print F "#if $parameters{guardFactoryWith}\n" if $parameters{guardFactoryWith};
# This is to avoid generating the same constructor several times.
my %uniqueTags = ();
for my $tagName (sort keys %tagConstructorMap) {
- my $interfaceName = $tags{$tagName}{'interfaceName'};
+ my $interfaceName = $tags{$tagName}{interfaceName};
# Ignore the mapped tag
# FIXME: It could be moved inside this loop but was split for readibility.
- next if (defined($uniqueTags{$interfaceName}) || $tags{$tagName}{'mapToTagName'});
+ next if (defined($uniqueTags{$interfaceName}) || $tags{$tagName}{mapToTagName});
$uniqueTags{$interfaceName} = '1';
- my $conditional = $tags{$tagName}{"conditional"};
+ my $conditional = $tags{$tagName}{conditional};
if ($conditional) {
my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
print F "#if ${conditionalString}\n\n";
@@ -323,20 +330,20 @@ sub printConstructors
printConstructorInterior($F, $tagName, $interfaceName, "tagName");
if ($conditional) {
- print F "#endif\n\n";
+ print F "#endif\n";
}
}
# Mapped tag name uses a special wrapper to keep their prefix and namespaceURI while using the mapped localname.
for my $tagName (sort keys %tagConstructorMap) {
- if ($tags{$tagName}{'mapToTagName'}) {
- my $mappedName = $tags{$tagName}{'mapToTagName'};
+ if ($tags{$tagName}{mapToTagName}) {
+ my $mappedName = $tags{$tagName}{mapToTagName};
printConstructorSignature($F, $mappedName, $mappedName . "To" . $tagName, "tagName");
- printConstructorInterior($F, $mappedName, $tags{$mappedName}{'interfaceName'}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");
+ printConstructorInterior($F, $mappedName, $tags{$mappedName}{interfaceName}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");
}
}
- print F "#endif\n" if $parameters{'guardFactoryWith'};
+ print F "#endif\n" if $parameters{guardFactoryWith};
}
sub printFunctionInits
@@ -346,14 +353,14 @@ sub printFunctionInits
for my $tagName (sort keys %tagConstructorMap) {
- my $conditional = $tags{$tagName}{"conditional"};
+ my $conditional = $tags{$tagName}{conditional};
if ($conditional) {
my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
print F "#if ${conditionalString}\n";
}
- if ($tags{$tagName}{'mapToTagName'}) {
- print F " addTag(${tagName}Tag, $tags{$tagName}{'mapToTagName'}To${tagName}Constructor);\n";
+ if ($tags{$tagName}{mapToTagName}) {
+ print F " addTag(${tagName}Tag, $tags{$tagName}{mapToTagName}To${tagName}Constructor);\n";
} else {
print F " addTag(${tagName}Tag, $tagConstructorMap{$tagName}Constructor);\n";
}
@@ -368,9 +375,7 @@ sub svgCapitalizationHacks
{
my $name = shift;
- if ($name =~ /^fe(.+)$/) {
- $name = "FE" . ucfirst $1;
- }
+ $name = "FE" . ucfirst $1 if $name =~ /^fe(.+)$/;
return $name;
}
@@ -379,7 +384,7 @@ sub upperCaseName
{
my $name = shift;
- $name = svgCapitalizationHacks($name) if ($parameters{'namespace'} eq "SVG");
+ $name = svgCapitalizationHacks($name) if ($parameters{namespace} eq "SVG");
while ($name =~ /^(.*?)_(.*)/) {
$name = $1 . ucfirst $2;
@@ -392,10 +397,11 @@ sub printLicenseHeader
{
my $F = shift;
print F "/*
- * THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT.
+ * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
*
+ * This file was generated by the dom/make_names.pl script.
*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -416,10 +422,9 @@ sub printLicenseHeader
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
";
}
@@ -428,16 +433,16 @@ sub printNamesHeaderFile
my ($headerPath) = shift;
my $F;
open F, ">$headerPath";
-
+
printLicenseHeader($F);
- print F "#ifndef DOM_$parameters{'namespace'}NAMES_H\n";
- print F "#define DOM_$parameters{'namespace'}NAMES_H\n\n";
+ print F "#ifndef DOM_$parameters{namespace}NAMES_H\n";
+ print F "#define DOM_$parameters{namespace}NAMES_H\n\n";
print F "#include \"QualifiedName.h\"\n\n";
-
- print F "namespace WebCore {\n\n namespace $parameters{'namespace'}Names {\n\n";
-
- my $lowerNamespace = lc($parameters{'namespacePrefix'});
- print F "#ifndef DOM_$parameters{'namespace'}NAMES_HIDE_GLOBALS\n";
+
+ print F "namespace WebCore {\n\n namespace $parameters{namespace}Names {\n\n";
+
+ my $lowerNamespace = lc($parameters{namespacePrefix});
+ print F "#ifndef DOM_$parameters{namespace}NAMES_HIDE_GLOBALS\n";
print F "// Namespace\n";
print F "extern const WebCore::AtomicString ${lowerNamespace}NamespaceURI;\n\n";
@@ -451,19 +456,19 @@ sub printNamesHeaderFile
printMacros($F, "extern const WebCore::QualifiedName", "Attr", \%attrs);
}
print F "#endif\n\n";
-
+
if (keys %tags) {
- print F "WebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size);\n";
+ print F "WebCore::QualifiedName** get$parameters{namespace}Tags(size_t* size);\n";
}
if (keys %attrs) {
- print F "WebCore::QualifiedName** get$parameters{'namespace'}Attrs(size_t* size);\n";
+ print F "WebCore::QualifiedName** get$parameters{namespace}Attrs(size_t* size);\n";
}
-
+
print F "\nvoid init();\n\n";
print F "} }\n\n";
print F "#endif\n\n";
-
+
close F;
}
@@ -475,25 +480,25 @@ sub printNamesCppFile
printLicenseHeader($F);
- my $lowerNamespace = lc($parameters{'namespacePrefix'});
+ my $lowerNamespace = lc($parameters{namespacePrefix});
print F "#include \"config.h\"\n";
print F "#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC\n";
-print F "#define DOM_$parameters{'namespace'}NAMES_HIDE_GLOBALS 1\n";
+print F "#define DOM_$parameters{namespace}NAMES_HIDE_GLOBALS 1\n";
print F "#else\n";
print F "#define QNAME_DEFAULT_CONSTRUCTOR 1\n";
print F "#endif\n\n";
-print F "#include \"$parameters{'namespace'}Names.h\"\n\n";
+print F "#include \"$parameters{namespace}Names.h\"\n\n";
print F "#include \"StaticConstructors.h\"\n";
-print F "namespace WebCore {\n\n namespace $parameters{'namespace'}Names {
+print F "namespace WebCore {\n\n namespace $parameters{namespace}Names {
using namespace WebCore;
-DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{'namespaceURI'}\")
+DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{namespaceURI}\")
";
if (keys %tags) {
@@ -502,14 +507,14 @@ DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{'namesp
print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI);\n";
}
- print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size)\n";
- print F "{\n static WebCore::QualifiedName* $parameters{'namespace'}Tags[] = {\n";
+ print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Tags(size_t* size)\n";
+ print F "{\n static WebCore::QualifiedName* $parameters{namespace}Tags[] = {\n";
for my $name (sort keys %tags) {
print F " (WebCore::QualifiedName*)&${name}Tag,\n";
}
print F " };\n";
print F " *size = ", scalar(keys %tags), ";\n";
- print F " return $parameters{'namespace'}Tags;\n";
+ print F " return $parameters{namespace}Tags;\n";
print F "}\n";
}
@@ -518,14 +523,14 @@ DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{'namesp
for my $name (sort keys %attrs) {
print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI);\n";
}
- print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Attrs(size_t* size)\n";
- print F "{\n static WebCore::QualifiedName* $parameters{'namespace'}Attr[] = {\n";
+ print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Attrs(size_t* size)\n";
+ print F "{\n static WebCore::QualifiedName* $parameters{namespace}Attr[] = {\n";
for my $name (sort keys %attrs) {
print F " (WebCore::QualifiedName*)&${name}Attr,\n";
}
print F " };\n";
print F " *size = ", scalar(keys %attrs), ";\n";
- print F " return $parameters{'namespace'}Attr;\n";
+ print F " return $parameters{namespace}Attr;\n";
print F "}\n";
}
@@ -549,16 +554,16 @@ print F "\nvoid init()
AtomicString::init();
";
- print(F " AtomicString ${lowerNamespace}NS(\"$parameters{'namespaceURI'}\");\n\n");
+ print(F " AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\");\n\n");
print(F " // Namespace\n");
print(F " new ((void*)&${lowerNamespace}NamespaceURI) AtomicString(${lowerNamespace}NS);\n\n");
if (keys %tags) {
- my $tagsNamespace = $parameters{'tagsNullNamespace'} ? "nullAtom" : "${lowerNamespace}NS";
+ my $tagsNamespace = $parameters{tagsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
printDefinitions($F, \%tags, "tags", $tagsNamespace);
}
if (keys %attrs) {
- my $attrsNamespace = $parameters{'attrsNullNamespace'} ? "nullAtom" : "${lowerNamespace}NS";
+ my $attrsNamespace = $parameters{attrsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
printDefinitions($F, \%attrs, "attributes", $attrsNamespace);
}
@@ -572,7 +577,7 @@ sub printJSElementIncludes
my %tagsSeen;
for my $tagName (sort keys %tags) {
- my $JSInterfaceName = $tags{$tagName}{"JSInterfaceName"};
+ my $JSInterfaceName = $tags{$tagName}{JSInterfaceName};
next if defined($tagsSeen{$JSInterfaceName}) || usesDefaultJSWrapper($tagName);
$tagsSeen{$JSInterfaceName} = 1;
@@ -586,7 +591,7 @@ sub printElementIncludes
my %tagsSeen;
for my $tagName (sort keys %tags) {
- my $interfaceName = $tags{$tagName}{"interfaceName"};
+ my $interfaceName = $tags{$tagName}{interfaceName};
next if defined($tagsSeen{$interfaceName});
$tagsSeen{$interfaceName} = 1;
@@ -604,7 +609,7 @@ sub printDefinitionStrings
my %names = %$namesRef;
for my $name (sort keys %$namesRef) {
- next if (!$parameters{'exportStrings'} and !$names{$name}{"exportString"});
+ next if (!$parameters{exportStrings} and !$names{$name}{exportString});
my $realName = $name;
$realName =~ s/_/-/g;
@@ -625,7 +630,7 @@ sub printDefinitions
my %names = %$namesRef;
for my $name (sort keys %$namesRef) {
- next if ($parameters{'exportStrings'} or $names{$name}{"exportString"});
+ next if ($parameters{exportStrings} or $names{$name}{exportString});
my $realName = $name;
$realName =~ s/_/-/g;
@@ -651,39 +656,31 @@ printLicenseHeader($F);
print F <<END
#include "config.h"
-#include "$parameters{'namespace'}ElementFactory.h"
-
-#include "$parameters{'namespace'}Names.h"
-#if ENABLE(DASHBOARD_SUPPORT)
-#include "Document.h"
-#include "Settings.h"
-#endif
+#include "$parameters{namespace}ElementFactory.h"
+#include "$parameters{namespace}Names.h"
END
;
-if ($parameters{'namespace'} eq "HTML") {
- print F "#include \"HTMLFormElement.h\"\n";
-}
-
printElementIncludes($F);
print F <<END
#include <wtf/HashMap.h>
+#if ENABLE(DASHBOARD_SUPPORT)
+#include "Document.h"
+#include "Settings.h"
+#endif
+
namespace WebCore {
-using namespace $parameters{'namespace'}Names;
+using namespace $parameters{namespace}Names;
END
;
-print F "typedef PassRefPtr<$parameters{'namespace'}Element> (*ConstructorFunction)(const QualifiedName&, Document*";
-
-if ($parameters{'namespace'} eq "HTML") {
- print F ", HTMLFormElement*";
-}
-
+print F "typedef PassRefPtr<$parameters{namespace}Element> (*ConstructorFunction)(const QualifiedName&, Document*";
+print F ", HTMLFormElement*" if $parameters{namespace} eq "HTML";
print F ", bool createdByParser);\n";
print F <<END
typedef HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
@@ -697,7 +694,7 @@ my %tagConstructorMap = buildConstructorMap();
printConstructors($F, \%tagConstructorMap);
-print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
+print F "#if $parameters{guardFactoryWith}\n" if $parameters{guardFactoryWith};
print F <<END
static void addTag(const QualifiedName& tag, ConstructorFunction func)
@@ -705,10 +702,10 @@ static void addTag(const QualifiedName& tag, ConstructorFunction func)
gFunctionMap->set(tag.localName().impl(), func);
}
-static inline void createFunctionMapIfNecessary()
+static void createFunctionMap()
{
- if (gFunctionMap)
- return;
+ ASSERT(!gFunctionMap);
+
// Create the table.
gFunctionMap = new FunctionMap;
@@ -719,30 +716,25 @@ END
printFunctionInits($F, \%tagConstructorMap);
print F "}\n";
-print F "#endif\n" if $parameters{'guardFactoryWith'};
-
-print F "\nPassRefPtr<$parameters{'namespace'}Element> $parameters{'namespace'}ElementFactory::create$parameters{'namespace'}Element(const QualifiedName& qName, Document* doc";
-
-if ($parameters{"namespace"} eq "HTML") {
- print F ", HTMLFormElement* formElement";
-}
+print F "#endif\n" if $parameters{guardFactoryWith};
+print F "\nPassRefPtr<$parameters{namespace}Element> $parameters{namespace}ElementFactory::create$parameters{namespace}Element(const QualifiedName& qName, Document* document";
+print F ", HTMLFormElement* formElement" if $parameters{namespace} eq "HTML";
print F ", bool createdByParser)\n{\n";
-print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
+print F "#if $parameters{guardFactoryWith}\n" if $parameters{guardFactoryWith};
print F <<END
- // Don't make elements without a document
- if (!doc)
+ if (!document)
return 0;
END
;
-if ($parameters{'namespace'} ne "HTML") {
+if ($parameters{namespace} ne "HTML") {
print F <<END
#if ENABLE(DASHBOARD_SUPPORT)
- Settings* settings = doc->settings();
+ Settings* settings = document->settings();
if (settings && settings->usesDashboardBackwardCompatibilityMode())
return 0;
#endif
@@ -752,21 +744,21 @@ END
}
print F <<END
- createFunctionMapIfNecessary();
- ConstructorFunction func = gFunctionMap->get(qName.localName().impl());
- if (func)
+ if (!gFunctionMap)
+ createFunctionMap();
+ if (ConstructorFunction function = gFunctionMap->get(qName.localName().impl()))
END
;
-if ($parameters{"namespace"} eq "HTML") {
- print F " return func(qName, doc, formElement, createdByParser);\n";
+if ($parameters{namespace} eq "HTML") {
+ print F " return function(qName, document, formElement, createdByParser);\n";
} else {
- print F " return func(qName, doc, createdByParser);\n";
+ print F " return function(qName, document, createdByParser);\n";
}
-print F " return new $parameters{'namespace'}Element(qName, doc);\n";
+print F " return $parameters{namespace}Element::create(qName, document);\n";
-if ($parameters{'guardFactoryWith'}) {
+if ($parameters{guardFactoryWith}) {
print F <<END
#else
@@ -797,8 +789,8 @@ sub printFactoryHeaderFile
printLicenseHeader($F);
print F<<END
-#ifndef $parameters{'namespace'}ElementFactory_h
-#define $parameters{'namespace'}ElementFactory_h
+#ifndef $parameters{namespace}ElementFactory_h
+#define $parameters{namespace}ElementFactory_h
#include <wtf/PassRefPtr.h>
@@ -811,35 +803,29 @@ namespace WebCore {
namespace WebCore {
- class $parameters{'namespace'}Element;
+ class $parameters{namespace}Element;
END
;
-if ($parameters{'namespace'} eq "HTML") {
- print F " class HTMLFormElement;\n";
-}
+print F " class HTMLFormElement;\n" if $parameters{namespace} eq "HTML";
print F<<END
// The idea behind this class is that there will eventually be a mapping from namespace URIs to ElementFactories that can dispense
// elements. In a compound document world, the generic createElement function (will end up being virtual) will be called.
- class $parameters{'namespace'}ElementFactory {
+ class $parameters{namespace}ElementFactory {
public:
PassRefPtr<Element> createElement(const WebCore::QualifiedName&, WebCore::Document*, bool createdByParser = true);
END
;
-print F " static PassRefPtr<$parameters{'namespace'}Element> create$parameters{'namespace'}Element(const WebCore::QualifiedName&, WebCore::Document*";
-
-if ($parameters{'namespace'} eq "HTML") {
- print F ", HTMLFormElement* = 0";
-}
-
+print F " static PassRefPtr<$parameters{namespace}Element> create$parameters{namespace}Element(const WebCore::QualifiedName&, WebCore::Document*";
+print F ", HTMLFormElement* = 0" if $parameters{namespace} eq "HTML";
print F ", bool /*createdByParser*/ = true);\n";
printf F<<END
};
}
-#endif // $parameters{'namespace'}ElementFactory_h
+#endif // $parameters{namespace}ElementFactory_h
END
;
@@ -854,7 +840,7 @@ sub usesDefaultJSWrapper
my $name = shift;
# A tag reuses the default wrapper if its JSInterfaceName matches the default namespace Element.
- return $tags{$name}{'JSInterfaceName'} eq $parameters{"namespace"} . "Element" || $tags{$name}{'JSInterfaceName'} eq "HTMLNoScriptElement";
+ return $tags{$name}{JSInterfaceName} eq $parameters{namespace} . "Element" || $tags{$name}{JSInterfaceName} eq "HTMLNoScriptElement";
}
sub printWrapperFunctions
@@ -864,11 +850,11 @@ sub printWrapperFunctions
my %tagsSeen;
for my $tagName (sort keys %tags) {
# Avoid defining the same wrapper method twice.
- my $JSInterfaceName = $tags{$tagName}{"JSInterfaceName"};
+ my $JSInterfaceName = $tags{$tagName}{JSInterfaceName};
next if defined($tagsSeen{$JSInterfaceName}) || usesDefaultJSWrapper($tagName);
$tagsSeen{$JSInterfaceName} = 1;
- my $conditional = $tags{$tagName}{"conditional"};
+ my $conditional = $tags{$tagName}{conditional};
if ($conditional) {
my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
print F "#if ${conditionalString}\n\n";
@@ -876,12 +862,12 @@ sub printWrapperFunctions
# Hack for the media tags
# FIXME: This should have been done via a CustomWrapper attribute and a separate *Custom file.
- if ($tags{$tagName}{"wrapperOnlyIfMediaIsAvailable"}) {
+ if ($tags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
print F <<END
-static JSNode* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{'namespace'}Element> element)
+static JSNode* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
{
if (!MediaPlayer::isAvailable())
- return CREATE_DOM_NODE_WRAPPER(exec, globalObject, $parameters{'namespace'}Element, element.get());
+ return CREATE_DOM_NODE_WRAPPER(exec, globalObject, $parameters{namespace}Element, element.get());
return CREATE_DOM_NODE_WRAPPER(exec, globalObject, ${JSInterfaceName}, element.get());
}
@@ -889,7 +875,7 @@ END
;
} else {
print F <<END
-static JSNode* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{'namespace'}Element> element)
+static JSNode* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
{
return CREATE_DOM_NODE_WRAPPER(exec, globalObject, ${JSInterfaceName}, element.get());
}
@@ -897,6 +883,7 @@ static JSNode* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObjec
END
;
}
+
if ($conditional) {
print F "#endif\n\n";
}
@@ -913,13 +900,13 @@ sub printWrapperFactoryCppFile
print F "#include \"config.h\"\n\n";
- print F "#if $parameters{'guardFactoryWith'}\n\n" if $parameters{'guardFactoryWith'};
+ print F "#if $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
- print F "#include \"JS$parameters{'namespace'}ElementWrapperFactory.h\"\n";
+ print F "#include \"JS$parameters{namespace}ElementWrapperFactory.h\"\n";
printJSElementIncludes($F);
- print F "\n#include \"$parameters{'namespace'}Names.h\"\n\n";
+ print F "\n#include \"$parameters{namespace}Names.h\"\n\n";
printElementIncludes($F);
@@ -930,9 +917,9 @@ using namespace JSC;
namespace WebCore {
-using namespace $parameters{'namespace'}Names;
+using namespace $parameters{namespace}Names;
-typedef JSNode* (*Create$parameters{'namespace'}ElementWrapperFunction)(ExecState*, JSDOMGlobalObject*, PassRefPtr<$parameters{'namespace'}Element>);
+typedef JSNode* (*Create$parameters{namespace}ElementWrapperFunction)(ExecState*, JSDOMGlobalObject*, PassRefPtr<$parameters{namespace}Element>);
END
;
@@ -940,9 +927,9 @@ END
printWrapperFunctions($F);
print F <<END
-JSNode* createJS$parameters{'namespace'}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{'namespace'}Element> element)
+JSNode* createJS$parameters{namespace}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
{
- typedef HashMap<WebCore::AtomicStringImpl*, Create$parameters{'namespace'}ElementWrapperFunction> FunctionMap;
+ typedef HashMap<WebCore::AtomicStringImpl*, Create$parameters{namespace}ElementWrapperFunction> FunctionMap;
DEFINE_STATIC_LOCAL(FunctionMap, map, ());
if (map.isEmpty()) {
END
@@ -952,13 +939,13 @@ END
# Do not add the name to the map if it does not have a JS wrapper constructor or uses the default wrapper.
next if usesDefaultJSWrapper($tag, \%tags);
- my $conditional = $tags{$tag}{"conditional"};
+ my $conditional = $tags{$tag}{conditional};
if ($conditional) {
my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
print F "#if ${conditionalString}\n";
}
- my $ucTag = $tags{$tag}{"JSInterfaceName"};
+ my $ucTag = $tags{$tag}{JSInterfaceName};
print F " map.set(${tag}Tag.localName().impl(), create${ucTag}Wrapper);\n";
if ($conditional) {
@@ -968,10 +955,10 @@ END
print F <<END
}
- Create$parameters{'namespace'}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl());
+ Create$parameters{namespace}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl());
if (createWrapperFunction)
return createWrapperFunction(exec, globalObject, element);
- return CREATE_DOM_NODE_WRAPPER(exec, globalObject, $parameters{'namespace'}Element, element.get());
+ return CREATE_DOM_NODE_WRAPPER(exec, globalObject, $parameters{namespace}Element, element.get());
}
}
@@ -979,7 +966,7 @@ END
END
;
- print F "#endif\n" if $parameters{'guardFactoryWith'};
+ print F "#endif\n" if $parameters{guardFactoryWith};
close F;
}
@@ -992,10 +979,10 @@ sub printWrapperFactoryHeaderFile
printLicenseHeader($F);
- print F "#ifndef JS$parameters{'namespace'}ElementWrapperFactory_h\n";
- print F "#define JS$parameters{'namespace'}ElementWrapperFactory_h\n\n";
+ print F "#ifndef JS$parameters{namespace}ElementWrapperFactory_h\n";
+ print F "#define JS$parameters{namespace}ElementWrapperFactory_h\n\n";
- print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
+ print F "#if $parameters{guardFactoryWith}\n" if $parameters{guardFactoryWith};
print F <<END
#include <wtf/Forward.h>
@@ -1008,18 +995,18 @@ namespace WebCore {
class JSNode;
class JSDOMGlobalObject;
- class $parameters{'namespace'}Element;
+ class $parameters{namespace}Element;
- JSNode* createJS$parameters{'namespace'}Wrapper(JSC::ExecState*, JSDOMGlobalObject*, PassRefPtr<$parameters{'namespace'}Element>);
+ JSNode* createJS$parameters{namespace}Wrapper(JSC::ExecState*, JSDOMGlobalObject*, PassRefPtr<$parameters{namespace}Element>);
}
END
;
- print F "#endif // $parameters{'guardFactoryWith'}\n\n" if $parameters{'guardFactoryWith'};
+ print F "#endif // $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
- print F "#endif // JS$parameters{'namespace'}ElementWrapperFactory_h\n";
+ print F "#endif // JS$parameters{namespace}ElementWrapperFactory_h\n";
close F;
}