summaryrefslogtreecommitdiffstats
path: root/WebCore/dom
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom')
-rw-r--r--WebCore/dom/Attr.idl2
-rw-r--r--WebCore/dom/CharacterData.cpp6
-rw-r--r--WebCore/dom/CharacterData.h4
-rw-r--r--WebCore/dom/CharacterData.idl2
-rw-r--r--WebCore/dom/ClientRect.cpp (renamed from WebCore/dom/WorkerTask.cpp)16
-rw-r--r--WebCore/dom/ClientRect.h59
-rw-r--r--WebCore/dom/ClientRect.idl (renamed from WebCore/dom/WorkerTask.h)34
-rw-r--r--WebCore/dom/ClientRectList.cpp66
-rw-r--r--WebCore/dom/ClientRectList.h (renamed from WebCore/dom/WorkerLocation.h)50
-rw-r--r--WebCore/dom/ClientRectList.idl (renamed from WebCore/dom/Worker.idl)28
-rw-r--r--WebCore/dom/Clipboard.cpp1
-rw-r--r--WebCore/dom/ContainerNode.cpp159
-rw-r--r--WebCore/dom/ContainerNode.h17
-rw-r--r--WebCore/dom/DOMImplementation.cpp3
-rw-r--r--WebCore/dom/Document.cpp317
-rw-r--r--WebCore/dom/Document.h88
-rw-r--r--WebCore/dom/Document.idl20
-rw-r--r--WebCore/dom/DocumentFragment.idl7
-rw-r--r--WebCore/dom/Element.cpp144
-rw-r--r--WebCore/dom/Element.h15
-rw-r--r--WebCore/dom/Element.idl16
-rw-r--r--WebCore/dom/EventException.idl3
-rw-r--r--WebCore/dom/EventListener.h19
-rw-r--r--WebCore/dom/EventListener.idl1
-rw-r--r--WebCore/dom/EventNames.h8
-rw-r--r--WebCore/dom/EventTarget.cpp2
-rw-r--r--WebCore/dom/EventTarget.h4
-rw-r--r--WebCore/dom/EventTarget.idl6
-rw-r--r--WebCore/dom/EventTargetNode.cpp1241
-rw-r--r--WebCore/dom/EventTargetNode.h219
-rw-r--r--WebCore/dom/EventTargetNode.idl90
-rw-r--r--WebCore/dom/ExceptionCode.cpp3
-rw-r--r--WebCore/dom/FormControlElement.h4
-rw-r--r--WebCore/dom/GenericWorkerTask.h109
-rw-r--r--WebCore/dom/InputElement.cpp4
-rw-r--r--WebCore/dom/InputElement.h4
-rw-r--r--WebCore/dom/MessagePort.cpp1
-rw-r--r--WebCore/dom/MouseEvent.cpp8
-rw-r--r--WebCore/dom/MouseEvent.h11
-rw-r--r--WebCore/dom/MouseRelatedEvent.cpp21
-rw-r--r--WebCore/dom/MouseRelatedEvent.h11
-rw-r--r--WebCore/dom/NamedAttrMap.cpp26
-rw-r--r--WebCore/dom/NamedAttrMap.h55
-rw-r--r--WebCore/dom/NamedMappedAttrMap.cpp4
-rw-r--r--WebCore/dom/NamedMappedAttrMap.h21
-rw-r--r--WebCore/dom/NamedNodeMap.h5
-rw-r--r--WebCore/dom/Node.cpp1258
-rw-r--r--WebCore/dom/Node.h193
-rw-r--r--WebCore/dom/Node.idl73
-rw-r--r--WebCore/dom/Position.cpp161
-rw-r--r--WebCore/dom/Position.h71
-rw-r--r--WebCore/dom/PositionIterator.cpp22
-rw-r--r--WebCore/dom/PositionIterator.h4
-rw-r--r--WebCore/dom/QualifiedName.cpp35
-rw-r--r--WebCore/dom/QualifiedName.h33
-rw-r--r--WebCore/dom/Range.cpp56
-rw-r--r--WebCore/dom/RangeBoundaryPoint.h48
-rw-r--r--WebCore/dom/ScriptExecutionContext.cpp16
-rw-r--r--WebCore/dom/ScriptExecutionContext.h12
-rw-r--r--WebCore/dom/Text.cpp7
-rw-r--r--WebCore/dom/Tokenizer.h2
-rw-r--r--WebCore/dom/WheelEvent.cpp11
-rw-r--r--WebCore/dom/WheelEvent.h6
-rw-r--r--WebCore/dom/Worker.cpp203
-rw-r--r--WebCore/dom/Worker.h113
-rw-r--r--WebCore/dom/WorkerContext.cpp223
-rw-r--r--WebCore/dom/WorkerContext.h124
-rw-r--r--WebCore/dom/WorkerContext.idl61
-rw-r--r--WebCore/dom/WorkerLocation.cpp85
-rw-r--r--WebCore/dom/WorkerLocation.idl48
-rw-r--r--WebCore/dom/WorkerMessagingProxy.cpp316
-rw-r--r--WebCore/dom/WorkerMessagingProxy.h96
-rw-r--r--WebCore/dom/WorkerRunLoop.cpp69
-rw-r--r--WebCore/dom/WorkerRunLoop.h64
-rw-r--r--WebCore/dom/WorkerThread.cpp154
-rw-r--r--WebCore/dom/WorkerThread.h78
-rw-r--r--WebCore/dom/XMLTokenizer.cpp43
-rw-r--r--WebCore/dom/XMLTokenizer.h2
-rw-r--r--WebCore/dom/XMLTokenizerLibxml2.cpp12
-rw-r--r--WebCore/dom/XMLTokenizerQt.cpp9
-rwxr-xr-xWebCore/dom/make_names.pl174
81 files changed, 2658 insertions, 4158 deletions
diff --git a/WebCore/dom/Attr.idl b/WebCore/dom/Attr.idl
index 42ac04c..ccbfada 100644
--- a/WebCore/dom/Attr.idl
+++ b/WebCore/dom/Attr.idl
@@ -25,7 +25,7 @@ module core {
GenerateNativeConverter,
InterfaceUUID=EEE8E22B-22C3-4e50-95F4-5E0B8AAD8231,
ImplementationUUID=41B16348-D8E7-4d21-BFDB-125705B7E91F
- ] Attr : EventTargetNode {
+ ] Attr : Node {
// DOM Level 1
diff --git a/WebCore/dom/CharacterData.cpp b/WebCore/dom/CharacterData.cpp
index 0ce4170..54e1888 100644
--- a/WebCore/dom/CharacterData.cpp
+++ b/WebCore/dom/CharacterData.cpp
@@ -31,13 +31,13 @@
namespace WebCore {
CharacterData::CharacterData(Document *doc, bool isText)
- : EventTargetNode(doc, false, false, isText)
+ : Node(doc, false, false, isText)
, m_data(StringImpl::empty())
{
}
CharacterData::CharacterData(Document* document, const String& text, bool isText)
- : EventTargetNode(document, false, false, isText)
+ : Node(document, false, false, isText)
{
m_data = text.impl() ? text.impl() : StringImpl::empty();
}
@@ -224,7 +224,7 @@ bool CharacterData::rendererIsNeeded(RenderStyle *style)
{
if (!m_data || !length())
return false;
- return EventTargetNode::rendererIsNeeded(style);
+ return Node::rendererIsNeeded(style);
}
bool CharacterData::offsetInCharacters() const
diff --git a/WebCore/dom/CharacterData.h b/WebCore/dom/CharacterData.h
index 412650e..d9e55c0 100644
--- a/WebCore/dom/CharacterData.h
+++ b/WebCore/dom/CharacterData.h
@@ -23,11 +23,11 @@
#ifndef CharacterData_h
#define CharacterData_h
-#include "EventTargetNode.h"
+#include "Node.h"
namespace WebCore {
-class CharacterData : public EventTargetNode {
+class CharacterData : public Node {
public:
CharacterData(Document*, const String& text, bool isText = false);
CharacterData(Document*, bool isText = false);
diff --git a/WebCore/dom/CharacterData.idl b/WebCore/dom/CharacterData.idl
index 74dc483..7c8c7ac 100644
--- a/WebCore/dom/CharacterData.idl
+++ b/WebCore/dom/CharacterData.idl
@@ -23,7 +23,7 @@ module core {
GenerateConstructor,
InterfaceUUID=149159F4-D2BA-4040-8137-6BF6424C972A,
ImplementationUUID=E2095280-B9BD-446a-8C03-79F78417CDFF
- ] CharacterData : EventTargetNode {
+ ] CharacterData : Node {
attribute [ConvertNullToNullString] DOMString data
setter raises(DOMException);
diff --git a/WebCore/dom/WorkerTask.cpp b/WebCore/dom/ClientRect.cpp
index 4a22c59..c69a2ab 100644
--- a/WebCore/dom/WorkerTask.cpp
+++ b/WebCore/dom/ClientRect.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * 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
@@ -25,17 +25,17 @@
*/
#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "WorkerTask.h"
+#include "ClientRect.h"
namespace WebCore {
-WorkerTask::~WorkerTask()
+ClientRect::ClientRect()
{
}
-} // namespace WebCore
+ClientRect::ClientRect(const IntRect& rect)
+ : m_rect(rect)
+{
+}
-#endif // ENABLE(WORKERS)
+} // namespace WebCore
diff --git a/WebCore/dom/ClientRect.h b/WebCore/dom/ClientRect.h
new file mode 100644
index 0000000..349ea85
--- /dev/null
+++ b/WebCore/dom/ClientRect.h
@@ -0,0 +1,59 @@
+/*
+ * 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 COMPUTER, 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 ClientRect_h
+#define ClientRect_h
+
+#include "FloatRect.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class IntRect;
+
+ class ClientRect : public RefCounted<ClientRect> {
+ public:
+ static PassRefPtr<ClientRect> create() { return adoptRef(new ClientRect); }
+ static PassRefPtr<ClientRect> create(const IntRect& rect) { return adoptRef(new ClientRect(rect)); }
+
+ float top() const { return m_rect.y(); }
+ float right() const { return m_rect.right(); }
+ float bottom() const { return m_rect.bottom(); }
+ float left() const { return m_rect.x(); }
+ float width() const { return m_rect.width(); }
+ float height() const { return m_rect.height(); }
+
+ private:
+ ClientRect();
+ ClientRect(const IntRect&);
+
+ FloatRect m_rect;
+ };
+
+} // namespace WebCore
+
+#endif // ClientRect_h
diff --git a/WebCore/dom/WorkerTask.h b/WebCore/dom/ClientRect.idl
index a842ce2..6f0598f 100644
--- a/WebCore/dom/WorkerTask.h
+++ b/WebCore/dom/ClientRect.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * 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
@@ -24,25 +24,17 @@
*
*/
-#ifndef WorkerTask_h
-#define WorkerTask_h
-
-#if ENABLE(WORKERS)
-
-#include <wtf/Threading.h>
-
-namespace WebCore {
-
- class WorkerContext;
-
- class WorkerTask : public ThreadSafeShared<WorkerTask> {
- public:
- virtual ~WorkerTask();
- virtual void performTask(WorkerContext*) = 0;
+module view {
+
+ interface [
+ GenerateConstructor
+ ] ClientRect {
+ readonly attribute float top;
+ readonly attribute float right;
+ readonly attribute float bottom;
+ readonly attribute float left;
+ readonly attribute float width;
+ readonly attribute float height;
};
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerTask_h
+}
diff --git a/WebCore/dom/ClientRectList.cpp b/WebCore/dom/ClientRectList.cpp
new file mode 100644
index 0000000..95ec758
--- /dev/null
+++ b/WebCore/dom/ClientRectList.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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 COMPUTER, 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.
+ *
+ */
+
+#include "config.h"
+#include "ClientRectList.h"
+
+#include "ExceptionCode.h"
+#include "ClientRect.h"
+
+namespace WebCore {
+
+ClientRectList::ClientRectList()
+{
+}
+
+ClientRectList::ClientRectList(const Vector<FloatQuad>& quads)
+{
+ m_list.reserveInitialCapacity(quads.size());
+ for (size_t i = 0; i < quads.size(); ++i)
+ m_list.append(ClientRect::create(quads[i].enclosingBoundingBox()));
+}
+
+ClientRectList::~ClientRectList()
+{
+}
+
+unsigned ClientRectList::length() const
+{
+ return m_list.size();
+}
+
+ClientRect* ClientRectList::item(unsigned index)
+{
+ if (index >= m_list.size()) {
+ // FIXME: this should throw an exception.
+ // ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ return m_list[index].get();
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/WorkerLocation.h b/WebCore/dom/ClientRectList.h
index 52c31ad..03915b1 100644
--- a/WebCore/dom/WorkerLocation.h
+++ b/WebCore/dom/ClientRectList.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * 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
@@ -24,50 +24,34 @@
*
*/
-#ifndef WorkerLocation_h
-#define WorkerLocation_h
+#ifndef ClientRectList_h
+#define ClientRectList_h
-#if ENABLE(WORKERS)
-
-#include "KURL.h"
+#include "FloatQuad.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
namespace WebCore {
- class String;
+ class ClientRect;
- class WorkerLocation : public RefCounted<WorkerLocation> {
+ class ClientRectList : public RefCounted<ClientRectList> {
public:
- static PassRefPtr<WorkerLocation> create(const KURL& url)
- {
- return adoptRef(new WorkerLocation(url));
- }
-
- const KURL& url() const { return m_url; }
-
- String href() const;
+ static PassRefPtr<ClientRectList> create() { return adoptRef(new ClientRectList); }
+ static PassRefPtr<ClientRectList> create(const Vector<FloatQuad>& quads) { return adoptRef(new ClientRectList(quads)); }
+ ~ClientRectList();
- // URI decomposition attributes
- String protocol() const;
- String host() const;
- String hostname() const;
- String port() const;
- String pathname() const;
- String search() const;
- String hash() const;
-
- String toString() const;
+ unsigned length() const;
+ ClientRect* item(unsigned index);
private:
- WorkerLocation(const KURL& url) : m_url(url) { }
+ ClientRectList();
+ ClientRectList(const Vector<FloatQuad>&);
- KURL m_url;
- };
+ Vector<RefPtr<ClientRect> > m_list;
+ };
} // namespace WebCore
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerLocation_h
+#endif // ClientRectList_h
diff --git a/WebCore/dom/Worker.idl b/WebCore/dom/ClientRectList.idl
index 2ef9b62..8230f6c 100644
--- a/WebCore/dom/Worker.idl
+++ b/WebCore/dom/ClientRectList.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * 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
@@ -24,25 +24,15 @@
*
*/
-module threads {
+module view {
- interface [CustomMarkFunction, Conditional=WORKERS] Worker {
-
- attribute EventListener onerror;
- attribute EventListener onmessage;
- void postMessage(in DOMString message);
-
- void terminate();
-
- // EventTarget interface
- [Custom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [Custom] void removeEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- boolean dispatchEvent(in Event evt)
- raises(EventException);
+ interface [
+ GenerateConstructor,
+ HasIndexGetter
+ ] ClientRectList {
+ readonly attribute unsigned long length;
+ ClientRect item(in [IsIndex] unsigned long index);
+ // FIXME: Fix list behavior to allow custom exceptions to be thrown.
};
}
diff --git a/WebCore/dom/Clipboard.cpp b/WebCore/dom/Clipboard.cpp
index f7a52ef..6d1bc15 100644
--- a/WebCore/dom/Clipboard.cpp
+++ b/WebCore/dom/Clipboard.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "Clipboard.h"
+#include "CachedImage.h"
#include "DOMImplementation.h"
#include "Frame.h"
#include "FrameLoader.h"
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 958fc4e..91b633f 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 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
@@ -32,6 +32,7 @@
#include "FrameView.h"
#include "InlineTextBox.h"
#include "MutationEvent.h"
+#include "Page.h"
#include "RenderTheme.h"
#include "RootInlineBox.h"
#include <wtf/CurrentTime.h>
@@ -42,16 +43,10 @@ static void dispatchChildInsertionEvents(Node*, ExceptionCode&);
static void dispatchChildRemovalEvents(Node*, ExceptionCode&);
typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
-static NodeCallbackQueue* s_postAttachCallbackQueue = 0;
+static NodeCallbackQueue* s_postAttachCallbackQueue;
-static size_t s_attachDepth = 0;
-
-ContainerNode::ContainerNode(Document* doc, bool isElement)
- : EventTargetNode(doc, isElement, true)
- , m_firstChild(0)
- , m_lastChild(0)
-{
-}
+static size_t s_attachDepth;
+static bool s_shouldReEnableMemoryCacheCallsAfterAttach;
void ContainerNode::removeAllChildren()
{
@@ -98,9 +93,8 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
return true;
RefPtr<Node> next = refChild;
- RefPtr<Node> prev = refChild->previousSibling();
+ RefPtr<Node> refChildPreviousSibling = refChild->previousSibling();
- int childCountDelta = 0;
RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
while (child) {
RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
@@ -128,8 +122,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
ASSERT(!child->nextSibling());
ASSERT(!child->previousSibling());
- childCountDelta++;
-
// Add child before "next".
forbidEventDispatch();
Node* prev = next->previousSibling();
@@ -149,6 +141,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
allowEventDispatch();
// Dispatch the mutation events.
+ childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
dispatchChildInsertionEvents(child.get(), ec);
// Add child to the rendering tree.
@@ -163,8 +156,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
}
document()->setDocumentChanged(true);
- if (childCountDelta)
- childrenChanged(false, prev.get(), next.get(), childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -222,7 +213,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
if (Node* oldParent = child->parentNode())
oldParent->removeChild(child.get(), ec);
if (ec)
- return 0;
+ return false;
// Due to arbitrary code running in response to a DOM mutation event it's
// possible that "prev" is no longer a child of "this".
@@ -288,7 +279,7 @@ void ContainerNode::willRemove()
{
for (Node *n = m_firstChild; n != 0; n = n->nextSibling())
n->willRemove();
- EventTargetNode::willRemove();
+ Node::willRemove();
}
static ExceptionCode willRemoveChild(Node *child)
@@ -392,25 +383,25 @@ bool ContainerNode::removeChildren()
if (!m_firstChild)
return false;
- Node* n;
+ // The container node can be removed from event handlers.
+ RefPtr<Node> protect(this);
- // do any prep work needed before actually starting to detach
- // and remove... e.g. stop loading frames, fire unload events
- for (n = m_firstChild; n; n = n->nextSibling())
- willRemoveChild(n);
+ // Do any prep work needed before actually starting to detach
+ // and remove... e.g. stop loading frames, fire unload events.
+ // FIXME: Adding new children from event handlers can cause an infinite loop here.
+ for (RefPtr<Node> n = m_firstChild; n; n = n->nextSibling())
+ willRemoveChild(n.get());
// exclude this node when looking for removed focusedNode since only children will be removed
document()->removeFocusedNodeOfSubtree(this, true);
forbidEventDispatch();
int childCountDelta = 0;
- while ((n = m_firstChild) != 0) {
+ while (RefPtr<Node> n = m_firstChild) {
childCountDelta--;
- Node *next = n->nextSibling();
+ Node* next = n->nextSibling();
- n->ref();
-
// Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744)
n->setPreviousSibling(0);
n->setNextSibling(0);
@@ -425,8 +416,6 @@ bool ContainerNode::removeChildren()
if (n->inDocument())
n->removedFromDocument();
-
- n->deref();
}
allowEventDispatch();
@@ -461,7 +450,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
return true;
// Now actually add the child(ren)
- int childCountDelta = 0;
RefPtr<Node> prev = lastChild();
RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
while (child) {
@@ -482,7 +470,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
}
// Append child to the end of the list
- childCountDelta++;
forbidEventDispatch();
child->setParent(this);
if (m_lastChild) {
@@ -494,6 +481,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
allowEventDispatch();
// Dispatch the mutation events
+ childrenChanged(false, prev.get(), 0, 1);
dispatchChildInsertionEvents(child.get(), ec);
// Add child to the rendering tree
@@ -508,7 +496,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
}
document()->setDocumentChanged(true);
- childrenChanged(false, prev.get(), 0, childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -539,13 +526,29 @@ ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
void ContainerNode::suspendPostAttachCallbacks()
{
+ if (!s_attachDepth) {
+ ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
+ if (Page* page = document()->page()) {
+ if (page->areMemoryCacheClientCallsEnabled()) {
+ page->setMemoryCacheClientCallsEnabled(false);
+ s_shouldReEnableMemoryCacheCallsAfterAttach = true;
+ }
+ }
+ }
++s_attachDepth;
}
void ContainerNode::resumePostAttachCallbacks()
{
- if (s_attachDepth == 1 && s_postAttachCallbackQueue)
- dispatchPostAttachCallbacks();
+ if (s_attachDepth == 1) {
+ if (s_postAttachCallbackQueue)
+ dispatchPostAttachCallbacks();
+ if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
+ s_shouldReEnableMemoryCacheCallsAfterAttach = false;
+ if (Page* page = document()->page())
+ page->setMemoryCacheClientCallsEnabled(true);
+ }
+ }
--s_attachDepth;
}
@@ -573,15 +576,13 @@ void ContainerNode::dispatchPostAttachCallbacks()
void ContainerNode::attach()
{
- ++s_attachDepth;
+ suspendPostAttachCallbacks();
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->attach();
- EventTargetNode::attach();
+ Node::attach();
- if (s_attachDepth == 1 && s_postAttachCallbackQueue)
- dispatchPostAttachCallbacks();
- --s_attachDepth;
+ resumePostAttachCallbacks();
}
void ContainerNode::detach()
@@ -589,39 +590,40 @@ void ContainerNode::detach()
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->detach();
setHasChangedChild(false);
- EventTargetNode::detach();
+ Node::detach();
}
void ContainerNode::insertedIntoDocument()
{
- EventTargetNode::insertedIntoDocument();
- for (Node *child = m_firstChild; child; child = child->nextSibling())
+ Node::insertedIntoDocument();
+ insertedIntoTree(false);
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
child->insertedIntoDocument();
}
void ContainerNode::removedFromDocument()
{
- EventTargetNode::removedFromDocument();
- for (Node *child = m_firstChild; child; child = child->nextSibling())
+ Node::removedFromDocument();
+ setInDocument(false);
+ removedFromTree(false);
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
child->removedFromDocument();
}
void ContainerNode::insertedIntoTree(bool deep)
{
- EventTargetNode::insertedIntoTree(deep);
- if (deep) {
- for (Node *child = m_firstChild; child; child = child->nextSibling())
- child->insertedIntoTree(deep);
- }
+ if (!deep)
+ return;
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->insertedIntoTree(true);
}
void ContainerNode::removedFromTree(bool deep)
{
- EventTargetNode::removedFromTree(deep);
- if (deep) {
- for (Node *child = m_firstChild; child; child = child->nextSibling())
- child->removedFromTree(deep);
- }
+ if (!deep)
+ return;
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->removedFromTree(true);
}
void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -677,13 +679,14 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
if (!o)
break;
}
+ ASSERT(o);
if (!o->isInline() || o->isReplaced()) {
point = o->localToAbsolute();
return true;
}
- if (p->element() && p->element() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
+ if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
// do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
} else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
point = o->container()->localToAbsolute();
@@ -713,9 +716,8 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
if (!renderer())
return false;
- RenderObject *o = renderer();
- if (!o->isInline() || o->isReplaced())
- {
+ RenderObject* o = renderer();
+ if (!o->isInline() || o->isReplaced()) {
RenderBox* box = toRenderBox(o);
point = o->localToAbsolute();
point.move(box->width(), box->height());
@@ -729,8 +731,8 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
else if (o->previousSibling())
o = o->previousSibling();
else {
- RenderObject *prev = 0;
- while(!prev) {
+ RenderObject* prev = 0;
+ while (!prev) {
o = o->parent();
if (!o)
return false;
@@ -738,12 +740,13 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
}
o = prev;
}
+ ASSERT(o);
if (o->isText() || o->isReplaced()) {
point = o->container()->localToAbsolute();
if (o->isText()) {
RenderText* text = toRenderText(o);
IntRect linesBox = text->linesBoundingBox();
- point.move(linesBox.x() + linesBox.width(), linesBox.height());
+ point.move(linesBox.x() + linesBox.width(), linesBox.y() + linesBox.height());
} else {
RenderBox* box = toRenderBox(o);
point.move(box->x() + box->width(), box->y() + box->height());
@@ -762,8 +765,7 @@ IntRect ContainerNode::getRect() const
// If we've found one corner, but not the other,
// then we should just return a point at the corner that we did find.
- if (foundUpperLeft != foundLowerRight)
- {
+ if (foundUpperLeft != foundLowerRight) {
if (foundUpperLeft)
lowerRight = upperLeft;
else
@@ -781,7 +783,7 @@ void ContainerNode::setFocus(bool received)
if (focused() == received)
return;
- EventTargetNode::setFocus(received);
+ Node::setFocus(received);
// note that we need to recalc the style
setChanged();
@@ -791,7 +793,7 @@ void ContainerNode::setActive(bool down, bool pause)
{
if (down == active()) return;
- EventTargetNode::setActive(down);
+ Node::setActive(down);
// note that we need to recalc the style
// FIXME: Move to Element
@@ -834,7 +836,7 @@ void ContainerNode::setHovered(bool over)
{
if (over == hovered()) return;
- EventTargetNode::setHovered(over);
+ Node::setHovered(over);
// note that we need to recalc the style
// FIXME: Move to Element
@@ -876,11 +878,11 @@ static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
else
c->insertedIntoTree(true);
- if (c->parentNode() &&
- doc->hasListenerType(Document::DOMNODEINSERTED_LISTENER) &&
- c->isEventTargetNode()) {
+ doc->incDOMTreeVersion();
+
+ if (c->parentNode() && doc->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) {
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, false,
c->parentNode(), String(), String(), String(), 0), ec);
if (ec)
return;
@@ -889,11 +891,8 @@ static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
// dispatch the DOMNodeInsertedIntoDocument event to all descendants
if (c->inDocument() && doc->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER))
for (; c; c = c->traverseNextNode(child)) {
- if (!c->isEventTargetNode())
- continue;
-
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false, false,
0, String(), String(), String(), 0), ec);
if (ec)
return;
@@ -908,12 +907,12 @@ static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
// update auxiliary doc info (e.g. iterators) to note that node is being removed
doc->nodeWillBeRemoved(child);
+ doc->incDOMTreeVersion();
+
// dispatch pre-removal mutation events
- if (c->parentNode() &&
- doc->hasListenerType(Document::DOMNODEREMOVED_LISTENER) &&
- c->isEventTargetNode()) {
+ if (c->parentNode() && doc->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, false,
c->parentNode(), String(), String(), String(), 0), ec);
if (ec)
return;
@@ -922,10 +921,8 @@ static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
// dispatch the DOMNodeRemovedFromDocument event to all descendants
if (c->inDocument() && doc->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER))
for (; c; c = c->traverseNextNode(child)) {
- if (!c->isEventTargetNode())
- continue;
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false, false,
0, String(), String(), String(), 0), ec);
if (ec)
return;
diff --git a/WebCore/dom/ContainerNode.h b/WebCore/dom/ContainerNode.h
index 91ca49a..3ad932c 100644
--- a/WebCore/dom/ContainerNode.h
+++ b/WebCore/dom/ContainerNode.h
@@ -24,7 +24,7 @@
#ifndef ContainerNode_h
#define ContainerNode_h
-#include "EventTargetNode.h"
+#include "Node.h"
#include "FloatPoint.h"
namespace WebCore {
@@ -36,7 +36,7 @@ namespace Private {
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
};
-class ContainerNode : public EventTargetNode {
+class ContainerNode : public Node {
public:
ContainerNode(Document*, bool isElement = false);
virtual ~ContainerNode();
@@ -75,8 +75,8 @@ public:
protected:
static void queuePostAttachCallback(NodeCallback, Node*);
- static void suspendPostAttachCallbacks();
- static void resumePostAttachCallbacks();
+ void suspendPostAttachCallbacks();
+ void resumePostAttachCallbacks();
template<class GenericNode, class GenericNodeContainer>
friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
@@ -96,7 +96,14 @@ private:
Node* m_firstChild;
Node* m_lastChild;
};
-
+
+inline ContainerNode::ContainerNode(Document* document, bool isElement)
+ : Node(document, isElement, true)
+ , m_firstChild(0)
+ , m_lastChild(0)
+{
+}
+
inline unsigned Node::containerChildNodeCount() const
{
ASSERT(isContainerNode());
diff --git a/WebCore/dom/DOMImplementation.cpp b/WebCore/dom/DOMImplementation.cpp
index 738575f..4f29f96 100644
--- a/WebCore/dom/DOMImplementation.cpp
+++ b/WebCore/dom/DOMImplementation.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "DOMImplementation.h"
+#include "ContentType.h"
#include "CSSStyleSheet.h"
#include "DocumentType.h"
#include "Element.h"
@@ -347,7 +348,7 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame
#if ENABLE(VIDEO)
// Check to see if the type can be played by our MediaPlayer, if so create a MediaDocument
- if (MediaPlayer::supportsType(type))
+ if (MediaPlayer::supportsType(ContentType(type)))
return MediaDocument::create(frame);
#endif
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index a687df8..2e2dd9a 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2008 David Levin (levin@chromium.org)
*
@@ -38,7 +38,6 @@
#include "Console.h"
#include "CookieJar.h"
#include "DOMImplementation.h"
-#include "DOMTimer.h"
#include "DOMWindow.h"
#include "DocLoader.h"
#include "DocumentFragment.h"
@@ -94,6 +93,7 @@
#include "ProgressEvent.h"
#include "RegisteredEventListener.h"
#include "RenderArena.h"
+#include "RenderTextControl.h"
#include "RenderView.h"
#include "RenderWidget.h"
#include "ScriptController.h"
@@ -294,6 +294,17 @@ static bool acceptsEditingFocus(Node *node)
return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
}
+static bool disableRangeMutation(Page* page)
+{
+#if PLATFORM(MAC)
+ // Disable Range mutation on document modifications in Tiger and Leopard Mail
+ // See <rdar://problem/5865171>
+ return page && (page->settings()->needsLeopardMailQuirks() || page->settings()->needsTigerMailQuirks());
+#else
+ return false;
+#endif
+}
+
static HashSet<Document*>* changedDocuments = 0;
Document::Document(Frame* frame, bool isXHTML)
@@ -303,7 +314,6 @@ Document::Document(Frame* frame, bool isXHTML)
, m_frameElementsShouldIgnoreScrolling(false)
, m_title("")
, m_titleSetExplicitly(false)
- , m_imageLoadEventTimer(this, &Document::imageLoadEventTimerFired)
, m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
#if ENABLE(XSLT)
, m_transformSource(0)
@@ -334,9 +344,6 @@ Document::Document(Frame* frame, bool isXHTML)
, m_hasOpenDatabases(false)
#endif
, m_usingGeolocation(false)
-#if USE(LOW_BANDWIDTH_DISPLAY)
- , m_inLowBandwidthDisplay(false)
-#endif
#ifdef ANDROID_MOBILE
, mExtraLayoutDelay(0)
#endif
@@ -555,7 +562,7 @@ PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionC
if (m_isXHTML)
return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, name, xhtmlNamespaceURI), this, 0, false);
- return createElement(QualifiedName(nullAtom, name, nullAtom), false, ec);
+ return createElement(QualifiedName(nullAtom, name, nullAtom), false);
}
PassRefPtr<DocumentFragment> Document::createDocumentFragment()
@@ -772,7 +779,7 @@ bool Document::hasPrefixNamespaceMismatch(const QualifiedName& qName)
}
// FIXME: This should really be in a possible ElementFactory class
-PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser, ExceptionCode& ec)
+PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
{
RefPtr<Element> e;
@@ -790,19 +797,10 @@ PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool cre
if (!e)
e = new Element(qName, document());
-
- // FIXME: The element factories should be fixed to not ignore qName.prefix()
- // Instead they should pass the entire qName into element creation so we don't
- // need to manually set the prefix after creation.
- // Then this code can become ASSERT(qName == e.qname());
- // and Document::createElement can stop taking ExceptionCode& as well.
- if (e && !qName.prefix().isNull()) {
- ec = 0;
- e->setPrefix(qName.prefix(), ec);
- if (ec)
- return 0;
- }
-
+
+ // <image> uses imgTag so we need a special rule.
+ ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName());
+
return e.release();
}
@@ -818,7 +816,7 @@ PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const
return 0;
}
- return createElement(qName, false, ec);
+ return createElement(qName, false);
}
Element* Document::getElementById(const AtomicString& elementId) const
@@ -861,7 +859,7 @@ String Document::readyState() const
return String();
}
-String Document::inputEncoding() const
+String Document::encoding() const
{
if (TextResourceDecoder* d = decoder())
return d->encoding().name();
@@ -920,8 +918,12 @@ Element* Document::elementFromPoint(int x, int y) const
if (!renderer())
return 0;
- HitTestRequest request(true, true);
- HitTestResult result(IntPoint(x, y));
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active);
+
+ float zoomFactor = frame() ? frame()->pageZoomFactor() : 1.0f;
+
+ HitTestResult result(roundedIntPoint(FloatPoint(x * zoomFactor, y * zoomFactor)));
renderView()->layer()->hitTest(request, result);
Node* n = result.innerNode();
@@ -999,9 +1001,8 @@ void Document::setTitle(const String& title, Element* titleElement)
m_titleElement = 0;
else if (!m_titleElement) {
if (HTMLElement* headElement = head()) {
+ m_titleElement = createElement(titleTag, false);
ExceptionCode ec = 0;
- m_titleElement = createElement("title", ec);
- ASSERT(!ec);
headElement->appendChild(m_titleElement, ec);
ASSERT(!ec);
}
@@ -1120,8 +1121,8 @@ void Document::setDocumentChanged(bool b)
void Document::recalcStyle(StyleChange change)
{
// we should not enter style recalc while painting
- if (frame() && frame()->view() && frame()->view()->isPainting()) {
- ASSERT(!frame()->view()->isPainting());
+ if (view() && view()->isPainting()) {
+ ASSERT(!view()->isPainting());
return;
}
@@ -1130,6 +1131,8 @@ void Document::recalcStyle(StyleChange change)
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
+ if (view())
+ view()->pauseScheduledEvents();
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::CalculateStyleTimeCounter);
@@ -1172,8 +1175,6 @@ void Document::recalcStyle(StyleChange change)
StyleChange ch = diff(documentStyle.get(), renderer()->style());
if (renderer() && ch != NoChange)
renderer()->setStyle(documentStyle.release());
- if (change != Force)
- change = ch;
}
for (Node* n = firstChild(); n; n = n->nextSibling())
@@ -1184,17 +1185,27 @@ void Document::recalcStyle(StyleChange change)
android::TimeCounter::record(android::TimeCounter::CalculateStyleTimeCounter, __FUNCTION__);
#endif
- if (changed() && view())
- view()->layout();
+ if (view()) {
+ if (changed())
+ view()->layout();
+#if USE(ACCELERATED_COMPOSITING)
+ else {
+ // If we didn't update compositing layers because of layout(), we need to do so here.
+ view()->updateCompositingLayers();
+ }
+#endif
+ }
bail_out:
setChanged(NoStyleChange);
setHasChangedChild(false);
setDocumentChanged(false);
-
+
+ if (view())
+ view()->resumeScheduledEvents();
resumePostAttachCallbacks();
m_inStyleRecalc = false;
-
+
// If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
if (m_closeAfterStyleRecalc) {
m_closeAfterStyleRecalc = false;
@@ -1237,7 +1248,6 @@ void Document::updateLayout()
if (Element* oe = ownerElement())
oe->document()->updateLayout();
- // FIXME: Dave Hyatt's pretty sure we can remove this because layout calls recalcStyle as needed.
updateRendering();
// Only do a layout if changes have occurred that make it necessary.
@@ -1290,6 +1300,9 @@ void Document::attach()
// Create the rendering tree
setRenderer(new (m_renderArena) RenderView(this, view()));
+#if USE(ACCELERATED_COMPOSITING)
+ renderView()->didMoveOnscreen();
+#endif
if (!m_styleSelector) {
bool matchAuthorAndUserStyles = true;
@@ -1318,15 +1331,13 @@ void Document::detach()
RenderObject* render = renderer();
+ // Send out documentWillBecomeInactive() notifications to registered elements,
+ // in order to stop media elements
+ documentWillBecomeInactive();
+
// indicate destruction mode, i.e. attached() but renderer == 0
setRenderer(0);
-
- // Empty out these lists as a performance optimization, since detaching
- // all the individual render objects will cause all the RenderImage
- // objects to remove themselves from the lists.
- m_imageLoadEventDispatchSoonList.clear();
- m_imageLoadEventDispatchingList.clear();
-
+
m_hoverNode = 0;
m_focusedNode = 0;
m_activeNode = 0;
@@ -1360,11 +1371,8 @@ void Document::removeAllEventListenersFromAllNodes()
m_windowEventListeners[i]->setRemoved(true);
m_windowEventListeners.clear();
removeAllDisconnectedNodeEventListeners();
- for (Node *n = this; n; n = n->traverseNextNode()) {
- if (!n->isEventTargetNode())
- continue;
- EventTargetNodeCast(n)->removeAllEventListeners();
- }
+ for (Node* node = this; node; node = node->traverseNextNode())
+ node->removeAllEventListeners();
}
void Document::registerDisconnectedNodeWithEventListeners(Node* node)
@@ -1381,13 +1389,13 @@ void Document::removeAllDisconnectedNodeEventListeners()
{
HashSet<Node*>::iterator end = m_disconnectedNodesWithEventListeners.end();
for (HashSet<Node*>::iterator i = m_disconnectedNodesWithEventListeners.begin(); i != end; ++i)
- EventTargetNodeCast(*i)->removeAllEventListeners();
+ (*i)->removeAllEventListeners();
m_disconnectedNodesWithEventListeners.clear();
}
RenderView* Document::renderView() const
{
- return static_cast<RenderView*>(renderer());
+ return toRenderView(renderer());
}
void Document::clearAXObjectCache()
@@ -1499,7 +1507,7 @@ void Document::implicitOpen()
setParsing(true);
}
-HTMLElement* Document::body()
+HTMLElement* Document::body() const
{
Node* de = documentElement();
if (!de)
@@ -1609,8 +1617,8 @@ void Document::implicitClose()
if (f)
f->animation()->resumeAnimations(this);
- dispatchImageLoadEventsNow();
- this->dispatchWindowEvent(eventNames().loadEvent, false, false);
+ ImageLoader::dispatchPendingLoadEvents();
+ dispatchWindowEvent(eventNames().loadEvent, false, false);
if (f)
f->loader()->handledOnloadEvents();
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -1692,8 +1700,8 @@ bool Document::shouldScheduleLayout()
// (a) Only schedule a layout once the stylesheets are loaded.
// (b) Only schedule layout once we have a body element.
- return haveStylesheetsLoaded()
- && body() || (documentElement() && !documentElement()->hasTagName(htmlTag));
+ return (haveStylesheetsLoaded() && body()) ||
+ (documentElement() && !documentElement()->hasTagName(htmlTag));
}
int Document::minimumLayoutDelay()
@@ -1713,28 +1721,30 @@ int Document::elapsedTime() const
return static_cast<int>((currentTime() - m_startTime) * 1000);
}
-void Document::write(const String& text, Document* ownerDocument)
+void Document::write(const SegmentedString& text, Document* ownerDocument)
{
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!ownerElement())
printf("Beginning a document.write at %d\n", elapsedTime());
#endif
-
- if (!m_tokenizer) {
+
+ if (!m_tokenizer)
open(ownerDocument);
- ASSERT(m_tokenizer);
- if (!m_tokenizer)
- return;
- write("<html>", ownerDocument);
- }
+
+ ASSERT(m_tokenizer);
m_tokenizer->write(text, false);
-
+
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!ownerElement())
printf("Ending a document.write at %d\n", elapsedTime());
#endif
}
+void Document::write(const String& text, Document* ownerDocument)
+{
+ write(SegmentedString(text), ownerDocument);
+}
+
void Document::writeln(const String& text, Document* ownerDocument)
{
write(text, ownerDocument);
@@ -1817,6 +1827,11 @@ void Document::updateBaseURL()
m_mappedElementSheet->setHref(m_baseURL.string());
}
+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)
{
m_sheet = CSSStyleSheet::create(this, url, charset);
@@ -2097,7 +2112,7 @@ MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
HitTestResult result(documentPoint);
renderView()->layer()->hitTest(request, result);
- if (!request.readonly)
+ if (!request.readOnly())
updateRendering();
return MouseEventWithHitTestResults(event, result);
@@ -2553,21 +2568,23 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
// Dispatch a change event for text fields or textareas that have been edited
RenderObject* r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer());
- if (r && (r->isTextArea() || r->isTextField()) && r->isEdited()) {
- EventTargetNodeCast(oldFocusedNode.get())->dispatchEventForType(eventNames().changeEvent, true, false);
- if ((r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer())))
- r->setEdited(false);
+ if (r && r->isTextControl() && toRenderTextControl(r)->isEdited()) {
+ oldFocusedNode->dispatchEventForType(eventNames().changeEvent, true, false);
+ if ((r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer()))) {
+ if (r->isTextControl())
+ toRenderTextControl(r)->setEdited(false);
+ }
}
// Dispatch the blur event and let the node do any other blur related activities (important for text fields)
- EventTargetNodeCast(oldFocusedNode.get())->dispatchBlurEvent();
+ oldFocusedNode->dispatchBlurEvent();
if (m_focusedNode) {
// handler shifted focus
focusChangeBlocked = true;
newFocusedNode = 0;
}
- EventTargetNodeCast(oldFocusedNode.get())->dispatchUIEvent(eventNames().DOMFocusOutEvent);
+ oldFocusedNode->dispatchUIEvent(eventNames().DOMFocusOutEvent);
if (m_focusedNode) {
// handler shifted focus
focusChangeBlocked = true;
@@ -2590,14 +2607,14 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
m_focusedNode = newFocusedNode.get();
// Dispatch the focus event and let the node do any other focus related activities (important for text fields)
- EventTargetNodeCast(m_focusedNode.get())->dispatchFocusEvent();
+ m_focusedNode->dispatchFocusEvent();
if (m_focusedNode != newFocusedNode) {
// handler shifted focus
focusChangeBlocked = true;
goto SetFocusedNodeDone;
}
- EventTargetNodeCast(m_focusedNode.get())->dispatchUIEvent(eventNames().DOMFocusInEvent);
+ m_focusedNode->dispatchUIEvent(eventNames().DOMFocusInEvent);
if (m_focusedNode != newFocusedNode) {
// handler shifted focus
focusChangeBlocked = true;
@@ -2637,7 +2654,7 @@ SetFocusedNodeDone:
return !focusChangeBlocked;
}
-void Document::setCSSTarget(Node* n)
+void Document::setCSSTarget(Element* n)
{
if (m_cssTarget)
m_cssTarget->setChanged();
@@ -2646,11 +2663,6 @@ void Document::setCSSTarget(Node* n)
n->setChanged();
}
-Node* Document::getCSSTarget() const
-{
- return m_cssTarget;
-}
-
void Document::attachNodeIterator(NodeIterator *ni)
{
m_nodeIterators.add(ni);
@@ -2663,7 +2675,7 @@ void Document::detachNodeIterator(NodeIterator *ni)
void Document::nodeChildrenChanged(ContainerNode* container)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenChanged(container);
@@ -2676,7 +2688,7 @@ void Document::nodeWillBeRemoved(Node* n)
for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
(*it)->nodeWillBeRemoved(n);
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
(*it)->nodeWillBeRemoved(n);
@@ -2690,7 +2702,7 @@ void Document::nodeWillBeRemoved(Node* n)
void Document::textInserted(Node* text, unsigned offset, unsigned length)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textInserted(text, offset, length);
@@ -2702,7 +2714,7 @@ void Document::textInserted(Node* text, unsigned offset, unsigned length)
void Document::textRemoved(Node* text, unsigned offset, unsigned length)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textRemoved(text, offset, length);
@@ -2715,7 +2727,7 @@ void Document::textRemoved(Node* text, unsigned offset, unsigned length)
void Document::textNodesMerged(Text* oldNode, unsigned offset)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
NodeWithIndex oldNodeWithIndex(oldNode);
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
@@ -2727,7 +2739,7 @@ void Document::textNodesMerged(Text* oldNode, unsigned offset)
void Document::textNodeSplit(Text* oldNode)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textNodeSplit(oldNode);
@@ -2956,66 +2968,6 @@ void Document::setWindowInlineEventListenerForTypeAndAttribute(const AtomicStrin
setWindowInlineEventListenerForType(eventType, createEventListener(attr->localName().string(), attr->value(), 0));
}
-void Document::dispatchImageLoadEventSoon(ImageLoader* image)
-{
- m_imageLoadEventDispatchSoonList.append(image);
- if (!m_imageLoadEventTimer.isActive())
- m_imageLoadEventTimer.startOneShot(0);
-}
-
-void Document::removeImage(ImageLoader* image)
-{
- // Remove instances of this image from both lists.
- // Use loops because we allow multiple instances to get into the lists.
- size_t size = m_imageLoadEventDispatchSoonList.size();
- for (size_t i = 0; i < size; ++i) {
- if (m_imageLoadEventDispatchSoonList[i] == image)
- m_imageLoadEventDispatchSoonList[i] = 0;
- }
- size = m_imageLoadEventDispatchingList.size();
- for (size_t i = 0; i < size; ++i) {
- if (m_imageLoadEventDispatchingList[i] == image)
- m_imageLoadEventDispatchingList[i] = 0;
- }
- if (m_imageLoadEventDispatchSoonList.isEmpty())
- m_imageLoadEventTimer.stop();
-}
-
-void Document::dispatchImageLoadEventsNow()
-{
- // Need to avoid re-entering this function; if new dispatches are
- // scheduled before the parent finishes processing the list, they
- // will set a timer and eventually be processed.
- if (!m_imageLoadEventDispatchingList.isEmpty())
- return;
-#ifdef BUILDING_ON_LEOPARD
- bool shouldReenableMemoryCacheClientCalls = false;
- if (settings() && settings()->needsIChatMemoryCacheCallsQuirk() && page()->areMemoryCacheClientCallsEnabled()) {
- shouldReenableMemoryCacheClientCalls = true;
- page()->setMemoryCacheClientCallsEnabled(false);
- }
-#endif
- m_imageLoadEventTimer.stop();
-
- m_imageLoadEventDispatchingList = m_imageLoadEventDispatchSoonList;
- m_imageLoadEventDispatchSoonList.clear();
- size_t size = m_imageLoadEventDispatchingList.size();
- for (size_t i = 0; i < size; ++i) {
- if (ImageLoader* image = m_imageLoadEventDispatchingList[i])
- image->dispatchLoadEvent();
- }
- m_imageLoadEventDispatchingList.clear();
-#ifdef BUILDING_ON_LEOPARD
- if (shouldReenableMemoryCacheClientCalls && page())
- page()->setMemoryCacheClientCallsEnabled(true);
-#endif
-}
-
-void Document::imageLoadEventTimerFired(Timer<Document>*)
-{
- dispatchImageLoadEventsNow();
-}
-
Element* Document::ownerElement() const
{
if (!frame())
@@ -3262,9 +3214,10 @@ KURL Document::completeURL(const String& url) const
// See also [CSS]StyleSheet::completeURL(const String&)
if (url.isNull())
return KURL();
+ const KURL& baseURL = ((m_baseURL.isEmpty() || m_baseURL == blankURL()) && parentDocument()) ? parentDocument()->baseURL() : m_baseURL;
if (!m_decoder)
- return KURL(m_baseURL, url);
- return KURL(m_baseURL, url, m_decoder->encoding());
+ return KURL(baseURL, url);
+ return KURL(baseURL, url, m_decoder->encoding());
}
void Document::setInPageCache(bool flag)
@@ -3288,6 +3241,11 @@ void Document::setInPageCache(bool flag)
void Document::documentWillBecomeInactive()
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (renderer())
+ renderView()->willMoveOffscreen();
+#endif
+
HashSet<Element*>::iterator end = m_documentActivationCallbackElements.end();
for (HashSet<Element*>::iterator i = m_documentActivationCallbackElements.begin(); i != end; ++i)
(*i)->documentWillBecomeInactive();
@@ -3298,6 +3256,11 @@ void Document::documentDidBecomeActive()
HashSet<Element*>::iterator end = m_documentActivationCallbackElements.end();
for (HashSet<Element*>::iterator i = m_documentActivationCallbackElements.begin(); i != end; ++i)
(*i)->documentDidBecomeActive();
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (renderer())
+ renderView()->didMoveOnscreen();
+#endif
}
void Document::registerForDocumentActivationCallbacks(Element* e)
@@ -4005,7 +3968,7 @@ void Document::finishedParsing()
Vector<String> Document::formElementsState() const
{
Vector<String> stateVector;
- stateVector.reserveCapacity(m_formElementsWithState.size() * 3);
+ stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 3);
typedef ListHashSet<FormControlElementWithState*>::const_iterator Iterator;
Iterator end = m_formElementsWithState.end();
for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
@@ -4225,6 +4188,20 @@ void Document::initSecurityContext()
securityOrigin()->grantLoadLocalResources();
}
+ if (Settings* settings = this->settings()) {
+ if (!settings->isWebSecurityEnabled()) {
+ // Web security is turned off. We should let this document access every
+ // other document. This is used primary by testing harnesses for web
+ // sites.
+ securityOrigin()->grantUniversalAccess();
+
+ } else if (settings->allowUniversalAccessFromFileURLs() && securityOrigin()->isLocal()) {
+ // Some clients want file:// URLs to have universal access, but that
+ // setting is dangerous for other clients.
+ securityOrigin()->grantUniversalAccess();
+ }
+ }
+
if (!securityOrigin()->isEmpty())
return;
@@ -4235,7 +4212,7 @@ void Document::initSecurityContext()
if (!ownerFrame)
ownerFrame = m_frame->loader()->opener();
- if (ownerFrame && ownerFrame->document()) {
+ if (ownerFrame) {
m_cookieURL = ownerFrame->document()->cookieURL();
// We alias the SecurityOrigins to match Firefox, see Bug 15313
// https://bugs.webkit.org/show_bug.cgi?id=15313
@@ -4428,22 +4405,6 @@ void Document::removeTouchEventListener(Node* node)
#endif
-void Document::addTimeout(int timeoutId, DOMTimer* timer)
-{
- ASSERT(!m_timeouts.contains(timeoutId));
- m_timeouts.set(timeoutId, timer);
-}
-
-void Document::removeTimeout(int timeoutId)
-{
- m_timeouts.remove(timeoutId);
-}
-
-DOMTimer* Document::findTimeout(int timeoutId)
-{
- return m_timeouts.get(timeoutId);
-}
-
void Document::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
{
if (DOMWindow* window = domWindow())
@@ -4471,6 +4432,12 @@ void Document::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const
page()->inspectorController()->resourceRetrievedByXMLHttpRequest(identifier, sourceString);
}
+void Document::scriptImported(unsigned long identifier, const String& sourceString)
+{
+ if (page())
+ page()->inspectorController()->scriptImported(identifier, sourceString);
+}
+
class ScriptExecutionContextTaskTimer : public TimerBase {
public:
ScriptExecutionContextTaskTimer(PassRefPtr<Document> context, PassRefPtr<ScriptExecutionContext::Task> task)
@@ -4541,4 +4508,24 @@ Element* Document::findAnchor(const String& name)
return 0;
}
+String Document::displayStringModifiedByEncoding(const String& str) const
+{
+ if (m_decoder)
+ return m_decoder->encoding().displayString(str.impl());
+ return str;
+}
+
+PassRefPtr<StringImpl> Document::displayStringModifiedByEncoding(PassRefPtr<StringImpl> str) const
+{
+ if (m_decoder)
+ return m_decoder->encoding().displayString(str);
+ return str;
+}
+
+void Document::displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const
+{
+ if (m_decoder)
+ m_decoder->encoding().displayBuffer(buffer, len);
+}
+
} // namespace WebCore
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index ce8116d..3d232ec 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -33,7 +33,6 @@
#include "HTMLFormElement.h"
#include "ScriptExecutionContext.h"
#include "StringHash.h"
-#include "TextResourceDecoder.h"
#include "Timer.h"
#include <wtf/HashCountedSet.h>
#include <wtf/ListHashSet.h>
@@ -63,7 +62,6 @@ namespace WebCore {
class Database;
class DOMImplementation;
class DOMSelection;
- class DOMTimer;
class DOMWindow;
class DatabaseThread;
class DocLoader;
@@ -77,6 +75,7 @@ namespace WebCore {
class FormControlElementWithState;
class Frame;
class FrameView;
+ class HitTestRequest;
class HTMLCanvasElement;
class HTMLDocument;
class HTMLElement;
@@ -84,7 +83,6 @@ namespace WebCore {
class HTMLHeadElement;
class HTMLInputElement;
class HTMLMapElement;
- class ImageLoader;
class IntPoint;
class JSNode;
class MouseEventWithHitTestResults;
@@ -98,6 +96,7 @@ namespace WebCore {
class RenderArena;
class RenderView;
class SecurityOrigin;
+ class SegmentedString;
class Settings;
class StyleSheet;
class StyleSheetList;
@@ -125,7 +124,6 @@ namespace WebCore {
#if ENABLE(DASHBOARD_SUPPORT)
struct DashboardRegionValue;
#endif
- struct HitTestRequest;
typedef int ExceptionCode;
@@ -235,18 +233,20 @@ public:
PassRefPtr<EntityReference> createEntityReference(const String& name, ExceptionCode&);
PassRefPtr<Node> importNode(Node* importedNode, bool deep, ExceptionCode&);
virtual PassRefPtr<Element> createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&);
- PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser, ExceptionCode& ec);
+ PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser);
Element* getElementById(const AtomicString&) const;
bool hasElementWithId(AtomicStringImpl* id) const;
bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); }
Element* elementFromPoint(int x, int y) const;
String readyState() const;
- String inputEncoding() const;
- String defaultCharset() const;
- String charset() const { return inputEncoding(); }
- String characterSet() const { return inputEncoding(); }
+ String defaultCharset() const;
+
+ // Synonyms backing similar DOM attributes. Use Document::encoding() to avoid virtual dispatch.
+ String inputEncoding() const { return Document::encoding(); }
+ String charset() const { return Document::encoding(); }
+ String characterSet() const { return Document::encoding(); }
void setCharset(const String&);
@@ -314,6 +314,7 @@ public:
#if ENABLE(WML)
virtual bool isWMLDocument() const { return false; }
#endif
+ virtual bool isFrameSet() const { return false; }
CSSStyleSelector* styleSelector() const { return m_styleSelector; }
@@ -330,11 +331,7 @@ public:
*/
bool haveStylesheetsLoaded() const
{
- return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets
-#if USE(LOW_BANDWIDTH_DISPLAY)
- || m_inLowBandwidthDisplay
-#endif
- ;
+ return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets;
}
/**
@@ -426,6 +423,7 @@ public:
void implicitClose();
void cancelParsing();
+ void write(const SegmentedString& text, Document* ownerDocument = 0);
void write(const String& text, Document* ownerDocument = 0);
void writeln(const String& text, Document* ownerDocument = 0);
void finishParsing();
@@ -446,6 +444,8 @@ public:
KURL completeURL(const String&) const;
+ virtual String userAgent(const KURL&) const;
+
// from cachedObjectClient
virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
@@ -532,8 +532,8 @@ public:
void activeChainNodeDetached(Node*);
// Updates for :target (CSS3 selector).
- void setCSSTarget(Node*);
- Node* getCSSTarget() const;
+ void setCSSTarget(Element*);
+ Element* cssTarget() const { return m_cssTarget; }
void setDocumentChanged(bool);
@@ -644,11 +644,7 @@ public:
*/
void processMetadataSettings(const String& content);
#endif
-
- void dispatchImageLoadEventSoon(ImageLoader*);
- void dispatchImageLoadEventsNow();
- void removeImage(ImageLoader*);
-
+
// Returns the owning element in the parent document.
// Returns 0 if this is the top level document.
Element* ownerElement() const;
@@ -692,7 +688,7 @@ public:
void removeImageMap(HTMLMapElement*);
HTMLMapElement* getImageMap(const String& url) const;
- HTMLElement* body();
+ HTMLElement* body() const;
void setBody(PassRefPtr<HTMLElement>, ExceptionCode&);
HTMLHeadElement* head();
@@ -776,13 +772,7 @@ public:
void setUseSecureKeyboardEntryWhenActive(bool);
bool useSecureKeyboardEntryWhenActive() const;
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- void setDocLoader(DocLoader* loader) { m_docLoader = loader; }
- bool inLowBandwidthDisplay() const { return m_inLowBandwidthDisplay; }
- void setLowBandwidthDisplay(bool lowBandWidth) { m_inLowBandwidthDisplay = lowBandWidth; }
-#endif
-
+
void addNodeListCache() { ++m_numNodeListCaches; }
void removeNodeListCache() { ASSERT(m_numNodeListCaches > 0); --m_numNodeListCaches; }
bool hasNodeListCaches() const { return m_numNodeListCaches; }
@@ -809,12 +799,9 @@ public:
virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString);
+ virtual void scriptImported(unsigned long, const String&);
virtual void postTask(PassRefPtr<Task>); // Executes the task on context's thread asynchronously.
- void addTimeout(int timeoutId, DOMTimer*);
- void removeTimeout(int timeoutId);
- DOMTimer* findTimeout(int timeoutId);
-
protected:
Document(Frame*, bool isXHTML);
@@ -837,6 +824,8 @@ private:
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.
+ String encoding() const;
+
CSSStyleSelector* m_styleSelector;
bool m_didCalculateStyleSelector;
@@ -953,13 +942,9 @@ private:
mutable AXObjectCache* m_axObjectCache;
- Vector<ImageLoader*> m_imageLoadEventDispatchSoonList;
- Vector<ImageLoader*> m_imageLoadEventDispatchingList;
- Timer<Document> m_imageLoadEventTimer;
-
Timer<Document> m_updateFocusAppearanceTimer;
- Node* m_cssTarget;
+ Element* m_cssTarget;
bool m_processingLoadEvent;
double m_startTime;
@@ -1008,20 +993,9 @@ public:
void setDecoder(PassRefPtr<TextResourceDecoder>);
TextResourceDecoder* decoder() const { return m_decoder.get(); }
- String displayStringModifiedByEncoding(const String& str) const {
- if (m_decoder)
- return m_decoder->encoding().displayString(str.impl());
- return str;
- }
- PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl> str) const {
- if (m_decoder)
- return m_decoder->encoding().displayString(str);
- return str;
- }
- void displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const {
- if (m_decoder)
- m_decoder->encoding().displayBuffer(buffer, len);
- }
+ 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; }
@@ -1079,7 +1053,6 @@ protected:
private:
void updateTitle();
void removeAllDisconnectedNodeEventListeners();
- void imageLoadEventTimerFired(Timer<Document>*);
void updateFocusAppearanceTimerFired(Timer<Document>*);
void updateBaseURL();
@@ -1152,16 +1125,9 @@ private:
#endif
bool m_usingGeolocation;
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- bool m_inLowBandwidthDisplay;
-#endif
#ifdef ANDROID_MOBILE
int mExtraLayoutDelay;
#endif
-
- typedef HashMap<int, DOMTimer*> TimeoutsMap;
- TimeoutsMap m_timeouts;
};
inline bool Document::hasElementWithId(AtomicStringImpl* id) const
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index dfdfe46..3543cc7 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -28,11 +28,11 @@ module core {
InlineGetOwnPropertySlot,
InterfaceUUID=48BB95FC-2D08-4c54-BE65-7558736A4CAE,
ImplementationUUID=FF5CBE81-F817-429c-A6C2-0CCCD2328062
- ] Document : EventTargetNode {
+ ] Document : Node {
// DOM Level 1 Core
readonly attribute DocumentType doctype;
- readonly attribute DOMImplementation implementation;
+ readonly attribute [V8Custom] DOMImplementation implementation;
readonly attribute Element documentElement;
[ReturnsNew] Element createElement(in [ConvertNullToNullString] DOMString tagName)
@@ -122,11 +122,11 @@ module core {
in XPathNSResolver resolver)
raises(DOMException);
XPathNSResolver createNSResolver(in Node nodeResolver);
- [OldStyleObjC] XPathResult evaluate(in DOMString expression,
- in Node contextNode,
- in XPathNSResolver resolver,
- in unsigned short type,
- in XPathResult inResult)
+ [OldStyleObjC, V8Custom] XPathResult evaluate(in DOMString expression,
+ in Node contextNode,
+ in XPathNSResolver resolver,
+ in unsigned short type,
+ in XPathResult inResult)
raises(DOMException);
#endif // ENABLE_XPATH
#endif // !defined(LANGUAGE_COM)
@@ -226,7 +226,7 @@ module core {
#if !defined(LANGUAGE_COM)
#if !defined(LANGUAGE_OBJECTIVE_C)
- DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
+ [V8Custom] DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
#endif
#endif
@@ -234,9 +234,9 @@ module core {
NodeList getElementsByClassName(in DOMString tagname);
// NodeSelector - Selector API
- Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ Element querySelector(in DOMString selectors)
raises(DOMException);
- NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ NodeList querySelectorAll(in DOMString selectors)
raises(DOMException);
#if ENABLE_WML
diff --git a/WebCore/dom/DocumentFragment.idl b/WebCore/dom/DocumentFragment.idl
index 2cdcdf8..ff6232f 100644
--- a/WebCore/dom/DocumentFragment.idl
+++ b/WebCore/dom/DocumentFragment.idl
@@ -23,12 +23,11 @@ module core {
GenerateConstructor,
InterfaceUUID=F5C8DAF0-D728-4b2b-9D9C-630621B07D35,
ImplementationUUID=E57BF71F-3FAA-495c-A307-E288F8E5B2EC
- ] DocumentFragment : EventTargetNode {
+ ] DocumentFragment : Node {
// NodeSelector - Selector API
- // FIXME: add support for NSResolver in languages other than JS
- Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ Element querySelector(in DOMString selectors)
raises(DOMException);
- NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ NodeList querySelectorAll(in DOMString selectors)
raises(DOMException);
};
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 781179d..dbec884 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -29,6 +29,8 @@
#include "AXObjectCache.h"
#include "CSSStyleSelector.h"
#include "CString.h"
+#include "ClientRect.h"
+#include "ClientRectList.h"
#include "Document.h"
#include "Editor.h"
#include "ElementRareData.h"
@@ -44,6 +46,9 @@
#include "Page.h"
#include "PlatformString.h"
#include "RenderBlock.h"
+#if ENABLE(SVG)
+#include "SVGNames.h"
+#endif
#include "SelectionController.h"
#include "TextIterator.h"
#include "XMLNames.h"
@@ -83,27 +88,32 @@ NodeRareData* Element::createRareData()
PassRefPtr<Node> Element::cloneNode(bool deep)
{
- ExceptionCode ec = 0;
- RefPtr<Element> clone = document()->createElementNS(namespaceURI(), nodeName(), ec);
- ASSERT(!ec);
-
- // clone attributes
+ return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
+}
+
+PassRefPtr<Element> Element::cloneElementWithChildren()
+{
+ RefPtr<Element> clone = cloneElementWithoutChildren();
+ cloneChildNodes(clone.get());
+ return clone.release();
+}
+
+PassRefPtr<Element> Element::cloneElementWithoutChildren()
+{
+ RefPtr<Element> clone = document()->createElement(tagQName(), false);
+ // This will catch HTML elements in the wrong namespace that are not correctly copied.
+ // This is a sanity check as HTML overloads some of the DOM methods.
+ ASSERT(isHTMLElement() == clone->isHTMLElement());
+
+ // Clone attributes.
if (namedAttrMap)
clone->attributes()->setAttributes(*namedAttrMap);
clone->copyNonAttributeProperties(this);
- if (deep)
- cloneChildNodes(clone.get());
-
return clone.release();
}
-PassRefPtr<Element> Element::cloneElement()
-{
- return static_pointer_cast<Element>(cloneNode(false));
-}
-
void Element::removeAttribute(const QualifiedName& name, ExceptionCode& ec)
{
if (namedAttrMap) {
@@ -189,9 +199,9 @@ void Element::scrollIntoView(bool alignToTop)
if (renderer()) {
// Align to the top / bottom and to the closest edge.
if (alignToTop)
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
else
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignBottomAlways);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
}
}
@@ -201,9 +211,9 @@ void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
IntRect bounds = getRect();
if (renderer()) {
if (centerIfNeeded)
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignCenterIfNeeded, RenderLayer::gAlignCenterIfNeeded);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
else
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
}
}
@@ -274,7 +284,7 @@ static int adjustForAbsoluteZoom(int value, RenderObject* renderer)
int Element::offsetLeft()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForLocalZoom(rend->offsetLeft(), rend);
return 0;
}
@@ -282,7 +292,7 @@ int Element::offsetLeft()
int Element::offsetTop()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForLocalZoom(rend->offsetTop(), rend);
return 0;
}
@@ -290,7 +300,7 @@ int Element::offsetTop()
int Element::offsetWidth()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForAbsoluteZoom(rend->offsetWidth(), rend);
return 0;
}
@@ -298,7 +308,7 @@ int Element::offsetWidth()
int Element::offsetHeight()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForAbsoluteZoom(rend->offsetHeight(), rend);
return 0;
}
@@ -306,9 +316,9 @@ int Element::offsetHeight()
Element* Element::offsetParent()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderObject* rend = renderer())
if (RenderObject* offsetParent = rend->offsetParent())
- return static_cast<Element*>(offsetParent->element());
+ return static_cast<Element*>(offsetParent->node());
return 0;
}
@@ -340,14 +350,11 @@ int Element::clientWidth()
if ((!inCompatMode && document()->documentElement() == this) ||
(inCompatMode && isHTMLElement() && document()->body() == this)) {
if (FrameView* view = document()->view())
- return view->layoutWidth();
+ return adjustForAbsoluteZoom(view->layoutWidth(), document()->renderer());
}
-
- if (RenderBox* rend = renderBox()) {
- if (!rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->clientWidth(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->clientWidth(), rend);
return 0;
}
@@ -362,13 +369,11 @@ int Element::clientHeight()
if ((!inCompatMode && document()->documentElement() == this) ||
(inCompatMode && isHTMLElement() && document()->body() == this)) {
if (FrameView* view = document()->view())
- return view->layoutHeight();
+ return adjustForAbsoluteZoom(view->layoutHeight(), document()->renderer());
}
- if (RenderBox* rend = renderBox()) {
- if (!rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->clientHeight(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->clientHeight(), rend);
return 0;
}
@@ -405,23 +410,67 @@ void Element::setScrollTop(int newTop)
int Element::scrollWidth()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox()) {
- if (rend->hasOverflowClip() || !rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
return 0;
}
int Element::scrollHeight()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox()) {
- if (rend->hasOverflowClip() || !rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
return 0;
}
+PassRefPtr<ClientRectList> Element::getClientRects() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+
+ RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
+ if (!renderBoxModelObject)
+ return ClientRectList::create();
+
+ // FIXME: Handle SVG elements.
+ // FIXME: Handle table/inline-table with a caption.
+
+ Vector<FloatQuad> quads;
+ renderBoxModelObject->absoluteQuads(quads);
+
+ if (FrameView* view = document()->view()) {
+ IntRect visibleContentRect = view->visibleContentRect();
+ for (size_t i = 0; i < quads.size(); ++i)
+ quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
+ }
+
+ return ClientRectList::create(quads);
+}
+
+PassRefPtr<ClientRect> Element::getBoundingClientRect() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+ RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
+ if (!renderBoxModelObject)
+ return ClientRect::create();
+
+ Vector<FloatQuad> quads;
+ renderBoxModelObject->absoluteQuads(quads);
+
+ if (quads.isEmpty())
+ return ClientRect::create();
+
+ IntRect result = quads[0].enclosingBoundingBox();
+ for (size_t i = 1; i < quads.size(); ++i)
+ result.unite(quads[i].enclosingBoundingBox());
+
+ if (FrameView* view = document()->view()) {
+ IntRect visibleContentRect = view->visibleContentRect();
+ result.move(-visibleContentRect.x(), -visibleContentRect.y());
+ }
+
+ return ClientRect::create(result);
+}
+
static inline bool shouldIgnoreAttributeCase(const Element* e)
{
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
@@ -1105,18 +1154,17 @@ void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
return;
// FIXME: We should restore the previous selection if there is one.
- Selection newSelection = hasTagName(htmlTag) || hasTagName(bodyTag) ? Selection(Position(this, 0), DOWNSTREAM) : Selection::selectionFromContentsOfNode(this);
+ VisibleSelection newSelection = hasTagName(htmlTag) || hasTagName(bodyTag) ? VisibleSelection(Position(this, 0), DOWNSTREAM) : VisibleSelection::selectionFromContentsOfNode(this);
if (frame->shouldChangeSelection(newSelection)) {
frame->selection()->setSelection(newSelection);
frame->revealSelection();
}
-#ifdef ANDROID_SCROLL_FIX
- // We handle the scrolling the screen with our navigation code,
- // so ignore this call to put the rectangle on screen.
}
-#else
- } else if (renderer() && !renderer()->isWidget())
+ // FIXME: I'm not sure all devices will want this off, but this is
+ // currently turned off for Andriod.
+#if !ENABLE(DIRECTIONAL_PAD_NAVIGATION)
+ else if (renderer() && !renderer()->isWidget())
renderer()->enclosingLayer()->scrollRectToVisible(getRect());
#endif
}
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index e9bab28..b9b391a 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -36,6 +36,8 @@ class Attribute;
class CSSStyleDeclaration;
class ElementRareData;
class IntSize;
+class ClientRect;
+class ClientRectList;
class Element : public ContainerNode {
public:
@@ -82,6 +84,9 @@ public:
int scrollWidth();
int scrollHeight();
+ PassRefPtr<ClientRectList> getClientRects() const;
+ PassRefPtr<ClientRect> getBoundingClientRect() const;
+
void removeAttribute(const String& name, ExceptionCode&);
void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
@@ -110,20 +115,18 @@ public:
// DOM methods overridden from parent classes
virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep);
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> cloneElement();
+ PassRefPtr<Element> cloneElementWithChildren();
+ PassRefPtr<Element> cloneElementWithoutChildren();
void normalizeAttributes();
virtual bool isFormControlElement() const { return false; }
virtual bool isFormControlElementWithState() const { return false; }
- virtual bool isInputTypeHidden() const { return false; }
- virtual bool isPasswordField() const { return false; }
String nodeNamePreservingCase() const;
@@ -215,6 +218,10 @@ private:
virtual const AtomicString& virtualLocalName() const { return localName(); }
virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
+ // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
+ // are used instead.
+ virtual PassRefPtr<Node> cloneNode(bool deep);
+
QualifiedName m_tagName;
virtual NodeRareData* createRareData();
diff --git a/WebCore/dom/Element.idl b/WebCore/dom/Element.idl
index ae2c1b8..889eaf0 100644
--- a/WebCore/dom/Element.idl
+++ b/WebCore/dom/Element.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 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
@@ -26,7 +26,7 @@ module core {
InlineGetOwnPropertySlot,
InterfaceUUID=FEFE9C21-E58C-4b5b-821A-61A514613763,
ImplementationUUID=12E5B08E-A680-4baf-9D1E-108AEF7ABBFB
- ] Element : EventTargetNode {
+ ] Element : Node {
// DOM Level 1 Core
@@ -104,13 +104,13 @@ module core {
NodeList getElementsByClassName(in DOMString name);
// NodeSelector - Selector API
- Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ Element querySelector(in DOMString selectors)
raises(DOMException);
- NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ NodeList querySelectorAll(in DOMString selectors)
raises(DOMException);
- // ElementTraversal API
#if !defined(LANGUAGE_COM)
+ // ElementTraversal API
readonly attribute Element firstElementChild;
readonly attribute Element lastElementChild;
readonly attribute Element previousElementSibling;
@@ -118,6 +118,12 @@ module core {
readonly attribute unsigned long childElementCount;
#endif
+#if defined(LANGUAGE_JAVASCRIPT)
+ // CSSOM View Module API
+ ClientRectList getClientRects();
+ ClientRect getBoundingClientRect();
+#endif
+
#if defined(LANGUAGE_OBJECTIVE_C)
// Objective-C extensions
readonly attribute DOMString innerText;
diff --git a/WebCore/dom/EventException.idl b/WebCore/dom/EventException.idl
index 61cfd65..f948078 100644
--- a/WebCore/dom/EventException.idl
+++ b/WebCore/dom/EventException.idl
@@ -30,7 +30,8 @@ module events {
// Introduced in DOM Level 2:
interface [
- GenerateConstructor
+ GenerateConstructor,
+ NoStaticTables
] EventException {
readonly attribute unsigned short code;
diff --git a/WebCore/dom/EventListener.h b/WebCore/dom/EventListener.h
index 24fce86..b7daa6d 100644
--- a/WebCore/dom/EventListener.h
+++ b/WebCore/dom/EventListener.h
@@ -1,5 +1,5 @@
/*
- * 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,6 +23,10 @@
#include <wtf/RefCounted.h>
+namespace JSC {
+ class JSObject;
+}
+
namespace WebCore {
class Event;
@@ -31,10 +35,21 @@ namespace WebCore {
public:
virtual ~EventListener() { }
virtual void handleEvent(Event*, bool isWindowEvent = false) = 0;
- virtual bool isInline() const { return false; }
virtual bool wasCreatedFromMarkup() const { return false; }
+
+#if USE(JSC)
+ virtual JSC::JSObject* function() const { return 0; }
+ virtual void mark() { }
+#endif
+
+ bool isInline() const { return virtualIsInline(); }
+
+ private:
+ virtual bool virtualIsInline() const { return false; }
};
+ inline void markIfNotNull(EventListener* listener) { if (listener) listener->mark(); }
+
}
#endif
diff --git a/WebCore/dom/EventListener.idl b/WebCore/dom/EventListener.idl
index 9d28703..9dc2e0a 100644
--- a/WebCore/dom/EventListener.idl
+++ b/WebCore/dom/EventListener.idl
@@ -22,6 +22,7 @@ module events {
// Introduced in DOM Level 2:
interface [
+ NoStaticTables,
ObjCProtocol,
InterfaceUUID=B04F2AE3-71E2-4ebe-ABFE-EF4938354082,
ImplementationUUID=DDFDD342-A78B-4f19-8F32-A5DF51B56E08
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index d6f2314..28a66bc 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -108,24 +108,26 @@ namespace WebCore {
macro(webkitBeforeTextInserted) \
macro(webkitEditableContentChanged) \
\
- macro(canshowcurrentframe) \
macro(canplay) \
macro(canplaythrough) \
- macro(dataunavailable) \
macro(durationchange) \
macro(emptied) \
macro(ended) \
- macro(loadedfirstframe) \
+ macro(loadeddata) \
macro(loadedmetadata) \
macro(pause) \
macro(play) \
+ macro(playing) \
macro(ratechange) \
+ macro(seeked) \
+ macro(seeking) \
macro(timeupdate) \
macro(volumechange) \
macro(waiting) \
\
macro(progress) \
macro(stalled) \
+ macro(suspend) \
\
macro(webkitAnimationEnd) \
macro(webkitAnimationStart) \
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index dcebd64..6717a02 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -44,7 +44,7 @@ EventTarget::~EventTarget()
{
}
-EventTargetNode* EventTarget::toNode()
+Node* EventTarget::toNode()
{
return 0;
}
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index 3a3ec84..81d2c5a 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -40,8 +40,8 @@ namespace WebCore {
class DOMApplicationCache;
class Event;
class EventListener;
- class EventTargetNode;
class MessagePort;
+ class Node;
class ScriptExecutionContext;
class SVGElementInstance;
class Worker;
@@ -54,7 +54,7 @@ namespace WebCore {
class EventTarget {
public:
virtual MessagePort* toMessagePort();
- virtual EventTargetNode* toNode();
+ virtual Node* toNode();
virtual XMLHttpRequest* toXMLHttpRequest();
virtual XMLHttpRequestUpload* toXMLHttpRequestUpload();
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/dom/EventTarget.idl b/WebCore/dom/EventTarget.idl
index d3f46f7..844dc32 100644
--- a/WebCore/dom/EventTarget.idl
+++ b/WebCore/dom/EventTarget.idl
@@ -26,13 +26,13 @@ module events {
PureInterface,
InterfaceUUID=1D71C7EC-0BA0-4044-BDFD-56B3E8F5F9D4
] EventTarget {
- [OldStyleObjC, EventTargetNodeCast] void addEventListener(in DOMString type,
+ [OldStyleObjC] void addEventListener(in DOMString type,
in EventListener listener,
in boolean useCapture);
- [OldStyleObjC, EventTargetNodeCast] void removeEventListener(in DOMString type,
+ [OldStyleObjC] void removeEventListener(in DOMString type,
in EventListener listener,
in boolean useCapture);
- [EventTargetNodeCast] boolean dispatchEvent(in Event event)
+ boolean dispatchEvent(in Event event)
raises(EventException);
};
diff --git a/WebCore/dom/EventTargetNode.cpp b/WebCore/dom/EventTargetNode.cpp
deleted file mode 100644
index d3d9a32..0000000
--- a/WebCore/dom/EventTargetNode.cpp
+++ /dev/null
@@ -1,1241 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * 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 "EventTargetNode.h"
-
-#include "Document.h"
-#include "EventException.h"
-#include "EventHandler.h"
-#include "EventListener.h"
-#include "EventNames.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "KeyboardEvent.h"
-#include "MouseEvent.h"
-#include "MutationEvent.h"
-#include "NodeRareData.h"
-#include "Page.h"
-#include "PlatformMouseEvent.h"
-#include "PlatformWheelEvent.h"
-#include "ProgressEvent.h"
-#include "RegisteredEventListener.h"
-#include "ScriptController.h"
-#include "TextEvent.h"
-#include "WebKitAnimationEvent.h"
-#include "WebKitTransitionEvent.h"
-#include "WheelEvent.h"
-#include <wtf/HashSet.h>
-
-#if ENABLE(DOM_STORAGE)
-#include "StorageEvent.h"
-#endif
-
-#if ENABLE(SVG)
-#include "SVGElementInstance.h"
-#include "SVGUseElement.h"
-#endif
-
-namespace WebCore {
-
-static HashSet<EventTargetNode*>* gNodesDispatchingSimulatedClicks = 0;
-
-EventTargetNode::EventTargetNode(Document* doc, bool isElement, bool isContainer, bool isText)
- : Node(doc, isElement, isContainer, isText)
-{
-}
-
-EventTargetNode::~EventTargetNode()
-{
- if (!eventListeners().isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-}
-
-ScriptExecutionContext* EventTargetNode::scriptExecutionContext() const
-{
- return document();
-}
-
-const RegisteredEventListenerVector& EventTargetNode::eventListeners() const
-{
- if (hasRareData()) {
- if (RegisteredEventListenerVector* listeners = rareData()->listeners())
- return *listeners;
- }
- static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector;
- return *emptyListenersVector;
-}
-
-void EventTargetNode::insertedIntoDocument()
-{
- if (!eventListeners().isEmpty())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- Node::insertedIntoDocument();
-}
-
-void EventTargetNode::removedFromDocument()
-{
- if (!eventListeners().isEmpty())
- document()->registerDisconnectedNodeWithEventListeners(this);
-
- Node::removedFromDocument();
-}
-
-void EventTargetNode::willMoveToNewOwnerDocument()
-{
- if (!eventListeners().isEmpty())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- Node::willMoveToNewOwnerDocument();
-}
-
-void EventTargetNode::didMoveToNewOwnerDocument()
-{
- if (!eventListeners().isEmpty())
- document()->registerDisconnectedNodeWithEventListeners(this);
-
- Node::didMoveToNewOwnerDocument();
-}
-
-static inline void updateSVGElementInstancesAfterEventListenerChange(EventTargetNode* referenceNode)
-{
- ASSERT(referenceNode);
-
-#if ENABLE(SVG)
- if (!referenceNode->isSVGElement())
- return;
-
- // Elements living inside a <use> shadow tree, never cause any updates!
- if (referenceNode->shadowTreeRootNode())
- return;
-
- // We're possibly (a child of) an element that is referenced by a <use> client
- // If an event listeners changes on a referenced element, update all instances.
- for (Node* node = referenceNode; node; node = node->parentNode()) {
- if (!node->hasID() || !node->isSVGElement())
- continue;
-
- SVGElementInstance::invalidateAllInstancesOfElement(static_cast<SVGElement*>(node));
- break;
- }
-#endif
-}
-
-void EventTargetNode::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);
-
- listeners.append(RegisteredEventListener::create(eventType, listener, useCapture));
- updateSVGElementInstancesAfterEventListenerChange(this);
-
-#if ENABLE(TOUCH_EVENTS) // Android
- if (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent)
- document->addTouchEventListener(this);
-#endif
-}
-
-void EventTargetNode::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);
-
- // removed last
- if (listeners->isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- updateSVGElementInstancesAfterEventListenerChange(this);
-
-#if ENABLE(TOUCH_EVENTS) // Android
- if (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent)
- document()->removeTouchEventListener(this);
-#endif
- return;
- }
- }
-}
-
-void EventTargetNode::removeAllEventListeners()
-{
- if (!hasRareData())
- return;
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
-#if ENABLE(TOUCH_EVENTS) // Android
- document()->removeTouchEventListener(this);
-#endif
- size_t size = listeners->size();
- for (size_t i = 0; i < size; ++i)
- listeners->at(i)->setRemoved(true);
- listeners->clear();
-}
-
-void EventTargetNode::handleLocalEvents(Event* event, bool useCapture)
-{
- 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);
- }
-}
-
-#if ENABLE(SVG)
-static inline SVGElementInstance* eventTargetAsSVGElementInstance(EventTargetNode* referenceNode)
-{
- ASSERT(referenceNode);
- if (!referenceNode->isSVGElement())
- return 0;
-
- // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
- // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
- for (Node* n = referenceNode; n; n = n->parentNode()) {
- if (!n->isShadowNode() || !n->isSVGElement())
- continue;
-
- Node* shadowTreeParentElement = n->shadowParentNode();
- ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
-
- if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
- return instance;
- }
-
- return 0;
-}
-#endif
-
-static inline EventTarget* eventTargetRespectingSVGTargetRules(EventTargetNode* referenceNode)
-{
- ASSERT(referenceNode);
-
-#if ENABLE(SVG)
- if (SVGElementInstance* instance = eventTargetAsSVGElementInstance(referenceNode)) {
- ASSERT(instance->shadowTreeElement() == referenceNode);
- return instance;
- }
-#endif
-
- return referenceNode;
-}
-
-bool EventTargetNode::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
-{
- RefPtr<Event> evt(e);
- ASSERT(!eventDispatchForbidden());
- if (!evt || evt->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return false;
- }
-
- evt->setTarget(eventTargetRespectingSVGTargetRules(this));
-
- RefPtr<FrameView> view = document()->view();
- return dispatchGenericEvent(evt.release());
-}
-
-bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
-{
- RefPtr<Event> event(prpEvent);
-
- ASSERT(!eventDispatchForbidden());
- ASSERT(event->target());
- ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
-
- // 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<EventTargetNode> 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);
- }
- }
-
- // Set up a pointer to indicate whether to dispatch window events.
- // We don't dispatch load events to the window. That quirk was originally
- // added because Mozilla doesn't propagate load events to the window object.
- Document* documentForWindowEvents = 0;
- if (event->type() != eventNames().loadEvent) {
- EventTargetNode* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get();
- if (topLevelContainer->isDocumentNode())
- documentForWindowEvents = static_cast<Document*>(topLevelContainer);
- }
-
- // Give the target node a chance to do some work before DOM event handlers get a crack.
- void* data = preDispatchEventHandler(event.get());
- if (event->propagationStopped())
- goto doneDispatching;
-
- // Trigger capturing event handlers, starting at the top and working our way down.
- event->setEventPhase(Event::CAPTURING_PHASE);
-
- if (documentForWindowEvents) {
- event->setCurrentTarget(documentForWindowEvents);
- documentForWindowEvents->handleWindowEvent(event.get(), true);
- 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);
- 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);
- if (event->propagationStopped())
- goto doneDispatching;
-
- if (event->bubbles() && !event->cancelBubble()) {
- // Trigger bubbling event handlers, starting at the bottom and working our way up.
- event->setEventPhase(Event::BUBBLING_PHASE);
-
- size_t size = ancestors.size();
- for (size_t i = 0; i < size; ++i) {
- ContainerNode* ancestor = ancestors[i].get();
- event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
- ancestor->handleLocalEvents(event.get(), false);
- if (event->propagationStopped() || event->cancelBubble())
- goto doneDispatching;
- }
- if (documentForWindowEvents) {
- event->setCurrentTarget(documentForWindowEvents);
- documentForWindowEvents->handleWindowEvent(event.get(), false);
- if (event->propagationStopped() || event->cancelBubble())
- goto doneDispatching;
- }
- }
-
-doneDispatching:
- event->setCurrentTarget(0);
- event->setEventPhase(0);
-
- // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler.
- postDispatchEventHandler(event.get(), data);
-
- // Call default event handlers. While the DOM does have a concept of preventing
- // default handling, the detail of which handlers are called is an internal
- // implementation detail and not part of the DOM.
- if (!event->defaultPrevented() && !event->defaultHandled()) {
- // Non-bubbling events call only one default event handler, the one for the target.
- defaultEventHandler(event.get());
- ASSERT(!event->defaultPrevented());
- if (event->defaultHandled())
- goto doneWithDefault;
- // For bubbling events, call default event handlers on the same targets in the
- // same order as the bubbling phase.
- if (event->bubbles()) {
- size_t size = ancestors.size();
- for (size_t i = 0; i < size; ++i) {
- ContainerNode* ancestor = ancestors[i].get();
- ancestor->defaultEventHandler(event.get());
- ASSERT(!event->defaultPrevented());
- if (event->defaultHandled())
- goto doneWithDefault;
- }
- }
- }
-
-doneWithDefault:
- Document::updateDocumentsRendering();
-
- return !event->defaultPrevented();
-}
-
-bool EventTargetNode::dispatchSubtreeModifiedEvent()
-{
- ASSERT(!eventDispatchForbidden());
-
- document()->incDOMTreeVersion();
-
- notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing.
-
- if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
- return false;
- ExceptionCode ec = 0;
- return dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true, false, 0, String(), String(), String(), 0), ec);
-}
-
-void EventTargetNode::dispatchWindowEvent(PassRefPtr<Event> e)
-{
- ASSERT(!eventDispatchForbidden());
- RefPtr<Event> evt(e);
- RefPtr<Document> doc = document();
- evt->setTarget(doc);
- doc->handleWindowEvent(evt.get(), true);
- doc->handleWindowEvent(evt.get(), false);
-}
-
-void EventTargetNode::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-{
- ASSERT(!eventDispatchForbidden());
- RefPtr<Document> doc = document();
- dispatchWindowEvent(Event::create(eventType, canBubbleArg, cancelableArg));
-
- if (eventType == eventNames().loadEvent) {
- // For onload events, send a separate load event to the enclosing frame only.
- // This is a DOM extension and is independent of bubbling/capturing rules of
- // the DOM.
- Element* ownerElement = doc->ownerElement();
- if (ownerElement) {
- RefPtr<Event> ownerEvent = Event::create(eventType, false, cancelableArg);
- ownerEvent->setTarget(ownerElement);
- ownerElement->dispatchGenericEvent(ownerEvent.release());
- }
- }
-}
-
-bool EventTargetNode::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
-{
- ASSERT(!eventDispatchForbidden());
- ASSERT(eventType == eventNames().DOMFocusInEvent || eventType == eventNames().DOMFocusOutEvent || eventType == eventNames().DOMActivateEvent);
-
- bool cancelable = eventType == eventNames().DOMActivateEvent;
-
- ExceptionCode ec = 0;
- RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
- evt->setUnderlyingEvent(underlyingEvent);
- return dispatchEvent(evt.release(), ec);
-}
-
-bool EventTargetNode::dispatchKeyEvent(const PlatformKeyboardEvent& key)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView());
- bool r = dispatchEvent(keyboardEvent, ec);
-
- // 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
- // let it get handled by AppKit
- if (keyboardEvent->defaultHandled())
- r = false;
-
- return r;
-}
-
-bool EventTargetNode::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
- int detail, Node* relatedTarget)
-{
- ASSERT(!eventDispatchForbidden());
-
- IntPoint contentsPos;
- if (FrameView* view = document()->view())
- contentsPos = view->windowToContents(event.pos());
-
- short button = event.button();
-
- ASSERT(event.eventType() == MouseEventMoved || button != NoButton);
-
- return dispatchMouseEvent(eventType, button, detail,
- contentsPos.x(), contentsPos.y(), event.globalX(), event.globalY(),
- event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
- false, relatedTarget);
-}
-
-void EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString& eventType,
- PassRefPtr<Event> underlyingEvent)
-{
- ASSERT(!eventDispatchForbidden());
-
- bool ctrlKey = false;
- bool altKey = false;
- bool shiftKey = false;
- bool metaKey = false;
- if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) {
- ctrlKey = keyStateEvent->ctrlKey();
- altKey = keyStateEvent->altKey();
- shiftKey = keyStateEvent->shiftKey();
- metaKey = keyStateEvent->metaKey();
- }
-
- // Like Gecko, we just pass 0 for everything when we make a fake mouse event.
- // Internet Explorer instead gives the current mouse position and state.
- dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0,
- ctrlKey, altKey, shiftKey, metaKey, true, 0, underlyingEvent);
-}
-
-void EventTargetNode::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
-{
- if (!gNodesDispatchingSimulatedClicks)
- gNodesDispatchingSimulatedClicks = new HashSet<EventTargetNode*>;
- else if (gNodesDispatchingSimulatedClicks->contains(this))
- return;
-
- gNodesDispatchingSimulatedClicks->add(this);
-
- // send mousedown and mouseup before the click, if requested
- if (sendMouseEvents)
- dispatchSimulatedMouseEvent(eventNames().mousedownEvent, event.get());
- setActive(true, showPressedLook);
- if (sendMouseEvents)
- dispatchSimulatedMouseEvent(eventNames().mouseupEvent, event.get());
- setActive(false);
-
- // always send click
- dispatchSimulatedMouseEvent(eventNames().clickEvent, event);
-
- gNodesDispatchingSimulatedClicks->remove(this);
-}
-
-bool EventTargetNode::dispatchMouseEvent(const AtomicString& eventType, int button, int detail,
- int pageX, int pageY, int screenX, int screenY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- bool isSimulated, Node* relatedTargetArg, PassRefPtr<Event> underlyingEvent)
-{
- ASSERT(!eventDispatchForbidden());
- if (disabled()) // Don't even send DOM events for disabled controls..
- return true;
-
- if (eventType.isEmpty())
- return false; // Shouldn't happen.
-
- // Dispatching the first event can easily result in this node being destroyed.
- // Since we dispatch up to three events here, we need to make sure we're referenced
- // so the pointer will be good for the two subsequent ones.
- RefPtr<Node> protect(this);
-
- 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.
- RefPtr<EventTargetNode> relatedTarget = (relatedTargetArg && relatedTargetArg->isEventTargetNode())
- ? static_cast<EventTargetNode*>(relatedTargetArg) : 0;
-
- if (Frame* frame = document()->frame()) {
- float pageZoom = frame->pageZoomFactor();
- if (pageZoom != 1.0f) {
- // Adjust our pageX and pageY to account for the page zoom.
- pageX = lroundf(pageX / pageZoom);
- pageY = lroundf(pageY / pageZoom);
- }
- }
-
- RefPtr<Event> mouseEvent = MouseEvent::create(eventType,
- true, cancelable, document()->defaultView(),
- detail, screenX, screenY, pageX, pageY,
- ctrlKey, altKey, shiftKey, metaKey, button,
- relatedTarget, 0, isSimulated);
- mouseEvent->setUnderlyingEvent(underlyingEvent.get());
-
- dispatchEvent(mouseEvent, ec);
- bool defaultHandled = mouseEvent->defaultHandled();
- bool defaultPrevented = mouseEvent->defaultPrevented();
- if (defaultHandled || defaultPrevented)
- swallowEvent = true;
-
- // Special case: If it's a double click event, we also send the dblclick event. This is not part
- // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
- // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
- if (eventType == eventNames().clickEvent && detail == 2) {
- RefPtr<Event> doubleClickEvent = MouseEvent::create(eventNames().dblclickEvent,
- true, cancelable, document()->defaultView(),
- detail, screenX, screenY, pageX, pageY,
- ctrlKey, altKey, shiftKey, metaKey, button,
- relatedTarget, 0, isSimulated);
- doubleClickEvent->setUnderlyingEvent(underlyingEvent.get());
- if (defaultHandled)
- doubleClickEvent->setDefaultHandled();
- dispatchEvent(doubleClickEvent, ec);
- if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
- swallowEvent = true;
- }
-
- return swallowEvent;
-}
-
-void EventTargetNode::dispatchWheelEvent(PlatformWheelEvent& e)
-{
- ASSERT(!eventDispatchForbidden());
- if (e.deltaX() == 0 && e.deltaY() == 0)
- return;
-
- FrameView* view = document()->view();
- if (!view)
- return;
-
- IntPoint pos = view->windowToContents(e.pos());
-
- // Convert the deltas from pixels to lines if we have a pixel scroll event.
- float deltaX = e.deltaX();
- float deltaY = e.deltaY();
-
- // FIXME: Should we do anything with a ScrollByPageWheelEvent here?
- // It will be treated like a line scroll of 1 right now.
- if (e.granularity() == ScrollByPixelWheelEvent) {
- deltaX /= cMouseWheelPixelsPerLineStep;
- deltaY /= cMouseWheelPixelsPerLineStep;
- }
-
- RefPtr<WheelEvent> we = WheelEvent::create(e.deltaX(), e.deltaY(),
- document()->defaultView(), e.globalX(), e.globalY(), pos.x(), pos.y(),
- e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey());
- ExceptionCode ec = 0;
- if (!dispatchEvent(we.release(), ec))
- e.accept();
-}
-
-bool EventTargetNode::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime)
-{
- ASSERT(!eventDispatchForbidden());
-
- ExceptionCode ec = 0;
- return dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec);
-}
-
-bool EventTargetNode::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime)
-{
- ASSERT(!eventDispatchForbidden());
-
- ExceptionCode ec = 0;
- return dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec);
-}
-
-void EventTargetNode::dispatchFocusEvent()
-{
- dispatchEventForType(eventNames().focusEvent, false, false);
-}
-
-void EventTargetNode::dispatchBlurEvent()
-{
- dispatchEventForType(eventNames().blurEvent, false, false);
-}
-
-bool EventTargetNode::dispatchEventForType(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec);
-}
-
-bool EventTargetNode::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- return dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec);
-}
-
-void EventTargetNode::dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source)
-{
-#if ENABLE(DOM_STORAGE)
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- dispatchEvent(StorageEvent::create(eventType, key, oldValue, newValue, source->document()->documentURI(), source->domWindow()), ec);
-#endif
-}
-
-void EventTargetNode::removeInlineEventListenerForType(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()->isInline())
- continue;
-
- r.setRemoved(true);
- listeners->remove(i);
-
- // removed last
- if (listeners->isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- updateSVGElementInstancesAfterEventListenerChange(this);
- return;
- }
-}
-
-void EventTargetNode::setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
- // In case we are the only one holding a reference to it, we don't want removeInlineEventListenerForType to destroy it.
- removeInlineEventListenerForType(eventType);
- if (listener)
- addEventListener(eventType, listener, false);
-}
-
-void EventTargetNode::setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute* attr)
-{
- setInlineEventListenerForType(eventType, document()->createEventListener(attr->localName().string(), attr->value(), this));
-}
-
-EventListener* EventTargetNode::inlineEventListenerForType(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()->isInline())
- return r.listener();
- }
- return 0;
-}
-
-#ifdef ANDROID
-EventListener *EventTargetNode::getEventListener(const AtomicString &eventType)
-{
- 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)
- return r.listener();
- }
- return 0;
-}
-#endif
-
-bool EventTargetNode::disabled() const
-{
- return false;
-}
-
-void EventTargetNode::defaultEventHandler(Event* event)
-{
- if (event->target() != this)
- return;
- const AtomicString& eventType = event->type();
- if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) {
- if (event->isKeyboardEvent())
- if (Frame* frame = document()->frame())
- frame->eventHandler()->defaultKeyboardEventHandler(static_cast<KeyboardEvent*>(event));
- } else if (eventType == eventNames().clickEvent) {
- int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
- dispatchUIEvent(eventNames().DOMActivateEvent, detail, event);
- } else if (eventType == eventNames().contextmenuEvent) {
- if (Frame* frame = document()->frame())
- if (Page* page = frame->page())
- page->contextMenuController()->handleContextMenuEvent(event);
- } else if (eventType == eventNames().textInputEvent) {
- if (event->isTextEvent())
- if (Frame* frame = document()->frame())
- frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event));
- }
-}
-
-EventListener* EventTargetNode::onabort() const
-{
- return inlineEventListenerForType(eventNames().abortEvent);
-}
-
-void EventTargetNode::setOnabort(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().abortEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onblur() const
-{
- return inlineEventListenerForType(eventNames().blurEvent);
-}
-
-void EventTargetNode::setOnblur(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().blurEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onchange() const
-{
- return inlineEventListenerForType(eventNames().changeEvent);
-}
-
-void EventTargetNode::setOnchange(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().changeEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onclick() const
-{
- return inlineEventListenerForType(eventNames().clickEvent);
-}
-
-void EventTargetNode::setOnclick(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().clickEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oncontextmenu() const
-{
- return inlineEventListenerForType(eventNames().contextmenuEvent);
-}
-
-void EventTargetNode::setOncontextmenu(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondblclick() const
-{
- return inlineEventListenerForType(eventNames().dblclickEvent);
-}
-
-void EventTargetNode::setOndblclick(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dblclickEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onerror() const
-{
- return inlineEventListenerForType(eventNames().errorEvent);
-}
-
-void EventTargetNode::setOnerror(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().errorEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onfocus() const
-{
- return inlineEventListenerForType(eventNames().focusEvent);
-}
-
-void EventTargetNode::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().focusEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oninput() const
-{
- return inlineEventListenerForType(eventNames().inputEvent);
-}
-
-void EventTargetNode::setOninput(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().inputEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onkeydown() const
-{
- return inlineEventListenerForType(eventNames().keydownEvent);
-}
-
-void EventTargetNode::setOnkeydown(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().keydownEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onkeypress() const
-{
- return inlineEventListenerForType(eventNames().keypressEvent);
-}
-
-void EventTargetNode::setOnkeypress(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().keypressEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onkeyup() const
-{
- return inlineEventListenerForType(eventNames().keyupEvent);
-}
-
-void EventTargetNode::setOnkeyup(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().keyupEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onload() const
-{
- return inlineEventListenerForType(eventNames().loadEvent);
-}
-
-void EventTargetNode::setOnload(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().loadEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmousedown() const
-{
- return inlineEventListenerForType(eventNames().mousedownEvent);
-}
-
-void EventTargetNode::setOnmousedown(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mousedownEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmousemove() const
-{
- return inlineEventListenerForType(eventNames().mousemoveEvent);
-}
-
-void EventTargetNode::setOnmousemove(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmouseout() const
-{
- return inlineEventListenerForType(eventNames().mouseoutEvent);
-}
-
-void EventTargetNode::setOnmouseout(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmouseover() const
-{
- return inlineEventListenerForType(eventNames().mouseoverEvent);
-}
-
-void EventTargetNode::setOnmouseover(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmouseup() const
-{
- return inlineEventListenerForType(eventNames().mouseupEvent);
-}
-
-void EventTargetNode::setOnmouseup(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mouseupEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmousewheel() const
-{
- return inlineEventListenerForType(eventNames().mousewheelEvent);
-}
-
-void EventTargetNode::setOnmousewheel(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onbeforecut() const
-{
- return inlineEventListenerForType(eventNames().beforecutEvent);
-}
-
-void EventTargetNode::setOnbeforecut(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().beforecutEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oncut() const
-{
- return inlineEventListenerForType(eventNames().cutEvent);
-}
-
-void EventTargetNode::setOncut(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().cutEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onbeforecopy() const
-{
- return inlineEventListenerForType(eventNames().beforecopyEvent);
-}
-
-void EventTargetNode::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oncopy() const
-{
- return inlineEventListenerForType(eventNames().copyEvent);
-}
-
-void EventTargetNode::setOncopy(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().copyEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onbeforepaste() const
-{
- return inlineEventListenerForType(eventNames().beforepasteEvent);
-}
-
-void EventTargetNode::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onpaste() const
-{
- return inlineEventListenerForType(eventNames().pasteEvent);
-}
-
-void EventTargetNode::setOnpaste(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().pasteEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragenter() const
-{
- return inlineEventListenerForType(eventNames().dragenterEvent);
-}
-
-void EventTargetNode::setOndragenter(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragenterEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragover() const
-{
- return inlineEventListenerForType(eventNames().dragoverEvent);
-}
-
-void EventTargetNode::setOndragover(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragoverEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragleave() const
-{
- return inlineEventListenerForType(eventNames().dragleaveEvent);
-}
-
-void EventTargetNode::setOndragleave(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondrop() const
-{
- return inlineEventListenerForType(eventNames().dropEvent);
-}
-
-void EventTargetNode::setOndrop(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dropEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragstart() const
-{
- return inlineEventListenerForType(eventNames().dragstartEvent);
-}
-
-void EventTargetNode::setOndragstart(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragstartEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondrag() const
-{
- return inlineEventListenerForType(eventNames().dragEvent);
-}
-
-void EventTargetNode::setOndrag(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragend() const
-{
- return inlineEventListenerForType(eventNames().dragendEvent);
-}
-
-void EventTargetNode::setOndragend(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragendEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onreset() const
-{
- return inlineEventListenerForType(eventNames().resetEvent);
-}
-
-void EventTargetNode::setOnreset(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().resetEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onresize() const
-{
- return inlineEventListenerForType(eventNames().resizeEvent);
-}
-
-void EventTargetNode::setOnresize(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().resizeEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onscroll() const
-{
- return inlineEventListenerForType(eventNames().scrollEvent);
-}
-
-void EventTargetNode::setOnscroll(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().scrollEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onsearch() const
-{
- return inlineEventListenerForType(eventNames().searchEvent);
-}
-
-void EventTargetNode::setOnsearch(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().searchEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onselect() const
-{
- return inlineEventListenerForType(eventNames().selectEvent);
-}
-
-void EventTargetNode::setOnselect(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().selectEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onselectstart() const
-{
- return inlineEventListenerForType(eventNames().selectstartEvent);
-}
-
-void EventTargetNode::setOnselectstart(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().selectstartEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onsubmit() const
-{
- return inlineEventListenerForType(eventNames().submitEvent);
-}
-
-void EventTargetNode::setOnsubmit(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().submitEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onunload() const
-{
- return inlineEventListenerForType(eventNames().unloadEvent);
-}
-
-void EventTargetNode::setOnunload(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().unloadEvent, eventListener);
-}
-
-#if ENABLE(TOUCH_EVENTS) // Android
-EventListener* EventTargetNode::ontouchstart() const
-{
- return inlineEventListenerForType(eventNames().touchstartEvent);
-}
-
-void EventTargetNode::setOntouchstart(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchstartEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ontouchend() const
-{
- return inlineEventListenerForType(eventNames().touchendEvent);
-}
-
-void EventTargetNode::setOntouchend(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchendEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ontouchmove() const
-{
- return inlineEventListenerForType(eventNames().touchmoveEvent);
-}
-
-void EventTargetNode::setOntouchmove(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchmoveEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ontouchcancel() const
-{
- return inlineEventListenerForType(eventNames().touchcancelEvent);
-}
-
-void EventTargetNode::setOntouchcancel(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchcancelEvent, eventListener);
-}
-
-#endif
-
-} // namespace WebCore
diff --git a/WebCore/dom/EventTargetNode.h b/WebCore/dom/EventTargetNode.h
deleted file mode 100644
index 1814b7b..0000000
--- a/WebCore/dom/EventTargetNode.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * 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 EventTargetNode_h
-#define EventTargetNode_h
-
-#include "EventTarget.h"
-#include "Node.h"
-
-namespace WebCore {
-
-class Attribute;
-class Frame;
-class RegisteredEventListener;
-
-typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector;
-
-class EventTargetNode : public Node, public EventTarget {
-public:
- EventTargetNode(Document*, bool isElement = false, bool isContainer = false, bool isText = false);
- virtual ~EventTargetNode();
-
- virtual bool isEventTargetNode() const { return true; }
- virtual EventTargetNode* toNode() { return this; }
-
- virtual ScriptExecutionContext* scriptExecutionContext() const;
-
- 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&);
- void removeAllEventListeners();
-
-#ifdef ANDROID
- EventListener* getEventListener(const AtomicString& eventType);
-#endif
- void setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
- void setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute*);
- void removeInlineEventListenerForType(const AtomicString& eventType);
- bool dispatchEventForType(const AtomicString& eventType, bool canBubble, bool cancelable);
- EventListener* inlineEventListenerForType(const AtomicString& eventType) const;
-
- bool dispatchSubtreeModifiedEvent();
- void dispatchWindowEvent(PassRefPtr<Event>);
- void dispatchWindowEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
- bool dispatchUIEvent(const AtomicString& eventType, int detail = 0, PassRefPtr<Event> underlyingEvent = 0);
- bool dispatchKeyEvent(const PlatformKeyboardEvent&);
- void dispatchWheelEvent(PlatformWheelEvent&);
- bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType,
- int clickCount = 0, Node* relatedTarget = 0);
- bool dispatchMouseEvent(const AtomicString& eventType, int button, int clickCount,
- int pageX, int pageY, int screenX, int screenY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- bool isSimulated = false, Node* relatedTarget = 0, PassRefPtr<Event> underlyingEvent = 0);
- void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent = 0);
- void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
- bool dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg);
- void dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source);
- bool dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime);
- bool dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime);
- bool dispatchGenericEvent(PassRefPtr<Event>);
-
- virtual void handleLocalEvents(Event*, bool useCapture);
-
- virtual void dispatchFocusEvent();
- virtual void dispatchBlurEvent();
-
- virtual void insertedIntoDocument();
- virtual void removedFromDocument();
- virtual void willMoveToNewOwnerDocument();
- virtual void didMoveToNewOwnerDocument();
-
- /**
- * Perform the default action for an event e.g. submitting a form
- */
- virtual void defaultEventHandler(Event*);
-
- /**
- * Used for disabled form elements; if true, prevents mouse events from being dispatched
- * to event listeners, and prevents DOMActivate events from being sent at all.
- */
- virtual bool disabled() const;
-
- const RegisteredEventListenerVector& eventListeners() const;
-
- EventListener* onabort() const;
- void setOnabort(PassRefPtr<EventListener>);
- EventListener* onblur() const;
- void setOnblur(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* onerror() const;
- void setOnerror(PassRefPtr<EventListener>);
- EventListener* onfocus() const;
- void setOnfocus(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* onload() const;
- void setOnload(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* 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* 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* onreset() const;
- void setOnreset(PassRefPtr<EventListener>);
- EventListener* onresize() const;
- void setOnresize(PassRefPtr<EventListener>);
- EventListener* onscroll() const;
- void setOnscroll(PassRefPtr<EventListener>);
- EventListener* onsearch() const;
- void setOnsearch(PassRefPtr<EventListener>);
- EventListener* onselect() const;
- void setOnselect(PassRefPtr<EventListener>);
- EventListener* onselectstart() const;
- void setOnselectstart(PassRefPtr<EventListener>);
- EventListener* onsubmit() const;
- void setOnsubmit(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>);
-#endif
-
- using Node::ref;
- using Node::deref;
-
-private:
- virtual void refEventTarget() { ref(); }
- virtual void derefEventTarget() { deref(); }
-};
-
-inline EventTargetNode* EventTargetNodeCast(Node* n)
-{
- ASSERT(n->isEventTargetNode());
- return static_cast<EventTargetNode*>(n);
-}
-
-inline const EventTargetNode* EventTargetNodeCast(const Node* n)
-{
- ASSERT(n->isEventTargetNode());
- return static_cast<const EventTargetNode*>(n);
-}
-
-} // namespace WebCore
-
-#endif // EventTargetNode_h
diff --git a/WebCore/dom/EventTargetNode.idl b/WebCore/dom/EventTargetNode.idl
deleted file mode 100644
index acb2e95..0000000
--- a/WebCore/dom/EventTargetNode.idl
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2008 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 core {
-
- interface [
- CustomPushEventHandlerScope,
- GenerateNativeConverter
- ] EventTargetNode : Node {
- // EventTarget
- attribute [DontEnum, ProtectedListener] EventListener onabort;
- attribute [DontEnum, ProtectedListener] EventListener onblur;
- attribute [DontEnum, ProtectedListener] EventListener onchange;
- attribute [DontEnum, ProtectedListener] EventListener onclick;
- attribute [DontEnum, ProtectedListener] EventListener oncontextmenu;
- attribute [DontEnum, ProtectedListener] EventListener ondblclick;
- attribute [DontEnum, ProtectedListener] EventListener onerror;
- attribute [DontEnum, ProtectedListener] EventListener onfocus;
- attribute [DontEnum, ProtectedListener] EventListener oninput;
- attribute [DontEnum, ProtectedListener] EventListener onkeydown;
- attribute [DontEnum, ProtectedListener] EventListener onkeypress;
- attribute [DontEnum, ProtectedListener] EventListener onkeyup;
- attribute [DontEnum, ProtectedListener] EventListener onload;
- attribute [DontEnum, ProtectedListener] EventListener onmousedown;
- attribute [DontEnum, ProtectedListener] EventListener onmousemove;
- attribute [DontEnum, ProtectedListener] EventListener onmouseout;
- attribute [DontEnum, ProtectedListener] EventListener onmouseover;
- attribute [DontEnum, ProtectedListener] EventListener onmouseup;
- attribute [DontEnum, ProtectedListener] EventListener onmousewheel;
- attribute [DontEnum, ProtectedListener] EventListener onbeforecut;
- attribute [DontEnum, ProtectedListener] EventListener oncut;
- attribute [DontEnum, ProtectedListener] EventListener onbeforecopy;
- attribute [DontEnum, ProtectedListener] EventListener oncopy;
- attribute [DontEnum, ProtectedListener] EventListener onbeforepaste;
- attribute [DontEnum, ProtectedListener] EventListener onpaste;
- attribute [DontEnum, ProtectedListener] EventListener ondragenter;
- attribute [DontEnum, ProtectedListener] EventListener ondragover;
- attribute [DontEnum, ProtectedListener] EventListener ondragleave;
- attribute [DontEnum, ProtectedListener] EventListener ondrop;
- attribute [DontEnum, ProtectedListener] EventListener ondragstart;
- attribute [DontEnum, ProtectedListener] EventListener ondrag;
- attribute [DontEnum, ProtectedListener] EventListener ondragend;
- attribute [DontEnum, ProtectedListener] EventListener onreset;
- attribute [DontEnum, ProtectedListener] EventListener onresize;
- attribute [DontEnum, ProtectedListener] EventListener onscroll;
- attribute [DontEnum, ProtectedListener] EventListener onsearch;
- attribute [DontEnum, ProtectedListener] EventListener onselect;
- attribute [DontEnum, ProtectedListener] EventListener onselectstart;
- attribute [DontEnum, ProtectedListener] EventListener onsubmit;
- attribute [DontEnum, ProtectedListener] EventListener onunload;
-#if ENABLE_TOUCH_EVENTS
- attribute [DontEnum, ProtectedListener] EventListener ontouchstart;
- attribute [DontEnum, ProtectedListener] EventListener ontouchend;
- attribute [DontEnum, ProtectedListener] EventListener ontouchmove;
- attribute [DontEnum, ProtectedListener] EventListener ontouchcancel;
-#endif
-
- [Custom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [Custom] void removeEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- boolean dispatchEvent(in Event event)
- raises(EventException);
- };
-
-}
diff --git a/WebCore/dom/ExceptionCode.cpp b/WebCore/dom/ExceptionCode.cpp
index fa0a7a7..8ce1643 100644
--- a/WebCore/dom/ExceptionCode.cpp
+++ b/WebCore/dom/ExceptionCode.cpp
@@ -71,7 +71,8 @@ static const char* const eventExceptionNames[] = {
};
static const char* const xmlHttpRequestExceptionNames[] = {
- "NETWORK_ERR"
+ "NETWORK_ERR",
+ "ABORT_ERR"
};
#if ENABLE(XPATH)
diff --git a/WebCore/dom/FormControlElement.h b/WebCore/dom/FormControlElement.h
index 881c9fd..dc77ada 100644
--- a/WebCore/dom/FormControlElement.h
+++ b/WebCore/dom/FormControlElement.h
@@ -30,6 +30,10 @@ class FormControlElement {
public:
virtual ~FormControlElement() { }
+ virtual bool isEnabled() const = 0;
+ virtual bool isReadOnlyControl() const = 0;
+ virtual bool isTextControl() const = 0;
+
virtual bool valueMatchesRenderer() const = 0;
virtual void setValueMatchesRenderer(bool value = true) = 0;
diff --git a/WebCore/dom/GenericWorkerTask.h b/WebCore/dom/GenericWorkerTask.h
deleted file mode 100644
index 79fd148..0000000
--- a/WebCore/dom/GenericWorkerTask.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2009, Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT
- * OWNER 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 GenericWorkerTask_h
-#define GenericWorkerTask_h
-
-#if ENABLE(WORKERS)
-
-#include "WorkerMessagingProxy.h"
-#include "ScriptExecutionContext.h"
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
- class GenericWorkerTaskBase : public ScriptExecutionContext::Task {
- protected:
- GenericWorkerTaskBase(WorkerMessagingProxy* messagingProxy) : m_messagingProxy(messagingProxy)
- {
- }
-
- bool canPerformTask()
- {
- return !m_messagingProxy->askedToTerminate();
- }
-
- WorkerMessagingProxy* m_messagingProxy;
- };
-
- template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
- class GenericWorkerTask6 : public GenericWorkerTaskBase {
- public:
- typedef void (*Method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6);
- typedef GenericWorkerTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> GenericWorkerTask;
-
- static PassRefPtr<GenericWorkerTask> create(WorkerMessagingProxy* messagingProxy, Method method, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6)
- {
- return adoptRef(new GenericWorkerTask(messagingProxy, method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6));
- }
-
- private:
- GenericWorkerTask6(WorkerMessagingProxy* messagingProxy, Method method, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6)
- : GenericWorkerTaskBase(messagingProxy)
- , m_method(method)
- , m_parameter1(parameter1)
- , m_parameter2(parameter2)
- , m_parameter3(parameter3)
- , m_parameter4(parameter4)
- , m_parameter5(parameter5)
- , m_parameter6(parameter6)
- {
- }
-
- virtual void performTask(ScriptExecutionContext* context)
- {
- if (!canPerformTask())
- return;
- (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5, m_parameter6);
- }
-
- private:
- Method m_method;
- P1 m_parameter1;
- P2 m_parameter2;
- P3 m_parameter3;
- P4 m_parameter4;
- P5 m_parameter5;
- P6 m_parameter6;
- };
-
- template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
- PassRefPtr<GenericWorkerTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> > createCallbackTask(
- WorkerMessagingProxy* messagingProxy,
- void (*method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6),
- const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6)
- {
- return GenericWorkerTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6>::create(messagingProxy, method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6);
- }
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // GenericWorkerTask_h
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index 47c1a28..6b733cb 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -114,7 +114,7 @@ void InputElement::updateSelectionRange(InputElementData& data, int start, int e
if (!data.inputElement()->isTextField())
return;
- if (RenderTextControl* renderer = static_cast<RenderTextControl*>(data.element()->renderer()))
+ if (RenderTextControl* renderer = toRenderTextControl(data.element()->renderer()))
renderer->setSelectionRange(start, end);
}
@@ -218,7 +218,7 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, Documen
// Make sure that the text to be inserted will not violate the maxLength.
int oldLength = numGraphemeClusters(data.inputElement()->value().impl());
ASSERT(oldLength <= data.maxLength());
- int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toRange().get()).impl());
+ int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toNormalizedRange().get()).impl());
ASSERT(oldLength >= selectionLength);
int maxNewLength = data.maxLength() - (oldLength - selectionLength);
diff --git a/WebCore/dom/InputElement.h b/WebCore/dom/InputElement.h
index c64f131..40c972f 100644
--- a/WebCore/dom/InputElement.h
+++ b/WebCore/dom/InputElement.h
@@ -36,6 +36,10 @@ class InputElement {
public:
virtual ~InputElement() { }
+ virtual bool isAutofilled() const = 0;
+ virtual bool isChecked() const = 0;
+ virtual bool isIndeterminate() const = 0;
+ virtual bool isInputTypeHidden() const = 0;
virtual bool isPasswordField() const = 0;
virtual bool isSearchField() const = 0;
virtual bool isTextField() const = 0;
diff --git a/WebCore/dom/MessagePort.cpp b/WebCore/dom/MessagePort.cpp
index 0607bea..312a1f3 100644
--- a/WebCore/dom/MessagePort.cpp
+++ b/WebCore/dom/MessagePort.cpp
@@ -137,6 +137,7 @@ void MessagePort::postMessage(const String& message, MessagePort* dataPort, Exce
ec = INVALID_ACCESS_ERR;
return;
}
+ ec = 0;
newMessagePort = dataPort->clone(ec);
if (ec)
return;
diff --git a/WebCore/dom/MouseEvent.cpp b/WebCore/dom/MouseEvent.cpp
index 1c97522..bdd39d3 100644
--- a/WebCore/dom/MouseEvent.cpp
+++ b/WebCore/dom/MouseEvent.cpp
@@ -36,7 +36,7 @@ MouseEvent::MouseEvent()
MouseEvent::MouseEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
int detail, int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTargetNode> relatedTarget,
+ unsigned short button, PassRefPtr<EventTarget> relatedTarget,
PassRefPtr<Clipboard> clipboard, bool isSimulated)
: MouseRelatedEvent(eventType, canBubble, cancelable, view, detail, screenX, screenY,
pageX, pageY, ctrlKey, altKey, shiftKey, metaKey, isSimulated)
@@ -54,7 +54,7 @@ MouseEvent::~MouseEvent()
void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
int detail, int screenX, int screenY, int clientX, int clientY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTargetNode> relatedTarget)
+ unsigned short button, PassRefPtr<EventTarget> relatedTarget)
{
if (dispatched())
return;
@@ -101,7 +101,7 @@ Node* MouseEvent::toElement() const
{
// MSIE extension - "the object toward which the user is moving the mouse pointer"
if (type() == eventNames().mouseoutEvent)
- return relatedTarget();
+ return relatedTarget() ? relatedTarget()->toNode() : 0;
return target() ? target()->toNode() : 0;
}
@@ -110,7 +110,7 @@ Node* MouseEvent::fromElement() const
{
// MSIE extension - "object from which activation or the mouse pointer is exiting during the event" (huh?)
if (type() != eventNames().mouseoutEvent)
- return relatedTarget();
+ return relatedTarget() ? relatedTarget()->toNode() : 0;
return target() ? target()->toNode() : 0;
}
diff --git a/WebCore/dom/MouseEvent.h b/WebCore/dom/MouseEvent.h
index aa3eee5..7454b04 100644
--- a/WebCore/dom/MouseEvent.h
+++ b/WebCore/dom/MouseEvent.h
@@ -25,7 +25,6 @@
#define MouseEvent_h
#include "Clipboard.h"
-#include "EventTargetNode.h"
#include "MouseRelatedEvent.h"
namespace WebCore {
@@ -40,7 +39,7 @@ namespace WebCore {
static PassRefPtr<MouseEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
int detail, int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTargetNode> relatedTarget, PassRefPtr<Clipboard> clipboard = 0, bool isSimulated = false)
+ PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard> clipboard = 0, bool isSimulated = false)
{
return adoptRef(new MouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, pageX, pageY,
ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget, clipboard, isSimulated));
@@ -50,13 +49,13 @@ namespace WebCore {
void initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
int detail, int screenX, int screenY, int clientX, int clientY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTargetNode> relatedTarget);
+ unsigned short button, PassRefPtr<EventTarget> relatedTarget);
// WinIE uses 1,4,2 for left/middle/right but not for click (just for mousedown/up, maybe others),
// but we will match the standard DOM.
unsigned short button() const { return m_button; }
bool buttonDown() const { return m_buttonDown; }
- EventTargetNode* relatedTarget() const { return m_relatedTarget.get(); }
+ EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
Clipboard* clipboard() const { return m_clipboard.get(); }
@@ -74,11 +73,11 @@ namespace WebCore {
MouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
int detail, int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTargetNode> relatedTarget, PassRefPtr<Clipboard> clipboard, bool isSimulated);
+ PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard> clipboard, bool isSimulated);
unsigned short m_button;
bool m_buttonDown;
- RefPtr<EventTargetNode> m_relatedTarget;
+ RefPtr<EventTarget> m_relatedTarget;
RefPtr<Clipboard> m_clipboard;
};
diff --git a/WebCore/dom/MouseRelatedEvent.cpp b/WebCore/dom/MouseRelatedEvent.cpp
index a69c8a7..c66b0a8 100644
--- a/WebCore/dom/MouseRelatedEvent.cpp
+++ b/WebCore/dom/MouseRelatedEvent.cpp
@@ -97,6 +97,8 @@ void MouseRelatedEvent::initCoordinates()
m_layerY = m_pageY;
m_offsetX = m_pageX;
m_offsetY = m_pageY;
+
+ computePageLocation();
}
void MouseRelatedEvent::initCoordinates(int clientX, int clientY)
@@ -112,6 +114,14 @@ void MouseRelatedEvent::initCoordinates(int clientX, int clientY)
m_layerY = m_pageY;
m_offsetX = m_pageX;
m_offsetY = m_pageY;
+
+ computePageLocation();
+}
+
+void MouseRelatedEvent::computePageLocation()
+{
+ float zoomFactor = (view() && view()->frame()) ? view()->frame()->pageZoomFactor() : 1.0f;
+ setAbsoluteLocation(roundedIntPoint(FloatPoint(pageX() * zoomFactor, pageY() * zoomFactor)));
}
void MouseRelatedEvent::receivedTarget()
@@ -133,9 +143,10 @@ void MouseRelatedEvent::receivedTarget()
// Adjust offsetX/Y to be relative to the target's position.
if (!isSimulated()) {
if (RenderObject* r = targ->renderer()) {
- FloatPoint absPos = r->absoluteToLocal(FloatPoint(m_pageX, m_pageY), false, true);
- m_offsetX = absPos.x();
- m_offsetY = absPos.y();
+ FloatPoint localPos = r->absoluteToLocal(absoluteLocation(), false, true);
+ float zoomFactor = (view() && view()->frame()) ? view()->frame()->pageZoomFactor() : 1.0f;
+ m_offsetX = lroundf(localPos.x() / zoomFactor);
+ m_offsetY = lroundf(localPos.y() / zoomFactor);
}
}
@@ -151,8 +162,8 @@ void MouseRelatedEvent::receivedTarget()
RenderLayer* layer = n->renderer()->enclosingLayer();
layer->updateLayerPosition();
for (; layer; layer = layer->parent()) {
- m_layerX -= layer->xPos();
- m_layerY -= layer->yPos();
+ m_layerX -= layer->x();
+ m_layerY -= layer->y();
}
}
}
diff --git a/WebCore/dom/MouseRelatedEvent.h b/WebCore/dom/MouseRelatedEvent.h
index 35c65dd..7649aa9 100644
--- a/WebCore/dom/MouseRelatedEvent.h
+++ b/WebCore/dom/MouseRelatedEvent.h
@@ -26,6 +26,7 @@
#ifndef MouseRelatedEvent_h
#define MouseRelatedEvent_h
+#include "IntPoint.h"
#include "UIEventWithKeyState.h"
namespace WebCore {
@@ -33,6 +34,8 @@ namespace WebCore {
// Internal only: Helper class for what's common between mouse and wheel events.
class MouseRelatedEvent : public UIEventWithKeyState {
public:
+ // Note that these values are adjusted to counter the effects of zoom, so that values
+ // exposed via DOM APIs are invariant under zooming.
int screenX() const { return m_screenX; }
int screenY() const { return m_screenY; }
int clientX() const { return m_clientX; }
@@ -46,6 +49,11 @@ namespace WebCore {
virtual int pageY() const;
int x() const;
int y() const;
+
+ // Page point in "absolute" coordinates (i.e. post-zoomed, page-relative coords,
+ // usable with RenderObject::absoluteToLocal).
+ IntPoint absoluteLocation() const { return m_absoluteLocation; }
+ void setAbsoluteLocation(const IntPoint& p) { m_absoluteLocation = p; }
protected:
MouseRelatedEvent();
@@ -56,6 +64,8 @@ namespace WebCore {
void initCoordinates();
void initCoordinates(int clientX, int clientY);
virtual void receivedTarget();
+
+ void computePageLocation();
// Expose these so MouseEvent::initMouseEvent can set them.
int m_screenX;
@@ -70,6 +80,7 @@ namespace WebCore {
int m_layerY;
int m_offsetX;
int m_offsetY;
+ IntPoint m_absoluteLocation;
bool m_isSimulated;
};
diff --git a/WebCore/dom/NamedAttrMap.cpp b/WebCore/dom/NamedAttrMap.cpp
index 8944b79..33c60d3 100644
--- a/WebCore/dom/NamedAttrMap.cpp
+++ b/WebCore/dom/NamedAttrMap.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, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* (C) 2007 Eric Seidel (eric@webkit.org)
*
* This library is free software; you can redistribute it and/or
@@ -39,9 +39,18 @@ static inline bool shouldIgnoreAttributeCase(const Element* e)
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
}
+inline void NamedAttrMap::detachAttributesFromElement()
+{
+ size_t size = m_attributes.size();
+ for (size_t i = 0; i < size; i++) {
+ if (Attr* attr = m_attributes[i]->attr())
+ attr->m_element = 0;
+ }
+}
+
NamedAttrMap::~NamedAttrMap()
{
- NamedAttrMap::clearAttributes(); // virtual function, qualify to be explicit and slightly faster
+ detachAttributesFromElement();
}
bool NamedAttrMap::isMappedAttributeMap() const
@@ -190,11 +199,7 @@ Attribute* NamedAttrMap::getAttributeItem(const QualifiedName& name) const
void NamedAttrMap::clearAttributes()
{
- unsigned len = length();
- for (unsigned i = 0; i < len; i++)
- if (Attr* attr = m_attributes[i]->attr())
- attr->m_element = 0;
-
+ detachAttributesFromElement();
m_attributes.clear();
}
@@ -203,7 +208,7 @@ void NamedAttrMap::detachFromElement()
// we allow a NamedAttrMap w/o an element in case someone still has a reference
// to if after the element gets deleted - but the map is now invalid
m_element = 0;
- clearAttributes();
+ detachAttributesFromElement();
}
void NamedAttrMap::setAttributes(const NamedAttrMap& other)
@@ -310,4 +315,9 @@ bool NamedAttrMap::mapsEquivalent(const NamedAttrMap* otherMap) const
return true;
}
+size_t NamedAttrMap::virtualLength() const
+{
+ return length();
+}
+
}
diff --git a/WebCore/dom/NamedAttrMap.h b/WebCore/dom/NamedAttrMap.h
index 693a9e5..61628e4 100644
--- a/WebCore/dom/NamedAttrMap.h
+++ b/WebCore/dom/NamedAttrMap.h
@@ -1,11 +1,9 @@
/*
- * 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 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,7 +27,6 @@
#include "Attribute.h"
#include "NamedNodeMap.h"
-#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#ifdef __OBJC__
@@ -50,28 +47,12 @@ public:
void setAttributes(const NamedAttrMap&);
- // DOM methods & attributes for NamedNodeMap
-
- virtual PassRefPtr<Node> getNamedItem(const String& name) const;
- virtual PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&);
-
- virtual PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
- virtual PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&);
-
- virtual PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
- virtual PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
- virtual PassRefPtr<Node> setNamedItem(Node* arg, ExceptionCode&);
-
- virtual PassRefPtr<Node> item(unsigned index) const;
size_t length() const { return m_attributes.size(); }
-
- // Other methods (not part of DOM)
Attribute* attributeItem(unsigned index) const { return m_attributes[index].get(); }
- Attribute* getAttributeItem(const QualifiedName& name) const;
- Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
-
+ Attribute* getAttributeItem(const QualifiedName&) const;
+
void shrinkToLength() { m_attributes.shrinkCapacity(length()); }
- void reserveCapacity(unsigned capacity) { m_attributes.reserveCapacity(capacity); }
+ void reserveInitialCapacity(unsigned capacity) { m_attributes.reserveInitialCapacity(capacity); }
// used during parsing: only inserts if not already there
// no error checking!
@@ -83,20 +64,38 @@ public:
}
virtual bool isMappedAttributeMap() const;
-
- const AtomicString& id() const { return m_id; }
- void setID(const AtomicString& _id) { m_id = _id; }
+ const AtomicString& id() const { return m_id; }
+ void setID(const AtomicString& newId) { m_id = newId; }
+
bool mapsEquivalent(const NamedAttrMap* otherMap) const;
- // These functions are internal, and do no error checking.
+ // These functions do no error checking.
void addAttribute(PassRefPtr<Attribute>);
- void removeAttribute(const QualifiedName& name);
+ void removeAttribute(const QualifiedName&);
protected:
virtual void clearAttributes();
+ Element* element() const { return m_element; }
+
+private:
+ void detachAttributesFromElement();
void detachFromElement();
+ Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
+
+ virtual PassRefPtr<Node> getNamedItem(const String& name) const;
+ virtual PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&);
+
+ virtual PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
+ virtual PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&);
+
+ virtual PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
+ virtual PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
+ virtual PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&);
+
+ virtual PassRefPtr<Node> item(unsigned index) const;
+ virtual size_t virtualLength() const;
Element* m_element;
Vector<RefPtr<Attribute> > m_attributes;
diff --git a/WebCore/dom/NamedMappedAttrMap.cpp b/WebCore/dom/NamedMappedAttrMap.cpp
index bc2d999..cff4997 100644
--- a/WebCore/dom/NamedMappedAttrMap.cpp
+++ b/WebCore/dom/NamedMappedAttrMap.cpp
@@ -75,12 +75,12 @@ bool NamedMappedAttrMap::mapsEquivalent(const NamedMappedAttrMap* otherMap) cons
void NamedMappedAttrMap::setClass(const String& classStr)
{
- if (!m_element->hasClass()) {
+ if (!element()->hasClass()) {
m_classNames.clear();
return;
}
- m_classNames.set(classStr, m_element->document()->inCompatMode());
+ m_classNames.set(classStr, element()->document()->inCompatMode());
}
}
diff --git a/WebCore/dom/NamedMappedAttrMap.h b/WebCore/dom/NamedMappedAttrMap.h
index c4deddc..9267f89 100644
--- a/WebCore/dom/NamedMappedAttrMap.h
+++ b/WebCore/dom/NamedMappedAttrMap.h
@@ -4,7 +4,7 @@
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 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
@@ -27,32 +27,33 @@
#define NamedMappedAttrMap_h
#include "ClassNames.h"
-#include "MappedAttribute.h"
+#include "MappedAttribute.h" // This header is not required for the NamedMappedAttrMap definition. Should remove it.
#include "NamedAttrMap.h"
namespace WebCore {
class NamedMappedAttrMap : public NamedAttrMap {
-private:
- NamedMappedAttrMap(Element* element) : NamedAttrMap(element), m_mappedAttributeCount(0) { }
public:
static PassRefPtr<NamedMappedAttrMap> create(Element* element = 0) { return adoptRef(new NamedMappedAttrMap(element)); }
- virtual void clearAttributes();
- virtual bool isMappedAttributeMap() const;
-
void clearClass() { m_classNames.clear(); }
void setClass(const String&);
const ClassNames& classNames() const { return m_classNames; }
- virtual bool hasMappedAttributes() const { return m_mappedAttributeCount > 0; }
+ bool hasMappedAttributes() const { return m_mappedAttributeCount > 0; }
void declRemoved() { m_mappedAttributeCount--; }
void declAdded() { m_mappedAttributeCount++; }
-
+
bool mapsEquivalent(const NamedMappedAttrMap*) const;
- int declCount() const;
private:
+ NamedMappedAttrMap(Element* element) : NamedAttrMap(element), m_mappedAttributeCount(0) { }
+
+ virtual void clearAttributes();
+ virtual bool isMappedAttributeMap() const;
+
+ int declCount() const;
+
ClassNames m_classNames;
int m_mappedAttributeCount;
};
diff --git a/WebCore/dom/NamedNodeMap.h b/WebCore/dom/NamedNodeMap.h
index 504af69..08e6efb 100644
--- a/WebCore/dom/NamedNodeMap.h
+++ b/WebCore/dom/NamedNodeMap.h
@@ -56,7 +56,10 @@ public:
virtual PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&) = 0;
virtual PassRefPtr<Node> item(unsigned index) const = 0;
- virtual size_t length() const = 0;
+ size_t length() const { return virtualLength(); }
+
+private:
+ virtual size_t virtualLength() const = 0;
};
} //namespace
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index eb591a7..bd8f497 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
@@ -44,25 +44,55 @@
#include "Document.h"
#include "DynamicNodeList.h"
#include "Element.h"
+#include "Event.h"
+#include "EventException.h"
+#include "EventHandler.h"
+#include "EventListener.h"
+#include "EventNames.h"
#include "ExceptionCode.h"
#include "Frame.h"
+#include "FrameView.h"
#include "HTMLNames.h"
#include "JSDOMBinding.h"
+#include "KeyboardEvent.h"
#include "Logging.h"
+#include "MouseEvent.h"
+#include "MutationEvent.h"
#include "NameNodeList.h"
#include "NamedAttrMap.h"
#include "NodeRareData.h"
+#include "Page.h"
+#include "PlatformMouseEvent.h"
+#include "PlatformWheelEvent.h"
#include "ProcessingInstruction.h"
+#include "ProgressEvent.h"
+#include "RegisteredEventListener.h"
#include "RenderObject.h"
#include "ScriptController.h"
#include "SelectorNodeList.h"
#include "StringBuilder.h"
#include "TagNodeList.h"
#include "Text.h"
+#include "TextEvent.h"
+#include "UIEvent.h"
+#include "UIEventWithKeyState.h"
+#include "WebKitAnimationEvent.h"
+#include "WebKitTransitionEvent.h"
+#include "WheelEvent.h"
#include "XMLNames.h"
#include "htmlediting.h"
+#include <wtf/HashSet.h>
#include <wtf/RefCountedLeakCounter.h>
+#if ENABLE(DOM_STORAGE)
+#include "StorageEvent.h"
+#endif
+
+#if ENABLE(SVG)
+#include "SVGElementInstance.h"
+#include "SVGUseElement.h"
+#endif
+
#define DUMP_NODE_STATISTICS 0
using namespace std;
@@ -71,6 +101,8 @@ namespace WebCore {
using namespace HTMLNames;
+static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;
+
bool Node::isSupported(const String& feature, const String& version)
{
return DOMImplementation::hasFeature(feature, version);
@@ -255,9 +287,9 @@ Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 )
// style in cases where you need to.
StyleChange ch = NoInherit;
EDisplay display1 = s1 ? s1->display() : NONE;
- bool fl1 = s1 && s1->hasPseudoStyle(RenderStyle::FIRST_LETTER);
+ bool fl1 = s1 && s1->hasPseudoStyle(FIRST_LETTER);
EDisplay display2 = s2 ? s2->display() : NONE;
- bool fl2 = s2 && s2->hasPseudoStyle(RenderStyle::FIRST_LETTER);
+ bool fl2 = s2 && s2->hasPseudoStyle(FIRST_LETTER);
if (display1 != display2 || fl1 != fl2 || (s1 && s2 && !s1->contentDataEquivalent(s2)))
ch = Detach;
@@ -270,21 +302,21 @@ Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 )
// If the pseudoStyles have changed, we want any StyleChange that is not NoChange
// because setStyle will do the right thing with anything else.
- if (ch == NoChange && s1->hasPseudoStyle(RenderStyle::BEFORE)) {
- RenderStyle* ps2 = s2->getCachedPseudoStyle(RenderStyle::BEFORE);
+ if (ch == NoChange && s1->hasPseudoStyle(BEFORE)) {
+ RenderStyle* ps2 = s2->getCachedPseudoStyle(BEFORE);
if (!ps2)
ch = NoInherit;
else {
- RenderStyle* ps1 = s1->getCachedPseudoStyle(RenderStyle::BEFORE);
+ RenderStyle* ps1 = s1->getCachedPseudoStyle(BEFORE);
ch = ps1 && *ps1 == *ps2 ? NoChange : NoInherit;
}
}
- if (ch == NoChange && s1->hasPseudoStyle(RenderStyle::AFTER)) {
- RenderStyle* ps2 = s2->getCachedPseudoStyle(RenderStyle::AFTER);
+ if (ch == NoChange && s1->hasPseudoStyle(AFTER)) {
+ RenderStyle* ps2 = s2->getCachedPseudoStyle(AFTER);
if (!ps2)
ch = NoInherit;
else {
- RenderStyle* ps1 = s1->getCachedPseudoStyle(RenderStyle::AFTER);
+ RenderStyle* ps1 = s1->getCachedPseudoStyle(AFTER);
ch = ps2 && *ps1 == *ps2 ? NoChange : NoInherit;
}
}
@@ -348,6 +380,9 @@ Node::~Node()
liveNodeSet.remove(this);
#endif
+ if (!eventListeners().isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
if (!hasRareData())
ASSERT(!NodeRareData::rareDataMap().contains(this));
else {
@@ -583,7 +618,12 @@ bool Node::shouldUseInputMethod() const
RenderBox* Node::renderBox() const
{
- return m_renderer && m_renderer->isBox() ? static_cast<RenderBox*>(m_renderer) : 0;
+ return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0;
+}
+
+RenderBoxModelObject* Node::renderBoxModelObject() const
+{
+ return m_renderer && m_renderer->isBoxModelObject() ? toRenderBoxModelObject(m_renderer) : 0;
}
IntRect Node::getRect() const
@@ -1081,21 +1121,6 @@ void Node::detach()
m_inDetach = false;
}
-void Node::insertedIntoDocument()
-{
- setInDocument(true);
- insertedIntoTree(false);
-}
-
-void Node::removedFromDocument()
-{
- if (m_document && m_document->getCSSTarget() == this)
- m_document->setCSSTarget(0);
-
- setInDocument(false);
- removedFromTree(false);
-}
-
Node *Node::previousEditable() const
{
Node *node = previousLeafNode();
@@ -1317,7 +1342,7 @@ bool Node::isBlockFlow() const
bool Node::isBlockFlowOrBlockTable() const
{
- return renderer() && (renderer()->isBlockFlow() || renderer()->isTable() && !renderer()->isInline());
+ return renderer() && (renderer()->isBlockFlow() || (renderer()->isTable() && !renderer()->isInline()));
}
bool Node::isEditableBlock() const
@@ -1984,6 +2009,36 @@ unsigned short Node::compareDocumentPosition(Node* otherNode)
DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS;
}
+FloatPoint Node::convertToPage(const FloatPoint& p) const
+{
+ // If there is a renderer, just ask it to do the conversion
+ if (renderer())
+ return renderer()->localToAbsolute(p, false, true);
+
+ // Otherwise go up the tree looking for a renderer
+ Element *parent = ancestorElement();
+ if (parent)
+ return parent->convertToPage(p);
+
+ // No parent - no conversion needed
+ return p;
+}
+
+FloatPoint Node::convertFromPage(const FloatPoint& p) const
+{
+ // If there is a renderer, just ask it to do the conversion
+ if (renderer())
+ return renderer()->absoluteToLocal(p, false, true);
+
+ // Otherwise go up the tree looking for a renderer
+ Element *parent = ancestorElement();
+ if (parent)
+ return parent->convertFromPage(p);
+
+ // No parent - no conversion needed
+ return p;
+}
+
#if !defined(NDEBUG) || defined(ANDROID_DOM_LOGGING)
static void appendAttributeDesc(const Node* node, String& string, const QualifiedName& name, const char* attrDesc)
@@ -2177,6 +2232,1157 @@ size_t Node::reportDOMNodesSize()
// --------
+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);
+}
+
+void Node::didMoveToNewOwnerDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->registerDisconnectedNodeWithEventListeners(this);
+}
+
+static inline void updateSVGElementInstancesAfterEventListenerChange(Node* referenceNode)
+{
+ ASSERT(referenceNode);
+
+#if ENABLE(SVG)
+ if (!referenceNode->isSVGElement())
+ return;
+
+ // Elements living inside a <use> shadow tree, never cause any updates!
+ if (referenceNode->shadowTreeRootNode())
+ return;
+
+ // We're possibly (a child of) an element that is referenced by a <use> client
+ // If an event listeners changes on a referenced element, update all instances.
+ for (Node* node = referenceNode; node; node = node->parentNode()) {
+ if (!node->hasID() || !node->isSVGElement())
+ continue;
+
+ SVGElementInstance::invalidateAllInstancesOfElement(static_cast<SVGElement*>(node));
+ break;
+ }
+#endif
+}
+
+void 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);
+
+ listeners.append(RegisteredEventListener::create(eventType, listener, useCapture));
+ updateSVGElementInstancesAfterEventListenerChange(this);
+
+#if ENABLE(TOUCH_EVENTS) // Android
+ if (eventType == eventNames().touchstartEvent ||
+ eventType == eventNames().touchendEvent ||
+ eventType == eventNames().touchmoveEvent ||
+ eventType == eventNames().touchcancelEvent)
+ document->addTouchEventListener(this);
+#endif
+}
+
+void 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);
+
+ // removed last
+ if (listeners->isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ updateSVGElementInstancesAfterEventListenerChange(this);
+#if ENABLE(TOUCH_EVENTS) // Android
+ if (eventType == eventNames().touchstartEvent ||
+ eventType == eventNames().touchendEvent ||
+ eventType == eventNames().touchmoveEvent ||
+ eventType == eventNames().touchcancelEvent)
+ document()->removeTouchEventListener(this);
+#endif
+ return;
+ }
+ }
+}
+
+void Node::removeAllEventListenersSlowCase()
+{
+ ASSERT(hasRareData());
+
+ RegisteredEventListenerVector* listeners = rareData()->listeners();
+ if (!listeners)
+ return;
+
+#if ENABLE(TOUCH_EVENTS) // Android
+ document()->removeTouchEventListener(this);
+#endif
+
+ size_t size = listeners->size();
+ for (size_t i = 0; i < size; ++i)
+ listeners->at(i)->setRemoved(true);
+ listeners->clear();
+}
+
+void Node::handleLocalEvents(Event* event, bool useCapture)
+{
+ 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);
+ }
+}
+
+#if ENABLE(SVG)
+static inline SVGElementInstance* eventTargetAsSVGElementInstance(Node* referenceNode)
+{
+ ASSERT(referenceNode);
+ if (!referenceNode->isSVGElement())
+ return 0;
+
+ // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
+ // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
+ for (Node* n = referenceNode; n; n = n->parentNode()) {
+ if (!n->isShadowNode() || !n->isSVGElement())
+ continue;
+
+ Node* shadowTreeParentElement = n->shadowParentNode();
+ ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
+
+ if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
+ return instance;
+ }
+
+ return 0;
+}
+#endif
+
+static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode)
+{
+ ASSERT(referenceNode);
+
+#if ENABLE(SVG)
+ if (SVGElementInstance* instance = eventTargetAsSVGElementInstance(referenceNode)) {
+ ASSERT(instance->shadowTreeElement() == referenceNode);
+ return instance;
+ }
+#endif
+
+ return referenceNode;
+}
+
+bool Node::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
+{
+ RefPtr<Event> evt(e);
+ ASSERT(!eventDispatchForbidden());
+ if (!evt || evt->type().isEmpty()) {
+ ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
+ return false;
+ }
+
+ evt->setTarget(eventTargetRespectingSVGTargetRules(this));
+
+ RefPtr<FrameView> view = document()->view();
+ return dispatchGenericEvent(evt.release());
+}
+
+bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
+{
+ RefPtr<Event> event(prpEvent);
+
+ ASSERT(!eventDispatchForbidden());
+ ASSERT(event->target());
+ ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
+
+ // 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);
+ }
+ }
+
+ // Set up a pointer to indicate whether to dispatch window events.
+ // We don't dispatch load events to the window. That quirk was originally
+ // added because Mozilla doesn't propagate load events to the window object.
+ Document* documentForWindowEvents = 0;
+ if (event->type() != eventNames().loadEvent) {
+ Node* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get();
+ if (topLevelContainer->isDocumentNode())
+ documentForWindowEvents = static_cast<Document*>(topLevelContainer);
+ }
+
+ // Give the target node a chance to do some work before DOM event handlers get a crack.
+ void* data = preDispatchEventHandler(event.get());
+ if (event->propagationStopped())
+ goto doneDispatching;
+
+ // Trigger capturing event handlers, starting at the top and working our way down.
+ event->setEventPhase(Event::CAPTURING_PHASE);
+
+ if (documentForWindowEvents) {
+ event->setCurrentTarget(documentForWindowEvents);
+ documentForWindowEvents->handleWindowEvent(event.get(), true);
+ 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);
+ 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);
+ if (event->propagationStopped())
+ goto doneDispatching;
+
+ if (event->bubbles() && !event->cancelBubble()) {
+ // Trigger bubbling event handlers, starting at the bottom and working our way up.
+ event->setEventPhase(Event::BUBBLING_PHASE);
+
+ size_t size = ancestors.size();
+ for (size_t i = 0; i < size; ++i) {
+ ContainerNode* ancestor = ancestors[i].get();
+ event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
+ ancestor->handleLocalEvents(event.get(), false);
+ if (event->propagationStopped() || event->cancelBubble())
+ goto doneDispatching;
+ }
+ if (documentForWindowEvents) {
+ event->setCurrentTarget(documentForWindowEvents);
+ documentForWindowEvents->handleWindowEvent(event.get(), false);
+ if (event->propagationStopped() || event->cancelBubble())
+ goto doneDispatching;
+ }
+ }
+
+doneDispatching:
+ event->setCurrentTarget(0);
+ event->setEventPhase(0);
+
+ // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler.
+ postDispatchEventHandler(event.get(), data);
+
+ // Call default event handlers. While the DOM does have a concept of preventing
+ // default handling, the detail of which handlers are called is an internal
+ // implementation detail and not part of the DOM.
+ if (!event->defaultPrevented() && !event->defaultHandled()) {
+ // Non-bubbling events call only one default event handler, the one for the target.
+ defaultEventHandler(event.get());
+ ASSERT(!event->defaultPrevented());
+ if (event->defaultHandled())
+ goto doneWithDefault;
+ // For bubbling events, call default event handlers on the same targets in the
+ // same order as the bubbling phase.
+ if (event->bubbles()) {
+ size_t size = ancestors.size();
+ for (size_t i = 0; i < size; ++i) {
+ ContainerNode* ancestor = ancestors[i].get();
+ ancestor->defaultEventHandler(event.get());
+ ASSERT(!event->defaultPrevented());
+ if (event->defaultHandled())
+ goto doneWithDefault;
+ }
+ }
+ }
+
+doneWithDefault:
+ Document::updateDocumentsRendering();
+
+ return !event->defaultPrevented();
+}
+
+bool Node::dispatchSubtreeModifiedEvent()
+{
+ ASSERT(!eventDispatchForbidden());
+
+ document()->incDOMTreeVersion();
+
+ notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing.
+
+ if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
+ return false;
+ ExceptionCode ec = 0;
+ return dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true, false, 0, String(), String(), String(), 0), ec);
+}
+
+void Node::dispatchWindowEvent(PassRefPtr<Event> e)
+{
+ ASSERT(!eventDispatchForbidden());
+ RefPtr<Event> evt(e);
+ RefPtr<Document> doc = document();
+ evt->setTarget(doc);
+ doc->handleWindowEvent(evt.get(), true);
+ doc->handleWindowEvent(evt.get(), false);
+}
+
+void Node::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ RefPtr<Document> doc = document();
+ dispatchWindowEvent(Event::create(eventType, canBubbleArg, cancelableArg));
+
+ if (eventType == eventNames().loadEvent) {
+ // For onload events, send a separate load event to the enclosing frame only.
+ // This is a DOM extension and is independent of bubbling/capturing rules of
+ // the DOM.
+ Element* ownerElement = doc->ownerElement();
+ if (ownerElement) {
+ RefPtr<Event> ownerEvent = Event::create(eventType, false, cancelableArg);
+ ownerEvent->setTarget(ownerElement);
+ ownerElement->dispatchGenericEvent(ownerEvent.release());
+ }
+ }
+}
+
+bool Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
+{
+ ASSERT(!eventDispatchForbidden());
+ ASSERT(eventType == eventNames().DOMFocusInEvent || eventType == eventNames().DOMFocusOutEvent || eventType == eventNames().DOMActivateEvent);
+
+ bool cancelable = eventType == eventNames().DOMActivateEvent;
+
+ ExceptionCode ec = 0;
+ RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
+ evt->setUnderlyingEvent(underlyingEvent);
+ return dispatchEvent(evt.release(), ec);
+}
+
+bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& key)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView());
+ bool r = dispatchEvent(keyboardEvent, ec);
+
+ // 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
+ // let it get handled by AppKit
+ if (keyboardEvent->defaultHandled())
+ r = false;
+
+ return r;
+}
+
+bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
+ int detail, Node* relatedTarget)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ IntPoint contentsPos;
+ if (FrameView* view = document()->view())
+ contentsPos = view->windowToContents(event.pos());
+
+ short button = event.button();
+
+ ASSERT(event.eventType() == MouseEventMoved || button != NoButton);
+
+ return dispatchMouseEvent(eventType, button, detail,
+ contentsPos.x(), contentsPos.y(), event.globalX(), event.globalY(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
+ false, relatedTarget);
+}
+
+void Node::dispatchSimulatedMouseEvent(const AtomicString& eventType,
+ PassRefPtr<Event> underlyingEvent)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ bool ctrlKey = false;
+ bool altKey = false;
+ bool shiftKey = false;
+ bool metaKey = false;
+ if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) {
+ ctrlKey = keyStateEvent->ctrlKey();
+ altKey = keyStateEvent->altKey();
+ shiftKey = keyStateEvent->shiftKey();
+ metaKey = keyStateEvent->metaKey();
+ }
+
+ // Like Gecko, we just pass 0 for everything when we make a fake mouse event.
+ // Internet Explorer instead gives the current mouse position and state.
+ dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0,
+ ctrlKey, altKey, shiftKey, metaKey, true, 0, underlyingEvent);
+}
+
+void Node::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
+{
+ if (!gNodesDispatchingSimulatedClicks)
+ gNodesDispatchingSimulatedClicks = new HashSet<Node*>;
+ else if (gNodesDispatchingSimulatedClicks->contains(this))
+ return;
+
+ gNodesDispatchingSimulatedClicks->add(this);
+
+ // send mousedown and mouseup before the click, if requested
+ if (sendMouseEvents)
+ dispatchSimulatedMouseEvent(eventNames().mousedownEvent, event.get());
+ setActive(true, showPressedLook);
+ if (sendMouseEvents)
+ dispatchSimulatedMouseEvent(eventNames().mouseupEvent, event.get());
+ setActive(false);
+
+ // always send click
+ dispatchSimulatedMouseEvent(eventNames().clickEvent, event);
+
+ gNodesDispatchingSimulatedClicks->remove(this);
+}
+
+bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int detail,
+ int pageX, int pageY, int screenX, int screenY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
+ bool isSimulated, Node* relatedTargetArg, PassRefPtr<Event> underlyingEvent)
+{
+ ASSERT(!eventDispatchForbidden());
+ if (disabled()) // Don't even send DOM events for disabled controls..
+ return true;
+
+ if (eventType.isEmpty())
+ return false; // Shouldn't happen.
+
+ // Dispatching the first event can easily result in this node being destroyed.
+ // Since we dispatch up to three events here, we need to make sure we're referenced
+ // so the pointer will be good for the two subsequent ones.
+ RefPtr<Node> protect(this);
+
+ 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.
+ RefPtr<Node> relatedTarget = relatedTargetArg;
+
+ int adjustedPageX = pageX;
+ int adjustedPageY = pageY;
+ if (Frame* frame = document()->frame()) {
+ float pageZoom = frame->pageZoomFactor();
+ if (pageZoom != 1.0f) {
+ // Adjust our pageX and pageY to account for the page zoom.
+ adjustedPageX = lroundf(pageX / pageZoom);
+ adjustedPageY = lroundf(pageY / pageZoom);
+ }
+ }
+
+ RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventType,
+ true, cancelable, document()->defaultView(),
+ detail, screenX, screenY, adjustedPageX, adjustedPageY,
+ ctrlKey, altKey, shiftKey, metaKey, button,
+ relatedTarget, 0, isSimulated);
+ mouseEvent->setUnderlyingEvent(underlyingEvent.get());
+ mouseEvent->setAbsoluteLocation(IntPoint(pageX, pageY));
+
+ dispatchEvent(mouseEvent, ec);
+ bool defaultHandled = mouseEvent->defaultHandled();
+ bool defaultPrevented = mouseEvent->defaultPrevented();
+ if (defaultHandled || defaultPrevented)
+ swallowEvent = true;
+
+ // Special case: If it's a double click event, we also send the dblclick event. This is not part
+ // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
+ // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
+ if (eventType == eventNames().clickEvent && detail == 2) {
+ RefPtr<Event> doubleClickEvent = MouseEvent::create(eventNames().dblclickEvent,
+ true, cancelable, document()->defaultView(),
+ detail, screenX, screenY, pageX, pageY,
+ ctrlKey, altKey, shiftKey, metaKey, button,
+ relatedTarget, 0, isSimulated);
+ doubleClickEvent->setUnderlyingEvent(underlyingEvent.get());
+ if (defaultHandled)
+ doubleClickEvent->setDefaultHandled();
+ dispatchEvent(doubleClickEvent, ec);
+ if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
+ swallowEvent = true;
+ }
+
+ return swallowEvent;
+}
+
+void Node::dispatchWheelEvent(PlatformWheelEvent& e)
+{
+ ASSERT(!eventDispatchForbidden());
+ if (e.deltaX() == 0 && e.deltaY() == 0)
+ return;
+
+ FrameView* view = document()->view();
+ if (!view)
+ return;
+
+ IntPoint pos = view->windowToContents(e.pos());
+
+ int adjustedPageX = pos.x();
+ int adjustedPageY = pos.y();
+ if (Frame* frame = document()->frame()) {
+ float pageZoom = frame->pageZoomFactor();
+ if (pageZoom != 1.0f) {
+ // Adjust our pageX and pageY to account for the page zoom.
+ adjustedPageX = lroundf(pos.x() / pageZoom);
+ adjustedPageY = lroundf(pos.y() / pageZoom);
+ }
+ }
+
+ RefPtr<WheelEvent> we = WheelEvent::create(e.wheelTicksX(), e.wheelTicksY(),
+ document()->defaultView(), e.globalX(), e.globalY(), adjustedPageX, adjustedPageY,
+ e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey());
+
+ we->setAbsoluteLocation(IntPoint(pos.x(), pos.y()));
+
+ ExceptionCode ec = 0;
+ if (!dispatchEvent(we.release(), ec))
+ e.accept();
+}
+
+bool Node::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ ExceptionCode ec = 0;
+ return dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec);
+}
+
+bool Node::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ ExceptionCode ec = 0;
+ return dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec);
+}
+
+void Node::dispatchFocusEvent()
+{
+ dispatchEventForType(eventNames().focusEvent, false, false);
+}
+
+void Node::dispatchBlurEvent()
+{
+ dispatchEventForType(eventNames().blurEvent, false, false);
+}
+
+bool Node::dispatchEventForType(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec);
+}
+
+bool Node::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ return dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec);
+}
+
+void Node::dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source)
+{
+#if ENABLE(DOM_STORAGE)
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ dispatchEvent(StorageEvent::create(eventType, key, oldValue, newValue, source->document()->documentURI(), source->domWindow()), ec);
+#endif
+}
+
+void Node::removeInlineEventListenerForType(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()->isInline())
+ continue;
+
+ r.setRemoved(true);
+ listeners->remove(i);
+
+ // removed last
+ if (listeners->isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ updateSVGElementInstancesAfterEventListenerChange(this);
+ return;
+ }
+}
+
+void Node::setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+{
+ // In case we are the only one holding a reference to it, we don't want removeInlineEventListenerForType to destroy it.
+ removeInlineEventListenerForType(eventType);
+ if (listener)
+ addEventListener(eventType, listener, false);
+}
+
+void Node::setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute* attr)
+{
+ setInlineEventListenerForType(eventType, document()->createEventListener(attr->localName().string(), attr->value(), this));
+}
+
+EventListener* Node::inlineEventListenerForType(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()->isInline())
+ return r.listener();
+ }
+ return 0;
+}
+
+bool Node::disabled() const
+{
+ return false;
+}
+
+void Node::defaultEventHandler(Event* event)
+{
+ if (event->target() != this)
+ return;
+ const AtomicString& eventType = event->type();
+ if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) {
+ if (event->isKeyboardEvent())
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->defaultKeyboardEventHandler(static_cast<KeyboardEvent*>(event));
+ } else if (eventType == eventNames().clickEvent) {
+ int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
+ dispatchUIEvent(eventNames().DOMActivateEvent, detail, event);
+ } else if (eventType == eventNames().contextmenuEvent) {
+ if (Frame* frame = document()->frame())
+ if (Page* page = frame->page())
+ page->contextMenuController()->handleContextMenuEvent(event);
+ } else if (eventType == eventNames().textInputEvent) {
+ if (event->isTextEvent())
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event));
+ }
+}
+
+EventListener* Node::onabort() const
+{
+ return inlineEventListenerForType(eventNames().abortEvent);
+}
+
+void Node::setOnabort(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().abortEvent, eventListener);
+}
+
+EventListener* Node::onblur() const
+{
+ return inlineEventListenerForType(eventNames().blurEvent);
+}
+
+void Node::setOnblur(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().blurEvent, eventListener);
+}
+
+EventListener* Node::onchange() const
+{
+ return inlineEventListenerForType(eventNames().changeEvent);
+}
+
+void Node::setOnchange(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().changeEvent, eventListener);
+}
+
+EventListener* Node::onclick() const
+{
+ return inlineEventListenerForType(eventNames().clickEvent);
+}
+
+void Node::setOnclick(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().clickEvent, eventListener);
+}
+
+EventListener* Node::oncontextmenu() const
+{
+ return inlineEventListenerForType(eventNames().contextmenuEvent);
+}
+
+void Node::setOncontextmenu(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener);
+}
+
+EventListener* Node::ondblclick() const
+{
+ return inlineEventListenerForType(eventNames().dblclickEvent);
+}
+
+void Node::setOndblclick(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dblclickEvent, eventListener);
+}
+
+EventListener* Node::onerror() const
+{
+ return inlineEventListenerForType(eventNames().errorEvent);
+}
+
+void Node::setOnerror(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().errorEvent, eventListener);
+}
+
+EventListener* Node::onfocus() const
+{
+ return inlineEventListenerForType(eventNames().focusEvent);
+}
+
+void Node::setOnfocus(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().focusEvent, eventListener);
+}
+
+EventListener* Node::oninput() const
+{
+ return inlineEventListenerForType(eventNames().inputEvent);
+}
+
+void Node::setOninput(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().inputEvent, eventListener);
+}
+
+EventListener* Node::onkeydown() const
+{
+ return inlineEventListenerForType(eventNames().keydownEvent);
+}
+
+void Node::setOnkeydown(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keydownEvent, eventListener);
+}
+
+EventListener* Node::onkeypress() const
+{
+ return inlineEventListenerForType(eventNames().keypressEvent);
+}
+
+void Node::setOnkeypress(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keypressEvent, eventListener);
+}
+
+EventListener* Node::onkeyup() const
+{
+ return inlineEventListenerForType(eventNames().keyupEvent);
+}
+
+void Node::setOnkeyup(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keyupEvent, eventListener);
+}
+
+EventListener* Node::onload() const
+{
+ return inlineEventListenerForType(eventNames().loadEvent);
+}
+
+void Node::setOnload(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().loadEvent, eventListener);
+}
+
+EventListener* Node::onmousedown() const
+{
+ return inlineEventListenerForType(eventNames().mousedownEvent);
+}
+
+void Node::setOnmousedown(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousedownEvent, eventListener);
+}
+
+EventListener* Node::onmousemove() const
+{
+ return inlineEventListenerForType(eventNames().mousemoveEvent);
+}
+
+void Node::setOnmousemove(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener);
+}
+
+EventListener* Node::onmouseout() const
+{
+ return inlineEventListenerForType(eventNames().mouseoutEvent);
+}
+
+void Node::setOnmouseout(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener);
+}
+
+EventListener* Node::onmouseover() const
+{
+ return inlineEventListenerForType(eventNames().mouseoverEvent);
+}
+
+void Node::setOnmouseover(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener);
+}
+
+EventListener* Node::onmouseup() const
+{
+ return inlineEventListenerForType(eventNames().mouseupEvent);
+}
+
+void Node::setOnmouseup(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseupEvent, eventListener);
+}
+
+EventListener* Node::onmousewheel() const
+{
+ return inlineEventListenerForType(eventNames().mousewheelEvent);
+}
+
+void Node::setOnmousewheel(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener);
+}
+
+EventListener* Node::onbeforecut() const
+{
+ return inlineEventListenerForType(eventNames().beforecutEvent);
+}
+
+void Node::setOnbeforecut(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().beforecutEvent, eventListener);
+}
+
+EventListener* Node::oncut() const
+{
+ return inlineEventListenerForType(eventNames().cutEvent);
+}
+
+void Node::setOncut(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().cutEvent, eventListener);
+}
+
+EventListener* Node::onbeforecopy() const
+{
+ return inlineEventListenerForType(eventNames().beforecopyEvent);
+}
+
+void Node::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener);
+}
+
+EventListener* Node::oncopy() const
+{
+ return inlineEventListenerForType(eventNames().copyEvent);
+}
+
+void Node::setOncopy(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().copyEvent, eventListener);
+}
+
+EventListener* Node::onbeforepaste() const
+{
+ return inlineEventListenerForType(eventNames().beforepasteEvent);
+}
+
+void Node::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener);
+}
+
+EventListener* Node::onpaste() const
+{
+ return inlineEventListenerForType(eventNames().pasteEvent);
+}
+
+void Node::setOnpaste(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().pasteEvent, eventListener);
+}
+
+EventListener* Node::ondragenter() const
+{
+ return inlineEventListenerForType(eventNames().dragenterEvent);
+}
+
+void Node::setOndragenter(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragenterEvent, eventListener);
+}
+
+EventListener* Node::ondragover() const
+{
+ return inlineEventListenerForType(eventNames().dragoverEvent);
+}
+
+void Node::setOndragover(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragoverEvent, eventListener);
+}
+
+EventListener* Node::ondragleave() const
+{
+ return inlineEventListenerForType(eventNames().dragleaveEvent);
+}
+
+void Node::setOndragleave(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener);
+}
+
+EventListener* Node::ondrop() const
+{
+ return inlineEventListenerForType(eventNames().dropEvent);
+}
+
+void Node::setOndrop(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dropEvent, eventListener);
+}
+
+EventListener* Node::ondragstart() const
+{
+ return inlineEventListenerForType(eventNames().dragstartEvent);
+}
+
+void Node::setOndragstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragstartEvent, eventListener);
+}
+
+EventListener* Node::ondrag() const
+{
+ return inlineEventListenerForType(eventNames().dragEvent);
+}
+
+void Node::setOndrag(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragEvent, eventListener);
+}
+
+EventListener* Node::ondragend() const
+{
+ return inlineEventListenerForType(eventNames().dragendEvent);
+}
+
+void Node::setOndragend(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragendEvent, eventListener);
+}
+
+EventListener* Node::onreset() const
+{
+ return inlineEventListenerForType(eventNames().resetEvent);
+}
+
+void Node::setOnreset(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().resetEvent, eventListener);
+}
+
+EventListener* Node::onresize() const
+{
+ return inlineEventListenerForType(eventNames().resizeEvent);
+}
+
+void Node::setOnresize(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().resizeEvent, eventListener);
+}
+
+EventListener* Node::onscroll() const
+{
+ return inlineEventListenerForType(eventNames().scrollEvent);
+}
+
+void Node::setOnscroll(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().scrollEvent, eventListener);
+}
+
+EventListener* Node::onsearch() const
+{
+ return inlineEventListenerForType(eventNames().searchEvent);
+}
+
+void Node::setOnsearch(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().searchEvent, eventListener);
+}
+
+EventListener* Node::onselect() const
+{
+ return inlineEventListenerForType(eventNames().selectEvent);
+}
+
+void Node::setOnselect(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().selectEvent, eventListener);
+}
+
+EventListener* Node::onselectstart() const
+{
+ return inlineEventListenerForType(eventNames().selectstartEvent);
+}
+
+void Node::setOnselectstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().selectstartEvent, eventListener);
+}
+
+EventListener* Node::onsubmit() const
+{
+ return inlineEventListenerForType(eventNames().submitEvent);
+}
+
+void Node::setOnsubmit(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().submitEvent, eventListener);
+}
+
+EventListener* Node::onunload() const
+{
+ return inlineEventListenerForType(eventNames().unloadEvent);
+}
+
+void Node::setOnunload(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().unloadEvent, eventListener);
+}
+
+#if ENABLE(TOUCH_EVENTS) // Android
+EventListener* Node::ontouchstart() const
+{
+ return inlineEventListenerForType(eventNames().touchstartEvent);
+}
+
+void Node::setOntouchstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchstartEvent, eventListener);
+}
+
+EventListener* Node::ontouchend() const
+{
+ return inlineEventListenerForType(eventNames().touchendEvent);
+}
+
+void Node::setOntouchend(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchendEvent, eventListener);
+}
+
+EventListener* Node::ontouchmove() const
+{
+ return inlineEventListenerForType(eventNames().touchmoveEvent);
+}
+
+void Node::setOntouchmove(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchmoveEvent, eventListener);
+}
+
+EventListener* Node::ontouchcancel() const
+{
+ return inlineEventListenerForType(eventNames().touchcancelEvent);
+}
+
+void Node::setOntouchcancel(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchcancelEvent, eventListener);
+}
+#endif // ENABLE(TOUCH_EVENT)
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index fa9995d..01f2736 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.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, 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,9 +25,11 @@
#define Node_h
#include "DocPtr.h"
+#include "EventTarget.h"
#include "KURLHash.h"
#include "PlatformString.h"
#include "TreeShared.h"
+#include "FloatPoint.h"
#include <wtf/Assertions.h>
#include <wtf/ListHashSet.h>
#include <wtf/OwnPtr.h>
@@ -36,30 +38,36 @@
namespace WebCore {
class AtomicString;
+class Attribute;
class ContainerNode;
class Document;
class DynamicNodeList;
class Element;
class Event;
class EventListener;
+class Frame;
class IntRect;
class KeyboardEvent;
class NSResolver;
class NamedAttrMap;
class NodeList;
+class NodeRareData;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
class PlatformWheelEvent;
class QualifiedName;
+class RegisteredEventListener;
class RenderArena;
class RenderBox;
+class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
class StringBuilder;
-class NodeRareData;
typedef int ExceptionCode;
+typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector;
+
enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, AnimationStyleChange };
const unsigned short DOCUMENT_POSITION_EQUIVALENT = 0x00;
@@ -71,7 +79,7 @@ const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
// this class implements nodes, which can have a parent but no children:
-class Node : public TreeShared<Node> {
+class Node : public EventTarget, public TreeShared<Node> {
friend class Document;
public:
enum NodeType {
@@ -180,7 +188,6 @@ public:
virtual bool isCommentNode() const { return false; }
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
- virtual bool isEventTargetNode() const { return false; }
virtual bool isShadowNode() const { return false; }
virtual Node* shadowParentNode() { return 0; }
Node* shadowAncestorNode();
@@ -290,14 +297,6 @@ public:
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
virtual bool isMouseFocusable() const;
- virtual bool isAutofilled() const { return false; }
- virtual bool isControl() const { return false; } // Eventually the notion of what is a control will be extensible.
- virtual bool isEnabled() const { return true; }
- virtual bool isChecked() const { return false; }
- virtual bool isIndeterminate() const { return false; }
- virtual bool isReadOnlyControl() const { return false; }
- virtual bool isTextControl() const { return false; }
-
virtual bool isContentEditable() const;
virtual bool isContentRichlyEditable() const;
virtual bool shouldUseInputMethod() const;
@@ -316,7 +315,7 @@ public:
Document* document() const
{
ASSERT(this);
- ASSERT(m_document || nodeType() == DOCUMENT_TYPE_NODE && !inDocument());
+ ASSERT(m_document || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
return m_document.get();
}
void setDocument(Document*);
@@ -375,10 +374,10 @@ public:
RenderObject* previousRenderer();
void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
- // Use with caution. Does no type checking. Mostly a convenience method for shadow nodes of form controls, where we know exactly
- // what kind of renderer we made.
+ // Use these two methods with caution.
RenderBox* renderBox() const;
-
+ RenderBoxModelObject* renderBoxModelObject() const;
+
void checkSetPrefix(const AtomicString& prefix, ExceptionCode&);
bool isDescendantOf(const Node*) const;
bool contains(const Node*) const;
@@ -405,6 +404,10 @@ public:
// Whether or not a selection can be started in this object
virtual bool canStartSelection() const;
+ // Getting points into and out of screen space
+ FloatPoint convertToPage(const FloatPoint& p) const;
+ FloatPoint convertFromPage(const FloatPoint& p) const;
+
// -----------------------------------------------------------------------------
// Integration with rendering tree
@@ -507,8 +510,8 @@ public:
#endif
protected:
- virtual void willMoveToNewOwnerDocument() { }
- virtual void didMoveToNewOwnerDocument() { }
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
void setTabIndexExplicitly(short);
@@ -518,6 +521,160 @@ protected:
NodeRareData* rareData() const;
NodeRareData* ensureRareData();
+public:
+ virtual Node* toNode() { return this; }
+
+ virtual ScriptExecutionContext* scriptExecutionContext() const;
+
+ 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&);
+ void removeAllEventListeners() { if (hasRareData()) removeAllEventListenersSlowCase(); }
+
+ void setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
+ void setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute*);
+ void removeInlineEventListenerForType(const AtomicString& eventType);
+ bool dispatchEventForType(const AtomicString& eventType, bool canBubble, bool cancelable);
+ EventListener* inlineEventListenerForType(const AtomicString& eventType) const;
+
+ bool dispatchSubtreeModifiedEvent();
+ void dispatchWindowEvent(PassRefPtr<Event>);
+ void dispatchWindowEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
+ bool dispatchUIEvent(const AtomicString& eventType, int detail = 0, PassRefPtr<Event> underlyingEvent = 0);
+ bool dispatchKeyEvent(const PlatformKeyboardEvent&);
+ void dispatchWheelEvent(PlatformWheelEvent&);
+ bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType,
+ int clickCount = 0, Node* relatedTarget = 0);
+ bool dispatchMouseEvent(const AtomicString& eventType, int button, int clickCount,
+ int pageX, int pageY, int screenX, int screenY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
+ bool isSimulated = false, Node* relatedTarget = 0, PassRefPtr<Event> underlyingEvent = 0);
+ void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent = 0);
+ void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
+ bool dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg);
+ void dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source);
+ bool dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime);
+ bool dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime);
+ bool dispatchGenericEvent(PassRefPtr<Event>);
+
+ virtual void handleLocalEvents(Event*, bool useCapture);
+
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+
+ /**
+ * Perform the default action for an event e.g. submitting a form
+ */
+ virtual void defaultEventHandler(Event*);
+
+ /**
+ * Used for disabled form elements; if true, prevents mouse events from being dispatched
+ * to event listeners, and prevents DOMActivate events from being sent at all.
+ */
+ virtual bool disabled() const;
+
+ const RegisteredEventListenerVector& eventListeners() const;
+
+ EventListener* onabort() const;
+ void setOnabort(PassRefPtr<EventListener>);
+ EventListener* onblur() const;
+ void setOnblur(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* onerror() const;
+ void setOnerror(PassRefPtr<EventListener>);
+ EventListener* onfocus() const;
+ void setOnfocus(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* onload() const;
+ void setOnload(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* 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* 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* onreset() const;
+ void setOnreset(PassRefPtr<EventListener>);
+ EventListener* onresize() const;
+ void setOnresize(PassRefPtr<EventListener>);
+ EventListener* onscroll() const;
+ void setOnscroll(PassRefPtr<EventListener>);
+ EventListener* onsearch() const;
+ void setOnsearch(PassRefPtr<EventListener>);
+ EventListener* onselect() const;
+ void setOnselect(PassRefPtr<EventListener>);
+ EventListener* onselectstart() const;
+ void setOnselectstart(PassRefPtr<EventListener>);
+ EventListener* onsubmit() const;
+ void setOnsubmit(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>);
+#endif
+
+ using TreeShared<Node>::ref;
+ using TreeShared<Node>::deref;
+
+private:
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+
+ void removeAllEventListenersSlowCase();
+
private:
virtual NodeRareData* createRareData();
Node* containerChildNode(unsigned index) const;
diff --git a/WebCore/dom/Node.idl b/WebCore/dom/Node.idl
index f45eaa6..0e1848d 100644
--- a/WebCore/dom/Node.idl
+++ b/WebCore/dom/Node.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
@@ -22,6 +22,7 @@ module core {
interface [
CustomMarkFunction,
+ CustomPushEventHandlerScope,
GenerateConstructor,
GenerateNativeConverter,
GenerateToJS,
@@ -64,15 +65,15 @@ module core {
readonly attribute NamedNodeMap attributes;
readonly attribute Document ownerDocument;
- [OldStyleObjC, Custom] Node insertBefore(in [Return] Node newChild,
+ [OldStyleObjC, JSCCustom] Node insertBefore(in [Return] Node newChild,
in Node refChild)
raises(DOMException);
- [OldStyleObjC, Custom] Node replaceChild(in Node newChild,
+ [OldStyleObjC, JSCCustom] Node replaceChild(in Node newChild,
in [Return] Node oldChild)
+ raises(DOMExceptionJSC);
+ [JSCCustom] Node removeChild(in [Return] Node oldChild)
raises(DOMException);
- [Custom] Node removeChild(in [Return] Node oldChild)
- raises(DOMException);
- [Custom] Node appendChild(in [Return] Node newChild)
+ [JSCCustom] Node appendChild(in [Return] Node newChild)
raises(DOMException);
boolean hasChildNodes();
@@ -131,6 +132,66 @@ module core {
// Objective-C extensions
readonly attribute boolean isContentEditable;
#endif /* defined(LANGUAGE_OBJECTIVE_C) */
+
+#if !defined(LANGUAGE_OBJECTIVE_C)
+#if !defined(LANGUAGE_COM)
+ attribute [DontEnum, ProtectedListener] EventListener onabort;
+ attribute [DontEnum, ProtectedListener] EventListener onblur;
+ attribute [DontEnum, ProtectedListener] EventListener onchange;
+ attribute [DontEnum, ProtectedListener] EventListener onclick;
+ attribute [DontEnum, ProtectedListener] EventListener oncontextmenu;
+ attribute [DontEnum, ProtectedListener] EventListener ondblclick;
+ attribute [DontEnum, ProtectedListener] EventListener onerror;
+ attribute [DontEnum, ProtectedListener] EventListener onfocus;
+ attribute [DontEnum, ProtectedListener] EventListener oninput;
+ attribute [DontEnum, ProtectedListener] EventListener onkeydown;
+ attribute [DontEnum, ProtectedListener] EventListener onkeypress;
+ attribute [DontEnum, ProtectedListener] EventListener onkeyup;
+ attribute [DontEnum, ProtectedListener] EventListener onload;
+ attribute [DontEnum, ProtectedListener] EventListener onmousedown;
+ attribute [DontEnum, ProtectedListener] EventListener onmousemove;
+ attribute [DontEnum, ProtectedListener] EventListener onmouseout;
+ attribute [DontEnum, ProtectedListener] EventListener onmouseover;
+ attribute [DontEnum, ProtectedListener] EventListener onmouseup;
+ attribute [DontEnum, ProtectedListener] EventListener onmousewheel;
+ attribute [DontEnum, ProtectedListener] EventListener onbeforecut;
+ attribute [DontEnum, ProtectedListener] EventListener oncut;
+ attribute [DontEnum, ProtectedListener] EventListener onbeforecopy;
+ attribute [DontEnum, ProtectedListener] EventListener oncopy;
+ attribute [DontEnum, ProtectedListener] EventListener onbeforepaste;
+ attribute [DontEnum, ProtectedListener] EventListener onpaste;
+ attribute [DontEnum, ProtectedListener] EventListener ondragenter;
+ attribute [DontEnum, ProtectedListener] EventListener ondragover;
+ attribute [DontEnum, ProtectedListener] EventListener ondragleave;
+ attribute [DontEnum, ProtectedListener] EventListener ondrop;
+ attribute [DontEnum, ProtectedListener] EventListener ondragstart;
+ attribute [DontEnum, ProtectedListener] EventListener ondrag;
+ attribute [DontEnum, ProtectedListener] EventListener ondragend;
+ attribute [DontEnum, ProtectedListener] EventListener onreset;
+ attribute [DontEnum, ProtectedListener] EventListener onresize;
+ attribute [DontEnum, ProtectedListener] EventListener onscroll;
+ attribute [DontEnum, ProtectedListener] EventListener onsearch;
+ attribute [DontEnum, ProtectedListener] EventListener onselect;
+ attribute [DontEnum, ProtectedListener] EventListener onselectstart;
+ attribute [DontEnum, ProtectedListener] EventListener onsubmit;
+ attribute [DontEnum, ProtectedListener] EventListener onunload;
+#if ENABLE_TOUCH_EVENTS
+ attribute [DontEnum, ProtectedListener] EventListener ontouchstart;
+ attribute [DontEnum, ProtectedListener] EventListener ontouchend;
+ attribute [DontEnum, ProtectedListener] EventListener ontouchmove;
+ attribute [DontEnum, ProtectedListener] EventListener ontouchcancel;
+#endif
+
+ [Custom] void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ [Custom] void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ boolean dispatchEvent(in Event event)
+ raises(EventException);
+#endif
+#endif
};
}
diff --git a/WebCore/dom/Position.cpp b/WebCore/dom/Position.cpp
index faa4a13..a2591ba 100644
--- a/WebCore/dom/Position.cpp
+++ b/WebCore/dom/Position.cpp
@@ -43,7 +43,7 @@ namespace WebCore {
using namespace HTMLNames;
-static Node *nextRenderedEditable(Node *node)
+static Node* nextRenderedEditable(Node* node)
{
while (1) {
node = node->nextEditable();
@@ -52,13 +52,13 @@ static Node *nextRenderedEditable(Node *node)
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
- if (renderer->inlineBoxWrapper() || renderer->isText() && toRenderText(renderer)->firstTextBox())
+ if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
return node;
}
return 0;
}
-static Node *previousRenderedEditable(Node *node)
+static Node* previousRenderedEditable(Node* node)
{
while (1) {
node = node->previousEditable();
@@ -67,7 +67,7 @@ static Node *previousRenderedEditable(Node *node)
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
- if (renderer->inlineBoxWrapper() || renderer->isText() && toRenderText(renderer)->firstTextBox())
+ if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
return node;
}
return 0;
@@ -97,60 +97,69 @@ PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
return WebCore::computedStyle(elem);
}
-Position Position::previous(EUsingComposedCharacters usingComposedCharacters) const
+Position Position::previous(PositionMoveType moveType) const
{
- Node *n = node();
+ Node* n = node();
if (!n)
return *this;
- int o = offset();
+ int o = m_offset;
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(o >= 0);
if (o > 0) {
- Node *child = n->childNode(o - 1);
- if (child) {
- return Position(child, maxDeepOffset(child));
- }
+ Node* child = n->childNode(o - 1);
+ if (child)
+ return lastDeepEditingPositionForNode(child);
+
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
// Going backward one character at a time is correct.
// 2) The old offset was a bogus offset like (<br>, 1), and there is no child.
// Going from 1 to 0 is correct.
- return Position(n, usingComposedCharacters ? uncheckedPreviousOffset(n, o) : o - 1);
+ switch (moveType) {
+ case CodePoint:
+ return Position(n, o - 1);
+ case Character:
+ return Position(n, uncheckedPreviousOffset(n, o));
+ case BackwardDeletion:
+ return Position(n, uncheckedPreviousOffsetForBackwardDeletion(n, o));
+ }
}
- Node *parent = n->parentNode();
+ Node* parent = n->parentNode();
if (!parent)
return *this;
return Position(parent, n->nodeIndex());
}
-Position Position::next(EUsingComposedCharacters usingComposedCharacters) const
+Position Position::next(PositionMoveType moveType) const
{
- Node *n = node();
+ ASSERT(moveType != BackwardDeletion);
+
+ Node* n = node();
if (!n)
return *this;
- int o = offset();
+ int o = m_offset;
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(o >= 0);
Node* child = n->childNode(o);
- if (child || !n->hasChildNodes() && o < maxDeepOffset(n)) {
+ if (child || (!n->hasChildNodes() && o < lastOffsetForEditing(n))) {
if (child)
- return Position(child, 0);
-
+ return firstDeepEditingPositionForNode(child);
+
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
// Going forward one character at a time is correct.
// 2) The new offset is a bogus offset like (<br>, 1), and there is no child.
// Going from 0 to 1 is correct.
- return Position(n, usingComposedCharacters ? uncheckedNextOffset(n, o) : o + 1);
+ return Position(n, (moveType == Character) ? uncheckedNextOffset(n, o) : o + 1);
}
- Node *parent = n->parentNode();
+ Node* parent = n->parentNode();
if (!parent)
return *this;
@@ -162,46 +171,61 @@ int Position::uncheckedPreviousOffset(const Node* n, int current)
return n->renderer() ? n->renderer()->previousOffset(current) : current - 1;
}
+int Position::uncheckedPreviousOffsetForBackwardDeletion(const Node* n, int current)
+{
+ return n->renderer() ? n->renderer()->previousOffsetForBackwardDeletion(current) : current - 1;
+}
+
int Position::uncheckedNextOffset(const Node* n, int current)
{
return n->renderer() ? n->renderer()->nextOffset(current) : current + 1;
}
-bool Position::atStart() const
+bool Position::atFirstEditingPositionForNode() const
{
- Node *n = node();
- if (!n)
+ if (isNull())
return true;
-
- return offset() <= 0 && n->parent() == 0;
+ return m_offset <= 0;
}
-bool Position::atEnd() const
+bool Position::atLastEditingPositionForNode() const
{
- Node *n = node();
- if (!n)
+ if (isNull())
return true;
-
- return n->parent() == 0 && offset() >= maxDeepOffset(n);
+ return m_offset >= lastOffsetForEditing(node());
+}
+
+bool Position::atStartOfTree() const
+{
+ if (isNull())
+ return true;
+ return !node()->parentNode() && m_offset <= 0;
+}
+
+bool Position::atEndOfTree() const
+{
+ if (isNull())
+ return true;
+ return !node()->parentNode() && m_offset >= lastOffsetForEditing(node());
}
int Position::renderedOffset() const
{
if (!node()->isTextNode())
- return offset();
+ return m_offset;
if (!node()->renderer())
- return offset();
+ return m_offset;
int result = 0;
RenderText *textRenderer = toRenderText(node()->renderer());
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
int start = box->start();
int end = box->start() + box->len();
- if (offset() < start)
+ if (m_offset < start)
return result;
- if (offset() <= end) {
- result += offset() - start;
+ if (m_offset <= end) {
+ result += m_offset - start;
return result;
}
result += box->len();
@@ -221,7 +245,7 @@ Position Position::previousCharacterPosition(EAffinity affinity) const
bool rendered = isCandidate();
Position currentPos = *this;
- while (!currentPos.atStart()) {
+ while (!currentPos.atStartOfTree()) {
currentPos = currentPos.previous();
if (currentPos.node()->rootEditableElement() != fromRootEditableElement)
@@ -249,7 +273,7 @@ Position Position::nextCharacterPosition(EAffinity affinity) const
bool rendered = isCandidate();
Position currentPos = *this;
- while (!currentPos.atEnd()) {
+ while (!currentPos.atEndOfTree()) {
currentPos = currentPos.next();
if (currentPos.node()->rootEditableElement() != fromRootEditableElement)
@@ -265,7 +289,7 @@ Position Position::nextCharacterPosition(EAffinity affinity) const
return *this;
}
-// Whether or not [node, 0] and [node, maxDeepOffset(node)] are their own VisiblePositions.
+// Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own VisiblePositions.
// If true, adjacent candidates are visually distinct.
// FIXME: Disregard nodes with renderers that have no height, as we do in isCandidate.
// FIXME: Share code with isCandidate, if possible.
@@ -359,7 +383,7 @@ Position Position::upstream() const
// Return position after tables and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
if (currentPos.atEndOfNode())
- return Position(currentNode, maxDeepOffset(currentNode));
+ return lastDeepEditingPositionForNode(currentNode);
continue;
}
@@ -396,7 +420,7 @@ Position Position::upstream() const
otherBox = otherBox->nextLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))
continuesOnNextLine = false;
}
@@ -405,7 +429,7 @@ Position Position::upstream() const
otherBox = otherBox->prevLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))
continuesOnNextLine = false;
}
@@ -508,7 +532,7 @@ Position Position::downstream() const
otherBox = otherBox->nextLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))
continuesOnNextLine = false;
}
@@ -517,7 +541,7 @@ Position Position::downstream() const
otherBox = otherBox->prevLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))
continuesOnNextLine = false;
}
@@ -534,7 +558,7 @@ bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* render
{
RenderObject* stop = renderer->nextInPreOrderAfterChildren();
for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
- if (o->element()) {
+ if (o->node()) {
if ((o->isText() && toRenderText(o)->linesBoundingBox().height()) ||
(o->isBox() && toRenderBox(o)->borderBoundingBox().height()))
return true;
@@ -560,17 +584,17 @@ bool Position::isCandidate() const
return false;
if (renderer->isBR())
- return offset() == 0 && !nodeIsUserSelectNone(node()->parent());
+ return m_offset == 0 && !nodeIsUserSelectNone(node()->parent());
if (renderer->isText())
return inRenderedText() && !nodeIsUserSelectNone(node());
if (isTableElement(node()) || editingIgnoresContent(node()))
- return (offset() == 0 || offset() == maxDeepOffset(node())) && !nodeIsUserSelectNone(node()->parent());
+ return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(node()->parent());
if (!node()->hasTagName(htmlTag) && renderer->isBlockFlow() && !hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
(toRenderBox(renderer)->height() || node()->hasTagName(bodyTag)))
- return offset() == 0 && !nodeIsUserSelectNone(node());
+ return atFirstEditingPositionForNode() && !nodeIsUserSelectNone(node());
return false;
}
@@ -586,15 +610,15 @@ bool Position::inRenderedText() const
RenderText *textRenderer = toRenderText(renderer);
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (offset() < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
+ if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
// The offset we're looking for is before this node
// this means the offset must be in content that is
// not rendered. Return false.
return false;
}
- if (box->containsCaretOffset(offset()))
+ if (box->containsCaretOffset(m_offset))
// Return false for offsets inside composed characters.
- return offset() == 0 || offset() == textRenderer->nextOffset(textRenderer->previousOffset(offset()));
+ return m_offset == 0 || m_offset == textRenderer->nextOffset(textRenderer->previousOffset(m_offset));
}
return false;
@@ -622,13 +646,13 @@ bool Position::isRenderedCharacter() const
RenderText* textRenderer = toRenderText(renderer);
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (offset() < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
+ if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
// The offset we're looking for is before this node
// this means the offset must be in content that is
// not rendered. Return false.
return false;
}
- if (offset() >= static_cast<int>(box->start()) && offset() < static_cast<int>(box->start() + box->len()))
+ if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast<int>(box->start() + box->len()))
return true;
}
@@ -656,11 +680,11 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
if (node()->hasTagName(brTag))
return false;
- if (offset() == pos.offset())
+ if (m_offset == pos.m_offset)
return false;
if (!node()->isTextNode() && !pos.node()->isTextNode()) {
- if (offset() != pos.offset())
+ if (m_offset != pos.m_offset)
return true;
}
}
@@ -734,7 +758,7 @@ Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo
Position prev = previousCharacterPosition(affinity);
if (prev != *this && prev.node()->inSameContainingBlockFlowElement(node()) && prev.node()->isTextNode()) {
String string = static_cast<Text *>(prev.node())->data();
- UChar c = string[prev.offset()];
+ UChar c = string[prev.m_offset];
if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : isCollapsibleWhitespace(c))
if (isEditablePosition(prev))
return prev;
@@ -809,11 +833,11 @@ static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
{
- caretOffset = offset();
+ caretOffset = m_offset;
RenderObject* renderer = node()->renderer();
if (!renderer->isText()) {
- inlineBox = renderer->inlineBoxWrapper();
- if (!inlineBox || caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset())
+ inlineBox = renderer->isBox() ? toRenderBox(renderer)->inlineBoxWrapper() : 0;
+ if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
return;
} else {
RenderText* textRenderer = toRenderText(renderer);
@@ -825,7 +849,7 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi
int caretMinOffset = box->caretMinOffset();
int caretMaxOffset = box->caretMaxOffset();
- if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || caretOffset == caretMaxOffset && box->isLineBreak())
+ if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || (caretOffset == caretMaxOffset && box->isLineBreak()))
continue;
if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset) {
@@ -943,7 +967,7 @@ void Position::debugPosition(const char* msg) const
if (isNull())
fprintf(stderr, "Position [%s]: null\n", msg);
else
- fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, node()->nodeName().utf8().data(), node(), offset());
+ fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, node()->nodeName().utf8().data(), node(), m_offset);
}
#ifndef NDEBUG
@@ -957,7 +981,7 @@ void Position::formatForDebugger(char* buffer, unsigned length) const
else {
char s[1024];
result += "offset ";
- result += String::number(offset());
+ result += String::number(m_offset);
result += " of ";
node()->formatForDebugger(s, sizeof(s));
result += s;
@@ -984,6 +1008,19 @@ 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
#ifndef NDEBUG
diff --git a/WebCore/dom/Position.h b/WebCore/dom/Position.h
index 2624238..8efb10f 100644
--- a/WebCore/dom/Position.h
+++ b/WebCore/dom/Position.h
@@ -40,7 +40,11 @@ class Node;
class Range;
class RenderObject;
-enum EUsingComposedCharacters { NotUsingComposedCharacters = false, UsingComposedCharacters = true };
+enum PositionMoveType {
+ CodePoint, // Move by a single code point.
+ Character, // Move to the next Unicode character break.
+ BackwardDeletion // Subject to platform conventions.
+};
// FIXME: Reduce the number of operations we have on a Position.
// This should be more like a humble struct, without so many different
@@ -48,20 +52,36 @@ enum EUsingComposedCharacters { NotUsingComposedCharacters = false, UsingCompose
class Position {
public:
- RefPtr<Node> container;
- int posOffset; // to be renamed to offset when we get rid of offset()
+ Position() : m_offset(0) { }
+
+ // This constructor should be private
+ Position(PassRefPtr<Node> anchorNode, int offset)
+ : m_anchorNode(anchorNode)
+ , m_offset(offset)
+ {}
- Position() : posOffset(0) { }
- Position(PassRefPtr<Node> c, int o) : container(c), posOffset(o) { }
+ void clear() { m_anchorNode.clear(); m_offset = 0; }
- void clear() { container.clear(); posOffset = 0; }
+ Node* anchorNode() const { return m_anchorNode.get(); }
- Node* node() const { return container.get(); }
- int offset() const { return posOffset; }
+ // FIXME: Callers should be moved off of node(), node() is not always the container for this position.
+ // For nodes which editingIgnoresContent(node()) returns true, positions like [ignoredNode, 0]
+ // will be treated as before ignoredNode (thus node() is really after the position, not containing it).
+ Node* node() const { return m_anchorNode.get(); }
Element* documentElement() const;
- bool isNull() const { return !container; }
- bool isNotNull() const { return container; }
+ void moveToPosition(PassRefPtr<Node> node, int offset)
+ {
+ m_anchorNode = node;
+ m_offset = offset;
+ }
+ void moveToOffset(int offset)
+ {
+ m_offset = offset;
+ }
+
+ bool isNull() const { return !m_anchorNode; }
+ bool isNotNull() const { return m_anchorNode; }
Element* element() const;
PassRefPtr<CSSComputedStyleDeclaration> computedStyle() const;
@@ -69,13 +89,19 @@ public:
// Move up or down the DOM by one position.
// Offsets are computed using render text for nodes that have renderers - but note that even when
// using composed characters, the result may be inside a single user-visible character if a ligature is formed.
- Position previous(EUsingComposedCharacters usingComposedCharacters=NotUsingComposedCharacters) const;
- Position next(EUsingComposedCharacters usingComposedCharacters=NotUsingComposedCharacters) const;
+ Position previous(PositionMoveType = CodePoint) const;
+ Position next(PositionMoveType = CodePoint) const;
static int uncheckedPreviousOffset(const Node*, int current);
+ static int uncheckedPreviousOffsetForBackwardDeletion(const Node*, int current);
static int uncheckedNextOffset(const Node*, int current);
- bool atStart() const;
- bool atEnd() const;
+ // These can be either inside or just before/after the node, depending on
+ // if the node is ignored by editing or not.
+ bool atFirstEditingPositionForNode() const;
+ bool atLastEditingPositionForNode() const;
+
+ bool atStartOfTree() const;
+ bool atEndOfTree() const;
// FIXME: Make these non-member functions and put them somewhere in the editing directory.
// These aren't really basic "position" operations. More high level editing helper functions.
@@ -109,11 +135,20 @@ private:
Position previousCharacterPosition(EAffinity) const;
Position nextCharacterPosition(EAffinity) const;
+
+ RefPtr<Node> m_anchorNode;
+public:
+ // m_offset can be the offset inside m_anchorNode, or if editingIgnoresContent(m_anchorNode)
+ // returns true, then other places in editing will treat m_offset == 0 as "before the anchor"
+ // and m_offset > 0 as "after the anchor node". See rangeCompliantEquivalent for more info.
+ int m_offset; // FIXME: This should be made private.
};
inline bool operator==(const Position& a, const Position& b)
{
- return a.container == b.container && a.posOffset == b.posOffset;
+ // FIXME: In <div><img></div> [div, 0] != [img, 0] even though most of the
+ // editing code will treat them as identical.
+ return a.anchorNode() == b.anchorNode() && a.m_offset == b.m_offset;
}
inline bool operator!=(const Position& a, const Position& b)
@@ -124,6 +159,12 @@ inline bool operator!=(const Position& a, const Position& b)
Position startPosition(const Range*);
Position endPosition(const Range*);
+// 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*);
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/dom/PositionIterator.cpp b/WebCore/dom/PositionIterator.cpp
index 06e1e32..781d352 100644
--- a/WebCore/dom/PositionIterator.cpp
+++ b/WebCore/dom/PositionIterator.cpp
@@ -36,7 +36,13 @@ using namespace HTMLNames;
PositionIterator::operator Position() const
{
- return Position(m_parent, m_child ? m_child->nodeIndex() : (m_parent->hasChildNodes() ? maxDeepOffset(m_parent) : m_offset));
+ if (m_child) {
+ ASSERT(m_child->parentNode() == m_parent);
+ return positionBeforeNode(m_child);
+ }
+ if (m_parent->hasChildNodes())
+ return lastDeepEditingPositionForNode(m_parent);
+ return Position(m_parent, m_offset);
}
void PositionIterator::increment()
@@ -51,7 +57,7 @@ void PositionIterator::increment()
return;
}
- if (!m_parent->hasChildNodes() && m_offset < maxDeepOffset(m_parent))
+ if (!m_parent->hasChildNodes() && m_offset < lastOffsetForEditing(m_parent))
m_offset = Position::uncheckedNextOffset(m_parent, m_offset);
else {
m_child = m_parent;
@@ -70,7 +76,7 @@ void PositionIterator::decrement()
m_parent = m_child->previousSibling();
if (m_parent) {
m_child = 0;
- m_offset = m_parent->hasChildNodes() ? 0 : maxDeepOffset(m_parent);
+ m_offset = m_parent->hasChildNodes() ? 0 : lastOffsetForEditing(m_parent);
} else {
m_child = m_child->parentNode();
m_parent = m_child->parentNode();
@@ -85,7 +91,7 @@ void PositionIterator::decrement()
if (m_parent->hasChildNodes()) {
m_parent = m_parent->lastChild();
if (!m_parent->hasChildNodes())
- m_offset = maxDeepOffset(m_parent);
+ m_offset = lastOffsetForEditing(m_parent);
} else {
m_child = m_parent;
m_parent = m_parent->parentNode();
@@ -99,7 +105,7 @@ bool PositionIterator::atStart() const
return true;
if (m_parent->parentNode())
return false;
- return !m_parent->hasChildNodes() && !m_offset || m_child && !m_child->previousSibling();
+ return (!m_parent->hasChildNodes() && !m_offset) || (m_child && !m_child->previousSibling());
}
bool PositionIterator::atEnd() const
@@ -108,7 +114,7 @@ bool PositionIterator::atEnd() const
return true;
if (m_child)
return false;
- return !m_parent->parentNode() && (m_parent->hasChildNodes() || m_offset >= maxDeepOffset(m_parent));
+ return !m_parent->parentNode() && (m_parent->hasChildNodes() || m_offset >= lastOffsetForEditing(m_parent));
}
bool PositionIterator::atStartOfNode() const
@@ -126,7 +132,7 @@ bool PositionIterator::atEndOfNode() const
return true;
if (m_child)
return false;
- return m_parent->hasChildNodes() || m_offset >= maxDeepOffset(m_parent);
+ return m_parent->hasChildNodes() || m_offset >= lastOffsetForEditing(m_parent);
}
bool PositionIterator::isCandidate() const
@@ -151,7 +157,7 @@ bool PositionIterator::isCandidate() const
return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_parent->parent());
if (!m_parent->hasTagName(htmlTag) && renderer->isBlockFlow() && !Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
- (static_cast<RenderBlock*>(renderer)->height() || m_parent->hasTagName(bodyTag)))
+ (toRenderBlock(renderer)->height() || m_parent->hasTagName(bodyTag)))
return atStartOfNode() && !Position::nodeIsUserSelectNone(m_parent);
return false;
diff --git a/WebCore/dom/PositionIterator.h b/WebCore/dom/PositionIterator.h
index 54f5020..98a2ccb 100644
--- a/WebCore/dom/PositionIterator.h
+++ b/WebCore/dom/PositionIterator.h
@@ -45,8 +45,8 @@ public:
PositionIterator(const Position& pos)
: m_parent(pos.node())
- , m_child(m_parent->childNode(pos.offset()))
- , m_offset(m_child ? 0 : pos.offset())
+ , m_child(m_parent->childNode(pos.m_offset))
+ , m_offset(m_child ? 0 : pos.m_offset)
{
}
operator Position() const;
diff --git a/WebCore/dom/QualifiedName.cpp b/WebCore/dom/QualifiedName.cpp
index f40f398..5953b97 100644
--- a/WebCore/dom/QualifiedName.cpp
+++ b/WebCore/dom/QualifiedName.cpp
@@ -1,7 +1,5 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
- * Copyright (C) 2005, 2006 Apple Computer, Inc.
+/*
+ * Copyright (C) 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
@@ -54,7 +52,6 @@ struct QNameComponentsTranslator {
static QNameSet* gNameCache;
QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
- : m_impl(0)
{
if (!gNameCache)
gNameCache = new QNameSet;
@@ -65,28 +62,6 @@ QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const
m_impl->ref();
}
-QualifiedName::~QualifiedName()
-{
- deref();
-}
-
-QualifiedName::QualifiedName(const QualifiedName& other)
-{
- m_impl = other.m_impl;
- ref();
-}
-
-const QualifiedName& QualifiedName::operator=(const QualifiedName& other)
-{
- if (m_impl != other.m_impl) {
- deref();
- m_impl = other.m_impl;
- ref();
- }
-
- return *this;
-}
-
void QualifiedName::deref()
{
#ifdef QNAME_DEFAULT_CONSTRUCTOR
@@ -99,12 +74,6 @@ void QualifiedName::deref()
m_impl->deref();
}
-void QualifiedName::setPrefix(const AtomicString& prefix)
-{
- QualifiedName other(prefix, localName(), namespaceURI());
- *this = other;
-}
-
String QualifiedName::toString() const
{
String local = localName();
diff --git a/WebCore/dom/QualifiedName.h b/WebCore/dom/QualifiedName.h
index d09cdea..13747a9 100644
--- a/WebCore/dom/QualifiedName.h
+++ b/WebCore/dom/QualifiedName.h
@@ -1,7 +1,5 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
- * Copyright (C) 2005 Apple Computer, Inc.
+ * Copyright (C) 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
@@ -19,6 +17,7 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#ifndef QualifiedName_h
#define QualifiedName_h
@@ -26,7 +25,7 @@
#include <wtf/HashFunctions.h>
namespace WebCore {
-
+
struct QualifiedNameComponents {
StringImpl* m_prefix;
StringImpl* m_localName;
@@ -37,32 +36,32 @@ class QualifiedName {
public:
class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
public:
- static PassRefPtr<QualifiedNameImpl> create(const AtomicString& p, const AtomicString& l, const AtomicString& n)
+ static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
{
- return adoptRef(new QualifiedNameImpl(p, l, n));
+ return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI));
}
-
+
AtomicString m_prefix;
AtomicString m_localName;
AtomicString m_namespace;
private:
- QualifiedNameImpl(const AtomicString& p, const AtomicString& l, const AtomicString& n)
- : m_prefix(p)
- , m_localName(l)
- , m_namespace(n)
+ QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
+ : m_prefix(prefix)
+ , m_localName(localName)
+ , m_namespace(namespaceURI.isEmpty() ? nullAtom : namespaceURI)
{
}
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
- ~QualifiedName();
+ ~QualifiedName() { deref(); }
#ifdef QNAME_DEFAULT_CONSTRUCTOR
QualifiedName() : m_impl(0) { }
#endif
- QualifiedName(const QualifiedName&);
- const QualifiedName& operator=(const QualifiedName&);
+ QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { ref(); }
+ const QualifiedName& operator=(const QualifiedName& other) { other.ref(); deref(); m_impl = other.m_impl; return *this; }
bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; }
bool operator!=(const QualifiedName& other) const { return !(*this == other); }
@@ -70,7 +69,7 @@ public:
bool matches(const QualifiedName& other) const { return m_impl == other.m_impl || (localName() == other.localName() && namespaceURI() == other.namespaceURI()); }
bool hasPrefix() const { return m_impl->m_prefix != nullAtom; }
- void setPrefix(const AtomicString& prefix);
+ void setPrefix(const AtomicString& prefix) { *this = QualifiedName(prefix, localName(), namespaceURI()); }
const AtomicString& prefix() const { return m_impl->m_prefix; }
const AtomicString& localName() const { return m_impl->m_localName; }
@@ -84,7 +83,7 @@ public:
static void init();
private:
- void ref() { m_impl->ref(); }
+ void ref() const { m_impl->ref(); }
void deref();
QualifiedNameImpl* m_impl;
@@ -100,7 +99,6 @@ inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a
inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); }
inline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); }
-
inline unsigned hashComponents(const QualifiedNameComponents& buf)
{
ASSERT(sizeof(QualifiedNameComponents) % (sizeof(uint16_t) * 2) == 0);
@@ -154,6 +152,7 @@ struct QualifiedNameHash {
namespace WTF {
template<typename T> struct DefaultHash;
+
template<> struct DefaultHash<WebCore::QualifiedName> {
typedef WebCore::QualifiedNameHash Hash;
};
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index b5afdd1..34b1d21 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -89,7 +89,7 @@ PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, PassRefPtr<N
PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, const Position& start, const Position& end)
{
- return adoptRef(new Range(ownerDocument, start.container.get(), start.posOffset, end.container.get(), end.posOffset));
+ return adoptRef(new Range(ownerDocument, start.node(), start.m_offset, end.node(), end.m_offset));
}
Range::~Range()
@@ -264,17 +264,17 @@ void Range::collapse(bool toStart, ExceptionCode& ec)
bool Range::isPointInRange(Node* refNode, int offset, ExceptionCode& ec)
{
- if (!refNode) {
- ec = NOT_FOUND_ERR;
+ if (!m_start.container()) {
+ ec = INVALID_STATE_ERR;
return false;
}
- if (!m_start.container() && refNode->attached()) {
- ec = INVALID_STATE_ERR;
+ if (!refNode) {
+ ec = HIERARCHY_REQUEST_ERR;
return false;
}
- if (m_start.container() && !refNode->attached()) {
+ if (!refNode->attached()) {
// Firefox doesn't throw an exception for this case; it returns false.
return false;
}
@@ -299,22 +299,17 @@ short Range::comparePoint(Node* refNode, int offset, ExceptionCode& ec)
// This method returns -1, 0 or 1 depending on if the point described by the
// refNode node and an offset within the node is before, same as, or after the range respectively.
- if (!refNode) {
- ec = NOT_FOUND_ERR;
- return 0;
- }
-
- if (!m_start.container() && refNode->attached()) {
+ if (!m_start.container()) {
ec = INVALID_STATE_ERR;
return 0;
}
- if (m_start.container() && !refNode->attached()) {
- // Firefox doesn't throw an exception for this case; it returns -1.
- return -1;
+ if (!refNode) {
+ ec = HIERARCHY_REQUEST_ERR;
+ return 0;
}
- if (refNode->document() != m_ownerDocument) {
+ if (!refNode->attached() || refNode->document() != m_ownerDocument) {
ec = WRONG_DOCUMENT_ERR;
return 0;
}
@@ -441,11 +436,14 @@ short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containerB, int offsetB)
{
- ASSERT(containerA && containerB);
+ ASSERT(containerA);
+ ASSERT(containerB);
+
if (!containerA)
return -1;
if (!containerB)
return 1;
+
// see DOM2 traversal & range section 2.5
// case 1: both points have the same container
@@ -529,7 +527,7 @@ short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containe
short Range::compareBoundaryPoints(const Position& a, const Position& b)
{
- return compareBoundaryPoints(a.container.get(), a.posOffset, b.container.get(), b.posOffset);
+ return compareBoundaryPoints(a.node(), a.m_offset, b.node(), b.m_offset);
}
bool Range::boundaryPointsValid() const
@@ -556,8 +554,8 @@ bool Range::intersectsNode(Node* refNode, ExceptionCode& ec)
return false;
}
- if (!m_start.container() && refNode->attached()
- || m_start.container() && !refNode->attached()
+ if ((!m_start.container() && refNode->attached())
+ || (m_start.container() && !refNode->attached())
|| refNode->document() != m_ownerDocument) {
// Firefox doesn't throw an exception for these cases; it returns false.
return false;
@@ -842,6 +840,17 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
processEnd = processEnd->parentNode();
}
+ // Collapse the range, making sure that the result is not within a node that was partially selected.
+ if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
+ if (partialStart)
+ setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1, ec);
+ else if (partialEnd)
+ setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), ec);
+ if (ec)
+ return 0;
+ m_end = m_start;
+ }
+
// Now add leftContents, stuff in between, and rightContents to the fragment
// (or just delete the stuff in between)
@@ -1592,13 +1601,16 @@ void Range::addLineBoxRects(Vector<IntRect>& rects, bool useSelectionHeight)
if (!start || !end)
return;
- RenderObject* stop = end->nextInPreOrderAfterChildren();
+ RenderObject* stop = end->childAt(m_end.offset());
+ if (!stop)
+ stop = end->nextInPreOrderAfterChildren();
+
for (RenderObject* r = start; r && r != stop; r = r->nextInPreOrder()) {
// only ask leaf render objects for their line box rects
if (!r->firstChild()) {
int startOffset = r == start ? m_start.offset() : 0;
int endOffset = r == end ? m_end.offset() : INT_MAX;
- r->addLineBoxRects(rects, startOffset, endOffset, useSelectionHeight);
+ r->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight);
}
}
}
diff --git a/WebCore/dom/RangeBoundaryPoint.h b/WebCore/dom/RangeBoundaryPoint.h
index 4cb7bf5..e39454e 100644
--- a/WebCore/dom/RangeBoundaryPoint.h
+++ b/WebCore/dom/RangeBoundaryPoint.h
@@ -55,6 +55,10 @@ public:
private:
static const int invalidOffset = -1;
+ // FIXME: RangeBoundaryPoint is the only file to ever use -1 as am expected offset for Position
+ // RangeBoundaryPoint currently needs to store a Position object to make the
+ // position() function be able to return a const& (and thus avoid ref-churn).
+
mutable Position m_position;
Node* m_childBefore;
};
@@ -72,7 +76,7 @@ inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
inline Node* RangeBoundaryPoint::container() const
{
- return m_position.container.get();
+ return m_position.node();
}
inline Node* RangeBoundaryPoint::childBefore() const
@@ -82,16 +86,16 @@ inline Node* RangeBoundaryPoint::childBefore() const
inline const Position& RangeBoundaryPoint::position() const
{
- if (m_position.posOffset >= 0)
+ if (m_position.m_offset >= 0)
return m_position;
ASSERT(m_childBefore);
- m_position.posOffset = m_childBefore->nodeIndex() + 1;
+ m_position.m_offset = m_childBefore->nodeIndex() + 1;
return m_position;
}
inline int RangeBoundaryPoint::offset() const
{
- return position().posOffset;
+ return position().m_offset;
}
inline void RangeBoundaryPoint::clear()
@@ -104,63 +108,59 @@ inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node
{
ASSERT(offset >= 0);
ASSERT(childBefore == (offset ? container->childNode(offset - 1) : 0));
- m_position.container = container;
- m_position.posOffset = offset;
+ m_position.moveToPosition(container, offset);
m_childBefore = childBefore;
}
inline void RangeBoundaryPoint::setOffset(int offset)
{
- ASSERT(m_position.container);
- ASSERT(m_position.container->offsetInCharacters());
- ASSERT(m_position.posOffset >= 0);
+ ASSERT(m_position.node());
+ ASSERT(m_position.node()->offsetInCharacters());
+ ASSERT(m_position.m_offset >= 0);
ASSERT(!m_childBefore);
- m_position.posOffset = offset;
+ m_position.moveToOffset(offset);
}
inline void RangeBoundaryPoint::setToChild(Node* child)
{
ASSERT(child);
ASSERT(child->parentNode());
- m_position.container = child->parentNode();
m_childBefore = child->previousSibling();
- m_position.posOffset = m_childBefore ? invalidOffset : 0;
+ m_position.moveToPosition(child->parentNode(), m_childBefore ? invalidOffset : 0);
}
inline void RangeBoundaryPoint::setToStart(PassRefPtr<Node> container)
{
ASSERT(container);
- m_position.container = container;
- m_position.posOffset = 0;
+ m_position.moveToPosition(container, 0);
m_childBefore = 0;
}
inline void RangeBoundaryPoint::setToEnd(PassRefPtr<Node> container)
{
ASSERT(container);
- m_position.container = container;
- if (m_position.container->offsetInCharacters()) {
- m_position.posOffset = m_position.container->maxCharacterOffset();
+ if (container->offsetInCharacters()) {
+ m_position.moveToPosition(container, container->maxCharacterOffset());
m_childBefore = 0;
} else {
- m_childBefore = m_position.container->lastChild();
- m_position.posOffset = m_childBefore ? invalidOffset : 0;
+ m_childBefore = container->lastChild();
+ m_position.moveToPosition(container, m_childBefore ? invalidOffset : 0);
}
}
inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
{
- ASSERT(m_position.posOffset);
+ ASSERT(m_position.m_offset);
m_childBefore = m_childBefore->previousSibling();
if (!m_childBefore)
- m_position.posOffset = 0;
- else if (m_position.posOffset > 0)
- --m_position.posOffset;
+ m_position.m_offset = 0;
+ else if (m_position.m_offset > 0)
+ --m_position.m_offset;
}
inline void RangeBoundaryPoint::invalidateOffset() const
{
- m_position.posOffset = invalidOffset;
+ m_position.m_offset = invalidOffset;
}
inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
diff --git a/WebCore/dom/ScriptExecutionContext.cpp b/WebCore/dom/ScriptExecutionContext.cpp
index 1d1aaec..c518734 100644
--- a/WebCore/dom/ScriptExecutionContext.cpp
+++ b/WebCore/dom/ScriptExecutionContext.cpp
@@ -175,6 +175,22 @@ void ScriptExecutionContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securi
m_securityOrigin = securityOrigin;
}
+void ScriptExecutionContext::addTimeout(int timeoutId, DOMTimer* timer)
+{
+ ASSERT(!m_timeouts.contains(timeoutId));
+ m_timeouts.set(timeoutId, timer);
+}
+
+void ScriptExecutionContext::removeTimeout(int timeoutId)
+{
+ m_timeouts.remove(timeoutId);
+}
+
+DOMTimer* ScriptExecutionContext::findTimeout(int timeoutId)
+{
+ return m_timeouts.get(timeoutId);
+}
+
ScriptExecutionContext::Task::~Task()
{
}
diff --git a/WebCore/dom/ScriptExecutionContext.h b/WebCore/dom/ScriptExecutionContext.h
index 6f09e1a..7b2f36a 100644
--- a/WebCore/dom/ScriptExecutionContext.h
+++ b/WebCore/dom/ScriptExecutionContext.h
@@ -37,6 +37,7 @@
namespace WebCore {
class ActiveDOMObject;
+ class DOMTimer;
class MessagePort;
class SecurityOrigin;
class ScriptString;
@@ -58,12 +59,15 @@ namespace WebCore {
const KURL& url() const { return virtualURL(); }
KURL completeURL(const String& url) const { return virtualCompleteURL(url); }
+ virtual String userAgent(const KURL&) const = 0;
+
SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL) = 0;
virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL) = 0;
virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString) = 0;
-
+ virtual void scriptImported(unsigned long, const String&) = 0;
+
// Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
bool canSuspendActiveDOMObjects();
// Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
@@ -94,6 +98,10 @@ namespace WebCore {
virtual void postTask(PassRefPtr<Task>) = 0; // Executes the task on context's thread asynchronously.
+ void addTimeout(int timeoutId, DOMTimer*);
+ void removeTimeout(int timeoutId);
+ DOMTimer* findTimeout(int timeoutId);
+
protected:
// Explicitly override the security origin for this script context.
// Note: It is dangerous to change the security origin of a script context
@@ -110,6 +118,8 @@ namespace WebCore {
HashMap<ActiveDOMObject*, void*> m_activeDOMObjects;
+ HashMap<int, DOMTimer*> m_timeouts;
+
virtual void refScriptExecutionContext() = 0;
virtual void derefScriptExecutionContext() = 0;
};
diff --git a/WebCore/dom/Text.cpp b/WebCore/dom/Text.cpp
index 6277ff6..5cb1af5 100644
--- a/WebCore/dom/Text.cpp
+++ b/WebCore/dom/Text.cpp
@@ -29,6 +29,7 @@
#if ENABLE(SVG)
#include "RenderSVGInlineText.h"
+#include "SVGNames.h"
#endif
#if ENABLE(WML)
@@ -233,7 +234,11 @@ bool Text::rendererIsNeeded(RenderStyle *style)
RenderObject *Text::createRenderer(RenderArena* arena, RenderStyle*)
{
#if ENABLE(SVG)
- if (parentNode()->isSVGElement())
+ if (parentNode()->isSVGElement()
+#if ENABLE(SVG_FOREIGN_OBJECT)
+ && !parentNode()->hasTagName(SVGNames::foreignObjectTag)
+#endif
+ )
return new (arena) RenderSVGInlineText(this, m_data);
#endif
diff --git a/WebCore/dom/Tokenizer.h b/WebCore/dom/Tokenizer.h
index 1ed9484..f9c6dc4 100644
--- a/WebCore/dom/Tokenizer.h
+++ b/WebCore/dom/Tokenizer.h
@@ -37,7 +37,7 @@ namespace WebCore {
// received during executing a script must be appended, hence the
// extra bool to be able to distinguish between both cases.
// document.write() always uses false, while the loader uses true.
- virtual bool write(const SegmentedString&, bool appendData) = 0;
+ virtual void write(const SegmentedString&, bool appendData) = 0;
virtual void finish() = 0;
virtual bool isWaitingForScripts() const = 0;
virtual void stopParsing() { m_parserStopped = true; }
diff --git a/WebCore/dom/WheelEvent.cpp b/WebCore/dom/WheelEvent.cpp
index a3c806e..2039541 100644
--- a/WebCore/dom/WheelEvent.cpp
+++ b/WebCore/dom/WheelEvent.cpp
@@ -34,20 +34,15 @@ WheelEvent::WheelEvent()
{
}
-WheelEvent::WheelEvent(float wheelDeltaX, float wheelDeltaY, PassRefPtr<AbstractView> view,
+WheelEvent::WheelEvent(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView> view,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
: MouseRelatedEvent(eventNames().mousewheelEvent,
true, true, view, 0, screenX, screenY, pageX, pageY,
ctrlKey, altKey, shiftKey, metaKey)
- , m_wheelDeltaX(lroundf(wheelDeltaX) * 120)
- , m_wheelDeltaY(lroundf(wheelDeltaY) * 120) // Normalize to the Windows 120 multiple
+ , m_wheelDeltaX(lroundf(wheelTicksX * 120))
+ , m_wheelDeltaY(lroundf(wheelTicksY * 120)) // Normalize to the Windows 120 multiple
{
- // Rounding delta to zero makes no sense and breaks Google Maps, <http://bugs.webkit.org/show_bug.cgi?id=16078>.
- if (wheelDeltaX && !m_wheelDeltaX)
- m_wheelDeltaX = (wheelDeltaX > 0) ? 120 : -120;
- if (wheelDeltaY && !m_wheelDeltaY)
- m_wheelDeltaY = (wheelDeltaY > 0) ? 120 : -120;
}
void WheelEvent::initWheelEvent(int wheelDeltaX, int wheelDeltaY, PassRefPtr<AbstractView> view,
diff --git a/WebCore/dom/WheelEvent.h b/WebCore/dom/WheelEvent.h
index 015796e..04d5421 100644
--- a/WebCore/dom/WheelEvent.h
+++ b/WebCore/dom/WheelEvent.h
@@ -35,11 +35,11 @@ namespace WebCore {
{
return adoptRef(new WheelEvent);
}
- static PassRefPtr<WheelEvent> create(float wheelDeltaX, float wheelDeltaY, PassRefPtr<AbstractView> view,
+ static PassRefPtr<WheelEvent> create(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView> view,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
- return adoptRef(new WheelEvent(wheelDeltaX, wheelDeltaY, view, screenX, screenY, pageX, pageY,
+ return adoptRef(new WheelEvent(wheelTicksX, wheelTicksY, view, screenX, screenY, pageX, pageY,
ctrlKey, altKey, shiftKey, metaKey));
}
@@ -56,7 +56,7 @@ namespace WebCore {
private:
WheelEvent();
- WheelEvent(float wheelDeltaX, float wheelDeltaY, PassRefPtr<AbstractView>,
+ WheelEvent(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView>,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
diff --git a/WebCore/dom/Worker.cpp b/WebCore/dom/Worker.cpp
deleted file mode 100644
index 6889a42..0000000
--- a/WebCore/dom/Worker.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "Worker.h"
-
-#include "CachedScript.h"
-#include "DOMWindow.h"
-#include "DocLoader.h"
-#include "Document.h"
-#include "EventException.h"
-#include "EventListener.h"
-#include "EventNames.h"
-#include "ExceptionCode.h"
-#include "Frame.h"
-#include "FrameLoader.h"
-#include "MessageEvent.h"
-#include "SecurityOrigin.h"
-#include "WorkerContext.h"
-#include "WorkerMessagingProxy.h"
-#include "WorkerTask.h"
-#include "WorkerThread.h"
-#include <wtf/MainThread.h>
-
-namespace WebCore {
-
-Worker::Worker(const String& url, Document* doc, ExceptionCode& ec)
- : ActiveDOMObject(doc, this)
- , m_messagingProxy(new WorkerMessagingProxy(doc, this))
-{
- m_scriptURL = doc->completeURL(url);
- if (url.isEmpty() || !m_scriptURL.isValid()) {
- ec = SYNTAX_ERR;
- return;
- }
-
- if (!doc->securityOrigin()->canAccess(SecurityOrigin::create(m_scriptURL).get())) {
- ec = SECURITY_ERR;
- return;
- }
-
- m_cachedScript = doc->docLoader()->requestScript(m_scriptURL, document()->charset());
- if (!m_cachedScript) {
- dispatchErrorEvent();
- return;
- }
-
- setPendingActivity(this); // The worker context does not exist while loading, so we much ensure that the worker object is not collected, as well as its event listeners.
- m_cachedScript->addClient(this);
-}
-
-Worker::~Worker()
-{
- ASSERT(isMainThread());
- ASSERT(scriptExecutionContext()); // The context is protected by messaging proxy, so it cannot be destroyed while a Worker exists.
- m_messagingProxy->workerObjectDestroyed();
-}
-
-Document* Worker::document() const
-{
- ASSERT(scriptExecutionContext()->isDocument());
- return static_cast<Document*>(scriptExecutionContext());
-}
-
-void Worker::postMessage(const String& message)
-{
- m_messagingProxy->postMessageToWorkerContext(message);
-}
-
-void Worker::terminate()
-{
- m_messagingProxy->terminate();
-}
-
-bool Worker::canSuspend() const
-{
- // FIXME: It is not currently possible to suspend a worker, so pages with workers can not go into page cache.
- return false;
-}
-
-void Worker::stop()
-{
- terminate();
-}
-
-bool Worker::hasPendingActivity() const
-{
- return m_messagingProxy->workerThreadHasPendingActivity() || ActiveDOMObject::hasPendingActivity();
-}
-
-void Worker::notifyFinished(CachedResource* unusedResource)
-{
- ASSERT_UNUSED(unusedResource, unusedResource == m_cachedScript);
-
- if (m_cachedScript->errorOccurred())
- dispatchErrorEvent();
- else {
- String userAgent = document()->frame() ? document()->frame()->loader()->userAgent(m_scriptURL) : String();
- RefPtr<WorkerThread> thread = WorkerThread::create(m_scriptURL, userAgent, m_cachedScript->script(), m_messagingProxy);
- m_messagingProxy->workerThreadCreated(thread);
- thread->start();
- }
-
- m_cachedScript->removeClient(this);
- m_cachedScript = 0;
-
- unsetPendingActivity(this);
-}
-
-void Worker::dispatchErrorEvent()
-{
- RefPtr<Event> evt = Event::create(eventNames().errorEvent, false, true);
- if (m_onErrorListener) {
- evt->setTarget(this);
- evt->setCurrentTarget(this);
- m_onErrorListener->handleEvent(evt.get(), true);
- }
-
- ExceptionCode ec = 0;
- dispatchEvent(evt.release(), ec);
- ASSERT(!ec);
-}
-
-void Worker::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
- 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);
- }
-}
-
-void Worker::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
- 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;
- }
- }
-}
-
-bool Worker::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
-{
- if (!event || event->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return true;
- }
-
- 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);
- }
-
- return !event->defaultPrevented();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/Worker.h b/WebCore/dom/Worker.h
deleted file mode 100644
index 6a47bac..0000000
--- a/WebCore/dom/Worker.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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 Worker_h
-#define Worker_h
-
-#if ENABLE(WORKERS)
-
-#include "AtomicStringHash.h"
-#include "ActiveDOMObject.h"
-#include "CachedResourceClient.h"
-#include "CachedResourceHandle.h"
-#include "EventListener.h"
-#include "EventTarget.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
- class CachedResource;
- class CachedScript;
- class Document;
- class ScriptExecutionContext;
- class String;
- class WorkerMessagingProxy;
- class WorkerTask;
-
- typedef int ExceptionCode;
-
- class Worker : public RefCounted<Worker>, public ActiveDOMObject, private CachedResourceClient, public EventTarget {
- public:
- static PassRefPtr<Worker> create(const String& url, Document* document, ExceptionCode& ec) { return adoptRef(new Worker(url, document, ec)); }
- ~Worker();
-
- virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
- Document* document() const;
-
- virtual Worker* toWorker() { return this; }
-
- void postMessage(const String& message);
-
- void terminate();
-
- virtual bool canSuspend() const;
- virtual void stop();
- virtual bool hasPendingActivity() const;
-
- 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<Worker>::ref;
- using RefCounted<Worker>::deref;
-
- void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onMessageListener = eventListener; }
- EventListener* onmessage() const { return m_onMessageListener.get(); }
-
- void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; }
- EventListener* onerror() const { return m_onErrorListener.get(); }
-
- private:
- Worker(const String&, Document*, ExceptionCode&);
-
- virtual void notifyFinished(CachedResource*);
-
- void dispatchErrorEvent();
-
- virtual void refEventTarget() { ref(); }
- virtual void derefEventTarget() { deref(); }
-
- KURL m_scriptURL;
- CachedResourceHandle<CachedScript> m_cachedScript;
-
- WorkerMessagingProxy* m_messagingProxy; // The proxy outlives the worker to perform thread shutdown.
-
- RefPtr<EventListener> m_onMessageListener;
- RefPtr<EventListener> m_onErrorListener;
- EventListenersMap m_eventListeners;
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // Worker_h
diff --git a/WebCore/dom/WorkerContext.cpp b/WebCore/dom/WorkerContext.cpp
deleted file mode 100644
index fe4643e..0000000
--- a/WebCore/dom/WorkerContext.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "WorkerContext.h"
-
-#include "ActiveDOMObject.h"
-#include "DOMWindow.h"
-#include "Event.h"
-#include "EventException.h"
-#include "GenericWorkerTask.h"
-#include "NotImplemented.h"
-#include "SecurityOrigin.h"
-#include "WorkerLocation.h"
-#include "WorkerMessagingProxy.h"
-#include "WorkerNavigator.h"
-#include "WorkerTask.h"
-#include "WorkerThread.h"
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-WorkerContext::WorkerContext(const KURL& url, const String& userAgent, WorkerThread* thread)
- : m_url(url)
- , m_userAgent(userAgent)
- , m_location(WorkerLocation::create(url))
- , m_script(new WorkerScriptController(this))
- , m_thread(thread)
-{
- setSecurityOrigin(SecurityOrigin::create(url));
-}
-
-WorkerContext::~WorkerContext()
-{
- ASSERT(currentThread() == m_thread->threadID());
-
- m_thread->messagingProxy()->workerContextDestroyed();
-}
-
-ScriptExecutionContext* WorkerContext::scriptExecutionContext() const
-{
- return const_cast<WorkerContext*>(this);
-}
-
-const KURL& WorkerContext::virtualURL() const
-{
- return m_url;
-}
-
-KURL WorkerContext::virtualCompleteURL(const String& url) const
-{
- return completeURL(url);
-}
-
-KURL WorkerContext::completeURL(const String& url) const
-{
- // Always return a null URL when passed a null string.
- // FIXME: Should we change the KURL constructor to have this behavior?
- if (url.isNull())
- return KURL();
- // FIXME: does this need to provide a charset, like Document::completeURL does?
- return KURL(m_location->url(), url);
-}
-
-WorkerNavigator* WorkerContext::navigator() const
-{
- if (!m_navigator)
- m_navigator = WorkerNavigator::create(m_userAgent);
- return m_navigator.get();
-}
-
-bool WorkerContext::hasPendingActivity() const
-{
- ActiveDOMObjectsMap& activeObjects = activeDOMObjects();
- ActiveDOMObjectsMap::const_iterator activeObjectsEnd = activeObjects.end();
- for (ActiveDOMObjectsMap::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) {
- if (iter->first->hasPendingActivity())
- return true;
- }
- return false;
-}
-
-void WorkerContext::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
-{
- m_thread->messagingProxy()->postWorkerException(errorMessage, lineNumber, sourceURL);
-}
-
-static void addMessageTask(ScriptExecutionContext* context, MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
-{
- context->addMessage(destination, source, level, message, lineNumber, sourceURL);
-}
-
-void WorkerContext::addMessage(MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
-{
- // createCallbackTask has to be a separate statement from postTaskToParentContext to make the destructor
- // for message.copy() get called before postTaskToParentContext. (If they are one statement, the destructor
- // gets called after postTaskToParentContext which causes a race condition.)
- RefPtr<Task> task = createCallbackTask(m_thread->messagingProxy(), &addMessageTask, destination, source, level, message.copy(), lineNumber, sourceURL.copy());
- postTaskToParentContext(task.release());
-}
-
-void WorkerContext::resourceRetrievedByXMLHttpRequest(unsigned long, const ScriptString&)
-{
- // FIXME: The implementation is pending the fixes in https://bugs.webkit.org/show_bug.cgi?id=23175
- notImplemented();
-}
-
-void WorkerContext::postMessage(const String& message)
-{
- m_thread->messagingProxy()->postMessageToWorkerObject(message);
-}
-
-void WorkerContext::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
- 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);
- }
-}
-
-void WorkerContext::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
- 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;
- }
- }
-}
-
-bool WorkerContext::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
-{
- if (!event || event->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return true;
- }
-
- 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);
- }
-
- return !event->defaultPrevented();
-}
-
-class ScriptExecutionContextTaskWorkerTask : public WorkerTask {
-public:
- static PassRefPtr<ScriptExecutionContextTaskWorkerTask> create(PassRefPtr<ScriptExecutionContext::Task> task)
- {
- return adoptRef(new ScriptExecutionContextTaskWorkerTask(task));
- }
-
-private:
- ScriptExecutionContextTaskWorkerTask(PassRefPtr<ScriptExecutionContext::Task> task)
- : m_task(task)
- {
- }
-
- virtual void performTask(WorkerContext* context)
- {
- m_task->performTask(context);
- }
-
- RefPtr<ScriptExecutionContext::Task> m_task;
-};
-
-void WorkerContext::postTask(PassRefPtr<Task> task)
-{
- thread()->runLoop().postTask(ScriptExecutionContextTaskWorkerTask::create(task));
-}
-
-void WorkerContext::postTaskToParentContext(PassRefPtr<Task> task)
-{
- thread()->messagingProxy()->postTaskToParentContext(task);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/WorkerContext.h b/WebCore/dom/WorkerContext.h
deleted file mode 100644
index 2e443d9..0000000
--- a/WebCore/dom/WorkerContext.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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 WorkerContext_h
-#define WorkerContext_h
-
-#if ENABLE(WORKERS)
-
-#include "AtomicStringHash.h"
-#include "EventListener.h"
-#include "EventTarget.h"
-#include "ScriptExecutionContext.h"
-#include "WorkerScriptController.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
- class WorkerLocation;
- class WorkerNavigator;
- class WorkerThread;
-
- class WorkerContext : public RefCounted<WorkerContext>, public ScriptExecutionContext, public EventTarget {
- public:
- static PassRefPtr<WorkerContext> create(const KURL& url, const String& userAgent, WorkerThread* thread)
- {
- return adoptRef(new WorkerContext(url, userAgent, thread));
- }
-
- virtual ~WorkerContext();
-
- virtual bool isWorkerContext() const { return true; }
-
- virtual ScriptExecutionContext* scriptExecutionContext() const;
-
- const KURL& url() const { return m_url; }
- KURL completeURL(const String&) const;
-
- WorkerLocation* location() const { return m_location.get(); }
- WorkerNavigator* navigator() const;
-
- WorkerScriptController* script() { return m_script.get(); }
- void clearScript() { return m_script.clear(); }
- WorkerThread* thread() { return m_thread; }
-
- bool hasPendingActivity() const;
-
- virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
- virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
- virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString);
-
- virtual WorkerContext* toWorkerContext() { return this; }
-
- void postMessage(const String& message);
- virtual void postTask(PassRefPtr<Task>); // Executes the task on context's thread asynchronously.
- void postTaskToParentContext(PassRefPtr<Task>); // Executes the task in the parent's context (and thread) asynchronously.
-
- 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&);
-
- void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onmessageListener = eventListener; }
- EventListener* onmessage() const { return m_onmessageListener.get(); }
-
- typedef Vector<RefPtr<EventListener> > ListenerVector;
- typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
- EventListenersMap& eventListeners() { return m_eventListeners; }
-
- using RefCounted<WorkerContext>::ref;
- using RefCounted<WorkerContext>::deref;
-
- private:
- virtual void refScriptExecutionContext() { ref(); }
- virtual void derefScriptExecutionContext() { deref(); }
- virtual void refEventTarget() { ref(); }
- virtual void derefEventTarget() { deref(); }
-
- WorkerContext(const KURL&, const String&, WorkerThread*);
-
- virtual const KURL& virtualURL() const;
- virtual KURL virtualCompleteURL(const String&) const;
-
- KURL m_url;
- String m_userAgent;
- RefPtr<WorkerLocation> m_location;
- mutable RefPtr<WorkerNavigator> m_navigator;
-
- OwnPtr<WorkerScriptController> m_script;
- WorkerThread* m_thread;
-
- RefPtr<EventListener> m_onmessageListener;
- EventListenersMap m_eventListeners;
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerContext_h
diff --git a/WebCore/dom/WorkerContext.idl b/WebCore/dom/WorkerContext.idl
deleted file mode 100644
index 6e7223c..0000000
--- a/WebCore/dom/WorkerContext.idl
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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 threads {
-
- interface [
- Conditional=WORKERS,
- CustomGetOwnPropertySlot,
- CustomMarkFunction,
- ExtendsDOMGlobalObject,
- LegacyParent=JSWorkerContextBase,
- NoStaticTables
- ] WorkerContext {
-#if defined(LANGUAGE_JAVASCRIPT)
- attribute [Custom] WorkerContext self;
-#endif
-
- attribute EventListener onmessage;
- void postMessage(in DOMString message);
-
- attribute [Replaceable] WorkerLocation location;
- attribute [Replaceable] WorkerNavigator navigator;
-
- attribute MessageEventConstructor MessageEvent;
- attribute WorkerLocationConstructor WorkerLocation;
-
- // EventTarget interface
- [Custom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [Custom] void removeEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- boolean dispatchEvent(in Event evt)
- raises(EventException);
- };
-
-}
diff --git a/WebCore/dom/WorkerLocation.cpp b/WebCore/dom/WorkerLocation.cpp
deleted file mode 100644
index 115a9ad..0000000
--- a/WebCore/dom/WorkerLocation.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "WorkerLocation.h"
-
-#include "PlatformString.h"
-
-namespace WebCore {
-
-String WorkerLocation::href() const
-{
- return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/";
-}
-
-String WorkerLocation::protocol() const
-{
- return m_url.protocol() + ":";
-}
-
-String WorkerLocation::host() const
-{
- return m_url.port() ? m_url.host() + ":" + String::number((static_cast<int>(m_url.port()))) : m_url.host();
-}
-
-String WorkerLocation::hostname() const
-{
- return m_url.host();
-}
-
-String WorkerLocation::port() const
-{
- return m_url.port() ? String::number(static_cast<int>(m_url.port())) : "";
-}
-
-String WorkerLocation::pathname() const
-{
- return m_url.path().isEmpty() ? "/" : m_url.path();
-}
-
-String WorkerLocation::search() const
-{
- return m_url.query();
-}
-
-String WorkerLocation::hash() const
-{
- return m_url.ref().isNull() ? "" : "#" + m_url.ref();
-}
-
-String WorkerLocation::toString() const
-{
- return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/";
-}
-
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/WorkerLocation.idl b/WebCore/dom/WorkerLocation.idl
deleted file mode 100644
index 5551f18..0000000
--- a/WebCore/dom/WorkerLocation.idl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 threads {
-
- interface [
- Conditional=WORKERS,
- GenerateConstructor,
- NoStaticTables
- ] WorkerLocation {
- readonly attribute DOMString href;
- readonly attribute DOMString protocol;
- readonly attribute DOMString host;
- readonly attribute DOMString hostname;
- readonly attribute DOMString port;
- readonly attribute DOMString pathname;
- readonly attribute DOMString search;
- readonly attribute DOMString hash;
-
- [DontEnum] DOMString toString();
- };
-
-}
diff --git a/WebCore/dom/WorkerMessagingProxy.cpp b/WebCore/dom/WorkerMessagingProxy.cpp
deleted file mode 100644
index b0d145e..0000000
--- a/WebCore/dom/WorkerMessagingProxy.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "WorkerMessagingProxy.h"
-
-#include "DOMWindow.h"
-#include "Document.h"
-#include "MessageEvent.h"
-#include "Worker.h"
-#include "WorkerContext.h"
-#include "WorkerTask.h"
-#include "WorkerThread.h"
-
-namespace WebCore {
-
-class MessageWorkerContextTask : public WorkerTask {
-public:
- static PassRefPtr<MessageWorkerContextTask> create(const String& message)
- {
- return adoptRef(new MessageWorkerContextTask(message));
- }
-
-private:
- MessageWorkerContextTask(const String& message)
- : m_message(message.copy())
- {
- }
-
- virtual void performTask(WorkerContext* context)
- {
- RefPtr<Event> evt = MessageEvent::create(m_message, "", "", 0, 0);
-
- if (context->onmessage()) {
- evt->setTarget(context);
- evt->setCurrentTarget(context);
- context->onmessage()->handleEvent(evt.get(), false);
- }
-
- ExceptionCode ec = 0;
- context->dispatchEvent(evt.release(), ec);
- ASSERT(!ec);
-
- context->thread()->messagingProxy()->confirmWorkerThreadMessage(context->hasPendingActivity());
- }
-
-private:
- String m_message;
-};
-
-class MessageWorkerTask : public ScriptExecutionContext::Task {
-public:
- static PassRefPtr<MessageWorkerTask> create(const String& message, WorkerMessagingProxy* messagingProxy)
- {
- return adoptRef(new MessageWorkerTask(message, messagingProxy));
- }
-
-private:
- MessageWorkerTask(const String& message, WorkerMessagingProxy* messagingProxy)
- : m_message(message.copy())
- , m_messagingProxy(messagingProxy)
- {
- }
-
- virtual void performTask(ScriptExecutionContext*)
- {
- Worker* workerObject = m_messagingProxy->workerObject();
- if (!workerObject || m_messagingProxy->askedToTerminate())
- return;
-
- RefPtr<Event> evt = MessageEvent::create(m_message, "", "", 0, 0);
-
- if (workerObject->onmessage()) {
- evt->setTarget(workerObject);
- evt->setCurrentTarget(workerObject);
- workerObject->onmessage()->handleEvent(evt.get(), false);
- }
-
- ExceptionCode ec = 0;
- workerObject->dispatchEvent(evt.release(), ec);
- ASSERT(!ec);
- }
-
-private:
- String m_message;
- WorkerMessagingProxy* m_messagingProxy;
-};
-
-class WorkerExceptionTask : public ScriptExecutionContext::Task {
-public:
- static PassRefPtr<WorkerExceptionTask> create(const String& errorMessage, int lineNumber, const String& sourceURL, WorkerMessagingProxy* messagingProxy)
- {
- return adoptRef(new WorkerExceptionTask(errorMessage, lineNumber, sourceURL, messagingProxy));
- }
-
-private:
- WorkerExceptionTask(const String& errorMessage, int lineNumber, const String& sourceURL, WorkerMessagingProxy* messagingProxy)
- : m_errorMessage(errorMessage.copy())
- , m_lineNumber(lineNumber)
- , m_sourceURL(sourceURL.copy())
- , m_messagingProxy(messagingProxy)
- {
- }
-
- virtual void performTask(ScriptExecutionContext* context)
- {
- if (!m_messagingProxy->askedToTerminate())
- context->reportException(m_errorMessage, m_lineNumber, m_sourceURL);
- }
-
- String m_errorMessage;
- int m_lineNumber;
- String m_sourceURL;
- WorkerMessagingProxy* m_messagingProxy;
-};
-
-class WorkerContextDestroyedTask : public ScriptExecutionContext::Task {
-public:
- static PassRefPtr<WorkerContextDestroyedTask> create(WorkerMessagingProxy* messagingProxy)
- {
- return adoptRef(new WorkerContextDestroyedTask(messagingProxy));
- }
-
-private:
- WorkerContextDestroyedTask(WorkerMessagingProxy* messagingProxy)
- : m_messagingProxy(messagingProxy)
- {
- }
-
- virtual void performTask(ScriptExecutionContext*)
- {
- m_messagingProxy->workerContextDestroyedInternal();
- }
-
- WorkerMessagingProxy* m_messagingProxy;
-};
-
-class WorkerThreadActivityReportTask : public ScriptExecutionContext::Task {
-public:
- static PassRefPtr<WorkerThreadActivityReportTask> create(WorkerMessagingProxy* messagingProxy, bool confirmingMessage, bool hasPendingActivity)
- {
- return adoptRef(new WorkerThreadActivityReportTask(messagingProxy, confirmingMessage, hasPendingActivity));
- }
-
-private:
- WorkerThreadActivityReportTask(WorkerMessagingProxy* messagingProxy, bool confirmingMessage, bool hasPendingActivity)
- : m_messagingProxy(messagingProxy)
- , m_confirmingMessage(confirmingMessage)
- , m_hasPendingActivity(hasPendingActivity)
- {
- }
-
- virtual void performTask(ScriptExecutionContext*)
- {
- m_messagingProxy->reportWorkerThreadActivityInternal(m_confirmingMessage, m_hasPendingActivity);
- }
-
- WorkerMessagingProxy* m_messagingProxy;
- bool m_confirmingMessage;
- bool m_hasPendingActivity;
-};
-
-
-WorkerMessagingProxy::WorkerMessagingProxy(PassRefPtr<ScriptExecutionContext> scriptExecutionContext, Worker* workerObject)
- : m_scriptExecutionContext(scriptExecutionContext)
- , m_workerObject(workerObject)
- , m_unconfirmedMessageCount(0)
- , m_workerThreadHadPendingActivity(false)
- , m_askedToTerminate(false)
-{
- ASSERT(m_workerObject);
- ASSERT((m_scriptExecutionContext->isDocument() && isMainThread())
- || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
-}
-
-WorkerMessagingProxy::~WorkerMessagingProxy()
-{
- ASSERT(!m_workerObject);
- ASSERT((m_scriptExecutionContext->isDocument() && isMainThread())
- || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
-}
-
-void WorkerMessagingProxy::postMessageToWorkerObject(const String& message)
-{
- m_scriptExecutionContext->postTask(MessageWorkerTask::create(message, this));
-}
-
-void WorkerMessagingProxy::postMessageToWorkerContext(const String& message)
-{
- if (m_askedToTerminate)
- return;
-
- if (m_workerThread) {
- ++m_unconfirmedMessageCount;
- m_workerThread->runLoop().postTask(MessageWorkerContextTask::create(message));
- } else
- m_queuedEarlyTasks.append(MessageWorkerContextTask::create(message));
-}
-
-void WorkerMessagingProxy::postTaskToParentContext(PassRefPtr<ScriptExecutionContext::Task> task)
-{
- m_scriptExecutionContext->postTask(task);
-}
-
-void WorkerMessagingProxy::postWorkerException(const String& errorMessage, int lineNumber, const String& sourceURL)
-{
- m_scriptExecutionContext->postTask(WorkerExceptionTask::create(errorMessage, lineNumber, sourceURL, this));
-}
-
-void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<WorkerThread> workerThread)
-{
- m_workerThread = workerThread;
-
- if (m_askedToTerminate) {
- // Worker.terminate() could be called from JS before the thread was created.
- m_workerThread->stop();
- } else {
- unsigned taskCount = m_queuedEarlyTasks.size();
- ASSERT(!m_unconfirmedMessageCount);
- m_unconfirmedMessageCount = taskCount + 1; // Worker initialization counts as a pending message.
-
- for (unsigned i = 0; i < taskCount; ++i)
- m_workerThread->runLoop().postTask(m_queuedEarlyTasks[i]);
- m_queuedEarlyTasks.clear();
- }
-}
-
-void WorkerMessagingProxy::workerObjectDestroyed()
-{
- m_workerObject = 0;
- if (m_workerThread)
- terminate();
- else
- workerContextDestroyedInternal(); // It never existed, just do our cleanup.
-}
-
-void WorkerMessagingProxy::workerContextDestroyed()
-{
- m_scriptExecutionContext->postTask(WorkerContextDestroyedTask::create(this));
- // Will execute workerContextDestroyedInternal() on context's thread.
-}
-
-void WorkerMessagingProxy::workerContextDestroyedInternal()
-{
- // WorkerContextDestroyedTask is always the last to be performed, so the proxy is not needed for communication
- // in either side any more. However, the Worker object may still exist, and it assumes that the proxy exists, too.
- if (!m_workerObject)
- delete this;
-}
-
-void WorkerMessagingProxy::terminate()
-{
- if (m_askedToTerminate)
- return;
- m_askedToTerminate = true;
-
- if (m_workerThread)
- m_workerThread->stop();
-}
-
-void WorkerMessagingProxy::confirmWorkerThreadMessage(bool hasPendingActivity)
-{
- m_scriptExecutionContext->postTask(WorkerThreadActivityReportTask::create(this, true, hasPendingActivity));
- // Will execute reportWorkerThreadActivityInternal() on context's thread.
-}
-
-void WorkerMessagingProxy::reportWorkerThreadActivity(bool hasPendingActivity)
-{
- m_scriptExecutionContext->postTask(WorkerThreadActivityReportTask::create(this, false, hasPendingActivity));
- // Will execute reportWorkerThreadActivityInternal() on context's thread.
-}
-
-void WorkerMessagingProxy::reportWorkerThreadActivityInternal(bool confirmingMessage, bool hasPendingActivity)
-{
- if (confirmingMessage && !m_askedToTerminate) {
- ASSERT(m_unconfirmedMessageCount);
- --m_unconfirmedMessageCount;
- }
-
- m_workerThreadHadPendingActivity = hasPendingActivity;
-}
-
-bool WorkerMessagingProxy::workerThreadHasPendingActivity() const
-{
- return (m_unconfirmedMessageCount || m_workerThreadHadPendingActivity) && !m_askedToTerminate;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/WorkerMessagingProxy.h b/WebCore/dom/WorkerMessagingProxy.h
deleted file mode 100644
index e7ba8a9..0000000
--- a/WebCore/dom/WorkerMessagingProxy.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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 WorkerMessagingProxy_h
-#define WorkerMessagingProxy_h
-
-#if ENABLE(WORKERS)
-
-#include "ScriptExecutionContext.h"
-#include <wtf/Noncopyable.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
- class ScriptExecutionContext;
- class String;
- class Worker;
- class WorkerTask;
- class WorkerThread;
-
- class WorkerMessagingProxy : Noncopyable {
- public:
- WorkerMessagingProxy(PassRefPtr<ScriptExecutionContext>, Worker*);
-
- void postMessageToWorkerObject(const String& message);
- void postMessageToWorkerContext(const String& message);
- void postTaskToParentContext(PassRefPtr<ScriptExecutionContext::Task>);
-
- void postWorkerException(const String& errorMessage, int lineNumber, const String& sourceURL);
-
- void workerThreadCreated(PassRefPtr<WorkerThread>);
- void workerObjectDestroyed();
- void workerContextDestroyed();
-
- void terminate();
-
- void confirmWorkerThreadMessage(bool hasPendingActivity);
- void reportWorkerThreadActivity(bool hasPendingActivity);
- bool workerThreadHasPendingActivity() const;
-
- private:
- friend class GenericWorkerTaskBase;
- friend class MessageWorkerTask;
- friend class WorkerContextDestroyedTask;
- friend class WorkerExceptionTask;
- friend class WorkerThreadActivityReportTask;
-
- ~WorkerMessagingProxy();
-
- void workerContextDestroyedInternal();
- void reportWorkerThreadActivityInternal(bool confirmingMessage, bool hasPendingActivity);
- Worker* workerObject() const { return m_workerObject; }
- bool askedToTerminate() { return m_askedToTerminate; }
-
- RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
- Worker* m_workerObject;
- RefPtr<WorkerThread> m_workerThread;
-
- unsigned m_unconfirmedMessageCount; // Unconfirmed messages from worker object to worker thread.
- bool m_workerThreadHadPendingActivity; // The latest confirmation from worker thread reported that it was still active.
-
- bool m_askedToTerminate;
-
- Vector<RefPtr<WorkerTask> > m_queuedEarlyTasks; // Tasks are queued here until there's a thread object created.
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerMessagingProxy_h
diff --git a/WebCore/dom/WorkerRunLoop.cpp b/WebCore/dom/WorkerRunLoop.cpp
deleted file mode 100644
index 98c2e8d..0000000
--- a/WebCore/dom/WorkerRunLoop.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT
- * OWNER 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"
-
-#if ENABLE(WORKERS)
-
-#include "WorkerRunLoop.h"
-#include "WorkerContext.h"
-#include "WorkerTask.h"
-#include "WorkerThread.h"
-
-namespace WebCore {
-
-void WorkerRunLoop::run(WorkerContext* context)
-{
- ASSERT(context);
- ASSERT(context->thread());
- ASSERT(context->thread()->threadID() == currentThread());
-
- while (true) {
- RefPtr<WorkerTask> task;
- if (!m_messageQueue.waitForMessage(task))
- break;
-
- task->performTask(context);
- }
-}
-
-void WorkerRunLoop::terminate()
-{
- m_messageQueue.kill();
-}
-
-void WorkerRunLoop::postTask(PassRefPtr<WorkerTask> task)
-{
- m_messageQueue.append(task);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/WorkerRunLoop.h b/WebCore/dom/WorkerRunLoop.h
deleted file mode 100644
index 03a746b..0000000
--- a/WebCore/dom/WorkerRunLoop.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT
- * OWNER 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 WorkerRunLoop_h
-#define WorkerRunLoop_h
-
-#if ENABLE(WORKERS)
-
-#include "WorkerTask.h"
-#include <wtf/MessageQueue.h>
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
- class WorkerContext;
-
- class WorkerRunLoop {
- public:
- WorkerRunLoop() {}
-
- // Blocking call. Waits for tasks and timers, invokes the callbacks.
- void run(WorkerContext*);
-
- void terminate();
- bool terminated() { return m_messageQueue.killed(); }
-
- void postTask(PassRefPtr<WorkerTask>);
-
- private:
- MessageQueue<RefPtr<WorkerTask> > m_messageQueue;
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerRunLoop_h
diff --git a/WebCore/dom/WorkerThread.cpp b/WebCore/dom/WorkerThread.cpp
deleted file mode 100644
index a762e0b..0000000
--- a/WebCore/dom/WorkerThread.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "WorkerThread.h"
-
-#include "KURL.h"
-#include "PlatformString.h"
-#include "ScriptSourceCode.h"
-#include "ScriptValue.h"
-#include "Worker.h"
-#include "WorkerContext.h"
-#include "WorkerMessagingProxy.h"
-#include "WorkerTask.h"
-
-#include <utility>
-#include <wtf/Noncopyable.h>
-
-namespace WebCore {
-struct WorkerThreadStartupData : Noncopyable {
-public:
- static std::auto_ptr<WorkerThreadStartupData> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
- {
- return std::auto_ptr<WorkerThreadStartupData>(new WorkerThreadStartupData(scriptURL, userAgent, sourceCode));
- }
-
- KURL m_scriptURL;
- String m_userAgent;
- String m_sourceCode;
-private:
- WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode);
-};
-
-WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
- : m_scriptURL(scriptURL.copy())
- , m_userAgent(userAgent.copy())
- , m_sourceCode(sourceCode.copy())
-{
-}
-
-PassRefPtr<WorkerThread> WorkerThread::create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy* messagingProxy)
-{
- return adoptRef(new WorkerThread(scriptURL, userAgent, sourceCode, messagingProxy));
-}
-
-WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy* messagingProxy)
- : m_threadID(0)
- , m_messagingProxy(messagingProxy)
- , m_startupData(WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode))
-{
-}
-
-WorkerThread::~WorkerThread()
-{
-}
-
-bool WorkerThread::start()
-{
- // Mutex protection is necessary to ensure that m_threadID is initialized when the thread starts.
- MutexLocker lock(m_threadCreationMutex);
-
- if (m_threadID)
- return true;
-
- m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore::Worker");
-
- return m_threadID;
-}
-
-void* WorkerThread::workerThreadStart(void* thread)
-{
- return static_cast<WorkerThread*>(thread)->workerThread();
-}
-
-void* WorkerThread::workerThread()
-{
- {
- MutexLocker lock(m_threadCreationMutex);
- m_workerContext = WorkerContext::create(m_startupData->m_scriptURL, m_startupData->m_userAgent, this);
- if (m_runLoop.terminated()) {
- // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
- // forbidExecution() couldn't be called from stop().
- m_workerContext->script()->forbidExecution();
- }
- }
-
- WorkerScriptController* script = m_workerContext->script();
- script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
- // Free the startup data to cause its member variable deref's happen on the worker's thread (since
- // all ref/derefs of these objects are happening on the thread at this point). Note that
- // WorkerThread::~WorkerThread happens on a different thread where it was created.
- m_startupData.clear();
-
- m_messagingProxy->confirmWorkerThreadMessage(m_workerContext->hasPendingActivity()); // This wasn't really a message, but it counts as one for GC.
-
- // Blocks until terminated.
- m_runLoop.run(m_workerContext.get());
-
- ThreadIdentifier threadID = m_threadID;
-
- m_workerContext->clearScript();
- ASSERT(m_workerContext->hasOneRef());
- // The below assignment will destroy the context, which will in turn notify messaging proxy.
- // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
- m_workerContext = 0;
-
- // The thread object may be already destroyed from notification now, don't try to access "this".
- detachThread(threadID);
-
- return 0;
-}
-
-void WorkerThread::stop()
-{
- // Mutex protection is necessary because stop() can be called before the context is fully created.
- MutexLocker lock(m_threadCreationMutex);
-
- // Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever.
- if (m_workerContext)
- m_workerContext->script()->forbidExecution();
-
- // FIXME: Rudely killing the thread won't work when we allow nested workers, because they will try to post notifications of their destruction.
- m_runLoop.terminate();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/WorkerThread.h b/WebCore/dom/WorkerThread.h
deleted file mode 100644
index 504db81..0000000
--- a/WebCore/dom/WorkerThread.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2008 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 COMPUTER, 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 WorkerThread_h
-#define WorkerThread_h
-
-#if ENABLE(WORKERS)
-
-#include <WorkerRunLoop.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
- class KURL;
- class String;
- class WorkerContext;
- class WorkerMessagingProxy;
- class WorkerTask;
- struct WorkerThreadStartupData;
-
- class WorkerThread : public RefCounted<WorkerThread> {
- public:
- static PassRefPtr<WorkerThread> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy*);
- ~WorkerThread();
-
- bool start();
- void stop();
-
- ThreadIdentifier threadID() const { return m_threadID; }
- WorkerRunLoop& runLoop() { return m_runLoop; }
- WorkerMessagingProxy* messagingProxy() const { return m_messagingProxy; }
-
- private:
- WorkerThread(const KURL&, const String& userAgent, const String& sourceCode, WorkerMessagingProxy*);
-
- static void* workerThreadStart(void*);
- void* workerThread();
-
- ThreadIdentifier m_threadID;
- WorkerRunLoop m_runLoop;
- WorkerMessagingProxy* m_messagingProxy;
-
- RefPtr<WorkerContext> m_workerContext;
- Mutex m_threadCreationMutex;
-
- OwnPtr<WorkerThreadStartupData> m_startupData;
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerThread_h
diff --git a/WebCore/dom/XMLTokenizer.cpp b/WebCore/dom/XMLTokenizer.cpp
index 6f57a46..1415922 100644
--- a/WebCore/dom/XMLTokenizer.cpp
+++ b/WebCore/dom/XMLTokenizer.cpp
@@ -64,6 +64,8 @@ using namespace std;
namespace WebCore {
+using namespace HTMLNames;
+
const int maxErrors = 25;
#if ENABLE(WML)
@@ -87,7 +89,7 @@ void XMLTokenizer::setCurrentNode(Node* n)
m_currentNodeIsReferenced = nodeNeedsReference;
}
-bool XMLTokenizer::write(const SegmentedString& s, bool /*appendData*/)
+void XMLTokenizer::write(const SegmentedString& s, bool /*appendData*/)
{
String parseString = s.toString();
@@ -95,15 +97,14 @@ bool XMLTokenizer::write(const SegmentedString& s, bool /*appendData*/)
m_originalSourceForTransform += parseString;
if (m_parserStopped || m_sawXSLTransform)
- return false;
+ return;
if (m_parserPaused) {
m_pendingSrc.append(s);
- return false;
+ return;
}
doWrite(s.toString());
- return false;
}
void XMLTokenizer::handleError(ErrorType type, const char* m, int lineNumber, int columnNumber)
@@ -200,20 +201,20 @@ void XMLTokenizer::finish()
static inline RefPtr<Element> createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
{
- ExceptionCode ec = 0;
- RefPtr<Element> reportElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "parsererror", ec);
- reportElement->setAttribute(HTMLNames::styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black");
+ RefPtr<Element> reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), false);
+ reportElement->setAttribute(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black");
- RefPtr<Element> h3 = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "h3", ec);
+ ExceptionCode ec = 0;
+ RefPtr<Element> h3 = doc->createElement(h3Tag, false);
reportElement->appendChild(h3.get(), ec);
h3->appendChild(doc->createTextNode("This page contains the following errors:"), ec);
-
- RefPtr<Element> fixed = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "div", ec);
+
+ RefPtr<Element> fixed = doc->createElement(divTag, false);
reportElement->appendChild(fixed.get(), ec);
- fixed->setAttribute(HTMLNames::styleAttr, "font-family:monospace;font-size:12px");
+ fixed->setAttribute(styleAttr, "font-family:monospace;font-size:12px");
fixed->appendChild(doc->createTextNode(errorMessages), ec);
-
- h3 = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "h3", ec);
+
+ h3 = doc->createElement(h3Tag, false);
reportElement->appendChild(h3.get(), ec);
h3->appendChild(doc->createTextNode("Below is a rendering of the page up to the first error."), ec);
@@ -235,16 +236,16 @@ void XMLTokenizer::insertErrorMessageBlock()
Document* doc = m_doc;
Node* documentElement = doc->documentElement();
if (!documentElement) {
- RefPtr<Node> rootElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "html", ec);
+ RefPtr<Node> rootElement = doc->createElement(htmlTag, false);
doc->appendChild(rootElement, ec);
- RefPtr<Node> body = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "body", ec);
+ RefPtr<Node> body = doc->createElement(bodyTag, false);
rootElement->appendChild(body, ec);
documentElement = body.get();
}
#if ENABLE(SVG)
else if (documentElement->namespaceURI() == SVGNames::svgNamespaceURI) {
- RefPtr<Node> rootElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "html", ec);
- RefPtr<Node> body = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "body", ec);
+ RefPtr<Node> rootElement = doc->createElement(htmlTag, false);
+ RefPtr<Node> body = doc->createElement(bodyTag, false);
rootElement->appendChild(body, ec);
body->appendChild(documentElement, ec);
doc->appendChild(rootElement.get(), ec);
@@ -253,8 +254,8 @@ void XMLTokenizer::insertErrorMessageBlock()
#endif
#if ENABLE(WML)
else if (isWMLDocument()) {
- RefPtr<Node> rootElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "html", ec);
- RefPtr<Node> body = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "body", ec);
+ RefPtr<Node> rootElement = doc->createElement(htmlTag, false);
+ RefPtr<Node> body = doc->createElement(bodyTag, false);
rootElement->appendChild(body, ec);
body->appendChild(documentElement, ec);
doc->appendChild(rootElement.get(), ec);
@@ -266,9 +267,9 @@ void XMLTokenizer::insertErrorMessageBlock()
documentElement->insertBefore(reportElement, documentElement->firstChild(), ec);
#if ENABLE(XSLT)
if (doc->transformSourceDocument()) {
- RefPtr<Element> par = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "p", ec);
+ RefPtr<Element> par = doc->createElement(pTag, false);
reportElement->appendChild(par, ec);
- par->setAttribute(HTMLNames::styleAttr, "white-space: normal");
+ par->setAttribute(styleAttr, "white-space: normal");
par->appendChild(doc->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."), ec);
}
#endif
diff --git a/WebCore/dom/XMLTokenizer.h b/WebCore/dom/XMLTokenizer.h
index c5c0847..8f35c63 100644
--- a/WebCore/dom/XMLTokenizer.h
+++ b/WebCore/dom/XMLTokenizer.h
@@ -169,7 +169,7 @@ namespace WebCore {
enum ErrorType { warning, nonFatal, fatal };
// from Tokenizer
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
virtual bool isWaitingForScripts() const;
virtual void stopParsing();
diff --git a/WebCore/dom/XMLTokenizerLibxml2.cpp b/WebCore/dom/XMLTokenizerLibxml2.cpp
index 24ea6e8..77a1afd 100644
--- a/WebCore/dom/XMLTokenizerLibxml2.cpp
+++ b/WebCore/dom/XMLTokenizerLibxml2.cpp
@@ -395,7 +395,7 @@ static void* openFunc(const char* uri)
ASSERT(globalDocLoader);
ASSERT(currentThread() == libxmlLoaderThread);
- KURL url(uri);
+ KURL url(KURL(), uri);
if (!shouldAllowExternalLoad(url))
return &globalDescriptor;
@@ -706,7 +706,8 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
nb_attributes, nb_defaulted, libxmlAttributes);
return;
}
-
+
+ bool isFirstElement = !m_sawFirstElement;
m_sawFirstElement = true;
exitText();
@@ -722,14 +723,14 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
uri = m_defaultNamespaceURI;
}
- ExceptionCode ec = 0;
QualifiedName qName(prefix, localName, uri);
- RefPtr<Element> newElement = m_doc->createElement(qName, true, ec);
+ RefPtr<Element> newElement = m_doc->createElement(qName, true);
if (!newElement) {
stopParsing();
return;
}
+ ExceptionCode ec = 0;
handleElementNamespaces(newElement.get(), libxmlNamespaces, nb_namespaces, ec);
if (ec) {
stopParsing();
@@ -763,6 +764,9 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
setCurrentNode(newElement.get());
if (m_view && !newElement->attached())
newElement->attach();
+
+ if (isFirstElement && m_doc->frame())
+ m_doc->frame()->loader()->dispatchDocumentElementAvailable();
}
void XMLTokenizer::endElementNs()
diff --git a/WebCore/dom/XMLTokenizerQt.cpp b/WebCore/dom/XMLTokenizerQt.cpp
index ce50126..68bc17b 100644
--- a/WebCore/dom/XMLTokenizerQt.cpp
+++ b/WebCore/dom/XMLTokenizerQt.cpp
@@ -507,6 +507,8 @@ void XMLTokenizer::parseStartElement()
m_sawFirstElement = true;
return;
}
+
+ bool isFirstElement = !m_sawFirstElement;
m_sawFirstElement = true;
exitText();
@@ -520,14 +522,14 @@ void XMLTokenizer::parseStartElement()
uri = m_defaultNamespaceURI;
}
- ExceptionCode ec = 0;
QualifiedName qName(prefix, localName, uri);
- RefPtr<Element> newElement = m_doc->createElement(qName, true, ec);
+ RefPtr<Element> newElement = m_doc->createElement(qName, true);
if (!newElement) {
stopParsing();
return;
}
+ ExceptionCode ec = 0;
handleElementNamespaces(newElement.get(), m_stream.namespaceDeclarations(), ec);
if (ec) {
stopParsing();
@@ -552,6 +554,9 @@ void XMLTokenizer::parseStartElement()
setCurrentNode(newElement.get());
if (m_view && !newElement->attached())
newElement->attach();
+
+ if (isFirstElement && m_doc->frame())
+ m_doc->frame()->loader()->dispatchDocumentElementAvailable();
}
void XMLTokenizer::parseEndElement()
diff --git a/WebCore/dom/make_names.pl b/WebCore/dom/make_names.pl
index f9eba88..f2a7a76 100755
--- a/WebCore/dom/make_names.pl
+++ b/WebCore/dom/make_names.pl
@@ -93,6 +93,7 @@ sub initializeTagPropertyHash
'interfaceName' => defaultInterfaceName($_[0]),
# By default, the JSInterfaceName is the same as the interfaceName.
'JSInterfaceName' => defaultInterfaceName($_[0]),
+ 'mapToTagName' => '',
'wrapperOnlyIfMediaIsAvailable' => 0);
}
@@ -217,47 +218,126 @@ sub printMacros
}
}
-sub printConstructors
+sub usesDefaultWrapper
{
- my $F = shift;
+ my $tagName = shift;
+ return $tagName eq $parameters{'namespace'} . "Element";
+}
- print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
- for my $name (sort keys %tags) {
- my $ucName = $tags{$name}{'interfaceName'};
-
- # Print the method signature avoiding unused arguments' name.
- print F "static PassRefPtr<$parameters{'namespace'}Element> ${name}Constructor(Document* doc";
- if ($parameters{'namespace'} eq "HTML") {
- print F ", HTMLFormElement* formElement";
- if ($tags{$name}{'constructorNeedsFormElement'}) {
- print F " formElement";
- }
- }
- print F ", bool";
- if ($tags{$name}{'constructorNeedsCreatedByParser'}) {
- print F " createdByParser";
+# Build a direct mapping from the tags to the Element to create, excluding
+# Element that have not constructor.
+sub buildConstructorMap
+{
+ my %tagConstructorMap = ();
+ for my $tagName (keys %tags) {
+ 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'};
}
- print F ")\n{\n";
- # Now call the constructor with the right parameters.
- print F " return new ${ucName}($parameters{'namespace'}Names::${name}Tag, doc";
- if ($tags{$name}{'constructorNeedsFormElement'}) {
- print F ", formElement";
+ # Chop the string to keep the interesting part.
+ $interfaceName =~ s/$parameters{'namespace'}(.*)Element/$1/;
+ $tagConstructorMap{$tagName} = lc($interfaceName);
+ }
+
+ return %tagConstructorMap;
+}
+
+# Helper method that print the constructor's signature avoiding
+# unneeded arguments.
+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 ", HTMLFormElement*";
+ if ($tags{$tagName}{'constructorNeedsFormElement'}) {
+ print F " formElement";
}
- if ($tags{$name}{'constructorNeedsCreatedByParser'}) {
- print F ", createdByParser";
+ }
+ print F ", bool";
+ if ($tags{$tagName}{'constructorNeedsCreatedByParser'}) {
+ print F " createdByParser";
+ }
+ print F ")\n{\n";
+}
+
+# Helper method to dump the constructor interior and call the
+# Element constructor with the right arguments.
+# The variable names should be kept in sync with the previous method.
+sub printConstructorInterior
+{
+ my ($F, $tagName, $interfaceName, $constructorTagName) = @_;
+
+ # Handle media elements.
+ if ($tags{$tagName}{'wrapperOnlyIfMediaIsAvailable'}) {
+ print F <<END
+ if (!MediaPlayer::isAvailable())
+ return new HTMLElement($constructorTagName, doc);
+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";
+ }
+ print F ");\n}\n\n";
+}
+
+sub printConstructors
+{
+ my ($F, $tagConstructorMapRef) = @_;
+ my %tagConstructorMap = %$tagConstructorMapRef;
+
+ 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'};
+
+ # 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'});
+
+ $uniqueTags{$interfaceName} = '1';
+
+ printConstructorSignature($F, $tagName, $tagConstructorMap{$tagName}, "tagName");
+ printConstructorInterior($F, $tagName, $interfaceName, "tagName");
+ }
+
+ # 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'};
+ printConstructorSignature($F, $mappedName, $mappedName . "To" . $tagName, "tagName");
+ printConstructorInterior($F, $mappedName, $tags{$mappedName}{'interfaceName'}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");
}
- print F ");\n}\n\n";
}
+
print F "#endif\n" if $parameters{'guardFactoryWith'};
}
sub printFunctionInits
{
- my $F = shift;
+ my ($F, $tagConstructorMap) = @_;
+ my %tagConstructorMap = %$tagConstructorMap;
- for my $name (sort keys %tags) {
- print F " gFunctionMap->set($parameters{'namespace'}Names::${name}Tag.localName().impl(), ${name}Constructor);\n";
+ for my $tagName (sort keys %tagConstructorMap) {
+ 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";
+ }
}
}
@@ -568,34 +648,40 @@ printElementIncludes($F);
print F <<END
#include <wtf/HashMap.h>
-using namespace WebCore;
+namespace WebCore {
+
+using namespace $parameters{'namespace'}Names;
END
;
-print F "typedef PassRefPtr<$parameters{'namespace'}Element> (*ConstructorFunction)(Document*";
+print F "typedef PassRefPtr<$parameters{'namespace'}Element> (*ConstructorFunction)(const QualifiedName&, Document*";
if ($parameters{'namespace'} eq "HTML") {
- print F ", HTMLFormElement* formElement";
+ print F ", HTMLFormElement*";
}
print F ", bool createdByParser);\n";
-
print F <<END
-typedef WTF::HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
+typedef HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
static FunctionMap* gFunctionMap = 0;
-namespace WebCore {
-
END
;
-printConstructors($F);
+my %tagConstructorMap = buildConstructorMap();
+
+printConstructors($F, \%tagConstructorMap);
print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
print F <<END
+static void addTag(const QualifiedName& tag, ConstructorFunction func)
+{
+ gFunctionMap->set(tag.localName().impl(), func);
+}
+
static inline void createFunctionMapIfNecessary()
{
if (gFunctionMap)
@@ -607,7 +693,7 @@ static inline void createFunctionMapIfNecessary()
END
;
-printFunctionInits($F);
+printFunctionInits($F, \%tagConstructorMap);
print F "}\n";
print F "#endif\n" if $parameters{'guardFactoryWith'};
@@ -627,12 +713,22 @@ print F <<END
if (!doc)
return 0;
+END
+;
+
+if ($parameters{'namespace'} ne "HTML") {
+print F <<END
#if ENABLE(DASHBOARD_SUPPORT)
Settings* settings = doc->settings();
if (settings && settings->usesDashboardBackwardCompatibilityMode())
return 0;
#endif
+END
+;
+}
+
+print F <<END
createFunctionMapIfNecessary();
ConstructorFunction func = gFunctionMap->get(qName.localName().impl());
if (func)
@@ -640,9 +736,9 @@ END
;
if ($parameters{"namespace"} eq "HTML") {
- print F " return func(doc, formElement, createdByParser);\n";
+ print F " return func(qName, doc, formElement, createdByParser);\n";
} else {
- print F " return func(doc, createdByParser);\n";
+ print F " return func(qName, doc, createdByParser);\n";
}
print F " return new $parameters{'namespace'}Element(qName, doc);\n";