summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/dom
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/dom')
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Attr.h2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Attr.idl4
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Attribute.h4
-rw-r--r--src/3rdparty/webkit/WebCore/dom/CharacterData.cpp23
-rw-r--r--src/3rdparty/webkit/WebCore/dom/CharacterData.h8
-rw-r--r--src/3rdparty/webkit/WebCore/dom/CharacterData.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.cpp86
-rw-r--r--src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.h47
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ClassNames.h2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ClientRect.cpp (renamed from src/3rdparty/webkit/WebCore/dom/DOMStringList.cpp)10
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ClientRect.h (renamed from src/3rdparty/webkit/WebCore/dom/StaticStringList.h)46
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ClientRect.idl (renamed from src/3rdparty/webkit/WebCore/dom/WorkerTask.cpp)25
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ClientRectList.cpp (renamed from src/3rdparty/webkit/WebCore/dom/StaticStringList.cpp)39
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ClientRectList.h (renamed from src/3rdparty/webkit/WebCore/dom/DOMStringList.h)31
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ClientRectList.idl (renamed from src/3rdparty/webkit/WebCore/dom/DOMStringList.idl)13
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Clipboard.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Clipboard.h7
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Clipboard.idl1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp221
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ContainerNode.h17
-rw-r--r--src/3rdparty/webkit/WebCore/dom/DOMCoreException.idl9
-rw-r--r--src/3rdparty/webkit/WebCore/dom/DOMImplementation.cpp34
-rw-r--r--src/3rdparty/webkit/WebCore/dom/DOMImplementation.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Document.cpp970
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Document.h210
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Document.idl117
-rw-r--r--src/3rdparty/webkit/WebCore/dom/DocumentFragment.idl7
-rw-r--r--src/3rdparty/webkit/WebCore/dom/DocumentMarker.h6
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Element.cpp290
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Element.h59
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Element.idl91
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ElementRareData.h13
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Event.cpp6
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Event.h2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Event.idl10
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventException.idl5
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventListener.h21
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventListener.idl1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventNames.h9
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventTarget.cpp7
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventTarget.h8
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventTarget.idl6
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp1166
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventTargetNode.h206
-rw-r--r--src/3rdparty/webkit/WebCore/dom/EventTargetNode.idl84
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ExceptionCode.cpp9
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ExceptionCode.h8
-rw-r--r--src/3rdparty/webkit/WebCore/dom/InputElement.cpp304
-rw-r--r--src/3rdparty/webkit/WebCore/dom/InputElement.h123
-rw-r--r--src/3rdparty/webkit/WebCore/dom/KeyboardEvent.idl6
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MessageChannel.cpp7
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MessagePort.cpp250
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MessagePort.h57
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MessagePort.idl5
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MessagePortChannel.cpp64
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MessagePortChannel.h103
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MouseEvent.cpp8
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MouseEvent.h11
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MouseEvent.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.cpp23
-rw-r--r--src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.h11
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NamedAttrMap.cpp64
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NamedAttrMap.h74
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.cpp7
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.h24
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NamedNodeMap.h65
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Node.cpp1345
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Node.h209
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Node.idl32
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NodeFilter.h1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NodeIterator.h1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/NodeRareData.h12
-rw-r--r--src/3rdparty/webkit/WebCore/dom/OptionElement.cpp150
-rw-r--r--src/3rdparty/webkit/WebCore/dom/OptionElement.h78
-rw-r--r--src/3rdparty/webkit/WebCore/dom/OptionGroupElement.cpp58
-rw-r--r--src/3rdparty/webkit/WebCore/dom/OptionGroupElement.h (renamed from src/3rdparty/webkit/WebCore/dom/FormControlElement.h)22
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Position.cpp352
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Position.h121
-rw-r--r--src/3rdparty/webkit/WebCore/dom/PositionIterator.cpp110
-rw-r--r--src/3rdparty/webkit/WebCore/dom/PositionIterator.h22
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp3
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/QualifiedName.cpp37
-rw-r--r--src/3rdparty/webkit/WebCore/dom/QualifiedName.h34
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Range.cpp116
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Range.h8
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Range.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/RangeBoundaryPoint.h121
-rw-r--r--src/3rdparty/webkit/WebCore/dom/RangeException.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h22
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ScriptElement.cpp59
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ScriptElement.h8
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.cpp18
-rw-r--r--src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.h21
-rw-r--r--src/3rdparty/webkit/WebCore/dom/SelectElement.cpp932
-rw-r--r--src/3rdparty/webkit/WebCore/dom/SelectElement.h181
-rw-r--r--src/3rdparty/webkit/WebCore/dom/StyleElement.cpp27
-rw-r--r--src/3rdparty/webkit/WebCore/dom/StyledElement.cpp29
-rw-r--r--src/3rdparty/webkit/WebCore/dom/StyledElement.h5
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Text.cpp41
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Text.h1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Tokenizer.h10
-rw-r--r--src/3rdparty/webkit/WebCore/dom/TreeWalker.h1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WheelEvent.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WheelEvent.h6
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WheelEvent.idl4
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Worker.cpp202
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Worker.h113
-rw-r--r--src/3rdparty/webkit/WebCore/dom/Worker.idl48
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerContext.cpp195
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerContext.h122
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerContext.idl61
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerLocation.cpp85
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerLocation.h73
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerLocation.idl48
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.cpp311
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.h93
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerThread.cpp154
-rw-r--r--src/3rdparty/webkit/WebCore/dom/WorkerThread.h79
-rw-r--r--src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp80
-rw-r--r--src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h15
-rw-r--r--src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp237
-rw-r--r--src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp124
-rw-r--r--src/3rdparty/webkit/WebCore/dom/XMLTokenizerScope.cpp68
-rw-r--r--src/3rdparty/webkit/WebCore/dom/XMLTokenizerScope.h (renamed from src/3rdparty/webkit/WebCore/dom/WorkerTask.h)44
-rw-r--r--src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.cpp222
-rw-r--r--src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.h129
-rwxr-xr-xsrc/3rdparty/webkit/WebCore/dom/make_names.pl251
128 files changed, 6997 insertions, 5124 deletions
diff --git a/src/3rdparty/webkit/WebCore/dom/Attr.h b/src/3rdparty/webkit/WebCore/dom/Attr.h
index 9525251..ed4dc07 100644
--- a/src/3rdparty/webkit/WebCore/dom/Attr.h
+++ b/src/3rdparty/webkit/WebCore/dom/Attr.h
@@ -37,7 +37,7 @@ namespace WebCore {
// destruction. however, this is not yet implemented.
class Attr : public ContainerNode {
- friend class NamedAttrMap;
+ friend class NamedNodeMap;
public:
Attr(Element*, Document*, PassRefPtr<Attribute>);
~Attr();
diff --git a/src/3rdparty/webkit/WebCore/dom/Attr.idl b/src/3rdparty/webkit/WebCore/dom/Attr.idl
index 42ac04c..29f4be1 100644
--- a/src/3rdparty/webkit/WebCore/dom/Attr.idl
+++ b/src/3rdparty/webkit/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
@@ -39,7 +39,7 @@ module core {
readonly attribute Element ownerElement;
// extensions
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
readonly attribute CSSStyleDeclaration style;
#endif
};
diff --git a/src/3rdparty/webkit/WebCore/dom/Attribute.h b/src/3rdparty/webkit/WebCore/dom/Attribute.h
index 2b2863f..b06d120 100644
--- a/src/3rdparty/webkit/WebCore/dom/Attribute.h
+++ b/src/3rdparty/webkit/WebCore/dom/Attribute.h
@@ -32,14 +32,14 @@ namespace WebCore {
class Attr;
class CSSStyleDeclaration;
class Element;
-class NamedAttrMap;
+class NamedNodeMap;
// This has no counterpart in DOM.
// It is an internal representation of the node value of an Attr.
// The actual Attr with its value as a Text child is allocated only if needed.
class Attribute : public RefCounted<Attribute> {
friend class Attr;
- friend class NamedAttrMap;
+ friend class NamedNodeMap;
public:
static PassRefPtr<Attribute> create(const QualifiedName& name, const AtomicString& value)
{
diff --git a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp
index 247a5b6..9a72de9 100644
--- a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp
@@ -23,7 +23,6 @@
#include "CharacterData.h"
#include "CString.h"
-#include "Document.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "MutationEvent.h"
@@ -31,14 +30,14 @@
namespace WebCore {
-CharacterData::CharacterData(Document *doc)
- : EventTargetNode(doc)
+CharacterData::CharacterData(Document *doc, bool isText)
+ : Node(doc, false, false, isText)
, m_data(StringImpl::empty())
{
}
-CharacterData::CharacterData(Document* document, const String& text)
- : EventTargetNode(document)
+CharacterData::CharacterData(Document* document, const String& text, bool isText)
+ : Node(document, false, false, isText)
{
m_data = text.impl() ? text.impl() : StringImpl::empty();
}
@@ -61,7 +60,7 @@ void CharacterData::setData(const String& data, ExceptionCode&)
detach();
attach();
} else if (renderer())
- static_cast<RenderText*>(renderer())->setText(m_data);
+ toRenderText(renderer())->setText(m_data);
dispatchModifiedEvent(oldStr.get());
@@ -89,7 +88,7 @@ void CharacterData::appendData(const String& arg, ExceptionCode&)
detach();
attach();
} else if (renderer())
- static_cast<RenderText*>(renderer())->setTextWithOffset(m_data, oldStr->length(), 0);
+ toRenderText(renderer())->setTextWithOffset(m_data, oldStr->length(), 0);
dispatchModifiedEvent(oldStr.get());
}
@@ -110,7 +109,7 @@ void CharacterData::insertData(unsigned offset, const String& arg, ExceptionCode
detach();
attach();
} else if (renderer())
- static_cast<RenderText*>(renderer())->setTextWithOffset(m_data, offset, 0);
+ toRenderText(renderer())->setTextWithOffset(m_data, offset, 0);
dispatchModifiedEvent(oldStr.get());
@@ -139,7 +138,7 @@ void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionCode& e
detach();
attach();
} else if (renderer())
- static_cast<RenderText*>(renderer())->setTextWithOffset(m_data, offset, count);
+ toRenderText(renderer())->setTextWithOffset(m_data, offset, count);
dispatchModifiedEvent(oldStr.get());
@@ -169,7 +168,7 @@ void CharacterData::replaceData(unsigned offset, unsigned count, const String& a
detach();
attach();
} else if (renderer())
- static_cast<RenderText*>(renderer())->setTextWithOffset(m_data, offset, count);
+ toRenderText(renderer())->setTextWithOffset(m_data, offset, count);
dispatchModifiedEvent(oldStr.get());
@@ -199,7 +198,7 @@ void CharacterData::dispatchModifiedEvent(StringImpl* prevValue)
parentNode()->childrenChanged();
if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) {
ExceptionCode ec;
- dispatchEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, false, 0, prevValue, m_data, String(), 0), ec);
+ dispatchMutationEvent(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data, ec);
}
dispatchSubtreeModifiedEvent();
}
@@ -225,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/src/3rdparty/webkit/WebCore/dom/CharacterData.h b/src/3rdparty/webkit/WebCore/dom/CharacterData.h
index 48ddc36..d9e55c0 100644
--- a/src/3rdparty/webkit/WebCore/dom/CharacterData.h
+++ b/src/3rdparty/webkit/WebCore/dom/CharacterData.h
@@ -23,14 +23,14 @@
#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);
- CharacterData(Document*);
+ CharacterData(Document*, const String& text, bool isText = false);
+ CharacterData(Document*, bool isText = false);
virtual ~CharacterData();
// DOM methods & attributes for CharacterData
diff --git a/src/3rdparty/webkit/WebCore/dom/CharacterData.idl b/src/3rdparty/webkit/WebCore/dom/CharacterData.idl
index 74dc483..7c8c7ac 100644
--- a/src/3rdparty/webkit/WebCore/dom/CharacterData.idl
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.cpp b/src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.cpp
new file mode 100644
index 0000000..9883f58
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 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
+ * 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 "CheckedRadioButtons.h"
+
+#include "HTMLInputElement.h"
+
+namespace WebCore {
+
+void CheckedRadioButtons::addButton(HTMLFormControlElement* element)
+{
+ // We only want to add radio buttons.
+ if (!element->isRadioButton())
+ return;
+
+ // Without a name, there is no group.
+ if (element->name().isEmpty())
+ return;
+
+ HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element);
+
+ // We only track checked buttons.
+ if (!inputElement->checked())
+ return;
+
+ if (!m_nameToCheckedRadioButtonMap)
+ m_nameToCheckedRadioButtonMap.set(new NameToInputMap);
+
+ pair<NameToInputMap::iterator, bool> result = m_nameToCheckedRadioButtonMap->add(element->name().impl(), inputElement);
+ if (result.second)
+ return;
+
+ HTMLInputElement* oldCheckedButton = result.first->second;
+ if (oldCheckedButton == inputElement)
+ return;
+
+ result.first->second = inputElement;
+ oldCheckedButton->setChecked(false);
+}
+
+HTMLInputElement* CheckedRadioButtons::checkedButtonForGroup(const AtomicString& name) const
+{
+ if (!m_nameToCheckedRadioButtonMap)
+ return 0;
+
+ return m_nameToCheckedRadioButtonMap->get(name.impl());
+}
+
+void CheckedRadioButtons::removeButton(HTMLFormControlElement* element)
+{
+ if (element->name().isEmpty() || !m_nameToCheckedRadioButtonMap)
+ return;
+
+ NameToInputMap::iterator it = m_nameToCheckedRadioButtonMap->find(element->name().impl());
+ if (it == m_nameToCheckedRadioButtonMap->end() || it->second != element)
+ return;
+
+ InputElement* inputElement = toInputElement(element);
+ ASSERT_UNUSED(inputElement, inputElement);
+ ASSERT(inputElement->isChecked());
+ ASSERT(element->isRadioButton());
+
+ m_nameToCheckedRadioButtonMap->remove(it);
+ if (m_nameToCheckedRadioButtonMap->isEmpty())
+ m_nameToCheckedRadioButtonMap.clear();
+}
+
+} // namespace
diff --git a/src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.h b/src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.h
new file mode 100644
index 0000000..5a57955
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/CheckedRadioButtons.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 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
+ * 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 CheckedRadioButtons_h
+#define CheckedRadioButtons_h
+
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class AtomicString;
+class AtomicStringImpl;
+class HTMLInputElement;
+class HTMLFormControlElement;
+
+class CheckedRadioButtons {
+public:
+ void addButton(HTMLFormControlElement*);
+ void removeButton(HTMLFormControlElement*);
+ HTMLInputElement* checkedButtonForGroup(const AtomicString& groupName) const;
+
+private:
+ typedef HashMap<AtomicStringImpl*, HTMLInputElement*> NameToInputMap;
+ OwnPtr<NameToInputMap> m_nameToCheckedRadioButtonMap;
+};
+
+} // namespace WebCore
+
+#endif // CheckedRadioButtons_h
diff --git a/src/3rdparty/webkit/WebCore/dom/ClassNames.h b/src/3rdparty/webkit/WebCore/dom/ClassNames.h
index 7992d54..8f4852f 100644
--- a/src/3rdparty/webkit/WebCore/dom/ClassNames.h
+++ b/src/3rdparty/webkit/WebCore/dom/ClassNames.h
@@ -56,8 +56,8 @@ namespace WebCore {
typedef Vector<AtomicString, 8> ClassNameVector;
String m_string;
- bool m_shouldFoldCase;
ClassNameVector m_vector;
+ bool m_shouldFoldCase;
bool m_createdVector;
};
diff --git a/src/3rdparty/webkit/WebCore/dom/DOMStringList.cpp b/src/3rdparty/webkit/WebCore/dom/ClientRect.cpp
index f89702b..c69a2ab 100644
--- a/src/3rdparty/webkit/WebCore/dom/DOMStringList.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/ClientRect.cpp
@@ -23,12 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
#include "config.h"
-#include "DOMStringList.h"
+#include "ClientRect.h"
namespace WebCore {
-DOMStringList::~DOMStringList()
+ClientRect::ClientRect()
+{
+}
+
+ClientRect::ClientRect(const IntRect& rect)
+ : m_rect(rect)
{
}
diff --git a/src/3rdparty/webkit/WebCore/dom/StaticStringList.h b/src/3rdparty/webkit/WebCore/dom/ClientRect.h
index 5b13e87..349ea85 100644
--- a/src/3rdparty/webkit/WebCore/dom/StaticStringList.h
+++ b/src/3rdparty/webkit/WebCore/dom/ClientRect.h
@@ -24,38 +24,36 @@
*
*/
-#ifndef StaticStringList_h
-#define StaticStringList_h
+#ifndef ClientRect_h
+#define ClientRect_h
-#include "DOMStringList.h"
+#include "FloatRect.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
- class StaticStringList : public DOMStringList {
+ class IntRect;
+
+ class ClientRect : public RefCounted<ClientRect> {
public:
- static PassRefPtr<StaticStringList> create(const Vector<String>& strings)
- {
- return adoptRef(new StaticStringList(strings));
- }
- static PassRefPtr<StaticStringList> adopt(Vector<String>& strings)
- {
- StaticStringList* newList = new StaticStringList;
- newList->m_strings.swap(strings);
- return adoptRef(newList);
- }
- virtual ~StaticStringList();
-
- virtual unsigned length() const;
- virtual String item(unsigned) const;
- virtual bool contains(const String&) const;
+ 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:
- StaticStringList(const Vector<String>&);
- StaticStringList();
+ ClientRect();
+ ClientRect(const IntRect&);
- Vector<String> m_strings;
- };
+ FloatRect m_rect;
+ };
} // namespace WebCore
-#endif // StaticStringList
+#endif // ClientRect_h
diff --git a/src/3rdparty/webkit/WebCore/dom/WorkerTask.cpp b/src/3rdparty/webkit/WebCore/dom/ClientRect.idl
index 4a22c59..6f0598f 100644
--- a/src/3rdparty/webkit/WebCore/dom/WorkerTask.cpp
+++ b/src/3rdparty/webkit/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,18 +24,17 @@
*
*/
-#include "config.h"
+module view {
-#if ENABLE(WORKERS)
+ 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;
+ };
-#include "WorkerTask.h"
-
-namespace WebCore {
-
-WorkerTask::~WorkerTask()
-{
}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/src/3rdparty/webkit/WebCore/dom/StaticStringList.cpp b/src/3rdparty/webkit/WebCore/dom/ClientRectList.cpp
index a6de92a..95ec758 100644
--- a/src/3rdparty/webkit/WebCore/dom/StaticStringList.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/ClientRectList.cpp
@@ -25,43 +25,42 @@
*/
#include "config.h"
-#include "StaticStringList.h"
+#include "ClientRectList.h"
-namespace WebCore {
+#include "ExceptionCode.h"
+#include "ClientRect.h"
-StaticStringList::StaticStringList(const Vector<String>& strings)
- : m_strings(strings)
-{
-}
+namespace WebCore {
-StaticStringList::StaticStringList()
+ClientRectList::ClientRectList()
{
}
-StaticStringList::~StaticStringList()
+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()));
}
-unsigned StaticStringList::length() const
+ClientRectList::~ClientRectList()
{
- return m_strings.size();
}
-String StaticStringList::item(unsigned index) const
+unsigned ClientRectList::length() const
{
- if (index >= m_strings.size())
- return "";
- return m_strings[index];
+ return m_list.size();
}
-bool StaticStringList::contains(const String& str) const
+ClientRect* ClientRectList::item(unsigned index)
{
- size_t count = m_strings.size();
- for (size_t i = 0; i < count; ++i) {
- if (m_strings[i] == str)
- return true;
+ if (index >= m_list.size()) {
+ // FIXME: this should throw an exception.
+ // ec = INDEX_SIZE_ERR;
+ return 0;
}
- return false;
+
+ return m_list[index].get();
}
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/DOMStringList.h b/src/3rdparty/webkit/WebCore/dom/ClientRectList.h
index 630e33e..03915b1 100644
--- a/src/3rdparty/webkit/WebCore/dom/DOMStringList.h
+++ b/src/3rdparty/webkit/WebCore/dom/ClientRectList.h
@@ -24,23 +24,34 @@
*
*/
-#ifndef DOMStringList_h
-#define DOMStringList_h
+#ifndef ClientRectList_h
+#define ClientRectList_h
-#include "PlatformString.h"
+#include "FloatQuad.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
namespace WebCore {
- class DOMStringList : public RefCounted<DOMStringList> {
+ class ClientRect;
+
+ class ClientRectList : public RefCounted<ClientRectList> {
public:
- virtual ~DOMStringList();
+ static PassRefPtr<ClientRectList> create() { return adoptRef(new ClientRectList); }
+ static PassRefPtr<ClientRectList> create(const Vector<FloatQuad>& quads) { return adoptRef(new ClientRectList(quads)); }
+ ~ClientRectList();
+
+ unsigned length() const;
+ ClientRect* item(unsigned index);
+
+ private:
+ ClientRectList();
+ ClientRectList(const Vector<FloatQuad>&);
- virtual unsigned length() const = 0;
- virtual String item(unsigned) const = 0;
- virtual bool contains(const String&) const = 0;
- };
+ Vector<RefPtr<ClientRect> > m_list;
+ };
} // namespace WebCore
-#endif // DOMStringList_h
+#endif // ClientRectList_h
diff --git a/src/3rdparty/webkit/WebCore/dom/DOMStringList.idl b/src/3rdparty/webkit/WebCore/dom/ClientRectList.idl
index 16d4e12..8230f6c 100644
--- a/src/3rdparty/webkit/WebCore/dom/DOMStringList.idl
+++ b/src/3rdparty/webkit/WebCore/dom/ClientRectList.idl
@@ -24,18 +24,15 @@
*
*/
-module core {
+module view {
interface [
GenerateConstructor,
- HasCustomIndexGetter
- ] DOMStringList {
-
- // Unlike the index getter, item() never raises exceptions, and returns null for out of bounds indices.
- [Custom] DOMString item(in unsigned long index);
-
+ HasIndexGetter
+ ] ClientRectList {
readonly attribute unsigned long length;
- boolean contains(in DOMString str);
+ ClientRect item(in [IsIndex] unsigned long index);
+ // FIXME: Fix list behavior to allow custom exceptions to be thrown.
};
}
diff --git a/src/3rdparty/webkit/WebCore/dom/Clipboard.cpp b/src/3rdparty/webkit/WebCore/dom/Clipboard.cpp
index f7a52ef..6d1bc15 100644
--- a/src/3rdparty/webkit/WebCore/dom/Clipboard.cpp
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/Clipboard.h b/src/3rdparty/webkit/WebCore/dom/Clipboard.h
index 59ae026..0fea604 100644
--- a/src/3rdparty/webkit/WebCore/dom/Clipboard.h
+++ b/src/3rdparty/webkit/WebCore/dom/Clipboard.h
@@ -33,6 +33,8 @@
namespace WebCore {
+ class FileList;
+
// State available during IE's events for drag and drop and copy/paste
class Clipboard : public RefCounted<Clipboard> {
public:
@@ -53,11 +55,12 @@ namespace WebCore {
// extensions beyond IE's API
virtual HashSet<String> types() const = 0;
-
+ virtual PassRefPtr<FileList> files() const = 0;
+
IntPoint dragLocation() const { return m_dragLoc; }
CachedImage* dragImage() const { return m_dragImage.get(); }
virtual void setDragImage(CachedImage*, const IntPoint&) = 0;
- Node* dragImageElement() { return m_dragImageElement.get(); }
+ Node* dragImageElement() const { return m_dragImageElement.get(); }
virtual void setDragImageElement(Node*, const IntPoint&) = 0;
virtual DragImageRef createDragImage(IntPoint& dragLocation) const = 0;
diff --git a/src/3rdparty/webkit/WebCore/dom/Clipboard.idl b/src/3rdparty/webkit/WebCore/dom/Clipboard.idl
index 6fe83f7..dc8677e 100644
--- a/src/3rdparty/webkit/WebCore/dom/Clipboard.idl
+++ b/src/3rdparty/webkit/WebCore/dom/Clipboard.idl
@@ -34,6 +34,7 @@ module core {
attribute [ConvertNullStringTo=Undefined] DOMString dropEffect;
attribute [ConvertNullStringTo=Undefined] DOMString effectAllowed;
readonly attribute [CustomGetter] Array types;
+ readonly attribute FileList files;
[Custom] void clearData(in [Optional] DOMString type)
raises(DOMException);
diff --git a/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp b/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp
index 0f46ae6..20cc7a3 100644
--- a/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp
+++ b/src/3rdparty/webkit/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
@@ -23,10 +23,9 @@
#include "config.h"
#include "ContainerNode.h"
+#include "Cache.h"
#include "ContainerNodeAlgorithms.h"
#include "DeleteButtonController.h"
-#include "Document.h"
-#include "Editor.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "FloatRect.h"
@@ -34,10 +33,11 @@
#include "FrameView.h"
#include "InlineTextBox.h"
#include "MutationEvent.h"
+#include "Page.h"
#include "RenderTheme.h"
#include "RootInlineBox.h"
-#include "SystemTime.h"
-#include <wtf/Vector.h>
+#include "loader.h"
+#include <wtf/CurrentTime.h>
namespace WebCore {
@@ -45,16 +45,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()
{
@@ -101,9 +95,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;
@@ -131,8 +124,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();
@@ -152,6 +143,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.
@@ -165,9 +157,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
child = nextChild.release();
}
- document()->setDocumentChanged(true);
- if (childCountDelta)
- childrenChanged(false, prev.get(), next.get(), childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -225,7 +214,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".
@@ -280,7 +269,6 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
child = nextChild.release();
}
- document()->setDocumentChanged(true);
if (childCountDelta)
childrenChanged(false, prev.get(), next.get(), childCountDelta);
dispatchSubtreeModifiedEvent();
@@ -291,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)
@@ -374,8 +362,6 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
allowEventDispatch();
- document()->setDocumentChanged(true);
-
// Dispatch post-removal mutation events
childrenChanged(false, prev, next, -1);
dispatchSubtreeModifiedEvent();
@@ -395,25 +381,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);
@@ -428,8 +414,6 @@ bool ContainerNode::removeChildren()
if (n->inDocument())
n->removedFromDocument();
-
- n->deref();
}
allowEventDispatch();
@@ -464,7 +448,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) {
@@ -485,7 +468,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) {
@@ -497,6 +479,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
@@ -510,14 +493,13 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
child = nextChild.release();
}
- document()->setDocumentChanged(true);
- childrenChanged(false, prev.get(), 0, childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
{
+ ASSERT(newChild);
// This function is only used during parsing.
// It does not send any DOM mutation events.
@@ -542,13 +524,31 @@ 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;
+ }
+ }
+ cache()->loader()->suspendPendingRequests();
+ }
++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);
+ }
+ cache()->loader()->resumePendingRequests();
+ }
--s_attachDepth;
}
@@ -576,55 +576,50 @@ void ContainerNode::dispatchPostAttachCallbacks()
void ContainerNode::attach()
{
- ++s_attachDepth;
-
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->attach();
- EventTargetNode::attach();
-
- if (s_attachDepth == 1 && s_postAttachCallbackQueue)
- dispatchPostAttachCallbacks();
- --s_attachDepth;
+ Node::attach();
}
void ContainerNode::detach()
{
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->detach();
- setHasChangedChild(false);
- EventTargetNode::detach();
+ setChildNeedsStyleRecalc(false);
+ 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)
@@ -680,21 +675,24 @@ 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() && !static_cast<RenderText*>(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();
- if (o->isText() && static_cast<RenderText *>(o)->firstTextBox()) {
- point.move(static_cast<RenderText *>(o)->minXPos(),
- static_cast<RenderText *>(o)->firstTextBox()->root()->topOverflow());
- } else
- point.move(o->xPos(), o->yPos());
+ if (o->isText() && toRenderText(o)->firstTextBox()) {
+ point.move(toRenderText(o)->linesBoundingBox().x(),
+ toRenderText(o)->firstTextBox()->root()->topOverflow());
+ } else if (o->isBox()) {
+ RenderBox* box = toRenderBox(o);
+ point.move(box->x(), box->y());
+ }
return true;
}
}
@@ -714,12 +712,11 @@ 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(o->width(),
- o->height() + o->borderTopExtra() + o->borderBottomExtra());
+ point.move(box->width(), box->height());
return true;
}
@@ -730,8 +727,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;
@@ -739,15 +736,17 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
}
o = prev;
}
+ ASSERT(o);
if (o->isText() || o->isReplaced()) {
point = o->container()->localToAbsolute();
- int xOffset;
- if (o->isText())
- xOffset = static_cast<RenderText *>(o)->minXPos() + o->width();
- else
- xOffset = o->xPos() + o->width();
-
- point.move(xOffset, o->yPos() + o->height());
+ if (o->isText()) {
+ RenderText* text = toRenderText(o);
+ IntRect linesBox = text->linesBoundingBox();
+ 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());
+ }
return true;
}
}
@@ -762,8 +761,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,26 +779,26 @@ void ContainerNode::setFocus(bool received)
if (focused() == received)
return;
- EventTargetNode::setFocus(received);
+ Node::setFocus(received);
// note that we need to recalc the style
- setChanged();
+ setNeedsStyleRecalc();
}
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
if (renderer()) {
bool reactsToPress = renderer()->style()->affectedByActiveRules();
if (reactsToPress)
- setChanged();
+ setNeedsStyleRecalc();
if (renderer() && renderer()->style()->hasAppearance()) {
- if (theme()->stateChanged(renderer(), PressedState))
+ if (renderer()->theme()->stateChanged(renderer(), PressedState))
reactsToPress = true;
}
if (reactsToPress && pause) {
@@ -813,7 +811,7 @@ void ContainerNode::setActive(bool down, bool pause)
#endif
// Ensure there are no pending changes
- Document::updateDocumentsRendering();
+ Document::updateStyleForAllDocuments();
// Do an immediate repaint.
if (renderer())
renderer()->repaint(true);
@@ -834,15 +832,15 @@ 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
if (renderer()) {
if (renderer()->style()->affectedByHoverRules())
- setChanged();
+ setNeedsStyleRecalc();
if (renderer() && renderer()->style()->hasAppearance())
- theme()->stateChanged(renderer(), HoverState);
+ renderer()->theme()->stateChanged(renderer(), HoverState);
}
}
@@ -876,12 +874,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->parentNode(), String(), String(), String(), 0), ec);
+ c->dispatchMutationEvent(eventNames().DOMNodeInsertedEvent, true, c->parentNode(), String(), String(), ec);
if (ec)
return;
}
@@ -889,12 +886,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,
- 0, String(), String(), String(), 0), ec);
+ c->dispatchMutationEvent(eventNames().DOMNodeInsertedIntoDocumentEvent, false, 0, String(), String(), ec);
if (ec)
return;
}
@@ -908,13 +901,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->parentNode(), String(), String(), String(), 0), ec);
+ c->dispatchMutationEvent(eventNames().DOMNodeRemovedEvent, true, c->parentNode(), String(), String(), ec);
if (ec)
return;
}
@@ -922,11 +914,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,
- 0, String(), String(), String(), 0), ec);
+ c->dispatchMutationEvent(eventNames().DOMNodeRemovedFromDocumentEvent, false, 0, String(), String(), ec);
if (ec)
return;
}
diff --git a/src/3rdparty/webkit/WebCore/dom/ContainerNode.h b/src/3rdparty/webkit/WebCore/dom/ContainerNode.h
index 91ca49a..3ad932c 100644
--- a/src/3rdparty/webkit/WebCore/dom/ContainerNode.h
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/DOMCoreException.idl b/src/3rdparty/webkit/WebCore/dom/DOMCoreException.idl
index c9ac356..3001995 100644
--- a/src/3rdparty/webkit/WebCore/dom/DOMCoreException.idl
+++ b/src/3rdparty/webkit/WebCore/dom/DOMCoreException.idl
@@ -36,7 +36,7 @@ module core {
readonly attribute DOMString name;
readonly attribute DOMString message;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// Override in a Mozilla compatible format
[DontEnum] DOMString toString();
#endif
@@ -66,6 +66,13 @@ module core {
const unsigned short VALIDATION_ERR = 16;
// Introduced in DOM Level 3:
const unsigned short TYPE_MISMATCH_ERR = 17;
+ // Introduced as an XHR extension:
+ const unsigned short SECURITY_ERR = 18;
+ // Introduced in HTML5:
+ const unsigned short NETWORK_ERR = 19;
+ const unsigned short ABORT_ERR = 20;
+ const unsigned short URL_MISMATCH_ERR = 21;
+ const unsigned short QUOTA_EXCEEDED_ERR = 22;
};
}
diff --git a/src/3rdparty/webkit/WebCore/dom/DOMImplementation.cpp b/src/3rdparty/webkit/WebCore/dom/DOMImplementation.cpp
index 3a60c5b..065f708 100644
--- a/src/3rdparty/webkit/WebCore/dom/DOMImplementation.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/DOMImplementation.cpp
@@ -4,7 +4,7 @@
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
- * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,6 +25,7 @@
#include "config.h"
#include "DOMImplementation.h"
+#include "ContentType.h"
#include "CSSStyleSheet.h"
#include "DocumentType.h"
#include "Element.h"
@@ -75,7 +76,7 @@ static bool isSVG10Feature(const String &feature)
static bool initialized = false;
DEFINE_STATIC_LOCAL(FeatureSet, svgFeatures, ());
if (!initialized) {
-#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(SVG_FILTER) && ENABLE(SVG_FONTS)
+#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(FILTERS) && ENABLE(SVG_FONTS)
addString(svgFeatures, "svg");
addString(svgFeatures, "svg.static");
#endif
@@ -83,7 +84,7 @@ static bool isSVG10Feature(const String &feature)
// addString(svgFeatures, "svg.dynamic");
// addString(svgFeatures, "svg.dom.animation");
// addString(svgFeatures, "svg.dom.dynamic");
-#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(SVG_FILTER) && ENABLE(SVG_FONTS)
+#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(FILTERS) && ENABLE(SVG_FONTS)
addString(svgFeatures, "dom");
addString(svgFeatures, "dom.svg");
addString(svgFeatures, "dom.svg.static");
@@ -103,7 +104,7 @@ static bool isSVG11Feature(const String &feature)
// Sadly, we cannot claim to implement any of the SVG 1.1 generic feature sets
// lack of Font and Filter support.
// http://bugs.webkit.org/show_bug.cgi?id=15480
-#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(SVG_FILTER) && ENABLE(SVG_FONTS)
+#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(FILTERS) && ENABLE(SVG_FONTS)
addString(svgFeatures, "SVG");
addString(svgFeatures, "SVGDOM");
addString(svgFeatures, "SVG-static");
@@ -140,7 +141,7 @@ static bool isSVG11Feature(const String &feature)
addString(svgFeatures, "Clip");
addString(svgFeatures, "BasicClip");
addString(svgFeatures, "Mask");
-#if ENABLE(SVG_FILTER)
+#if ENABLE(FILTERS)
// addString(svgFeatures, "Filter");
addString(svgFeatures, "BasicFilter");
#endif
@@ -249,9 +250,10 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceUR
doc->addChild(doctype);
if (!qualifiedName.isEmpty()) {
- doc->addChild(doc->createElementNS(namespaceURI, qualifiedName, ec));
- if (ec != 0)
+ RefPtr<Node> documentElement = doc->createElementNS(namespaceURI, qualifiedName, ec);
+ if (ec)
return 0;
+ doc->addChild(documentElement.release());
}
// Hixie's interpretation of the DOM Core spec suggests we should prefer
@@ -287,8 +289,8 @@ bool DOMImplementation::isXMLMIMEType(const String& mimeType)
{
if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
return true;
- static const char* validChars = "[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]"; // per RFCs: 3023, 2045
- DEFINE_STATIC_LOCAL(RegularExpression, xmlTypeRegExp, (String("^") + validChars + "+/" + validChars + "+\\+xml$"));
+ static const char* const validChars = "[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]"; // per RFCs: 3023, 2045
+ DEFINE_STATIC_LOCAL(RegularExpression, xmlTypeRegExp, (String("^") + validChars + "+/" + validChars + "+\\+xml$", TextCaseSensitive));
return xmlTypeRegExp.match(mimeType) > -1;
}
@@ -312,15 +314,17 @@ PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& tit
PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame* frame, bool inViewSourceMode)
{
- if (inViewSourceMode) {
- if (type == "text/html" || type == "application/xhtml+xml" || type == "image/svg+xml" || isTextMIMEType(type) || isXMLMIMEType(type))
- return HTMLViewSourceDocument::create(frame, type);
- }
+ if (inViewSourceMode)
+ return HTMLViewSourceDocument::create(frame, type);
// Plugins cannot take HTML and XHTML from us, and we don't even need to initialize the plugin database for those.
if (type == "text/html")
return HTMLDocument::create(frame);
- if (type == "application/xhtml+xml")
+ if (type == "application/xhtml+xml"
+#if ENABLE(XHTMLMP)
+ || type == "application/vnd.wap.xhtml+xml"
+#endif
+ )
return Document::createXHTML(frame);
#if ENABLE(WML)
@@ -347,7 +351,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/src/3rdparty/webkit/WebCore/dom/DOMImplementation.idl b/src/3rdparty/webkit/WebCore/dom/DOMImplementation.idl
index 94d75fb..6f4df80 100644
--- a/src/3rdparty/webkit/WebCore/dom/DOMImplementation.idl
+++ b/src/3rdparty/webkit/WebCore/dom/DOMImplementation.idl
@@ -44,7 +44,7 @@ module core {
// DOMImplementationCSS interface from DOM Level 2 CSS
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
[OldStyleObjC] CSSStyleSheet createCSSStyleSheet(in DOMString title,
in DOMString media)
raises(DOMException);
diff --git a/src/3rdparty/webkit/WebCore/dom/Document.cpp b/src/3rdparty/webkit/WebCore/dom/Document.cpp
index a51d1ab..3d01c80 100644
--- a/src/3rdparty/webkit/WebCore/dom/Document.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/Document.cpp
@@ -3,9 +3,9 @@
* (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) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2008 David Levin (levin@chromium.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,8 +26,9 @@
#include "config.h"
#include "Document.h"
-#include "AnimationController.h"
#include "AXObjectCache.h"
+#include "AnimationController.h"
+#include "Attr.h"
#include "CDATASection.h"
#include "CSSHelper.h"
#include "CSSStyleSelector.h"
@@ -39,7 +40,6 @@
#include "Console.h"
#include "CookieJar.h"
#include "DOMImplementation.h"
-#include "DOMTimer.h"
#include "DOMWindow.h"
#include "DocLoader.h"
#include "DocumentFragment.h"
@@ -61,6 +61,7 @@
#include "HTMLAnchorElement.h"
#include "HTMLBodyElement.h"
#include "HTMLCanvasElement.h"
+#include "HTMLCollection.h"
#include "HTMLDocument.h"
#include "HTMLElementFactory.h"
#include "HTMLFrameOwnerElement.h"
@@ -70,6 +71,7 @@
#include "HTMLMapElement.h"
#include "HTMLNameCollection.h"
#include "HTMLNames.h"
+#include "HTMLParser.h"
#include "HTMLStyleElement.h"
#include "HTMLTitleElement.h"
#include "HTTPParsers.h"
@@ -77,8 +79,11 @@
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "ImageLoader.h"
+#include "InspectorController.h"
+#include "ScriptEventListener.h"
#include "KeyboardEvent.h"
#include "Logging.h"
+#include "MappedAttribute.h"
#include "MessageEvent.h"
#include "MouseEvent.h"
#include "MouseEventWithHitTestResults.h"
@@ -93,22 +98,22 @@
#include "ProcessingInstruction.h"
#include "ProgressEvent.h"
#include "RegisteredEventListener.h"
-#include "RegularExpression.h"
#include "RenderArena.h"
+#include "RenderTextControl.h"
#include "RenderView.h"
#include "RenderWidget.h"
#include "ScriptController.h"
+#include "ScriptElement.h"
#include "SecurityOrigin.h"
#include "SegmentedString.h"
#include "SelectionController.h"
#include "Settings.h"
#include "StyleSheetList.h"
-#include "SystemTime.h"
#include "TextEvent.h"
#include "TextIterator.h"
#include "TextResourceDecoder.h"
-#include "TreeWalker.h"
#include "Timer.h"
+#include "TreeWalker.h"
#include "UIEvent.h"
#include "WebKitAnimationEvent.h"
#include "WebKitTransitionEvent.h"
@@ -116,12 +121,11 @@
#include "XMLHttpRequest.h"
#include "XMLNames.h"
#include "XMLTokenizer.h"
-#include "JSDOMBinding.h"
-#include "ScriptController.h"
+#include <wtf/CurrentTime.h>
#include <wtf/HashFunctions.h>
#include <wtf/MainThread.h>
-#include <wtf/StdLibExtras.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/StdLibExtras.h>
#if ENABLE(DATABASE)
#include "Database.h"
@@ -161,6 +165,10 @@
#include "WMLNames.h"
#endif
+#if ENABLE(XHTMLMP)
+#include "HTMLNoScriptElement.h"
+#endif
+
using namespace std;
using namespace WTF;
using namespace Unicode;
@@ -275,17 +283,29 @@ static bool acceptsEditingFocus(Node *node)
return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
}
-static HashSet<Document*>* changedDocuments = 0;
+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*>* documentsThatNeedStyleRecalc = 0;
Document::Document(Frame* frame, bool isXHTML)
: ContainerNode(0)
, m_domtree_version(0)
, m_styleSheets(StyleSheetList::create(this))
+ , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
, m_frameElementsShouldIgnoreScrolling(false)
, m_title("")
, m_titleSetExplicitly(false)
- , m_imageLoadEventTimer(this, &Document::imageLoadEventTimerFired)
, m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
+ , m_executeScriptSoonTimer(this, &Document::executeScriptSoonTimerFired)
#if ENABLE(XSLT)
, m_transformSource(0)
#endif
@@ -315,9 +335,6 @@ Document::Document(Frame* frame, bool isXHTML)
, m_hasOpenDatabases(false)
#endif
, m_usingGeolocation(false)
-#if USE(LOW_BANDWIDTH_DISPLAY)
- , m_inLowBandwidthDisplay(false)
-#endif
{
m_document.resetSkippingRef(this);
@@ -334,7 +351,6 @@ Document::Document(Frame* frame, bool isXHTML)
visuallyOrdered = false;
m_bParsing = false;
- m_docChanged = false;
m_tokenizer = 0;
m_wellFormed = false;
@@ -349,6 +365,7 @@ Document::Document(Frame* frame, bool isXHTML)
m_usesSiblingRules = false;
m_usesFirstLineRules = false;
m_usesFirstLetterRules = false;
+ m_usesBeforeAfterRules = false;
m_gotoAnchorNeededAfterStylesheetsLoad = false;
m_styleSelector = 0;
@@ -373,6 +390,9 @@ Document::Document(Frame* frame, bool isXHTML)
static int docID = 0;
m_docID = docID++;
+#if ENABLE(XHTMLMP)
+ m_shouldProcessNoScriptElement = settings() && !settings()->isJavaScriptEnabled();
+#endif
}
void Document::removedLastRef()
@@ -422,13 +442,17 @@ Document::~Document()
ASSERT(!m_inPageCache);
ASSERT(!m_savedRenderer);
ASSERT(m_ranges.isEmpty());
+ ASSERT(!m_styleRecalcTimer.isActive());
+
+ for (size_t i = 0; i < m_scriptsToExecuteSoon.size(); ++i)
+ m_scriptsToExecuteSoon[i].first->element()->deref(); // Balances ref() in executeScriptSoon().
removeAllEventListeners();
+#if USE(JSC)
forgetAllDOMNodesForDocument(this);
+#endif
- if (m_docChanged && changedDocuments)
- changedDocuments->remove(this);
delete m_tokenizer;
m_document.resetSkippingRef(0);
delete m_styleSelector;
@@ -513,16 +537,13 @@ void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* a
m_documentElement = 0;
}
-Element* Document::documentElement() const
+void Document::cacheDocumentElement() const
{
- if (!m_documentElement) {
- Node* n = firstChild();
- while (n && !n->isElementNode())
- n = n->nextSibling();
- m_documentElement = static_cast<Element*>(n);
- }
-
- return m_documentElement.get();
+ ASSERT(!m_documentElement);
+ Node* n = firstChild();
+ while (n && !n->isElementNode())
+ n = n->nextSibling();
+ m_documentElement = static_cast<Element*>(n);
}
PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec)
@@ -535,7 +556,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()
@@ -629,7 +650,7 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo
if (ec)
return 0;
- NamedAttrMap* attrs = oldElement->attributes(true);
+ NamedNodeMap* attrs = oldElement->attributes(true);
if (attrs) {
unsigned length = attrs->length();
for (unsigned i = 0; i < length; i++) {
@@ -752,7 +773,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;
@@ -764,25 +785,21 @@ PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool cre
e = SVGElementFactory::createSVGElement(qName, this, createdByParser);
#endif
#if ENABLE(WML)
- else if (qName.namespaceURI() == WMLNames::wmlNamespaceURI || isWMLDocument())
+ else if (qName.namespaceURI() == WMLNames::wmlNamespaceURI)
e = WMLElementFactory::createWMLElement(qName, this, createdByParser);
+ else if (isWMLDocument())
+ e = WMLElementFactory::createWMLElement(QualifiedName(nullAtom, qName.localName(), WMLNames::wmlNamespaceURI), this, createdByParser);
#endif
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.
+#if ENABLE(WML)
+ if (!isWMLDocument())
+#endif
+ ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName());
+
return e.release();
}
@@ -798,7 +815,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
@@ -841,10 +858,10 @@ String Document::readyState() const
return String();
}
-String Document::inputEncoding() const
+String Document::encoding() const
{
if (TextResourceDecoder* d = decoder())
- return d->encoding().name();
+ return d->encoding().domName();
return String();
}
@@ -900,9 +917,13 @@ Element* Document::elementFromPoint(int x, int y) const
if (!renderer())
return 0;
- HitTestRequest request(true, true);
- HitTestResult result(IntPoint(x, y));
- renderer()->layer()->hitTest(request, result);
+ 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();
while (n && !n->isElementNode())
@@ -979,9 +1000,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);
}
@@ -1077,42 +1097,56 @@ PassRefPtr<TreeWalker> Document::createTreeWalker(Node *root, unsigned whatToSho
return TreeWalker::create(root, whatToShow, filter, expandEntityReferences);
}
-void Document::setDocumentChanged(bool b)
+void Document::scheduleStyleRecalc()
{
- if (b) {
- if (!m_docChanged) {
- if (!changedDocuments)
- changedDocuments = new HashSet<Document*>;
- changedDocuments->add(this);
- }
- if (m_accessKeyMapValid) {
- m_accessKeyMapValid = false;
- m_elementsByAccessKey.clear();
- }
- } else {
- if (m_docChanged && changedDocuments)
- changedDocuments->remove(this);
+ if (m_styleRecalcTimer.isActive() || inPageCache())
+ return;
+
+ ASSERT(childNeedsStyleRecalc());
+
+ if (!documentsThatNeedStyleRecalc)
+ documentsThatNeedStyleRecalc = new HashSet<Document*>;
+ documentsThatNeedStyleRecalc->add(this);
+
+ // FIXME: Why on earth is this here? This is clearly misplaced.
+ if (m_accessKeyMapValid) {
+ m_accessKeyMapValid = false;
+ m_elementsByAccessKey.clear();
}
+
+ m_styleRecalcTimer.startOneShot(0);
+}
- m_docChanged = b;
+void Document::unscheduleStyleRecalc()
+{
+ ASSERT(!childNeedsStyleRecalc());
+
+ if (documentsThatNeedStyleRecalc)
+ documentsThatNeedStyleRecalc->remove(this);
+
+ m_styleRecalcTimer.stop();
+}
+
+void Document::styleRecalcTimerFired(Timer<Document>*)
+{
+ updateStyleIfNeeded();
}
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;
}
if (m_inStyleRecalc)
return; // Guard against re-entrancy. -dwh
- if (m_frame)
- m_frame->animation()->beginAnimationUpdate();
-
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
+ if (view())
+ view()->pauseScheduledEvents();
ASSERT(!renderer() || renderArena());
if (!renderer() || !renderArena())
@@ -1151,57 +1185,64 @@ 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())
- if (change >= Inherit || n->hasChangedChild() || n->changed())
+ if (change >= Inherit || n->childNeedsStyleRecalc() || n->needsStyleRecalc())
n->recalcStyle(change);
- if (changed() && view())
- view()->layout();
+#if USE(ACCELERATED_COMPOSITING)
+ if (view()) {
+ bool layoutPending = view()->layoutPending() || renderer()->needsLayout();
+ // If we didn't update compositing layers because of layout(), we need to do so here.
+ if (!layoutPending)
+ view()->updateCompositingLayers();
+ }
+#endif
bail_out:
- setChanged(NoStyleChange);
- setHasChangedChild(false);
- setDocumentChanged(false);
-
+ setNeedsStyleRecalc(NoStyleChange);
+ setChildNeedsStyleRecalc(false);
+ unscheduleStyleRecalc();
+
+ 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;
implicitClose();
}
-
- if (m_frame)
- m_frame->animation()->endAnimationUpdate();
}
-void Document::updateRendering()
+void Document::updateStyleIfNeeded()
{
- if (hasChangedChild() && !inPageCache())
- recalcStyle(NoChange);
+ if (!childNeedsStyleRecalc() || inPageCache())
+ return;
+
+ if (m_frame)
+ m_frame->animation()->beginAnimationUpdate();
+
+ recalcStyle(NoChange);
- // Tell the animation controller that the style is available and it can start animations
+ // Tell the animation controller that updateStyleIfNeeded is finished and it can do any post-processing
if (m_frame)
- m_frame->animation()->styleAvailable();
+ m_frame->animation()->endAnimationUpdate();
}
-void Document::updateDocumentsRendering()
+void Document::updateStyleForAllDocuments()
{
- if (!changedDocuments)
+ if (!documentsThatNeedStyleRecalc)
return;
- while (changedDocuments->size()) {
- HashSet<Document*>::iterator it = changedDocuments->begin();
+ while (documentsThatNeedStyleRecalc->size()) {
+ HashSet<Document*>::iterator it = documentsThatNeedStyleRecalc->begin();
Document* doc = *it;
- changedDocuments->remove(it);
-
- doc->m_docChanged = false;
- doc->updateRendering();
+ documentsThatNeedStyleRecalc->remove(doc);
+ ASSERT(doc->childNeedsStyleRecalc() && !doc->inPageCache());
+ doc->updateStyleIfNeeded();
}
}
@@ -1210,8 +1251,7 @@ 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();
+ updateStyleIfNeeded();
// Only do a layout if changes have occurred that make it necessary.
FrameView* v = view();
@@ -1263,6 +1303,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;
@@ -1291,29 +1334,36 @@ void Document::detach()
RenderObject* render = renderer();
+ // Send out documentWillBecomeInactive() notifications to registered elements,
+ // in order to stop media elements
+ documentWillBecomeInactive();
+
+ if (m_frame) {
+ FrameView* view = m_frame->view();
+ if (view)
+ view->detachCustomScrollbars();
+ }
+
// 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;
ContainerNode::detach();
+ unscheduleStyleRecalc();
+
if (render)
render->destroy();
// This is required, as our Frame might delete itself as soon as it detaches
- // us. However, this violates Node::detach() symantics, as it's never
- // possible to re-attach. Eventually Document::detach() should be renamed
- // or this call made explicit in each of the callers of Document::detach().
- clearFramePointer();
+ // us. However, this violates Node::detach() symantics, as it's never
+ // possible to re-attach. Eventually Document::detach() should be renamed,
+ // or this setting of the frame to 0 could be made explicit in each of the
+ // callers of Document::detach().
+ m_frame = 0;
if (m_renderArena) {
delete m_renderArena;
@@ -1321,23 +1371,13 @@ void Document::detach()
}
}
-void Document::clearFramePointer()
-{
- m_frame = 0;
-}
-
-void Document::removeAllEventListenersFromAllNodes()
+void Document::removeAllEventListeners()
{
- size_t size = m_windowEventListeners.size();
- for (size_t i = 0; i < size; ++i)
- m_windowEventListeners[i]->setRemoved(true);
- m_windowEventListeners.clear();
+ if (DOMWindow* domWindow = this->domWindow())
+ domWindow->removeAllEventListeners();
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)
@@ -1354,10 +1394,15 @@ 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 toRenderView(renderer());
+}
+
void Document::clearAXObjectCache()
{
// clear cache in top document
@@ -1438,7 +1483,7 @@ void Document::open(Document* ownerDocument)
if (m_frame->loader()->state() == FrameStateProvisional)
m_frame->loader()->stopAllLoaders();
}
-
+
implicitOpen();
if (m_frame)
@@ -1465,9 +1510,17 @@ void Document::implicitOpen()
clear();
m_tokenizer = createTokenizer();
setParsing(true);
+
+ if (m_frame)
+ m_tokenizer->setXSSAuditor(m_frame->script()->xssAuditor());
+
+ // If we reload, the animation controller sticks around and has
+ // a stale animation time. We need to update it here.
+ if (m_frame && m_frame->animation())
+ m_frame->animation()->beginAnimationUpdate();
}
-HTMLElement* Document::body()
+HTMLElement* Document::body() const
{
Node* de = documentElement();
if (!de)
@@ -1554,10 +1607,16 @@ void Document::implicitClose()
// Parser should have picked up all preloads by now
m_docLoader->clearPreloads();
- // Create a body element if we don't already have one. See Radar 3758785.
+ // Create a head and a body if we don't have those yet (e.g. for about:blank).
if (!this->body() && isHTMLDocument()) {
if (Node* documentElement = this->documentElement()) {
ExceptionCode ec = 0;
+
+ // The implicit <head> isn't expected in older versions of Mail - <rdar://problem/6863795>
+ if (!head() && shouldCreateImplicitHead(this)) {
+ documentElement->appendChild(new HTMLHeadElement(headTag, this), ec);
+ ASSERT(!ec);
+ }
documentElement->appendChild(new HTMLBodyElement(bodyTag, this), ec);
ASSERT(!ec);
}
@@ -1577,8 +1636,8 @@ void Document::implicitClose()
if (f)
f->animation()->resumeAnimations(this);
- dispatchImageLoadEventsNow();
- this->dispatchWindowEvent(eventNames().loadEvent, false, false);
+ ImageLoader::dispatchPendingLoadEvents();
+ dispatchLoadEvent();
if (f)
f->loader()->handledOnloadEvents();
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -1605,30 +1664,21 @@ void Document::implicitClose()
frame()->loader()->checkCallImplicitClose();
- // Now do our painting/layout, but only if we aren't in a subframe or if we're in a subframe
- // that has been sized already. Otherwise, our view size would be incorrect, so doing any
- // layout/painting now would be pointless.
+ // We used to force a synchronous display and flush here. This really isn't
+ // necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
+ // (if your platform is syncing flushes and limiting them to 60fps).
+ m_overMinimumLayoutThreshold = true;
if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
- updateRendering();
+ updateStyleIfNeeded();
// Always do a layout after loading if needed.
if (view() && renderer() && (!renderer()->firstChild() || renderer()->needsLayout()))
view()->layout();
-
- // Paint immediately after the document is ready. We do this to ensure that any timers set by the
- // onload don't have a chance to fire before we would have painted. To avoid over-flushing we only
- // worry about this for the top-level document. For platforms that use native widgets for ScrollViews, this
- // call does nothing (Mac, wx).
- // FIXME: This causes a timing issue with the dispatchDidFinishLoad delegate callback on Mac, so think
- // before enabling it, even if Mac becomes viewless later.
- // See <rdar://problem/5092361>
- if (view() && !ownerElement())
- view()->hostWindow()->paint();
}
#if PLATFORM(MAC)
if (f && renderer() && this == topDocument() && AXObjectCache::accessibilityEnabled())
- axObjectCache()->postNotificationToElement(renderer(), "AXLoadComplete");
+ axObjectCache()->postNotification(renderer(), "AXLoadComplete", true);
#endif
#if ENABLE(SVG)
@@ -1660,8 +1710,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()
@@ -1681,28 +1731,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);
@@ -1731,11 +1783,8 @@ void Document::clear()
m_tokenizer = 0;
removeChildren();
-
- size_t size = m_windowEventListeners.size();
- for (size_t i = 0; i < size; ++i)
- m_windowEventListeners[i]->setRemoved(true);
- m_windowEventListeners.clear();
+ if (DOMWindow* domWindow = this->domWindow())
+ domWindow->removeAllEventListeners();
}
const KURL& Document::virtualURL() const
@@ -1767,7 +1816,15 @@ void Document::setBaseElementURL(const KURL& baseElementURL)
void Document::updateBaseURL()
{
- m_baseURL = m_baseElementURL.isEmpty() ? KURL(documentURI()) : m_baseElementURL;
+ // DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 HTML], the base URI is computed using
+ // first the value of the href attribute of the HTML BASE element if any, and the value of the documentURI attribute
+ // from the Document interface otherwise.
+ if (m_baseElementURL.isEmpty()) {
+ // The documentURI attribute is an arbitrary string. DOM 3 Core does not specify how it should be resolved,
+ // so we use a null base URL.
+ m_baseURL = KURL(KURL(), documentURI());
+ } else
+ m_baseURL = m_baseElementURL;
if (!m_baseURL.isValid())
m_baseURL = KURL();
@@ -1777,6 +1834,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);
@@ -1953,11 +2015,11 @@ Node *Document::nodeWithAbsIndex(int absIndex)
return n;
}
-void Document::processHttpEquiv(const String &equiv, const String &content)
+void Document::processHttpEquiv(const String& equiv, const String& content)
{
ASSERT(!equiv.isNull() && !content.isNull());
- Frame *frame = this->frame();
+ Frame* frame = this->frame();
if (equalIgnoringCase(equiv, "default-style")) {
// The preferred style set has been overridden as per section
@@ -1987,6 +2049,13 @@ void Document::processHttpEquiv(const String &equiv, const String &content)
setContentLanguage(content);
else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
parseDNSPrefetchControlHeader(content);
+ else if (equalIgnoringCase(equiv, "x-frame-options")) {
+ FrameLoader* frameLoader = frame->loader();
+ if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
+ frameLoader->stopAllLoaders();
+ frameLoader->scheduleHTTPRedirection(0, blankURL());
+ }
+ }
}
MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const IntPoint& documentPoint, const PlatformMouseEvent& event)
@@ -1997,10 +2066,10 @@ MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
return MouseEventWithHitTestResults(event, HitTestResult(IntPoint()));
HitTestResult result(documentPoint);
- renderer()->layer()->hitTest(request, result);
+ renderView()->layer()->hitTest(request, result);
- if (!request.readonly)
- updateRendering();
+ if (!request.readOnly())
+ updateStyleIfNeeded();
return MouseEventWithHitTestResults(event, result);
}
@@ -2455,21 +2524,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->dispatchEvent(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, 0, 0);
if (m_focusedNode) {
// handler shifted focus
focusChangeBlocked = true;
@@ -2492,14 +2563,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, 0, 0);
if (m_focusedNode != newFocusedNode) {
// handler shifted focus
focusChangeBlocked = true;
@@ -2529,28 +2600,45 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
}
}
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) && !PLATFORM(CHROMIUM)
if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled())
axObjectCache()->handleFocusedUIElementChanged();
+#elif PLATFORM(GTK)
+ if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled()) {
+ RenderObject* oldFocusedRenderer = 0;
+ RenderObject* newFocusedRenderer = 0;
+
+ if (oldFocusedNode)
+ oldFocusedRenderer = oldFocusedNode.get()->renderer();
+ if (newFocusedNode)
+ newFocusedRenderer = newFocusedNode.get()->renderer();
+
+ axObjectCache()->handleFocusedUIElementChangedWithRenderers(oldFocusedRenderer, newFocusedRenderer);
+ }
#endif
SetFocusedNodeDone:
- updateRendering();
+ updateStyleIfNeeded();
return !focusChangeBlocked;
- }
+}
+
+void Document::getFocusableNodes(Vector<RefPtr<Node> >& nodes)
+{
+ updateLayout();
+
+ for (Node* node = firstChild(); node; node = node->traverseNextNode()) {
+ if (node->isFocusable())
+ nodes.append(node);
+ }
+}
-void Document::setCSSTarget(Node* n)
+void Document::setCSSTarget(Element* n)
{
if (m_cssTarget)
- m_cssTarget->setChanged();
+ m_cssTarget->setNeedsStyleRecalc();
m_cssTarget = n;
if (n)
- n->setChanged();
-}
-
-Node* Document::getCSSTarget() const
-{
- return m_cssTarget;
+ n->setNeedsStyleRecalc();
}
void Document::attachNodeIterator(NodeIterator *ni)
@@ -2565,7 +2653,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);
@@ -2578,7 +2666,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);
@@ -2592,7 +2680,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);
@@ -2604,7 +2692,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);
@@ -2617,7 +2705,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)
@@ -2629,7 +2717,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);
@@ -2643,9 +2731,59 @@ DOMWindow* Document::domWindow() const
{
if (!frame())
return 0;
+
+ // The m_frame pointer is not (not always?) zeroed out when the document is put into b/f cache, so the frame can hold an unrelated document/window pair.
+ // FIXME: We should always zero out the frame pointer on navigation to avoid accidentally accessing the new frame content.
+ if (m_frame->document() != this)
+ return 0;
+
return frame()->domWindow();
}
+void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+{
+ DOMWindow* domWindow = this->domWindow();
+ if (!domWindow)
+ return;
+ domWindow->setAttributeEventListener(eventType, listener);
+}
+
+EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType)
+{
+ DOMWindow* domWindow = this->domWindow();
+ if (!domWindow)
+ return 0;
+ return domWindow->getAttributeEventListener(eventType);
+}
+
+void Document::dispatchWindowEvent(PassRefPtr<Event> event)
+{
+ ASSERT(!eventDispatchForbidden());
+ DOMWindow* domWindow = this->domWindow();
+ if (!domWindow)
+ return;
+ ExceptionCode ec;
+ domWindow->dispatchEvent(event, ec);
+}
+
+void Document::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ DOMWindow* domWindow = this->domWindow();
+ if (!domWindow)
+ return;
+ domWindow->dispatchEvent(eventType, canBubbleArg, cancelableArg);
+}
+
+void Document::dispatchLoadEvent()
+{
+ ASSERT(!eventDispatchForbidden());
+ DOMWindow* domWindow = this->domWindow();
+ if (!domWindow)
+ return;
+ domWindow->dispatchLoadEvent();
+}
+
PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec)
{
if (eventType == "Event" || eventType == "Events" || eventType == "HTMLEvents")
@@ -2719,191 +2857,6 @@ CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&)
return 0;
}
-void Document::handleWindowEvent(Event* event, bool useCapture)
-{
- if (m_windowEventListeners.isEmpty())
- return;
-
- // If any HTML event listeners are registered on the window, dispatch them here.
- RegisteredEventListenerVector listenersCopy = m_windowEventListeners;
- size_t size = listenersCopy.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *listenersCopy[i];
- if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
- r.listener()->handleEvent(event, true);
- }
-}
-
-void Document::setWindowInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
- // If we already have it we don't want removeWindowEventListener to delete it
- removeWindowInlineEventListenerForType(eventType);
- if (listener)
- addWindowEventListener(eventType, listener, false);
-}
-
-EventListener* Document::windowInlineEventListenerForType(const AtomicString& eventType)
-{
- size_t size = m_windowEventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *m_windowEventListeners[i];
- if (r.eventType() == eventType && r.listener()->isInline())
- return r.listener();
- }
- return 0;
-}
-
-void Document::removeWindowInlineEventListenerForType(const AtomicString& eventType)
-{
- size_t size = m_windowEventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *m_windowEventListeners[i];
- if (r.eventType() == eventType && r.listener()->isInline()) {
- if (eventType == eventNames().unloadEvent)
- removePendingFrameUnloadEventCount();
- else if (eventType == eventNames().beforeunloadEvent)
- removePendingFrameBeforeUnloadEventCount();
- r.setRemoved(true);
- m_windowEventListeners.remove(i);
- return;
- }
- }
-}
-
-void Document::addWindowEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
- if (eventType == eventNames().unloadEvent)
- addPendingFrameUnloadEventCount();
- else if (eventType == eventNames().beforeunloadEvent)
- addPendingFrameBeforeUnloadEventCount();
- // Remove existing identical listener set with identical arguments.
- // The DOM 2 spec says that "duplicate instances are discarded" in this case.
- removeWindowEventListener(eventType, listener.get(), useCapture);
- addListenerTypeIfNeeded(eventType);
- m_windowEventListeners.append(RegisteredEventListener::create(eventType, listener, useCapture));
-}
-
-void Document::removeWindowEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
- size_t size = m_windowEventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *m_windowEventListeners[i];
- if (r.eventType() == eventType && r.listener() == listener && r.useCapture() == useCapture) {
- if (eventType == eventNames().unloadEvent)
- removePendingFrameUnloadEventCount();
- else if (eventType == eventNames().beforeunloadEvent)
- removePendingFrameBeforeUnloadEventCount();
- r.setRemoved(true);
- m_windowEventListeners.remove(i);
- return;
- }
- }
-}
-
-bool Document::hasWindowEventListener(const AtomicString& eventType)
-{
- size_t size = m_windowEventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- if (m_windowEventListeners[i]->eventType() == eventType)
- return true;
- }
- return false;
-}
-
-void Document::addPendingFrameUnloadEventCount()
-{
- if (m_frame)
- m_frame->eventHandler()->addPendingFrameUnloadEventCount();
-}
-
-void Document::removePendingFrameUnloadEventCount()
-{
- if (m_frame)
- m_frame->eventHandler()->removePendingFrameUnloadEventCount();
-}
-
-void Document::addPendingFrameBeforeUnloadEventCount()
-{
- if (m_frame)
- m_frame->eventHandler()->addPendingFrameBeforeUnloadEventCount();
-}
-
-void Document::removePendingFrameBeforeUnloadEventCount()
-{
- if (m_frame)
- m_frame->eventHandler()->removePendingFrameBeforeUnloadEventCount();
-}
-
-PassRefPtr<EventListener> Document::createEventListener(const String& functionName, const String& code, Node* node)
-{
- Frame* frm = frame();
- if (!frm || !frm->script()->isEnabled())
- return 0;
-
-#if ENABLE(SVG)
- if (node ? node->isSVGElement() : isSVGDocument())
- return frm->script()->createSVGEventHandler(functionName, code, node);
-#endif
-
- // We may want to treat compound document event handlers in a different way, in future.
- return frm->script()->createInlineEventListener(functionName, code, node);
-}
-
-void Document::setWindowInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute* attr)
-{
- 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;
-
- 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();
-}
-
-void Document::imageLoadEventTimerFired(Timer<Document>*)
-{
- dispatchImageLoadEventsNow();
-}
-
Element* Document::ownerElement() const
{
if (!frame())
@@ -2932,7 +2885,7 @@ void Document::setCookie(const String& value)
if (cookieURL.isEmpty())
return;
- setCookies(this, cookieURL, policyBaseURL(), value);
+ setCookies(this, cookieURL, value);
}
String Document::referrer() const
@@ -3143,13 +3096,6 @@ void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder)
m_decoder = decoder;
}
-UChar Document::backslashAsCurrencySymbol() const
-{
- if (!m_decoder)
- return '\\';
- return m_decoder->encoding().backslashAsCurrencySymbol();
-}
-
KURL Document::completeURL(const String& url) const
{
// Always return a null URL when passed a null string.
@@ -3157,14 +3103,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());
-}
-
-bool Document::inPageCache()
-{
- return m_inPageCache;
+ return KURL(baseURL, url);
+ return KURL(baseURL, url, m_decoder->encoding());
}
void Document::setInPageCache(bool flag)
@@ -3178,16 +3120,24 @@ void Document::setInPageCache(bool flag)
m_savedRenderer = renderer();
if (FrameView* v = view())
v->resetScrollbars();
+ unscheduleStyleRecalc();
} else {
ASSERT(renderer() == 0 || renderer() == m_savedRenderer);
ASSERT(m_renderArena);
setRenderer(m_savedRenderer);
m_savedRenderer = 0;
+ if (childNeedsStyleRecalc())
+ scheduleStyleRecalc();
}
}
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();
@@ -3198,6 +3148,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)
@@ -3289,7 +3244,7 @@ void Document::addMarker(Range *range, DocumentMarker::MarkerType type, String d
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
RefPtr<Range> textPiece = markedText.range();
int exception = 0;
- DocumentMarker marker = {type, textPiece->startOffset(exception), textPiece->endOffset(exception), description};
+ DocumentMarker marker = {type, textPiece->startOffset(exception), textPiece->endOffset(exception), description, false};
addMarker(textPiece->startContainer(exception), marker);
}
}
@@ -3714,6 +3669,53 @@ void Document::shiftMarkers(Node *node, unsigned startOffset, int delta, Documen
node->renderer()->repaint();
}
+void Document::setMarkersActive(Range* range, bool active)
+{
+ if (m_markers.isEmpty())
+ return;
+
+ ExceptionCode ec = 0;
+ Node* startContainer = range->startContainer(ec);
+ Node* endContainer = range->endContainer(ec);
+
+ Node* pastLastNode = range->pastLastNode();
+ for (Node* node = range->firstNode(); node != pastLastNode; node = node->traverseNextNode()) {
+ int startOffset = node == startContainer ? range->startOffset(ec) : 0;
+ int endOffset = node == endContainer ? range->endOffset(ec) : INT_MAX;
+ setMarkersActive(node, startOffset, endOffset, active);
+ }
+}
+
+void Document::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active)
+{
+ MarkerMapVectorPair* vectorPair = m_markers.get(node);
+ if (!vectorPair)
+ return;
+
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ ASSERT(markers.size() == vectorPair->second.size());
+
+ bool docDirty = false;
+ for (size_t i = 0; i != markers.size(); ++i) {
+ DocumentMarker &marker = markers[i];
+
+ // Markers are returned in order, so stop if we are now past the specified range.
+ if (marker.startOffset >= endOffset)
+ break;
+
+ // Skip marker that is wrong type or before target.
+ if (marker.endOffset < startOffset || marker.type != DocumentMarker::TextMatch)
+ continue;
+
+ marker.activeMatch = active;
+ docDirty = true;
+ }
+
+ // repaint the affected node
+ if (docDirty && node->renderer())
+ node->renderer()->repaint();
+}
+
#if ENABLE(XSLT)
void Document::applyXSLTransform(ProcessingInstruction* pi)
@@ -3780,6 +3782,11 @@ Document *Document::topDocument() const
return doc;
}
+PassRefPtr<Attr> Document::createAttribute(const String& name, ExceptionCode& ec)
+{
+ return createAttributeNS(String(), name, ec, true);
+}
+
PassRefPtr<Attr> Document::createAttributeNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode& ec, bool shouldIgnoreNamespaceChecks)
{
String prefix, localName;
@@ -3819,75 +3826,75 @@ SVGDocumentExtensions* Document::accessSVGExtensions()
PassRefPtr<HTMLCollection> Document::images()
{
- return HTMLCollection::create(this, HTMLCollection::DocImages);
+ return HTMLCollection::create(this, DocImages);
}
PassRefPtr<HTMLCollection> Document::applets()
{
- return HTMLCollection::create(this, HTMLCollection::DocApplets);
+ return HTMLCollection::create(this, DocApplets);
}
PassRefPtr<HTMLCollection> Document::embeds()
{
- return HTMLCollection::create(this, HTMLCollection::DocEmbeds);
+ return HTMLCollection::create(this, DocEmbeds);
}
PassRefPtr<HTMLCollection> Document::plugins()
{
// This is an alias for embeds() required for the JS DOM bindings.
- return HTMLCollection::create(this, HTMLCollection::DocEmbeds);
+ return HTMLCollection::create(this, DocEmbeds);
}
PassRefPtr<HTMLCollection> Document::objects()
{
- return HTMLCollection::create(this, HTMLCollection::DocObjects);
+ return HTMLCollection::create(this, DocObjects);
}
PassRefPtr<HTMLCollection> Document::scripts()
{
- return HTMLCollection::create(this, HTMLCollection::DocScripts);
+ return HTMLCollection::create(this, DocScripts);
}
PassRefPtr<HTMLCollection> Document::links()
{
- return HTMLCollection::create(this, HTMLCollection::DocLinks);
+ return HTMLCollection::create(this, DocLinks);
}
PassRefPtr<HTMLCollection> Document::forms()
{
- return HTMLCollection::create(this, HTMLCollection::DocForms);
+ return HTMLCollection::create(this, DocForms);
}
PassRefPtr<HTMLCollection> Document::anchors()
{
- return HTMLCollection::create(this, HTMLCollection::DocAnchors);
+ return HTMLCollection::create(this, DocAnchors);
}
PassRefPtr<HTMLCollection> Document::all()
{
- return HTMLCollection::create(this, HTMLCollection::DocAll);
+ return HTMLCollection::create(this, DocAll);
}
PassRefPtr<HTMLCollection> Document::windowNamedItems(const String &name)
{
- return HTMLNameCollection::create(this, HTMLCollection::WindowNamedItems, name);
+ return HTMLNameCollection::create(this, WindowNamedItems, name);
}
PassRefPtr<HTMLCollection> Document::documentNamedItems(const String &name)
{
- return HTMLNameCollection::create(this, HTMLCollection::DocumentNamedItems, name);
+ return HTMLNameCollection::create(this, DocumentNamedItems, name);
}
-HTMLCollection::CollectionInfo* Document::nameCollectionInfo(HTMLCollection::Type type, const AtomicString& name)
+CollectionCache* Document::nameCollectionInfo(CollectionType type, const AtomicString& name)
{
- ASSERT(type >= HTMLCollection::FirstNamedDocumentCachedType);
- unsigned index = type - HTMLCollection::FirstNamedDocumentCachedType;
- ASSERT(index < HTMLCollection::NumNamedDocumentCachedTypes);
+ ASSERT(type >= FirstNamedDocumentCachedType);
+ unsigned index = type - FirstNamedDocumentCachedType;
+ ASSERT(index < NumNamedDocumentCachedTypes);
NamedCollectionMap& map = m_nameCollectionInfo[index];
NamedCollectionMap::iterator iter = map.find(name.impl());
if (iter == map.end())
- iter = map.add(name.impl(), new HTMLCollection::CollectionInfo).first;
+ iter = map.add(name.impl(), new CollectionCache).first;
return iter->second;
}
@@ -3905,15 +3912,15 @@ void Document::finishedParsing()
Vector<String> Document::formElementsState() const
{
Vector<String> stateVector;
- stateVector.reserveCapacity(m_formElementsWithState.size() * 3);
- typedef ListHashSet<HTMLFormControlElementWithState*>::const_iterator Iterator;
+ stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 3);
+ typedef ListHashSet<Element*>::const_iterator Iterator;
Iterator end = m_formElementsWithState.end();
for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
- HTMLFormControlElementWithState* e = *it;
+ Element* e = *it;
String value;
- if (e->saveState(value)) {
- stateVector.append(e->name().string());
- stateVector.append(e->type().string());
+ if (e->saveFormControlState(value)) {
+ stateVector.append(e->formControlName().string());
+ stateVector.append(e->formControlType().string());
stateVector.append(value);
}
}
@@ -4122,6 +4129,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;
@@ -4132,7 +4153,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
@@ -4174,6 +4195,34 @@ void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
element->updateFocusAppearance(false);
}
+void Document::executeScriptSoonTimerFired(Timer<Document>* timer)
+{
+ ASSERT_UNUSED(timer, timer == &m_executeScriptSoonTimer);
+
+ Vector<pair<ScriptElementData*, CachedResourceHandle<CachedScript> > > scripts;
+ scripts.swap(m_scriptsToExecuteSoon);
+ size_t size = scripts.size();
+ for (size_t i = 0; i < size; ++i) {
+ scripts[i].first->execute(scripts[i].second.get());
+ scripts[i].first->element()->deref(); // Balances ref() in executeScriptSoon().
+ }
+}
+
+void Document::executeScriptSoon(ScriptElementData* data, CachedResourceHandle<CachedScript> cachedScript)
+{
+ ASSERT_ARG(data, data);
+
+ Element* element = data->element();
+ ASSERT(element);
+ ASSERT(element->document() == this);
+ ASSERT(element->inDocument());
+
+ m_scriptsToExecuteSoon.append(make_pair(data, cachedScript));
+ element->ref(); // Balanced by deref()s in executeScriptSoonTimerFired() and ~Document().
+ if (!m_executeScriptSoonTimer.isActive())
+ m_executeScriptSoonTimer.startOneShot(0);
+}
+
// FF method for accessing the selection added for compatability.
DOMSelection* Document::getSelection() const
{
@@ -4205,7 +4254,7 @@ DatabaseThread* Document::databaseThread()
if (!m_databaseThread && !m_hasOpenDatabases) {
// Create the database thread on first request - but not if at least one database was already opened,
// because in that case we already had a database thread and terminated it and should not create another.
- m_databaseThread = DatabaseThread::create(this);
+ m_databaseThread = DatabaseThread::create();
if (!m_databaseThread->start())
m_databaseThread = 0;
}
@@ -4237,6 +4286,14 @@ void Document::resetWMLPageState()
if (WMLPageState* pageState = wmlPageStateForDocument(this))
pageState->reset();
}
+
+void Document::initializeWMLPageState()
+{
+ if (!isWMLDocument())
+ return;
+
+ static_cast<WMLDocument*>(this)->initialize();
+}
#endif
void Document::attachRange(Range* range)
@@ -4247,7 +4304,8 @@ void Document::attachRange(Range* range)
void Document::detachRange(Range* range)
{
- ASSERT(m_ranges.contains(range));
+ // We don't ASSERT m_ranges.contains(range) to allow us to call this
+ // unconditionally to fix: https://bugs.webkit.org/show_bug.cgi?id=26044
m_ranges.remove(range);
}
@@ -4293,26 +4351,42 @@ void Document::parseDNSPrefetchControlHeader(const String& dnsPrefetchControl)
m_haveExplicitlyDisabledDNSPrefetch = true;
}
-void Document::addTimeout(int timeoutId, DOMTimer* timer)
+void Document::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
{
- ASSERT(!m_timeouts.contains(timeoutId));
- m_timeouts.set(timeoutId, timer);
+ if (DOMWindow* window = domWindow())
+ window->console()->addMessage(JSMessageSource, ErrorMessageLevel, errorMessage, lineNumber, sourceURL);
}
-void Document::removeTimeout(int timeoutId)
+void Document::addMessage(MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
{
- m_timeouts.remove(timeoutId);
+ switch (destination) {
+ case InspectorControllerDestination:
+ if (page())
+ page()->inspectorController()->addMessageToConsole(source, level, message, lineNumber, sourceURL);
+ return;
+ case ConsoleDestination:
+ if (DOMWindow* window = domWindow())
+ window->console()->addMessage(source, level, message, lineNumber, sourceURL);
+ return;
+ }
+ ASSERT_NOT_REACHED();
}
-DOMTimer* Document::findTimeout(int timeoutId)
+void Document::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString)
{
- return m_timeouts.get(timeoutId);
+ if (page())
+ page()->inspectorController()->resourceRetrievedByXMLHttpRequest(identifier, sourceString);
+ Frame* frame = this->frame();
+ if (frame) {
+ FrameLoader* frameLoader = frame->loader();
+ frameLoader->didLoadResourceByXMLHttpRequest(identifier, sourceString);
+ }
}
-void Document::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
+void Document::scriptImported(unsigned long identifier, const String& sourceString)
{
- if (DOMWindow* window = domWindow())
- window->console()->addMessage(JSMessageSource, ErrorMessageLevel, errorMessage, lineNumber, sourceURL);
+ if (page())
+ page()->inspectorController()->scriptImported(identifier, sourceString);
}
class ScriptExecutionContextTaskTimer : public TimerBase {
@@ -4385,4 +4459,36 @@ 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);
+}
+
+#if ENABLE(XHTMLMP)
+bool Document::isXHTMLMPDocument() const
+{
+ if (!frame() || !frame()->loader())
+ return false;
+ // As per section 7.2 of OMA-WAP-XHTMLMP-V1_1-20061020-A.pdf, a conforming user agent
+ // MUST accept XHTMLMP document identified as "application/vnd.wap.xhtml+xml"
+ // and SHOULD accept it identified as "application/xhtml+xml"
+ return frame()->loader()->responseMIMEType() == "application/vnd.wap.xhtml+xml" || frame()->loader()->responseMIMEType() == "application/xhtml+xml";
+}
+#endif
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/Document.h b/src/3rdparty/webkit/WebCore/dom/Document.h
index 2fdc860..92865f4 100644
--- a/src/3rdparty/webkit/WebCore/dom/Document.h
+++ b/src/3rdparty/webkit/WebCore/dom/Document.h
@@ -3,8 +3,8 @@
* (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) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,16 +26,16 @@
#ifndef Document_h
#define Document_h
-#include "Attr.h"
+#include "CachedResourceHandle.h"
+#include "CheckedRadioButtons.h"
+#include "ContainerNode.h"
+#include "CollectionCache.h"
+#include "CollectionType.h"
#include "Color.h"
#include "DocumentMarker.h"
-#include "HTMLCollection.h"
-#include "HTMLFormElement.h"
#include "ScriptExecutionContext.h"
-#include "StringHash.h"
#include "Timer.h"
#include <wtf/HashCountedSet.h>
-#include <wtf/ListHashSet.h>
// FIXME: We should move Mac off of the old Frame-based user stylesheet loading
// code and onto the new code in Page. We can't do that until the code in Page
@@ -48,11 +48,11 @@
namespace WebCore {
- class AXObjectCache;
class Attr;
- class Attribute;
+ class AXObjectCache;
class CDATASection;
class CachedCSSStyleSheet;
+ class CachedScript;
class CanvasRenderingContext2D;
class CharacterData;
class CSSStyleDeclaration;
@@ -62,7 +62,6 @@ namespace WebCore {
class Database;
class DOMImplementation;
class DOMSelection;
- class DOMTimer;
class DOMWindow;
class DatabaseThread;
class DocLoader;
@@ -75,15 +74,15 @@ namespace WebCore {
class EventListener;
class Frame;
class FrameView;
+ class HitTestRequest;
class HTMLCanvasElement;
+ class HTMLCollection;
class HTMLDocument;
class HTMLElement;
- class HTMLFormControlElementWithState;
class HTMLFormElement;
class HTMLHeadElement;
class HTMLInputElement;
class HTMLMapElement;
- class ImageLoader;
class IntPoint;
class JSNode;
class MouseEventWithHitTestResults;
@@ -95,7 +94,10 @@ namespace WebCore {
class Range;
class RegisteredEventListener;
class RenderArena;
+ class RenderView;
+ class ScriptElementData;
class SecurityOrigin;
+ class SegmentedString;
class Settings;
class StyleSheet;
class StyleSheetList;
@@ -123,7 +125,6 @@ namespace WebCore {
#if ENABLE(DASHBOARD_SUPPORT)
struct DashboardRegionValue;
#endif
- struct HitTestRequest;
typedef int ExceptionCode;
@@ -214,30 +215,39 @@ public:
DOMImplementation* implementation() const;
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
- Element* documentElement() const;
+
+ Element* documentElement() const
+ {
+ if (!m_documentElement)
+ cacheDocumentElement();
+ return m_documentElement.get();
+ }
+
virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
PassRefPtr<DocumentFragment> createDocumentFragment ();
PassRefPtr<Text> createTextNode(const String& data);
PassRefPtr<Comment> createComment(const String& data);
PassRefPtr<CDATASection> createCDATASection(const String& data, ExceptionCode&);
PassRefPtr<ProcessingInstruction> createProcessingInstruction(const String& target, const String& data, ExceptionCode&);
- PassRefPtr<Attr> createAttribute(const String& name, ExceptionCode& ec) { return createAttributeNS(String(), name, ec, true); }
+ PassRefPtr<Attr> createAttribute(const String& name, ExceptionCode&);
PassRefPtr<Attr> createAttributeNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&, bool shouldIgnoreNamespaceChecks = false);
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&);
@@ -279,15 +289,15 @@ public:
// quirks mode for historical compatibility reasons.
Element* findAnchor(const String& name);
- HTMLCollection::CollectionInfo* collectionInfo(HTMLCollection::Type type)
+ CollectionCache* collectionInfo(CollectionType type)
{
- ASSERT(type >= HTMLCollection::FirstUnnamedDocumentCachedType);
- unsigned index = type - HTMLCollection::FirstUnnamedDocumentCachedType;
- ASSERT(index < HTMLCollection::NumUnnamedDocumentCachedTypes);
+ ASSERT(type >= FirstUnnamedDocumentCachedType);
+ unsigned index = type - FirstUnnamedDocumentCachedType;
+ ASSERT(index < NumUnnamedDocumentCachedTypes);
return &m_collectionInfo[index];
}
- HTMLCollection::CollectionInfo* nameCollectionInfo(HTMLCollection::Type, const AtomicString& name);
+ CollectionCache* nameCollectionInfo(CollectionType, const AtomicString& name);
// DOM methods overridden from parent classes
@@ -299,12 +309,20 @@ public:
virtual bool isImageDocument() const { return false; }
#if ENABLE(SVG)
virtual bool isSVGDocument() const { return false; }
+#else
+ static bool isSVGDocument() { return false; }
#endif
virtual bool isPluginDocument() const { return false; }
virtual bool isMediaDocument() const { return false; }
#if ENABLE(WML)
virtual bool isWMLDocument() const { return false; }
#endif
+#if ENABLE(XHTMLMP)
+ bool isXHTMLMPDocument() const;
+ bool shouldProcessNoscriptElement() const { return m_shouldProcessNoScriptElement; }
+ void setShouldProcessNoscriptElement(bool shouldDo) { m_shouldProcessNoScriptElement = shouldDo; }
+#endif
+ virtual bool isFrameSet() const { return false; }
CSSStyleSelector* styleSelector() const { return m_styleSelector; }
@@ -321,11 +339,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;
}
/**
@@ -361,10 +375,12 @@ public:
void setUsesFirstLineRules(bool b) { m_usesFirstLineRules = b; }
bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
+ bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules; }
+ void setUsesBeforeAfterRules(bool b) { m_usesBeforeAfterRules = b; }
// Machinery for saving and restoring state when you leave and then go back to a page.
- void registerFormElementWithState(HTMLFormControlElementWithState* e) { m_formElementsWithState.add(e); }
- void unregisterFormElementWithState(HTMLFormControlElementWithState* e) { m_formElementsWithState.remove(e); }
+ void registerFormElementWithState(Element* e) { m_formElementsWithState.add(e); }
+ void unregisterFormElementWithState(Element* e) { m_formElementsWithState.remove(e); }
Vector<String> formElementsState() const;
void setStateForNewFormElements(const Vector<String>&);
bool hasStateForNewFormElements() const;
@@ -388,19 +404,19 @@ public:
PassRefPtr<EditingText> createEditingTextNode(const String&);
virtual void recalcStyle( StyleChange = NoChange );
- virtual void updateRendering();
+ virtual void updateStyleIfNeeded();
void updateLayout();
void updateLayoutIgnorePendingStylesheets();
- static void updateDocumentsRendering();
+ static void updateStyleForAllDocuments(); // FIXME: Try to reduce the # of calls to this function.
DocLoader* docLoader() { return m_docLoader; }
virtual void attach();
virtual void detach();
- void clearFramePointer();
-
RenderArena* renderArena() { return m_renderArena; }
+ RenderView* renderView() const;
+
void clearAXObjectCache();
AXObjectCache* axObjectCache() const;
@@ -413,6 +429,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();
@@ -433,6 +450,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*);
@@ -502,6 +521,8 @@ public:
bool setFocusedNode(PassRefPtr<Node>);
Node* focusedNode() const { return m_focusedNode.get(); }
+ void getFocusableNodes(Vector<RefPtr<Node> >&);
+
// The m_ignoreAutofocus flag specifies whether or not the document has been changed by the user enough
// for WebCore to ignore the autofocus attribute on any form controls
bool ignoreAutofocus() const { return m_ignoreAutofocus; };
@@ -519,10 +540,12 @@ 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);
+ void scheduleStyleRecalc();
+ void unscheduleStyleRecalc();
+ void styleRecalcTimerFired(Timer<Document>*);
void attachNodeIterator(NodeIterator*);
void detachNodeIterator(NodeIterator*);
@@ -541,6 +564,13 @@ public:
DOMWindow* defaultView() const { return domWindow(); }
DOMWindow* domWindow() const;
+ // Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists.
+ void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+ EventListener* getWindowAttributeEventListener(const AtomicString& eventType);
+ void dispatchWindowEvent(PassRefPtr<Event>);
+ void dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg);
+ void dispatchLoadEvent();
+
PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);
// keep track of what types of event listeners are registered, so we don't
@@ -566,24 +596,6 @@ public:
CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);
- void handleWindowEvent(Event*, bool useCapture);
- void setWindowInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
- EventListener* windowInlineEventListenerForType(const AtomicString& eventType);
- void removeWindowInlineEventListenerForType(const AtomicString& eventType);
-
- void setWindowInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute*);
-
- void addWindowEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- void removeWindowEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
- bool hasWindowEventListener(const AtomicString& eventType);
-
- void addPendingFrameUnloadEventCount();
- void removePendingFrameUnloadEventCount();
- void addPendingFrameBeforeUnloadEventCount();
- void removePendingFrameBeforeUnloadEventCount();
-
- PassRefPtr<EventListener> createEventListener(const String& functionName, const String& code, Node*);
-
/**
* Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
* The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
@@ -624,10 +636,6 @@ public:
*/
void processHttpEquiv(const String& equiv, const String& content);
- 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;
@@ -648,8 +656,8 @@ public:
const KURL& cookieURL() const { return m_cookieURL; }
- const KURL& policyBaseURL() const { return m_policyBaseURL; }
- void setPolicyBaseURL(const KURL& url) { m_policyBaseURL = url; }
+ const KURL& firstPartyForCookies() const { return m_firstPartyForCookies; }
+ void setFirstPartyForCookies(const KURL& url) { m_firstPartyForCookies = url; }
// The following implements the rule from HTML 4 for what valid names are.
// To get this right for all the XML cases, we probably have to improve this or move it
@@ -671,7 +679,7 @@ public:
void removeImageMap(HTMLMapElement*);
HTMLMapElement* getImageMap(const String& url) const;
- HTMLElement* body();
+ HTMLElement* body() const;
void setBody(PassRefPtr<HTMLElement>, ExceptionCode&);
HTMLHeadElement* head();
@@ -694,6 +702,8 @@ public:
void setRenderedRectForMarker(Node*, DocumentMarker, const IntRect&);
void invalidateRenderedRectsForMarkersInRect(const IntRect&);
void shiftMarkers(Node*, unsigned startOffset, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ void setMarkersActive(Range*, bool);
+ void setMarkersActive(Node*, unsigned startOffset, unsigned endOffset, bool);
DocumentMarker* markerContainingPoint(const IntPoint&, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
Vector<DocumentMarker> markersForNode(Node*);
@@ -710,6 +720,8 @@ public:
int docID() const { return m_docID; }
+ void executeScriptSoon(ScriptElementData*, CachedResourceHandle<CachedScript>);
+
#if ENABLE(XSLT)
void applyXSLTransform(ProcessingInstruction* pi);
void setTransformSource(void* doc);
@@ -755,13 +767,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; }
@@ -781,12 +787,11 @@ public:
void parseDNSPrefetchControlHeader(const String&);
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);
@@ -797,6 +802,10 @@ 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;
+
+ void executeScriptSoonTimerFired(Timer<Document>*);
+
CSSStyleSelector* m_styleSelector;
bool m_didCalculateStyleSelector;
@@ -810,7 +819,7 @@ private:
KURL m_baseURL; // Node.baseURI: The URL to use when resolving relative URLs.
KURL m_baseElementURL; // The URL set by the <base> element.
KURL m_cookieURL; // The URL to use for cookie access.
- KURL m_policyBaseURL; // The policy URL for third-party cookie blocking.
+ KURL m_firstPartyForCookies; // The policy URL for third-party cookie blocking.
// Document.documentURI:
// Although URL-like, Document.documentURI can actually be set to any
@@ -872,10 +881,8 @@ private:
RefPtr<StyleSheetList> m_styleSheets; // All of the stylesheets that are currently in effect for our media type and stylesheet set.
ListHashSet<Node*> m_styleSheetCandidateNodes; // All of the nodes that could potentially provide stylesheets to the document (<link>, <style>, <?xml-stylesheet>)
- RegisteredEventListenerVector m_windowEventListeners;
-
typedef HashMap<FormElementKey, Vector<String>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap;
- ListHashSet<HTMLFormControlElementWithState*> m_formElementsWithState;
+ ListHashSet<Element*> m_formElementsWithState;
FormElementStateMap m_stateForNewFormElements;
Color m_linkColor;
@@ -888,13 +895,14 @@ private:
bool m_loadingSheet;
bool visuallyOrdered;
bool m_bParsing;
- bool m_docChanged;
+ Timer<Document> m_styleRecalcTimer;
bool m_inStyleRecalc;
bool m_closeAfterStyleRecalc;
bool m_usesDescendantRules;
bool m_usesSiblingRules;
bool m_usesFirstLineRules;
bool m_usesFirstLetterRules;
+ bool m_usesBeforeAfterRules;
bool m_gotoAnchorNeededAfterStylesheetsLoad;
bool m_isDNSPrefetchEnabled;
bool m_haveExplicitlyDisabledDNSPrefetch;
@@ -912,17 +920,16 @@ 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;
bool m_overMinimumLayoutThreshold;
+
+ Vector<std::pair<ScriptElementData*, CachedResourceHandle<CachedScript> > > m_scriptsToExecuteSoon;
+ Timer<Document> m_executeScriptSoonTimer;
#if ENABLE(XSLT)
void* m_transformSource;
@@ -946,8 +953,12 @@ private:
String m_contentLanguage;
+#if ENABLE(XHTMLMP)
+ bool m_shouldProcessNoScriptElement;
+#endif
+
public:
- bool inPageCache();
+ bool inPageCache() const { return m_inPageCache; }
void setInPageCache(bool flag);
// Elements can register themselves for the "documentWillBecomeInactive()" and
@@ -967,7 +978,9 @@ public:
void setDecoder(PassRefPtr<TextResourceDecoder>);
TextResourceDecoder* decoder() const { return m_decoder.get(); }
- UChar backslashAsCurrencySymbol() const;
+ 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; }
@@ -982,12 +995,12 @@ public:
void setDashboardRegions(const Vector<DashboardRegionValue>&);
#endif
- void removeAllEventListenersFromAllNodes();
+ void removeAllEventListeners();
void registerDisconnectedNodeWithEventListeners(Node*);
void unregisterDisconnectedNodeWithEventListeners(Node*);
- HTMLFormElement::CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+ CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
#if ENABLE(SVG)
const SVGDocumentExtensions* svgExtensions();
@@ -1017,6 +1030,7 @@ public:
#if ENABLE(WML)
void resetWMLPageState();
+ void initializeWMLPageState();
#endif
protected:
@@ -1025,10 +1039,11 @@ protected:
private:
void updateTitle();
void removeAllDisconnectedNodeEventListeners();
- void imageLoadEventTimerFired(Timer<Document>*);
void updateFocusAppearanceTimerFired(Timer<Document>*);
void updateBaseURL();
+ void cacheDocumentElement() const;
+
RenderObject* m_savedRenderer;
int m_secureForms;
@@ -1046,11 +1061,11 @@ private:
int m_selfOnlyRefCount;
- HTMLFormElement::CheckedRadioButtons m_checkedRadioButtons;
+ CheckedRadioButtons m_checkedRadioButtons;
- typedef HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*> NamedCollectionMap;
- HTMLCollection::CollectionInfo m_collectionInfo[HTMLCollection::NumUnnamedDocumentCachedTypes];
- NamedCollectionMap m_nameCollectionInfo[HTMLCollection::NumNamedDocumentCachedTypes];
+ typedef HashMap<AtomicStringImpl*, CollectionCache*> NamedCollectionMap;
+ CollectionCache m_collectionInfo[NumUnnamedDocumentCachedTypes];
+ NamedCollectionMap m_nameCollectionInfo[NumNamedDocumentCachedTypes];
#if ENABLE(XPATH)
RefPtr<XPathEvaluator> m_xpathEvaluator;
@@ -1096,13 +1111,6 @@ private:
#endif
bool m_usingGeolocation;
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- bool m_inLowBandwidthDisplay;
-#endif
-
- typedef HashMap<int, DOMTimer*> TimeoutsMap;
- TimeoutsMap m_timeouts;
};
inline bool Document::hasElementWithId(AtomicStringImpl* id) const
diff --git a/src/3rdparty/webkit/WebCore/dom/Document.idl b/src/3rdparty/webkit/WebCore/dom/Document.idl
index dfdfe46..ac6dd0e 100644
--- a/src/3rdparty/webkit/WebCore/dom/Document.idl
+++ b/src/3rdparty/webkit/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)
@@ -81,7 +81,7 @@ module core {
attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString documentURI;
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
// DOM Level 2 Events (DocumentEvents interface)
Event createEvent(in DOMString eventType)
@@ -116,17 +116,17 @@ module core {
[OldStyleObjC] CSSStyleDeclaration getOverrideStyle(in Element element,
in DOMString pseudoElement);
-#if ENABLE_XPATH
+#if defined(ENABLE_XPATH) && ENABLE_XPATH
// DOM Level 3 XPath (XPathEvaluator interface)
[OldStyleObjC] XPathExpression createExpression(in DOMString expression,
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)
@@ -137,7 +137,7 @@ module core {
in boolean userInterface,
in [ConvertUndefinedOrNullToNullString] DOMString value);
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// FIXME: remove the these two versions once [Optional] is implemented for Objective-C.
boolean execCommand(in DOMString command,
in boolean userInterface);
@@ -154,7 +154,7 @@ module core {
attribute [ConvertNullToNullString] DOMString title;
readonly attribute DOMString referrer;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
attribute [ConvertNullToNullString] DOMString domain;
#else
readonly attribute DOMString domain;
@@ -180,7 +180,7 @@ module core {
NodeList getElementsByName(in DOMString elementName);
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
attribute [Custom] Location location;
#endif
@@ -193,7 +193,7 @@ module core {
Element elementFromPoint(in long x, in long y);
// Mozilla extensions
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
DOMSelection getSelection();
#endif
readonly attribute [ConvertNullStringTo=Null] DOMString characterSet;
@@ -203,13 +203,13 @@ module core {
readonly attribute [ConvertNullStringTo=Null] DOMString preferredStylesheetSet;
attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString selectedStylesheetSet;
-#if !defined(LANGUAGE_COM)
-#if !defined(LANGUAGE_JAVASCRIPT)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
CSSStyleDeclaration createCSSStyleDeclaration();
#endif
#endif
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// DOM Level 2 Style Interface
[OldStyleObjC, UsesView] CSSStyleDeclaration getComputedStyle(in Element element,
in DOMString pseudoElement);
@@ -224,9 +224,9 @@ module core {
#endif
-#if !defined(LANGUAGE_COM)
-#if !defined(LANGUAGE_OBJECTIVE_C)
- DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+ [V8Custom] DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
#endif
#endif
@@ -234,14 +234,87 @@ 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
+#if defined(ENABLE_WML) && ENABLE_WML
// Only used from within WML layout tests, WML doesn't have JS support at all.
void resetWMLPageState();
+ void initializeWMLPageState();
+#endif
+
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+ // Event handler DOM attributes
+ attribute [DontEnum] EventListener onabort;
+ attribute [DontEnum] EventListener onblur;
+ attribute [DontEnum] EventListener onchange;
+ attribute [DontEnum] EventListener onclick;
+ attribute [DontEnum] EventListener oncontextmenu;
+ attribute [DontEnum] EventListener ondblclick;
+ attribute [DontEnum] EventListener ondrag;
+ attribute [DontEnum] EventListener ondragend;
+ attribute [DontEnum] EventListener ondragenter;
+ attribute [DontEnum] EventListener ondragleave;
+ attribute [DontEnum] EventListener ondragover;
+ attribute [DontEnum] EventListener ondragstart;
+ attribute [DontEnum] EventListener ondrop;
+ attribute [DontEnum] EventListener onerror;
+ attribute [DontEnum] EventListener onfocus;
+ attribute [DontEnum] EventListener oninput;
+ attribute [DontEnum] EventListener onkeydown;
+ attribute [DontEnum] EventListener onkeypress;
+ attribute [DontEnum] EventListener onkeyup;
+ attribute [DontEnum] EventListener onload;
+ attribute [DontEnum] EventListener onmousedown;
+ attribute [DontEnum] EventListener onmousemove;
+ attribute [DontEnum] EventListener onmouseout;
+ attribute [DontEnum] EventListener onmouseover;
+ attribute [DontEnum] EventListener onmouseup;
+ attribute [DontEnum] EventListener onmousewheel;
+ attribute [DontEnum] EventListener onscroll;
+ attribute [DontEnum] EventListener onselect;
+ attribute [DontEnum] EventListener onsubmit;
+
+ // attribute [DontEnum] EventListener oncanplay;
+ // attribute [DontEnum] EventListener oncanplaythrough;
+ // attribute [DontEnum] EventListener ondurationchange;
+ // attribute [DontEnum] EventListener onemptied;
+ // attribute [DontEnum] EventListener onended;
+ // attribute [DontEnum] EventListener onformchange;
+ // attribute [DontEnum] EventListener onforminput;
+ // attribute [DontEnum] EventListener oninvalid;
+ // attribute [DontEnum] EventListener onloadeddata;
+ // attribute [DontEnum] EventListener onloadedmetadata;
+ // attribute [DontEnum] EventListener onloadstart;
+ // attribute [DontEnum] EventListener onpause;
+ // attribute [DontEnum] EventListener onplay;
+ // attribute [DontEnum] EventListener onplaying;
+ // attribute [DontEnum] EventListener onprogress;
+ // attribute [DontEnum] EventListener onratechange;
+ // attribute [DontEnum] EventListener onreadystatechange;
+ // attribute [DontEnum] EventListener onseeked;
+ // attribute [DontEnum] EventListener onseeking;
+ // attribute [DontEnum] EventListener onshow;
+ // attribute [DontEnum] EventListener onstalled;
+ // attribute [DontEnum] EventListener onsuspend;
+ // attribute [DontEnum] EventListener ontimeupdate;
+ // attribute [DontEnum] EventListener onvolumechange;
+ // attribute [DontEnum] EventListener onwaiting;
+
+ // WebKit extensions
+ attribute [DontEnum] EventListener onbeforecut;
+ attribute [DontEnum] EventListener oncut;
+ attribute [DontEnum] EventListener onbeforecopy;
+ attribute [DontEnum] EventListener oncopy;
+ attribute [DontEnum] EventListener onbeforepaste;
+ attribute [DontEnum] EventListener onpaste;
+ attribute [DontEnum] EventListener onreset;
+ attribute [DontEnum] EventListener onsearch;
+ attribute [DontEnum] EventListener onselectstart;
+#endif
#endif
};
diff --git a/src/3rdparty/webkit/WebCore/dom/DocumentFragment.idl b/src/3rdparty/webkit/WebCore/dom/DocumentFragment.idl
index 2cdcdf8..ff6232f 100644
--- a/src/3rdparty/webkit/WebCore/dom/DocumentFragment.idl
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/DocumentMarker.h b/src/3rdparty/webkit/WebCore/dom/DocumentMarker.h
index 2ba9b47..8945eb0 100644
--- a/src/3rdparty/webkit/WebCore/dom/DocumentMarker.h
+++ b/src/3rdparty/webkit/WebCore/dom/DocumentMarker.h
@@ -30,19 +30,23 @@ namespace WebCore {
// A range of a node within a document that is "marked", such as the range of a misspelled word.
// It optionally includes a description that could be displayed in the user interface.
+// It also optionally includes a flag specifying whether the match is active, which is ignored
+// for all types other than type TextMatch.
struct DocumentMarker {
enum MarkerType {
AllMarkers = -1,
Spelling,
Grammar,
- TextMatch
+ TextMatch,
+ Replacement
};
MarkerType type;
unsigned startOffset;
unsigned endOffset;
String description;
+ bool activeMatch;
bool operator==(const DocumentMarker& o) const
{
diff --git a/src/3rdparty/webkit/WebCore/dom/Element.cpp b/src/3rdparty/webkit/WebCore/dom/Element.cpp
index 5faeea2..d858888 100644
--- a/src/3rdparty/webkit/WebCore/dom/Element.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/Element.cpp
@@ -4,7 +4,7 @@
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 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
@@ -27,8 +27,11 @@
#include "Element.h"
#include "AXObjectCache.h"
+#include "Attr.h"
#include "CSSStyleSelector.h"
#include "CString.h"
+#include "ClientRect.h"
+#include "ClientRectList.h"
#include "Document.h"
#include "Editor.h"
#include "ElementRareData.h"
@@ -38,7 +41,7 @@
#include "FrameView.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
-#include "NamedAttrMap.h"
+#include "NamedNodeMap.h"
#include "NodeList.h"
#include "NodeRenderStyle.h"
#include "Page.h"
@@ -48,6 +51,10 @@
#include "TextIterator.h"
#include "XMLNames.h"
+#if ENABLE(SVG)
+#include "SVGNames.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
@@ -78,30 +85,35 @@ inline ElementRareData* Element::ensureRareData()
NodeRareData* Element::createRareData()
{
- return new ElementRareData(this);
+ return new ElementRareData;
}
PassRefPtr<Node> Element::cloneNode(bool deep)
{
- ExceptionCode ec = 0;
- RefPtr<Element> clone = document()->createElementNS(namespaceURI(), nodeName(), ec);
- ASSERT(!ec);
-
- // clone attributes
- if (namedAttrMap)
- clone->attributes()->setAttributes(*namedAttrMap);
-
- clone->copyNonAttributeProperties(this);
-
- if (deep)
- cloneChildNodes(clone.get());
+ return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
+}
+PassRefPtr<Element> Element::cloneElementWithChildren()
+{
+ RefPtr<Element> clone = cloneElementWithoutChildren();
+ cloneChildNodes(clone.get());
return clone.release();
}
-PassRefPtr<Element> Element::cloneElement()
+PassRefPtr<Element> Element::cloneElementWithoutChildren()
{
- return static_pointer_cast<Element>(cloneNode(false));
+ 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(*attributes(true)); // Call attributes(true) to force attribute synchronization to occur (for svg and style) before cloning happens.
+
+ clone->copyNonAttributeProperties(this);
+
+ return clone.release();
}
void Element::removeAttribute(const QualifiedName& name, ExceptionCode& ec)
@@ -130,12 +142,12 @@ void Element::setBooleanAttribute(const QualifiedName& name, bool b)
}
// Virtual function, defined in base class.
-NamedAttrMap* Element::attributes() const
+NamedNodeMap* Element::attributes() const
{
return attributes(false);
}
-NamedAttrMap* Element::attributes(bool readonly) const
+NamedNodeMap* Element::attributes(bool readonly) const
{
if (!m_isStyleAttributeValid)
updateStyleAttribute();
@@ -189,9 +201,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 +213,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);
}
}
@@ -217,7 +229,7 @@ void Element::scrollByUnits(int units, ScrollGranularity granularity)
direction = ScrollUp;
units = -units;
}
- rend->layer()->scroll(direction, granularity, units);
+ toRenderBox(rend)->layer()->scroll(direction, granularity, units);
}
}
}
@@ -258,23 +270,54 @@ static float localZoomForRenderer(RenderObject* renderer)
static int adjustForLocalZoom(int value, RenderObject* renderer)
{
float zoomFactor = localZoomForRenderer(renderer);
- if (zoomFactor == 1.0f)
+ if (zoomFactor == 1)
return value;
+ // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
+ if (zoomFactor > 1)
+ value++;
return static_cast<int>(value / zoomFactor);
}
static int adjustForAbsoluteZoom(int value, RenderObject* renderer)
{
float zoomFactor = renderer->style()->effectiveZoom();
- if (zoomFactor == 1.0f)
+ if (zoomFactor == 1)
return value;
+ // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
+ if (zoomFactor > 1)
+ value++;
return static_cast<int>(value / zoomFactor);
}
+static FloatPoint adjustFloatPointForAbsoluteZoom(const FloatPoint& point, RenderObject* renderer)
+{
+ // The result here is in floats, so we don't need the truncation hack from the integer version above.
+ float zoomFactor = renderer->style()->effectiveZoom();
+ if (zoomFactor == 1)
+ return point;
+ return FloatPoint(point.x() / zoomFactor, point.y() / zoomFactor);
+}
+
+static void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject* renderer)
+{
+ quad.setP1(adjustFloatPointForAbsoluteZoom(quad.p1(), renderer));
+ quad.setP2(adjustFloatPointForAbsoluteZoom(quad.p2(), renderer));
+ quad.setP3(adjustFloatPointForAbsoluteZoom(quad.p3(), renderer));
+ quad.setP4(adjustFloatPointForAbsoluteZoom(quad.p4(), renderer));
+}
+
+static void adjustIntRectForAbsoluteZoom(IntRect& rect, RenderObject* renderer)
+{
+ rect.setX(adjustForAbsoluteZoom(rect.x(), renderer));
+ rect.setY(adjustForAbsoluteZoom(rect.y(), renderer));
+ rect.setWidth(adjustForAbsoluteZoom(rect.width(), renderer));
+ rect.setHeight(adjustForAbsoluteZoom(rect.height(), renderer));
+}
+
int Element::offsetLeft()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForLocalZoom(rend->offsetLeft(), rend);
return 0;
}
@@ -282,7 +325,7 @@ int Element::offsetLeft()
int Element::offsetTop()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForLocalZoom(rend->offsetTop(), rend);
return 0;
}
@@ -290,7 +333,7 @@ int Element::offsetTop()
int Element::offsetWidth()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForAbsoluteZoom(rend->offsetWidth(), rend);
return 0;
}
@@ -298,7 +341,7 @@ int Element::offsetWidth()
int Element::offsetHeight()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForAbsoluteZoom(rend->offsetHeight(), rend);
return 0;
}
@@ -308,7 +351,7 @@ Element* Element::offsetParent()
document()->updateLayoutIgnorePendingStylesheets();
if (RenderObject* rend = renderer())
if (RenderObject* offsetParent = rend->offsetParent())
- return static_cast<Element*>(offsetParent->element());
+ return static_cast<Element*>(offsetParent->node());
return 0;
}
@@ -316,7 +359,7 @@ int Element::clientLeft()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
return adjustForAbsoluteZoom(rend->clientLeft(), rend);
return 0;
}
@@ -325,7 +368,7 @@ int Element::clientTop()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
return adjustForAbsoluteZoom(rend->clientTop(), rend);
return 0;
}
@@ -340,11 +383,10 @@ 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 (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
return adjustForAbsoluteZoom(rend->clientWidth(), rend);
return 0;
}
@@ -360,26 +402,26 @@ 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 (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
return adjustForAbsoluteZoom(rend->clientHeight(), rend);
return 0;
}
-int Element::scrollLeft()
+int Element::scrollLeft() const
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
return 0;
}
-int Element::scrollTop()
+int Element::scrollTop() const
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
return adjustForAbsoluteZoom(rend->scrollTop(), rend);
return 0;
}
@@ -387,33 +429,85 @@ int Element::scrollTop()
void Element::setScrollLeft(int newLeft)
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
}
void Element::setScrollTop(int newTop)
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
}
-int Element::scrollWidth()
+int Element::scrollWidth() const
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ if (RenderBox* rend = renderBox())
return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
return 0;
}
-int Element::scrollHeight()
+int Element::scrollHeight() const
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderObject* rend = renderer())
+ 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());
+ adjustFloatQuadForAbsoluteZoom(quads[i], renderBoxModelObject);
+ }
+ }
+
+ 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());
+ }
+
+ adjustIntRectForAbsoluteZoom(result, renderBoxModelObject);
+
+ return ClientRect::create(result);
+}
+
static inline bool shouldIgnoreAttributeCase(const Element* e)
{
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
@@ -496,20 +590,20 @@ PassRefPtr<Attribute> Element::createAttribute(const QualifiedName& name, const
void Element::attributeChanged(Attribute* attr, bool)
{
+ if (!document()->axObjectCache()->accessibilityEnabled())
+ return;
+
const QualifiedName& attrName = attr->name();
if (attrName == aria_activedescendantAttr) {
// any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact
- if (document()->axObjectCache()->accessibilityEnabled())
- document()->axObjectCache()->handleActiveDescendantChanged(renderer());
- }
- if (attrName == roleAttr) {
+ document()->axObjectCache()->handleActiveDescendantChanged(renderer());
+ } else if (attrName == roleAttr) {
// the role attribute can change at any time, and the AccessibilityObject must pick up these changes
- if (document()->axObjectCache()->accessibilityEnabled())
- document()->axObjectCache()->handleAriaRoleChanged(renderer());
+ document()->axObjectCache()->handleAriaRoleChanged(renderer());
}
}
-void Element::setAttributeMap(PassRefPtr<NamedAttrMap> list)
+void Element::setAttributeMap(PassRefPtr<NamedNodeMap> list)
{
document()->incDOMTreeVersion();
@@ -587,7 +681,7 @@ KURL Element::baseURI() const
void Element::createAttributeMap() const
{
- namedAttrMap = NamedAttrMap::create(const_cast<Element*>(this));
+ namedAttrMap = NamedNodeMap::create(const_cast<Element*>(this));
}
bool Element::isURLAttribute(Attribute*) const
@@ -620,7 +714,7 @@ void Element::insertedIntoDocument()
ContainerNode::insertedIntoDocument();
if (hasID()) {
- if (NamedAttrMap* attrs = namedAttrMap.get()) {
+ if (NamedNodeMap* attrs = namedAttrMap.get()) {
Attribute* idItem = attrs->getAttributeItem(idAttr);
if (idItem && !idItem->isNull())
updateId(nullAtom, idItem->value());
@@ -631,7 +725,7 @@ void Element::insertedIntoDocument()
void Element::removedFromDocument()
{
if (hasID()) {
- if (NamedAttrMap* attrs = namedAttrMap.get()) {
+ if (NamedNodeMap* attrs = namedAttrMap.get()) {
Attribute* idItem = attrs->getAttributeItem(idAttr);
if (idItem && !idItem->isNull())
updateId(idItem->value(), nullAtom);
@@ -643,6 +737,8 @@ void Element::removedFromDocument()
void Element::attach()
{
+ suspendPostAttachCallbacks();
+
createRendererIfNeeded();
ContainerNode::attach();
if (hasRareData()) {
@@ -653,13 +749,15 @@ void Element::attach()
data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
}
}
+
+ resumePostAttachCallbacks();
}
void Element::detach()
{
cancelFocusAppearanceUpdate();
if (hasRareData())
- rareData()->resetComputedStyle(this);
+ rareData()->resetComputedStyle();
ContainerNode::detach();
}
@@ -667,7 +765,7 @@ void Element::recalcStyle(StyleChange change)
{
RenderStyle* currentStyle = renderStyle();
bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
- bool hasPositionalRules = changed() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
+ bool hasPositionalRules = needsStyleRecalc() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
#if ENABLE(SVG)
@@ -675,11 +773,11 @@ void Element::recalcStyle(StyleChange change)
hasParentStyle = true;
#endif
- if ((change > NoChange || changed())) {
+ if ((change > NoChange || needsStyleRecalc())) {
if (hasRareData())
- rareData()->resetComputedStyle(this);
+ rareData()->resetComputedStyle();
}
- if (hasParentStyle && (change >= Inherit || changed())) {
+ if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
StyleChange ch = diff(currentStyle, newStyle.get());
if (ch == Detach || !currentStyle) {
@@ -687,8 +785,8 @@ void Element::recalcStyle(StyleChange change)
detach();
attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
// attach recalulates the style for all children. No need to do it twice.
- setChanged(NoStyleChange);
- setHasChangedChild(false);
+ setNeedsStyleRecalc(NoStyleChange);
+ setChildNeedsStyleRecalc(false);
return;
}
@@ -715,7 +813,7 @@ void Element::recalcStyle(StyleChange change)
if (ch != NoChange) {
setRenderStyle(newStyle);
- } else if (changed() && (styleChangeType() != AnimationStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
+ } else if (needsStyleRecalc() && (styleChangeType() != AnimationStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
// Although no change occurred, we use the new style so that the cousin style sharing code won't get
// fooled into believing this style is the same. This is only necessary if the document actually uses
// sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of
@@ -740,17 +838,17 @@ void Element::recalcStyle(StyleChange change)
// without doing way too much re-resolution.
bool forceCheckOfNextElementSibling = false;
for (Node *n = firstChild(); n; n = n->nextSibling()) {
- bool childRulesChanged = n->changed() && n->styleChangeType() == FullStyleChange;
+ bool childRulesChanged = n->needsStyleRecalc() && n->styleChangeType() == FullStyleChange;
if (forceCheckOfNextElementSibling && n->isElementNode())
- n->setChanged();
- if (change >= Inherit || n->isTextNode() || n->hasChangedChild() || n->changed())
+ n->setNeedsStyleRecalc();
+ if (change >= Inherit || n->isTextNode() || n->childNeedsStyleRecalc() || n->needsStyleRecalc())
n->recalcStyle(change);
if (n->isElementNode())
forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
}
- setChanged(NoStyleChange);
- setHasChangedChild(false);
+ setNeedsStyleRecalc(NoStyleChange);
+ setChildNeedsStyleRecalc(false);
}
bool Element::childTypeAllowed(NodeType type)
@@ -772,7 +870,7 @@ bool Element::childTypeAllowed(NodeType type)
static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
Node* beforeChange, Node* afterChange, int childCountDelta)
{
- if (!style || (e->changed() && style->childrenAffectedByPositionalRules()))
+ if (!style || (e->needsStyleRecalc() && style->childrenAffectedByPositionalRules()))
return;
// :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
@@ -792,11 +890,11 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
// This is the insert/append case.
if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
- firstElementAfterInsertion->setChanged();
+ firstElementAfterInsertion->setNeedsStyleRecalc();
// We also have to handle node removal.
if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())
- newFirstChild->setChanged();
+ newFirstChild->setNeedsStyleRecalc();
}
// :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
@@ -814,12 +912,12 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
- lastElementBeforeInsertion->setChanged();
+ lastElementBeforeInsertion->setNeedsStyleRecalc();
// We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
// to match now.
if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !newLastChild->renderStyle()->lastChildState())
- newLastChild->setChanged();
+ newLastChild->setNeedsStyleRecalc();
}
// The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
@@ -830,7 +928,7 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
- firstElementAfterInsertion->setChanged();
+ firstElementAfterInsertion->setNeedsStyleRecalc();
}
// Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
@@ -842,11 +940,11 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
// here. recalcStyle will then force a walk of the children when it sees that this has happened.
if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
(style->childrenAffectedByBackwardPositionalRules() && beforeChange))
- e->setChanged();
+ e->setNeedsStyleRecalc();
// :empty selector.
if (style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes()))
- e->setChanged();
+ e->setNeedsStyleRecalc();
}
void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -891,7 +989,7 @@ String Element::openTagStartToString() const
{
String result = "<" + nodeName();
- NamedAttrMap *attrMap = attributes(true);
+ NamedNodeMap* attrMap = attributes(true);
if (attrMap) {
unsigned numAttrs = attrMap->length();
@@ -991,7 +1089,7 @@ PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
return 0;
}
- NamedAttrMap *attrs = attributes(true);
+ NamedNodeMap* attrs = attributes(true);
if (!attrs)
return 0;
@@ -1026,7 +1124,7 @@ void Element::removeAttributeNS(const String& namespaceURI, const String& localN
PassRefPtr<Attr> Element::getAttributeNode(const String& name)
{
- NamedAttrMap* attrs = attributes(true);
+ NamedNodeMap* attrs = attributes(true);
if (!attrs)
return 0;
String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
@@ -1035,7 +1133,7 @@ PassRefPtr<Attr> Element::getAttributeNode(const String& name)
PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
{
- NamedAttrMap* attrs = attributes(true);
+ NamedNodeMap* attrs = attributes(true);
if (!attrs)
return 0;
return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
@@ -1043,7 +1141,7 @@ PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const S
bool Element::hasAttribute(const String& name) const
{
- NamedAttrMap* attrs = attributes(true);
+ NamedNodeMap* attrs = attributes(true);
if (!attrs)
return false;
@@ -1055,7 +1153,7 @@ bool Element::hasAttribute(const String& name) const
bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
{
- NamedAttrMap* attrs = attributes(true);
+ NamedNodeMap* attrs = attributes(true);
if (!attrs)
return false;
return attrs->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
@@ -1097,14 +1195,19 @@ 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();
}
- } 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
}
void Element::blur()
@@ -1184,7 +1287,7 @@ void Element::cancelFocusAppearanceUpdate()
void Element::normalizeAttributes()
{
// Normalize attributes.
- NamedAttrMap* attrs = attributes(true);
+ NamedNodeMap* attrs = attributes(true);
if (!attrs)
return;
unsigned numAttrs = attrs->length();
@@ -1238,4 +1341,15 @@ unsigned Element::childElementCount() const
return count;
}
+KURL Element::getURLAttribute(const QualifiedName& name) const
+{
+#ifndef NDEBUG
+ if (namedAttrMap) {
+ if (Attribute* attribute = namedAttrMap->getAttributeItem(name))
+ ASSERT(isURLAttribute(attribute));
+ }
+#endif
+ return document()->completeURL(getAttribute(name));
}
+
+} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/Element.h b/src/3rdparty/webkit/WebCore/dom/Element.h
index b48424f..dfa2c0e 100644
--- a/src/3rdparty/webkit/WebCore/dom/Element.h
+++ b/src/3rdparty/webkit/WebCore/dom/Element.h
@@ -34,6 +34,8 @@ namespace WebCore {
class Attr;
class Attribute;
class CSSStyleDeclaration;
+class ClientRect;
+class ClientRectList;
class ElementRareData;
class IntSize;
@@ -59,7 +61,7 @@ public:
void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&);
- void scrollIntoView (bool alignToTop = true);
+ void scrollIntoView(bool alignToTop = true);
void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
void scrollByUnits(int units, ScrollGranularity);
@@ -75,12 +77,15 @@ public:
int clientTop();
int clientWidth();
int clientHeight();
- int scrollLeft();
- int scrollTop();
- void setScrollLeft(int);
- void setScrollTop(int);
- int scrollWidth();
- int scrollHeight();
+ virtual int scrollLeft() const;
+ virtual int scrollTop() const;
+ virtual void setScrollLeft(int);
+ virtual void setScrollTop(int);
+ virtual int scrollWidth() const;
+ virtual int scrollHeight() const;
+
+ PassRefPtr<ClientRectList> getClientRects() const;
+ PassRefPtr<ClientRect> getBoundingClientRect() const;
void removeAttribute(const String& name, ExceptionCode&);
void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
@@ -110,33 +115,29 @@ 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 isInputTypeHidden() const { return false; }
- virtual bool isPasswordField() const { return false; }
-
String nodeNamePreservingCase() const;
// convenience methods which ignore exceptions
void setAttribute(const QualifiedName&, const AtomicString& value);
void setBooleanAttribute(const QualifiedName& name, bool);
- virtual NamedAttrMap* attributes() const;
- NamedAttrMap* attributes(bool readonly) const;
+ virtual NamedNodeMap* attributes() const;
+ NamedNodeMap* attributes(bool readonly) const;
// This method is called whenever an attribute is added, changed or removed.
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
// not part of the DOM
- void setAttributeMap(PassRefPtr<NamedAttrMap>);
+ void setAttributeMap(PassRefPtr<NamedNodeMap>);
virtual void copyNonAttributeProperties(const Element* /*source*/) { }
@@ -157,6 +158,7 @@ public:
virtual void accessKeyAction(bool /*sendToAnyEvent*/) { }
virtual bool isURLAttribute(Attribute*) const;
+ KURL getURLAttribute(const QualifiedName&) const;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual String target() const { return String(); }
@@ -198,6 +200,23 @@ public:
Element* nextElementSibling() const;
unsigned childElementCount() const;
+ // FormControlElement API
+ virtual bool isFormControlElement() const { return false; }
+ virtual bool isEnabledFormControl() const { return true; }
+ virtual bool isReadOnlyFormControl() const { return false; }
+ virtual bool isTextFormControl() const { return false; }
+
+ virtual bool formControlValueMatchesRenderer() const { return false; }
+ virtual void setFormControlValueMatchesRenderer(bool) { }
+
+ virtual const AtomicString& formControlName() const { return nullAtom; }
+ virtual const AtomicString& formControlType() const { return nullAtom; }
+
+ virtual bool saveFormControlState(String&) const { return false; }
+ virtual void restoreFormControlState(const String&) { }
+
+ virtual void dispatchFormControlChangeEvent() { }
+
private:
virtual void createAttributeMap() const;
@@ -214,6 +233,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();
@@ -221,7 +244,7 @@ protected:
ElementRareData* rareData() const;
ElementRareData* ensureRareData();
- mutable RefPtr<NamedAttrMap> namedAttrMap;
+ mutable RefPtr<NamedNodeMap> namedAttrMap;
};
inline bool Node::hasTagName(const QualifiedName& name) const
@@ -234,7 +257,7 @@ inline bool Node::hasAttributes() const
return isElementNode() && static_cast<const Element*>(this)->hasAttributes();
}
-inline NamedAttrMap* Node::attributes() const
+inline NamedNodeMap* Node::attributes() const
{
return isElementNode() ? static_cast<const Element*>(this)->attributes() : 0;
}
diff --git a/src/3rdparty/webkit/WebCore/dom/Element.idl b/src/3rdparty/webkit/WebCore/dom/Element.idl
index ae2c1b8..53711e9 100644
--- a/src/3rdparty/webkit/WebCore/dom/Element.idl
+++ b/src/3rdparty/webkit/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
@@ -66,7 +66,7 @@ module core {
[OldStyleObjC] boolean hasAttributeNS(in [ConvertNullToNullString] DOMString namespaceURI,
in DOMString localName);
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
readonly attribute CSSStyleDeclaration style;
#endif
@@ -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);
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
// ElementTraversal API
-#if !defined(LANGUAGE_COM)
readonly attribute Element firstElementChild;
readonly attribute Element lastElementChild;
readonly attribute Element previousElementSibling;
@@ -118,11 +118,88 @@ module core {
readonly attribute unsigned long childElementCount;
#endif
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ // CSSOM View Module API
+ ClientRectList getClientRects();
+ ClientRect getBoundingClientRect();
+#endif
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extensions
readonly attribute DOMString innerText;
#endif
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+ // Event handler DOM attributes
+ attribute [DontEnum] EventListener onabort;
+ attribute [DontEnum] EventListener onblur;
+ attribute [DontEnum] EventListener onchange;
+ attribute [DontEnum] EventListener onclick;
+ attribute [DontEnum] EventListener oncontextmenu;
+ attribute [DontEnum] EventListener ondblclick;
+ attribute [DontEnum] EventListener ondrag;
+ attribute [DontEnum] EventListener ondragend;
+ attribute [DontEnum] EventListener ondragenter;
+ attribute [DontEnum] EventListener ondragleave;
+ attribute [DontEnum] EventListener ondragover;
+ attribute [DontEnum] EventListener ondragstart;
+ attribute [DontEnum] EventListener ondrop;
+ attribute [DontEnum] EventListener onerror;
+ attribute [DontEnum] EventListener onfocus;
+ attribute [DontEnum] EventListener oninput;
+ attribute [DontEnum] EventListener onkeydown;
+ attribute [DontEnum] EventListener onkeypress;
+ attribute [DontEnum] EventListener onkeyup;
+ attribute [DontEnum] EventListener onload;
+ attribute [DontEnum] EventListener onmousedown;
+ attribute [DontEnum] EventListener onmousemove;
+ attribute [DontEnum] EventListener onmouseout;
+ attribute [DontEnum] EventListener onmouseover;
+ attribute [DontEnum] EventListener onmouseup;
+ attribute [DontEnum] EventListener onmousewheel;
+ attribute [DontEnum] EventListener onscroll;
+ attribute [DontEnum] EventListener onselect;
+ attribute [DontEnum] EventListener onsubmit;
+
+ // attribute [DontEnum] EventListener oncanplay;
+ // attribute [DontEnum] EventListener oncanplaythrough;
+ // attribute [DontEnum] EventListener ondurationchange;
+ // attribute [DontEnum] EventListener onemptied;
+ // attribute [DontEnum] EventListener onended;
+ // attribute [DontEnum] EventListener onformchange;
+ // attribute [DontEnum] EventListener onforminput;
+ // attribute [DontEnum] EventListener oninvalid;
+ // attribute [DontEnum] EventListener onloadeddata;
+ // attribute [DontEnum] EventListener onloadedmetadata;
+ // attribute [DontEnum] EventListener onloadstart;
+ // attribute [DontEnum] EventListener onpause;
+ // attribute [DontEnum] EventListener onplay;
+ // attribute [DontEnum] EventListener onplaying;
+ // attribute [DontEnum] EventListener onprogress;
+ // attribute [DontEnum] EventListener onratechange;
+ // attribute [DontEnum] EventListener onreadystatechange;
+ // attribute [DontEnum] EventListener onseeked;
+ // attribute [DontEnum] EventListener onseeking;
+ // attribute [DontEnum] EventListener onshow;
+ // attribute [DontEnum] EventListener onstalled;
+ // attribute [DontEnum] EventListener onsuspend;
+ // attribute [DontEnum] EventListener ontimeupdate;
+ // attribute [DontEnum] EventListener onvolumechange;
+ // attribute [DontEnum] EventListener onwaiting;
+
+ // WebKit extensions
+ attribute [DontEnum] EventListener onbeforecut;
+ attribute [DontEnum] EventListener oncut;
+ attribute [DontEnum] EventListener onbeforecopy;
+ attribute [DontEnum] EventListener oncopy;
+ attribute [DontEnum] EventListener onbeforepaste;
+ attribute [DontEnum] EventListener onpaste;
+ attribute [DontEnum] EventListener onreset;
+ attribute [DontEnum] EventListener onsearch;
+ attribute [DontEnum] EventListener onselectstart;
+#endif
+#endif
};
}
diff --git a/src/3rdparty/webkit/WebCore/dom/ElementRareData.h b/src/3rdparty/webkit/WebCore/dom/ElementRareData.h
index 096f846..94e0499 100644
--- a/src/3rdparty/webkit/WebCore/dom/ElementRareData.h
+++ b/src/3rdparty/webkit/WebCore/dom/ElementRareData.h
@@ -1,6 +1,5 @@
-/**
- *
- * Copyright (C) 2008 Apple Computer, Inc.
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 David Smith <catfish.man@gmail.com>
*
* This library is free software; you can redistribute it and/or
@@ -30,9 +29,9 @@ namespace WebCore {
class ElementRareData : public NodeRareData {
public:
- ElementRareData(Element*);
+ ElementRareData();
- void resetComputedStyle(Element*);
+ void resetComputedStyle();
using NodeRareData::needsFocusAppearanceUpdateSoonAfterAttach;
using NodeRareData::setNeedsFocusAppearanceUpdateSoonAfterAttach;
@@ -46,12 +45,12 @@ inline IntSize defaultMinimumSizeForResizing()
return IntSize(INT_MAX, INT_MAX);
}
-inline ElementRareData::ElementRareData(Element* e)
+inline ElementRareData::ElementRareData()
: m_minimumSizeForResizing(defaultMinimumSizeForResizing())
{
}
-inline void ElementRareData::resetComputedStyle(Element* element)
+inline void ElementRareData::resetComputedStyle()
{
m_computedStyle.clear();
}
diff --git a/src/3rdparty/webkit/WebCore/dom/Event.cpp b/src/3rdparty/webkit/WebCore/dom/Event.cpp
index 67ae492..b4b87ed 100644
--- a/src/3rdparty/webkit/WebCore/dom/Event.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/Event.cpp
@@ -24,7 +24,7 @@
#include "Event.h"
#include "AtomicString.h"
-#include "SystemTime.h"
+#include <wtf/CurrentTime.h>
namespace WebCore {
@@ -35,8 +35,8 @@ Event::Event()
, m_defaultPrevented(false)
, m_defaultHandled(false)
, m_cancelBubble(false)
- , m_currentTarget(0)
, m_eventPhase(0)
+ , m_currentTarget(0)
, m_createTime(static_cast<DOMTimeStamp>(currentTime() * 1000.0))
{
}
@@ -49,8 +49,8 @@ Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableAr
, m_defaultPrevented(false)
, m_defaultHandled(false)
, m_cancelBubble(false)
- , m_currentTarget(0)
, m_eventPhase(0)
+ , m_currentTarget(0)
, m_createTime(static_cast<DOMTimeStamp>(currentTime() * 1000.0))
{
}
diff --git a/src/3rdparty/webkit/WebCore/dom/Event.h b/src/3rdparty/webkit/WebCore/dom/Event.h
index a30dd39..6984215 100644
--- a/src/3rdparty/webkit/WebCore/dom/Event.h
+++ b/src/3rdparty/webkit/WebCore/dom/Event.h
@@ -157,8 +157,8 @@ namespace WebCore {
bool m_defaultHandled;
bool m_cancelBubble;
- EventTarget* m_currentTarget;
unsigned short m_eventPhase;
+ EventTarget* m_currentTarget;
RefPtr<EventTarget> m_target;
DOMTimeStamp m_createTime;
diff --git a/src/3rdparty/webkit/WebCore/dom/Event.idl b/src/3rdparty/webkit/WebCore/dom/Event.idl
index 99b0bd1..5ac9e0c 100644
--- a/src/3rdparty/webkit/WebCore/dom/Event.idl
+++ b/src/3rdparty/webkit/WebCore/dom/Event.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
@@ -24,7 +24,7 @@ module events {
interface [
GenerateConstructor,
NoStaticTables,
- ObjCCustomInternalImpl,
+ Polymorphic,
InterfaceUUID=D17495FA-ACAD-4d27-9362-E19E057B189D,
ImplementationUUID=CFDCDDB2-5B3F-412d-BDA4-80B23C721549
] Event {
@@ -34,7 +34,7 @@ module events {
const unsigned short AT_TARGET = 2;
const unsigned short BUBBLING_PHASE = 3;
-#if !defined(LANGUAGE_OBJECTIVE_C)
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
// Reverse-engineered from Netscape
const unsigned short MOUSEDOWN = 1;
const unsigned short MOUSEUP = 2;
@@ -60,7 +60,7 @@ module events {
readonly attribute unsigned short eventPhase;
readonly attribute boolean bubbles;
readonly attribute boolean cancelable;
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
readonly attribute DOMTimeStamp timeStamp;
#endif
void stopPropagation();
@@ -74,7 +74,7 @@ module events {
attribute boolean returnValue;
attribute boolean cancelBubble;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
readonly attribute [Custom] Clipboard clipboardData;
#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/EventException.idl b/src/3rdparty/webkit/WebCore/dom/EventException.idl
index 61cfd65..3d82f85 100644
--- a/src/3rdparty/webkit/WebCore/dom/EventException.idl
+++ b/src/3rdparty/webkit/WebCore/dom/EventException.idl
@@ -30,14 +30,15 @@ module events {
// Introduced in DOM Level 2:
interface [
- GenerateConstructor
+ GenerateConstructor,
+ NoStaticTables
] EventException {
readonly attribute unsigned short code;
readonly attribute DOMString name;
readonly attribute DOMString message;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// Override in a Mozilla compatible format
[DontEnum] DOMString toString();
#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/EventListener.h b/src/3rdparty/webkit/WebCore/dom/EventListener.h
index 24fce86..dbc41b2 100644
--- a/src/3rdparty/webkit/WebCore/dom/EventListener.h
+++ b/src/3rdparty/webkit/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,23 @@ 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* jsFunction() const { return 0; }
+ virtual void markJSFunction() { }
+#endif
+
+ bool isAttribute() const { return virtualisAttribute(); }
+
+ private:
+ virtual bool virtualisAttribute() const { return false; }
};
+#if USE(JSC)
+ inline void markIfNotNull(EventListener* listener) { if (listener) listener->markJSFunction(); }
+#endif
+
}
#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/EventListener.idl b/src/3rdparty/webkit/WebCore/dom/EventListener.idl
index 9d28703..9dc2e0a 100644
--- a/src/3rdparty/webkit/WebCore/dom/EventListener.idl
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/EventNames.h b/src/3rdparty/webkit/WebCore/dom/EventNames.h
index 35c7571..9272ba4 100644
--- a/src/3rdparty/webkit/WebCore/dom/EventNames.h
+++ b/src/3rdparty/webkit/WebCore/dom/EventNames.h
@@ -68,6 +68,7 @@ namespace WebCore {
macro(mouseup) \
macro(mousewheel) \
macro(noupdate) \
+ macro(obsolete) \
macro(offline) \
macro(online) \
macro(overflowchanged) \
@@ -101,24 +102,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/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp b/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp
index dcebd64..06cea07 100644
--- a/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp
@@ -44,7 +44,12 @@ EventTarget::~EventTarget()
{
}
-EventTargetNode* EventTarget::toNode()
+Node* EventTarget::toNode()
+{
+ return 0;
+}
+
+DOMWindow* EventTarget::toDOMWindow()
{
return 0;
}
diff --git a/src/3rdparty/webkit/WebCore/dom/EventTarget.h b/src/3rdparty/webkit/WebCore/dom/EventTarget.h
index 3a3ec84..662902e 100644
--- a/src/3rdparty/webkit/WebCore/dom/EventTarget.h
+++ b/src/3rdparty/webkit/WebCore/dom/EventTarget.h
@@ -38,12 +38,13 @@ namespace WebCore {
class AtomicString;
class DOMApplicationCache;
+ class DOMWindow;
class Event;
class EventListener;
- class EventTargetNode;
class MessagePort;
- class ScriptExecutionContext;
+ class Node;
class SVGElementInstance;
+ class ScriptExecutionContext;
class Worker;
class WorkerContext;
class XMLHttpRequest;
@@ -54,7 +55,8 @@ namespace WebCore {
class EventTarget {
public:
virtual MessagePort* toMessagePort();
- virtual EventTargetNode* toNode();
+ virtual Node* toNode();
+ virtual DOMWindow* toDOMWindow();
virtual XMLHttpRequest* toXMLHttpRequest();
virtual XMLHttpRequestUpload* toXMLHttpRequestUpload();
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/src/3rdparty/webkit/WebCore/dom/EventTarget.idl b/src/3rdparty/webkit/WebCore/dom/EventTarget.idl
index d3f46f7..844dc32 100644
--- a/src/3rdparty/webkit/WebCore/dom/EventTarget.idl
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp b/src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp
deleted file mode 100644
index 8553da7..0000000
--- a/src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp
+++ /dev/null
@@ -1,1166 +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)
- : Node(doc, isElement, isContainer)
-{
-}
-
-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);
-}
-
-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);
- return;
- }
- }
-}
-
-void EventTargetNode::removeAllEventListeners()
-{
- if (!hasRareData())
- return;
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
- 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(), ec);
-}
-
-bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> prpEvent, ExceptionCode& ec)
-{
- 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);
- ExceptionCode ec = 0;
- ownerElement->dispatchGenericEvent(ownerEvent.release(), ec);
- }
- }
-}
-
-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;
-}
-
-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);
-}
-
-} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/EventTargetNode.h b/src/3rdparty/webkit/WebCore/dom/EventTargetNode.h
deleted file mode 100644
index 201b108..0000000
--- a/src/3rdparty/webkit/WebCore/dom/EventTargetNode.h
+++ /dev/null
@@ -1,206 +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);
- 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();
-
- 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>, ExceptionCode&);
-
- 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>);
-
- 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/src/3rdparty/webkit/WebCore/dom/EventTargetNode.idl b/src/3rdparty/webkit/WebCore/dom/EventTargetNode.idl
deleted file mode 100644
index 0049593..0000000
--- a/src/3rdparty/webkit/WebCore/dom/EventTargetNode.idl
+++ /dev/null
@@ -1,84 +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;
-
- [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/src/3rdparty/webkit/WebCore/dom/ExceptionCode.cpp b/src/3rdparty/webkit/WebCore/dom/ExceptionCode.cpp
index fa0a7a7..0291a21 100644
--- a/src/3rdparty/webkit/WebCore/dom/ExceptionCode.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/ExceptionCode.cpp
@@ -58,7 +58,11 @@ static const char* const exceptionNames[] = {
"INVALID_ACCESS_ERR",
"VALIDATION_ERR",
"TYPE_MISMATCH_ERR",
- "SECURITY_ERR"
+ "SECURITY_ERR",
+ "NETWORK_ERR",
+ "ABORT_ERR",
+ "URL_MISMATCH_ERR",
+ "QUOTA_EXCEEDED_ERR"
};
static const char* const rangeExceptionNames[] = {
@@ -71,7 +75,8 @@ static const char* const eventExceptionNames[] = {
};
static const char* const xmlHttpRequestExceptionNames[] = {
- "NETWORK_ERR"
+ "NETWORK_ERR",
+ "ABORT_ERR"
};
#if ENABLE(XPATH)
diff --git a/src/3rdparty/webkit/WebCore/dom/ExceptionCode.h b/src/3rdparty/webkit/WebCore/dom/ExceptionCode.h
index 9e34ae0..58b18e2 100644
--- a/src/3rdparty/webkit/WebCore/dom/ExceptionCode.h
+++ b/src/3rdparty/webkit/WebCore/dom/ExceptionCode.h
@@ -51,7 +51,13 @@ namespace WebCore {
TYPE_MISMATCH_ERR = 17,
// XMLHttpRequest extension:
- SECURITY_ERR = 18
+ SECURITY_ERR = 18,
+
+ // Others introduced in HTML5:
+ NETWORK_ERR = 19,
+ ABORT_ERR = 20,
+ URL_MISMATCH_ERR = 21,
+ QUOTA_EXCEEDED_ERR = 22,
};
enum ExceptionType {
diff --git a/src/3rdparty/webkit/WebCore/dom/InputElement.cpp b/src/3rdparty/webkit/WebCore/dom/InputElement.cpp
new file mode 100644
index 0000000..108d17e
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/InputElement.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "InputElement.h"
+
+#include "BeforeTextInsertedEvent.h"
+#include "ChromeClient.h"
+#include "Document.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "MappedAttribute.h"
+#include "Page.h"
+#include "RenderTextControlSingleLine.h"
+#include "SelectionController.h"
+#include "TextIterator.h"
+#include "TextBreakIterator.h"
+
+#if ENABLE(WML)
+#include "WMLInputElement.h"
+#include "WMLNames.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// FIXME: According to HTML4, the length attribute's value can be arbitrarily
+// large. However, due to http://bugs.webkit.org/show_bugs.cgi?id=14536 things
+// get rather sluggish when a text field has a larger number of characters than
+// this, even when just clicking in the text field.
+const int InputElement::s_maximumLength = 524288;
+const int InputElement::s_defaultSize = 20;
+
+void InputElement::dispatchFocusEvent(InputElementData& data, InputElement* inputElement, Element* element)
+{
+ if (!inputElement->isTextField())
+ return;
+
+ updatePlaceholderVisibility(data, inputElement, element);
+
+ Document* document = element->document();
+ if (inputElement->isPasswordField() && document->frame())
+ document->setUseSecureKeyboardEntryWhenActive(true);
+}
+
+void InputElement::dispatchBlurEvent(InputElementData& data, InputElement* inputElement, Element* element)
+{
+ if (!inputElement->isTextField())
+ return;
+
+ Document* document = element->document();
+ Frame* frame = document->frame();
+ if (!frame)
+ return;
+
+ updatePlaceholderVisibility(data, inputElement, element);
+
+ if (inputElement->isPasswordField())
+ document->setUseSecureKeyboardEntryWhenActive(false);
+
+ frame->textFieldDidEndEditing(element);
+}
+
+void InputElement::updatePlaceholderVisibility(InputElementData& data, InputElement* inputElement, Element* element, bool placeholderValueChanged)
+{
+ ASSERT(inputElement->isTextField());
+ Document* document = element->document();
+
+ bool oldPlaceholderShouldBeVisible = data.placeholderShouldBeVisible();
+ data.setPlaceholderShouldBeVisible(inputElement->value().isEmpty()
+ && document->focusedNode() != element
+ && !inputElement->placeholder().isEmpty());
+
+ if ((oldPlaceholderShouldBeVisible != data.placeholderShouldBeVisible() || placeholderValueChanged) && element->renderer())
+ static_cast<RenderTextControlSingleLine*>(element->renderer())->updatePlaceholderVisibility();
+}
+
+void InputElement::updateFocusAppearance(InputElementData& data, InputElement* inputElement, Element* element, bool restorePreviousSelection)
+{
+ ASSERT(inputElement->isTextField());
+
+ if (!restorePreviousSelection || data.cachedSelectionStart() == -1)
+ inputElement->select();
+ else
+ // Restore the cached selection.
+ updateSelectionRange(inputElement, element, data.cachedSelectionStart(), data.cachedSelectionEnd());
+
+ Document* document = element->document();
+ if (document && document->frame())
+ document->frame()->revealSelection();
+}
+
+void InputElement::updateSelectionRange(InputElement* inputElement, Element* element, int start, int end)
+{
+ if (!inputElement->isTextField())
+ return;
+
+ if (RenderTextControl* renderer = toRenderTextControl(element->renderer()))
+ renderer->setSelectionRange(start, end);
+}
+
+void InputElement::aboutToUnload(InputElement* inputElement, Element* element)
+{
+ if (!inputElement->isTextField() || !element->focused())
+ return;
+
+ Document* document = element->document();
+ Frame* frame = document->frame();
+ if (!frame)
+ return;
+
+ frame->textFieldDidEndEditing(element);
+}
+
+void InputElement::setValueFromRenderer(InputElementData& data, InputElement* inputElement, Element* element, const String& value)
+{
+ // Renderer and our event handler are responsible for constraining values.
+ ASSERT(value == inputElement->constrainValue(value) || inputElement->constrainValue(value).isEmpty());
+
+ if (inputElement->isTextField())
+ updatePlaceholderVisibility(data, inputElement, element);
+
+ // Workaround for bug where trailing \n is included in the result of textContent.
+ // The assert macro above may also be simplified to: value == constrainValue(value)
+ // http://bugs.webkit.org/show_bug.cgi?id=9661
+ if (value == "\n")
+ data.setValue("");
+ else
+ data.setValue(value);
+
+ element->setFormControlValueMatchesRenderer(true);
+
+ // Fire the "input" DOM event
+ element->dispatchEvent(eventNames().inputEvent, true, false);
+ notifyFormStateChanged(element);
+}
+
+static int numCharactersInGraphemeClusters(StringImpl* s, int numGraphemeClusters)
+{
+ if (!s)
+ return 0;
+
+ TextBreakIterator* it = characterBreakIterator(s->characters(), s->length());
+ if (!it)
+ return 0;
+
+ for (int i = 0; i < numGraphemeClusters; ++i) {
+ if (textBreakNext(it) == TextBreakDone)
+ return s->length();
+ }
+
+ return textBreakCurrent(it);
+}
+
+String InputElement::constrainValue(const InputElement* inputElement, const String& proposedValue, int maxLength)
+{
+ String string = proposedValue;
+ if (!inputElement->isTextField())
+ return string;
+
+ string.replace("\r\n", " ");
+ string.replace('\r', ' ');
+ string.replace('\n', ' ');
+
+ StringImpl* s = string.impl();
+ int newLength = numCharactersInGraphemeClusters(s, maxLength);
+ for (int i = 0; i < newLength; ++i) {
+ const UChar& current = (*s)[i];
+ if (current < ' ' && current != '\t') {
+ newLength = i;
+ break;
+ }
+ }
+
+ if (newLength < static_cast<int>(string.length()))
+ return string.left(newLength);
+
+ return string;
+}
+
+static int numGraphemeClusters(StringImpl* s)
+{
+ if (!s)
+ return 0;
+
+ TextBreakIterator* it = characterBreakIterator(s->characters(), s->length());
+ if (!it)
+ return 0;
+
+ int num = 0;
+ while (textBreakNext(it) != TextBreakDone)
+ ++num;
+
+ return num;
+}
+
+void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputElement* inputElement, Document* document, Event* event)
+{
+ ASSERT(event->isBeforeTextInsertedEvent());
+
+ // Make sure that the text to be inserted will not violate the maxLength.
+ int oldLength = numGraphemeClusters(inputElement->value().impl());
+ ASSERT(oldLength <= data.maxLength());
+ int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toNormalizedRange().get()).impl());
+ ASSERT(oldLength >= selectionLength);
+ int maxNewLength = data.maxLength() - (oldLength - selectionLength);
+
+ // Truncate the inserted text to avoid violating the maxLength and other constraints.
+ BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event);
+ textEvent->setText(constrainValue(inputElement, textEvent->text(), maxNewLength));
+}
+
+void InputElement::parseSizeAttribute(InputElementData& data, Element* element, MappedAttribute* attribute)
+{
+ data.setSize(attribute->isNull() ? InputElement::s_defaultSize : attribute->value().toInt());
+
+ if (RenderObject* renderer = element->renderer())
+ renderer->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+void InputElement::parseMaxLengthAttribute(InputElementData& data, InputElement* inputElement, Element* element, MappedAttribute* attribute)
+{
+ int maxLength = attribute->isNull() ? InputElement::s_maximumLength : attribute->value().toInt();
+ if (maxLength <= 0 || maxLength > InputElement::s_maximumLength)
+ maxLength = InputElement::s_maximumLength;
+
+ int oldMaxLength = data.maxLength();
+ data.setMaxLength(maxLength);
+
+ if (oldMaxLength != maxLength)
+ updateValueIfNeeded(data, inputElement);
+
+ element->setNeedsStyleRecalc();
+}
+
+void InputElement::updateValueIfNeeded(InputElementData& data, InputElement* inputElement)
+{
+ String oldValue = data.value();
+ String newValue = inputElement->constrainValue(oldValue);
+ if (newValue != oldValue)
+ inputElement->setValue(newValue);
+}
+
+void InputElement::notifyFormStateChanged(Element* element)
+{
+ Document* document = element->document();
+ Frame* frame = document->frame();
+ if (!frame)
+ return;
+
+ if (Page* page = frame->page())
+ page->chrome()->client()->formStateDidChange(element);
+}
+
+// InputElementData
+InputElementData::InputElementData()
+ : m_placeholderShouldBeVisible(false)
+ , m_size(InputElement::s_defaultSize)
+ , m_maxLength(InputElement::s_maximumLength)
+ , m_cachedSelectionStart(-1)
+ , m_cachedSelectionEnd(-1)
+{
+}
+
+const AtomicString& InputElementData::name() const
+{
+ return m_name.isNull() ? emptyAtom : m_name;
+}
+
+InputElement* toInputElement(Element* element)
+{
+ if (element->isHTMLElement() && (element->hasTagName(inputTag) || element->hasTagName(isindexTag)))
+ return static_cast<HTMLInputElement*>(element);
+
+#if ENABLE(WML)
+ if (element->isWMLElement() && element->hasTagName(WMLNames::inputTag))
+ return static_cast<WMLInputElement*>(element);
+#endif
+
+ return 0;
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/dom/InputElement.h b/src/3rdparty/webkit/WebCore/dom/InputElement.h
new file mode 100644
index 0000000..7ad3cbd
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/InputElement.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef InputElement_h
+#define InputElement_h
+
+#include "AtomicString.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Document;
+class Element;
+class Event;
+class InputElementData;
+class MappedAttribute;
+
+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;
+
+ virtual bool placeholderShouldBeVisible() const = 0;
+ virtual bool searchEventsShouldBeDispatched() const = 0;
+
+ virtual int size() const = 0;
+ virtual String value() const = 0;
+ virtual void setValue(const String&) = 0;
+
+ virtual String placeholder() const = 0;
+ virtual void setPlaceholder(const String&) = 0;
+
+ virtual String constrainValue(const String&) const = 0;
+ virtual void setValueFromRenderer(const String&) = 0;
+
+ virtual void cacheSelection(int start, int end) = 0;
+ virtual void select() = 0;
+
+ static const int s_maximumLength;
+ static const int s_defaultSize;
+
+protected:
+ static void dispatchFocusEvent(InputElementData&, InputElement*, Element*);
+ static void dispatchBlurEvent(InputElementData&, InputElement*, Element*);
+ static void updatePlaceholderVisibility(InputElementData&, InputElement*, Element*, bool placeholderValueChanged = false);
+ static void updateFocusAppearance(InputElementData&, InputElement*, Element*, bool restorePreviousSelection);
+ static void updateSelectionRange(InputElement*, Element*, int start, int end);
+ static void aboutToUnload(InputElement*, Element*);
+ static void setValueFromRenderer(InputElementData&, InputElement*, Element*, const String&);
+ static String constrainValue(const InputElement*, const String& proposedValue, int maxLength);
+ static void handleBeforeTextInsertedEvent(InputElementData&, InputElement*, Document*, Event*);
+ static void parseSizeAttribute(InputElementData&, Element*, MappedAttribute*);
+ static void parseMaxLengthAttribute(InputElementData&, InputElement*, Element*, MappedAttribute*);
+ static void updateValueIfNeeded(InputElementData&, InputElement*);
+ static void notifyFormStateChanged(Element*);
+};
+
+// HTML/WMLInputElement hold this struct as member variable
+// and pass it to the static helper functions in InputElement
+class InputElementData {
+public:
+ InputElementData();
+
+ bool placeholderShouldBeVisible() const { return m_placeholderShouldBeVisible; }
+ void setPlaceholderShouldBeVisible(bool visible) { m_placeholderShouldBeVisible = visible; }
+
+ const AtomicString& name() const;
+ void setName(const AtomicString& value) { m_name = value; }
+
+ String value() const { return m_value; }
+ void setValue(const String& value) { m_value = value; }
+
+ int size() const { return m_size; }
+ void setSize(int value) { m_size = value; }
+
+ int maxLength() const { return m_maxLength; }
+ void setMaxLength(int value) { m_maxLength = value; }
+
+ int cachedSelectionStart() const { return m_cachedSelectionStart; }
+ void setCachedSelectionStart(int value) { m_cachedSelectionStart = value; }
+
+ int cachedSelectionEnd() const { return m_cachedSelectionEnd; }
+ void setCachedSelectionEnd(int value) { m_cachedSelectionEnd = value; }
+
+private:
+ bool m_placeholderShouldBeVisible;
+ AtomicString m_name;
+ String m_value;
+ int m_size;
+ int m_maxLength;
+ int m_cachedSelectionStart;
+ int m_cachedSelectionEnd;
+};
+
+InputElement* toInputElement(Element*);
+
+}
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/KeyboardEvent.idl b/src/3rdparty/webkit/WebCore/dom/KeyboardEvent.idl
index 808319f..58e5da7 100644
--- a/src/3rdparty/webkit/WebCore/dom/KeyboardEvent.idl
+++ b/src/3rdparty/webkit/WebCore/dom/KeyboardEvent.idl
@@ -25,7 +25,7 @@ module events {
GenerateConstructor
] KeyboardEvent : UIEvent {
-#if !defined(LANGUAGE_JAVASCRIPT)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
// KeyLocationCode
const unsigned long KEY_LOCATION_STANDARD = 0x00;
const unsigned long KEY_LOCATION_LEFT = 0x01;
@@ -41,7 +41,7 @@ module events {
readonly attribute boolean metaKey;
readonly attribute boolean altGraphKey;
-#if !defined(LANGUAGE_JAVASCRIPT)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
boolean getModifierState(in DOMString keyIdentifierArg);
#endif
@@ -59,7 +59,7 @@ module events {
in boolean altGraphKey);
// WebKit Extensions
-#if !defined(LANGUAGE_JAVASCRIPT)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
readonly attribute long keyCode;
readonly attribute long charCode;
diff --git a/src/3rdparty/webkit/WebCore/dom/MessageChannel.cpp b/src/3rdparty/webkit/WebCore/dom/MessageChannel.cpp
index 3a90913..ac0a4ab 100644
--- a/src/3rdparty/webkit/WebCore/dom/MessageChannel.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/MessageChannel.cpp
@@ -28,14 +28,15 @@
#include "MessageChannel.h"
#include "MessagePort.h"
+#include "PlatformMessagePortChannel.h"
namespace WebCore {
MessageChannel::MessageChannel(ScriptExecutionContext* context)
- : m_port1(MessagePort::create(context))
- , m_port2(MessagePort::create(context))
+ : m_port1(MessagePort::create(*context))
+ , m_port2(MessagePort::create(*context))
{
- MessagePort::entangle(m_port1.get(), m_port2.get());
+ PlatformMessagePortChannel::createChannel(m_port1.get(), m_port2.get());
}
MessageChannel::~MessageChannel()
diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp b/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp
index 75f5a1e..9f3e4d2 100644
--- a/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp
@@ -38,89 +38,23 @@
namespace WebCore {
-class MessagePortCloseEventTask : public ScriptExecutionContext::Task {
-public:
- static PassRefPtr<MessagePortCloseEventTask> create(PassRefPtr<MessagePort> port)
- {
- return adoptRef(new MessagePortCloseEventTask(port));
- }
-
-private:
- MessagePortCloseEventTask(PassRefPtr<MessagePort> port)
- : m_port(port)
- {
- ASSERT(m_port);
- }
-
- virtual void performTask(ScriptExecutionContext* context)
- {
- ASSERT(!m_port->active());
- ASSERT(context == m_port->scriptExecutionContext());
-
- // Closing may destroy the port, dispatch any remaining messages now.
- if (m_port->queueIsOpen())
- m_port->dispatchMessages();
-
- m_port->dispatchCloseEvent();
- }
-
- RefPtr<MessagePort> m_port;
-};
-
-PassRefPtr<MessagePort::EventData> MessagePort::EventData::create(const String& message, PassRefPtr<MessagePort> port)
-{
- return adoptRef(new EventData(message, port));
-}
-
-MessagePort::EventData::EventData(const String& message, PassRefPtr<MessagePort> messagePort)
- : message(message.copy())
- , messagePort(messagePort)
-{
-}
-
-MessagePort::EventData::~EventData()
+MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext)
+ : m_entangledChannel(0)
+ , m_started(false)
+ , m_scriptExecutionContext(&scriptExecutionContext)
{
-}
+ m_scriptExecutionContext->createdMessagePort(this);
-MessagePort::MessagePort(ScriptExecutionContext* scriptExecutionContext)
- : m_entangledPort(0)
- , m_queueIsOpen(false)
- , m_scriptExecutionContext(scriptExecutionContext)
- , m_pendingCloseEvent(false)
-{
- if (scriptExecutionContext)
- scriptExecutionContext->createdMessagePort(this);
+ // Don't need to call processMessagePortMessagesSoon() here, because the port will not be opened until start() is invoked.
}
MessagePort::~MessagePort()
{
- if (m_entangledPort)
- unentangle();
-
+ close();
if (m_scriptExecutionContext)
m_scriptExecutionContext->destroyedMessagePort(this);
}
-PassRefPtr<MessagePort> MessagePort::clone(ExceptionCode& ec)
-{
- if (!m_entangledPort) {
- ec = INVALID_STATE_ERR;
- return 0;
- }
-
- RefPtr<MessagePort> remotePort = m_entangledPort;
- RefPtr<MessagePort> newPort = MessagePort::create(0);
-
- // Move all the events in the port message queue of original port to the port message queue of new port, if any, leaving the new port's port message queue in its initial closed state.
- // If events are posted (e.g. from a worker thread) while this code is executing, there is no guarantee whether they end up in the original or new port's message queue.
- RefPtr<EventData> eventData;
- while (m_messageQueue.tryGetMessage(eventData))
- newPort->m_messageQueue.append(eventData);
-
- entangle(remotePort.get(), newPort.get()); // The port object will be unentangled.
- return newPort;
-}
-
void MessagePort::postMessage(const String& message, ExceptionCode& ec)
{
postMessage(message, 0, ec);
@@ -128,106 +62,86 @@ void MessagePort::postMessage(const String& message, ExceptionCode& ec)
void MessagePort::postMessage(const String& message, MessagePort* dataPort, ExceptionCode& ec)
{
- if (!m_entangledPort || !m_scriptExecutionContext)
+ if (!m_entangledChannel)
return;
+ ASSERT(m_scriptExecutionContext);
- RefPtr<MessagePort> newMessagePort;
+ OwnPtr<MessagePortChannel> channel;
if (dataPort) {
- if (dataPort == this || dataPort == m_entangledPort) {
- ec = INVALID_ACCESS_ERR;
+ if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) {
+ ec = INVALID_STATE_ERR;
return;
}
- newMessagePort = dataPort->clone(ec);
+ channel = dataPort->disentangle(ec);
if (ec)
return;
}
-
- m_entangledPort->m_messageQueue.append(EventData::create(message, newMessagePort));
- if (m_entangledPort->m_queueIsOpen && m_entangledPort->m_scriptExecutionContext)
- m_entangledPort->m_scriptExecutionContext->processMessagePortMessagesSoon();
+ m_entangledChannel->postMessageToRemote(MessagePortChannel::EventData::create(message, channel.release()));
}
-PassRefPtr<MessagePort> MessagePort::startConversation(ScriptExecutionContext* scriptExecutionContext, const String& message)
+PassOwnPtr<MessagePortChannel> MessagePort::disentangle(ExceptionCode& ec)
{
- RefPtr<MessagePort> port1 = MessagePort::create(scriptExecutionContext);
- if (!m_entangledPort || !m_scriptExecutionContext)
- return port1;
- RefPtr<MessagePort> port2 = MessagePort::create(0);
-
- entangle(port1.get(), port2.get());
+ if (!m_entangledChannel)
+ ec = INVALID_STATE_ERR;
+ else {
+ m_entangledChannel->disentangle();
- m_entangledPort->m_messageQueue.append(EventData::create(message, port2));
- if (m_entangledPort->m_queueIsOpen && m_entangledPort->m_scriptExecutionContext)
- m_entangledPort->m_scriptExecutionContext->processMessagePortMessagesSoon();
- return port1;
+ // We can't receive any messages or generate any events, so remove ourselves from the list of active ports.
+ ASSERT(m_scriptExecutionContext);
+ m_scriptExecutionContext->destroyedMessagePort(this);
+ m_scriptExecutionContext = 0;
+ }
+ return m_entangledChannel.release();
}
-void MessagePort::start()
+// Invoked to notify us that there are messages available for this port.
+// This code may be called from another thread, and so should not call any non-threadsafe APIs (i.e. should not call into the entangled channel or access mutable variables).
+void MessagePort::messageAvailable()
{
- if (m_queueIsOpen || !m_scriptExecutionContext)
- return;
-
- m_queueIsOpen = true;
+ ASSERT(m_scriptExecutionContext);
m_scriptExecutionContext->processMessagePortMessagesSoon();
}
-void MessagePort::close()
+void MessagePort::start()
{
- if (!m_entangledPort)
+ // Do nothing if we've been cloned
+ if (!m_entangledChannel)
return;
- MessagePort* otherPort = m_entangledPort;
- unentangle();
+ ASSERT(m_scriptExecutionContext);
+ if (m_started)
+ return;
- queueCloseEvent();
- otherPort->queueCloseEvent();
+ m_started = true;
+ m_scriptExecutionContext->processMessagePortMessagesSoon();
}
-void MessagePort::entangle(MessagePort* port1, MessagePort* port2)
+void MessagePort::close()
{
- if (port1->m_entangledPort) {
- ASSERT(port1->m_entangledPort != port2);
- port1->unentangle();
- }
-
- if (port2->m_entangledPort) {
- ASSERT(port2->m_entangledPort != port1);
- port2->unentangle();
- }
-
- port1->m_entangledPort = port2;
- port2->m_entangledPort = port1;
+ if (!m_entangledChannel)
+ return;
+ m_entangledChannel->close();
}
-void MessagePort::unentangle()
+void MessagePort::entangle(PassOwnPtr<MessagePortChannel> remote)
{
- ASSERT(this == m_entangledPort->m_entangledPort);
+ // Only invoked to set our initial entanglement.
+ ASSERT(!m_entangledChannel);
+ ASSERT(m_scriptExecutionContext);
- m_entangledPort->m_entangledPort = 0;
- m_entangledPort = 0;
+ // Don't entangle the ports if the channel is closed.
+ if (remote->entangleIfOpen(this))
+ m_entangledChannel = remote;
}
void MessagePort::contextDestroyed()
{
ASSERT(m_scriptExecutionContext);
-
- if (m_entangledPort)
- unentangle();
-
+ // Must close port before blowing away the cached context, to ensure that we get no more calls to messageAvailable().
+ close();
m_scriptExecutionContext = 0;
}
-void MessagePort::attachToContext(ScriptExecutionContext* scriptExecutionContext)
-{
- ASSERT(!m_scriptExecutionContext);
- ASSERT(!m_queueIsOpen);
-
- m_scriptExecutionContext = scriptExecutionContext;
- m_scriptExecutionContext->createdMessagePort(this);
-
- // FIXME: Need to call processMessagePortMessagesSoon()?
-}
-
ScriptExecutionContext* MessagePort::scriptExecutionContext() const
{
return m_scriptExecutionContext;
@@ -236,17 +150,19 @@ ScriptExecutionContext* MessagePort::scriptExecutionContext() const
void MessagePort::dispatchMessages()
{
// Messages for contexts that are not fully active get dispatched too, but JSAbstractEventListener::handleEvent() doesn't call handlers for these.
- // FIXME: Such messages should be dispatched if the document returns from page cache. They are only allowed to be lost if the document is discarded.
- ASSERT(queueIsOpen());
-
- RefPtr<EventData> eventData;
- while (m_messageQueue.tryGetMessage(eventData)) {
-
- ASSERT(!eventData->messagePort || !eventData->messagePort->m_scriptExecutionContext);
- if (eventData->messagePort)
- eventData->messagePort->attachToContext(m_scriptExecutionContext);
-
- RefPtr<Event> evt = MessageEvent::create(eventData->message, "", "", 0, eventData->messagePort);
+ // The HTML5 spec specifies that any messages sent to a document that is not fully active should be dropped, so this behavior is OK.
+ ASSERT(started());
+
+ OwnPtr<MessagePortChannel::EventData> eventData;
+ while (m_entangledChannel && m_entangledChannel->tryGetMessageFromRemote(eventData)) {
+ RefPtr<MessagePort> port;
+ OwnPtr<MessagePortChannel> channel = eventData->channel();
+ if (channel) {
+ // The remote side sent over a MessagePortChannel, so create a MessagePort to wrap it.
+ port = MessagePort::create(*m_scriptExecutionContext);
+ port->entangle(channel.release());
+ }
+ RefPtr<Event> evt = MessageEvent::create(eventData->message(), "", "", 0, port.release());
if (m_onMessageListener) {
evt->setTarget(this);
@@ -260,31 +176,6 @@ void MessagePort::dispatchMessages()
}
}
-void MessagePort::queueCloseEvent()
-{
- ASSERT(!m_pendingCloseEvent);
- m_pendingCloseEvent = true;
-
- m_scriptExecutionContext->postTask(MessagePortCloseEventTask::create(this));
-}
-
-void MessagePort::dispatchCloseEvent()
-{
- ASSERT(m_pendingCloseEvent);
- m_pendingCloseEvent = false;
-
- RefPtr<Event> evt = Event::create(eventNames().closeEvent, false, true);
- if (m_onCloseListener) {
- evt->setTarget(this);
- evt->setCurrentTarget(this);
- m_onCloseListener->handleEvent(evt.get(), false);
- }
-
- ExceptionCode ec = 0;
- dispatchEvent(evt.release(), ec);
- ASSERT(!ec);
-}
-
void MessagePort::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
{
EventListenersMap::iterator iter = m_eventListeners.find(eventType);
@@ -336,9 +227,22 @@ bool MessagePort::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
return !event->defaultPrevented();
}
+void MessagePort::setOnmessage(PassRefPtr<EventListener> eventListener)
+{
+ m_onMessageListener = eventListener;
+ start();
+}
+
bool MessagePort::hasPendingActivity()
{
- return m_pendingCloseEvent || (m_queueIsOpen && !m_messageQueue.isEmpty());
+ // The spec says that entangled message ports should always be treated as if they have a strong reference.
+ // We'll also stipulate that the queue needs to be open (if the app drops its reference to the port before start()-ing it, then it's not really entangled as it's unreachable).
+ return m_started && m_entangledChannel && m_entangledChannel->hasPendingActivity();
+}
+
+MessagePort* MessagePort::locallyEntangledPort()
+{
+ return m_entangledChannel ? m_entangledChannel->locallyEntangledPort(m_scriptExecutionContext) : 0;
}
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.h b/src/3rdparty/webkit/WebCore/dom/MessagePort.h
index 19252a7..f416b9b 100644
--- a/src/3rdparty/webkit/WebCore/dom/MessagePort.h
+++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.h
@@ -30,9 +30,11 @@
#include "AtomicStringHash.h"
#include "EventListener.h"
#include "EventTarget.h"
+#include "MessagePortChannel.h"
#include <wtf/HashMap.h>
-#include <wtf/MessageQueue.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
@@ -44,35 +46,29 @@ namespace WebCore {
class Frame;
class ScriptExecutionContext;
class String;
- class WorkerContext;
class MessagePort : public RefCounted<MessagePort>, public EventTarget {
public:
- static PassRefPtr<MessagePort> create(ScriptExecutionContext* scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
+ static PassRefPtr<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
~MessagePort();
- PassRefPtr<MessagePort> clone(ExceptionCode&); // Returns a port that isn't attached to any context.
-
- bool active() const { return m_entangledPort; }
void postMessage(const String& message, ExceptionCode&);
void postMessage(const String& message, MessagePort*, ExceptionCode&);
- PassRefPtr<MessagePort> startConversation(ScriptExecutionContext*, const String& message);
void start();
void close();
- bool queueIsOpen() const { return m_queueIsOpen; }
+ void entangle(PassOwnPtr<MessagePortChannel>);
+ PassOwnPtr<MessagePortChannel> disentangle(ExceptionCode&);
- MessagePort* entangledPort() { return m_entangledPort; }
- static void entangle(MessagePort*, MessagePort*);
- void unentangle();
+ void messageAvailable();
+ bool started() const { return m_started; }
void contextDestroyed();
- void attachToContext(ScriptExecutionContext*);
+
virtual ScriptExecutionContext* scriptExecutionContext() const;
virtual MessagePort* toMessagePort() { return this; }
- void queueCloseEvent();
void dispatchMessages();
virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
@@ -88,47 +84,30 @@ namespace WebCore {
bool hasPendingActivity();
- // FIXME: Per current spec, setting onmessage should automagically start the port (unlike addEventListener("message", ...)).
- void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onMessageListener = eventListener; }
+ void setOnmessage(PassRefPtr<EventListener>);
EventListener* onmessage() const { return m_onMessageListener.get(); }
- void setOnclose(PassRefPtr<EventListener> eventListener) { m_onCloseListener = eventListener; }
- EventListener* onclose() const { return m_onCloseListener.get(); }
+ // Returns null if there is no entangled port, or if the entangled port is run by a different thread.
+ // Returns null otherwise.
+ // NOTE: This is used solely to enable a GC optimization. Some platforms may not be able to determine ownership of the remote port (since it may live cross-process) - those platforms may always return null.
+ MessagePort* locallyEntangledPort();
+ bool isEntangled() { return m_entangledChannel; }
private:
- friend class MessagePortCloseEventTask;
-
- MessagePort(ScriptExecutionContext*);
+ MessagePort(ScriptExecutionContext&);
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
- void dispatchCloseEvent();
-
- MessagePort* m_entangledPort;
+ OwnPtr<MessagePortChannel> m_entangledChannel;
- // FIXME: EventData is necessary to pass messages to other threads. In single threaded case, we can just queue a created event.
- struct EventData : public RefCounted<EventData> {
- static PassRefPtr<EventData> create(const String& message, PassRefPtr<MessagePort>);
- ~EventData();
-
- String message;
- RefPtr<MessagePort> messagePort;
-
- private:
- EventData(const String& message, PassRefPtr<MessagePort>);
- };
- MessageQueue<RefPtr<EventData> > m_messageQueue; // FIXME: No need to use MessageQueue in single threaded case.
- bool m_queueIsOpen;
+ bool m_started;
ScriptExecutionContext* m_scriptExecutionContext;
RefPtr<EventListener> m_onMessageListener;
- RefPtr<EventListener> m_onCloseListener;
EventListenersMap m_eventListeners;
-
- bool m_pendingCloseEvent; // The port is GC protected while waiting for a close event to be dispatched.
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.idl b/src/3rdparty/webkit/WebCore/dom/MessagePort.idl
index 2596c0f..e5f9ad1 100644
--- a/src/3rdparty/webkit/WebCore/dom/MessagePort.idl
+++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.idl
@@ -33,17 +33,14 @@ module events {
] MessagePort {
// We need to have something as an ObjC binding, because MessagePort is used in MessageEvent, which already has one,
// but we don't want to actually expose the API while it is in flux.
-#if defined(LANGUAGE_JAVASCRIPT)
- readonly attribute boolean active;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
void postMessage(in DOMString message, in [Optional] MessagePort messagePort)
raises(DOMException);
- [Custom] MessagePort startConversation(in DOMString message);
void start();
void close();
// event handler attributes
attribute EventListener onmessage;
- attribute EventListener onclose;
// EventTarget interface
[Custom] void addEventListener(in DOMString type,
diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePortChannel.cpp b/src/3rdparty/webkit/WebCore/dom/MessagePortChannel.cpp
new file mode 100644
index 0000000..768d4f4
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/MessagePortChannel.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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"
+#include "MessagePortChannel.h"
+
+#include "PlatformMessagePortChannel.h"
+
+namespace WebCore {
+
+PassOwnPtr<MessagePortChannel> MessagePortChannel::create(PassRefPtr<PlatformMessagePortChannel> channel)
+{
+ return new MessagePortChannel(channel);
+}
+
+PassOwnPtr<MessagePortChannel::EventData> MessagePortChannel::EventData::create(const String& message, PassOwnPtr<MessagePortChannel> channel)
+{
+ return new EventData(message, channel);
+}
+
+MessagePortChannel::EventData::EventData(const String& message, PassOwnPtr<MessagePortChannel> channel)
+ : m_message(message.copy())
+ , m_channel(channel)
+{
+}
+
+MessagePortChannel::MessagePortChannel(PassRefPtr<PlatformMessagePortChannel> channel)
+ : m_channel(channel)
+{
+}
+
+MessagePortChannel::~MessagePortChannel()
+{
+ // Make sure we close our platform channel when the base is freed, to keep the channel objects from leaking.
+ m_channel->close();
+}
+
+} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePortChannel.h b/src/3rdparty/webkit/WebCore/dom/MessagePortChannel.h
new file mode 100644
index 0000000..15b3d16
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/MessagePortChannel.h
@@ -0,0 +1,103 @@
+/*
+ * 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 MessagePortChannel_h
+#define MessagePortChannel_h
+
+#include "PlatformString.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class MessagePort;
+ class PlatformMessagePortChannel;
+ class ScriptExecutionContext;
+ class String;
+
+ // MessagePortChannel is a platform-independent interface to the remote side of a message channel.
+ // It acts as a wrapper around the platform-dependent PlatformMessagePortChannel implementation which ensures that the platform-dependent close() method is invoked before destruction.
+ class MessagePortChannel : Noncopyable {
+ public:
+ // Creates a new wrapper for the passed channel.
+ static PassOwnPtr<MessagePortChannel> create(PassRefPtr<PlatformMessagePortChannel>);
+
+ // Entangles the channel with a port (called when a port has been cloned, after the clone has been marshalled to its new owning thread and is ready to receive messages).
+ // Returns false if the entanglement failed because the port was closed.
+ bool entangleIfOpen(MessagePort*);
+
+ // Disentangles the channel from a given port so it no longer forwards messages to the port. Called when the port is being cloned and no new owning thread has yet been established.
+ void disentangle();
+
+ // Closes the port (ensures that no further messages can be added to either queue).
+ void close();
+
+ // Used by MessagePort.postMessage() to prevent callers from passing a port's own entangled port.
+ bool isConnectedTo(MessagePort*);
+
+ // Returns true if the proxy currently contains messages for this port.
+ bool hasPendingActivity();
+
+ class EventData {
+ public:
+ static PassOwnPtr<EventData> create(const String&, PassOwnPtr<MessagePortChannel>);
+
+ const String& message() { return m_message; }
+ PassOwnPtr<MessagePortChannel> channel() { return m_channel.release(); }
+
+ private:
+ EventData(const String& message, PassOwnPtr<MessagePortChannel>);
+ String m_message;
+ OwnPtr<MessagePortChannel> m_channel;
+ };
+
+ // Sends a message and optional cloned port to the remote port.
+ void postMessageToRemote(PassOwnPtr<EventData>);
+
+ // Extracts a message from the message queue for this port.
+ bool tryGetMessageFromRemote(OwnPtr<EventData>&);
+
+ // Returns the entangled port if run by the same thread (see MessagePort::locallyEntangledPort() for more details).
+ MessagePort* locallyEntangledPort(const ScriptExecutionContext*);
+
+ ~MessagePortChannel();
+
+ private:
+ MessagePortChannel(PassRefPtr<PlatformMessagePortChannel>);
+ RefPtr<PlatformMessagePortChannel> m_channel;
+ };
+
+} // namespace WebCore
+
+#endif // MessagePortChannel_h
diff --git a/src/3rdparty/webkit/WebCore/dom/MouseEvent.cpp b/src/3rdparty/webkit/WebCore/dom/MouseEvent.cpp
index 1c97522..bdd39d3 100644
--- a/src/3rdparty/webkit/WebCore/dom/MouseEvent.cpp
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/MouseEvent.h b/src/3rdparty/webkit/WebCore/dom/MouseEvent.h
index aa3eee5..7454b04 100644
--- a/src/3rdparty/webkit/WebCore/dom/MouseEvent.h
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/MouseEvent.idl b/src/3rdparty/webkit/WebCore/dom/MouseEvent.idl
index 3195a7a..c509459 100644
--- a/src/3rdparty/webkit/WebCore/dom/MouseEvent.idl
+++ b/src/3rdparty/webkit/WebCore/dom/MouseEvent.idl
@@ -58,7 +58,7 @@ module events {
readonly attribute Node fromElement;
readonly attribute Node toElement;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
readonly attribute Clipboard dataTransfer;
#endif
};
diff --git a/src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.cpp b/src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.cpp
index a69c8a7..4ed85ce 100644
--- a/src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.cpp
+++ b/src/3rdparty/webkit/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()
@@ -128,14 +138,15 @@ void MouseRelatedEvent::receivedTarget()
m_offsetY = m_pageY;
// Must have an updated render tree for this math to work correctly.
- targ->document()->updateRendering();
+ targ->document()->updateStyleIfNeeded();
// 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/src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.h b/src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.h
index 35c65dd..7649aa9 100644
--- a/src/3rdparty/webkit/WebCore/dom/MouseRelatedEvent.h
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/NamedAttrMap.cpp b/src/3rdparty/webkit/WebCore/dom/NamedAttrMap.cpp
index 8944b79..f3e9bb2 100644
--- a/src/3rdparty/webkit/WebCore/dom/NamedAttrMap.cpp
+++ b/src/3rdparty/webkit/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
@@ -23,8 +23,9 @@
*/
#include "config.h"
-#include "NamedAttrMap.h"
+#include "NamedNodeMap.h"
+#include "Attr.h"
#include "Document.h"
#include "Element.h"
#include "ExceptionCode.h"
@@ -39,17 +40,26 @@ static inline bool shouldIgnoreAttributeCase(const Element* e)
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
}
-NamedAttrMap::~NamedAttrMap()
+inline void NamedNodeMap::detachAttributesFromElement()
{
- NamedAttrMap::clearAttributes(); // virtual function, qualify to be explicit and slightly faster
+ 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;
+ }
+}
+
+NamedNodeMap::~NamedNodeMap()
+{
+ detachAttributesFromElement();
}
-bool NamedAttrMap::isMappedAttributeMap() const
+bool NamedNodeMap::isMappedAttributeMap() const
{
return false;
}
-PassRefPtr<Node> NamedAttrMap::getNamedItem(const String& name) const
+PassRefPtr<Node> NamedNodeMap::getNamedItem(const String& name) const
{
Attribute* a = getAttributeItem(name, shouldIgnoreAttributeCase(m_element));
if (!a)
@@ -58,12 +68,12 @@ PassRefPtr<Node> NamedAttrMap::getNamedItem(const String& name) const
return a->createAttrIfNeeded(m_element);
}
-PassRefPtr<Node> NamedAttrMap::getNamedItemNS(const String& namespaceURI, const String& localName) const
+PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const String& namespaceURI, const String& localName) const
{
return getNamedItem(QualifiedName(nullAtom, localName, namespaceURI));
}
-PassRefPtr<Node> NamedAttrMap::removeNamedItem(const String& name, ExceptionCode& ec)
+PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode& ec)
{
Attribute* a = getAttributeItem(name, shouldIgnoreAttributeCase(m_element));
if (!a) {
@@ -74,12 +84,12 @@ PassRefPtr<Node> NamedAttrMap::removeNamedItem(const String& name, ExceptionCode
return removeNamedItem(a->name(), ec);
}
-PassRefPtr<Node> NamedAttrMap::removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
+PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
{
return removeNamedItem(QualifiedName(nullAtom, localName, namespaceURI), ec);
}
-PassRefPtr<Node> NamedAttrMap::getNamedItem(const QualifiedName& name) const
+PassRefPtr<Node> NamedNodeMap::getNamedItem(const QualifiedName& name) const
{
Attribute* a = getAttributeItem(name);
if (!a)
@@ -88,7 +98,7 @@ PassRefPtr<Node> NamedAttrMap::getNamedItem(const QualifiedName& name) const
return a->createAttrIfNeeded(m_element);
}
-PassRefPtr<Node> NamedAttrMap::setNamedItem(Node* arg, ExceptionCode& ec)
+PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* arg, ExceptionCode& ec)
{
if (!m_element || !arg) {
ec = NOT_FOUND_ERR;
@@ -137,7 +147,7 @@ PassRefPtr<Node> NamedAttrMap::setNamedItem(Node* arg, ExceptionCode& ec)
// The DOM2 spec doesn't say that removeAttribute[NS] throws NOT_FOUND_ERR
// if the attribute is not found, but at this level we have to throw NOT_FOUND_ERR
// because of removeNamedItem, removeNamedItemNS, and removeAttributeNode.
-PassRefPtr<Node> NamedAttrMap::removeNamedItem(const QualifiedName& name, ExceptionCode& ec)
+PassRefPtr<Node> NamedNodeMap::removeNamedItem(const QualifiedName& name, ExceptionCode& ec)
{
Attribute* a = getAttributeItem(name);
if (!a) {
@@ -154,7 +164,7 @@ PassRefPtr<Node> NamedAttrMap::removeNamedItem(const QualifiedName& name, Except
return r.release();
}
-PassRefPtr<Node> NamedAttrMap::item (unsigned index) const
+PassRefPtr<Node> NamedNodeMap::item (unsigned index) const
{
if (index >= length())
return 0;
@@ -164,7 +174,7 @@ PassRefPtr<Node> NamedAttrMap::item (unsigned index) const
// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
// can tune the behaviour (hasAttribute is case sensitive whereas getAttribute is not).
-Attribute* NamedAttrMap::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
+Attribute* NamedNodeMap::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
{
unsigned len = length();
for (unsigned i = 0; i < len; ++i) {
@@ -178,7 +188,7 @@ Attribute* NamedAttrMap::getAttributeItem(const String& name, bool shouldIgnoreA
return 0;
}
-Attribute* NamedAttrMap::getAttributeItem(const QualifiedName& name) const
+Attribute* NamedNodeMap::getAttributeItem(const QualifiedName& name) const
{
unsigned len = length();
for (unsigned i = 0; i < len; ++i) {
@@ -188,25 +198,21 @@ Attribute* NamedAttrMap::getAttributeItem(const QualifiedName& name) const
return 0;
}
-void NamedAttrMap::clearAttributes()
+void NamedNodeMap::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();
}
-void NamedAttrMap::detachFromElement()
+void NamedNodeMap::detachFromElement()
{
- // we allow a NamedAttrMap w/o an element in case someone still has a reference
+ // we allow a NamedNodeMap w/o an element in case someone still has a reference
// to if after the element gets deleted - but the map is now invalid
m_element = 0;
- clearAttributes();
+ detachAttributesFromElement();
}
-void NamedAttrMap::setAttributes(const NamedAttrMap& other)
+void NamedNodeMap::setAttributes(const NamedNodeMap& other)
{
// clone all attributes in the other map, but attach to our element
if (!m_element)
@@ -228,13 +234,13 @@ void NamedAttrMap::setAttributes(const NamedAttrMap& other)
// FIXME: This is wasteful. The class list could be preserved on a copy, and we
// wouldn't have to waste time reparsing the attribute.
- // The derived class, HTMLNamedAttrMap, which manages a parsed class list for the CLASS attribute,
+ // The derived class, HTMLNamedNodeMap, which manages a parsed class list for the CLASS attribute,
// will update its member variable when parse attribute is called.
for (unsigned i = 0; i < newLength; i++)
m_element->attributeChanged(m_attributes[i].get(), true);
}
-void NamedAttrMap::addAttribute(PassRefPtr<Attribute> prpAttribute)
+void NamedNodeMap::addAttribute(PassRefPtr<Attribute> prpAttribute)
{
RefPtr<Attribute> attribute = prpAttribute;
@@ -256,7 +262,7 @@ void NamedAttrMap::addAttribute(PassRefPtr<Attribute> prpAttribute)
}
}
-void NamedAttrMap::removeAttribute(const QualifiedName& name)
+void NamedNodeMap::removeAttribute(const QualifiedName& name)
{
unsigned len = length();
unsigned index = len + 1;
@@ -290,7 +296,7 @@ void NamedAttrMap::removeAttribute(const QualifiedName& name)
}
}
-bool NamedAttrMap::mapsEquivalent(const NamedAttrMap* otherMap) const
+bool NamedNodeMap::mapsEquivalent(const NamedNodeMap* otherMap) const
{
if (!otherMap)
return false;
diff --git a/src/3rdparty/webkit/WebCore/dom/NamedAttrMap.h b/src/3rdparty/webkit/WebCore/dom/NamedAttrMap.h
index 693a9e5..4fb96de 100644
--- a/src/3rdparty/webkit/WebCore/dom/NamedAttrMap.h
+++ b/src/3rdparty/webkit/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
@@ -28,9 +26,6 @@
#define NamedAttrMap_h
#include "Attribute.h"
-#include "NamedNodeMap.h"
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
#ifdef __OBJC__
#define id id_AVOID_KEYWORD
@@ -38,43 +33,49 @@
namespace WebCore {
-// the map of attributes of an element
-class NamedAttrMap : public NamedNodeMap {
+class Node;
+
+typedef int ExceptionCode;
+
+class NamedNodeMap : public RefCounted<NamedNodeMap> {
friend class Element;
+
protected:
- NamedAttrMap(Element* element) : m_element(element) { }
-public:
- static PassRefPtr<NamedAttrMap> create(Element* element) { return adoptRef(new NamedAttrMap(element)); }
+ NamedNodeMap(Element* element) : m_element(element) { }
- virtual ~NamedAttrMap();
+public:
+ static PassRefPtr<NamedNodeMap> create(Element* element) { return adoptRef(new NamedNodeMap(element)); }
- void setAttributes(const NamedAttrMap&);
+ virtual ~NamedNodeMap();
- // DOM methods & attributes for NamedNodeMap
+ // Public DOM interface.
- virtual PassRefPtr<Node> getNamedItem(const String& name) const;
- virtual PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&);
+ PassRefPtr<Node> getNamedItem(const String& name) const;
+ 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&);
+ PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
+ 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&);
+ PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
+ PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
+ PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&);
+ PassRefPtr<Node> setNamedItemNS(Node* node, ExceptionCode& ec) { return setNamedItem(node, ec); }
- virtual PassRefPtr<Node> item(unsigned index) const;
+ PassRefPtr<Node> item(unsigned index) const;
size_t length() const { return m_attributes.size(); }
+ bool isEmpty() const { return !length(); }
+
+ // Internal interface.
+
+ void setAttributes(const NamedNodeMap&);
- // 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!
+ // Used during parsing: only inserts if not already there. No error checking!
void insertAttribute(PassRefPtr<Attribute> newAttribute, bool allowDuplicates)
{
ASSERT(!m_element);
@@ -85,18 +86,23 @@ public:
virtual bool isMappedAttributeMap() const;
const AtomicString& id() const { return m_id; }
- void setID(const AtomicString& _id) { m_id = _id; }
-
- bool mapsEquivalent(const NamedAttrMap* otherMap) const;
+ void setID(const AtomicString& newId) { m_id = newId; }
- // These functions are internal, and do no error checking.
+ bool mapsEquivalent(const NamedNodeMap* otherMap) const;
+
+ // 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;
Element* m_element;
Vector<RefPtr<Attribute> > m_attributes;
diff --git a/src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.cpp b/src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.cpp
index bc2d999..d8e3c80 100644
--- a/src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.cpp
@@ -27,6 +27,7 @@
#include "Document.h"
#include "Element.h"
+#include "MappedAttribute.h"
namespace WebCore {
@@ -34,7 +35,7 @@ void NamedMappedAttrMap::clearAttributes()
{
m_classNames.clear();
m_mappedAttributeCount = 0;
- NamedAttrMap::clearAttributes();
+ NamedNodeMap::clearAttributes();
}
bool NamedMappedAttrMap::isMappedAttributeMap() const
@@ -75,12 +76,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/src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.h b/src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.h
index c4deddc..0afa278 100644
--- a/src/3rdparty/webkit/WebCore/dom/NamedMappedAttrMap.h
+++ b/src/3rdparty/webkit/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,32 @@
#define NamedMappedAttrMap_h
#include "ClassNames.h"
-#include "MappedAttribute.h"
-#include "NamedAttrMap.h"
+#include "NamedNodeMap.h"
namespace WebCore {
-class NamedMappedAttrMap : public NamedAttrMap {
-private:
- NamedMappedAttrMap(Element* element) : NamedAttrMap(element), m_mappedAttributeCount(0) { }
+class NamedMappedAttrMap : public NamedNodeMap {
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) : NamedNodeMap(element), m_mappedAttributeCount(0) { }
+
+ virtual void clearAttributes();
+ virtual bool isMappedAttributeMap() const;
+
+ int declCount() const;
+
ClassNames m_classNames;
int m_mappedAttributeCount;
};
diff --git a/src/3rdparty/webkit/WebCore/dom/NamedNodeMap.h b/src/3rdparty/webkit/WebCore/dom/NamedNodeMap.h
index 504af69..37ef870 100644
--- a/src/3rdparty/webkit/WebCore/dom/NamedNodeMap.h
+++ b/src/3rdparty/webkit/WebCore/dom/NamedNodeMap.h
@@ -1,64 +1 @@
-/*
- * This file is part of the DOM implementation for KDE.
- *
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef NamedNodeMap_h
-#define NamedNodeMap_h
-
-#include <wtf/RefCounted.h>
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
-class Node;
-class QualifiedName;
-class String;
-
-typedef int ExceptionCode;
-
-// Generic NamedNodeMap interface
-// Other classes implement this for more specific situations e.g. attributes of an element.
-class NamedNodeMap : public RefCounted<NamedNodeMap> {
-public:
- virtual ~NamedNodeMap() { }
-
- virtual PassRefPtr<Node> getNamedItem(const String& name) const = 0;
- virtual PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&) = 0;
-
- virtual PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const = 0;
- PassRefPtr<Node> setNamedItemNS(Node* arg, ExceptionCode& ec) { return setNamedItem(arg, ec); }
- virtual PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&) = 0;
-
- // DOM methods & attributes for NamedNodeMap
- virtual PassRefPtr<Node> getNamedItem(const QualifiedName& attrName) const = 0;
- virtual PassRefPtr<Node> removeNamedItem(const QualifiedName& attrName, ExceptionCode&) = 0;
- virtual PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&) = 0;
-
- virtual PassRefPtr<Node> item(unsigned index) const = 0;
- virtual size_t length() const = 0;
-};
-
-} //namespace
-
-#endif
+#include "NamedAttrMap.h"
diff --git a/src/3rdparty/webkit/WebCore/dom/Node.cpp b/src/3rdparty/webkit/WebCore/dom/Node.cpp
index 6c1254f..3ddf4c0 100644
--- a/src/3rdparty/webkit/WebCore/dom/Node.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/Node.cpp
@@ -2,8 +2,9 @@
* 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)
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +25,7 @@
#include "config.h"
#include "Node.h"
+#include "Attr.h"
#include "CSSParser.h"
#include "CSSRule.h"
#include "CSSRuleList.h"
@@ -39,24 +41,59 @@
#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 "NamedNodeMap.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/PassOwnPtr.h>
#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/UnusedParam.h>
+
+#if ENABLE(DOM_STORAGE)
+#include "StorageEvent.h"
+#endif
+
+#if ENABLE(SVG)
+#include "SVGElementInstance.h"
+#include "SVGUseElement.h"
+#endif
+
+#if ENABLE(XHTMLMP)
+#include "HTMLNoScriptElement.h"
+#endif
#define DUMP_NODE_STATISTICS 0
@@ -66,6 +103,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);
@@ -120,7 +159,7 @@ void Node::dumpStatistics()
result.first->second++;
// AttributeMap stats
- if (NamedAttrMap* attrMap = element->attributes(true)) {
+ if (NamedNodeMap* attrMap = element->attributes(true)) {
attributes += attrMap->length();
++attrMaps;
if (attrMap->isMappedAttributeMap())
@@ -217,7 +256,7 @@ void Node::dumpStatistics()
printf(" Number of MappedAttributes: %zu [%zu]\n", mappedAttributes, sizeof(MappedAttribute));
printf(" Number of MappedAttributes with a StyleDeclaration: %zu\n", mappedAttributesWithStyleDecl);
printf(" Number of Attributes with an Attr: %zu\n", attributesWithAttr);
- printf(" Number of NamedAttrMaps: %zu\n", attrMaps);
+ printf(" Number of NamedNodeMaps: %zu\n", attrMaps);
printf(" Number of NamedMappedAttrMap: %zu\n", mappedAttrMaps);
#endif
}
@@ -243,16 +282,16 @@ void Node::stopIgnoringLeaks()
#endif
}
-Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 )
+Node::StyleChange Node::diff(const RenderStyle* s1, const RenderStyle* s2)
{
// FIXME: The behavior of this function is just totally wrong. It doesn't handle
// explicit inheritance of non-inherited properties and so you end up not re-resolving
// 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;
@@ -263,23 +302,29 @@ Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 )
else if (s1->inheritedNotEqual(s2))
ch = Inherit;
+ // For nth-child and other positional rules, treat styles as different if they have
+ // changed positionally in the DOM. This way subsequent sibling resolutions won't be confused
+ // by the wrong child index and evaluate to incorrect results.
+ if (ch == NoChange && s1->childIndex() != s2->childIndex())
+ ch = NoInherit;
+
// 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;
}
}
@@ -287,7 +332,7 @@ Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 )
return ch;
}
-Node::Node(Document* doc, bool isElement, bool isContainer)
+Node::Node(Document* doc, bool isElement, bool isContainer, bool isText)
: m_document(doc)
, m_previous(0)
, m_next(0)
@@ -296,7 +341,7 @@ Node::Node(Document* doc, bool isElement, bool isContainer)
, m_hasId(false)
, m_hasClass(false)
, m_attached(false)
- , m_hasChangedChild(false)
+ , m_childNeedsStyleRecalc(false)
, m_inDocument(false)
, m_isLink(false)
, m_active(false)
@@ -307,6 +352,7 @@ Node::Node(Document* doc, bool isElement, bool isContainer)
, m_hasRareData(false)
, m_isElement(isElement)
, m_isContainer(isContainer)
+ , m_isText(isText)
, m_parsingChildrenFinished(true)
#if ENABLE(SVG)
, m_areSVGAttributesValid(true)
@@ -342,6 +388,9 @@ Node::~Node()
liveNodeSet.remove(this);
#endif
+ if (!eventListeners().isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
if (!hasRareData())
ASSERT(!NodeRareData::rareDataMap().contains(this));
else {
@@ -364,18 +413,51 @@ Node::~Node()
m_next->setPreviousSibling(0);
}
-void Node::setDocument(Document* doc)
+#ifdef NDEBUG
+
+static inline void setWillMoveToNewOwnerDocumentWasCalled(bool)
+{
+}
+
+static inline void setDidMoveToNewOwnerDocumentWasCalled(bool)
{
- if (inDocument() || m_document == doc)
+}
+
+#else
+
+static bool willMoveToNewOwnerDocumentWasCalled;
+static bool didMoveToNewOwnerDocumentWasCalled;
+
+static void setWillMoveToNewOwnerDocumentWasCalled(bool wasCalled)
+{
+ willMoveToNewOwnerDocumentWasCalled = wasCalled;
+}
+
+static void setDidMoveToNewOwnerDocumentWasCalled(bool wasCalled)
+{
+ didMoveToNewOwnerDocumentWasCalled = wasCalled;
+}
+
+#endif
+
+void Node::setDocument(Document* document)
+{
+ if (inDocument() || m_document == document)
return;
+ setWillMoveToNewOwnerDocumentWasCalled(false);
willMoveToNewOwnerDocument();
+ ASSERT(willMoveToNewOwnerDocumentWasCalled);
- updateDOMNodeDocument(this, m_document.get(), doc);
+#if USE(JSC)
+ updateDOMNodeDocument(this, m_document.get(), document);
+#endif
- m_document = doc;
+ m_document = document;
+ setDidMoveToNewOwnerDocumentWasCalled(false);
didMoveToNewOwnerDocument();
+ ASSERT(didMoveToNewOwnerDocumentWasCalled);
}
NodeRareData* Node::rareData() const
@@ -431,7 +513,7 @@ PassRefPtr<NodeList> Node::childNodes()
{
NodeRareData* data = ensureRareData();
if (!data->nodeLists()) {
- data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));
+ data->setNodeLists(NodeListsNodeData::create());
document()->addNodeListCache();
}
@@ -491,43 +573,57 @@ void Node::remove(ExceptionCode& ec)
void Node::normalize()
{
// Go through the subtree beneath us, normalizing all nodes. This means that
- // any two adjacent text nodes are merged together.
+ // any two adjacent text nodes are merged and any empty text nodes are removed.
RefPtr<Node> node = this;
while (Node* firstChild = node->firstChild())
node = firstChild;
- for (; node; node = node->traverseNextNodePostOrder()) {
+ while (node) {
NodeType type = node->nodeType();
if (type == ELEMENT_NODE)
static_cast<Element*>(node.get())->normalizeAttributes();
- Node* firstChild = node->firstChild();
- if (firstChild && !firstChild->nextSibling() && firstChild->isTextNode()) {
- Text* text = static_cast<Text*>(firstChild);
- if (!text->length()) {
- ExceptionCode ec;
- text->remove(ec);
- }
- }
-
if (node == this)
break;
- if (type == TEXT_NODE) {
- while (1) {
- Node* nextSibling = node->nextSibling();
- if (!nextSibling || !nextSibling->isTextNode())
- break;
- // Current child and the next one are both text nodes. Merge them.
- Text* text = static_cast<Text*>(node.get());
- RefPtr<Text> nextText = static_cast<Text*>(nextSibling);
- unsigned offset = text->length();
+ if (type != TEXT_NODE) {
+ node = node->traverseNextNodePostOrder();
+ continue;
+ }
+
+ Text* text = static_cast<Text*>(node.get());
+
+ // Remove empty text nodes.
+ if (!text->length()) {
+ // Care must be taken to get the next node before removing the current node.
+ node = node->traverseNextNodePostOrder();
+ ExceptionCode ec;
+ text->remove(ec);
+ continue;
+ }
+
+ // Merge text nodes.
+ while (Node* nextSibling = node->nextSibling()) {
+ if (!nextSibling->isTextNode())
+ break;
+ RefPtr<Text> nextText = static_cast<Text*>(nextSibling);
+
+ // Remove empty text nodes.
+ if (!nextText->length()) {
ExceptionCode ec;
- text->appendData(nextText->data(), ec);
- document()->textNodesMerged(nextText.get(), offset);
nextText->remove(ec);
+ continue;
}
+
+ // Both non-empty text nodes. Merge them.
+ unsigned offset = text->length();
+ ExceptionCode ec;
+ text->appendData(nextText->data(), ec);
+ document()->textNodesMerged(nextText.get(), offset);
+ nextText->remove(ec);
}
+
+ node = node->traverseNextNodePostOrder();
}
}
@@ -575,18 +671,25 @@ bool Node::shouldUseInputMethod() const
return isContentEditable();
}
+RenderBox* Node::renderBox() const
+{
+ 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
{
// FIXME: broken with transforms
- if (renderer()) {
- FloatPoint absPos = renderer()->localToAbsolute();
- return IntRect(roundedIntPoint(absPos),
- IntSize(renderer()->width(), renderer()->height() + renderer()->borderTopExtra() + renderer()->borderBottomExtra()));
- }
+ if (renderer())
+ return renderer()->absoluteBoundingBoxRect();
return IntRect();
}
-void Node::setChanged(StyleChangeType changeType)
+void Node::setNeedsStyleRecalc(StyleChangeType changeType)
{
if ((changeType != NoStyleChange) && !attached()) // changed compared to what?
return;
@@ -595,9 +698,10 @@ void Node::setChanged(StyleChangeType changeType)
m_styleChange = changeType;
if (m_styleChange != NoStyleChange) {
- for (Node* p = parentNode(); p && !p->hasChangedChild(); p = p->parentNode())
- p->setHasChangedChild(true);
- document()->setDocumentChanged(true);
+ for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
+ p->setChildNeedsStyleRecalc(true);
+ if (document()->childNeedsStyleRecalc())
+ document()->scheduleStyleRecalc();
}
}
@@ -619,7 +723,7 @@ void Node::lazyAttach()
}
if (n->firstChild())
- n->setHasChangedChild(true);
+ n->setChildNeedsStyleRecalc(true);
n->m_styleChange = FullStyleChange;
n->m_attached = true;
}
@@ -630,9 +734,10 @@ void Node::lazyAttach()
lazyAttachedAncestor->detach();
lazyAttachedAncestor->attach();
} else {
- for (Node* p = parentNode(); p && !p->hasChangedChild(); p = p->parentNode())
- p->setHasChangedChild(true);
- document()->setDocumentChanged(true);
+ for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
+ p->setChildNeedsStyleRecalc(true);
+ if (document()->childNeedsStyleRecalc())
+ document()->scheduleStyleRecalc();
}
}
@@ -681,7 +786,7 @@ void Node::registerDynamicNodeList(DynamicNodeList* list)
{
NodeRareData* data = ensureRareData();
if (!data->nodeLists()) {
- data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));
+ data->setNodeLists(NodeListsNodeData::create());
document()->addNodeListCache();
} else if (!m_document->hasNodeListCaches()) {
// We haven't been receiving notifications while there were no registered lists, so the cache is invalid now.
@@ -1073,21 +1178,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();
@@ -1198,7 +1288,7 @@ void Node::createRendererIfNeeded()
RenderObject* parentRenderer = parent->renderer();
if (parentRenderer && parentRenderer->canHaveChildren()
-#if ENABLE(SVG)
+#if ENABLE(SVG) || ENABLE(XHTMLMP)
&& parent->childShouldCreateRenderer(this)
#endif
) {
@@ -1219,8 +1309,14 @@ void Node::createRendererIfNeeded()
PassRefPtr<RenderStyle> Node::styleForRenderer()
{
- if (isElementNode())
- return document()->styleSelector()->styleForElement(static_cast<Element*>(this));
+ if (isElementNode()) {
+ bool allowSharing = true;
+#if ENABLE(XHTMLMP)
+ // noscript needs the display property protected - it's a special case
+ allowSharing = localName() != HTMLNames::noscriptTag.localName();
+#endif
+ return document()->styleSelector()->styleForElement(static_cast<Element*>(this), 0, allowSharing);
+ }
return parentNode() && parentNode()->renderer() ? parentNode()->renderer()->style() : 0;
}
@@ -1263,6 +1359,14 @@ bool Node::canStartSelection() const
{
if (isContentEditable())
return true;
+
+ if (renderer()) {
+ RenderStyle* style = renderer()->style();
+ // We allow selections to begin within an element that has -webkit-user-select: none set,
+ // but if the element is draggable then dragging should take priority over selection.
+ if (style->userDrag() == DRAG_ELEMENT && style->userSelect() == SELECT_NONE)
+ return false;
+ }
return parent() ? parent()->canStartSelection() : true;
}
@@ -1309,7 +1413,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
@@ -1384,7 +1488,7 @@ PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceU
NodeRareData* data = ensureRareData();
if (!data->nodeLists()) {
- data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));
+ data->setNodeLists(NodeListsNodeData::create());
document()->addNodeListCache();
}
@@ -1405,7 +1509,7 @@ PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
{
NodeRareData* data = ensureRareData();
if (!data->nodeLists()) {
- data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));
+ data->setNodeLists(NodeListsNodeData::create());
document()->addNodeListCache();
}
@@ -1420,7 +1524,7 @@ PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
{
NodeRareData* data = ensureRareData();
if (!data->nodeLists()) {
- data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));
+ data->setNodeLists(NodeListsNodeData::create());
document()->addNodeListCache();
}
@@ -1585,8 +1689,8 @@ bool Node::isEqualNode(Node *other) const
if (nodeValue() != other->nodeValue())
return false;
- NamedAttrMap *attrs = attributes();
- NamedAttrMap *otherAttrs = other->attributes();
+ NamedNodeMap *attrs = attributes();
+ NamedNodeMap *otherAttrs = other->attributes();
if (!attrs && otherAttrs)
return false;
@@ -1627,7 +1731,7 @@ bool Node::isDefaultNamespace(const AtomicString &namespaceURI) const
return elem->namespaceURI() == namespaceURI;
if (elem->hasAttributes()) {
- NamedAttrMap *attrs = elem->attributes();
+ NamedNodeMap *attrs = elem->attributes();
for (unsigned i = 0; i < attrs->length(); i++) {
Attribute *attr = attrs->attributeItem(i);
@@ -1713,7 +1817,7 @@ String Node::lookupNamespaceURI(const String &prefix) const
return elem->namespaceURI();
if (elem->hasAttributes()) {
- NamedAttrMap *attrs = elem->attributes();
+ NamedNodeMap *attrs = elem->attributes();
for (unsigned i = 0; i < attrs->length(); i++) {
Attribute *attr = attrs->attributeItem(i);
@@ -1768,7 +1872,7 @@ String Node::lookupNamespacePrefix(const AtomicString &_namespaceURI, const Elem
return prefix();
if (hasAttributes()) {
- NamedAttrMap *attrs = attributes();
+ NamedNodeMap *attrs = attributes();
for (unsigned i = 0; i < attrs->length(); i++) {
Attribute *attr = attrs->attributeItem(i);
@@ -1909,7 +2013,7 @@ unsigned short Node::compareDocumentPosition(Node* otherNode)
if (attr1 && attr2 && start1 == start2 && start1) {
// We are comparing two attributes on the same node. Crawl our attribute map
// and see which one we hit first.
- NamedAttrMap* map = attr1->ownerElement()->attributes(true);
+ NamedNodeMap* map = attr1->ownerElement()->attributes(true);
unsigned length = map->length();
for (unsigned i = 0; i < length; ++i) {
// If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an
@@ -1976,6 +2080,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;
+}
+
#ifndef NDEBUG
static void appendAttributeDesc(const Node* node, String& string, const QualifiedName& name, const char* attrDesc)
@@ -2112,6 +2246,1047 @@ ContainerNode* Node::eventParentNode()
// --------
+ScriptExecutionContext* Node::scriptExecutionContext() const
+{
+ return document();
+}
+
+const RegisteredEventListenerVector& Node::eventListeners() const
+{
+ if (hasRareData()) {
+ if (RegisteredEventListenerVector* listeners = rareData()->listeners())
+ return *listeners;
+ }
+ static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector;
+ return *emptyListenersVector;
+}
+
+void Node::insertedIntoDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ setInDocument(true);
+}
+
+void Node::removedFromDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->registerDisconnectedNodeWithEventListeners(this);
+
+ setInDocument(false);
+}
+
+void Node::willMoveToNewOwnerDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ ASSERT(!willMoveToNewOwnerDocumentWasCalled);
+ setWillMoveToNewOwnerDocumentWasCalled(true);
+}
+
+void Node::didMoveToNewOwnerDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->registerDisconnectedNodeWithEventListeners(this);
+
+ ASSERT(!didMoveToNewOwnerDocumentWasCalled);
+ setDidMoveToNewOwnerDocumentWasCalled(true);
+}
+
+static inline void updateSVGElementInstancesAfterEventListenerChange(Node* referenceNode)
+{
+#if !ENABLE(SVG)
+ UNUSED_PARAM(referenceNode);
+#else
+ ASSERT(referenceNode);
+ 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);
+}
+
+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);
+ return;
+ }
+ }
+}
+
+void Node::removeAllEventListenersSlowCase()
+{
+ ASSERT(hasRareData());
+
+ RegisteredEventListenerVector* listeners = rareData()->listeners();
+ if (!listeners)
+ return;
+
+ 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 / where 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.
+ DOMWindow* targetForWindowEvents = 0;
+ if (event->type() != eventNames().loadEvent) {
+ Node* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get();
+ if (topLevelContainer->isDocumentNode())
+ targetForWindowEvents = static_cast<Document*>(topLevelContainer)->domWindow();
+ }
+
+ // 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 (targetForWindowEvents) {
+ event->setCurrentTarget(targetForWindowEvents);
+ targetForWindowEvents->handleEvent(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 (targetForWindowEvents) {
+ event->setCurrentTarget(targetForWindowEvents);
+ targetForWindowEvents->handleEvent(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::updateStyleForAllDocuments();
+
+ return !event->defaultPrevented();
+}
+
+void 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;
+
+ ExceptionCode ec = 0;
+ dispatchMutationEvent(eventNames().DOMSubtreeModifiedEvent, true, 0, String(), String(), ec);
+}
+
+void 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);
+ 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, 0);
+}
+
+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();
+}
+
+void Node::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ ExceptionCode ec = 0;
+ dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec);
+}
+
+void Node::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ ExceptionCode ec = 0;
+ dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec);
+}
+
+void Node::dispatchMutationEvent(const AtomicString& eventType, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode& ec)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ dispatchEvent(MutationEvent::create(eventType, canBubble, false, relatedNode, prevValue, newValue, String(), 0), ec);
+}
+
+void Node::dispatchFocusEvent()
+{
+ dispatchEvent(eventNames().focusEvent, false, false);
+}
+
+void Node::dispatchBlurEvent()
+{
+ dispatchEvent(eventNames().blurEvent, false, false);
+}
+
+bool Node::dispatchEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec);
+}
+
+void Node::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec);
+}
+
+void Node::clearAttributeEventListener(const AtomicString& eventType)
+{
+ if (!hasRareData())
+ return;
+
+ RegisteredEventListenerVector* listeners = rareData()->listeners();
+ if (!listeners)
+ return;
+
+ size_t size = listeners->size();
+ for (size_t i = 0; i < size; ++i) {
+ RegisteredEventListener& r = *listeners->at(i);
+ if (r.eventType() != eventType || !r.listener()->isAttribute())
+ continue;
+
+ r.setRemoved(true);
+ listeners->remove(i);
+
+ // removed last
+ if (listeners->isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ updateSVGElementInstancesAfterEventListenerChange(this);
+ return;
+ }
+}
+
+void Node::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+{
+ clearAttributeEventListener(eventType);
+ if (listener)
+ addEventListener(eventType, listener, false);
+}
+
+EventListener* Node::getAttributeEventListener(const AtomicString& eventType) const
+{
+ const RegisteredEventListenerVector& listeners = eventListeners();
+ size_t size = listeners.size();
+ for (size_t i = 0; i < size; ++i) {
+ const RegisteredEventListener& r = *listeners[i];
+ if (r.eventType() == eventType && r.listener()->isAttribute())
+ return r.listener();
+ }
+ return 0;
+}
+
+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 getAttributeEventListener(eventNames().abortEvent);
+}
+
+void Node::setOnabort(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().abortEvent, eventListener);
+}
+
+EventListener* Node::onblur() const
+{
+ return getAttributeEventListener(eventNames().blurEvent);
+}
+
+void Node::setOnblur(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().blurEvent, eventListener);
+}
+
+EventListener* Node::onchange() const
+{
+ return getAttributeEventListener(eventNames().changeEvent);
+}
+
+void Node::setOnchange(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().changeEvent, eventListener);
+}
+
+EventListener* Node::onclick() const
+{
+ return getAttributeEventListener(eventNames().clickEvent);
+}
+
+void Node::setOnclick(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().clickEvent, eventListener);
+}
+
+EventListener* Node::oncontextmenu() const
+{
+ return getAttributeEventListener(eventNames().contextmenuEvent);
+}
+
+void Node::setOncontextmenu(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().contextmenuEvent, eventListener);
+}
+
+EventListener* Node::ondblclick() const
+{
+ return getAttributeEventListener(eventNames().dblclickEvent);
+}
+
+void Node::setOndblclick(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dblclickEvent, eventListener);
+}
+
+EventListener* Node::onerror() const
+{
+ return getAttributeEventListener(eventNames().errorEvent);
+}
+
+void Node::setOnerror(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().errorEvent, eventListener);
+}
+
+EventListener* Node::onfocus() const
+{
+ return getAttributeEventListener(eventNames().focusEvent);
+}
+
+void Node::setOnfocus(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().focusEvent, eventListener);
+}
+
+EventListener* Node::oninput() const
+{
+ return getAttributeEventListener(eventNames().inputEvent);
+}
+
+void Node::setOninput(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().inputEvent, eventListener);
+}
+
+EventListener* Node::onkeydown() const
+{
+ return getAttributeEventListener(eventNames().keydownEvent);
+}
+
+void Node::setOnkeydown(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().keydownEvent, eventListener);
+}
+
+EventListener* Node::onkeypress() const
+{
+ return getAttributeEventListener(eventNames().keypressEvent);
+}
+
+void Node::setOnkeypress(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().keypressEvent, eventListener);
+}
+
+EventListener* Node::onkeyup() const
+{
+ return getAttributeEventListener(eventNames().keyupEvent);
+}
+
+void Node::setOnkeyup(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().keyupEvent, eventListener);
+}
+
+EventListener* Node::onload() const
+{
+ return getAttributeEventListener(eventNames().loadEvent);
+}
+
+void Node::setOnload(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().loadEvent, eventListener);
+}
+
+EventListener* Node::onmousedown() const
+{
+ return getAttributeEventListener(eventNames().mousedownEvent);
+}
+
+void Node::setOnmousedown(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().mousedownEvent, eventListener);
+}
+
+EventListener* Node::onmousemove() const
+{
+ return getAttributeEventListener(eventNames().mousemoveEvent);
+}
+
+void Node::setOnmousemove(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().mousemoveEvent, eventListener);
+}
+
+EventListener* Node::onmouseout() const
+{
+ return getAttributeEventListener(eventNames().mouseoutEvent);
+}
+
+void Node::setOnmouseout(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().mouseoutEvent, eventListener);
+}
+
+EventListener* Node::onmouseover() const
+{
+ return getAttributeEventListener(eventNames().mouseoverEvent);
+}
+
+void Node::setOnmouseover(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().mouseoverEvent, eventListener);
+}
+
+EventListener* Node::onmouseup() const
+{
+ return getAttributeEventListener(eventNames().mouseupEvent);
+}
+
+void Node::setOnmouseup(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().mouseupEvent, eventListener);
+}
+
+EventListener* Node::onmousewheel() const
+{
+ return getAttributeEventListener(eventNames().mousewheelEvent);
+}
+
+void Node::setOnmousewheel(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().mousewheelEvent, eventListener);
+}
+
+EventListener* Node::ondragenter() const
+{
+ return getAttributeEventListener(eventNames().dragenterEvent);
+}
+
+void Node::setOndragenter(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dragenterEvent, eventListener);
+}
+
+EventListener* Node::ondragover() const
+{
+ return getAttributeEventListener(eventNames().dragoverEvent);
+}
+
+void Node::setOndragover(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dragoverEvent, eventListener);
+}
+
+EventListener* Node::ondragleave() const
+{
+ return getAttributeEventListener(eventNames().dragleaveEvent);
+}
+
+void Node::setOndragleave(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dragleaveEvent, eventListener);
+}
+
+EventListener* Node::ondrop() const
+{
+ return getAttributeEventListener(eventNames().dropEvent);
+}
+
+void Node::setOndrop(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dropEvent, eventListener);
+}
+
+EventListener* Node::ondragstart() const
+{
+ return getAttributeEventListener(eventNames().dragstartEvent);
+}
+
+void Node::setOndragstart(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dragstartEvent, eventListener);
+}
+
+EventListener* Node::ondrag() const
+{
+ return getAttributeEventListener(eventNames().dragEvent);
+}
+
+void Node::setOndrag(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dragEvent, eventListener);
+}
+
+EventListener* Node::ondragend() const
+{
+ return getAttributeEventListener(eventNames().dragendEvent);
+}
+
+void Node::setOndragend(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().dragendEvent, eventListener);
+}
+
+EventListener* Node::onscroll() const
+{
+ return getAttributeEventListener(eventNames().scrollEvent);
+}
+
+void Node::setOnscroll(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().scrollEvent, eventListener);
+}
+
+EventListener* Node::onselect() const
+{
+ return getAttributeEventListener(eventNames().selectEvent);
+}
+
+void Node::setOnselect(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().selectEvent, eventListener);
+}
+
+EventListener* Node::onsubmit() const
+{
+ return getAttributeEventListener(eventNames().submitEvent);
+}
+
+void Node::setOnsubmit(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().submitEvent, eventListener);
+}
+
+EventListener* Node::onbeforecut() const
+{
+ return getAttributeEventListener(eventNames().beforecutEvent);
+}
+
+void Node::setOnbeforecut(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().beforecutEvent, eventListener);
+}
+
+EventListener* Node::oncut() const
+{
+ return getAttributeEventListener(eventNames().cutEvent);
+}
+
+void Node::setOncut(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().cutEvent, eventListener);
+}
+
+EventListener* Node::onbeforecopy() const
+{
+ return getAttributeEventListener(eventNames().beforecopyEvent);
+}
+
+void Node::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().beforecopyEvent, eventListener);
+}
+
+EventListener* Node::oncopy() const
+{
+ return getAttributeEventListener(eventNames().copyEvent);
+}
+
+void Node::setOncopy(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().copyEvent, eventListener);
+}
+
+EventListener* Node::onbeforepaste() const
+{
+ return getAttributeEventListener(eventNames().beforepasteEvent);
+}
+
+void Node::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().beforepasteEvent, eventListener);
+}
+
+EventListener* Node::onpaste() const
+{
+ return getAttributeEventListener(eventNames().pasteEvent);
+}
+
+void Node::setOnpaste(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().pasteEvent, eventListener);
+}
+
+EventListener* Node::onreset() const
+{
+ return getAttributeEventListener(eventNames().resetEvent);
+}
+
+void Node::setOnreset(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().resetEvent, eventListener);
+}
+
+EventListener* Node::onsearch() const
+{
+ return getAttributeEventListener(eventNames().searchEvent);
+}
+
+void Node::setOnsearch(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().searchEvent, eventListener);
+}
+
+EventListener* Node::onselectstart() const
+{
+ return getAttributeEventListener(eventNames().selectstartEvent);
+}
+
+void Node::setOnselectstart(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().selectstartEvent, eventListener);
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/src/3rdparty/webkit/WebCore/dom/Node.h b/src/3rdparty/webkit/WebCore/dom/Node.h
index 5478b86..ab743f4 100644
--- a/src/3rdparty/webkit/WebCore/dom/Node.h
+++ b/src/3rdparty/webkit/WebCore/dom/Node.h
@@ -2,7 +2,8 @@
* 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, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,9 +26,12 @@
#define Node_h
#include "DocPtr.h"
+#include "EventTarget.h"
#include "KURLHash.h"
#include "PlatformString.h"
+#include "RegisteredEventListener.h"
#include "TreeShared.h"
+#include "FloatPoint.h"
#include <wtf/Assertions.h>
#include <wtf/ListHashSet.h>
#include <wtf/OwnPtr.h>
@@ -36,26 +40,31 @@
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 NamedNodeMap;
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;
@@ -70,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 {
@@ -97,9 +106,9 @@ public:
static void dumpStatistics();
enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
- static StyleChange diff(RenderStyle*, RenderStyle*);
+ static StyleChange diff(const RenderStyle*, const RenderStyle*);
- Node(Document*, bool isElement = false, bool isContainer = false);
+ Node(Document*, bool isElement = false, bool isContainer = false, bool isText = false);
virtual ~Node();
// DOM methods & attributes for Node
@@ -117,7 +126,7 @@ public:
Node* firstChild() const { return isContainerNode() ? containerFirstChild() : 0; }
Node* lastChild() const { return isContainerNode() ? containerLastChild() : 0; }
bool hasAttributes() const;
- NamedAttrMap* attributes() const;
+ NamedNodeMap* attributes() const;
virtual KURL baseURI() const;
@@ -157,6 +166,8 @@ public:
bool isElementNode() const { return m_isElement; }
bool isContainerNode() const { return m_isContainer; }
+ bool isTextNode() const { return m_isText; }
+
virtual bool isHTMLElement() const { return false; }
#if ENABLE(SVG)
@@ -174,11 +185,9 @@ public:
virtual bool isStyledElement() const { return false; }
virtual bool isFrameOwnerElement() const { return false; }
virtual bool isAttributeNode() const { return false; }
- virtual bool isTextNode() const { return false; }
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();
@@ -256,16 +265,16 @@ public:
bool focused() const { return hasRareData() ? rareDataFocused() : false; }
bool attached() const { return m_attached; }
void setAttached(bool b = true) { m_attached = b; }
- bool changed() const { return m_styleChange != NoStyleChange; }
+ bool needsStyleRecalc() const { return m_styleChange != NoStyleChange; }
StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_styleChange); }
- bool hasChangedChild() const { return m_hasChangedChild; }
+ bool childNeedsStyleRecalc() const { return m_childNeedsStyleRecalc; }
bool isLink() const { return m_isLink; }
void setHasID(bool b = true) { m_hasId = b; }
void setHasClass(bool b = true) { m_hasClass = b; }
- void setHasChangedChild( bool b = true ) { m_hasChangedChild = b; }
+ void setChildNeedsStyleRecalc(bool b = true) { m_childNeedsStyleRecalc = b; }
void setInDocument(bool b = true) { m_inDocument = b; }
void setInActiveChain(bool b = true) { m_inActiveChain = b; }
- void setChanged(StyleChangeType changeType = FullStyleChange);
+ void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
void setIsLink(bool b = true) { m_isLink = b; }
bool inSubtreeMark() const { return m_inSubtreeMark; }
@@ -288,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;
@@ -314,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*);
@@ -373,6 +374,10 @@ public:
RenderObject* previousRenderer();
void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
+ // 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;
@@ -399,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
@@ -419,7 +428,7 @@ public:
void createRendererIfNeeded();
PassRefPtr<RenderStyle> styleForRenderer();
virtual bool rendererIsNeeded(RenderStyle*);
-#if ENABLE(SVG)
+#if ENABLE(SVG) || ENABLE(XHTMLMP)
virtual bool childShouldCreateRenderer(Node*) const { return true; }
#endif
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
@@ -491,8 +500,8 @@ public:
unsigned short compareDocumentPosition(Node*);
protected:
- virtual void willMoveToNewOwnerDocument() { }
- virtual void didMoveToNewOwnerDocument() { }
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
void setTabIndexExplicitly(short);
@@ -502,6 +511,153 @@ protected:
NodeRareData* rareData() const;
NodeRareData* ensureRareData();
+public:
+ virtual Node* toNode() { return this; }
+
+ virtual ScriptExecutionContext* scriptExecutionContext() const;
+
+ // Used for standard DOM addEventListener / removeEventListener APIs.
+ virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+ virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+
+ // Used for legacy "onEvent" property APIs.
+ void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+ void clearAttributeEventListener(const AtomicString& eventType);
+ EventListener* getAttributeEventListener(const AtomicString& eventType) const;
+
+ virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
+ bool dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
+
+ void removeAllEventListeners() { if (hasRareData()) removeAllEventListenersSlowCase(); }
+
+ void dispatchSubtreeModifiedEvent();
+ void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent);
+ 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, Node* relatedTarget, PassRefPtr<Event> underlyingEvent);
+ void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent);
+ void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
+ void dispatchProgressEvent(const AtomicString& eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg);
+ void dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime);
+ void dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime);
+ void dispatchMutationEvent(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode&);
+
+ bool dispatchGenericEvent(PassRefPtr<Event>);
+
+ virtual void handleLocalEvents(Event*, bool useCapture);
+
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+
+ /**
+ * 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;
+
+ // These 4 attribute event handler attributes are overrided by HTMLBodyElement
+ // and HTMLFrameSetElement to forward to the DOMWindow.
+ virtual EventListener* onblur() const;
+ virtual void setOnblur(PassRefPtr<EventListener>);
+ virtual EventListener* onerror() const;
+ virtual void setOnerror(PassRefPtr<EventListener>);
+ virtual EventListener* onfocus() const;
+ virtual void setOnfocus(PassRefPtr<EventListener>);
+ virtual EventListener* onload() const;
+ virtual void setOnload(PassRefPtr<EventListener>);
+
+ EventListener* onabort() const;
+ void setOnabort(PassRefPtr<EventListener>);
+ EventListener* onchange() const;
+ void setOnchange(PassRefPtr<EventListener>);
+ EventListener* onclick() const;
+ void setOnclick(PassRefPtr<EventListener>);
+ EventListener* oncontextmenu() const;
+ void setOncontextmenu(PassRefPtr<EventListener>);
+ EventListener* ondblclick() const;
+ void setOndblclick(PassRefPtr<EventListener>);
+ EventListener* oninput() const;
+ void setOninput(PassRefPtr<EventListener>);
+ EventListener* onkeydown() const;
+ void setOnkeydown(PassRefPtr<EventListener>);
+ EventListener* onkeypress() const;
+ void setOnkeypress(PassRefPtr<EventListener>);
+ EventListener* onkeyup() const;
+ void setOnkeyup(PassRefPtr<EventListener>);
+ EventListener* onmousedown() const;
+ void setOnmousedown(PassRefPtr<EventListener>);
+ EventListener* onmousemove() const;
+ void setOnmousemove(PassRefPtr<EventListener>);
+ EventListener* onmouseout() const;
+ void setOnmouseout(PassRefPtr<EventListener>);
+ EventListener* onmouseover() const;
+ void setOnmouseover(PassRefPtr<EventListener>);
+ EventListener* onmouseup() const;
+ void setOnmouseup(PassRefPtr<EventListener>);
+ EventListener* onmousewheel() const;
+ void setOnmousewheel(PassRefPtr<EventListener>);
+ EventListener* ondragenter() const;
+ void setOndragenter(PassRefPtr<EventListener>);
+ EventListener* ondragover() const;
+ void setOndragover(PassRefPtr<EventListener>);
+ EventListener* ondragleave() const;
+ void setOndragleave(PassRefPtr<EventListener>);
+ EventListener* ondrop() const;
+ void setOndrop(PassRefPtr<EventListener>);
+ EventListener* ondragstart() const;
+ void setOndragstart(PassRefPtr<EventListener>);
+ EventListener* ondrag() const;
+ void setOndrag(PassRefPtr<EventListener>);
+ EventListener* ondragend() const;
+ void setOndragend(PassRefPtr<EventListener>);
+ EventListener* onscroll() const;
+ void setOnscroll(PassRefPtr<EventListener>);
+ EventListener* onselect() const;
+ void setOnselect(PassRefPtr<EventListener>);
+ EventListener* onsubmit() const;
+ void setOnsubmit(PassRefPtr<EventListener>);
+
+ // WebKit extensions
+ EventListener* onbeforecut() const;
+ void setOnbeforecut(PassRefPtr<EventListener>);
+ EventListener* oncut() const;
+ void setOncut(PassRefPtr<EventListener>);
+ EventListener* onbeforecopy() const;
+ void setOnbeforecopy(PassRefPtr<EventListener>);
+ EventListener* oncopy() const;
+ void setOncopy(PassRefPtr<EventListener>);
+ EventListener* onbeforepaste() const;
+ void setOnbeforepaste(PassRefPtr<EventListener>);
+ EventListener* onpaste() const;
+ void setOnpaste(PassRefPtr<EventListener>);
+ EventListener* onreset() const;
+ void setOnreset(PassRefPtr<EventListener>);
+ EventListener* onsearch() const;
+ void setOnsearch(PassRefPtr<EventListener>);
+ EventListener* onselectstart() const;
+ void setOnselectstart(PassRefPtr<EventListener>);
+
+ 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;
@@ -529,7 +685,7 @@ private:
bool m_hasId : 1;
bool m_hasClass : 1;
bool m_attached : 1;
- bool m_hasChangedChild : 1;
+ bool m_childNeedsStyleRecalc : 1;
bool m_inDocument : 1;
bool m_isLink : 1;
bool m_active : 1;
@@ -540,6 +696,7 @@ private:
bool m_hasRareData : 1;
const bool m_isElement : 1;
const bool m_isContainer : 1;
+ const bool m_isText : 1;
protected:
// These bits are used by the Element derived class, pulled up here so they can
diff --git a/src/3rdparty/webkit/WebCore/dom/Node.idl b/src/3rdparty/webkit/WebCore/dom/Node.idl
index f45eaa6..bcfb226 100644
--- a/src/3rdparty/webkit/WebCore/dom/Node.idl
+++ b/src/3rdparty/webkit/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,15 +22,16 @@ module core {
interface [
CustomMarkFunction,
+ CustomPushEventHandlerScope,
GenerateConstructor,
GenerateNativeConverter,
GenerateToJS,
InlineGetOwnPropertySlot,
- ObjCCustomInternalImpl,
+ Polymorphic,
InterfaceUUID=84BA0D7A-7E3E-4a7b-B6FB-7653E8FB54ED,
ImplementationUUID=81B47FDB-94B0-40fd-8E0C-FB2A6E53CC04
] Node
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
: Object, EventTarget
#endif /* defined(LANGUAGE_OBJECTIVE_C) */
{
@@ -64,12 +65,12 @@ module core {
readonly attribute NamedNodeMap attributes;
readonly attribute Document ownerDocument;
- [OldStyleObjC, Custom] Node insertBefore(in [Return] Node newChild,
+ [OldStyleObjC, Custom] Node insertBefore(in [Return] Node newChild,
in Node refChild)
raises(DOMException);
- [OldStyleObjC, Custom] Node replaceChild(in Node newChild,
+ [OldStyleObjC, Custom] Node replaceChild(in Node newChild,
in [Return] Node oldChild)
- raises(DOMException);
+ raises(DOMExceptionJSC);
[Custom] Node removeChild(in [Return] Node oldChild)
raises(DOMException);
[Custom] Node appendChild(in [Return] Node newChild)
@@ -124,13 +125,26 @@ module core {
DOMUserData getUserData(in DOMString key);
#endif /* 0 */
- // IE extentions
- readonly attribute Node parentElement;
+ // IE extensions
+ readonly attribute Element parentElement;
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extensions
readonly attribute boolean isContentEditable;
#endif /* defined(LANGUAGE_OBJECTIVE_C) */
+
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+ [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/src/3rdparty/webkit/WebCore/dom/NodeFilter.h b/src/3rdparty/webkit/WebCore/dom/NodeFilter.h
index 4356357..94c87e3 100644
--- a/src/3rdparty/webkit/WebCore/dom/NodeFilter.h
+++ b/src/3rdparty/webkit/WebCore/dom/NodeFilter.h
@@ -25,7 +25,6 @@
#ifndef NodeFilter_h
#define NodeFilter_h
-#include "JSDOMBinding.h"
#include "NodeFilterCondition.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
diff --git a/src/3rdparty/webkit/WebCore/dom/NodeIterator.h b/src/3rdparty/webkit/WebCore/dom/NodeIterator.h
index d7eee36..2a992d3 100644
--- a/src/3rdparty/webkit/WebCore/dom/NodeIterator.h
+++ b/src/3rdparty/webkit/WebCore/dom/NodeIterator.h
@@ -25,7 +25,6 @@
#ifndef NodeIterator_h
#define NodeIterator_h
-#include "JSDOMBinding.h"
#include "NodeFilter.h"
#include "Traversal.h"
#include <wtf/PassRefPtr.h>
diff --git a/src/3rdparty/webkit/WebCore/dom/NodeRareData.h b/src/3rdparty/webkit/WebCore/dom/NodeRareData.h
index bbcfca8..ae0e516 100644
--- a/src/3rdparty/webkit/WebCore/dom/NodeRareData.h
+++ b/src/3rdparty/webkit/WebCore/dom/NodeRareData.h
@@ -28,6 +28,7 @@
#include "StringHash.h"
#include "QualifiedName.h"
#include <wtf/HashSet.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -44,7 +45,11 @@ struct NodeListsNodeData {
typedef HashMap<QualifiedName, DynamicNodeList::Caches*> TagCacheMap;
TagCacheMap m_tagNodeListCaches;
-
+
+ static PassOwnPtr<NodeListsNodeData> create() {
+ return new NodeListsNodeData;
+ }
+
~NodeListsNodeData()
{
deleteAllValues(m_classNodeListCaches);
@@ -55,6 +60,9 @@ struct NodeListsNodeData {
void invalidateCaches();
void invalidateCachesThatDependOnAttributes();
bool isEmpty() const;
+
+private:
+ NodeListsNodeData() { }
};
class NodeRareData {
@@ -81,7 +89,7 @@ public:
}
void clearNodeLists() { m_nodeLists.clear(); }
- void setNodeLists(std::auto_ptr<NodeListsNodeData> lists) { m_nodeLists.set(lists.release()); }
+ void setNodeLists(PassOwnPtr<NodeListsNodeData> lists) { m_nodeLists = lists; }
NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }
short tabIndex() const { return m_tabIndex; }
diff --git a/src/3rdparty/webkit/WebCore/dom/OptionElement.cpp b/src/3rdparty/webkit/WebCore/dom/OptionElement.cpp
new file mode 100644
index 0000000..581c070
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/OptionElement.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "OptionElement.h"
+
+#include "Document.h"
+#include "Element.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "OptionGroupElement.h"
+#include "ScriptElement.h"
+#include "SelectElement.h"
+#include <wtf/Assertions.h>
+
+#if ENABLE(WML)
+#include "WMLOptionElement.h"
+#include "WMLNames.h"
+#endif
+
+namespace WebCore {
+
+void OptionElement::setSelectedState(OptionElementData& data, Element* element, bool selected)
+{
+ if (data.selected() == selected)
+ return;
+
+ data.setSelected(selected);
+ element->setNeedsStyleRecalc();
+}
+
+int OptionElement::optionIndex(SelectElement* selectElement, const Element* element)
+{
+ if (!selectElement)
+ return 0;
+
+ // Let's do this dynamically. Might be a bit slow, but we're sure
+ // we won't forget to update a member variable in some cases...
+ const Vector<Element*>& items = selectElement->listItems();
+ int length = items.size();
+ int optionIndex = 0;
+ for (int i = 0; i < length; ++i) {
+ if (!isOptionElement(items[i]))
+ continue;
+ if (items[i] == element)
+ return optionIndex;
+ ++optionIndex;
+ }
+
+ return 0;
+}
+
+String OptionElement::collectOptionText(const OptionElementData& data, const Element* element)
+{
+ Document* document = element->document();
+ String text;
+
+ // WinIE does not use the label attribute, so as a quirk, we ignore it.
+ if (!document->inCompatMode())
+ text = data.label();
+
+ if (text.isEmpty()) {
+ Node* n = element->firstChild();
+ while (n) {
+ if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE)
+ text += n->nodeValue();
+
+ // skip script content
+ if (n->isElementNode() && toScriptElement(static_cast<Element*>(n)))
+ n = n->traverseNextSibling(element);
+ else
+ n = n->traverseNextNode(element);
+ }
+ }
+
+ text = document->displayStringModifiedByEncoding(text);
+
+ // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
+ text = text.stripWhiteSpace();
+
+ // We want to collapse our whitespace too. This will match other browsers.
+ text = text.simplifyWhiteSpace();
+ return text;
+}
+
+String OptionElement::collectOptionTextRespectingGroupLabel(const OptionElementData& data, const Element* element)
+{
+ Element* parentElement = static_cast<Element*>(element->parentNode());
+ if (parentElement && toOptionGroupElement(parentElement))
+ return " " + collectOptionText(data, element);
+
+ return collectOptionText(data, element);
+}
+
+String OptionElement::collectOptionValue(const OptionElementData& data, const Element* element)
+{
+ String value = data.value();
+ if (!value.isNull())
+ return value;
+
+ // Use the text if the value wasn't set.
+ return collectOptionText(data, element).stripWhiteSpace();
+}
+
+// OptionElementData
+OptionElementData::OptionElementData()
+ : m_selected(false)
+{
+}
+
+OptionElement* toOptionElement(Element* element)
+{
+ if (element->isHTMLElement() && element->hasTagName(HTMLNames::optionTag))
+ return static_cast<HTMLOptionElement*>(element);
+
+#if ENABLE(WML)
+ if (element->isWMLElement() && element->hasTagName(WMLNames::optionTag))
+ return static_cast<WMLOptionElement*>(element);
+#endif
+
+ return 0;
+}
+
+bool isOptionElement(Element* element)
+{
+ return element->hasLocalName(HTMLNames::optionTag)
+#if ENABLE(WML)
+ || element->hasLocalName(WMLNames::optionTag)
+#endif
+ ;
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/dom/OptionElement.h b/src/3rdparty/webkit/WebCore/dom/OptionElement.h
new file mode 100644
index 0000000..c6b9778
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/OptionElement.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef OptionElement_h
+#define OptionElement_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Element;
+class Document;
+class OptionElementData;
+class SelectElement;
+
+class OptionElement {
+public:
+ virtual ~OptionElement() { }
+
+ virtual bool selected() const = 0;
+ virtual void setSelectedState(bool) = 0;
+
+ virtual String text() const = 0;
+ virtual String textIndentedToRespectGroupLabel() const = 0;
+ virtual String value() const = 0;
+
+protected:
+ static void setSelectedState(OptionElementData&, Element*, bool selected);
+ static int optionIndex(SelectElement*, const Element*);
+ static String collectOptionText(const OptionElementData&, const Element*);
+ static String collectOptionTextRespectingGroupLabel(const OptionElementData&, const Element*);
+ static String collectOptionValue(const OptionElementData&, const Element*);
+};
+
+// HTML/WMLOptionElement hold this struct as member variable
+// and pass it to the static helper functions in OptionElement
+class OptionElementData {
+public:
+ OptionElementData();
+
+ String value() const { return m_value; }
+ void setValue(const String& value) { m_value = value; }
+
+ String label() const { return m_label; }
+ void setLabel(const String& label) { m_label = label; }
+
+ bool selected() const { return m_selected; }
+ void setSelected(bool selected) { m_selected = selected; }
+
+private:
+ String m_value;
+ String m_label;
+ bool m_selected;
+};
+
+OptionElement* toOptionElement(Element*);
+bool isOptionElement(Element*);
+
+}
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/OptionGroupElement.cpp b/src/3rdparty/webkit/WebCore/dom/OptionGroupElement.cpp
new file mode 100644
index 0000000..8a001bc
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/OptionGroupElement.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "OptionGroupElement.h"
+
+#include "Element.h"
+#include "HTMLNames.h"
+#include "HTMLOptGroupElement.h"
+#include <wtf/Assertions.h>
+
+#if ENABLE(WML)
+#include "WMLOptGroupElement.h"
+#include "WMLNames.h"
+#endif
+
+namespace WebCore {
+
+OptionGroupElement* toOptionGroupElement(Element* element)
+{
+ if (element->isHTMLElement() && element->hasTagName(HTMLNames::optgroupTag))
+ return static_cast<HTMLOptGroupElement*>(element);
+
+#if ENABLE(WML)
+ if (element->isWMLElement() && element->hasTagName(WMLNames::optgroupTag))
+ return static_cast<WMLOptGroupElement*>(element);
+#endif
+
+ return 0;
+}
+
+bool isOptionGroupElement(Element* element)
+{
+ return element->hasLocalName(HTMLNames::optgroupTag)
+#if ENABLE(WML)
+ || element->hasLocalName(WMLNames::optgroupTag)
+#endif
+ ;
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/dom/FormControlElement.h b/src/3rdparty/webkit/WebCore/dom/OptionGroupElement.h
index a22b835..e4b1566 100644
--- a/src/3rdparty/webkit/WebCore/dom/FormControlElement.h
+++ b/src/3rdparty/webkit/WebCore/dom/OptionGroupElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -18,22 +18,24 @@
*
*/
-#ifndef FormControlElement_h
-#define FormControlElement_h
+#ifndef OptionGroupElement_h
+#define OptionGroupElement_h
namespace WebCore {
-class FormControlElement {
-public:
- virtual ~FormControlElement() { }
+class Element;
+class String;
- virtual bool valueMatchesRenderer() const = 0;
- virtual void setValueMatchesRenderer(bool value = true) = 0;
+class OptionGroupElement {
+public:
+ virtual ~OptionGroupElement() { }
-protected:
- FormControlElement() { }
+ virtual String groupLabelText() const = 0;
};
+OptionGroupElement* toOptionGroupElement(Element*);
+bool isOptionGroupElement(Element*);
+
}
#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/Position.cpp b/src/3rdparty/webkit/WebCore/dom/Position.cpp
index 8613d55..3b4c3e8 100644
--- a/src/3rdparty/webkit/WebCore/dom/Position.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/Position.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 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
@@ -29,14 +29,12 @@
#include "CSSComputedStyleDeclaration.h"
#include "CString.h"
#include "CharacterNames.h"
-#include "Document.h"
-#include "Element.h"
-#include "HTMLNames.h"
#include "Logging.h"
#include "PositionIterator.h"
#include "RenderBlock.h"
#include "Text.h"
#include "TextIterator.h"
+#include "VisiblePosition.h"
#include "htmlediting.h"
#include "visible_units.h"
#include <stdio.h>
@@ -45,7 +43,7 @@ namespace WebCore {
using namespace HTMLNames;
-static Node *nextRenderedEditable(Node *node)
+static Node* nextRenderedEditable(Node* node)
{
while (1) {
node = node->nextEditable();
@@ -54,13 +52,13 @@ static Node *nextRenderedEditable(Node *node)
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
- if (renderer->inlineBoxWrapper() || renderer->isText() && static_cast<RenderText*>(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();
@@ -69,26 +67,141 @@ static Node *previousRenderedEditable(Node *node)
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
- if (renderer->inlineBoxWrapper() || renderer->isText() && static_cast<RenderText*>(renderer)->firstTextBox())
+ if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
return node;
}
return 0;
}
-Element* Position::documentElement() const
+Position::Position(PassRefPtr<Node> anchorNode, int offset)
+ : m_anchorNode(anchorNode)
+ , m_offset(offset)
+ , m_anchorType(anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset))
+ , m_isLegacyEditingPosition(true)
{
- if (Node* n = node())
- if (Element* e = n->document()->documentElement())
- return e;
+}
+
+Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
+ : m_anchorNode(anchorNode)
+ , m_offset(0)
+ , m_anchorType(anchorType)
+ , m_isLegacyEditingPosition(false)
+{
+ ASSERT(anchorType != PositionIsOffsetInAnchor);
+}
+
+Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorType)
+ : m_anchorNode(anchorNode)
+ , m_offset(offset)
+ , m_anchorType(anchorType)
+ , m_isLegacyEditingPosition(false)
+{
+ ASSERT(anchorType == PositionIsOffsetInAnchor);
+}
+
+void Position::moveToPosition(PassRefPtr<Node> node, int offset)
+{
+ ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
+ m_anchorNode = node;
+ m_offset = offset;
+ if (m_isLegacyEditingPosition)
+ m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
+}
+void Position::moveToOffset(int offset)
+{
+ ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
+ m_offset = offset;
+ if (m_isLegacyEditingPosition)
+ m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
+}
+
+Node* Position::containerNode() const
+{
+ if (!m_anchorNode)
+ return 0;
+
+ switch (anchorType()) {
+ case PositionIsOffsetInAnchor:
+ return m_anchorNode.get();
+ case PositionIsBeforeAnchor:
+ case PositionIsAfterAnchor:
+ return m_anchorNode->parentNode();
+ }
+ ASSERT_NOT_REACHED();
return 0;
}
-Element *Position::element() const
+int Position::computeOffsetInContainerNode() const
{
- Node *n;
- for (n = node(); n && !n->isElementNode(); n = n->parentNode())
- ; // empty loop body
- return static_cast<Element *>(n);
+ if (!m_anchorNode)
+ return 0;
+
+ switch (anchorType()) {
+ case PositionIsOffsetInAnchor:
+ {
+ int maximumValidOffset = m_anchorNode->offsetInCharacters() ? m_anchorNode->maxCharacterOffset() : m_anchorNode->childNodeCount();
+ return std::min(maximumValidOffset, m_offset);
+ }
+ case PositionIsBeforeAnchor:
+ return m_anchorNode->nodeIndex();
+ case PositionIsAfterAnchor:
+ return m_anchorNode->nodeIndex() + 1;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+Node* Position::computeNodeBeforePosition() const
+{
+ if (!m_anchorNode)
+ return 0;
+
+ switch (anchorType()) {
+ case PositionIsOffsetInAnchor:
+ return m_anchorNode->childNode(m_offset - 1); // -1 converts to childNode((unsigned)-1) and returns null.
+ case PositionIsBeforeAnchor:
+ return m_anchorNode->previousSibling();
+ case PositionIsAfterAnchor:
+ return m_anchorNode.get();
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+Node* Position::computeNodeAfterPosition() const
+{
+ if (!m_anchorNode)
+ return 0;
+
+ switch (anchorType()) {
+ case PositionIsOffsetInAnchor:
+ return m_anchorNode->childNode(m_offset);
+ case PositionIsBeforeAnchor:
+ return m_anchorNode.get();
+ case PositionIsAfterAnchor:
+ return m_anchorNode->nextSibling();
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+Position::AnchorType Position::anchorTypeForLegacyEditingPosition(Node* anchorNode, int offset)
+{
+ if (anchorNode && editingIgnoresContent(anchorNode)) {
+ if (offset == 0)
+ return Position::PositionIsBeforeAnchor;
+ return Position::PositionIsAfterAnchor;
+ }
+ return Position::PositionIsOffsetInAnchor;
+}
+
+// FIXME: This method is confusing (does it return anchorNode() or containerNode()?) and should be renamed or removed
+Element* Position::element() const
+{
+ Node* n = anchorNode();
+ while (n && !n->isElementNode())
+ n = n->parentNode();
+ return static_cast<Element*>(n);
}
PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
@@ -99,60 +212,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;
@@ -164,49 +286,64 @@ 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 = static_cast<RenderText *>(node()->renderer());
+ RenderText *textRenderer = toRenderText(node()->renderer());
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- int start = box->m_start;
- int end = box->m_start + box->m_len;
- if (offset() < start)
+ int start = box->start();
+ int end = box->start() + box->len();
+ if (m_offset < start)
return result;
- if (offset() <= end) {
- result += offset() - start;
+ if (m_offset <= end) {
+ result += m_offset - start;
return result;
}
- result += box->m_len;
+ result += box->len();
}
return result;
}
@@ -223,7 +360,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)
@@ -251,7 +388,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)
@@ -267,7 +404,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.
@@ -284,7 +421,7 @@ static bool endsOfNodeAreVisuallyDistinctPositions(Node* node)
return false;
// There is a VisiblePosition inside an empty inline-block container.
- return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && node->renderer()->height() != 0 && !node->firstChild();
+ return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && toRenderBox(node->renderer())->height() != 0 && !node->firstChild();
}
static Node* enclosingVisualBoundary(Node* node)
@@ -361,12 +498,12 @@ 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;
}
// return current position if it is in rendered text
- if (renderer->isText() && static_cast<RenderText*>(renderer)->firstTextBox()) {
+ if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
if (currentNode != startNode) {
// This assertion fires in layout tests in the case-transform.html test because
// of a mix-up between offsets in the text in the DOM tree with text in the
@@ -377,7 +514,7 @@ Position Position::upstream() const
}
unsigned textOffset = currentPos.offsetInLeafNode();
- RenderText* textRenderer = static_cast<RenderText*>(renderer);
+ RenderText* textRenderer = toRenderText(renderer);
InlineTextBox* lastTextBox = textRenderer->lastTextBox();
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (textOffset <= box->start() + box->len()) {
@@ -398,7 +535,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;
}
@@ -407,7 +544,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;
}
@@ -482,14 +619,14 @@ Position Position::downstream() const
}
// return current position if it is in rendered text
- if (renderer->isText() && static_cast<RenderText*>(renderer)->firstTextBox()) {
+ if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
if (currentNode != startNode) {
ASSERT(currentPos.atStartOfNode());
return Position(currentNode, renderer->caretMinOffset());
}
unsigned textOffset = currentPos.offsetInLeafNode();
- RenderText* textRenderer = static_cast<RenderText*>(renderer);
+ RenderText* textRenderer = toRenderText(renderer);
InlineTextBox* lastTextBox = textRenderer->lastTextBox();
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (textOffset <= box->end()) {
@@ -510,7 +647,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;
}
@@ -519,7 +656,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;
}
@@ -536,9 +673,11 @@ bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* render
{
RenderObject* stop = renderer->nextInPreOrderAfterChildren();
for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
- if (o->element() && o->height())
- return true;
-
+ if (o->node()) {
+ if ((o->isText() && toRenderText(o)->linesBoundingBox().height()) ||
+ (o->isBox() && toRenderBox(o)->borderBoundingBox().height()))
+ return true;
+ }
return false;
}
@@ -560,17 +699,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) &&
- (renderer->height() || node()->hasTagName(bodyTag)))
- return offset() == 0 && !nodeIsUserSelectNone(node());
+ (toRenderBox(renderer)->height() || node()->hasTagName(bodyTag)))
+ return atFirstEditingPositionForNode() && !nodeIsUserSelectNone(node());
return false;
}
@@ -584,17 +723,17 @@ bool Position::inRenderedText() const
if (!renderer)
return false;
- RenderText *textRenderer = static_cast<RenderText *>(renderer);
+ RenderText *textRenderer = toRenderText(renderer);
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (offset() < box->m_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;
@@ -616,19 +755,19 @@ bool Position::isRenderedCharacter() const
if (isNull() || !node()->isTextNode())
return false;
- RenderObject *renderer = node()->renderer();
+ RenderObject* renderer = node()->renderer();
if (!renderer)
return false;
- RenderText *textRenderer = static_cast<RenderText *>(renderer);
- for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (offset() < box->m_start && !textRenderer->containsReversedText()) {
+ RenderText* textRenderer = toRenderText(renderer);
+ for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+ 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() >= box->m_start && offset() < box->m_start + box->m_len)
+ if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast<int>(box->start() + box->len()))
return true;
}
@@ -656,11 +795,11 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
if (node()->hasTagName(brTag))
return false;
- if (offset() == pos.offset())
+ if (m_offset == pos.deprecatedEditingOffset())
return false;
if (!node()->isTextNode() && !pos.node()->isTextNode()) {
- if (offset() != pos.offset())
+ if (m_offset != pos.deprecatedEditingOffset())
return true;
}
}
@@ -734,7 +873,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.deprecatedEditingOffset()];
if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : isCollapsibleWhitespace(c))
if (isEditablePosition(prev))
return prev;
@@ -783,40 +922,42 @@ static bool isNonTextLeafChild(RenderObject* object)
static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
{
- InlineTextBox* match = 0;
- int minOffset = INT_MAX;
RenderBlock* container = renderer->containingBlock();
RenderObject* next = renderer;
while ((next = next->nextInPreOrder(container))) {
if (next->isRenderBlock())
- break;
+ return 0;
if (next->isBR())
- break;
+ return 0;
if (isNonTextLeafChild(next))
- break;
+ return 0;
if (next->isText()) {
- for (InlineTextBox* box = static_cast<RenderText*>(next)->firstTextBox(); box; box = box->nextTextBox()) {
+ InlineTextBox* match = 0;
+ int minOffset = INT_MAX;
+ for (InlineTextBox* box = toRenderText(next)->firstTextBox(); box; box = box->nextTextBox()) {
int caretMinOffset = box->caretMinOffset();
if (caretMinOffset < minOffset) {
match = box;
minOffset = caretMinOffset;
}
}
+ if (match)
+ return match;
}
}
- return match;
+ return 0;
}
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 = static_cast<RenderText*>(renderer);
+ RenderText* textRenderer = toRenderText(renderer);
InlineTextBox* box;
InlineTextBox* candidate = 0;
@@ -825,7 +966,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 +1084,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 +1098,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 +1125,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/src/3rdparty/webkit/WebCore/dom/Position.h b/src/3rdparty/webkit/WebCore/dom/Position.h
index 2624238..57f73ec 100644
--- a/src/3rdparty/webkit/WebCore/dom/Position.h
+++ b/src/3rdparty/webkit/WebCore/dom/Position.h
@@ -28,6 +28,7 @@
#include "TextAffinity.h"
#include "TextDirection.h"
+#include <wtf/Assertions.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -40,28 +41,76 @@ class Node;
class Range;
class RenderObject;
-enum EUsingComposedCharacters { NotUsingComposedCharacters = false, UsingComposedCharacters = true };
-
-// FIXME: Reduce the number of operations we have on a Position.
-// This should be more like a humble struct, without so many different
-// member functions. We should find better homes for these functions.
+enum PositionMoveType {
+ CodePoint, // Move by a single code point.
+ Character, // Move to the next Unicode character break.
+ BackwardDeletion // Subject to platform conventions.
+};
class Position {
public:
- RefPtr<Node> container;
- int posOffset; // to be renamed to offset when we get rid of offset()
-
- Position() : posOffset(0) { }
- Position(PassRefPtr<Node> c, int o) : container(c), posOffset(o) { }
-
- void clear() { container.clear(); posOffset = 0; }
-
- Node* node() const { return container.get(); }
- int offset() const { return posOffset; }
- Element* documentElement() const;
-
- bool isNull() const { return !container; }
- bool isNotNull() const { return container; }
+ enum AnchorType {
+ PositionIsOffsetInAnchor,
+ PositionIsAfterAnchor,
+ PositionIsBeforeAnchor
+ };
+
+ Position()
+ : m_offset(0)
+ , m_anchorType(PositionIsOffsetInAnchor)
+ , m_isLegacyEditingPosition(false)
+ {
+ }
+
+ // For creating legacy editing positions: (Anchor type will be determined from editingIgnoresContent(node))
+ Position(PassRefPtr<Node> anchorNode, int offset);
+
+ // For creating before/after positions:
+ Position(PassRefPtr<Node> anchorNode, AnchorType);
+ // For creating offset positions:
+ Position(PassRefPtr<Node> anchorNode, int offset, AnchorType);
+
+ AnchorType anchorType() const { return m_anchorType; }
+
+ void clear() { m_anchorNode.clear(); m_offset = 0; m_anchorType = PositionIsOffsetInAnchor; m_isLegacyEditingPosition = false; }
+
+ // These are always DOM compliant values. Editing positions like [img, 0] (aka [img, before])
+ // will return img->parentNode() and img->nodeIndex() from these functions.
+ Node* containerNode() const; // NULL for a before/after position anchored to a node with no parent
+ int computeOffsetInContainerNode() const; // O(n) for before/after-anchored positions, O(1) for parent-anchored positions
+
+ // Inline O(1) access for Positions which callers know to be parent-anchored
+ int offsetInContainerNode() const
+ {
+ ASSERT(anchorType() == PositionIsOffsetInAnchor);
+ return m_offset;
+ }
+
+ // New code should not use this function.
+ int deprecatedEditingOffset() const
+ {
+ // This should probably ASSERT(m_isLegacyEditingPosition);
+ return m_offset;
+ }
+
+ // These are convenience methods which are smart about whether the position is neighbor anchored or parent anchored
+ Node* computeNodeBeforePosition() const;
+ Node* computeNodeAfterPosition() const;
+
+ Node* anchorNode() const { return m_anchorNode.get(); }
+
+ // 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(); }
+
+ // These should only be used for PositionIsOffsetInAnchor positions, unless
+ // the position is a legacy editing position.
+ void moveToPosition(PassRefPtr<Node> anchorNode, int offset);
+ void moveToOffset(int offset);
+
+ bool isNull() const { return !m_anchorNode; }
+ bool isNotNull() const { return m_anchorNode; }
Element* element() const;
PassRefPtr<CSSComputedStyleDeclaration> computedStyle() const;
@@ -69,13 +118,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 +164,23 @@ private:
Position previousCharacterPosition(EAffinity) const;
Position nextCharacterPosition(EAffinity) const;
+
+ static AnchorType anchorTypeForLegacyEditingPosition(Node* anchorNode, int offset);
+
+ RefPtr<Node> m_anchorNode;
+ // 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;
+ AnchorType m_anchorType : 2;
+ bool m_isLegacyEditingPosition : 1;
};
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.deprecatedEditingOffset() == b.deprecatedEditingOffset();
}
inline bool operator!=(const Position& a, const Position& b)
@@ -124,6 +191,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/src/3rdparty/webkit/WebCore/dom/PositionIterator.cpp b/src/3rdparty/webkit/WebCore/dom/PositionIterator.cpp
index 218ace1..a029b5e 100644
--- a/src/3rdparty/webkit/WebCore/dom/PositionIterator.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/PositionIterator.cpp
@@ -27,7 +27,7 @@
#include "PositionIterator.h"
#include "Node.h"
-#include "RenderObject.h"
+#include "RenderBlock.h"
#include "htmlediting.h"
namespace WebCore {
@@ -36,105 +36,111 @@ 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_nodeAfterPositionInAnchor) {
+ ASSERT(m_nodeAfterPositionInAnchor->parentNode() == m_anchorNode);
+ return positionBeforeNode(m_nodeAfterPositionInAnchor);
+ }
+ if (m_anchorNode->hasChildNodes())
+ return lastDeepEditingPositionForNode(m_anchorNode);
+ return Position(m_anchorNode, m_offsetInAnchor);
}
void PositionIterator::increment()
{
- if (!m_parent)
+ if (!m_anchorNode)
return;
- if (m_child) {
- m_parent = m_child;
- m_child = m_parent->firstChild();
- m_offset = 0;
+ if (m_nodeAfterPositionInAnchor) {
+ m_anchorNode = m_nodeAfterPositionInAnchor;
+ m_nodeAfterPositionInAnchor = m_anchorNode->firstChild();
+ m_offsetInAnchor = 0;
return;
}
- if (!m_parent->hasChildNodes() && m_offset < maxDeepOffset(m_parent))
- m_offset = Position::uncheckedNextOffset(m_parent, m_offset);
+ if (!m_anchorNode->hasChildNodes() && m_offsetInAnchor < lastOffsetForEditing(m_anchorNode))
+ m_offsetInAnchor = Position::uncheckedNextOffset(m_anchorNode, m_offsetInAnchor);
else {
- m_child = m_parent;
- m_parent = m_child->parentNode();
- m_child = m_child->nextSibling();
- m_offset = 0;
+ m_nodeAfterPositionInAnchor = m_anchorNode;
+ m_anchorNode = m_nodeAfterPositionInAnchor->parentNode();
+ m_nodeAfterPositionInAnchor = m_nodeAfterPositionInAnchor->nextSibling();
+ m_offsetInAnchor = 0;
}
}
void PositionIterator::decrement()
{
- if (!m_parent)
+ if (!m_anchorNode)
return;
- if (m_child) {
- m_parent = m_child->previousSibling();
- if (m_parent) {
- m_child = 0;
- m_offset = m_parent->hasChildNodes() ? 0 : maxDeepOffset(m_parent);
+ if (m_nodeAfterPositionInAnchor) {
+ m_anchorNode = m_nodeAfterPositionInAnchor->previousSibling();
+ if (m_anchorNode) {
+ m_nodeAfterPositionInAnchor = 0;
+ m_offsetInAnchor = m_anchorNode->hasChildNodes() ? 0 : lastOffsetForEditing(m_anchorNode);
} else {
- m_child = m_child->parentNode();
- m_parent = m_child->parentNode();
- m_offset = 0;
+ m_nodeAfterPositionInAnchor = m_nodeAfterPositionInAnchor->parentNode();
+ m_anchorNode = m_nodeAfterPositionInAnchor->parentNode();
+ m_offsetInAnchor = 0;
}
return;
}
- if (m_offset) {
- m_offset = Position::uncheckedPreviousOffset(m_parent, m_offset);
+ if (m_offsetInAnchor) {
+ m_offsetInAnchor = Position::uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor);
} else {
- if (m_parent->hasChildNodes()) {
- m_parent = m_parent->lastChild();
- if (!m_parent->hasChildNodes())
- m_offset = maxDeepOffset(m_parent);
+ if (m_anchorNode->hasChildNodes()) {
+ m_anchorNode = m_anchorNode->lastChild();
+ if (!m_anchorNode->hasChildNodes())
+ m_offsetInAnchor = lastOffsetForEditing(m_anchorNode);
} else {
- m_child = m_parent;
- m_parent = m_parent->parentNode();
+ m_nodeAfterPositionInAnchor = m_anchorNode;
+ m_anchorNode = m_anchorNode->parentNode();
}
}
}
bool PositionIterator::atStart() const
{
- if (!m_parent)
+ if (!m_anchorNode)
return true;
- if (m_parent->parentNode())
+ if (m_anchorNode->parentNode())
return false;
- return !m_parent->hasChildNodes() && !m_offset || m_child && !m_child->previousSibling();
+ return (!m_anchorNode->hasChildNodes() && !m_offsetInAnchor) || (m_nodeAfterPositionInAnchor && !m_nodeAfterPositionInAnchor->previousSibling());
}
bool PositionIterator::atEnd() const
{
- if (!m_parent)
+ if (!m_anchorNode)
return true;
- if (m_child)
+ if (m_nodeAfterPositionInAnchor)
return false;
- return !m_parent->parentNode() && (m_parent->hasChildNodes() || m_offset >= maxDeepOffset(m_parent));
+ return !m_anchorNode->parentNode() && (m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode));
}
bool PositionIterator::atStartOfNode() const
{
- if (!m_parent)
+ if (!m_anchorNode)
return true;
- if (!m_child)
- return !m_parent->hasChildNodes() && !m_offset;
- return !m_child->previousSibling();
+ if (!m_nodeAfterPositionInAnchor)
+ return !m_anchorNode->hasChildNodes() && !m_offsetInAnchor;
+ return !m_nodeAfterPositionInAnchor->previousSibling();
}
bool PositionIterator::atEndOfNode() const
{
- if (!m_parent)
+ if (!m_anchorNode)
return true;
- if (m_child)
+ if (m_nodeAfterPositionInAnchor)
return false;
- return m_parent->hasChildNodes() || m_offset >= maxDeepOffset(m_parent);
+ return m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode);
}
bool PositionIterator::isCandidate() const
{
- if (!m_parent)
+ if (!m_anchorNode)
return false;
- RenderObject* renderer = m_parent->renderer();
+ RenderObject* renderer = m_anchorNode->renderer();
if (!renderer)
return false;
@@ -142,17 +148,17 @@ bool PositionIterator::isCandidate() const
return false;
if (renderer->isBR())
- return !m_offset && !Position::nodeIsUserSelectNone(m_parent->parent());
+ return !m_offsetInAnchor && !Position::nodeIsUserSelectNone(m_anchorNode->parent());
if (renderer->isText())
- return Position(*this).inRenderedText() && !Position::nodeIsUserSelectNone(m_parent);
+ return Position(*this).inRenderedText() && !Position::nodeIsUserSelectNone(m_anchorNode);
- if (isTableElement(m_parent) || editingIgnoresContent(m_parent))
- return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_parent->parent());
+ if (isTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
+ return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parent());
- if (!m_parent->hasTagName(htmlTag) && renderer->isBlockFlow() && !Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
- (renderer->height() || m_parent->hasTagName(bodyTag)))
- return atStartOfNode() && !Position::nodeIsUserSelectNone(m_parent);
+ if (!m_anchorNode->hasTagName(htmlTag) && renderer->isBlockFlow() && !Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
+ (toRenderBlock(renderer)->height() || m_anchorNode->hasTagName(bodyTag)))
+ return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
return false;
}
diff --git a/src/3rdparty/webkit/WebCore/dom/PositionIterator.h b/src/3rdparty/webkit/WebCore/dom/PositionIterator.h
index 54f5020..7af8977 100644
--- a/src/3rdparty/webkit/WebCore/dom/PositionIterator.h
+++ b/src/3rdparty/webkit/WebCore/dom/PositionIterator.h
@@ -37,16 +37,16 @@ namespace WebCore {
class PositionIterator {
public:
PositionIterator()
- : m_parent(0)
- , m_child(0)
- , m_offset(0)
+ : m_anchorNode(0)
+ , m_nodeAfterPositionInAnchor(0)
+ , m_offsetInAnchor(0)
{
}
PositionIterator(const Position& pos)
- : m_parent(pos.node())
- , m_child(m_parent->childNode(pos.offset()))
- , m_offset(m_child ? 0 : pos.offset())
+ : m_anchorNode(pos.anchorNode())
+ , m_nodeAfterPositionInAnchor(m_anchorNode->childNode(pos.deprecatedEditingOffset()))
+ , m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : pos.deprecatedEditingOffset())
{
}
operator Position() const;
@@ -54,8 +54,8 @@ public:
void increment();
void decrement();
- Node* node() const { return m_parent; }
- int offsetInLeafNode() const { return m_offset; }
+ Node* node() const { return m_anchorNode; }
+ int offsetInLeafNode() const { return m_offsetInAnchor; }
bool atStart() const;
bool atEnd() const;
@@ -64,9 +64,9 @@ public:
bool isCandidate() const;
private:
- Node* m_parent;
- Node* m_child;
- int m_offset;
+ Node* m_anchorNode;
+ Node* m_nodeAfterPositionInAnchor; // If this is non-null, m_nodeAfterPositionInAnchor->parentNode() == m_anchorNode;
+ int m_offsetInAnchor;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp b/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp
index 906902a..879bf62 100644
--- a/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp
@@ -258,8 +258,7 @@ void ProcessingInstruction::removedFromDocument()
{
ContainerNode::removedFromDocument();
- if (document()->renderer())
- document()->removeStyleSheetCandidateNode(this);
+ document()->removeStyleSheetCandidateNode(this);
// FIXME: It's terrible to do a synchronous update of the style selector just because a <style> or <link> element got removed.
if (m_cachedSheet)
diff --git a/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.idl b/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.idl
index d0923f1..578b22e 100644
--- a/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.idl
+++ b/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.idl
@@ -32,7 +32,7 @@ module core {
attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString data
setter raises(DOMException);
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
// interface LinkStyle from DOM Level 2 Style Sheets
readonly attribute StyleSheet sheet;
#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/QualifiedName.cpp b/src/3rdparty/webkit/WebCore/dom/QualifiedName.cpp
index f40f398..607c846 100644
--- a/src/3rdparty/webkit/WebCore/dom/QualifiedName.cpp
+++ b/src/3rdparty/webkit/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,39 +52,16 @@ struct QNameComponentsTranslator {
static QNameSet* gNameCache;
QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
- : m_impl(0)
{
if (!gNameCache)
gNameCache = new QNameSet;
- QualifiedNameComponents components = { p.impl(), l.impl(), n.impl() };
+ QualifiedNameComponents components = { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() };
pair<QNameSet::iterator, bool> addResult = gNameCache->add<QualifiedNameComponents, QNameComponentsTranslator>(components);
m_impl = *addResult.first;
if (!addResult.second)
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/src/3rdparty/webkit/WebCore/dom/QualifiedName.h b/src/3rdparty/webkit/WebCore/dom/QualifiedName.h
index d09cdea..939927b 100644
--- a/src/3rdparty/webkit/WebCore/dom/QualifiedName.h
+++ b/src/3rdparty/webkit/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,33 @@ 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)
{
+ ASSERT(!namespaceURI.isEmpty() || namespaceURI.isNull());
}
};
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 +70,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 +84,7 @@ public:
static void init();
private:
- void ref() { m_impl->ref(); }
+ void ref() const { m_impl->ref(); }
void deref();
QualifiedNameImpl* m_impl;
@@ -100,7 +100,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 +153,7 @@ struct QualifiedNameHash {
namespace WTF {
template<typename T> struct DefaultHash;
+
template<> struct DefaultHash<WebCore::QualifiedName> {
typedef WebCore::QualifiedNameHash Hash;
};
diff --git a/src/3rdparty/webkit/WebCore/dom/Range.cpp b/src/3rdparty/webkit/WebCore/dom/Range.cpp
index ab1a42d..4fb1164 100644
--- a/src/3rdparty/webkit/WebCore/dom/Range.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/Range.cpp
@@ -26,16 +26,13 @@
#include "RangeException.h"
#include "CString.h"
-#include "Document.h"
#include "DocumentFragment.h"
-#include "ExceptionCode.h"
#include "HTMLElement.h"
-#include "HTMLNames.h"
#include "NodeWithIndex.h"
#include "ProcessingInstruction.h"
-#include "RenderBlock.h"
#include "Text.h"
#include "TextIterator.h"
+#include "VisiblePosition.h"
#include "markup.h"
#include "visible_units.h"
#include <stdio.h>
@@ -44,7 +41,6 @@
namespace WebCore {
using namespace std;
-using namespace HTMLNames;
#ifndef NDEBUG
static WTF::RefCountedLeakCounter rangeCounter("Range");
@@ -94,13 +90,13 @@ 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.deprecatedEditingOffset(), end.node(), end.deprecatedEditingOffset()));
}
Range::~Range()
{
- if (m_start.container())
- m_ownerDocument->detachRange(this);
+ // Always detach (even if we've already detached) to fix https://bugs.webkit.org/show_bug.cgi?id=26044
+ m_ownerDocument->detachRange(this);
#ifndef NDEBUG
rangeCounter.decrement();
@@ -212,7 +208,7 @@ void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
if (startRootContainer != endRootContainer)
collapse(true, ec);
// check if new start after end
- else if (compareBoundaryPoints(m_start.container(), m_start.offset(), m_end.container(), m_end.offset()) > 0)
+ else if (compareBoundaryPoints(m_start, m_end) > 0)
collapse(true, ec);
}
@@ -250,7 +246,7 @@ void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
if (startRootContainer != endRootContainer)
collapse(false, ec);
// check if new end before start
- if (compareBoundaryPoints(m_start.container(), m_start.offset(), m_end.container(), m_end.offset()) > 0)
+ if (compareBoundaryPoints(m_start, m_end) > 0)
collapse(false, ec);
}
@@ -269,17 +265,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;
}
@@ -304,22 +300,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;
}
@@ -388,7 +379,6 @@ Range::CompareResults Range::compareNode(Node* refNode, ExceptionCode& ec)
}
}
-
short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, ExceptionCode& ec) const
{
if (!m_start.container()) {
@@ -427,17 +417,13 @@ short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
switch (how) {
case START_TO_START:
- return compareBoundaryPoints(m_start.container(), m_start.offset(),
- sourceRange->m_start.container(), sourceRange->m_start.offset());
+ return compareBoundaryPoints(m_start, sourceRange->m_start);
case START_TO_END:
- return compareBoundaryPoints(m_end.container(), m_end.offset(),
- sourceRange->m_start.container(), sourceRange->m_start.offset());
+ return compareBoundaryPoints(m_end, sourceRange->m_start);
case END_TO_END:
- return compareBoundaryPoints(m_end.container(), m_end.offset(),
- sourceRange->m_end.container(), sourceRange->m_end.offset());
+ return compareBoundaryPoints(m_end, sourceRange->m_end);
case END_TO_START:
- return compareBoundaryPoints(m_start.container(), m_start.offset(),
- sourceRange->m_end.container(), sourceRange->m_end.offset());
+ return compareBoundaryPoints(m_start, sourceRange->m_end);
}
ec = SYNTAX_ERR;
@@ -446,11 +432,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
@@ -532,14 +521,14 @@ short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containe
return 0;
}
-short Range::compareBoundaryPoints(const Position& a, const Position& b)
+short Range::compareBoundaryPoints(const RangeBoundaryPoint& boundaryA, const RangeBoundaryPoint& boundaryB)
{
- return compareBoundaryPoints(a.container.get(), a.posOffset, b.container.get(), b.posOffset);
+ return compareBoundaryPoints(boundaryA.container(), boundaryA.offset(), boundaryB.container(), boundaryB.offset());
}
bool Range::boundaryPointsValid() const
{
- return m_start.container() && compareBoundaryPoints(m_start.container(), m_start.offset(), m_end.container(), m_end.offset()) <= 0;
+ return m_start.container() && compareBoundaryPoints(m_start, m_end) <= 0;
}
void Range::deleteContents(ExceptionCode& ec)
@@ -561,8 +550,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;
@@ -847,6 +836,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)
@@ -986,7 +986,7 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionCode& ec)
// This special case doesn't seem to match the DOM specification, but it's currently required
// to pass Acid3. We might later decide to remove this.
if (collapsed)
- m_end.setToChild(newText.get());
+ m_end.setToBeforeChild(newText.get());
} else {
RefPtr<Node> lastChild;
if (collapsed)
@@ -1069,6 +1069,7 @@ PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& marku
void Range::detach(ExceptionCode& ec)
{
+ // Check first to see if we've already detached:
if (!m_start.container()) {
ec = INVALID_STATE_ERR;
return;
@@ -1350,8 +1351,8 @@ void Range::selectNodeContents(Node* refNode, ExceptionCode& ec)
}
}
- m_start.setToStart(refNode);
- m_end.setToEnd(refNode);
+ m_start.setToStartOfNode(refNode);
+ m_end.setToEndOfNode(refNode);
}
void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
@@ -1580,31 +1581,30 @@ IntRect Range::boundingBox()
{
IntRect result;
Vector<IntRect> rects;
- addLineBoxRects(rects);
+ textRects(rects);
const size_t n = rects.size();
for (size_t i = 0; i < n; ++i)
result.unite(rects[i]);
return result;
}
-void Range::addLineBoxRects(Vector<IntRect>& rects, bool useSelectionHeight)
+void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight)
{
if (!m_start.container() || !m_end.container())
return;
- RenderObject* start = m_start.container()->renderer();
- RenderObject* end = m_end.container()->renderer();
- if (!start || !end)
- return;
+ Node* startContainer = m_start.container();
+ Node* endContainer = m_end.container();
- RenderObject* 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);
- }
+ Node* stopNode = pastLastNode();
+ for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
+ RenderObject* r = node->renderer();
+ if (!r || !r->isText())
+ continue;
+ RenderText* renderText = toRenderText(r);
+ int startOffset = node == startContainer ? m_start.offset() : 0;
+ int endOffset = node == endContainer ? m_end.offset() : INT_MAX;
+ renderText->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight);
}
}
@@ -1700,7 +1700,7 @@ static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node*
for (Node* n = boundary.container(); n; n = n->parentNode()) {
if (n == nodeToBeRemoved) {
- boundary.setToChild(nodeToBeRemoved);
+ boundary.setToBeforeChild(nodeToBeRemoved);
return;
}
}
diff --git a/src/3rdparty/webkit/WebCore/dom/Range.h b/src/3rdparty/webkit/WebCore/dom/Range.h
index 49dea82..115f442 100644
--- a/src/3rdparty/webkit/WebCore/dom/Range.h
+++ b/src/3rdparty/webkit/WebCore/dom/Range.h
@@ -66,7 +66,7 @@ public:
enum CompareHow { START_TO_START, START_TO_END, END_TO_END, END_TO_START };
short compareBoundaryPoints(CompareHow, const Range* sourceRange, ExceptionCode&) const;
static short compareBoundaryPoints(Node* containerA, int offsetA, Node* containerB, int offsetB);
- static short compareBoundaryPoints(const Position&, const Position&);
+ static short compareBoundaryPoints(const RangeBoundaryPoint& boundaryA, const RangeBoundaryPoint& boundaryB);
bool boundaryPointsValid() const;
bool intersectsNode(Node* refNode, ExceptionCode&);
void deleteContents(ExceptionCode&);
@@ -91,8 +91,8 @@ public:
void surroundContents(PassRefPtr<Node>, ExceptionCode&);
void setStartBefore(Node*, ExceptionCode&);
- const Position& startPosition() const { return m_start.position(); }
- const Position& endPosition() const { return m_end.position(); }
+ const Position startPosition() const { return m_start.toPosition(); }
+ const Position endPosition() const { return m_end.toPosition(); }
Node* firstNode() const;
Node* pastLastNode() const;
@@ -102,7 +102,7 @@ public:
Node* shadowTreeRootNode() const;
IntRect boundingBox();
- void addLineBoxRects(Vector<IntRect>&, bool useSelectionHeight = false);
+ void textRects(Vector<IntRect>&, bool useSelectionHeight = false);
void nodeChildrenChanged(ContainerNode*);
void nodeWillBeRemoved(Node*);
diff --git a/src/3rdparty/webkit/WebCore/dom/Range.idl b/src/3rdparty/webkit/WebCore/dom/Range.idl
index 4344474..0750c32 100644
--- a/src/3rdparty/webkit/WebCore/dom/Range.idl
+++ b/src/3rdparty/webkit/WebCore/dom/Range.idl
@@ -112,7 +112,7 @@ module ranges {
in long offset)
raises(RangeException, DOMException);
-#if !defined(LANGUAGE_JAVASCRIPT)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
readonly attribute DOMString text;
#endif
};
diff --git a/src/3rdparty/webkit/WebCore/dom/RangeBoundaryPoint.h b/src/3rdparty/webkit/WebCore/dom/RangeBoundaryPoint.h
index 4cb7bf5..1bbbe1a 100644
--- a/src/3rdparty/webkit/WebCore/dom/RangeBoundaryPoint.h
+++ b/src/3rdparty/webkit/WebCore/dom/RangeBoundaryPoint.h
@@ -33,10 +33,10 @@ namespace WebCore {
class RangeBoundaryPoint {
public:
- RangeBoundaryPoint();
explicit RangeBoundaryPoint(PassRefPtr<Node> container);
- const Position& position() const;
+ const Position toPosition() const;
+
Node* container() const;
int offset() const;
Node* childBefore() const;
@@ -45,122 +45,131 @@ public:
void set(PassRefPtr<Node> container, int offset, Node* childBefore);
void setOffset(int offset);
- void setToChild(Node* child);
- void setToStart(PassRefPtr<Node> container);
- void setToEnd(PassRefPtr<Node> container);
+
+ void setToBeforeChild(Node*);
+ void setToStartOfNode(PassRefPtr<Node>);
+ void setToEndOfNode(PassRefPtr<Node>);
void childBeforeWillBeRemoved();
void invalidateOffset() const;
+ void ensureOffsetIsValid() const;
private:
static const int invalidOffset = -1;
-
- mutable Position m_position;
- Node* m_childBefore;
+
+ RefPtr<Node> m_containerNode;
+ mutable int m_offsetInContainer;
+ Node* m_childBeforeBoundary;
};
-inline RangeBoundaryPoint::RangeBoundaryPoint()
- : m_childBefore(0)
-{
-}
-
inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
- : m_position(container, 0)
- , m_childBefore(0)
+ : m_containerNode(container)
+ , m_offsetInContainer(0)
+ , m_childBeforeBoundary(0)
{
+ ASSERT(m_containerNode);
}
inline Node* RangeBoundaryPoint::container() const
{
- return m_position.container.get();
+ return m_containerNode.get();
}
inline Node* RangeBoundaryPoint::childBefore() const
{
- return m_childBefore;
+ return m_childBeforeBoundary;
}
-inline const Position& RangeBoundaryPoint::position() const
+inline void RangeBoundaryPoint::ensureOffsetIsValid() const
{
- if (m_position.posOffset >= 0)
- return m_position;
- ASSERT(m_childBefore);
- m_position.posOffset = m_childBefore->nodeIndex() + 1;
- return m_position;
+ if (m_offsetInContainer >= 0)
+ return;
+
+ ASSERT(m_childBeforeBoundary);
+ m_offsetInContainer = m_childBeforeBoundary->nodeIndex() + 1;
+}
+
+inline const Position RangeBoundaryPoint::toPosition() const
+{
+ ensureOffsetIsValid();
+ return Position(m_containerNode.get(), m_offsetInContainer);
}
inline int RangeBoundaryPoint::offset() const
{
- return position().posOffset;
+ ensureOffsetIsValid();
+ return m_offsetInContainer;
}
inline void RangeBoundaryPoint::clear()
{
- m_position.clear();
- m_childBefore = 0;
+ m_containerNode.clear();
+ m_offsetInContainer = 0;
+ m_childBeforeBoundary = 0;
}
inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node* childBefore)
{
+ ASSERT(container);
ASSERT(offset >= 0);
ASSERT(childBefore == (offset ? container->childNode(offset - 1) : 0));
- m_position.container = container;
- m_position.posOffset = offset;
- m_childBefore = childBefore;
+ m_containerNode = container;
+ m_offsetInContainer = offset;
+ m_childBeforeBoundary = childBefore;
}
inline void RangeBoundaryPoint::setOffset(int offset)
{
- ASSERT(m_position.container);
- ASSERT(m_position.container->offsetInCharacters());
- ASSERT(m_position.posOffset >= 0);
- ASSERT(!m_childBefore);
- m_position.posOffset = offset;
+ ASSERT(m_containerNode);
+ ASSERT(m_containerNode->offsetInCharacters());
+ ASSERT(m_offsetInContainer >= 0);
+ ASSERT(!m_childBeforeBoundary);
+ m_offsetInContainer = offset;
}
-inline void RangeBoundaryPoint::setToChild(Node* child)
+inline void RangeBoundaryPoint::setToBeforeChild(Node* child)
{
ASSERT(child);
ASSERT(child->parentNode());
- m_position.container = child->parentNode();
- m_childBefore = child->previousSibling();
- m_position.posOffset = m_childBefore ? invalidOffset : 0;
+ m_childBeforeBoundary = child->previousSibling();
+ m_containerNode = child->parentNode();
+ m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
}
-inline void RangeBoundaryPoint::setToStart(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToStartOfNode(PassRefPtr<Node> container)
{
ASSERT(container);
- m_position.container = container;
- m_position.posOffset = 0;
- m_childBefore = 0;
+ m_containerNode = container;
+ m_offsetInContainer = 0;
+ m_childBeforeBoundary = 0;
}
-inline void RangeBoundaryPoint::setToEnd(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToEndOfNode(PassRefPtr<Node> container)
{
ASSERT(container);
- m_position.container = container;
- if (m_position.container->offsetInCharacters()) {
- m_position.posOffset = m_position.container->maxCharacterOffset();
- m_childBefore = 0;
+ m_containerNode = container;
+ if (m_containerNode->offsetInCharacters()) {
+ m_offsetInContainer = m_containerNode->maxCharacterOffset();
+ m_childBeforeBoundary = 0;
} else {
- m_childBefore = m_position.container->lastChild();
- m_position.posOffset = m_childBefore ? invalidOffset : 0;
+ m_childBeforeBoundary = m_containerNode->lastChild();
+ m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
}
}
inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
{
- ASSERT(m_position.posOffset);
- m_childBefore = m_childBefore->previousSibling();
- if (!m_childBefore)
- m_position.posOffset = 0;
- else if (m_position.posOffset > 0)
- --m_position.posOffset;
+ ASSERT(m_offsetInContainer);
+ m_childBeforeBoundary = m_childBeforeBoundary->previousSibling();
+ if (!m_childBeforeBoundary)
+ m_offsetInContainer = 0;
+ else if (m_offsetInContainer > 0)
+ --m_offsetInContainer;
}
inline void RangeBoundaryPoint::invalidateOffset() const
{
- m_position.posOffset = invalidOffset;
+ m_offsetInContainer = invalidOffset;
}
inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
diff --git a/src/3rdparty/webkit/WebCore/dom/RangeException.idl b/src/3rdparty/webkit/WebCore/dom/RangeException.idl
index 36cde16..d2cf385 100644
--- a/src/3rdparty/webkit/WebCore/dom/RangeException.idl
+++ b/src/3rdparty/webkit/WebCore/dom/RangeException.idl
@@ -27,7 +27,7 @@ module ranges {
readonly attribute DOMString name;
readonly attribute DOMString message;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
[DontEnum] DOMString toString();
#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h
index 29b061d..479c2ff 100644
--- a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h
+++ b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h
@@ -25,11 +25,10 @@
#define RegisteredEventListener_h
#include "AtomicString.h"
+#include "EventListener.h"
namespace WebCore {
- class EventListener;
-
class RegisteredEventListener : public RefCounted<RegisteredEventListener> {
public:
static PassRefPtr<RegisteredEventListener> create(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
@@ -53,6 +52,25 @@ namespace WebCore {
bool m_removed;
};
+ typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector;
+
+#if USE(JSC)
+ inline void markEventListeners(const RegisteredEventListenerVector& listeners)
+ {
+ for (size_t i = 0; i < listeners.size(); ++i)
+ listeners[i]->listener()->markJSFunction();
+ }
+
+ inline void invalidateEventListeners(const RegisteredEventListenerVector& listeners)
+ {
+ // For efficiency's sake, we just set the "removed" bit, instead of
+ // actually removing the event listener. The node that owns these
+ // listeners is about to be deleted, anyway.
+ for (size_t i = 0; i < listeners.size(); ++i)
+ listeners[i]->setRemoved(true);
+ }
+#endif
+
} // namespace WebCore
#endif // RegisteredEventListener_h
diff --git a/src/3rdparty/webkit/WebCore/dom/ScriptElement.cpp b/src/3rdparty/webkit/WebCore/dom/ScriptElement.cpp
index aeadc41..fe38b46 100644
--- a/src/3rdparty/webkit/WebCore/dom/ScriptElement.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/ScriptElement.cpp
@@ -29,6 +29,8 @@
#include "Document.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "HTMLNames.h"
+#include "HTMLScriptElement.h"
#include "MIMETypeRegistry.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
@@ -37,6 +39,11 @@
#include "Text.h"
#include <wtf/StdLibExtras.h>
+#if ENABLE(SVG)
+#include "SVGNames.h"
+#include "SVGScriptElement.h"
+#endif
+
namespace WebCore {
void ScriptElement::insertedIntoDocument(ScriptElementData& data, const String& sourceUrl)
@@ -121,6 +128,7 @@ ScriptElementData::ScriptElementData(ScriptElement* scriptElement, Element* elem
, m_element(element)
, m_cachedScript(0)
, m_createdByParser(false)
+ , m_requested(false)
, m_evaluated(false)
, m_firedLoad(false)
{
@@ -145,6 +153,7 @@ void ScriptElementData::requestScript(const String& sourceUrl)
ASSERT(!m_cachedScript);
m_cachedScript = document->docLoader()->requestScript(sourceUrl, scriptCharset());
+ m_requested = true;
// m_createdByParser is never reset - always resied at the initial value set while parsing.
// m_evaluated is left untouched as well to avoid script reexecution, if a <script> element
@@ -171,7 +180,7 @@ void ScriptElementData::evaluateScript(const ScriptSourceCode& sourceCode)
m_evaluated = true;
frame->script()->evaluate(sourceCode);
- Document::updateDocumentsRendering();
+ Document::updateStyleForAllDocuments();
}
}
@@ -183,28 +192,28 @@ void ScriptElementData::stopLoadRequest()
}
}
-void ScriptElementData::notifyFinished(CachedResource* o)
+void ScriptElementData::execute(CachedScript* cachedScript)
{
- CachedScript* cs = static_cast<CachedScript*>(o);
- ASSERT(cs == m_cachedScript);
-
- // Evaluating the script could lead to a garbage collection which can
- // delete the script element so we need to protect it and us with it!
- RefPtr<Element> protector(m_element);
-
- if (cs->errorOccurred())
+ ASSERT(cachedScript);
+ if (cachedScript->errorOccurred())
m_scriptElement->dispatchErrorEvent();
else {
- evaluateScript(ScriptSourceCode(cs));
+ evaluateScript(ScriptSourceCode(cachedScript));
m_scriptElement->dispatchLoadEvent();
}
+ cachedScript->removeClient(this);
+}
- stopLoadRequest();
+void ScriptElementData::notifyFinished(CachedResource* o)
+{
+ ASSERT_UNUSED(o, o == m_cachedScript);
+ m_element->document()->executeScriptSoon(this, m_cachedScript);
+ m_cachedScript = 0;
}
bool ScriptElementData::ignoresLoadRequest() const
{
- return m_evaluated || m_cachedScript || m_createdByParser || !m_element->inDocument();
+ return m_evaluated || m_requested || m_createdByParser || !m_element->inDocument();
}
bool ScriptElementData::shouldExecuteAsJavaScript() const
@@ -224,8 +233,15 @@ bool ScriptElementData::shouldExecuteAsJavaScript() const
if (!language.isEmpty())
return isSupportedJavaScriptLanguage(language);
- // No type or language is specified, so we assume the script to be JavaScript
- return true;
+ // No type or language is specified, so we assume the script to be JavaScript.
+ // We don't yet support setting event listeners via the 'for' attribute for scripts.
+ // If there is such an attribute it's likely better to not execute the script than to do so
+ // immediately and unconditionally.
+ // FIXME: After <rdar://problem/4471751> / https://bugs.webkit.org/show_bug.cgi?id=16915 are resolved
+ // and we support the for syntax in script tags, this check can be removed and we should just
+ // return 'true' here.
+ String forAttribute = m_scriptElement->forAttributeValue();
+ return forAttribute.isEmpty();
}
String ScriptElementData::scriptCharset() const
@@ -269,4 +285,17 @@ String ScriptElementData::scriptContent() const
return String::adopt(val);
}
+ScriptElement* toScriptElement(Element* element)
+{
+ if (element->isHTMLElement() && element->hasTagName(HTMLNames::scriptTag))
+ return static_cast<HTMLScriptElement*>(element);
+
+#if ENABLE(SVG)
+ if (element->isSVGElement() && element->hasTagName(SVGNames::scriptTag))
+ return static_cast<SVGScriptElement*>(element);
+#endif
+
+ return 0;
+}
+
}
diff --git a/src/3rdparty/webkit/WebCore/dom/ScriptElement.h b/src/3rdparty/webkit/WebCore/dom/ScriptElement.h
index 73cd077..0aed5e8 100644
--- a/src/3rdparty/webkit/WebCore/dom/ScriptElement.h
+++ b/src/3rdparty/webkit/WebCore/dom/ScriptElement.h
@@ -42,6 +42,7 @@ public:
virtual String charsetAttributeValue() const = 0;
virtual String typeAttributeValue() const = 0;
virtual String languageAttributeValue() const = 0;
+ virtual String forAttributeValue() const = 0;
virtual void dispatchLoadEvent() = 0;
virtual void dispatchErrorEvent() = 0;
@@ -49,6 +50,8 @@ public:
// A charset for loading the script (may be overridden by HTTP headers or a BOM).
virtual String scriptCharset() const = 0;
+ virtual bool shouldExecuteAsJavaScript() const = 0;
+
protected:
// Helper functions used by our parent classes.
static void insertedIntoDocument(ScriptElementData&, const String& sourceUrl);
@@ -81,6 +84,8 @@ public:
void evaluateScript(const ScriptSourceCode&);
void stopLoadRequest();
+ void execute(CachedScript*);
+
private:
virtual void notifyFinished(CachedResource*);
@@ -89,10 +94,13 @@ private:
Element* m_element;
CachedResourceHandle<CachedScript> m_cachedScript;
bool m_createdByParser;
+ bool m_requested;
bool m_evaluated;
bool m_firedLoad;
};
+ScriptElement* toScriptElement(Element*);
+
}
#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.cpp b/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.cpp
index 1d1aaec..45d4e23 100644
--- a/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.cpp
@@ -88,7 +88,7 @@ void ScriptExecutionContext::dispatchMessagePortEvents()
MessagePort* port = ports[i];
// The port may be destroyed, and another one created at the same address, but this is safe, as the worst that can happen
// as a result is that dispatchMessages() will be called needlessly.
- if (m_messagePorts.contains(port) && port->queueIsOpen())
+ if (m_messagePorts.contains(port) && port->started())
port->dispatchMessages();
}
}
@@ -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/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.h b/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.h
index 2e9d56c..7b2f36a 100644
--- a/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.h
+++ b/src/3rdparty/webkit/WebCore/dom/ScriptExecutionContext.h
@@ -27,6 +27,7 @@
#ifndef ScriptExecutionContext_h
#define ScriptExecutionContext_h
+#include "Console.h"
#include "KURL.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -36,10 +37,17 @@
namespace WebCore {
class ActiveDOMObject;
+ class DOMTimer;
class MessagePort;
class SecurityOrigin;
+ class ScriptString;
class String;
+ enum MessageDestination {
+ InspectorControllerDestination,
+ ConsoleDestination,
+ };
+
class ScriptExecutionContext {
public:
ScriptExecutionContext();
@@ -51,10 +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' -
@@ -85,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
@@ -101,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/src/3rdparty/webkit/WebCore/dom/SelectElement.cpp b/src/3rdparty/webkit/WebCore/dom/SelectElement.cpp
new file mode 100644
index 0000000..1831f3a
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/SelectElement.cpp
@@ -0,0 +1,932 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "SelectElement.h"
+
+#include "CharacterNames.h"
+#include "ChromeClient.h"
+#include "Element.h"
+#include "EventHandler.h"
+#include "EventNames.h"
+#include "FormDataList.h"
+#include "Frame.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "HTMLKeygenElement.h"
+#include "HTMLSelectElement.h"
+#include "KeyboardEvent.h"
+#include "MappedAttribute.h"
+#include "MouseEvent.h"
+#include "OptionElement.h"
+#include "OptionGroupElement.h"
+#include "Page.h"
+#include "RenderListBox.h"
+#include "RenderMenuList.h"
+#include <wtf/Assertions.h>
+
+#if ENABLE(WML)
+#include "WMLNames.h"
+#include "WMLSelectElement.h"
+#endif
+
+#if PLATFORM(MAC)
+#define ARROW_KEYS_POP_MENU 1
+#else
+#define ARROW_KEYS_POP_MENU 0
+#endif
+
+using std::min;
+using std::max;
+using namespace WTF;
+using namespace Unicode;
+
+namespace WebCore {
+
+static const DOMTimeStamp typeAheadTimeout = 1000;
+
+void SelectElement::selectAll(SelectElementData& data, Element* element)
+{
+ ASSERT(!data.usesMenuList());
+ if (!element->renderer() || !data.multiple())
+ return;
+
+ // Save the selection so it can be compared to the new selectAll selection when dispatching change events
+ saveLastSelection(data, element);
+
+ data.setActiveSelectionState(true);
+ setActiveSelectionAnchorIndex(data, element, nextSelectableListIndex(data, element, -1));
+ setActiveSelectionEndIndex(data, previousSelectableListIndex(data, element, -1));
+
+ updateListBoxSelection(data, element, false);
+ listBoxOnChange(data, element);
+}
+
+void SelectElement::saveLastSelection(SelectElementData& data, Element* element)
+{
+ if (data.usesMenuList()) {
+ data.setLastOnChangeIndex(selectedIndex(data, element));
+ return;
+ }
+
+ Vector<bool>& lastOnChangeSelection = data.lastOnChangeSelection();
+ lastOnChangeSelection.clear();
+
+ const Vector<Element*>& items = data.listItems(element);
+ for (unsigned i = 0; i < items.size(); ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ lastOnChangeSelection.append(optionElement && optionElement->selected());
+ }
+}
+
+int SelectElement::nextSelectableListIndex(SelectElementData& data, Element* element, int startIndex)
+{
+ const Vector<Element*>& items = data.listItems(element);
+ int index = startIndex + 1;
+ while (index >= 0 && (unsigned) index < items.size() && (!isOptionElement(items[index]) || items[index]->disabled()))
+ ++index;
+ if ((unsigned) index == items.size())
+ return startIndex;
+ return index;
+}
+
+int SelectElement::previousSelectableListIndex(SelectElementData& data, Element* element, int startIndex)
+{
+ const Vector<Element*>& items = data.listItems(element);
+ if (startIndex == -1)
+ startIndex = items.size();
+ int index = startIndex - 1;
+ while (index >= 0 && (unsigned) index < items.size() && (!isOptionElement(items[index]) || items[index]->disabled()))
+ --index;
+ if (index == -1)
+ return startIndex;
+ return index;
+}
+
+void SelectElement::setActiveSelectionAnchorIndex(SelectElementData& data, Element* element, int index)
+{
+ data.setActiveSelectionAnchorIndex(index);
+
+ // Cache the selection state so we can restore the old selection as the new selection pivots around this anchor index
+ Vector<bool>& cachedStateForActiveSelection = data.cachedStateForActiveSelection();
+ cachedStateForActiveSelection.clear();
+
+ const Vector<Element*>& items = data.listItems(element);
+ for (unsigned i = 0; i < items.size(); ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ cachedStateForActiveSelection.append(optionElement && optionElement->selected());
+ }
+}
+
+void SelectElement::setActiveSelectionEndIndex(SelectElementData& data, int index)
+{
+ data.setActiveSelectionEndIndex(index);
+}
+
+void SelectElement::updateListBoxSelection(SelectElementData& data, Element* element, bool deselectOtherOptions)
+{
+ ASSERT(element->renderer() && element->renderer()->isListBox());
+ ASSERT(data.activeSelectionAnchorIndex() >= 0);
+
+ unsigned start = min(data.activeSelectionAnchorIndex(), data.activeSelectionEndIndex());
+ unsigned end = max(data.activeSelectionAnchorIndex(), data.activeSelectionEndIndex());
+ Vector<bool>& cachedStateForActiveSelection = data.cachedStateForActiveSelection();
+
+ const Vector<Element*>& items = data.listItems(element);
+ for (unsigned i = 0; i < items.size(); ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ if (!optionElement || items[i]->disabled())
+ continue;
+
+ if (i >= start && i <= end)
+ optionElement->setSelectedState(data.activeSelectionState());
+ else if (deselectOtherOptions || i >= cachedStateForActiveSelection.size())
+ optionElement->setSelectedState(false);
+ else
+ optionElement->setSelectedState(cachedStateForActiveSelection[i]);
+ }
+
+ scrollToSelection(data, element);
+}
+
+void SelectElement::listBoxOnChange(SelectElementData& data, Element* element)
+{
+ ASSERT(!data.usesMenuList());
+
+ Vector<bool>& lastOnChangeSelection = data.lastOnChangeSelection();
+ const Vector<Element*>& items = data.listItems(element);
+
+ // If the cached selection list is empty, or the size has changed, then fire dispatchFormControlChangeEvent, and return early.
+ if (lastOnChangeSelection.isEmpty() || lastOnChangeSelection.size() != items.size()) {
+ element->dispatchFormControlChangeEvent();
+ return;
+ }
+
+ // Update lastOnChangeSelection and fire dispatchFormControlChangeEvent
+ bool fireOnChange = false;
+ for (unsigned i = 0; i < items.size(); ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ bool selected = optionElement && optionElement->selected();
+ if (selected != lastOnChangeSelection[i])
+ fireOnChange = true;
+ lastOnChangeSelection[i] = selected;
+ }
+
+ if (fireOnChange)
+ element->dispatchFormControlChangeEvent();
+}
+
+void SelectElement::menuListOnChange(SelectElementData& data, Element* element)
+{
+ ASSERT(data.usesMenuList());
+
+ int selected = selectedIndex(data, element);
+ if (data.lastOnChangeIndex() != selected && data.userDrivenChange()) {
+ data.setLastOnChangeIndex(selected);
+ data.setUserDrivenChange(false);
+ element->dispatchFormControlChangeEvent();
+ }
+}
+
+void SelectElement::scrollToSelection(SelectElementData& data, Element* element)
+{
+ if (data.usesMenuList())
+ return;
+
+ if (RenderObject* renderer = element->renderer())
+ static_cast<RenderListBox*>(renderer)->selectionChanged();
+}
+
+void SelectElement::recalcStyle(SelectElementData& data, Element* element)
+{
+ RenderObject* renderer = element->renderer();
+ if (element->childNeedsStyleRecalc() && renderer) {
+ if (data.usesMenuList())
+ static_cast<RenderMenuList*>(renderer)->setOptionsChanged(true);
+ else
+ static_cast<RenderListBox*>(renderer)->setOptionsChanged(true);
+ } else if (data.shouldRecalcListItems())
+ recalcListItems(data, element);
+}
+
+void SelectElement::setRecalcListItems(SelectElementData& data, Element* element)
+{
+ data.setShouldRecalcListItems(true);
+ data.setActiveSelectionAnchorIndex(-1); // Manual selection anchor is reset when manipulating the select programmatically.
+ if (RenderObject* renderer = element->renderer()) {
+ if (data.usesMenuList())
+ static_cast<RenderMenuList*>(renderer)->setOptionsChanged(true);
+ else
+ static_cast<RenderListBox*>(renderer)->setOptionsChanged(true);
+ }
+ element->setNeedsStyleRecalc();
+}
+
+void SelectElement::recalcListItems(SelectElementData& data, const Element* element, bool updateSelectedStates)
+{
+ Vector<Element*>& listItems = data.rawListItems();
+ listItems.clear();
+
+ OptionElement* foundSelected = 0;
+ for (Node* currentNode = element->firstChild(); currentNode;) {
+ if (!currentNode->isElementNode()) {
+ currentNode = currentNode->traverseNextSibling(element);
+ continue;
+ }
+
+ Element* current = static_cast<Element*>(currentNode);
+
+ // optgroup tags may not nest. However, both FireFox and IE will
+ // flatten the tree automatically, so we follow suit.
+ // (http://www.w3.org/TR/html401/interact/forms.html#h-17.6)
+ if (isOptionGroupElement(current)) {
+ listItems.append(current);
+ if (current->firstChild()) {
+ currentNode = current->firstChild();
+ continue;
+ }
+ }
+
+ if (OptionElement* optionElement = toOptionElement(current)) {
+ listItems.append(current);
+
+ if (updateSelectedStates) {
+ if (!foundSelected && (data.usesMenuList() || (!data.multiple() && optionElement->selected()))) {
+ foundSelected = optionElement;
+ foundSelected->setSelectedState(true);
+ } else if (foundSelected && !data.multiple() && optionElement->selected()) {
+ foundSelected->setSelectedState(false);
+ foundSelected = optionElement;
+ }
+ }
+ }
+
+ if (current->hasTagName(HTMLNames::hrTag))
+ listItems.append(current);
+
+ // In conforming HTML code, only <optgroup> and <option> will be found
+ // within a <select>. We call traverseNextSibling so that we only step
+ // into those tags that we choose to. For web-compat, we should cope
+ // with the case where odd tags like a <div> have been added but we
+ // handle this because such tags have already been removed from the
+ // <select>'s subtree at this point.
+ currentNode = currentNode->traverseNextSibling(element);
+ }
+
+ data.setShouldRecalcListItems(false);
+}
+
+int SelectElement::selectedIndex(const SelectElementData& data, const Element* element)
+{
+ unsigned index = 0;
+
+ // return the number of the first option selected
+ const Vector<Element*>& items = data.listItems(element);
+ for (size_t i = 0; i < items.size(); ++i) {
+ if (OptionElement* optionElement = toOptionElement(items[i])) {
+ if (optionElement->selected())
+ return index;
+ ++index;
+ }
+ }
+
+ return -1;
+}
+
+void SelectElement::setSelectedIndex(SelectElementData& data, Element* element, int optionIndex, bool deselect, bool fireOnChangeNow, bool userDrivenChange)
+{
+ const Vector<Element*>& items = data.listItems(element);
+ int listIndex = optionToListIndex(data, element, optionIndex);
+ if (!data.multiple())
+ deselect = true;
+
+ Element* excludeElement = 0;
+ if (OptionElement* optionElement = (listIndex >= 0 ? toOptionElement(items[listIndex]) : 0)) {
+ excludeElement = items[listIndex];
+ if (data.activeSelectionAnchorIndex() < 0 || deselect)
+ setActiveSelectionAnchorIndex(data, element, listIndex);
+ if (data.activeSelectionEndIndex() < 0 || deselect)
+ setActiveSelectionEndIndex(data, listIndex);
+ optionElement->setSelectedState(true);
+ }
+
+ if (deselect)
+ deselectItems(data, element, excludeElement);
+
+ // For the menu list case, this is what makes the selected element appear.
+ if (RenderObject* renderer = element->renderer())
+ renderer->updateFromElement();
+
+ scrollToSelection(data, element);
+
+ // This only gets called with fireOnChangeNow for menu lists.
+ if (data.usesMenuList()) {
+ data.setUserDrivenChange(userDrivenChange);
+ if (fireOnChangeNow)
+ menuListOnChange(data, element);
+ }
+
+ if (Frame* frame = element->document()->frame())
+ frame->page()->chrome()->client()->formStateDidChange(element);
+}
+
+int SelectElement::optionToListIndex(const SelectElementData& data, const Element* element, int optionIndex)
+{
+ const Vector<Element*>& items = data.listItems(element);
+ int listSize = (int) items.size();
+ if (optionIndex < 0 || optionIndex >= listSize)
+ return -1;
+
+ int optionIndex2 = -1;
+ for (int listIndex = 0; listIndex < listSize; ++listIndex) {
+ if (isOptionElement(items[listIndex])) {
+ ++optionIndex2;
+ if (optionIndex2 == optionIndex)
+ return listIndex;
+ }
+ }
+
+ return -1;
+}
+
+int SelectElement::listToOptionIndex(const SelectElementData& data, const Element* element, int listIndex)
+{
+ const Vector<Element*>& items = data.listItems(element);
+ if (listIndex < 0 || listIndex >= int(items.size()) ||
+ !isOptionElement(items[listIndex]))
+ return -1;
+
+ int optionIndex = 0; // actual index of option not counting OPTGROUP entries that may be in list
+ for (int i = 0; i < listIndex; ++i)
+ if (isOptionElement(items[i]))
+ ++optionIndex;
+
+ return optionIndex;
+}
+
+void SelectElement::dispatchFocusEvent(SelectElementData& data, Element* element)
+{
+ // Save the selection so it can be compared to the new selection when dispatching change events during blur event dispatchal
+ if (data.usesMenuList())
+ saveLastSelection(data, element);
+}
+
+void SelectElement::dispatchBlurEvent(SelectElementData& data, Element* element)
+{
+ // We only need to fire change events here for menu lists, because we fire change events for list boxes whenever the selection change is actually made.
+ // This matches other browsers' behavior.
+ if (data.usesMenuList())
+ menuListOnChange(data, element);
+}
+
+void SelectElement::deselectItems(SelectElementData& data, Element* element, Element* excludeElement)
+{
+ const Vector<Element*>& items = data.listItems(element);
+ for (unsigned i = 0; i < items.size(); ++i) {
+ if (items[i] == excludeElement)
+ continue;
+
+ if (OptionElement* optionElement = toOptionElement(items[i]))
+ optionElement->setSelectedState(false);
+ }
+}
+
+bool SelectElement::saveFormControlState(const SelectElementData& data, const Element* element, String& value)
+{
+ const Vector<Element*>& items = data.listItems(element);
+ int length = items.size();
+
+ // FIXME: Change this code to use the new StringImpl::createUninitialized code path.
+ Vector<char, 1024> characters(length);
+ for (int i = 0; i < length; ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ bool selected = optionElement && optionElement->selected();
+ characters[i] = selected ? 'X' : '.';
+ }
+
+ value = String(characters.data(), length);
+ return true;
+}
+
+void SelectElement::restoreFormControlState(SelectElementData& data, Element* element, const String& state)
+{
+ recalcListItems(data, element);
+
+ const Vector<Element*>& items = data.listItems(element);
+ int length = items.size();
+
+ for (int i = 0; i < length; ++i) {
+ if (OptionElement* optionElement = toOptionElement(items[i]))
+ optionElement->setSelectedState(state[i] == 'X');
+ }
+
+ element->setNeedsStyleRecalc();
+}
+
+void SelectElement::parseMultipleAttribute(SelectElementData& data, Element* element, MappedAttribute* attribute)
+{
+ bool oldUsesMenuList = data.usesMenuList();
+ data.setMultiple(!attribute->isNull());
+ if (oldUsesMenuList != data.usesMenuList() && element->attached()) {
+ element->detach();
+ element->attach();
+ }
+}
+
+bool SelectElement::appendFormData(SelectElementData& data, Element* element, FormDataList& list)
+{
+ const AtomicString& name = element->formControlName();
+ if (name.isEmpty())
+ return false;
+
+ bool successful = false;
+ const Vector<Element*>& items = data.listItems(element);
+
+ for (unsigned i = 0; i < items.size(); ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ if (optionElement && optionElement->selected()) {
+ list.appendData(name, optionElement->value());
+ successful = true;
+ }
+ }
+
+ // FIXME: This case should not happen. Make sure that we select the first option
+ // in any case, otherwise we have no consistency with the DOM interface.
+ // We return the first one if it was a combobox select
+ if (!successful && !data.multiple() && data.size() <= 1 && items.size()) {
+ OptionElement* optionElement = toOptionElement(items[0]);
+ const AtomicString& value = optionElement->value();
+ if (value.isNull())
+ list.appendData(name, optionElement->text().stripWhiteSpace());
+ else
+ list.appendData(name, value);
+ successful = true;
+ }
+
+ return successful;
+}
+
+void SelectElement::reset(SelectElementData& data, Element* element)
+{
+ bool optionSelected = false;
+ OptionElement* firstOption = 0;
+
+ const Vector<Element*>& items = data.listItems(element);
+ for (unsigned i = 0; i < items.size(); ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ if (!optionElement)
+ continue;
+
+ if (!items[i]->getAttribute(HTMLNames::selectedAttr).isNull()) {
+ optionElement->setSelectedState(true);
+ optionSelected = true;
+ } else
+ optionElement->setSelectedState(false);
+
+ if (!firstOption)
+ firstOption = optionElement;
+ }
+
+ if (!optionSelected && firstOption && data.usesMenuList())
+ firstOption->setSelectedState(true);
+
+ element->setNeedsStyleRecalc();
+}
+
+void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm)
+{
+#if !ARROW_KEYS_POP_MENU
+ UNUSED_PARAM(htmlForm);
+#endif
+
+ if (event->type() == eventNames().keydownEvent) {
+ if (!element->renderer() || !event->isKeyboardEvent())
+ return;
+
+ String keyIdentifier = static_cast<KeyboardEvent*>(event)->keyIdentifier();
+ bool handled = false;
+
+#if ARROW_KEYS_POP_MENU
+ if (keyIdentifier == "Down" || keyIdentifier == "Up") {
+ element->focus();
+ // Save the selection so it can be compared to the new selection when dispatching change events during setSelectedIndex,
+ // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
+ saveLastSelection(data, element);
+ if (RenderMenuList* menuList = static_cast<RenderMenuList*>(element->renderer()))
+ menuList->showPopup();
+ handled = true;
+ }
+#else
+ const Vector<Element*>& listItems = data.listItems(element);
+ int size = listItems.size();
+
+ int listIndex = optionToListIndex(data, element, selectedIndex(data, element));
+ if (keyIdentifier == "Down" || keyIdentifier == "Right") {
+ for (listIndex += 1;
+ listIndex >= 0 && listIndex < size && (listItems[listIndex]->disabled() || !isOptionElement(listItems[listIndex]));
+ ++listIndex) { }
+ if (listIndex >= 0 && listIndex < size)
+ setSelectedIndex(data, element, listToOptionIndex(data, element, listIndex));
+ handled = true;
+ } else if (keyIdentifier == "Up" || keyIdentifier == "Left") {
+ for (listIndex -= 1;
+ listIndex >= 0 && listIndex < size && (listItems[listIndex]->disabled() || !isOptionElement(listItems[listIndex]));
+ --listIndex) { }
+ if (listIndex >= 0 && listIndex < size)
+ setSelectedIndex(data, element, listToOptionIndex(data, element, listIndex));
+ handled = true;
+ }
+#endif
+ if (handled)
+ event->setDefaultHandled();
+ }
+
+ // Use key press event here since sending simulated mouse events
+ // on key down blocks the proper sending of the key press event.
+ if (event->type() == eventNames().keypressEvent) {
+ if (!element->renderer() || !event->isKeyboardEvent())
+ return;
+
+ int keyCode = static_cast<KeyboardEvent*>(event)->keyCode();
+ bool handled = false;
+
+#if ARROW_KEYS_POP_MENU
+ if (keyCode == ' ') {
+ element->focus();
+ // Save the selection so it can be compared to the new selection when dispatching change events during setSelectedIndex,
+ // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
+ saveLastSelection(data, element);
+ if (RenderMenuList* menuList = static_cast<RenderMenuList*>(element->renderer()))
+ menuList->showPopup();
+ handled = true;
+ } else if (keyCode == '\r') {
+ menuListOnChange(data, element);
+ if (htmlForm)
+ htmlForm->submitClick(event);
+ handled = true;
+ }
+#else
+ int listIndex = optionToListIndex(data, element, selectedIndex(data, element));
+ if (keyCode == '\r') {
+ // listIndex should already be selected, but this will fire the onchange handler.
+ setSelectedIndex(data, element, listToOptionIndex(data, element, listIndex), true, true);
+ handled = true;
+ }
+#endif
+ if (handled)
+ event->setDefaultHandled();
+ }
+
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ element->focus();
+ if (RenderMenuList* menuList = static_cast<RenderMenuList*>(element->renderer())) {
+ if (menuList->popupIsVisible())
+ menuList->hidePopup();
+ else {
+ // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
+ // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
+ saveLastSelection(data, element);
+ menuList->showPopup();
+ }
+ }
+ event->setDefaultHandled();
+ }
+}
+
+void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm)
+{
+ const Vector<Element*>& listItems = data.listItems(element);
+
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ element->focus();
+
+ // Convert to coords relative to the list box if needed.
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ IntPoint localOffset = roundedIntPoint(element->renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
+ int listIndex = static_cast<RenderListBox*>(element->renderer())->listIndexAtOffset(localOffset.x(), localOffset.y());
+ if (listIndex >= 0) {
+ // Save the selection so it can be compared to the new selection when dispatching change events during mouseup, or after autoscroll finishes.
+ saveLastSelection(data, element);
+
+ data.setActiveSelectionState(true);
+
+ bool multiSelectKeyPressed = false;
+#if PLATFORM(MAC)
+ multiSelectKeyPressed = mouseEvent->metaKey();
+#else
+ multiSelectKeyPressed = mouseEvent->ctrlKey();
+#endif
+
+ bool shiftSelect = data.multiple() && mouseEvent->shiftKey();
+ bool multiSelect = data.multiple() && multiSelectKeyPressed && !mouseEvent->shiftKey();
+
+ Element* clickedElement = listItems[listIndex];
+ OptionElement* option = toOptionElement(clickedElement);
+ if (option) {
+ // Keep track of whether an active selection (like during drag selection), should select or deselect
+ if (option->selected() && multiSelectKeyPressed)
+ data.setActiveSelectionState(false);
+
+ if (!data.activeSelectionState())
+ option->setSelectedState(false);
+ }
+
+ // If we're not in any special multiple selection mode, then deselect all other items, excluding the clicked option.
+ // If no option was clicked, then this will deselect all items in the list.
+ if (!shiftSelect && !multiSelect)
+ deselectItems(data, element, clickedElement);
+
+ // If the anchor hasn't been set, and we're doing a single selection or a shift selection, then initialize the anchor to the first selected index.
+ if (data.activeSelectionAnchorIndex() < 0 && !multiSelect)
+ setActiveSelectionAnchorIndex(data, element, selectedIndex(data, element));
+
+ // Set the selection state of the clicked option
+ if (option && !clickedElement->disabled())
+ option->setSelectedState(true);
+
+ // If there was no selectedIndex() for the previous initialization, or
+ // If we're doing a single selection, or a multiple selection (using cmd or ctrl), then initialize the anchor index to the listIndex that just got clicked.
+ if (listIndex >= 0 && (data.activeSelectionAnchorIndex() < 0 || !shiftSelect))
+ setActiveSelectionAnchorIndex(data, element, listIndex);
+
+ setActiveSelectionEndIndex(data, listIndex);
+ updateListBoxSelection(data, element, !multiSelect);
+
+ if (Frame* frame = element->document()->frame())
+ frame->eventHandler()->setMouseDownMayStartAutoscroll();
+
+ event->setDefaultHandled();
+ }
+ } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton && element->document()->frame()->eventHandler()->autoscrollRenderer() != element->renderer())
+ // This makes sure we fire dispatchFormControlChangeEvent for a single click. For drag selection, onChange will fire when the autoscroll timer stops.
+ listBoxOnChange(data, element);
+ else if (event->type() == eventNames().keydownEvent) {
+ if (!event->isKeyboardEvent())
+ return;
+ String keyIdentifier = static_cast<KeyboardEvent*>(event)->keyIdentifier();
+
+ int endIndex = 0;
+ if (data.activeSelectionEndIndex() < 0) {
+ // Initialize the end index
+ if (keyIdentifier == "Down")
+ endIndex = nextSelectableListIndex(data, element, lastSelectedListIndex(data, element));
+ else if (keyIdentifier == "Up")
+ endIndex = previousSelectableListIndex(data, element, optionToListIndex(data, element, selectedIndex(data, element)));
+ } else {
+ // Set the end index based on the current end index
+ if (keyIdentifier == "Down")
+ endIndex = nextSelectableListIndex(data, element, data.activeSelectionEndIndex());
+ else if (keyIdentifier == "Up")
+ endIndex = previousSelectableListIndex(data, element, data.activeSelectionEndIndex());
+ }
+
+ if (keyIdentifier == "Down" || keyIdentifier == "Up") {
+ // Save the selection so it can be compared to the new selection when dispatching change events immediately after making the new selection.
+ saveLastSelection(data, element);
+
+ ASSERT(endIndex >= 0 && (unsigned) endIndex < listItems.size());
+ setActiveSelectionEndIndex(data, endIndex);
+
+ // If the anchor is unitialized, or if we're going to deselect all other options, then set the anchor index equal to the end index.
+ bool deselectOthers = !data.multiple() || !static_cast<KeyboardEvent*>(event)->shiftKey();
+ if (data.activeSelectionAnchorIndex() < 0 || deselectOthers) {
+ data.setActiveSelectionState(true);
+ if (deselectOthers)
+ deselectItems(data, element);
+ setActiveSelectionAnchorIndex(data, element, data.activeSelectionEndIndex());
+ }
+
+ static_cast<RenderListBox*>(element->renderer())->scrollToRevealElementAtListIndex(endIndex);
+ updateListBoxSelection(data, element, deselectOthers);
+ listBoxOnChange(data, element);
+ event->setDefaultHandled();
+ }
+ } else if (event->type() == eventNames().keypressEvent) {
+ if (!event->isKeyboardEvent())
+ return;
+ int keyCode = static_cast<KeyboardEvent*>(event)->keyCode();
+
+ if (keyCode == '\r') {
+ if (htmlForm)
+ htmlForm->submitClick(event);
+ event->setDefaultHandled();
+ return;
+ }
+ }
+}
+
+void SelectElement::defaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm)
+{
+ if (!element->renderer())
+ return;
+
+ if (data.usesMenuList())
+ menuListDefaultEventHandler(data, element, event, htmlForm);
+ else
+ listBoxDefaultEventHandler(data, element, event, htmlForm);
+
+ if (event->defaultHandled())
+ return;
+
+ if (event->type() == eventNames().keypressEvent && event->isKeyboardEvent()) {
+ KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(event);
+ if (!keyboardEvent->ctrlKey() && !keyboardEvent->altKey() && !keyboardEvent->metaKey() && isPrintableChar(keyboardEvent->charCode())) {
+ typeAheadFind(data, element, keyboardEvent);
+ event->setDefaultHandled();
+ return;
+ }
+ }
+}
+
+int SelectElement::lastSelectedListIndex(const SelectElementData& data, const Element* element)
+{
+ // return the number of the last option selected
+ unsigned index = 0;
+ bool found = false;
+ const Vector<Element*>& items = data.listItems(element);
+ for (size_t i = 0; i < items.size(); ++i) {
+ if (OptionElement* optionElement = toOptionElement(items[i])) {
+ if (optionElement->selected()) {
+ index = i;
+ found = true;
+ }
+ }
+ }
+
+ return found ? (int) index : -1;
+}
+
+static String stripLeadingWhiteSpace(const String& string)
+{
+ int length = string.length();
+
+ int i;
+ for (i = 0; i < length; ++i) {
+ if (string[i] != noBreakSpace && (string[i] <= 0x7F ? !isASCIISpace(string[i]) : (direction(string[i]) != WhiteSpaceNeutral)))
+ break;
+ }
+
+ return string.substring(i, length - i);
+}
+
+void SelectElement::typeAheadFind(SelectElementData& data, Element* element, KeyboardEvent* event)
+{
+ if (event->timeStamp() < data.lastCharTime())
+ return;
+
+ DOMTimeStamp delta = event->timeStamp() - data.lastCharTime();
+ data.setLastCharTime(event->timeStamp());
+
+ UChar c = event->charCode();
+
+ String prefix;
+ int searchStartOffset = 1;
+ if (delta > typeAheadTimeout) {
+ prefix = String(&c, 1);
+ data.setTypedString(prefix);
+ data.setRepeatingChar(c);
+ } else {
+ data.typedString().append(c);
+
+ if (c == data.repeatingChar())
+ // The user is likely trying to cycle through all the items starting with this character, so just search on the character
+ prefix = String(&c, 1);
+ else {
+ data.setRepeatingChar(0);
+ prefix = data.typedString();
+ searchStartOffset = 0;
+ }
+ }
+
+ const Vector<Element*>& items = data.listItems(element);
+ int itemCount = items.size();
+ if (itemCount < 1)
+ return;
+
+ int selected = selectedIndex(data, element);
+ int index = (optionToListIndex(data, element, selected >= 0 ? selected : 0) + searchStartOffset) % itemCount;
+ ASSERT(index >= 0);
+
+ for (int i = 0; i < itemCount; ++i, index = (index + 1) % itemCount) {
+ OptionElement* optionElement = toOptionElement(items[index]);
+ if (!optionElement || items[index]->disabled())
+ continue;
+
+ String text = optionElement->textIndentedToRespectGroupLabel();
+ if (stripLeadingWhiteSpace(text).startsWith(prefix, false)) {
+ setSelectedIndex(data, element, listToOptionIndex(data, element, index));
+ if (!data.usesMenuList())
+ listBoxOnChange(data, element);
+ element->setNeedsStyleRecalc();
+ return;
+ }
+ }
+}
+
+void SelectElement::insertedIntoTree(SelectElementData& data, Element* element)
+{
+ // When the element is created during document parsing, it won't have any items yet - but for innerHTML
+ // and related methods, this method is called after the whole subtree is constructed.
+ recalcListItems(data, element, true);
+}
+
+void SelectElement::accessKeySetSelectedIndex(SelectElementData& data, Element* element, int index)
+{
+ // first bring into focus the list box
+ if (!element->focused())
+ element->accessKeyAction(false);
+
+ // if this index is already selected, unselect. otherwise update the selected index
+ const Vector<Element*>& items = data.listItems(element);
+ int listIndex = optionToListIndex(data, element, index);
+ if (OptionElement* optionElement = (listIndex >= 0 ? toOptionElement(items[listIndex]) : 0)) {
+ if (optionElement->selected())
+ optionElement->setSelectedState(false);
+ else
+ setSelectedIndex(data, element, index, false, true);
+ }
+
+ listBoxOnChange(data, element);
+ scrollToSelection(data, element);
+}
+
+// SelectElementData
+SelectElementData::SelectElementData()
+ : m_multiple(false)
+ , m_size(0)
+ , m_lastOnChangeIndex(-1)
+ , m_activeSelectionState(false)
+ , m_activeSelectionAnchorIndex(-1)
+ , m_activeSelectionEndIndex(-1)
+ , m_recalcListItems(false)
+ , m_repeatingChar(0)
+ , m_lastCharTime(0)
+{
+}
+
+void SelectElementData::checkListItems(const Element* element) const
+{
+#ifndef NDEBUG
+ const Vector<Element*>& items = m_listItems;
+ SelectElement::recalcListItems(*const_cast<SelectElementData*>(this), element, false);
+ ASSERT(items == m_listItems);
+#else
+ UNUSED_PARAM(element);
+#endif
+}
+
+Vector<Element*>& SelectElementData::listItems(const Element* element)
+{
+ if (m_recalcListItems)
+ SelectElement::recalcListItems(*this, element);
+ else
+ checkListItems(element);
+
+ return m_listItems;
+}
+
+const Vector<Element*>& SelectElementData::listItems(const Element* element) const
+{
+ if (m_recalcListItems)
+ SelectElement::recalcListItems(*const_cast<SelectElementData*>(this), element);
+ else
+ checkListItems(element);
+
+ return m_listItems;
+}
+
+SelectElement* toSelectElement(Element* element)
+{
+ if (element->isHTMLElement()) {
+ if (element->hasTagName(HTMLNames::selectTag))
+ return static_cast<HTMLSelectElement*>(element);
+ if (element->hasTagName(HTMLNames::keygenTag))
+ return static_cast<HTMLKeygenElement*>(element);
+ }
+
+#if ENABLE(WML)
+ if (element->isWMLElement() && element->hasTagName(WMLNames::selectTag))
+ return static_cast<WMLSelectElement*>(element);
+#endif
+
+ return 0;
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/dom/SelectElement.h b/src/3rdparty/webkit/WebCore/dom/SelectElement.h
new file mode 100644
index 0000000..29187ae
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/SelectElement.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http//www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SelectElement_h
+#define SelectElement_h
+
+#include "Event.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Element;
+class Event;
+class FormDataList;
+class HTMLFormElement;
+class KeyboardEvent;
+class MappedAttribute;
+class SelectElementData;
+class String;
+
+class SelectElement {
+public:
+ virtual bool multiple() const = 0;
+
+ virtual int size() const = 0;
+ virtual const Vector<Element*>& listItems() const = 0;
+
+ virtual void listBoxOnChange() = 0;
+ virtual void updateListBoxSelection(bool deselectOtherOptions) = 0;
+
+ virtual void menuListOnChange() = 0;
+
+ virtual int activeSelectionStartListIndex() const = 0;
+ virtual int activeSelectionEndListIndex() const = 0;
+
+ virtual void setActiveSelectionAnchorIndex(int index) = 0;
+ virtual void setActiveSelectionEndIndex(int index) = 0;
+
+ virtual int listToOptionIndex(int listIndex) const = 0;
+ virtual int optionToListIndex(int optionIndex) const = 0;
+
+ virtual int selectedIndex() const = 0;
+ virtual void setSelectedIndex(int index, bool deselect = true) = 0;
+ virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false) = 0;
+
+protected:
+ virtual ~SelectElement() { }
+
+ friend class SelectElementData;
+
+ static void selectAll(SelectElementData&, Element*);
+ static void saveLastSelection(SelectElementData&, Element*);
+ static int nextSelectableListIndex(SelectElementData&, Element*, int startIndex);
+ static int previousSelectableListIndex(SelectElementData&, Element*, int startIndex);
+ static void setActiveSelectionAnchorIndex(SelectElementData&, Element*, int index);
+ static void setActiveSelectionEndIndex(SelectElementData&, int index);
+ static void updateListBoxSelection(SelectElementData&, Element*, bool deselectOtherOptions);
+ static void listBoxOnChange(SelectElementData&, Element*);
+ static void menuListOnChange(SelectElementData&, Element*);
+ static void scrollToSelection(SelectElementData&, Element*);
+ static void recalcStyle(SelectElementData&, Element*);
+ static void setRecalcListItems(SelectElementData&, Element*);
+ static void recalcListItems(SelectElementData&, const Element*, bool updateSelectedStates = true);
+ static int selectedIndex(const SelectElementData&, const Element*);
+ static void setSelectedIndex(SelectElementData&, Element*, int optionIndex, bool deselect = true, bool fireOnChangeNow = false, bool userDrivenChange = true);
+ static int optionToListIndex(const SelectElementData&, const Element*, int optionIndex);
+ static int listToOptionIndex(const SelectElementData&, const Element*, int listIndex);
+ static void dispatchFocusEvent(SelectElementData&, Element*);
+ static void dispatchBlurEvent(SelectElementData&, Element*);
+ static void deselectItems(SelectElementData&, Element*, Element* excludeElement = 0);
+ static bool saveFormControlState(const SelectElementData&, const Element*, String& state);
+ static void restoreFormControlState(SelectElementData&, Element*, const String& state);
+ static void parseMultipleAttribute(SelectElementData&, Element*, MappedAttribute*);
+ static bool appendFormData(SelectElementData&, Element*, FormDataList&);
+ static void reset(SelectElementData&, Element*);
+ static void defaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement* = 0);
+ static int lastSelectedListIndex(const SelectElementData&, const Element*);
+ static void typeAheadFind(SelectElementData&, Element*, KeyboardEvent*);
+ static void insertedIntoTree(SelectElementData&, Element*);
+ static void accessKeySetSelectedIndex(SelectElementData&, Element*, int index);
+
+private:
+ static void menuListDefaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement*);
+ static void listBoxDefaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement*);
+};
+
+// HTML/WMLSelectElement hold this struct as member variable
+// and pass it to the static helper functions in SelectElement
+class SelectElementData {
+public:
+ SelectElementData();
+
+ bool multiple() const { return m_multiple; }
+ void setMultiple(bool value) { m_multiple = value; }
+
+ int size() const { return m_size; }
+ void setSize(int value) { m_size = value; }
+
+ bool usesMenuList() const { return !m_multiple && m_size <= 1; }
+
+ int lastOnChangeIndex() const { return m_lastOnChangeIndex; }
+ void setLastOnChangeIndex(int value) { m_lastOnChangeIndex = value; }
+
+ bool userDrivenChange() const { return m_userDrivenChange; }
+ void setUserDrivenChange(bool value) { m_userDrivenChange = value; }
+
+ Vector<bool>& lastOnChangeSelection() { return m_lastOnChangeSelection; }
+
+ bool activeSelectionState() const { return m_activeSelectionState; }
+ void setActiveSelectionState(bool value) { m_activeSelectionState = value; }
+
+ int activeSelectionAnchorIndex() const { return m_activeSelectionAnchorIndex; }
+ void setActiveSelectionAnchorIndex(int value) { m_activeSelectionAnchorIndex = value; }
+
+ int activeSelectionEndIndex() const { return m_activeSelectionEndIndex; }
+ void setActiveSelectionEndIndex(int value) { m_activeSelectionEndIndex = value; }
+
+ Vector<bool>& cachedStateForActiveSelection() { return m_cachedStateForActiveSelection; }
+
+ bool shouldRecalcListItems() const { return m_recalcListItems; }
+ void setShouldRecalcListItems(bool value) { m_recalcListItems = value; }
+
+ Vector<Element*>& rawListItems() { return m_listItems; }
+ Vector<Element*>& listItems(const Element*);
+ const Vector<Element*>& listItems(const Element*) const;
+
+ UChar repeatingChar() const { return m_repeatingChar; }
+ void setRepeatingChar(const UChar& value) { m_repeatingChar = value; }
+
+ DOMTimeStamp lastCharTime() const { return m_lastCharTime; }
+ void setLastCharTime(const DOMTimeStamp& value) { m_lastCharTime = value; }
+
+ String& typedString() { return m_typedString; }
+ void setTypedString(const String& value) { m_typedString = value; }
+
+private:
+ void checkListItems(const Element*) const;
+
+ bool m_multiple;
+ int m_size;
+
+ int m_lastOnChangeIndex;
+ Vector<bool> m_lastOnChangeSelection;
+ bool m_userDrivenChange;
+
+ bool m_activeSelectionState;
+ int m_activeSelectionAnchorIndex;
+ int m_activeSelectionEndIndex;
+ Vector<bool> m_cachedStateForActiveSelection;
+
+ bool m_recalcListItems;
+ Vector<Element*> m_listItems;
+
+ // Instance variables for type-ahead find
+ UChar m_repeatingChar;
+ DOMTimeStamp m_lastCharTime;
+ String m_typedString;
+};
+
+SelectElement* toSelectElement(Element*);
+
+}
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/dom/StyleElement.cpp b/src/3rdparty/webkit/WebCore/dom/StyleElement.cpp
index 68c3ec7..a21959d 100644
--- a/src/3rdparty/webkit/WebCore/dom/StyleElement.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/StyleElement.cpp
@@ -61,13 +61,28 @@ void StyleElement::process(Element* e)
if (!e || !e->inDocument())
return;
- Vector<UChar> text;
-
- for (Node* c = e->firstChild(); c; c = c->nextSibling())
- if (c->nodeType() == Node::TEXT_NODE || c->nodeType() == Node::CDATA_SECTION_NODE || c->nodeType() == Node::COMMENT_NODE)
- append(text, c->nodeValue());
+ unsigned resultLength = 0;
+ for (Node* c = e->firstChild(); c; c = c->nextSibling()) {
+ Node::NodeType nodeType = c->nodeType();
+ if (nodeType == Node::TEXT_NODE || nodeType == Node::CDATA_SECTION_NODE || nodeType == Node::COMMENT_NODE)
+ resultLength += c->nodeValue().length();
+ }
+ UChar* text;
+ String sheetText = String::createUninitialized(resultLength, text);
+
+ UChar* p = text;
+ for (Node* c = e->firstChild(); c; c = c->nextSibling()) {
+ Node::NodeType nodeType = c->nodeType();
+ if (nodeType == Node::TEXT_NODE || nodeType == Node::CDATA_SECTION_NODE || nodeType == Node::COMMENT_NODE) {
+ String nodeValue = c->nodeValue();
+ unsigned nodeLength = nodeValue.length();
+ memcpy(p, nodeValue.characters(), nodeLength * sizeof(UChar));
+ p += nodeLength;
+ }
+ }
+ ASSERT(p == text + resultLength);
- createSheet(e, String::adopt(text));
+ createSheet(e, sheetText);
}
void StyleElement::createSheet(Element* e, const String& text)
diff --git a/src/3rdparty/webkit/WebCore/dom/StyledElement.cpp b/src/3rdparty/webkit/WebCore/dom/StyledElement.cpp
index d5af1b7..8ddfd31 100644
--- a/src/3rdparty/webkit/WebCore/dom/StyledElement.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/StyledElement.cpp
@@ -29,6 +29,7 @@
#include "CSSValueKeywords.h"
#include "Document.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include <wtf/HashFunctions.h>
using namespace std;
@@ -157,7 +158,7 @@ void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
MappedAttribute* mappedAttr = static_cast<MappedAttribute*>(attr);
if (mappedAttr->decl() && !preserveDecls) {
mappedAttr->setDecl(0);
- setChanged();
+ setNeedsStyleRecalc();
if (namedAttrMap)
mappedAttributes()->declRemoved();
}
@@ -167,7 +168,7 @@ void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
bool needToParse = mapToEntry(attr->name(), entry);
if (preserveDecls) {
if (mappedAttr->decl()) {
- setChanged();
+ setNeedsStyleRecalc();
if (namedAttrMap)
mappedAttributes()->declAdded();
checkDecl = false;
@@ -177,7 +178,7 @@ void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(entry, attr);
if (decl) {
mappedAttr->setDecl(decl);
- setChanged();
+ setNeedsStyleRecalc();
if (namedAttrMap)
mappedAttributes()->declAdded();
checkDecl = false;
@@ -185,11 +186,16 @@ void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
needToParse = true;
}
+ // parseMappedAttribute() might create a CSSMappedAttributeDeclaration on the attribute.
+ // Normally we would be concerned about reseting the parent of those declarations in StyledElement::didMoveToNewOwnerDocument().
+ // But currently we always clear its parent and node below when adding it to the decl table.
+ // If that changes for some reason moving between documents will be buggy.
+ // webarchive/adopt-attribute-styled-node-webarchive.html should catch any resulting crashes.
if (needToParse)
parseMappedAttribute(mappedAttr);
if (entry == eNone && ownerDocument()->attached() && ownerDocument()->styleSelector()->hasSelectorForAttribute(attr->name().localName()))
- setChanged();
+ setNeedsStyleRecalc();
if (checkDecl && mappedAttr->decl()) {
// Add the decl to the table in the appropriate spot.
@@ -227,7 +233,7 @@ void StyledElement::classAttributeChanged(const AtomicString& newClassString)
else
mappedAttributes()->clearClass();
}
- setChanged();
+ setNeedsStyleRecalc();
dispatchSubtreeModifiedEvent();
}
@@ -244,7 +250,7 @@ void StyledElement::parseMappedAttribute(MappedAttribute *attr)
else
namedAttrMap->setID(attr->value());
}
- setChanged();
+ setNeedsStyleRecalc();
} else if (attr->name() == classAttr)
classAttributeChanged(attr->value());
else if (attr->name() == styleAttr) {
@@ -253,7 +259,7 @@ void StyledElement::parseMappedAttribute(MappedAttribute *attr)
else
getInlineStyleDecl()->parseDeclaration(attr->value());
m_isStyleAttributeValid = true;
- setChanged();
+ setNeedsStyleRecalc();
}
}
@@ -502,4 +508,13 @@ void StyledElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
style->addSubresourceStyleURLs(urls);
}
+
+void StyledElement::didMoveToNewOwnerDocument()
+{
+ if (m_inlineStyleDecl)
+ m_inlineStyleDecl->setParent(document()->elementSheet());
+
+ Element::didMoveToNewOwnerDocument();
+}
+
}
diff --git a/src/3rdparty/webkit/WebCore/dom/StyledElement.h b/src/3rdparty/webkit/WebCore/dom/StyledElement.h
index 4ca48e9..158992e 100644
--- a/src/3rdparty/webkit/WebCore/dom/StyledElement.h
+++ b/src/3rdparty/webkit/WebCore/dom/StyledElement.h
@@ -25,12 +25,15 @@
#ifndef StyledElement_h
#define StyledElement_h
+#include "CSSPrimitiveValue.h"
#include "Element.h"
+#include "MappedAttributeEntry.h"
#include "NamedMappedAttrMap.h"
namespace WebCore {
class CSSMappedAttributeDeclaration;
+class CSSMutableStyleDeclaration;
class MappedAttribute;
class StyledElement : public Element {
@@ -87,6 +90,8 @@ protected:
// parseMappedAttribute (called via setAttribute()) and
// svgAttributeChanged (called when element.className.baseValue is set)
void classAttributeChanged(const AtomicString& newClassString);
+
+ virtual void didMoveToNewOwnerDocument();
RefPtr<CSSMutableStyleDeclaration> m_inlineStyleDecl;
};
diff --git a/src/3rdparty/webkit/WebCore/dom/Text.cpp b/src/3rdparty/webkit/WebCore/dom/Text.cpp
index 187e39d..04e499a 100644
--- a/src/3rdparty/webkit/WebCore/dom/Text.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/Text.cpp
@@ -23,13 +23,13 @@
#include "Text.h"
#include "CString.h"
-#include "Document.h"
#include "ExceptionCode.h"
#include "RenderText.h"
#include "TextBreakIterator.h"
#if ENABLE(SVG)
#include "RenderSVGInlineText.h"
+#include "SVGNames.h"
#endif
#if ENABLE(WML)
@@ -42,12 +42,12 @@ namespace WebCore {
// DOM Section 1.1.1
Text::Text(Document* document, const String& text)
- : CharacterData(document, text)
+ : CharacterData(document, text, true)
{
}
Text::Text(Document* document)
- : CharacterData(document)
+ : CharacterData(document, true)
{
}
@@ -81,7 +81,7 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
document()->textNodeSplit(this);
if (renderer())
- static_cast<RenderText*>(renderer())->setText(m_data);
+ toRenderText(renderer())->setText(m_data);
return newText.release();
}
@@ -125,17 +125,30 @@ String Text::wholeText() const
const Text* startText = earliestLogicallyAdjacentTextNode(this);
const Text* endText = latestLogicallyAdjacentTextNode(this);
- Vector<UChar> result;
Node* onePastEndText = endText->nextSibling();
+ unsigned resultLength = 0;
for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) {
if (!n->isTextNode())
continue;
const Text* t = static_cast<const Text*>(n);
const String& data = t->data();
- result.append(data.characters(), data.length());
+ resultLength += data.length();
}
+ UChar* resultData;
+ String result = String::createUninitialized(resultLength, resultData);
+ UChar* p = resultData;
+ for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) {
+ if (!n->isTextNode())
+ continue;
+ const Text* t = static_cast<const Text*>(n);
+ const String& data = t->data();
+ unsigned dataLength = data.length();
+ memcpy(p, data.characters(), dataLength * sizeof(UChar));
+ p += dataLength;
+ }
+ ASSERT(p == resultData + resultLength);
- return String::adopt(result);
+ return result;
}
PassRefPtr<Text> Text::replaceWholeText(const String& newText, ExceptionCode&)
@@ -210,7 +223,7 @@ bool Text::rendererIsNeeded(RenderStyle *style)
if (prev && prev->isBR()) // <span><br/> <br/></span>
return false;
- if (par->isInlineFlow()) {
+ if (par->isRenderInline()) {
// <span><div/> <div/></span>
if (prev && !prev->isInline())
return false;
@@ -234,7 +247,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
@@ -253,17 +270,17 @@ void Text::recalcStyle(StyleChange change)
if (renderer())
renderer()->setStyle(parentNode()->renderer()->style());
}
- if (changed()) {
+ if (needsStyleRecalc()) {
if (renderer()) {
if (renderer()->isText())
- static_cast<RenderText*>(renderer())->setText(m_data);
+ toRenderText(renderer())->setText(m_data);
} else {
if (attached())
detach();
attach();
}
}
- setChanged(NoStyleChange);
+ setNeedsStyleRecalc(NoStyleChange);
}
// DOM Section 1.1.1
diff --git a/src/3rdparty/webkit/WebCore/dom/Text.h b/src/3rdparty/webkit/WebCore/dom/Text.h
index 27b1945..5e711d0 100644
--- a/src/3rdparty/webkit/WebCore/dom/Text.h
+++ b/src/3rdparty/webkit/WebCore/dom/Text.h
@@ -51,7 +51,6 @@ public:
// Other methods (not part of DOM)
- virtual bool isTextNode() const { return true; }
virtual void attach();
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/src/3rdparty/webkit/WebCore/dom/Tokenizer.h b/src/3rdparty/webkit/WebCore/dom/Tokenizer.h
index 1ed9484..ea303f9 100644
--- a/src/3rdparty/webkit/WebCore/dom/Tokenizer.h
+++ b/src/3rdparty/webkit/WebCore/dom/Tokenizer.h
@@ -28,6 +28,7 @@
namespace WebCore {
class SegmentedString;
+ class XSSAuditor;
class Tokenizer {
public:
@@ -37,7 +38,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; }
@@ -58,11 +59,15 @@ namespace WebCore {
virtual void executeScriptsWaitingForStylesheets() {}
virtual bool isHTMLTokenizer() const { return false; }
+
+ XSSAuditor* xssAuditor() const { return m_XSSAuditor; }
+ void setXSSAuditor(XSSAuditor* auditor) { m_XSSAuditor = auditor; }
protected:
Tokenizer(bool viewSourceMode = false)
: m_parserStopped(false)
, m_inViewSourceMode(viewSourceMode)
+ , m_XSSAuditor(0)
{
}
@@ -71,6 +76,9 @@ namespace WebCore {
// even when it has buffered data.
bool m_parserStopped;
bool m_inViewSourceMode;
+
+ // The XSSAuditor associated with this tokenizer.
+ XSSAuditor* m_XSSAuditor;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/TreeWalker.h b/src/3rdparty/webkit/WebCore/dom/TreeWalker.h
index d06acb9..4cc8e9a 100644
--- a/src/3rdparty/webkit/WebCore/dom/TreeWalker.h
+++ b/src/3rdparty/webkit/WebCore/dom/TreeWalker.h
@@ -25,7 +25,6 @@
#ifndef TreeWalker_h
#define TreeWalker_h
-#include "JSDOMBinding.h"
#include "NodeFilter.h"
#include "Traversal.h"
#include <wtf/PassRefPtr.h>
diff --git a/src/3rdparty/webkit/WebCore/dom/WheelEvent.cpp b/src/3rdparty/webkit/WebCore/dom/WheelEvent.cpp
index a3c806e..2039541 100644
--- a/src/3rdparty/webkit/WebCore/dom/WheelEvent.cpp
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/WheelEvent.h b/src/3rdparty/webkit/WebCore/dom/WheelEvent.h
index 015796e..04d5421 100644
--- a/src/3rdparty/webkit/WebCore/dom/WheelEvent.h
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/WheelEvent.idl b/src/3rdparty/webkit/WebCore/dom/WheelEvent.idl
index 1445509..4cba4ac 100644
--- a/src/3rdparty/webkit/WebCore/dom/WheelEvent.idl
+++ b/src/3rdparty/webkit/WebCore/dom/WheelEvent.idl
@@ -42,11 +42,11 @@ module events {
readonly attribute long x;
readonly attribute long y;
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
readonly attribute boolean isHorizontal;
#endif /* defined(LANGUAGE_OBJECTIVE_C) */
-#if !defined(LANGUAGE_JAVASCRIPT)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
void initWheelEvent(in long wheelDeltaX,
in long wheelDeltaY,
in DOMWindow view,
diff --git a/src/3rdparty/webkit/WebCore/dom/Worker.cpp b/src/3rdparty/webkit/WebCore/dom/Worker.cpp
deleted file mode 100644
index bdd083f..0000000
--- a/src/3rdparty/webkit/WebCore/dom/Worker.cpp
+++ /dev/null
@@ -1,202 +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* resource)
-{
- ASSERT(resource == m_cachedScript.get());
- 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/src/3rdparty/webkit/WebCore/dom/Worker.h b/src/3rdparty/webkit/WebCore/dom/Worker.h
deleted file mode 100644
index 6a47bac..0000000
--- a/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/Worker.idl b/src/3rdparty/webkit/WebCore/dom/Worker.idl
deleted file mode 100644
index 2ef9b62..0000000
--- a/src/3rdparty/webkit/WebCore/dom/Worker.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.
- *
- * 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 [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);
- };
-
-}
diff --git a/src/3rdparty/webkit/WebCore/dom/WorkerContext.cpp b/src/3rdparty/webkit/WebCore/dom/WorkerContext.cpp
deleted file mode 100644
index 8a9af07..0000000
--- a/src/3rdparty/webkit/WebCore/dom/WorkerContext.cpp
+++ /dev/null
@@ -1,195 +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 "SecurityOrigin.h"
-#include "WorkerLocation.h"
-#include "WorkerMessagingProxy.h"
-#include "WorkerNavigator.h"
-#include "WorkerTask.h"
-#include "WorkerThread.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);
-}
-
-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()->messageQueue().append(ScriptExecutionContextTaskWorkerTask::create(task));
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/src/3rdparty/webkit/WebCore/dom/WorkerContext.h b/src/3rdparty/webkit/WebCore/dom/WorkerContext.h
deleted file mode 100644
index c9774d9..0000000
--- a/src/3rdparty/webkit/WebCore/dom/WorkerContext.h
+++ /dev/null
@@ -1,122 +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 WorkerTask;
- 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 WorkerContext* toWorkerContext() { return this; }
-
- void postMessage(const String& message);
- virtual void postTask(PassRefPtr<Task>); // Executes the task on context's 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/src/3rdparty/webkit/WebCore/dom/WorkerContext.idl b/src/3rdparty/webkit/WebCore/dom/WorkerContext.idl
deleted file mode 100644
index 6e7223c..0000000
--- a/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/WorkerLocation.cpp b/src/3rdparty/webkit/WebCore/dom/WorkerLocation.cpp
deleted file mode 100644
index 115a9ad..0000000
--- a/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/WorkerLocation.h b/src/3rdparty/webkit/WebCore/dom/WorkerLocation.h
deleted file mode 100644
index 52c31ad..0000000
--- a/src/3rdparty/webkit/WebCore/dom/WorkerLocation.h
+++ /dev/null
@@ -1,73 +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 WorkerLocation_h
-#define WorkerLocation_h
-
-#if ENABLE(WORKERS)
-
-#include "KURL.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
- class String;
-
- class WorkerLocation : public RefCounted<WorkerLocation> {
- public:
- static PassRefPtr<WorkerLocation> create(const KURL& url)
- {
- return adoptRef(new WorkerLocation(url));
- }
-
- const KURL& url() const { return m_url; }
-
- String href() const;
-
- // 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;
-
- private:
- WorkerLocation(const KURL& url) : m_url(url) { }
-
- KURL m_url;
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerLocation_h
diff --git a/src/3rdparty/webkit/WebCore/dom/WorkerLocation.idl b/src/3rdparty/webkit/WebCore/dom/WorkerLocation.idl
deleted file mode 100644
index 5551f18..0000000
--- a/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.cpp b/src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.cpp
deleted file mode 100644
index b69b9c5..0000000
--- a/src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.cpp
+++ /dev/null
@@ -1,311 +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->messageQueue().append(MessageWorkerContextTask::create(message));
- } else
- m_queuedEarlyTasks.append(MessageWorkerContextTask::create(message));
-}
-
-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->messageQueue().append(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/src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.h b/src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.h
deleted file mode 100644
index c004940..0000000
--- a/src/3rdparty/webkit/WebCore/dom/WorkerMessagingProxy.h
+++ /dev/null
@@ -1,93 +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 <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 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 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/src/3rdparty/webkit/WebCore/dom/WorkerThread.cpp b/src/3rdparty/webkit/WebCore/dom/WorkerThread.cpp
deleted file mode 100644
index d2c4933..0000000
--- a/src/3rdparty/webkit/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);
- }
-
- 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.
-
- while (true) {
- RefPtr<WorkerTask> task;
- if (!m_messageQueue.waitForMessage(task))
- break;
-
- task->performTask(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_messageQueue.kill();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/src/3rdparty/webkit/WebCore/dom/WorkerThread.h b/src/3rdparty/webkit/WebCore/dom/WorkerThread.h
deleted file mode 100644
index 07e3e8a..0000000
--- a/src/3rdparty/webkit/WebCore/dom/WorkerThread.h
+++ /dev/null
@@ -1,79 +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 <wtf/MessageQueue.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;
- class 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; }
- MessageQueue<RefPtr<WorkerTask> >& messageQueue() { return m_messageQueue; }
-
- 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;
- WorkerMessagingProxy* m_messagingProxy;
-
- RefPtr<WorkerContext> m_workerContext;
- Mutex m_threadCreationMutex;
-
- MessageQueue<RefPtr<WorkerTask> > m_messageQueue;
- OwnPtr<WorkerThreadStartupData> m_startupData;
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerThread_h
diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp
index c411e50..1747c3c 100644
--- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp
@@ -39,7 +39,6 @@
#include "FrameView.h"
#include "HTMLLinkElement.h"
#include "HTMLNames.h"
-#include "HTMLScriptElement.h"
#include "HTMLStyleElement.h"
#include "ProcessingInstruction.h"
#include "ResourceError.h"
@@ -47,6 +46,7 @@
#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include "ScriptController.h"
+#include "ScriptElement.h"
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "TextResourceDecoder.h"
@@ -57,7 +57,6 @@
#if ENABLE(SVG)
#include "SVGNames.h"
-#include "SVGScriptElement.h"
#include "SVGStyleElement.h"
#endif
@@ -65,32 +64,9 @@ using namespace std;
namespace WebCore {
-const int maxErrors = 25;
+using namespace HTMLNames;
-bool isScriptElement(Element* element)
-{
- return element->hasTagName(HTMLNames::scriptTag)
-#if ENABLE(SVG)
- || element->hasTagName(SVGNames::scriptTag)
-#endif
- ;
-}
-
-ScriptElement* castToScriptElement(Element* element)
-{
- ASSERT(isScriptElement(element));
-
- if (element->hasTagName(HTMLNames::scriptTag))
- return static_cast<HTMLScriptElement*>(element);
-
-#if ENABLE(SVG)
- if (element->hasTagName(SVGNames::scriptTag))
- return static_cast<SVGScriptElement*>(element);
-#endif
-
- ASSERT_NOT_REACHED();
- return 0;
-}
+const int maxErrors = 25;
#if ENABLE(WML)
bool XMLTokenizer::isWMLDocument() const
@@ -113,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();
@@ -121,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)
@@ -226,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);
@@ -261,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);
@@ -279,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);
@@ -292,18 +267,18 @@ 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
- doc->updateRendering();
+ doc->updateStyleIfNeeded();
}
-void XMLTokenizer::notifyFinished(CachedResource* finishedObj)
+void XMLTokenizer::notifyFinished(CachedResource* unusedResource)
{
- ASSERT(m_pendingScript == finishedObj);
+ ASSERT_UNUSED(unusedResource, unusedResource == m_pendingScript);
ASSERT(m_pendingScript->accessCount() > 0);
ScriptSourceCode sourceCode(m_pendingScript.get());
@@ -315,7 +290,7 @@ void XMLTokenizer::notifyFinished(CachedResource* finishedObj)
RefPtr<Element> e = m_scriptElement;
m_scriptElement = 0;
- ScriptElement* scriptElement = castToScriptElement(e.get());
+ ScriptElement* scriptElement = toScriptElement(e.get());
ASSERT(scriptElement);
if (errorOccurred)
@@ -345,4 +320,3 @@ void XMLTokenizer::pauseParsing()
}
}
-
diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h
index 6d54eeb..019a831 100644
--- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h
+++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h
@@ -3,6 +3,7 @@
* Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -60,7 +61,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();
@@ -72,6 +73,10 @@ namespace WebCore {
void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; }
bool isXHTMLDocument() const { return m_isXHTMLDocument; }
+#if ENABLE(XHTMLMP)
+ void setIsXHTMLMPDocument(bool isXHTML) { m_isXHTMLMPDocument = isXHTML; }
+ bool isXHTMLMPDocument() const { return m_isXHTMLMPDocument; }
+#endif
#if ENABLE(WML)
bool isWMLDocument() const;
#endif
@@ -149,6 +154,10 @@ public:
bool m_sawXSLTransform;
bool m_sawFirstElement;
bool m_isXHTMLDocument;
+#if ENABLE(XHTMLMP)
+ bool m_isXHTMLMPDocument;
+ bool m_hasDocTypeDeclaration;
+#endif
bool m_parserPaused;
bool m_requestingScript;
@@ -173,15 +182,11 @@ public:
#if ENABLE(XSLT)
void* xmlDocPtrForString(DocLoader*, const String& source, const String& url);
-void setLoaderForLibXMLCallbacks(DocLoader*);
#endif
HashMap<String, String> parseAttributes(const String&, bool& attrsOK);
bool parseXMLDocumentFragment(const String&, DocumentFragment*, Element* parent = 0);
-bool isScriptElement(Element*);
-ScriptElement* castToScriptElement(Element*);
-
} // namespace WebCore
#endif // XMLTokenizer_h
diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp
index d0eacdc..4098eaa 100644
--- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp
@@ -5,7 +5,7 @@
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Holger Hans Peter Freyther
- * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -50,17 +50,24 @@
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "TextResourceDecoder.h"
+#include "XMLTokenizerScope.h"
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <wtf/Platform.h>
#include <wtf/StringExtras.h>
#include <wtf/Threading.h>
+#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
#if ENABLE(XSLT)
#include <libxslt/xslt.h>
#endif
+#if ENABLE(XHTMLMP)
+#include "HTMLNames.h"
+#include "HTMLScriptElement.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -81,12 +88,12 @@ public:
callback->xmlPrefix = xmlStrdup(xmlPrefix);
callback->xmlURI = xmlStrdup(xmlURI);
callback->nb_namespaces = nb_namespaces;
- callback->namespaces = reinterpret_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * nb_namespaces * 2));
+ callback->namespaces = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * nb_namespaces * 2));
for (int i = 0; i < nb_namespaces * 2 ; i++)
callback->namespaces[i] = xmlStrdup(namespaces[i]);
callback->nb_attributes = nb_attributes;
callback->nb_defaulted = nb_defaulted;
- callback->attributes = reinterpret_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * nb_attributes * 5));
+ callback->attributes = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * nb_attributes * 5));
for (int i = 0; i < nb_attributes; i++) {
// Each attribute has 5 elements in the array:
// name, prefix, uri, value and an end pointer.
@@ -203,8 +210,8 @@ private:
virtual void call(XMLTokenizer* tokenizer) {
tokenizer->startElementNs(xmlLocalName, xmlPrefix, xmlURI,
- nb_namespaces, (const xmlChar**)namespaces,
- nb_attributes, nb_defaulted, (const xmlChar**)(attributes));
+ nb_namespaces, const_cast<const xmlChar**>(namespaces),
+ nb_attributes, nb_defaulted, const_cast<const xmlChar**>(attributes));
}
xmlChar* xmlLocalName;
@@ -324,14 +331,13 @@ private:
// --------------------------------
static int globalDescriptor = 0;
-static DocLoader* globalDocLoader = 0;
static ThreadIdentifier libxmlLoaderThread = 0;
static int matchFunc(const char*)
{
// Only match loads initiated due to uses of libxml2 from within XMLTokenizer to avoid
// interfering with client applications that also use libxml2. http://bugs.webkit.org/show_bug.cgi?id=17353
- return globalDocLoader && currentThread() == libxmlLoaderThread;
+ return XMLTokenizerScope::currentDocLoader && currentThread() == libxmlLoaderThread;
}
class OffsetBuffer {
@@ -381,8 +387,8 @@ static bool shouldAllowExternalLoad(const KURL& url)
// retrieved content. If we had more context, we could potentially allow
// the parser to load a DTD. As things stand, we take the conservative
// route and allow same-origin requests only.
- if (!globalDocLoader->doc()->securityOrigin()->canRequest(url)) {
- globalDocLoader->printAccessDeniedMessage(url);
+ if (!XMLTokenizerScope::currentDocLoader->doc()->securityOrigin()->canRequest(url)) {
+ XMLTokenizerScope::currentDocLoader->printAccessDeniedMessage(url);
return false;
}
@@ -391,10 +397,10 @@ static bool shouldAllowExternalLoad(const KURL& url)
static void* openFunc(const char* uri)
{
- ASSERT(globalDocLoader);
+ ASSERT(XMLTokenizerScope::currentDocLoader);
ASSERT(currentThread() == libxmlLoaderThread);
- KURL url(uri);
+ KURL url(KURL(), uri);
if (!shouldAllowExternalLoad(url))
return &globalDescriptor;
@@ -402,15 +408,16 @@ static void* openFunc(const char* uri)
ResourceError error;
ResourceResponse response;
Vector<char> data;
-
- DocLoader* docLoader = globalDocLoader;
- globalDocLoader = 0;
- // FIXME: We should restore the original global error handler as well.
- if (docLoader->frame())
- docLoader->frame()->loader()->loadResourceSynchronously(url, error, response, data);
- globalDocLoader = docLoader;
+ {
+ DocLoader* docLoader = XMLTokenizerScope::currentDocLoader;
+ XMLTokenizerScope scope(0);
+ // FIXME: We should restore the original global error handler as well.
+
+ if (docLoader->frame())
+ docLoader->frame()->loader()->loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
+ }
// We have to check the URL again after the load to catch redirects.
// See <https://bugs.webkit.org/show_bug.cgi?id=21963>.
@@ -452,11 +459,6 @@ static void errorFunc(void*, const char*, ...)
}
#endif
-void setLoaderForLibXMLCallbacks(DocLoader* docLoader)
-{
- globalDocLoader = docLoader;
-}
-
static bool didInit = false;
static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* userData)
@@ -529,6 +531,10 @@ XMLTokenizer::XMLTokenizer(Document* _doc, FrameView* _view)
, m_sawXSLTransform(false)
, m_sawFirstElement(false)
, m_isXHTMLDocument(false)
+#if ENABLE(XHTMLMP)
+ , m_isXHTMLMPDocument(false)
+ , m_hasDocTypeDeclaration(false)
+#endif
, m_parserPaused(false)
, m_requestingScript(false)
, m_finishCalled(false)
@@ -552,6 +558,10 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
, m_sawXSLTransform(false)
, m_sawFirstElement(false)
, m_isXHTMLDocument(false)
+#if ENABLE(XHTMLMP)
+ , m_isXHTMLMPDocument(false)
+ , m_hasDocTypeDeclaration(false)
+#endif
, m_parserPaused(false)
, m_requestingScript(false)
, m_finishCalled(false)
@@ -582,7 +592,7 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
return;
for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
- if (NamedAttrMap* attrs = element->attributes()) {
+ if (NamedNodeMap* attrs = element->attributes()) {
for (unsigned i = 0; i < attrs->length(); i++) {
Attribute* attr = attrs->attributeItem(i);
if (attr->localName() == "xmlns")
@@ -624,6 +634,7 @@ void XMLTokenizer::doWrite(const String& parseString)
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
xmlSwitchEncoding(m_context, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
+ XMLTokenizerScope scope(m_doc->docLoader());
xmlParseChunk(m_context, reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
}
@@ -705,8 +716,14 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
nb_attributes, nb_defaulted, libxmlAttributes);
return;
}
-
- m_sawFirstElement = true;
+
+#if ENABLE(XHTMLMP)
+ // check if the DOCTYPE Declaration of XHTMLMP document exists
+ if (!m_hasDocTypeDeclaration && m_doc->isXHTMLMPDocument()) {
+ handleError(fatal, "DOCTYPE declaration lost.", lineNumber(), columnNumber());
+ return;
+ }
+#endif
exitText();
@@ -721,14 +738,35 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
uri = m_defaultNamespaceURI;
}
- ExceptionCode ec = 0;
+#if ENABLE(XHTMLMP)
+ if (!m_sawFirstElement && isXHTMLMPDocument()) {
+ // As per the section 7.1 of OMA-WAP-XHTMLMP-V1_1-20061020-A.pdf,
+ // we should make sure that the root element MUST be 'html' and
+ // ensure the name of the default namespace on the root elment 'html'
+ // MUST be 'http://www.w3.org/1999/xhtml'
+ if (localName != HTMLNames::htmlTag.localName()) {
+ handleError(fatal, "XHTMLMP document expects 'html' as root element.", lineNumber(), columnNumber());
+ return;
+ }
+
+ if (uri.isNull()) {
+ m_defaultNamespaceURI = HTMLNames::xhtmlNamespaceURI;
+ uri = m_defaultNamespaceURI;
+ }
+ }
+#endif
+
+ bool isFirstElement = !m_sawFirstElement;
+ m_sawFirstElement = true;
+
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();
@@ -737,7 +775,7 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
ScriptController* jsProxy = m_doc->frame() ? m_doc->frame()->script() : 0;
if (jsProxy && m_doc->frame()->script()->isEnabled())
- jsProxy->setEventHandlerLineno(lineNumber());
+ jsProxy->setEventHandlerLineNumber(lineNumber());
handleElementAttributes(newElement.get(), libxmlAttributes, nb_attributes, ec);
if (ec) {
@@ -746,11 +784,12 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
}
if (jsProxy)
- jsProxy->setEventHandlerLineno(0);
+ jsProxy->setEventHandlerLineNumber(0);
newElement->beginParsingChildren();
- if (isScriptElement(newElement.get()))
+ ScriptElement* scriptElement = toScriptElement(newElement.get());
+ if (scriptElement)
m_scriptStartLine = lineNumber();
if (!m_currentNode->addChild(newElement.get())) {
@@ -761,6 +800,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()
@@ -778,15 +820,29 @@ void XMLTokenizer::endElementNs()
Node* n = m_currentNode;
RefPtr<Node> parent = n->parentNode();
n->finishParsingChildren();
-
- // don't load external scripts for standalone documents (for now)
- if (n->isElementNode() && m_view && isScriptElement(static_cast<Element*>(n))) {
- ASSERT(!m_pendingScript);
- m_requestingScript = true;
- Element* element = static_cast<Element*>(n);
- ScriptElement* scriptElement = castToScriptElement(element);
+ if (!n->isElementNode() || !m_view) {
+ setCurrentNode(parent.get());
+ return;
+ }
+
+ Element* element = static_cast<Element*>(n);
+ ScriptElement* scriptElement = toScriptElement(element);
+ if (!scriptElement) {
+ setCurrentNode(parent.get());
+ return;
+ }
+ // don't load external scripts for standalone documents (for now)
+ ASSERT(!m_pendingScript);
+ m_requestingScript = true;
+
+#if ENABLE(XHTMLMP)
+ if (!scriptElement->shouldExecuteAsJavaScript())
+ m_doc->setShouldProcessNoscriptElement(true);
+ else
+#endif
+ {
String scriptHref = scriptElement->sourceAttributeValue();
if (!scriptHref.isEmpty()) {
// we have a src attribute
@@ -802,10 +858,8 @@ void XMLTokenizer::endElementNs()
m_scriptElement = 0;
} else
m_view->frame()->loader()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), m_doc->url(), m_scriptStartLine));
-
- m_requestingScript = false;
}
-
+ m_requestingScript = false;
setCurrentNode(parent.get());
}
@@ -833,7 +887,8 @@ void XMLTokenizer::error(ErrorType type, const char* message, va_list args)
vsnprintf(m, sizeof(m) - 1, message, args);
#else
char* m;
- vasprintf(&m, message, args);
+ if (vasprintf(&m, message, args) == -1)
+ return;
#endif
if (m_parserPaused)
@@ -932,6 +987,9 @@ void XMLTokenizer::startDocument(const xmlChar* version, const xmlChar* encoding
void XMLTokenizer::endDocument()
{
exitText();
+#if ENABLE(XHTMLMP)
+ m_hasDocTypeDeclaration = false;
+#endif
}
void XMLTokenizer::internalSubset(const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID)
@@ -945,8 +1003,10 @@ void XMLTokenizer::internalSubset(const xmlChar* name, const xmlChar* externalID
}
if (m_doc) {
-#if ENABLE(WML)
+#if ENABLE(WML) || ENABLE(XHTMLMP)
String extId = toString(externalID);
+#endif
+#if ENABLE(WML)
if (isWMLDocument()
&& extId != "-//WAPFORUM//DTD WML 1.3//EN"
&& extId != "-//WAPFORUM//DTD WML 1.2//EN"
@@ -954,8 +1014,31 @@ void XMLTokenizer::internalSubset(const xmlChar* name, const xmlChar* externalID
&& extId != "-//WAPFORUM//DTD WML 1.0//EN")
handleError(fatal, "Invalid DTD Public ID", lineNumber(), columnNumber());
#endif
+#if ENABLE(XHTMLMP)
+ String dtdName = toString(name);
+ if (extId == "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
+ || extId == "-//WAPFORUM//DTD XHTML Mobile 1.1//EN") {
+ if (dtdName != HTMLNames::htmlTag.localName()) {
+ handleError(fatal, "Invalid DOCTYPE declaration, expected 'html' as root element.", lineNumber(), columnNumber());
+ return;
+ }
+
+ if (m_doc->isXHTMLMPDocument())
+ setIsXHTMLMPDocument(true);
+ else
+ setIsXHTMLDocument(true);
+
+ m_hasDocTypeDeclaration = true;
+ }
+#endif
+#if ENABLE(XHTMLMP)
+ m_doc->addChild(DocumentType::create(m_doc, dtdName, extId, toString(systemID)));
+#elif ENABLE(WML)
+ m_doc->addChild(DocumentType::create(m_doc, toString(name), extId, toString(systemID)));
+#else
m_doc->addChild(DocumentType::create(m_doc, toString(name), toString(externalID), toString(systemID)));
+#endif
}
}
@@ -970,6 +1053,8 @@ static inline XMLTokenizer* getTokenizer(void* closure)
static inline bool hackAroundLibXMLEntityBug(void* closure)
{
#if LIBXML_VERSION >= 20627
+ UNUSED_PARAM(closure);
+
// This bug has been fixed in libxml 2.6.27.
return false;
#else
@@ -1052,19 +1137,22 @@ static void normalErrorHandler(void* closure, const char* message, ...)
va_end(args);
}
-// Using a global variable entity and marking it XML_INTERNAL_PREDEFINED_ENTITY is
+// Using a static entity and marking it XML_INTERNAL_PREDEFINED_ENTITY is
// a hack to avoid malloc/free. Using a global variable like this could cause trouble
// if libxml implementation details were to change
-static xmlChar sharedXHTMLEntityResult[5] = {0,0,0,0,0};
-static xmlEntity sharedXHTMLEntity = {
- 0, XML_ENTITY_DECL, 0, 0, 0, 0, 0, 0, 0,
- sharedXHTMLEntityResult, sharedXHTMLEntityResult, 0,
- XML_INTERNAL_PREDEFINED_ENTITY, 0, 0, 0, 0, 0,
-#if LIBXML_VERSION >= 20627
- // xmlEntity gained an extra member in 2.6.27.
- 1
-#endif
-};
+static xmlChar sharedXHTMLEntityResult[5] = {0, 0, 0, 0, 0};
+
+static xmlEntityPtr sharedXHTMLEntity()
+{
+ static xmlEntity entity;
+ if (!entity.type) {
+ entity.type = XML_ENTITY_DECL;
+ entity.orig = sharedXHTMLEntityResult;
+ entity.content = sharedXHTMLEntityResult;
+ entity.etype = XML_INTERNAL_PREDEFINED_ENTITY;
+ }
+ return &entity;
+}
static xmlEntityPtr getXHTMLEntity(const xmlChar* name)
{
@@ -1074,11 +1162,12 @@ static xmlEntityPtr getXHTMLEntity(const xmlChar* name)
CString value = String(&c, 1).utf8();
ASSERT(value.length() < 5);
- sharedXHTMLEntity.length = value.length();
- sharedXHTMLEntity.name = name;
- memcpy(sharedXHTMLEntityResult, value.data(), sharedXHTMLEntity.length + 1);
+ xmlEntityPtr entity = sharedXHTMLEntity();
+ entity->length = value.length();
+ entity->name = name;
+ memcpy(sharedXHTMLEntityResult, value.data(), entity->length + 1);
- return &sharedXHTMLEntity;
+ return entity;
}
static xmlEntityPtr getEntityHandler(void* closure, const xmlChar* name)
@@ -1092,6 +1181,9 @@ static xmlEntityPtr getEntityHandler(void* closure, const xmlChar* name)
ent = xmlGetDocEntity(ctxt->myDoc, name);
if (!ent && (getTokenizer(closure)->isXHTMLDocument()
+#if ENABLE(XHTMLMP)
+ || getTokenizer(closure)->isXHTMLMPDocument()
+#endif
#if ENABLE(WML)
|| getTokenizer(closure)->isWMLDocument()
#endif
@@ -1133,7 +1225,10 @@ static void externalSubsetHandler(void* closure, const xmlChar*, const xmlChar*
|| (extId == "-//W3C//DTD XHTML Basic 1.0//EN")
|| (extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN")
|| (extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN")
- || (extId == "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"))
+#if !ENABLE(XHTMLMP)
+ || (extId == "-//WAPFORUM//DTD XHTML Mobile 1.0//EN")
+#endif
+ )
getTokenizer(closure)->setIsXHTMLDocument(true); // controls if we replace entities or not.
}
@@ -1171,6 +1266,7 @@ void XMLTokenizer::initializeParserContext(const char* chunk)
m_sawXSLTransform = false;
m_sawFirstElement = false;
+ XMLTokenizerScope scope(m_doc->docLoader());
if (m_parsingFragment)
m_context = createMemoryParser(&sax, this, chunk);
else
@@ -1192,8 +1288,11 @@ void XMLTokenizer::doEnd()
if (m_context) {
// Tell libxml we're done.
- xmlParseChunk(m_context, 0, 0, 1);
-
+ {
+ XMLTokenizerScope scope(m_doc->docLoader());
+ xmlParseChunk(m_context, 0, 0, 1);
+ }
+
if (m_context->myDoc)
xmlFreeDoc(m_context->myDoc);
xmlFreeParserCtxt(m_context);
@@ -1213,21 +1312,12 @@ void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const Strin
const UChar BOM = 0xFEFF;
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
- xmlGenericErrorFunc oldErrorFunc = xmlGenericError;
- void* oldErrorContext = xmlGenericErrorContext;
-
- setLoaderForLibXMLCallbacks(docLoader);
- xmlSetGenericErrorFunc(0, errorFunc);
-
+ XMLTokenizerScope scope(docLoader, errorFunc, 0);
xmlDocPtr sourceDoc = xmlReadMemory(reinterpret_cast<const char*>(source.characters()),
source.length() * sizeof(UChar),
url.latin1().data(),
BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE",
XSLT_PARSE_OPTIONS);
-
- setLoaderForLibXMLCallbacks(0);
- xmlSetGenericErrorFunc(oldErrorContext, oldErrorFunc);
-
return sourceDoc;
}
#endif
@@ -1281,7 +1371,8 @@ bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, E
XMLTokenizer tokenizer(fragment, parent);
- tokenizer.initializeParserContext(chunk.utf8().data());
+ CString chunkAsUtf8 = chunk.utf8();
+ tokenizer.initializeParserContext(chunkAsUtf8.data());
xmlParseContent(tokenizer.m_context);
@@ -1289,7 +1380,7 @@ bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, E
// Check if all the chunk has been processed.
long bytesProcessed = xmlByteConsumed(tokenizer.m_context);
- if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) == sizeof(UChar) * chunk.length())
+ if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length())
return false;
// No error if the chunk is well formed or it is not but we have no error.
diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp
index 39ccefe..3173708 100644
--- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp
+++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp
@@ -5,7 +5,7 @@
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Holger Hans Peter Freyther
- * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -56,6 +56,11 @@
#include <wtf/Threading.h>
#include <wtf/Vector.h>
+#if ENABLE(XHTMLMP)
+#include "HTMLNames.h"
+#include "HTMLScriptElement.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -85,6 +90,10 @@ XMLTokenizer::XMLTokenizer(Document* _doc, FrameView* _view)
, m_sawXSLTransform(false)
, m_sawFirstElement(false)
, m_isXHTMLDocument(false)
+#if ENABLE(XHTMLMP)
+ , m_isXHTMLMPDocument(false)
+ , m_hasDocTypeDeclaration(false)
+#endif
, m_parserPaused(false)
, m_requestingScript(false)
, m_finishCalled(false)
@@ -110,6 +119,10 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
, m_sawXSLTransform(false)
, m_sawFirstElement(false)
, m_isXHTMLDocument(false)
+#if ENABLE(XHTMLMP)
+ , m_isXHTMLMPDocument(false)
+ , m_hasDocTypeDeclaration(false)
+#endif
, m_parserPaused(false)
, m_requestingScript(false)
, m_finishCalled(false)
@@ -141,7 +154,7 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
#if QT_VERSION < 0x040400
for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
- if (NamedAttrMap* attrs = element->attributes()) {
+ if (NamedNodeMap* attrs = element->attributes()) {
for (unsigned i = 0; i < attrs->length(); i++) {
Attribute* attr = attrs->attributeItem(i);
if (attr->localName() == "xmlns")
@@ -154,7 +167,7 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
#else
QXmlStreamNamespaceDeclarations namespaces;
for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
- if (NamedAttrMap* attrs = element->attributes()) {
+ if (NamedNodeMap* attrs = element->attributes()) {
for (unsigned i = 0; i < attrs->length(); i++) {
Attribute* attr = attrs->attributeItem(i);
if (attr->localName() == "xmlns")
@@ -357,7 +370,7 @@ HashMap<String, String> parseAttributes(const String& string, bool& attrsOK)
state.gotAttributes = false;
QXmlStreamReader stream;
- QString dummy = QString::fromLatin1("<?xml version=\"1.0\"?><attrs %1 />").arg(string);
+ QString dummy = QString(QLatin1String("<?xml version=\"1.0\"?><attrs %1 />")).arg(string);
stream.addData(dummy);
while (!stream.atEnd()) {
stream.readNext();
@@ -419,6 +432,12 @@ void XMLTokenizer::parse()
}
break;
case QXmlStreamReader::StartElement: {
+#if ENABLE(XHTMLMP)
+ if (m_doc->isXHTMLMPDocument() && !m_hasDocTypeDeclaration) {
+ handleError(fatal, "DOCTYPE declaration lost.", lineNumber(), columnNumber());
+ break;
+ }
+#endif
parseStartElement();
}
break;
@@ -443,12 +462,18 @@ void XMLTokenizer::parse()
case QXmlStreamReader::DTD: {
//qDebug()<<"------------- DTD";
parseDtd();
+#if ENABLE(XHTMLMP)
+ m_hasDocTypeDeclaration = true;
+#endif
}
break;
case QXmlStreamReader::EntityReference: {
//qDebug()<<"---------- ENTITY = "<<m_stream.name().toString()
// <<", t = "<<m_stream.text().toString();
if (isXHTMLDocument()
+#if ENABLE(XHTMLMP)
+ || isXHTMLMPDocument()
+#endif
#if ENABLE(WML)
|| isWMLDocument()
#endif
@@ -507,7 +532,6 @@ void XMLTokenizer::parseStartElement()
m_sawFirstElement = true;
return;
}
- m_sawFirstElement = true;
exitText();
@@ -520,14 +544,36 @@ 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;
}
+#if ENABLE(XHTMLMP)
+ if (!m_sawFirstElement && isXHTMLMPDocument()) {
+ // As per 7.1 section of OMA-WAP-XHTMLMP-V1_1-20061020-A.pdf,
+ // we should make sure that the root element MUST be 'html' and
+ // ensure the name of the default namespace on the root elment 'html'
+ // MUST be 'http://www.w3.org/1999/xhtml'
+ if (localName != HTMLNames::htmlTag.localName()) {
+ handleError(fatal, "XHTMLMP document expects 'html' as root element.", lineNumber(), columnNumber());
+ return;
+ }
+
+ if (uri.isNull()) {
+ m_defaultNamespaceURI = HTMLNames::xhtmlNamespaceURI;
+ uri = m_defaultNamespaceURI;
+ m_stream.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration(prefix, HTMLNames::xhtmlNamespaceURI));
+ }
+ }
+#endif
+
+ bool isFirstElement = !m_sawFirstElement;
+ m_sawFirstElement = true;
+
+ ExceptionCode ec = 0;
handleElementNamespaces(newElement.get(), m_stream.namespaceDeclarations(), ec);
if (ec) {
stopParsing();
@@ -540,7 +586,8 @@ void XMLTokenizer::parseStartElement()
return;
}
- if (isScriptElement(newElement.get()))
+ ScriptElement* scriptElement = toScriptElement(newElement.get());
+ if (scriptElement)
m_scriptStartLine = lineNumber();
if (!m_currentNode->addChild(newElement.get())) {
@@ -551,6 +598,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()
@@ -561,17 +611,31 @@ void XMLTokenizer::parseEndElement()
RefPtr<Node> parent = n->parentNode();
n->finishParsingChildren();
- // don't load external scripts for standalone documents (for now)
- if (n->isElementNode() && m_view && isScriptElement(static_cast<Element*>(n))) {
- ASSERT(!m_pendingScript);
- m_requestingScript = true;
+ if (!n->isElementNode() || !m_view) {
+ setCurrentNode(parent.get());
+ return;
+ }
- Element* element = static_cast<Element*>(n);
- ScriptElement* scriptElement = castToScriptElement(element);
+ Element* element = static_cast<Element*>(n);
+ ScriptElement* scriptElement = toScriptElement(element);
+ if (!scriptElement) {
+ setCurrentNode(parent.get());
+ return;
+ }
+
+ // don't load external scripts for standalone documents (for now)
+ ASSERT(!m_pendingScript);
+ m_requestingScript = true;
+#if ENABLE(XHTMLMP)
+ if (!scriptElement->shouldExecuteAsJavaScript())
+ m_doc->setShouldProcessNoscriptElement(true);
+ else
+#endif
+ {
String scriptHref = scriptElement->sourceAttributeValue();
if (!scriptHref.isEmpty()) {
- // we have a src attribute
+ // we have a src attribute
String scriptCharset = scriptElement->scriptCharset();
if ((m_pendingScript = m_doc->docLoader()->requestScript(scriptHref, scriptCharset))) {
m_scriptElement = element;
@@ -580,14 +644,12 @@ void XMLTokenizer::parseEndElement()
// m_pendingScript will be 0 if script was already loaded and ref() executed it
if (m_pendingScript)
pauseParsing();
- } else
+ } else
m_scriptElement = 0;
} else
m_view->frame()->loader()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), m_doc->url(), m_scriptStartLine));
-
- m_requestingScript = false;
}
-
+ m_requestingScript = false;
setCurrentNode(parent.get());
}
@@ -622,7 +684,7 @@ void XMLTokenizer::parseProcessingInstruction()
#if ENABLE(XSLT)
m_sawXSLTransform = !m_sawFirstElement && pi->isXSL();
- if (m_sawXSLTransform && !m_doc->transformSourceDocument())
+ if (m_sawXSLTransform && !m_doc->transformSourceDocument()))
stopParsing();
#endif
}
@@ -650,6 +712,9 @@ void XMLTokenizer::parseComment()
void XMLTokenizer::endDocument()
{
+#if ENABLE(XHTMLMP)
+ m_hasDocTypeDeclaration = false;
+#endif
}
bool XMLTokenizer::hasError() const
@@ -743,9 +808,25 @@ void XMLTokenizer::parseDtd()
|| (publicId == QLatin1String("-//W3C//DTD XHTML Basic 1.0//EN"))
|| (publicId == QLatin1String("-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"))
|| (publicId == QLatin1String("-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"))
- || (publicId == QLatin1String("-//WAPFORUM//DTD XHTML Mobile 1.0//EN"))) {
+#if !ENABLE(XHTMLMP)
+ || (publicId == QLatin1String("-//WAPFORUM//DTD XHTML Mobile 1.0//EN"))
+#endif
+ )
setIsXHTMLDocument(true); // controls if we replace entities or not.
+#if ENABLE(XHTMLMP)
+ else if ((publicId == QLatin1String("-//WAPFORUM//DTD XHTML Mobile 1.1//EN"))
+ || (publicId == QLatin1String("-//WAPFORUM//DTD XHTML Mobile 1.0//EN"))) {
+ if (AtomicString(name) != HTMLNames::htmlTag.localName()) {
+ handleError(fatal, "Invalid DOCTYPE declaration, expected 'html' as root element.", lineNumber(), columnNumber());
+ return;
+ }
+
+ if (m_doc->isXHTMLMPDocument()) // check if the MIME type is correct with this method
+ setIsXHTMLMPDocument(true);
+ else
+ setIsXHTMLDocument(true);
}
+#endif
#if ENABLE(WML)
else if (m_doc->isWMLDocument()
&& publicId != QLatin1String("-//WAPFORUM//DTD WML 1.3//EN")
@@ -760,4 +841,3 @@ void XMLTokenizer::parseDtd()
}
}
-
diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerScope.cpp b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerScope.cpp
new file mode 100644
index 0000000..3769f59
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerScope.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "XMLTokenizerScope.h"
+
+namespace WebCore {
+
+DocLoader* XMLTokenizerScope::currentDocLoader = 0;
+
+XMLTokenizerScope::XMLTokenizerScope(DocLoader* docLoader)
+ : m_oldDocLoader(currentDocLoader)
+#if ENABLE(XSLT)
+ , m_oldGenericErrorFunc(xmlGenericError)
+ , m_oldStructuredErrorFunc(xmlStructuredError)
+ , m_oldErrorContext(xmlGenericErrorContext)
+#endif
+{
+ currentDocLoader = docLoader;
+}
+
+#if ENABLE(XSLT)
+XMLTokenizerScope::XMLTokenizerScope(DocLoader* docLoader, xmlGenericErrorFunc genericErrorFunc, xmlStructuredErrorFunc structuredErrorFunc, void* errorContext)
+ : m_oldDocLoader(currentDocLoader)
+ , m_oldGenericErrorFunc(xmlGenericError)
+ , m_oldStructuredErrorFunc(xmlStructuredError)
+ , m_oldErrorContext(xmlGenericErrorContext)
+{
+ currentDocLoader = docLoader;
+ if (genericErrorFunc)
+ xmlSetGenericErrorFunc(errorContext, genericErrorFunc);
+ if (structuredErrorFunc)
+ xmlSetStructuredErrorFunc(errorContext, structuredErrorFunc);
+}
+#endif
+
+XMLTokenizerScope::~XMLTokenizerScope()
+{
+ currentDocLoader = m_oldDocLoader;
+#if ENABLE(XSLT)
+ xmlSetGenericErrorFunc(m_oldErrorContext, m_oldGenericErrorFunc);
+ xmlSetStructuredErrorFunc(m_oldErrorContext, m_oldStructuredErrorFunc);
+#endif
+}
+
+}
diff --git a/src/3rdparty/webkit/WebCore/dom/WorkerTask.h b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerScope.h
index a842ce2..a3c1188 100644
--- a/src/3rdparty/webkit/WebCore/dom/WorkerTask.h
+++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerScope.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
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * 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
@@ -21,28 +21,42 @@
* 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 WorkerTask_h
-#define WorkerTask_h
+#ifndef XMLTokenizerScope_h
+#define XMLTokenizerScope_h
-#if ENABLE(WORKERS)
+#include <wtf/Noncopyable.h>
-#include <wtf/Threading.h>
+#if ENABLE(XSLT)
+#include <libxml/tree.h>
+#endif
namespace WebCore {
- class WorkerContext;
+ class DocLoader;
- class WorkerTask : public ThreadSafeShared<WorkerTask> {
+ class XMLTokenizerScope : Noncopyable {
public:
- virtual ~WorkerTask();
- virtual void performTask(WorkerContext*) = 0;
+ XMLTokenizerScope(DocLoader* docLoader);
+ ~XMLTokenizerScope();
+
+ static DocLoader* currentDocLoader;
+
+#if ENABLE(XSLT)
+ XMLTokenizerScope(DocLoader* docLoader, xmlGenericErrorFunc genericErrorFunc, xmlStructuredErrorFunc structuredErrorFunc = 0, void* errorContext = 0);
+#endif
+
+ private:
+ DocLoader* m_oldDocLoader;
+
+#if ENABLE(XSLT)
+ xmlGenericErrorFunc m_oldGenericErrorFunc;
+ xmlStructuredErrorFunc m_oldStructuredErrorFunc;
+ void* m_oldErrorContext;
+#endif
};
} // namespace WebCore
-#endif // ENABLE(WORKERS)
-
-#endif // WorkerTask_h
+#endif // XMLTokenizerScope_h
diff --git a/src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.cpp b/src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.cpp
new file mode 100644
index 0000000..80ab7c8
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.cpp
@@ -0,0 +1,222 @@
+/*
+ * 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"
+#include "PlatformMessagePortChannel.h"
+
+#include "MessagePort.h"
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+// MessagePortChannel implementations - just delegate to the PlatformMessagePortChannel.
+bool MessagePortChannel::entangleIfOpen(MessagePort* port)
+{
+ return m_channel->entangleIfOpen(port);
+}
+
+void MessagePortChannel::disentangle()
+{
+ m_channel->disentangle();
+}
+
+void MessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message)
+{
+ m_channel->postMessageToRemote(message);
+}
+
+bool MessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result)
+{
+ return m_channel->tryGetMessageFromRemote(result);
+}
+
+void MessagePortChannel::close()
+{
+ m_channel->close();
+}
+
+bool MessagePortChannel::isConnectedTo(MessagePort* port)
+{
+ return m_channel->isConnectedTo(port);
+}
+
+bool MessagePortChannel::hasPendingActivity()
+{
+ return m_channel->hasPendingActivity();
+}
+
+MessagePort* MessagePortChannel::locallyEntangledPort(const ScriptExecutionContext* context)
+{
+ return m_channel->locallyEntangledPort(context);
+}
+
+PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::create(PassRefPtr<MessagePortQueue> incoming, PassRefPtr<MessagePortQueue> outgoing)
+{
+ return adoptRef(new PlatformMessagePortChannel(incoming, outgoing));
+}
+
+PlatformMessagePortChannel::PlatformMessagePortChannel(PassRefPtr<MessagePortQueue> incoming, PassRefPtr<MessagePortQueue> outgoing)
+ : m_entangledChannel(0)
+ , m_incomingQueue(incoming)
+ , m_outgoingQueue(outgoing)
+ , m_remotePort(0)
+{
+}
+
+PlatformMessagePortChannel::~PlatformMessagePortChannel()
+{
+}
+
+void PlatformMessagePortChannel::createChannel(PassRefPtr<MessagePort> port1, PassRefPtr<MessagePort> port2)
+{
+ // Create incoming/outgoing queues.
+ RefPtr<PlatformMessagePortChannel::MessagePortQueue> queue1 = PlatformMessagePortChannel::MessagePortQueue::create();
+ RefPtr<PlatformMessagePortChannel::MessagePortQueue> queue2 = PlatformMessagePortChannel::MessagePortQueue::create();
+
+ // Create proxies for each endpoint.
+ RefPtr<PlatformMessagePortChannel> channel1 = PlatformMessagePortChannel::create(queue1, queue2);
+ RefPtr<PlatformMessagePortChannel> channel2 = PlatformMessagePortChannel::create(queue2, queue1);
+
+ // Entangle the two endpoints.
+ channel1->setEntangledChannel(channel2);
+ channel2->setEntangledChannel(channel1);
+
+ // Now entangle the proxies with the appropriate local ports.
+ port1->entangle(MessagePortChannel::create(channel2));
+ port2->entangle(MessagePortChannel::create(channel1));
+}
+
+bool PlatformMessagePortChannel::entangleIfOpen(MessagePort* port)
+{
+ // We can't call member functions on our remote pair while holding our mutex or we'll deadlock, but we need to guard against the remote port getting closed/freed, so create a standalone reference.
+ RefPtr<PlatformMessagePortChannel> remote = entangledChannel();
+ if (!remote)
+ return false;
+ remote->setRemotePort(port);
+ return true;
+}
+
+void PlatformMessagePortChannel::disentangle()
+{
+ RefPtr<PlatformMessagePortChannel> remote = entangledChannel();
+ if (remote)
+ remote->setRemotePort(0);
+}
+
+void PlatformMessagePortChannel::setRemotePort(MessagePort* port)
+{
+ MutexLocker lock(m_mutex);
+ // Should never set port if it is already set.
+ ASSERT(!port || !m_remotePort);
+ m_remotePort = port;
+}
+
+MessagePort* PlatformMessagePortChannel::remotePort()
+{
+ MutexLocker lock(m_mutex);
+ return m_remotePort;
+}
+
+PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::entangledChannel()
+{
+ MutexLocker lock(m_mutex);
+ return m_entangledChannel;
+}
+
+void PlatformMessagePortChannel::setEntangledChannel(PassRefPtr<PlatformMessagePortChannel> remote)
+{
+ MutexLocker lock(m_mutex);
+ // Should only be set as part of initial creation/entanglement.
+ if (remote)
+ ASSERT(!m_entangledChannel.get());
+ m_entangledChannel = remote;
+}
+
+void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message)
+{
+ MutexLocker lock(m_mutex);
+ if (!m_outgoingQueue)
+ return;
+ bool wasEmpty = m_outgoingQueue->appendAndCheckEmpty(message);
+ if (wasEmpty && m_remotePort)
+ m_remotePort->messageAvailable();
+}
+
+bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result)
+{
+ MutexLocker lock(m_mutex);
+ return m_incomingQueue->tryGetMessage(result);
+}
+
+bool PlatformMessagePortChannel::isConnectedTo(MessagePort* port)
+{
+ MutexLocker lock(m_mutex);
+ return m_remotePort == port;
+}
+
+// Closes the port so no further messages can be sent from either end.
+void PlatformMessagePortChannel::close()
+{
+ RefPtr<PlatformMessagePortChannel> remote = entangledChannel();
+ if (!remote)
+ return;
+ closeInternal();
+ remote->closeInternal();
+}
+
+void PlatformMessagePortChannel::closeInternal()
+{
+ MutexLocker lock(m_mutex);
+ // Disentangle ourselves from the other end. We still maintain a reference to our incoming queue, since previously-existing messages should still be delivered.
+ m_remotePort = 0;
+ m_entangledChannel = 0;
+ m_outgoingQueue = 0;
+}
+
+bool PlatformMessagePortChannel::hasPendingActivity()
+{
+ MutexLocker lock(m_mutex);
+ return !m_incomingQueue->isEmpty();
+}
+
+MessagePort* PlatformMessagePortChannel::locallyEntangledPort(const ScriptExecutionContext* context)
+{
+ MutexLocker lock(m_mutex);
+ // See if both contexts are run by the same thread (are the same context, or are both documents).
+ if (m_remotePort) {
+ // The remote port's ScriptExecutionContext is guaranteed not to change here - MessagePort::contextDestroyed() will close the port before the context goes away, and close() will block because we are holding the mutex.
+ ScriptExecutionContext* remoteContext = m_remotePort->scriptExecutionContext();
+ if (remoteContext == context || (remoteContext && remoteContext->isDocument() && context->isDocument()))
+ return m_remotePort;
+ }
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.h b/src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.h
new file mode 100644
index 0000000..0ce2d13
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/dom/default/PlatformMessagePortChannel.h
@@ -0,0 +1,129 @@
+/*
+ * 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 PlatformMessagePortChannel_h
+#define PlatformMessagePortChannel_h
+
+#include "MessagePortChannel.h"
+
+#include <wtf/MessageQueue.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+ class MessagePort;
+
+ // PlatformMessagePortChannel is a platform-dependent interface to the remote side of a message channel.
+ // This default implementation supports multiple threads running within a single process. Implementations for multi-process platforms should define these public APIs in their own platform-specific PlatformMessagePortChannel file.
+ // The goal of this implementation is to eliminate contention except when cloning or closing the port, so each side of the channel has its own separate mutex.
+ class PlatformMessagePortChannel : public ThreadSafeShared<PlatformMessagePortChannel> {
+ public:
+ static void createChannel(PassRefPtr<MessagePort>, PassRefPtr<MessagePort>);
+
+ // APIs delegated from MessagePortChannel.h
+ bool entangleIfOpen(MessagePort*);
+ void disentangle();
+ void postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData>);
+ bool tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>&);
+ void close();
+ bool isConnectedTo(MessagePort*);
+ bool hasPendingActivity();
+ MessagePort* locallyEntangledPort(const ScriptExecutionContext*);
+
+ // Wrapper for MessageQueue that allows us to do thread safe sharing by two proxies.
+ class MessagePortQueue : public ThreadSafeShared<MessagePortQueue> {
+ public:
+ static PassRefPtr<MessagePortQueue> create() { return adoptRef(new MessagePortQueue()); }
+
+ bool tryGetMessage(OwnPtr<MessagePortChannel::EventData>& message)
+ {
+ MessagePortChannel::EventData* holder = 0;
+ bool messageAvailable = m_queue.tryGetMessage(holder);
+ if (messageAvailable)
+ message.set(holder);
+ return messageAvailable;
+ }
+
+ bool appendAndCheckEmpty(PassOwnPtr<MessagePortChannel::EventData> message)
+ {
+ return m_queue.appendAndCheckEmpty(message.release());
+ }
+
+ bool isEmpty()
+ {
+ return m_queue.isEmpty();
+ }
+
+ ~MessagePortQueue()
+ {
+ // Manually free any items left in the queue, since we can't use OwnPtr internally.
+ MessagePortChannel::EventData* data = 0;
+ while (m_queue.tryGetMessage(data))
+ delete data;
+ }
+ private:
+ MessagePortQueue() { }
+
+ // OwnPtr is Noncopyable, so we can't use it as the template type in a MessageQueue. So we just store a pointer to EventData and manually free it in the destructor.
+ // FIXME: Use a lock-free queue implementation to completely eliminate contention when sending/receiving messages.
+ MessageQueue<MessagePortChannel::EventData*> m_queue;
+ };
+
+ ~PlatformMessagePortChannel();
+
+ private:
+ static PassRefPtr<PlatformMessagePortChannel> create(PassRefPtr<MessagePortQueue> incoming, PassRefPtr<MessagePortQueue> outgoing);
+ PlatformMessagePortChannel(PassRefPtr<MessagePortQueue> incoming, PassRefPtr<MessagePortQueue> outgoing);
+
+ PassRefPtr<PlatformMessagePortChannel> entangledChannel();
+ void setEntangledChannel(PassRefPtr<PlatformMessagePortChannel>);
+
+ void setRemotePort(MessagePort*);
+ MessagePort* remotePort();
+ void closeInternal();
+
+ // Mutex used to ensure exclusive access to the object internals.
+ Mutex m_mutex;
+
+ // Pointer to our entangled pair - cleared when close() is called.
+ RefPtr<PlatformMessagePortChannel> m_entangledChannel;
+
+ // Reference to the message queue for the (local) entangled port.
+ RefPtr<MessagePortQueue> m_incomingQueue;
+ RefPtr<MessagePortQueue> m_outgoingQueue;
+
+ // The port we are connected to (the remote port) - this is the port that is notified when new messages arrive.
+ MessagePort* m_remotePort;
+ };
+
+} // namespace WebCore
+
+#endif // PlatformMessagePortChannel_h
diff --git a/src/3rdparty/webkit/WebCore/dom/make_names.pl b/src/3rdparty/webkit/WebCore/dom/make_names.pl
index 8541c0b..12f0ec7 100755
--- a/src/3rdparty/webkit/WebCore/dom/make_names.pl
+++ b/src/3rdparty/webkit/WebCore/dom/make_names.pl
@@ -1,6 +1,8 @@
#!/usr/bin/perl -w
-# Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
+# Copyright (C) 2009, Julien Chaffraix <jchaffraix@webkit.org>
+# Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -87,10 +89,12 @@ if ($printWrapperFactory) {
sub initializeTagPropertyHash
{
return ('constructorNeedsCreatedByParser' => 0,
+ 'constructorNeedsFormElement' => 0,
'exportString' => 0,
'interfaceName' => defaultInterfaceName($_[0]),
# By default, the JSInterfaceName is the same as the interfaceName.
'JSInterfaceName' => defaultInterfaceName($_[0]),
+ 'mapToTagName' => '',
'wrapperOnlyIfMediaIsAvailable' => 0,
'conditional' => 0);
}
@@ -216,32 +220,147 @@ sub printMacros
}
}
+sub usesDefaultWrapper
+{
+ my $tagName = shift;
+ return $tagName eq $parameters{'namespace'} . "Element";
+}
+
+# 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'};
+ }
+
+ # 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";
+ }
+ }
+ 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 = shift;
+ my ($F, $tagConstructorMapRef) = @_;
+ my %tagConstructorMap = %$tagConstructorMapRef;
print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
- for my $name (sort keys %tags) {
- my $ucName = $tags{$name}{'interfaceName'};
- print F "static PassRefPtr<$parameters{'namespace'}Element> ${name}Constructor(Document* doc, bool createdByParser)\n";
- print F "{\n";
- if ($tags{$name}{'constructorNeedsCreatedByParser'}) {
- print F " return new ${ucName}($parameters{'namespace'}Names::${name}Tag, doc, createdByParser);\n";
- } else {
- print F " return new ${ucName}($parameters{'namespace'}Names::${name}Tag, doc);\n";
+ # 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';
+
+ my $conditional = $tags{$tagName}{"conditional"};
+ if ($conditional) {
+ my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
+ print F "#if ${conditionalString}\n\n";
+ }
+
+ printConstructorSignature($F, $tagName, $tagConstructorMap{$tagName}, "tagName");
+ printConstructorInterior($F, $tagName, $interfaceName, "tagName");
+
+ if ($conditional) {
+ print F "#endif\n\n";
}
- print F "}\n\n";
}
+
+ # Mapped tag name uses a special wrapper to keep their prefix and namespaceURI while using the mapped localname.
+ for my $tagName (sort keys %tagConstructorMap) {
+ if ($tags{$tagName}{'mapToTagName'}) {
+ my $mappedName = $tags{$tagName}{'mapToTagName'};
+ printConstructorSignature($F, $mappedName, $mappedName . "To" . $tagName, "tagName");
+ printConstructorInterior($F, $mappedName, $tags{$mappedName}{'interfaceName'}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");
+ }
+ }
+
print F "#endif\n" if $parameters{'guardFactoryWith'};
}
sub printFunctionInits
{
- my $F = shift;
+ my ($F, $tagConstructorMap) = @_;
+ my %tagConstructorMap = %$tagConstructorMap;
+
+ for my $tagName (sort keys %tagConstructorMap) {
+
+ my $conditional = $tags{$tagName}{"conditional"};
+ if ($conditional) {
+ my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
+ print F "#if ${conditionalString}\n";
+ }
- for my $name (sort keys %tags) {
- print F " gFunctionMap->set($parameters{'namespace'}Names::${name}Tag.localName().impl(), ${name}Constructor);\n";
+ if ($tags{$tagName}{'mapToTagName'}) {
+ print F " addTag(${tagName}Tag, $tags{$tagName}{'mapToTagName'}To${tagName}Constructor);\n";
+ } else {
+ print F " addTag(${tagName}Tag, $tagConstructorMap{$tagName}Constructor);\n";
+ }
+
+ if ($conditional) {
+ print F "#endif\n\n";
+ }
}
}
@@ -325,16 +444,23 @@ sub printNamesHeaderFile
if (keys %tags) {
print F "// Tags\n";
printMacros($F, "extern const WebCore::QualifiedName", "Tag", \%tags);
- print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size);\n";
}
if (keys %attrs) {
print F "// Attributes\n";
printMacros($F, "extern const WebCore::QualifiedName", "Attr", \%attrs);
- print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Attr(size_t* size);\n";
}
print F "#endif\n\n";
- print F "void init();\n\n";
+
+ if (keys %tags) {
+ print F "WebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size);\n";
+ }
+
+ if (keys %attrs) {
+ print F "WebCore::QualifiedName** get$parameters{'namespace'}Attrs(size_t* size);\n";
+ }
+
+ print F "\nvoid init();\n\n";
print F "} }\n\n";
print F "#endif\n\n";
@@ -536,28 +662,49 @@ print F <<END
END
;
+if ($parameters{'namespace'} eq "HTML") {
+ print F "#include \"HTMLFormElement.h\"\n";
+}
+
printElementIncludes($F);
print F <<END
#include <wtf/HashMap.h>
-using namespace WebCore;
+namespace WebCore {
-typedef PassRefPtr<$parameters{'namespace'}Element> (*ConstructorFunction)(Document*, bool createdByParser);
-typedef WTF::HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
+using namespace $parameters{'namespace'}Names;
-static FunctionMap* gFunctionMap = 0;
+END
+;
-namespace WebCore {
+print F "typedef PassRefPtr<$parameters{'namespace'}Element> (*ConstructorFunction)(const QualifiedName&, Document*";
+
+if ($parameters{'namespace'} eq "HTML") {
+ print F ", HTMLFormElement*";
+}
+
+print F ", bool createdByParser);\n";
+print F <<END
+typedef HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
+
+static FunctionMap* gFunctionMap = 0;
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)
@@ -569,16 +716,18 @@ static inline void createFunctionMapIfNecessary()
END
;
-printFunctionInits($F);
+printFunctionInits($F, \%tagConstructorMap);
print F "}\n";
-print F "#endif\n\n" if $parameters{'guardFactoryWith'};
+print F "#endif\n" if $parameters{'guardFactoryWith'};
-print F <<END
-PassRefPtr<$parameters{'namespace'}Element> $parameters{'namespace'}ElementFactory::create$parameters{'namespace'}Element(const QualifiedName& qName, Document* doc, bool createdByParser)
-{
-END
-;
+print F "\nPassRefPtr<$parameters{'namespace'}Element> $parameters{'namespace'}ElementFactory::create$parameters{'namespace'}Element(const QualifiedName& qName, Document* doc";
+
+if ($parameters{"namespace"} eq "HTML") {
+ print F ", HTMLFormElement* formElement";
+}
+
+print F ", bool createdByParser)\n{\n";
print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
@@ -587,21 +736,36 @@ 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)
- return func(doc, createdByParser);
-
- return new $parameters{'namespace'}Element(qName, doc);
END
;
+if ($parameters{"namespace"} eq "HTML") {
+ print F " return func(qName, doc, formElement, createdByParser);\n";
+} else {
+ print F " return func(qName, doc, createdByParser);\n";
+}
+
+print F " return new $parameters{'namespace'}Element(qName, doc);\n";
+
if ($parameters{'guardFactoryWith'}) {
print F <<END
@@ -648,13 +812,30 @@ namespace WebCore {
namespace WebCore {
class $parameters{'namespace'}Element;
+END
+;
+
+if ($parameters{'namespace'} eq "HTML") {
+ print F " class HTMLFormElement;\n";
+}
+print F<<END
// The idea behind this class is that there will eventually be a mapping from namespace URIs to ElementFactories that can dispense
// elements. In a compound document world, the generic createElement function (will end up being virtual) will be called.
class $parameters{'namespace'}ElementFactory {
public:
PassRefPtr<Element> createElement(const WebCore::QualifiedName&, WebCore::Document*, bool createdByParser = true);
- static PassRefPtr<$parameters{'namespace'}Element> create$parameters{'namespace'}Element(const WebCore::QualifiedName&, WebCore::Document*, bool createdByParser = true);
+END
+;
+print F " static PassRefPtr<$parameters{'namespace'}Element> create$parameters{'namespace'}Element(const WebCore::QualifiedName&, WebCore::Document*";
+
+if ($parameters{'namespace'} eq "HTML") {
+ print F ", HTMLFormElement* = 0";
+}
+
+print F ", bool /*createdByParser*/ = true);\n";
+
+printf F<<END
};
}
@@ -673,7 +854,7 @@ sub usesDefaultJSWrapper
my $name = shift;
# A tag reuses the default wrapper if its JSInterfaceName matches the default namespace Element.
- return $tags{$name}{'JSInterfaceName'} eq $parameters{"namespace"} . "Element";
+ return $tags{$name}{'JSInterfaceName'} eq $parameters{"namespace"} . "Element" || $tags{$name}{'JSInterfaceName'} eq "HTMLNoScriptElement";
}
sub printWrapperFunctions