summaryrefslogtreecommitdiffstats
path: root/WebCore/dom
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-12-15 10:12:09 +0000
committerSteve Block <steveblock@google.com>2009-12-17 17:41:10 +0000
commit643ca7872b450ea4efacab6188849e5aac2ba161 (patch)
tree6982576c228bcd1a7efe98afed544d840751094c /WebCore/dom
parentd026980fde6eb3b01c1fe49441174e89cd1be298 (diff)
downloadexternal_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.zip
external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.gz
external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.bz2
Merge webkit.org at r51976 : Initial merge by git.
Change-Id: Ib0e7e2f0fb4bee5a186610272edf3186f0986b43
Diffstat (limited to 'WebCore/dom')
-rw-r--r--WebCore/dom/BeforeUnloadEvent.cpp2
-rw-r--r--WebCore/dom/BeforeUnloadEvent.h2
-rw-r--r--WebCore/dom/CSSMappedAttributeDeclaration.cpp2
-rw-r--r--WebCore/dom/ClassNodeList.h4
-rw-r--r--WebCore/dom/Clipboard.cpp2
-rw-r--r--WebCore/dom/CompositionEvent.cpp63
-rw-r--r--WebCore/dom/CompositionEvent.h61
-rw-r--r--WebCore/dom/CompositionEvent.idl43
-rw-r--r--WebCore/dom/DOMImplementation.cpp3
-rw-r--r--WebCore/dom/Document.cpp158
-rw-r--r--WebCore/dom/Document.h47
-rw-r--r--WebCore/dom/Document.idl9
-rw-r--r--WebCore/dom/DynamicNodeList.cpp4
-rw-r--r--WebCore/dom/Element.cpp25
-rw-r--r--WebCore/dom/Element.h3
-rw-r--r--WebCore/dom/Event.cpp10
-rw-r--r--WebCore/dom/Event.h2
-rw-r--r--WebCore/dom/EventNames.cpp2
-rw-r--r--WebCore/dom/EventNames.h9
-rw-r--r--WebCore/dom/EventTarget.cpp35
-rw-r--r--WebCore/dom/EventTarget.h9
-rw-r--r--WebCore/dom/InputElement.h3
-rw-r--r--WebCore/dom/KeyboardEvent.cpp1
-rw-r--r--WebCore/dom/KeyboardEvent.h4
-rw-r--r--WebCore/dom/MappedAttributeEntry.h2
-rw-r--r--WebCore/dom/MessagePort.cpp4
-rw-r--r--WebCore/dom/MessagePort.h6
-rw-r--r--WebCore/dom/MessagePortChannel.h2
-rw-r--r--WebCore/dom/MouseRelatedEvent.h2
-rw-r--r--WebCore/dom/NamedAttrMap.cpp30
-rw-r--r--WebCore/dom/NamedMappedAttrMap.h6
-rw-r--r--WebCore/dom/Node.cpp50
-rw-r--r--WebCore/dom/Node.h4
-rw-r--r--WebCore/dom/NodeFilter.h5
-rw-r--r--WebCore/dom/NodeIterator.h7
-rw-r--r--WebCore/dom/NodeRareData.h4
-rw-r--r--WebCore/dom/PopStateEvent.cpp50
-rw-r--r--WebCore/dom/PopStateEvent.h57
-rw-r--r--WebCore/dom/PopStateEvent.idl40
-rw-r--r--WebCore/dom/Position.cpp79
-rw-r--r--WebCore/dom/Position.h12
-rw-r--r--WebCore/dom/PositionIterator.cpp12
-rw-r--r--WebCore/dom/ProcessingInstruction.cpp1
-rw-r--r--WebCore/dom/QualifiedName.cpp12
-rw-r--r--WebCore/dom/QualifiedName.h4
-rw-r--r--WebCore/dom/Range.cpp26
-rw-r--r--WebCore/dom/Range.h3
-rw-r--r--WebCore/dom/RangeException.h2
-rw-r--r--WebCore/dom/ScriptElement.cpp14
-rw-r--r--WebCore/dom/ScriptExecutionContext.cpp4
-rw-r--r--WebCore/dom/ScriptExecutionContext.h5
-rw-r--r--WebCore/dom/SpaceSplitString.cpp (renamed from WebCore/dom/ClassNames.cpp)6
-rw-r--r--WebCore/dom/SpaceSplitString.h (renamed from WebCore/dom/ClassNames.h)28
-rw-r--r--WebCore/dom/StyleElement.h2
-rw-r--r--WebCore/dom/StyledElement.h2
-rw-r--r--WebCore/dom/Tokenizer.h4
-rw-r--r--WebCore/dom/TreeWalker.h17
-rw-r--r--WebCore/dom/XMLTokenizer.cpp3
-rw-r--r--WebCore/dom/XMLTokenizer.h20
-rw-r--r--WebCore/dom/XMLTokenizerLibxml2.cpp59
-rw-r--r--WebCore/dom/XMLTokenizerQt.cpp117
-rw-r--r--WebCore/dom/default/PlatformMessagePortChannel.cpp3
-rw-r--r--WebCore/dom/default/PlatformMessagePortChannel.h21
63 files changed, 852 insertions, 376 deletions
diff --git a/WebCore/dom/BeforeUnloadEvent.cpp b/WebCore/dom/BeforeUnloadEvent.cpp
index 2521aa1..97d7f97 100644
--- a/WebCore/dom/BeforeUnloadEvent.cpp
+++ b/WebCore/dom/BeforeUnloadEvent.cpp
@@ -1,6 +1,4 @@
/**
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
diff --git a/WebCore/dom/BeforeUnloadEvent.h b/WebCore/dom/BeforeUnloadEvent.h
index 39c96fd..2644693 100644
--- a/WebCore/dom/BeforeUnloadEvent.h
+++ b/WebCore/dom/BeforeUnloadEvent.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
diff --git a/WebCore/dom/CSSMappedAttributeDeclaration.cpp b/WebCore/dom/CSSMappedAttributeDeclaration.cpp
index 7fe0915..9ee6474 100644
--- a/WebCore/dom/CSSMappedAttributeDeclaration.cpp
+++ b/WebCore/dom/CSSMappedAttributeDeclaration.cpp
@@ -1,6 +1,4 @@
/**
- * 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)
diff --git a/WebCore/dom/ClassNodeList.h b/WebCore/dom/ClassNodeList.h
index d40ee19..c519b3e 100644
--- a/WebCore/dom/ClassNodeList.h
+++ b/WebCore/dom/ClassNodeList.h
@@ -30,8 +30,8 @@
#ifndef ClassNodeList_h
#define ClassNodeList_h
-#include "ClassNames.h"
#include "DynamicNodeList.h"
+#include "SpaceSplitString.h"
namespace WebCore {
@@ -47,7 +47,7 @@ namespace WebCore {
virtual bool nodeMatches(Element*) const;
- ClassNames m_classNames;
+ SpaceSplitString m_classNames;
};
} // namespace WebCore
diff --git a/WebCore/dom/Clipboard.cpp b/WebCore/dom/Clipboard.cpp
index 6d1bc15..2aea90a 100644
--- a/WebCore/dom/Clipboard.cpp
+++ b/WebCore/dom/Clipboard.cpp
@@ -55,6 +55,8 @@ void Clipboard::setAccessPolicy(ClipboardAccessPolicy policy)
static DragOperation dragOpFromIEOp(const String& op)
{
// yep, it's really just this fixed set
+ if (op == "uninitialized")
+ return DragOperationEvery;
if (op == "none")
return DragOperationNone;
if (op == "copy")
diff --git a/WebCore/dom/CompositionEvent.cpp b/WebCore/dom/CompositionEvent.cpp
new file mode 100644
index 0000000..508d5e6
--- /dev/null
+++ b/WebCore/dom/CompositionEvent.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "CompositionEvent.h"
+
+#include "EventNames.h"
+
+namespace WebCore {
+
+CompositionEvent::CompositionEvent()
+{
+}
+
+CompositionEvent::CompositionEvent(const AtomicString& type, PassRefPtr<AbstractView> view, const String& data)
+ : UIEvent(type, true, true, view, 0)
+ , m_data(data)
+{
+}
+
+CompositionEvent::~CompositionEvent()
+{
+}
+
+void CompositionEvent::initCompositionEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, const String& data)
+{
+ if (dispatched())
+ return;
+
+ initUIEvent(type, canBubble, cancelable, view, 0);
+
+ m_data = data;
+}
+
+bool CompositionEvent::isCompositionEvent() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/CompositionEvent.h b/WebCore/dom/CompositionEvent.h
new file mode 100644
index 0000000..4ff01ae
--- /dev/null
+++ b/WebCore/dom/CompositionEvent.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 CompositionEvent_h
+#define CompositionEvent_h
+
+#include "UIEvent.h"
+
+namespace WebCore {
+
+ class CompositionEvent : public UIEvent {
+ public:
+ static PassRefPtr<CompositionEvent> create()
+ {
+ return adoptRef(new CompositionEvent);
+ }
+ static PassRefPtr<CompositionEvent> create(const AtomicString& type, PassRefPtr<AbstractView> view, const String& data)
+ {
+ return adoptRef(new CompositionEvent(type, view, data));
+ }
+ virtual ~CompositionEvent();
+
+ void initCompositionEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, const String& data);
+
+ String data() const { return m_data; }
+
+ virtual bool isCompositionEvent() const;
+
+ private:
+ CompositionEvent();
+ CompositionEvent(const AtomicString& type, PassRefPtr<AbstractView> view, const String& data);
+
+ String m_data;
+ };
+
+} // namespace WebCore
+
+#endif // CompositionEvent_h
diff --git a/WebCore/dom/CompositionEvent.idl b/WebCore/dom/CompositionEvent.idl
new file mode 100644
index 0000000..3752091
--- /dev/null
+++ b/WebCore/dom/CompositionEvent.idl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 events {
+
+ // Introduced in DOM Level 3:
+ interface [
+ GenerateConstructor
+ ] CompositionEvent : UIEvent {
+
+ readonly attribute DOMString data;
+
+ void initCompositionEvent(in DOMString typeArg,
+ in boolean canBubbleArg,
+ in boolean cancelableArg,
+ in DOMWindow viewArg,
+ in DOMString dataArg);
+
+ };
+
+}
diff --git a/WebCore/dom/DOMImplementation.cpp b/WebCore/dom/DOMImplementation.cpp
index 59b9703..f7c8242 100644
--- a/WebCore/dom/DOMImplementation.cpp
+++ b/WebCore/dom/DOMImplementation.cpp
@@ -305,7 +305,8 @@ PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& tit
{
RefPtr<HTMLDocument> d = HTMLDocument::create(0);
d->open();
- d->write("<!doctype html><html><head><title>" + title + "</title></head><body></body></html>");
+ d->write("<!doctype html><html><body></body></html>");
+ d->setTitle(title);
return d.release();
}
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 174e58d..ba6dc97 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -98,6 +98,7 @@
#include "PageGroup.h"
#include "PageTransitionEvent.h"
#include "PlatformKeyboardEvent.h"
+#include "PopStateEvent.h"
#include "ProcessingInstruction.h"
#include "ProgressEvent.h"
#include "RegisteredEventListener.h"
@@ -386,15 +387,18 @@ Document::Document(Frame* frame, bool isXHTML)
m_ignoreAutofocus = false;
m_frame = frame;
+<<<<<<< HEAD:WebCore/dom/Document.cpp
m_renderArena = 0;
#if !PLATFORM(ANDROID)
+=======
+
+>>>>>>> webkit.org at r51976:WebCore/dom/Document.cpp
m_axObjectCache = 0;
#endif
m_docLoader = new DocLoader(this);
visuallyOrdered = false;
m_bParsing = false;
- m_tokenizer = 0;
m_wellFormed = false;
setParseMode(Strict);
@@ -465,8 +469,7 @@ void Document::removedLastRef()
deleteAllValues(m_markers);
m_markers.clear();
- delete m_tokenizer;
- m_tokenizer = 0;
+ m_tokenizer.clear();
m_cssCanvasElements.clear();
@@ -500,18 +503,15 @@ Document::~Document()
forgetAllDOMNodesForDocument(this);
#endif
- delete m_tokenizer;
+ m_tokenizer.clear();
m_document = 0;
delete m_styleSelector;
- delete m_docLoader;
-
- if (m_renderArena) {
- delete m_renderArena;
- m_renderArena = 0;
- }
+ m_docLoader.clear();
+
+ m_renderArena.clear();
#if ENABLE(XBL)
- delete m_bindingManager;
+ m_bindingManager.clear();
#endif
deleteAllValues(m_markers);
@@ -1264,13 +1264,13 @@ void Document::recalcStyle(StyleChange change)
return; // Guard against re-entrancy. -dwh
#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->willRecalculateStyle();
#endif
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
+ RenderWidget::suspendWidgetHierarchyUpdates();
if (view())
view()->pauseScheduledEvents();
@@ -1341,6 +1341,7 @@ bail_out:
if (view())
view()->resumeScheduledEvents();
+ RenderWidget::resumeWidgetHierarchyUpdates();
resumePostAttachCallbacks();
m_inStyleRecalc = false;
@@ -1351,7 +1352,7 @@ bail_out:
}
#if ENABLE(INSPECTOR)
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->didRecalculateStyle();
#endif
}
@@ -1442,7 +1443,7 @@ void Document::attach()
m_renderArena = new RenderArena();
// Create the rendering tree
- setRenderer(new (m_renderArena) RenderView(this, view()));
+ setRenderer(new (m_renderArena.get()) RenderView(this, view()));
#if USE(ACCELERATED_COMPOSITING)
renderView()->didMoveOnscreen();
#endif
@@ -1514,17 +1515,19 @@ void Document::detach()
if (render)
render->destroy();
+ HashSet<RefPtr<HistoryItem> > associatedHistoryItems;
+ associatedHistoryItems.swap(m_associatedHistoryItems);
+ HashSet<RefPtr<HistoryItem> >::iterator end = associatedHistoryItems.end();
+ for (HashSet<RefPtr<HistoryItem> >::iterator i = associatedHistoryItems.begin(); i != end; ++i)
+ (*i)->documentDetached(this);
+
// 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 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;
- m_renderArena = 0;
- }
+ m_renderArena.clear();
}
void Document::removeAllEventListeners()
@@ -1647,8 +1650,7 @@ void Document::cancelParsing()
// the onload handler when closing as a side effect of a cancel-style
// change, such as opening a new document or closing the window while
// still parsing
- delete m_tokenizer;
- m_tokenizer = 0;
+ m_tokenizer.clear();
close();
}
}
@@ -1657,8 +1659,7 @@ void Document::implicitOpen()
{
cancelParsing();
- delete m_tokenizer;
- m_tokenizer = 0;
+ m_tokenizer.clear();
removeChildren();
@@ -1755,8 +1756,7 @@ void Document::implicitClose()
// We have to clear the tokenizer, in case someone document.write()s from the
// onLoad event handler, as in Radar 3206524.
- delete m_tokenizer;
- m_tokenizer = 0;
+ m_tokenizer.clear();
// Parser should have picked up all preloads by now
m_docLoader->clearPreloads();
@@ -1793,6 +1793,9 @@ void Document::implicitClose()
ImageLoader::dispatchPendingEvents();
dispatchWindowLoadEvent();
dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, false), this);
+ if (m_pendingStateObject)
+ dispatchWindowEvent(PopStateEvent::create(m_pendingStateObject.release()));
+
if (f)
f->loader()->handledOnloadEvents();
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -2291,8 +2294,10 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
}
} else if (equalIgnoringCase(equiv, "set-cookie")) {
// FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
- if (isHTMLDocument())
- static_cast<HTMLDocument*>(this)->setCookie(content);
+ if (isHTMLDocument()) {
+ ExceptionCode ec; // Exception (for sandboxed documents) ignored.
+ static_cast<HTMLDocument*>(this)->setCookie(content, ec);
+ }
} else if (equalIgnoringCase(equiv, "content-language"))
setContentLanguage(content);
else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
@@ -2608,7 +2613,7 @@ void Document::recalcStyleSelector()
sheet = cssSheet.get();
}
}
- } else if (n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))
+ } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag)))
#if ENABLE(SVG)
|| (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
#endif
@@ -2770,14 +2775,14 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
oldFocusedNode->setActive(false);
oldFocusedNode->setFocus(false);
-
+
// Dispatch a change event for text fields or textareas that have been edited
RenderObject* r = oldFocusedNode->renderer();
- if (r && r->isTextControl() && toRenderTextControl(r)->isEdited()) {
- oldFocusedNode->dispatchEvent(Event::create(eventNames().changeEvent, true, false));
+ if (r && r->isTextControl() && toRenderTextControl(r)->wasChangedSinceLastChangeEvent()) {
+ static_cast<Element*>(oldFocusedNode.get())->dispatchFormControlChangeEvent();
r = oldFocusedNode->renderer();
if (r && r->isTextControl())
- toRenderTextControl(r)->setEdited(false);
+ toRenderTextControl(r)->setChangedSinceLastChangeEvent(false);
}
// Dispatch the blur event and let the node do any other blur related activities (important for text fields)
@@ -2861,6 +2866,8 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
axObjectCache()->handleFocusedUIElementChanged(oldFocusedRenderer, newFocusedRenderer);
}
#endif
+ if (!focusChangeBlocked)
+ page()->chrome()->focusedNodeChanged(m_focusedNode.get());
SetFocusedNodeDone:
updateStyleIfNeeded();
@@ -3112,11 +3119,20 @@ Element* Document::ownerElement() const
return frame()->ownerElement();
}
-String Document::cookie() const
+String Document::cookie(ExceptionCode& ec) const
{
if (page() && !page()->cookieEnabled())
return String();
+ // FIXME: The HTML5 DOM spec states that this attribute can raise an
+ // INVALID_STATE_ERR exception on getting if the Document has no
+ // browsing context.
+
+ if (securityOrigin()->isSandboxed(SandboxOrigin)) {
+ ec = SECURITY_ERR;
+ return String();
+ }
+
KURL cookieURL = this->cookieURL();
if (cookieURL.isEmpty())
return String();
@@ -3124,11 +3140,20 @@ String Document::cookie() const
return cookies(this, cookieURL);
}
-void Document::setCookie(const String& value)
+void Document::setCookie(const String& value, ExceptionCode& ec)
{
if (page() && !page()->cookieEnabled())
return;
+ // FIXME: The HTML5 DOM spec states that this attribute can raise an
+ // INVALID_STATE_ERR exception on setting if the Document has no
+ // browsing context.
+
+ if (securityOrigin()->isSandboxed(SandboxOrigin)) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
KURL cookieURL = this->cookieURL();
if (cookieURL.isEmpty())
return;
@@ -3855,7 +3880,7 @@ void Document::repaintMarkers(DocumentMarker::MarkerType markerType)
}
}
-void Document::setRenderedRectForMarker(Node* node, DocumentMarker marker, const IntRect& r)
+void Document::setRenderedRectForMarker(Node* node, const DocumentMarker& marker, const IntRect& r)
{
MarkerMapVectorPair* vectorPair = m_markers.get(node);
if (!vectorPair) {
@@ -4377,6 +4402,8 @@ void Document::initSecurityContext()
m_cookieURL = url;
ScriptExecutionContext::setSecurityOrigin(SecurityOrigin::create(url));
+ updateSandboxFlags();
+
if (SecurityOrigin::allowSubstituteDataAccessToLocal()) {
// If this document was loaded with substituteData, then the document can
// load local resources. See https://bugs.webkit.org/show_bug.cgi?id=16756
@@ -4427,6 +4454,46 @@ void Document::setSecurityOrigin(SecurityOrigin* securityOrigin)
initDNSPrefetch();
}
+void Document::updateURLForPushOrReplaceState(const KURL& url)
+{
+ Frame* f = frame();
+ if (!f)
+ return;
+
+ setURL(url);
+ f->loader()->documentLoader()->replaceRequestURLForSameDocumentNavigation(url);
+}
+
+void Document::statePopped(SerializedScriptValue* stateObject)
+{
+ Frame* f = frame();
+ if (!f)
+ return;
+
+ if (f->loader()->isComplete())
+ dispatchWindowEvent(PopStateEvent::create(stateObject));
+ else
+ m_pendingStateObject = stateObject;
+}
+
+void Document::registerHistoryItem(HistoryItem* item)
+{
+ ASSERT(!m_associatedHistoryItems.contains(item));
+ m_associatedHistoryItems.add(item);
+}
+
+void Document::unregisterHistoryItem(HistoryItem* item)
+{
+ ASSERT(m_associatedHistoryItems.contains(item) || m_associatedHistoryItems.isEmpty());
+ m_associatedHistoryItems.remove(item);
+}
+
+void Document::updateSandboxFlags()
+{
+ if (m_frame && securityOrigin())
+ securityOrigin()->setSandboxFlags(m_frame->loader()->sandboxFlags());
+}
+
void Document::updateFocusAppearanceSoon()
{
if (!m_updateFocusAppearanceTimer.isActive())
@@ -4690,7 +4757,7 @@ void Document::scriptImported(unsigned long identifier, const String& sourceStri
class ScriptExecutionContextTaskTimer : public TimerBase {
public:
- ScriptExecutionContextTaskTimer(PassRefPtr<Document> context, PassRefPtr<ScriptExecutionContext::Task> task)
+ ScriptExecutionContextTaskTimer(PassRefPtr<Document> context, PassOwnPtr<ScriptExecutionContext::Task> task)
: m_context(context)
, m_task(task)
{
@@ -4704,18 +4771,18 @@ private:
}
RefPtr<Document> m_context;
- RefPtr<ScriptExecutionContext::Task> m_task;
+ OwnPtr<ScriptExecutionContext::Task> m_task;
};
-struct PerformTaskContext {
- PerformTaskContext(ScriptExecutionContext* scriptExecutionContext, PassRefPtr<ScriptExecutionContext::Task> task)
+struct PerformTaskContext : Noncopyable {
+ PerformTaskContext(ScriptExecutionContext* scriptExecutionContext, PassOwnPtr<ScriptExecutionContext::Task> task)
: scriptExecutionContext(scriptExecutionContext)
, task(task)
{
}
ScriptExecutionContext* scriptExecutionContext; // The context should exist until task execution.
- RefPtr<ScriptExecutionContext::Task> task;
+ OwnPtr<ScriptExecutionContext::Task> task;
};
static void performTask(void* ctx)
@@ -4725,7 +4792,7 @@ static void performTask(void* ctx)
delete ptctx;
}
-void Document::postTask(PassRefPtr<Task> task)
+void Document::postTask(PassOwnPtr<Task> task)
{
if (isMainThread()) {
ScriptExecutionContextTaskTimer* timer = new ScriptExecutionContextTaskTimer(static_cast<Document*>(this), task);
@@ -4790,4 +4857,11 @@ bool Document::isXHTMLMPDocument() const
}
#endif
+#if ENABLE(INSPECTOR)
+InspectorTimelineAgent* Document::inspectorTimelineAgent() const
+{
+ return page() ? page()->inspectorTimelineAgent() : 0;
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 9f5785e..3d0582c 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -33,7 +33,6 @@
#include "CollectionType.h"
#include "Color.h"
#include "DocumentMarker.h"
-#include "Page.h"
#include "ScriptExecutionContext.h"
#include "Timer.h"
#include <wtf/HashCountedSet.h>
@@ -68,7 +67,6 @@ namespace WebCore {
class EventListener;
class Frame;
class FrameView;
- class HitTestRequest;
class HTMLCanvasElement;
class HTMLCollection;
class HTMLAllCollection;
@@ -78,6 +76,8 @@ namespace WebCore {
class HTMLHeadElement;
class HTMLInputElement;
class HTMLMapElement;
+ class HistoryItem;
+ class HitTestRequest;
class InspectorTimelineAgent;
class IntPoint;
class DOMWrapperWorld;
@@ -85,6 +85,7 @@ namespace WebCore {
class MouseEventWithHitTestResults;
class NodeFilter;
class NodeIterator;
+ class Page;
class PlatformMouseEvent;
class ProcessingInstruction;
class Range;
@@ -93,6 +94,7 @@ namespace WebCore {
class RenderView;
class ScriptElementData;
class SecurityOrigin;
+ class SerializedScriptValue;
class SegmentedString;
class Settings;
class StyleSheet;
@@ -451,12 +453,12 @@ public:
void updateLayout();
void updateLayoutIgnorePendingStylesheets();
static void updateStyleForAllDocuments(); // FIXME: Try to reduce the # of calls to this function.
- DocLoader* docLoader() { return m_docLoader; }
+ DocLoader* docLoader() { return m_docLoader.get(); }
virtual void attach();
virtual void detach();
- RenderArena* renderArena() { return m_renderArena; }
+ RenderArena* renderArena() { return m_renderArena.get(); }
RenderView* renderView() const;
@@ -504,7 +506,7 @@ public:
CSSStyleSheet* mappedElementSheet();
virtual Tokenizer* createTokenizer();
- Tokenizer* tokenizer() { return m_tokenizer; }
+ Tokenizer* tokenizer() { return m_tokenizer.get(); }
bool printing() const { return m_printing; }
void setPrinting(bool p) { m_printing = p; }
@@ -683,8 +685,8 @@ public:
void setTitle(const String&, Element* titleElement = 0);
void removeTitle(Element* titleElement);
- String cookie() const;
- void setCookie(const String&);
+ String cookie(ExceptionCode&) const;
+ void setCookie(const String&, ExceptionCode&);
String referrer() const;
@@ -738,7 +740,7 @@ public:
void removeMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
void removeMarkers(Node*);
void repaintMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- void setRenderedRectForMarker(Node*, DocumentMarker, const IntRect&);
+ void setRenderedRectForMarker(Node*, const DocumentMarker&, const IntRect&);
void invalidateRenderedRectsForMarkersInRect(const IntRect&);
void shiftMarkers(Node*, unsigned startOffset, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
void setMarkersActive(Range*, bool);
@@ -772,7 +774,7 @@ public:
#if ENABLE(XBL)
// XBL methods
- XBLBindingManager* bindingManager() const { return m_bindingManager; }
+ XBLBindingManager* bindingManager() const { return m_bindingManager.get(); }
#endif
void incDOMTreeVersion() { ++m_domtree_version; }
@@ -832,7 +834,7 @@ public:
virtual void addMessage(MessageDestination, MessageSource, MessageType, 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.
+ virtual void postTask(PassOwnPtr<Task>); // Executes the task on context's thread asynchronously.
typedef HashMap<WebCore::Node*, JSNode*> JSWrapperCache;
typedef HashMap<DOMWrapperWorld*, JSWrapperCache*> JSWrapperCacheMap;
@@ -900,6 +902,13 @@ public:
// that already contains content.
void setSecurityOrigin(SecurityOrigin*);
+ void updateURLForPushOrReplaceState(const KURL&);
+ void statePopped(SerializedScriptValue*);
+ void registerHistoryItem(HistoryItem* item);
+ void unregisterHistoryItem(HistoryItem* item);
+
+ void updateSandboxFlags(); // Set sandbox flags as determined by the frame.
+
bool processingLoadEvent() const { return m_processingLoadEvent; }
#if ENABLE(DATABASE)
@@ -976,8 +985,8 @@ private:
bool m_didCalculateStyleSelector;
Frame* m_frame;
- DocLoader* m_docLoader;
- Tokenizer* m_tokenizer;
+ OwnPtr<DocLoader> m_docLoader;
+ OwnPtr<Tokenizer> m_tokenizer;
bool m_wellFormed;
// Document URLs.
@@ -1076,8 +1085,8 @@ private:
String m_title;
bool m_titleSetExplicitly;
RefPtr<Element> m_titleElement;
-
- RenderArena* m_renderArena;
+
+ OwnPtr<RenderArena> m_renderArena;
typedef std::pair<Vector<DocumentMarker>, Vector<IntRect> > MarkerMapVectorPair;
typedef HashMap<RefPtr<Node>, MarkerMapVectorPair*> MarkerMap;
@@ -1090,6 +1099,8 @@ private:
Element* m_cssTarget;
bool m_processingLoadEvent;
+ RefPtr<SerializedScriptValue> m_pendingStateObject;
+ HashSet<RefPtr<HistoryItem> > m_associatedHistoryItems;
double m_startTime;
bool m_overMinimumLayoutThreshold;
@@ -1102,7 +1113,7 @@ private:
#endif
#if ENABLE(XBL)
- XBLBindingManager* m_bindingManager; // The access point through which documents and elements communicate with XBL.
+ OwnPtr<XBLBindingManager> m_bindingManager; // The access point through which documents and elements communicate with XBL.
#endif
typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName;
@@ -1204,12 +1215,6 @@ inline bool Node::isDocumentNode() const
return this == m_document;
}
-#if ENABLE(INSPECTOR)
-inline InspectorTimelineAgent* Document::inspectorTimelineAgent() const {
- return page() ? page()->inspectorTimelineAgent() : 0;
-}
-#endif
-
} // namespace WebCore
#endif // Document_h
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index ce7010a..e54add0 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -35,7 +35,7 @@ module core {
readonly attribute [V8Custom] DOMImplementation implementation;
readonly attribute Element documentElement;
- [ReturnsNew] Element createElement(in [ConvertNullToNullString, HintAtomic] DOMString tagName)
+ [ReturnsNew] Element createElement(in [ConvertNullToNullString] DOMString tagName)
raises (DOMException);
DocumentFragment createDocumentFragment();
[ReturnsNew] Text createTextNode(in DOMString data);
@@ -64,7 +64,7 @@ module core {
raises (DOMException);
[OldStyleObjC] NodeList getElementsByTagNameNS(in [ConvertNullToNullString] DOMString namespaceURI,
in DOMString localName);
- Element getElementById(in [HintAtomic] DOMString elementId);
+ Element getElementById(in DOMString elementId);
// DOM Level 3 Core
@@ -162,10 +162,9 @@ module core {
#endif
readonly attribute DOMString URL;
- // FIXME: the DOM spec states that this attribute can
- // raise an exception on setting.
attribute [ConvertNullToNullString] DOMString cookie
- /*setter raises (DOMException)*/;
+ setter raises (DOMException),
+ getter raises (DOMException);
// FIXME: the DOM spec does NOT have this attribute
// raising an exception.
diff --git a/WebCore/dom/DynamicNodeList.cpp b/WebCore/dom/DynamicNodeList.cpp
index 892a5e7..3f0744b 100644
--- a/WebCore/dom/DynamicNodeList.cpp
+++ b/WebCore/dom/DynamicNodeList.cpp
@@ -129,7 +129,9 @@ Node* DynamicNodeList::itemWithName(const AtomicString& elementId) const
return node;
}
}
- return 0;
+ if (!node)
+ return 0;
+ // In the case of multiple nodes with the same name, just fall through.
}
unsigned length = this->length();
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 9edde25..d7f1b11 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -47,6 +47,7 @@
#include "NodeRenderStyle.h"
#include "Page.h"
#include "RenderView.h"
+#include "RenderWidget.h"
#include "TextIterator.h"
#include "XMLNames.h"
@@ -135,6 +136,12 @@ void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
ExceptionCode ec;
setAttribute(name, value, ec);
}
+
+void Element::setCStringAttribute(const QualifiedName& name, const char* cStringValue)
+{
+ ExceptionCode ec;
+ setAttribute(name, AtomicString(cStringValue), ec);
+}
void Element::setBooleanAttribute(const QualifiedName& name, bool b)
{
@@ -488,8 +495,10 @@ static inline bool shouldIgnoreAttributeCase(const Element* e)
const AtomicString& Element::getAttribute(const String& name) const
{
- String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
- if (localName == styleAttr.localName() && !m_isStyleAttributeValid)
+ bool ignoreCase = shouldIgnoreAttributeCase(this);
+
+ // Update the 'style' attribute if it's invalid and being requested:
+ if (!m_isStyleAttributeValid && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
updateStyleAttribute();
#if ENABLE(SVG)
@@ -498,8 +507,8 @@ const AtomicString& Element::getAttribute(const String& name) const
#endif
if (namedAttrMap)
- if (Attribute* a = namedAttrMap->getAttributeItem(name, shouldIgnoreAttributeCase(this)))
- return a->value();
+ if (Attribute* attribute = namedAttrMap->getAttributeItem(name, ignoreCase))
+ return attribute->value();
return nullAtom;
}
@@ -727,6 +736,7 @@ void Element::removedFromDocument()
void Element::attach()
{
suspendPostAttachCallbacks();
+ RenderWidget::suspendWidgetHierarchyUpdates();
createRendererIfNeeded();
ContainerNode::attach();
@@ -739,20 +749,25 @@ void Element::attach()
}
}
+ RenderWidget::resumeWidgetHierarchyUpdates();
resumePostAttachCallbacks();
}
void Element::detach()
{
+ RenderWidget::suspendWidgetHierarchyUpdates();
+
cancelFocusAppearanceUpdate();
if (hasRareData())
rareData()->resetComputedStyle();
ContainerNode::detach();
+
+ RenderWidget::resumeWidgetHierarchyUpdates();
}
bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
{
- ASSERT(currentStyle = renderStyle());
+ ASSERT(currentStyle == renderStyle());
if (!renderer() || !currentStyle)
return false;
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index d27976a..97d3eb4 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -167,6 +167,9 @@ public:
// convenience methods which ignore exceptions
void setAttribute(const QualifiedName&, const AtomicString& value);
void setBooleanAttribute(const QualifiedName& name, bool);
+ // Please don't use setCStringAttribute in performance-sensitive code;
+ // use a static AtomicString value instead to avoid the conversion overhead.
+ void setCStringAttribute(const QualifiedName&, const char* cStringValue);
virtual NamedNodeMap* attributes() const;
NamedNodeMap* attributes(bool readonly) const;
diff --git a/WebCore/dom/Event.cpp b/WebCore/dom/Event.cpp
index 5d8eaaa..eda44b0 100644
--- a/WebCore/dom/Event.cpp
+++ b/WebCore/dom/Event.cpp
@@ -96,6 +96,11 @@ bool Event::isTextEvent() const
return false;
}
+bool Event::isCompositionEvent() const
+{
+ return false;
+}
+
bool Event::isDragEvent() const
{
return false;
@@ -131,6 +136,11 @@ bool Event::isPageTransitionEvent() const
return false;
}
+bool Event::isPopStateEvent() const
+{
+ return false;
+}
+
bool Event::isProgressEvent() const
{
return false;
diff --git a/WebCore/dom/Event.h b/WebCore/dom/Event.h
index b391985..7ec85a7 100644
--- a/WebCore/dom/Event.h
+++ b/WebCore/dom/Event.h
@@ -103,6 +103,7 @@ namespace WebCore {
virtual bool isMutationEvent() const;
virtual bool isKeyboardEvent() const;
virtual bool isTextEvent() const;
+ virtual bool isCompositionEvent() const;
virtual bool isDragEvent() const; // a subset of mouse events
virtual bool isClipboardEvent() const;
virtual bool isMessageEvent() const;
@@ -110,6 +111,7 @@ namespace WebCore {
virtual bool isBeforeTextInsertedEvent() const;
virtual bool isOverflowEvent() const;
virtual bool isPageTransitionEvent() const;
+ virtual bool isPopStateEvent() const;
virtual bool isProgressEvent() const;
virtual bool isXMLHttpRequestProgressEvent() const;
virtual bool isWebKitAnimationEvent() const;
diff --git a/WebCore/dom/EventNames.cpp b/WebCore/dom/EventNames.cpp
index 00191ab..900b8ef 100644
--- a/WebCore/dom/EventNames.cpp
+++ b/WebCore/dom/EventNames.cpp
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2005 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index b2db177..63460a5 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -41,6 +41,9 @@ namespace WebCore {
macro(checking) \
macro(click) \
macro(close) \
+ macro(compositionend) \
+ macro(compositionstart) \
+ macro(compositionupdate) \
macro(connect) \
macro(contextmenu) \
macro(copy) \
@@ -81,6 +84,7 @@ namespace WebCore {
macro(pagehide) \
macro(pageshow) \
macro(paste) \
+ macro(popstate) \
macro(readystatechange) \
macro(reset) \
macro(resize) \
@@ -135,6 +139,9 @@ namespace WebCore {
macro(volumechange) \
macro(waiting) \
\
+ macro(webkitbeginfullscreen) \
+ macro(webkitendfullscreen) \
+ \
macro(progress) \
macro(stalled) \
macro(suspend) \
@@ -149,7 +156,7 @@ namespace WebCore {
\
// end of DOM_EVENT_NAMES_FOR_EACH
- class EventNames {
+ class EventNames : public Noncopyable {
int dummy; // Needed to make initialization macro work.
// Private to prevent accidental call to EventNames() instead of eventNames()
EventNames();
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index 694e78a..65d751a 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -1,6 +1,4 @@
/*
- * 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)
@@ -68,6 +66,11 @@ bool eventDispatchForbidden()
}
#endif // NDEBUG
+EventTargetData::~EventTargetData()
+{
+ deleteAllValues(eventListenerMap);
+}
+
EventTarget::~EventTarget()
{
}
@@ -157,16 +160,19 @@ bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<Eve
{
EventTargetData* d = ensureEventTargetData();
- pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, EventListenerVector());
- EventListenerVector& entry = result.first->second;
+ pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, 0);
+ EventListenerVector*& entry = result.first->second;
+ const bool isNewEntry = result.second;
+ if (isNewEntry)
+ entry = new EventListenerVector();
RegisteredEventListener registeredListener(listener, useCapture);
- if (!result.second) { // pre-existing entry
- if (entry.find(registeredListener) != notFound) // duplicate listener
+ if (!isNewEntry) {
+ if (entry->find(registeredListener) != notFound) // duplicate listener
return false;
}
- entry.append(registeredListener);
+ entry->append(registeredListener);
return true;
}
@@ -179,16 +185,18 @@ bool EventTarget::removeEventListener(const AtomicString& eventType, EventListen
EventListenerMap::iterator result = d->eventListenerMap.find(eventType);
if (result == d->eventListenerMap.end())
return false;
- EventListenerVector& entry = result->second;
+ EventListenerVector* entry = result->second;
RegisteredEventListener registeredListener(listener, useCapture);
- size_t index = entry.find(registeredListener);
+ size_t index = entry->find(registeredListener);
if (index == notFound)
return false;
- entry.remove(index);
- if (!entry.size())
+ entry->remove(index);
+ if (entry->isEmpty()) {
+ delete entry;
d->eventListenerMap.remove(result);
+ }
// Notify firing events planning to invoke the listener at 'index' that
// they have one less listener to invoke.
@@ -266,7 +274,7 @@ bool EventTarget::fireEventListeners(Event* event)
EventListenerMap::iterator result = d->eventListenerMap.find(event->type());
if (result == d->eventListenerMap.end())
return false;
- EventListenerVector& entry = result->second;
+ EventListenerVector& entry = *result->second;
RefPtr<EventTarget> protect = this;
@@ -303,7 +311,7 @@ const EventListenerVector& EventTarget::getEventListeners(const AtomicString& ev
EventListenerMap::iterator it = d->eventListenerMap.find(eventType);
if (it == d->eventListenerMap.end())
return emptyVector;
- return it->second;
+ return *it->second;
}
void EventTarget::removeAllEventListeners()
@@ -311,6 +319,7 @@ void EventTarget::removeAllEventListeners()
EventTargetData* d = eventTargetData();
if (!d)
return;
+ deleteAllValues(d->eventListenerMap);
d->eventListenerMap.clear();
// Notify firing events planning to invoke the listener at 'index' that
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index 9a1975c..2d77c87 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -76,9 +76,11 @@ namespace WebCore {
typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
typedef Vector<RegisteredEventListener, 1> EventListenerVector;
- typedef HashMap<AtomicString, EventListenerVector> EventListenerMap;
+ typedef HashMap<AtomicString, EventListenerVector*> EventListenerMap;
+
+ struct EventTargetData : Noncopyable {
+ ~EventTargetData();
- struct EventTargetData {
EventListenerMap eventListenerMap;
FiringEventIteratorVector firingEventIterators;
};
@@ -190,7 +192,7 @@ namespace WebCore {
EventListenerMap::iterator end = d->eventListenerMap.end();
for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) {
- EventListenerVector& entry = it->second;
+ EventListenerVector& entry = *it->second;
for (size_t i = 0; i < entry.size(); ++i)
entry[i].listener->markJSFunction(markStack);
}
@@ -202,6 +204,7 @@ namespace WebCore {
if (!d)
return;
+ deleteAllValues(d->eventListenerMap);
d->eventListenerMap.clear();
}
#endif
diff --git a/WebCore/dom/InputElement.h b/WebCore/dom/InputElement.h
index e0e7110..2ae0312 100644
--- a/WebCore/dom/InputElement.h
+++ b/WebCore/dom/InputElement.h
@@ -48,7 +48,8 @@ public:
virtual int size() const = 0;
virtual String value() const = 0;
- virtual void setValue(const String&) = 0;
+ virtual void setValue(const String&, bool sendChangeEvent = false) = 0;
+ virtual void setValueForUser(const String&) = 0;
virtual String sanitizeValue(const String&) const = 0;
virtual void setValueFromRenderer(const String&) = 0;
diff --git a/WebCore/dom/KeyboardEvent.cpp b/WebCore/dom/KeyboardEvent.cpp
index 6bc825f..99c9220 100644
--- a/WebCore/dom/KeyboardEvent.cpp
+++ b/WebCore/dom/KeyboardEvent.cpp
@@ -80,7 +80,6 @@ KeyboardEvent::KeyboardEvent(const AtomicString& eventType, bool canBubble, bool
KeyboardEvent::~KeyboardEvent()
{
- delete m_keyEvent;
}
void KeyboardEvent::initKeyboardEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view,
diff --git a/WebCore/dom/KeyboardEvent.h b/WebCore/dom/KeyboardEvent.h
index 2b0a131..793ac41 100644
--- a/WebCore/dom/KeyboardEvent.h
+++ b/WebCore/dom/KeyboardEvent.h
@@ -79,7 +79,7 @@ namespace WebCore {
bool altGraphKey() const { return m_altGraphKey; }
- const PlatformKeyboardEvent* keyEvent() const { return m_keyEvent; }
+ const PlatformKeyboardEvent* keyEvent() const { return m_keyEvent.get(); }
int keyCode() const; // key code for keydown and keyup, character for keypress
int charCode() const; // character code for keypress, 0 for keydown and keyup
@@ -99,7 +99,7 @@ namespace WebCore {
const String& keyIdentifier, unsigned keyLocation,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey);
- PlatformKeyboardEvent* m_keyEvent;
+ OwnPtr<PlatformKeyboardEvent> m_keyEvent;
String m_keyIdentifier;
unsigned m_keyLocation;
bool m_altGraphKey : 1;
diff --git a/WebCore/dom/MappedAttributeEntry.h b/WebCore/dom/MappedAttributeEntry.h
index 745ad23..842e7a8 100644
--- a/WebCore/dom/MappedAttributeEntry.h
+++ b/WebCore/dom/MappedAttributeEntry.h
@@ -1,6 +1,4 @@
/*
- * 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)
diff --git a/WebCore/dom/MessagePort.cpp b/WebCore/dom/MessagePort.cpp
index 9f6e649..1051920 100644
--- a/WebCore/dom/MessagePort.cpp
+++ b/WebCore/dom/MessagePort.cpp
@@ -41,6 +41,7 @@ namespace WebCore {
MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext)
: m_entangledChannel(0)
, m_started(false)
+ , m_closed(false)
, m_scriptExecutionContext(&scriptExecutionContext)
{
m_scriptExecutionContext->createdMessagePort(this);
@@ -131,6 +132,7 @@ void MessagePort::start()
void MessagePort::close()
{
+ m_closed = true;
if (!m_entangledChannel)
return;
m_entangledChannel->close();
@@ -200,7 +202,7 @@ PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessageP
// Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
for (unsigned int i = 0; i < ports->size(); ++i) {
MessagePort* port = (*ports)[i].get();
- if (!port || !port->isEntangled() || portSet.contains(port)) {
+ if (!port || port->isCloned() || portSet.contains(port)) {
ec = INVALID_STATE_ERR;
return 0;
}
diff --git a/WebCore/dom/MessagePort.h b/WebCore/dom/MessagePort.h
index 0ab0f50..ae1eb22 100644
--- a/WebCore/dom/MessagePort.h
+++ b/WebCore/dom/MessagePort.h
@@ -103,7 +103,10 @@ namespace WebCore {
// 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; }
+ // A port starts out its life entangled, and remains entangled until it is closed or is cloned.
+ bool isEntangled() { return !m_closed && !isCloned(); }
+ // A port is cloned if its entangled channel has been removed and sent to a new owner via postMessage().
+ bool isCloned() { return !m_entangledChannel; }
private:
MessagePort(ScriptExecutionContext&);
@@ -116,6 +119,7 @@ namespace WebCore {
OwnPtr<MessagePortChannel> m_entangledChannel;
bool m_started;
+ bool m_closed;
ScriptExecutionContext* m_scriptExecutionContext;
EventTargetData m_eventTargetData;
diff --git a/WebCore/dom/MessagePortChannel.h b/WebCore/dom/MessagePortChannel.h
index 2321b1f..90cb0d9 100644
--- a/WebCore/dom/MessagePortChannel.h
+++ b/WebCore/dom/MessagePortChannel.h
@@ -78,7 +78,7 @@ namespace WebCore {
// Returns true if the proxy currently contains messages for this port.
bool hasPendingActivity();
- class EventData {
+ class EventData : public Noncopyable {
public:
static PassOwnPtr<EventData> create(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>);
diff --git a/WebCore/dom/MouseRelatedEvent.h b/WebCore/dom/MouseRelatedEvent.h
index 7649aa9..fc494d1 100644
--- a/WebCore/dom/MouseRelatedEvent.h
+++ b/WebCore/dom/MouseRelatedEvent.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
diff --git a/WebCore/dom/NamedAttrMap.cpp b/WebCore/dom/NamedAttrMap.cpp
index d4ec598..56b40b9 100644
--- a/WebCore/dom/NamedAttrMap.cpp
+++ b/WebCore/dom/NamedAttrMap.cpp
@@ -177,11 +177,33 @@ PassRefPtr<Node> NamedNodeMap::item(unsigned index) const
Attribute* NamedNodeMap::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
{
unsigned len = length();
+ bool doSlowCheck = shouldIgnoreAttributeCase;
+
+ // Optimize for the case where the attribute exists and its name exactly matches.
for (unsigned i = 0; i < len; ++i) {
- if (!m_attributes[i]->name().hasPrefix() && m_attributes[i]->name().localName() == name)
- return m_attributes[i].get();
- if (shouldIgnoreAttributeCase ? equalIgnoringCase(m_attributes[i]->name().toString(), name) : name == m_attributes[i]->name().toString())
- return m_attributes[i].get();
+ const QualifiedName& attrName = m_attributes[i]->name();
+ if (!attrName.hasPrefix()) {
+ if (name == attrName.localName())
+ return m_attributes[i].get();
+ } else
+ doSlowCheck = true;
+ }
+
+ // Continue to checking case-insensitively and/or full namespaced names if necessary:
+ if (doSlowCheck) {
+ for (unsigned i = 0; i < len; ++i) {
+ const QualifiedName& attrName = m_attributes[i]->name();
+ if (!attrName.hasPrefix()) {
+ if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attrName.localName()))
+ return m_attributes[i].get();
+ } else {
+ // FIXME: Would be faster to do this comparison without calling toString, which
+ // generates a temporary string by concatenation. But this branch is only reached
+ // if the attribute name has a prefix, which is rare in HTML.
+ if (equalPossiblyIgnoringCase(name, attrName.toString(), shouldIgnoreAttributeCase))
+ return m_attributes[i].get();
+ }
+ }
}
return 0;
}
diff --git a/WebCore/dom/NamedMappedAttrMap.h b/WebCore/dom/NamedMappedAttrMap.h
index 0afa278..a288685 100644
--- a/WebCore/dom/NamedMappedAttrMap.h
+++ b/WebCore/dom/NamedMappedAttrMap.h
@@ -26,8 +26,8 @@
#ifndef NamedMappedAttrMap_h
#define NamedMappedAttrMap_h
-#include "ClassNames.h"
#include "NamedNodeMap.h"
+#include "SpaceSplitString.h"
namespace WebCore {
@@ -37,7 +37,7 @@ public:
void clearClass() { m_classNames.clear(); }
void setClass(const String&);
- const ClassNames& classNames() const { return m_classNames; }
+ const SpaceSplitString& classNames() const { return m_classNames; }
bool hasMappedAttributes() const { return m_mappedAttributeCount > 0; }
void declRemoved() { m_mappedAttributeCount--; }
@@ -53,7 +53,7 @@ private:
int declCount() const;
- ClassNames m_classNames;
+ SpaceSplitString m_classNames;
int m_mappedAttributeCount;
};
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 446efda..4ae83de 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -415,7 +415,6 @@ Node::Node(Document* document, ConstructionType type)
, m_hovered(false)
, m_inActiveChain(false)
, m_inDetach(false)
- , m_inSubtreeMark(false)
, m_hasRareData(false)
, m_isElement(isElement(type))
, m_isContainer(isContainer(type))
@@ -1768,23 +1767,22 @@ bool Node::isEqualNode(Node *other) const
return true;
}
-bool Node::isDefaultNamespace(const AtomicString &namespaceURI) const
+bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
{
- // Implemented according to
- // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#isDefaultNamespaceAlgo
-
+ const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAtom : namespaceURIMaybeEmpty;
+
switch (nodeType()) {
case ELEMENT_NODE: {
- const Element *elem = static_cast<const Element *>(this);
+ const Element* elem = static_cast<const Element*>(this);
if (elem->prefix().isNull())
return elem->namespaceURI() == namespaceURI;
if (elem->hasAttributes()) {
- NamedNodeMap *attrs = elem->attributes();
+ NamedNodeMap* attrs = elem->attributes();
for (unsigned i = 0; i < attrs->length(); i++) {
- Attribute *attr = attrs->attributeItem(i);
+ Attribute* attr = attrs->attributeItem(i);
if (attr->localName() == "xmlns")
return attr->value() == namespaceURI;
@@ -1806,7 +1804,7 @@ bool Node::isDefaultNamespace(const AtomicString &namespaceURI) const
case DOCUMENT_FRAGMENT_NODE:
return false;
case ATTRIBUTE_NODE: {
- const Attr *attr = static_cast<const Attr *>(this);
+ const Attr* attr = static_cast<const Attr*>(this);
if (attr->ownerElement())
return attr->ownerElement()->isDefaultNamespace(namespaceURI);
return false;
@@ -2539,6 +2537,23 @@ bool Node::dispatchEvent(PassRefPtr<Event> prpEvent)
return dispatchGenericEvent(event.release());
}
+static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, Vector<RefPtr<ContainerNode> >& ancestors)
+{
+ if (window && window->hasEventListeners(eventType))
+ return true;
+
+ if (node->hasEventListeners(eventType))
+ return true;
+
+ for (size_t i = 0; i < ancestors.size(); i++) {
+ ContainerNode* ancestor = ancestors[i].get();
+ if (ancestor->hasEventListeners(eventType))
+ return true;
+ }
+
+ return false;
+}
+
bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
{
RefPtr<Event> event(prpEvent);
@@ -2547,12 +2562,6 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
ASSERT(event->target());
ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
-#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = document()->inspectorTimelineAgent();
- if (timelineAgent)
- timelineAgent->willDispatchDOMEvent(*event);
-#endif
-
// Make a vector of ancestors to send the event to.
// If the node is not in a document just send the event to it.
// Be sure to ref all of nodes since event handlers could result in the last reference going away.
@@ -2570,6 +2579,13 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
targetForWindowEvents = static_cast<Document*>(topLevelContainer)->domWindow();
}
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* timelineAgent = document()->inspectorTimelineAgent();
+ bool timelineAgentIsActive = timelineAgent && eventHasListeners(event->type(), targetForWindowEvents, this, ancestors);
+ if (timelineAgentIsActive)
+ timelineAgent->willDispatchEvent(*event);
+#endif
+
// 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())
@@ -2651,8 +2667,8 @@ doneDispatching:
doneWithDefault:
#if ENABLE(INSPECTOR)
- if (timelineAgent)
- timelineAgent->didDispatchDOMEvent();
+ if (timelineAgentIsActive && (timelineAgent = document()->inspectorTimelineAgent()))
+ timelineAgent->didDispatchEvent();
#endif
Document::updateStyleForAllDocuments();
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index 082ab16..7da8634 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -289,9 +289,6 @@ public:
void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
void setIsLink(bool b = true) { m_isLink = b; }
- bool inSubtreeMark() const { return m_inSubtreeMark; }
- void setInSubtreeMark(bool b = true) { m_inSubtreeMark = b; }
-
void lazyAttach();
virtual bool canLazyAttach();
@@ -642,7 +639,6 @@ private:
bool m_hovered : 1;
bool m_inActiveChain : 1;
bool m_inDetach : 1;
- bool m_inSubtreeMark : 1;
bool m_hasRareData : 1;
const bool m_isElement : 1;
const bool m_isContainer : 1;
diff --git a/WebCore/dom/NodeFilter.h b/WebCore/dom/NodeFilter.h
index 5a542ad..53b32e1 100644
--- a/WebCore/dom/NodeFilter.h
+++ b/WebCore/dom/NodeFilter.h
@@ -73,8 +73,9 @@ namespace WebCore {
short acceptNode(ScriptState*, Node*) const;
void markAggregate(JSC::MarkStack& markStack) { m_condition->markAggregate(markStack); };
- // For non-JS bindings. Silently ignores the JavaScript exception if any.
- short acceptNode(Node* node) const { return acceptNode(scriptStateFromNode(node), node); }
+ // Do not call these functions. They are just scaffolding to support the Objective-C bindings.
+ // They operate in the main thread normal world, and they swallow JS exceptions.
+ short acceptNode(Node* node) const { return acceptNode(scriptStateFromNode(mainThreadNormalWorld(), node), node); }
private:
NodeFilter(PassRefPtr<NodeFilterCondition> condition) : m_condition(condition) { }
diff --git a/WebCore/dom/NodeIterator.h b/WebCore/dom/NodeIterator.h
index 2a992d3..3eec49a 100644
--- a/WebCore/dom/NodeIterator.h
+++ b/WebCore/dom/NodeIterator.h
@@ -52,9 +52,10 @@ namespace WebCore {
// This function is called before any node is removed from the document tree.
void nodeWillBeRemoved(Node*);
- // For non-JS bindings. Silently ignores the JavaScript exception if any.
- PassRefPtr<Node> nextNode(ExceptionCode& ec) { return nextNode(scriptStateFromNode(referenceNode()), ec); }
- PassRefPtr<Node> previousNode(ExceptionCode& ec) { return previousNode(scriptStateFromNode(referenceNode()), ec); }
+ // Do not call these functions. They are just scaffolding to support the Objective-C bindings.
+ // They operate in the main thread normal world, and they swallow JS exceptions.
+ PassRefPtr<Node> nextNode(ExceptionCode& ec) { return nextNode(scriptStateFromNode(mainThreadNormalWorld(), referenceNode()), ec); }
+ PassRefPtr<Node> previousNode(ExceptionCode& ec) { return previousNode(scriptStateFromNode(mainThreadNormalWorld(), referenceNode()), ec); }
private:
NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
diff --git a/WebCore/dom/NodeRareData.h b/WebCore/dom/NodeRareData.h
index 8b9e1bf..6e9d0e4 100644
--- a/WebCore/dom/NodeRareData.h
+++ b/WebCore/dom/NodeRareData.h
@@ -33,7 +33,7 @@
namespace WebCore {
-struct NodeListsNodeData {
+struct NodeListsNodeData : Noncopyable {
typedef HashSet<DynamicNodeList*> NodeListSet;
NodeListSet m_listsWithCaches;
@@ -62,7 +62,7 @@ private:
}
};
-class NodeRareData {
+class NodeRareData : public Noncopyable {
public:
NodeRareData()
: m_tabIndex(0)
diff --git a/WebCore/dom/PopStateEvent.cpp b/WebCore/dom/PopStateEvent.cpp
new file mode 100644
index 0000000..b9ad862
--- /dev/null
+++ b/WebCore/dom/PopStateEvent.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "PopStateEvent.h"
+
+#include "EventNames.h"
+
+namespace WebCore {
+
+PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> stateObject)
+ : Event(eventNames().popstateEvent, false, true)
+ , m_stateObject(stateObject)
+{
+}
+
+void PopStateEvent::initPopStateEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> stateObject)
+{
+ if (dispatched())
+ return;
+
+ initEvent(type, canBubble, cancelable);
+
+ m_stateObject = stateObject;
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/PopStateEvent.h b/WebCore/dom/PopStateEvent.h
new file mode 100644
index 0000000..2fb8d06
--- /dev/null
+++ b/WebCore/dom/PopStateEvent.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef PopStateEvent_h
+#define PopStateEvent_h
+
+#include "Event.h"
+#include "SerializedScriptValue.h"
+
+namespace WebCore {
+
+class SerializedScriptValue;
+
+class PopStateEvent : public Event {
+public:
+ static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue> stateObject)
+ {
+ return adoptRef(new PopStateEvent(stateObject));
+ }
+
+ void initPopStateEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue>);
+ bool isPopStateEvent() const { return true; }
+
+ SerializedScriptValue* state() const { return m_stateObject.get(); }
+
+private:
+ PopStateEvent(PassRefPtr<SerializedScriptValue>);
+
+ RefPtr<SerializedScriptValue> m_stateObject;
+};
+
+} // namespace WebCore
+
+#endif // PopStateEvent_h
diff --git a/WebCore/dom/PopStateEvent.idl b/WebCore/dom/PopStateEvent.idl
new file mode 100644
index 0000000..c6775ec
--- /dev/null
+++ b/WebCore/dom/PopStateEvent.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+module events {
+
+ interface [
+ GenerateConstructor
+ ] PopStateEvent : Event {
+ [Custom] void initPopStateEvent(in DOMString typeArg,
+ in boolean canBubbleArg,
+ in boolean cancelableArg,
+ in any stateArg);
+
+ readonly attribute [CustomGetter] any state;
+ };
+
+}
diff --git a/WebCore/dom/Position.cpp b/WebCore/dom/Position.cpp
index 060b28c..0ff8262 100644
--- a/WebCore/dom/Position.cpp
+++ b/WebCore/dom/Position.cpp
@@ -307,6 +307,27 @@ bool Position::atLastEditingPositionForNode() const
return m_offset >= lastOffsetForEditing(node());
}
+// A position is considered at editing boundary if one of the following is true:
+// 1. It is the first position in the node and the next visually equivalent position
+// is non editable.
+// 2. It is the last position in the node and the previous visually equivalent position
+// is non editable.
+// 3. It is an editable position and both the next and previous visually equivalent
+// positions are both non editable.
+bool Position::atEditingBoundary() const
+{
+ Position nextPosition = downstream(CanCrossEditingBoundary);
+ if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosition.node()->isContentEditable())
+ return true;
+
+ Position prevPosition = upstream(CanCrossEditingBoundary);
+ if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.node()->isContentEditable())
+ return true;
+
+ return nextPosition.isNotNull() && !nextPosition.node()->isContentEditable()
+ && prevPosition.isNotNull() && !prevPosition.node()->isContentEditable();
+}
+
bool Position::atStartOfTree() const
{
if (isNull())
@@ -448,7 +469,7 @@ static bool isStreamer(const PositionIterator& pos)
// and downstream() will return the right one.
// Also, upstream() will return [boundary, 0] for any of the positions from [boundary, 0] to the first candidate
// in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true.
-Position Position::upstream() const
+Position Position::upstream(EditingBoundaryCrossingRule rule) const
{
Node* startNode = node();
if (!startNode)
@@ -460,6 +481,7 @@ Position Position::upstream() const
PositionIterator currentPos = lastVisible;
bool startEditable = startNode->isContentEditable();
Node* lastNode = startNode;
+ bool boundaryCrossed = false;
for (; !currentPos.atStart(); currentPos.decrement()) {
Node* currentNode = currentPos.node();
@@ -468,8 +490,11 @@ Position Position::upstream() const
if (currentNode != lastNode) {
// Don't change editability.
bool currentEditable = currentNode->isContentEditable();
- if (startEditable != currentEditable)
- break;
+ if (startEditable != currentEditable) {
+ if (rule == CannotCrossEditingBoundary)
+ break;
+ boundaryCrossed = true;
+ }
lastNode = currentNode;
}
@@ -483,6 +508,11 @@ Position Position::upstream() const
if (!renderer || renderer->style()->visibility() != VISIBLE)
continue;
+ if (rule == CanCrossEditingBoundary && boundaryCrossed) {
+ lastVisible = currentPos;
+ break;
+ }
+
// track last visible streamer position
if (isStreamer(currentPos))
lastVisible = currentPos;
@@ -560,7 +590,7 @@ Position Position::upstream() const
// and upstream() will return the left one.
// Also, downstream() will return the last position in the last atomic node in boundary for all of the positions
// in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPositions(boundary).
-Position Position::downstream() const
+Position Position::downstream(EditingBoundaryCrossingRule rule) const
{
Node* startNode = node();
if (!startNode)
@@ -572,6 +602,7 @@ Position Position::downstream() const
PositionIterator currentPos = lastVisible;
bool startEditable = startNode->isContentEditable();
Node* lastNode = startNode;
+ bool boundaryCrossed = false;
for (; !currentPos.atEnd(); currentPos.increment()) {
Node* currentNode = currentPos.node();
@@ -580,8 +611,12 @@ Position Position::downstream() const
if (currentNode != lastNode) {
// Don't change editability.
bool currentEditable = currentNode->isContentEditable();
- if (startEditable != currentEditable)
- break;
+ if (startEditable != currentEditable) {
+ if (rule == CannotCrossEditingBoundary)
+ break;
+ boundaryCrossed = true;
+ }
+
lastNode = currentNode;
}
@@ -604,6 +639,11 @@ Position Position::downstream() const
if (!renderer || renderer->style()->visibility() != VISIBLE)
continue;
+ if (rule == CanCrossEditingBoundary && boundaryCrossed) {
+ lastVisible = currentPos;
+ break;
+ }
+
// track last visible streamer position
if (isStreamer(currentPos))
lastVisible = currentPos;
@@ -704,10 +744,14 @@ bool Position::isCandidate() const
if (isTableElement(node()) || editingIgnoresContent(node()))
return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(node()->parent());
- if (!node()->hasTagName(htmlTag) && renderer->isBlockFlow() && !hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
- (toRenderBox(renderer)->height() || node()->hasTagName(bodyTag)))
- return atFirstEditingPositionForNode() && !nodeIsUserSelectNone(node());
-
+ if (!m_anchorNode->hasTagName(htmlTag) && renderer->isBlockFlow()) {
+ if (toRenderBlock(renderer)->height() || m_anchorNode->hasTagName(bodyTag)) {
+ if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
+ return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(node());
+ return m_anchorNode->isContentEditable() && !Position::nodeIsUserSelectNone(node()) && atEditingBoundary();
+ }
+ }
+
return false;
}
@@ -949,7 +993,22 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi
{
caretOffset = m_offset;
RenderObject* renderer = node()->renderer();
+
if (!renderer->isText()) {
+ if (renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
+ bool lastPosition = caretOffset == lastOffsetInNode(node());
+ Node* startNode = lastPosition ? node()->childNode(caretOffset - 1) : node()->childNode(caretOffset);
+ while (startNode && (!startNode->renderer() || (startNode->isTextNode() && toRenderText(startNode->renderer())->isAllCollapsibleWhitespace())))
+ startNode = (lastPosition)? startNode->previousSibling(): startNode->nextSibling();
+ if (startNode) {
+ Position pos(startNode, 0);
+ pos = pos.downstream(CanCrossEditingBoundary);
+ pos.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
+ if (lastPosition && inlineBox)
+ caretOffset = inlineBox->caretMaxOffset();
+ return;
+ }
+ }
inlineBox = renderer->isBox() ? toRenderBox(renderer)->inlineBoxWrapper() : 0;
if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
return;
diff --git a/WebCore/dom/Position.h b/WebCore/dom/Position.h
index c08872d..1e0304e 100644
--- a/WebCore/dom/Position.h
+++ b/WebCore/dom/Position.h
@@ -56,6 +56,11 @@ public:
PositionIsBeforeAnchor
};
+ enum EditingBoundaryCrossingRule {
+ CanCrossEditingBoundary,
+ CannotCrossEditingBoundary
+ };
+
Position()
: m_offset(0)
, m_anchorType(PositionIsOffsetInAnchor)
@@ -130,6 +135,9 @@ public:
bool atFirstEditingPositionForNode() const;
bool atLastEditingPositionForNode() const;
+ // Retuns true if the visually equivalent positions around have different editability
+ bool atEditingBoundary() const;
+
bool atStartOfTree() const;
bool atEndOfTree() const;
@@ -139,8 +147,8 @@ public:
Position trailingWhitespacePosition(EAffinity, bool considerNonCollapsibleWhitespace = false) const;
// These return useful visually equivalent positions.
- Position upstream() const;
- Position downstream() const;
+ Position upstream(EditingBoundaryCrossingRule = CannotCrossEditingBoundary) const;
+ Position downstream(EditingBoundaryCrossingRule = CannotCrossEditingBoundary) const;
bool isCandidate() const;
bool inRenderedText() const;
diff --git a/WebCore/dom/PositionIterator.cpp b/WebCore/dom/PositionIterator.cpp
index 8d881ba..f5b65f5 100644
--- a/WebCore/dom/PositionIterator.cpp
+++ b/WebCore/dom/PositionIterator.cpp
@@ -156,10 +156,14 @@ bool PositionIterator::isCandidate() const
if (isTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parent());
- if (!m_anchorNode->hasTagName(htmlTag) && renderer->isBlockFlow() && !Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
- (toRenderBlock(renderer)->height() || m_anchorNode->hasTagName(bodyTag)))
- return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
-
+ if (!m_anchorNode->hasTagName(htmlTag) && renderer->isBlockFlow()) {
+ if (toRenderBlock(renderer)->height() || m_anchorNode->hasTagName(bodyTag)) {
+ if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
+ return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
+ return m_anchorNode->isContentEditable() && !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).atEditingBoundary();
+ }
+ }
+
return false;
}
diff --git a/WebCore/dom/ProcessingInstruction.cpp b/WebCore/dom/ProcessingInstruction.cpp
index 8a94864..8adf9aa 100644
--- a/WebCore/dom/ProcessingInstruction.cpp
+++ b/WebCore/dom/ProcessingInstruction.cpp
@@ -42,6 +42,7 @@ inline ProcessingInstruction::ProcessingInstruction(Document* document, const St
, m_cachedSheet(0)
, m_loading(false)
, m_alternate(false)
+ , m_createdByParser(false)
#if ENABLE(XSLT)
, m_isXSL(false)
#endif
diff --git a/WebCore/dom/QualifiedName.cpp b/WebCore/dom/QualifiedName.cpp
index 2c5f39a..795bdb6 100644
--- a/WebCore/dom/QualifiedName.cpp
+++ b/WebCore/dom/QualifiedName.cpp
@@ -51,7 +51,7 @@ struct QNameComponentsTranslator {
static QNameSet* gNameCache;
-QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
+void QualifiedName::init(const AtomicString& p, const AtomicString& l, const AtomicString& n)
{
if (!gNameCache)
gNameCache = new QNameSet;
@@ -62,6 +62,16 @@ QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const
m_impl->ref();
}
+QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
+{
+ init(p, l, n);
+}
+
+QualifiedName::QualifiedName(const AtomicString& p, const char* l, const AtomicString& n)
+{
+ init(p, AtomicString(l), n);
+}
+
void QualifiedName::deref()
{
#ifdef QNAME_DEFAULT_CONSTRUCTOR
diff --git a/WebCore/dom/QualifiedName.h b/WebCore/dom/QualifiedName.h
index 3b9f5c4..a7e1fcb 100644
--- a/WebCore/dom/QualifiedName.h
+++ b/WebCore/dom/QualifiedName.h
@@ -32,7 +32,7 @@ struct QualifiedNameComponents {
StringImpl* m_namespace;
};
-class QualifiedName {
+class QualifiedName : public FastAllocBase {
public:
class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
public:
@@ -57,6 +57,7 @@ public:
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
+ QualifiedName(const AtomicString& prefix, const char* localName, const AtomicString& namespaceURI);
~QualifiedName() { deref(); }
#ifdef QNAME_DEFAULT_CONSTRUCTOR
QualifiedName() : m_impl(0) { }
@@ -88,6 +89,7 @@ public:
static void init();
private:
+ void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
void ref() const { m_impl->ref(); }
void deref();
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index 122130d..84a46c2 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -1595,12 +1595,32 @@ IntRect Range::boundingBox()
void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight)
{
- if (!m_start.container() || !m_end.container())
+ Node* startContainer = m_start.container();
+ Node* endContainer = m_end.container();
+
+ if (!startContainer || !endContainer)
return;
+ 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() : numeric_limits<int>::max();
+ renderText->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight);
+ }
+}
+
+void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight)
+{
Node* startContainer = m_start.container();
Node* endContainer = m_end.container();
+ if (!startContainer || !endContainer)
+ return;
+
Node* stopNode = pastLastNode();
for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
RenderObject* r = node->renderer();
@@ -1608,8 +1628,8 @@ void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight)
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);
+ int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
+ renderText->absoluteQuadsForRange(quads, startOffset, endOffset, useSelectionHeight);
}
}
diff --git a/WebCore/dom/Range.h b/WebCore/dom/Range.h
index e2e282b..583f9f0 100644
--- a/WebCore/dom/Range.h
+++ b/WebCore/dom/Range.h
@@ -105,7 +105,10 @@ public:
Node* shadowTreeRootNode() const;
IntRect boundingBox();
+ // Not transform-friendly
void textRects(Vector<IntRect>&, bool useSelectionHeight = false);
+ // Transform-friendly
+ void textQuads(Vector<FloatQuad>&, bool useSelectionHeight = false);
void nodeChildrenChanged(ContainerNode*);
void nodeWillBeRemoved(Node*);
diff --git a/WebCore/dom/RangeException.h b/WebCore/dom/RangeException.h
index 2eee3b0..c9f4f5c 100644
--- a/WebCore/dom/RangeException.h
+++ b/WebCore/dom/RangeException.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
* (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
diff --git a/WebCore/dom/ScriptElement.cpp b/WebCore/dom/ScriptElement.cpp
index 827aff3..83ed2bb 100644
--- a/WebCore/dom/ScriptElement.cpp
+++ b/WebCore/dom/ScriptElement.cpp
@@ -229,12 +229,14 @@ bool ScriptElementData::shouldExecuteAsJavaScript() const
We want to accept all the values that either of these browsers accept, but not other values.
*/
String type = m_scriptElement->typeAttributeValue();
- if (!type.isEmpty())
- return MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower());
-
- String language = m_scriptElement->languageAttributeValue();
- if (!language.isEmpty())
- return isSupportedJavaScriptLanguage(language);
+ if (!type.isEmpty()) {
+ if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()))
+ return false;
+ } else {
+ String language = m_scriptElement->languageAttributeValue();
+ if (!language.isEmpty() && !isSupportedJavaScriptLanguage(language))
+ return false;
+ }
// 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.
diff --git a/WebCore/dom/ScriptExecutionContext.cpp b/WebCore/dom/ScriptExecutionContext.cpp
index f7046e3..bc71084 100644
--- a/WebCore/dom/ScriptExecutionContext.cpp
+++ b/WebCore/dom/ScriptExecutionContext.cpp
@@ -44,9 +44,9 @@ namespace WebCore {
class ProcessMessagesSoonTask : public ScriptExecutionContext::Task {
public:
- static PassRefPtr<ProcessMessagesSoonTask> create()
+ static PassOwnPtr<ProcessMessagesSoonTask> create()
{
- return adoptRef(new ProcessMessagesSoonTask);
+ return new ProcessMessagesSoonTask;
}
virtual void performTask(ScriptExecutionContext* context)
diff --git a/WebCore/dom/ScriptExecutionContext.h b/WebCore/dom/ScriptExecutionContext.h
index 398afec..cf332c3 100644
--- a/WebCore/dom/ScriptExecutionContext.h
+++ b/WebCore/dom/ScriptExecutionContext.h
@@ -31,6 +31,7 @@
#include "KURL.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Threading.h>
@@ -92,13 +93,13 @@ namespace WebCore {
void ref() { refScriptExecutionContext(); }
void deref() { derefScriptExecutionContext(); }
- class Task : public ThreadSafeShared<Task> {
+ class Task : public Noncopyable {
public:
virtual ~Task();
virtual void performTask(ScriptExecutionContext*) = 0;
};
- virtual void postTask(PassRefPtr<Task>) = 0; // Executes the task on context's thread asynchronously.
+ virtual void postTask(PassOwnPtr<Task>) = 0; // Executes the task on context's thread asynchronously.
void addTimeout(int timeoutId, DOMTimer*);
void removeTimeout(int timeoutId);
diff --git a/WebCore/dom/ClassNames.cpp b/WebCore/dom/SpaceSplitString.cpp
index 1c5ff47..b062dbf 100644
--- a/WebCore/dom/ClassNames.cpp
+++ b/WebCore/dom/SpaceSplitString.cpp
@@ -19,7 +19,7 @@
*/
#include "config.h"
-#include "ClassNames.h"
+#include "SpaceSplitString.h"
#include <wtf/ASCIICType.h>
@@ -41,7 +41,7 @@ static bool hasNonASCIIOrUpper(const String& string)
return hasUpper || (ored & ~0x7F);
}
-void ClassNamesData::createVector()
+void SpaceSplitStringData::createVector()
{
ASSERT(!m_createdVector);
ASSERT(m_vector.isEmpty());
@@ -70,7 +70,7 @@ void ClassNamesData::createVector()
m_createdVector = true;
}
-bool ClassNamesData::containsAll(ClassNamesData& other)
+bool SpaceSplitStringData::containsAll(SpaceSplitStringData& other)
{
ensureVector();
other.ensureVector();
diff --git a/WebCore/dom/ClassNames.h b/WebCore/dom/SpaceSplitString.h
index a836606..2ef3fc4 100644
--- a/WebCore/dom/ClassNames.h
+++ b/WebCore/dom/SpaceSplitString.h
@@ -18,8 +18,8 @@
*
*/
-#ifndef ClassNames_h
-#define ClassNames_h
+#ifndef SpaceSplitString_h
+#define SpaceSplitString_h
#include "AtomicString.h"
#include <wtf/OwnPtr.h>
@@ -27,9 +27,9 @@
namespace WebCore {
- class ClassNamesData : public Noncopyable {
+ class SpaceSplitStringData : public Noncopyable {
public:
- ClassNamesData(const String& string, bool shouldFoldCase)
+ SpaceSplitStringData(const String& string, bool shouldFoldCase)
: m_string(string), m_shouldFoldCase(shouldFoldCase), m_createdVector(false)
{
}
@@ -45,7 +45,7 @@ namespace WebCore {
return false;
}
- bool containsAll(ClassNamesData&);
+ bool containsAll(SpaceSplitStringData&);
size_t size() { ensureVector(); return m_vector.size(); }
const AtomicString& operator[](size_t i) { ensureVector(); ASSERT(i < size()); return m_vector[i]; }
@@ -54,29 +54,29 @@ namespace WebCore {
void ensureVector() { if (!m_createdVector) createVector(); }
void createVector();
- typedef Vector<AtomicString, 8> ClassNameVector;
+ typedef Vector<AtomicString, 8> StringVector;
String m_string;
- ClassNameVector m_vector;
+ StringVector m_vector;
bool m_shouldFoldCase;
bool m_createdVector;
};
- class ClassNames {
+ class SpaceSplitString {
public:
- ClassNames() { }
- ClassNames(const String& string, bool shouldFoldCase) : m_data(new ClassNamesData(string, shouldFoldCase)) { }
+ SpaceSplitString() { }
+ SpaceSplitString(const String& string, bool shouldFoldCase) : m_data(new SpaceSplitStringData(string, shouldFoldCase)) { }
- void set(const String& string, bool shouldFoldCase) { m_data.set(new ClassNamesData(string, shouldFoldCase)); }
+ void set(const String& string, bool shouldFoldCase) { m_data.set(new SpaceSplitStringData(string, shouldFoldCase)); }
void clear() { m_data.clear(); }
bool contains(const AtomicString& string) const { return m_data && m_data->contains(string); }
- bool containsAll(const ClassNames& names) const { return !names.m_data || (m_data && m_data->containsAll(*names.m_data)); }
+ bool containsAll(const SpaceSplitString& names) const { return !names.m_data || (m_data && m_data->containsAll(*names.m_data)); }
size_t size() const { return m_data ? m_data->size() : 0; }
const AtomicString& operator[](size_t i) const { ASSERT(i < size()); return (*m_data)[i]; }
private:
- OwnPtr<ClassNamesData> m_data;
+ OwnPtr<SpaceSplitStringData> m_data;
};
inline bool isClassWhitespace(UChar c)
@@ -86,4 +86,4 @@ namespace WebCore {
} // namespace WebCore
-#endif // ClassNames_h
+#endif // SpaceSplitString_h
diff --git a/WebCore/dom/StyleElement.h b/WebCore/dom/StyleElement.h
index 7f83909..9d3ac84 100644
--- a/WebCore/dom/StyleElement.h
+++ b/WebCore/dom/StyleElement.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2006, 2007 Rob Buis
*
* This library is free software; you can redistribute it and/or
diff --git a/WebCore/dom/StyledElement.h b/WebCore/dom/StyledElement.h
index 85fa7a7..52bffd3 100644
--- a/WebCore/dom/StyledElement.h
+++ b/WebCore/dom/StyledElement.h
@@ -66,7 +66,7 @@ public:
CSSStyleDeclaration* style();
void invalidateStyleAttribute();
- const ClassNames& classNames() const { ASSERT(hasClass()); ASSERT(mappedAttributes()); return mappedAttributes()->classNames(); }
+ const SpaceSplitString& classNames() const { ASSERT(hasClass()); ASSERT(mappedAttributes()); return mappedAttributes()->classNames(); }
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
diff --git a/WebCore/dom/Tokenizer.h b/WebCore/dom/Tokenizer.h
index ea303f9..9a9b7b3 100644
--- a/WebCore/dom/Tokenizer.h
+++ b/WebCore/dom/Tokenizer.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 2000 Peter Kelly (pmk@post.com)
* Copyright (C) 2005, 2006 Apple Computer, Inc.
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
@@ -30,7 +28,7 @@ namespace WebCore {
class SegmentedString;
class XSSAuditor;
- class Tokenizer {
+ class Tokenizer : public Noncopyable {
public:
virtual ~Tokenizer() { }
diff --git a/WebCore/dom/TreeWalker.h b/WebCore/dom/TreeWalker.h
index 4cc8e9a..88e59da 100644
--- a/WebCore/dom/TreeWalker.h
+++ b/WebCore/dom/TreeWalker.h
@@ -52,14 +52,15 @@ namespace WebCore {
Node* previousNode(ScriptState*);
Node* nextNode(ScriptState*);
- // For non-JS bindings. Silently ignores the JavaScript exception if any.
- Node* parentNode() { return parentNode(scriptStateFromNode(m_current.get())); }
- Node* firstChild() { return firstChild(scriptStateFromNode(m_current.get())); }
- Node* lastChild() { return lastChild(scriptStateFromNode(m_current.get())); }
- Node* previousSibling() { return previousSibling(scriptStateFromNode(m_current.get())); }
- Node* nextSibling() { return nextSibling(scriptStateFromNode(m_current.get())); }
- Node* previousNode() { return previousNode(scriptStateFromNode(m_current.get())); }
- Node* nextNode() { return nextNode(scriptStateFromNode(m_current.get())); }
+ // Do not call these functions. They are just scaffolding to support the Objective-C bindings.
+ // They operate in the main thread normal world, and they swallow JS exceptions.
+ Node* parentNode() { return parentNode(scriptStateFromNode(mainThreadNormalWorld(), m_current.get())); }
+ Node* firstChild() { return firstChild(scriptStateFromNode(mainThreadNormalWorld(), m_current.get())); }
+ Node* lastChild() { return lastChild(scriptStateFromNode(mainThreadNormalWorld(), m_current.get())); }
+ Node* previousSibling() { return previousSibling(scriptStateFromNode(mainThreadNormalWorld(), m_current.get())); }
+ Node* nextSibling() { return nextSibling(scriptStateFromNode(mainThreadNormalWorld(), m_current.get())); }
+ Node* previousNode() { return previousNode(scriptStateFromNode(mainThreadNormalWorld(), m_current.get())); }
+ Node* nextNode() { return nextNode(scriptStateFromNode(mainThreadNormalWorld(), m_current.get())); }
private:
TreeWalker(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
diff --git a/WebCore/dom/XMLTokenizer.cpp b/WebCore/dom/XMLTokenizer.cpp
index 30d39e0..56f8ff4 100644
--- a/WebCore/dom/XMLTokenizer.cpp
+++ b/WebCore/dom/XMLTokenizer.cpp
@@ -91,7 +91,8 @@ void XMLTokenizer::pushCurrentNode(Node* n)
void XMLTokenizer::popCurrentNode()
{
- ASSERT(m_currentNode);
+ if (!m_currentNode)
+ return;
ASSERT(m_currentNodeStack.size());
if (m_currentNode != m_doc)
diff --git a/WebCore/dom/XMLTokenizer.h b/WebCore/dom/XMLTokenizer.h
index 095e8db..2f9c113 100644
--- a/WebCore/dom/XMLTokenizer.h
+++ b/WebCore/dom/XMLTokenizer.h
@@ -161,6 +161,23 @@ namespace WebCore {
class PendingCallbacks;
class ScriptElement;
+#if !USE(QXMLSTREAM)
+ class XMLParserContext : public RefCounted<XMLParserContext> {
+ public:
+ static PassRefPtr<XMLParserContext> createMemoryParser(xmlSAXHandlerPtr, void*, const char*);
+ static PassRefPtr<XMLParserContext> createStringParser(xmlSAXHandlerPtr, void*);
+ ~XMLParserContext();
+ xmlParserCtxtPtr context() const { return m_context; }
+
+ private:
+ XMLParserContext(xmlParserCtxtPtr context)
+ : m_context(context)
+ {
+ }
+ xmlParserCtxtPtr m_context;
+ };
+#endif
+
class XMLTokenizer : public Tokenizer, public CachedResourceClient {
public:
XMLTokenizer(Document*, FrameView* = 0);
@@ -255,7 +272,8 @@ public:
QXmlStreamReader m_stream;
bool m_wroteText;
#else
- xmlParserCtxtPtr m_context;
+ xmlParserCtxtPtr context() const { return m_context ? m_context->context() : 0; };
+ RefPtr<XMLParserContext> m_context;
OwnPtr<PendingCallbacks> m_pendingCallbacks;
Vector<xmlChar> m_bufferedText;
#endif
diff --git a/WebCore/dom/XMLTokenizerLibxml2.cpp b/WebCore/dom/XMLTokenizerLibxml2.cpp
index 9aa0961..42c8b9b 100644
--- a/WebCore/dom/XMLTokenizerLibxml2.cpp
+++ b/WebCore/dom/XMLTokenizerLibxml2.cpp
@@ -465,7 +465,7 @@ static void errorFunc(void*, const char*, ...)
static bool didInit = false;
-static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* userData)
+PassRefPtr<XMLParserContext> XMLParserContext::createStringParser(xmlSAXHandlerPtr handlers, void* userData)
{
if (!didInit) {
xmlInitParser();
@@ -482,12 +482,12 @@ static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* user
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
xmlSwitchEncoding(parser, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
- return parser;
+ return adoptRef(new XMLParserContext(parser));
}
// Chunk should be encoded in UTF-8
-static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk)
+PassRefPtr<XMLParserContext> XMLParserContext::createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk)
{
if (!didInit) {
xmlInitParser();
@@ -518,8 +518,8 @@ static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* user
parser->str_xmlns = xmlDictLookup(parser->dict, BAD_CAST "xmlns", 5);
parser->str_xml_ns = xmlDictLookup(parser->dict, XML_XML_NAMESPACE, 36);
parser->_private = userData;
-
- return parser;
+
+ return adoptRef(new XMLParserContext(parser));
}
// --------------------------------
@@ -609,6 +609,13 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
m_defaultNamespaceURI = parentElement->namespaceURI();
}
+XMLParserContext::~XMLParserContext()
+{
+ if (m_context->myDoc)
+ xmlFreeDoc(m_context->myDoc);
+ xmlFreeParserCtxt(m_context);
+}
+
XMLTokenizer::~XMLTokenizer()
{
clearCurrentNodeStack();
@@ -616,15 +623,16 @@ XMLTokenizer::~XMLTokenizer()
m_doc->deref();
if (m_pendingScript)
m_pendingScript->removeClient(this);
- if (m_context)
- xmlFreeParserCtxt(m_context);
}
void XMLTokenizer::doWrite(const String& parseString)
{
if (!m_context)
initializeParserContext();
-
+
+ // Protect the libxml context from deletion during a callback
+ RefPtr<XMLParserContext> context = m_context;
+
// libXML throws an error if you try to switch the encoding for an empty string.
if (parseString.length()) {
// Hack around libxml2's lack of encoding overide support by manually
@@ -633,15 +641,15 @@ void XMLTokenizer::doWrite(const String& parseString)
// and switch encodings, causing the parse to fail.
const UChar BOM = 0xFEFF;
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
- xmlSwitchEncoding(m_context, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
+ xmlSwitchEncoding(context->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);
+ xmlParseChunk(context->context(), reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
}
if (m_doc->decoder() && m_doc->decoder()->sawError()) {
// If the decoder saw an error, report it as fatal (stops parsing)
- handleError(fatal, "Encoding error", lineNumber(), columnNumber());
+ handleError(fatal, "Encoding error", context->context()->input->line, context->context()->input->col);
}
return;
@@ -1277,9 +1285,9 @@ void XMLTokenizer::initializeParserContext(const char* chunk)
XMLTokenizerScope scope(m_doc->docLoader());
if (m_parsingFragment)
- m_context = createMemoryParser(&sax, this, chunk);
+ m_context = XMLParserContext::createMemoryParser(&sax, this, chunk);
else
- m_context = createStringParser(&sax, this);
+ m_context = XMLParserContext::createStringParser(&sax, this);
}
void XMLTokenizer::doEnd()
@@ -1300,12 +1308,9 @@ void XMLTokenizer::doEnd()
// Tell libxml we're done.
{
XMLTokenizerScope scope(m_doc->docLoader());
- xmlParseChunk(m_context, 0, 0, 1);
+ xmlParseChunk(context(), 0, 0, 1);
}
- if (m_context->myDoc)
- xmlFreeDoc(m_context->myDoc);
- xmlFreeParserCtxt(m_context);
m_context = 0;
}
}
@@ -1334,18 +1339,19 @@ void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const Strin
int XMLTokenizer::lineNumber() const
{
- return m_context ? m_context->input->line : 1;
+ return context() ? context()->input->line : 1;
}
int XMLTokenizer::columnNumber() const
{
- return m_context ? m_context->input->col : 1;
+ return context() ? context()->input->col : 1;
}
void XMLTokenizer::stopParsing()
{
Tokenizer::stopParsing();
- xmlStopParser(m_context);
+ if (context())
+ xmlStopParser(context());
}
void XMLTokenizer::resumeParsing()
@@ -1384,17 +1390,17 @@ bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, E
CString chunkAsUtf8 = chunk.utf8();
tokenizer.initializeParserContext(chunkAsUtf8.data());
- xmlParseContent(tokenizer.m_context);
+ xmlParseContent(tokenizer.context());
tokenizer.endDocument();
// Check if all the chunk has been processed.
- long bytesProcessed = xmlByteConsumed(tokenizer.m_context);
+ long bytesProcessed = xmlByteConsumed(tokenizer.context());
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.
- return tokenizer.m_context->wellFormed || xmlCtxtGetLastError(tokenizer.m_context) == 0;
+ return tokenizer.context()->wellFormed || xmlCtxtGetLastError(tokenizer.context()) == 0;
}
// --------------------------------
@@ -1437,12 +1443,9 @@ HashMap<String, String> parseAttributes(const String& string, bool& attrsOK)
memset(&sax, 0, sizeof(sax));
sax.startElementNs = attributesStartElementNsHandler;
sax.initialized = XML_SAX2_MAGIC;
- xmlParserCtxtPtr parser = createStringParser(&sax, &state);
+ RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax, &state);
String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />";
- xmlParseChunk(parser, reinterpret_cast<const char*>(parseString.characters()), parseString.length() * sizeof(UChar), 1);
- if (parser->myDoc)
- xmlFreeDoc(parser->myDoc);
- xmlFreeParserCtxt(parser);
+ xmlParseChunk(parser->context(), reinterpret_cast<const char*>(parseString.characters()), parseString.length() * sizeof(UChar), 1);
attrsOK = state.gotAttributes;
return state.attributes;
}
diff --git a/WebCore/dom/XMLTokenizerQt.cpp b/WebCore/dom/XMLTokenizerQt.cpp
index c6e73ba..4e61715 100644
--- a/WebCore/dom/XMLTokenizerQt.cpp
+++ b/WebCore/dom/XMLTokenizerQt.cpp
@@ -66,7 +66,6 @@ using namespace std;
namespace WebCore {
-#if QT_VERSION >= 0x040400
class EntityResolver : public QXmlStreamEntityResolver {
virtual QString resolveUndeclaredEntity(const QString &name);
};
@@ -76,7 +75,6 @@ QString EntityResolver::resolveUndeclaredEntity(const QString &name)
UChar c = decodeNamedEntity(name.toUtf8().constData());
return QString(c);
}
-#endif
// --------------------------------
@@ -103,9 +101,7 @@ XMLTokenizer::XMLTokenizer(Document* _doc, FrameView* _view)
, m_scriptStartLine(0)
, m_parsingFragment(false)
{
-#if QT_VERSION >= 0x040400
m_stream.setEntityResolver(new EntityResolver);
-#endif
}
XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
@@ -149,19 +145,6 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
if (elemStack.isEmpty())
return;
-#if QT_VERSION < 0x040400
- for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
- if (NamedNodeMap* attrs = element->attributes()) {
- for (unsigned i = 0; i < attrs->length(); i++) {
- Attribute* attr = attrs->attributeItem(i);
- if (attr->localName() == "xmlns")
- m_defaultNamespaceURI = attr->value();
- else if (attr->prefix() == "xmlns")
- m_prefixToNamespaceMap.set(attr->localName(), attr->value());
- }
- }
- }
-#else
QXmlStreamNamespaceDeclarations namespaces;
for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
if (NamedNodeMap* attrs = element->attributes()) {
@@ -176,7 +159,6 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
}
m_stream.addExtraNamespaceDeclarations(namespaces);
m_stream.setEntityResolver(new EntityResolver);
-#endif
// If the parent element is not in document tree, there may be no xmlns attribute; just default to the parent's namespace.
if (m_defaultNamespaceURI.isNull() && !parentElement->inDocument())
@@ -190,9 +172,7 @@ XMLTokenizer::~XMLTokenizer()
m_doc->deref();
if (m_pendingScript)
m_pendingScript->removeClient(this);
-#if QT_VERSION >= 0x040400
delete m_stream.entityResolver();
-#endif
}
void XMLTokenizer::doWrite(const String& parseString)
@@ -207,27 +187,6 @@ void XMLTokenizer::doWrite(const String& parseString)
QString data(parseString);
if (!data.isEmpty()) {
-#if QT_VERSION < 0x040400
- if (!m_sawFirstElement) {
- int idx = data.indexOf(QLatin1String("<?xml"));
- if (idx != -1) {
- int start = idx + 5;
- int end = data.indexOf(QLatin1String("?>"), start);
- QString content = data.mid(start, end-start);
- bool ok = true;
- HashMap<String, String> attrs = parseAttributes(content, ok);
- String version = attrs.get("version");
- String encoding = attrs.get("encoding");
- ExceptionCode ec = 0;
- if (!m_parsingFragment) {
- if (!version.isEmpty())
- m_doc->setXMLVersion(version, ec);
- if (!encoding.isEmpty())
- m_doc->setXMLEncoding(encoding);
- }
- }
- }
-#endif
m_stream.addData(data);
parse();
}
@@ -256,7 +215,7 @@ void XMLTokenizer::doEnd()
#endif
if (m_stream.error() == QXmlStreamReader::PrematureEndOfDocumentError
- || (m_wroteText && !m_sawFirstElement && !m_sawXSLTransform))
+ || (m_wroteText && !m_sawFirstElement && !m_sawXSLTransform && !m_sawError))
handleError(fatal, qPrintable(m_stream.errorString()), lineNumber(), columnNumber());
}
@@ -485,14 +444,12 @@ void XMLTokenizer::startDocument()
if (!m_parsingFragment) {
m_doc->setXMLStandalone(m_stream.isStandaloneDocument(), ec);
-#if QT_VERSION >= 0x040400
QStringRef version = m_stream.documentVersion();
if (!version.isEmpty())
m_doc->setXMLVersion(version, ec);
QStringRef encoding = m_stream.documentEncoding();
if (!encoding.isEmpty())
m_doc->setXMLEncoding(encoding);
-#endif
}
}
@@ -702,83 +659,11 @@ bool XMLTokenizer::hasError() const
return m_stream.hasError();
}
-#if QT_VERSION < 0x040400
-static QString parseId(const QString &dtd, int *pos, bool *ok)
-{
- *ok = true;
- int start = *pos + 1;
- int end = start;
- if (dtd.at(*pos) == QLatin1Char('\''))
- while (start < dtd.length() && dtd.at(end) != QLatin1Char('\''))
- ++end;
- else if (dtd.at(*pos) == QLatin1Char('\"'))
- while (start < dtd.length() && dtd.at(end) != QLatin1Char('\"'))
- ++end;
- else {
- *ok = false;
- return QString();
- }
- *pos = end + 1;
- return dtd.mid(start, end - start);
-}
-#endif
-
void XMLTokenizer::parseDtd()
{
-#if QT_VERSION >= 0x040400
QStringRef name = m_stream.dtdName();
QStringRef publicId = m_stream.dtdPublicId();
QStringRef systemId = m_stream.dtdSystemId();
-#else
- QString dtd = m_stream.text().toString();
-
- int start = dtd.indexOf("<!DOCTYPE ") + 10;
- while (start < dtd.length() && dtd.at(start).isSpace())
- ++start;
- int end = start;
- while (start < dtd.length() && !dtd.at(end).isSpace())
- ++end;
- QString name = dtd.mid(start, end - start);
-
- start = end;
- while (start < dtd.length() && dtd.at(start).isSpace())
- ++start;
- end = start;
- while (start < dtd.length() && !dtd.at(end).isSpace())
- ++end;
- QString id = dtd.mid(start, end - start);
- start = end;
- while (start < dtd.length() && dtd.at(start).isSpace())
- ++start;
- QString publicId;
- QString systemId;
- if (id == QLatin1String("PUBLIC")) {
- bool ok;
- publicId = parseId(dtd, &start, &ok);
- if (!ok) {
- handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber());
- return;
- }
- while (start < dtd.length() && dtd.at(start).isSpace())
- ++start;
- systemId = parseId(dtd, &start, &ok);
- if (!ok) {
- handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber());
- return;
- }
- } else if (id == QLatin1String("SYSTEM")) {
- bool ok;
- systemId = parseId(dtd, &start, &ok);
- if (!ok) {
- handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber());
- return;
- }
- } else if (id == QLatin1String("[") || id == QLatin1String(">")) {
- } else {
- handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber());
- return;
- }
-#endif
//qDebug() << dtd << name << publicId << systemId;
if ((publicId == QLatin1String("-//W3C//DTD XHTML 1.0 Transitional//EN"))
diff --git a/WebCore/dom/default/PlatformMessagePortChannel.cpp b/WebCore/dom/default/PlatformMessagePortChannel.cpp
index d668703..9e0e7dc 100644
--- a/WebCore/dom/default/PlatformMessagePortChannel.cpp
+++ b/WebCore/dom/default/PlatformMessagePortChannel.cpp
@@ -193,7 +193,8 @@ void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChann
bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result)
{
MutexLocker lock(m_mutex);
- return m_incomingQueue->tryGetMessage(result);
+ result = m_incomingQueue->tryGetMessage();
+ return result;
}
bool PlatformMessagePortChannel::isConnectedTo(MessagePort* port)
diff --git a/WebCore/dom/default/PlatformMessagePortChannel.h b/WebCore/dom/default/PlatformMessagePortChannel.h
index 0ce2d13..2aad952 100644
--- a/WebCore/dom/default/PlatformMessagePortChannel.h
+++ b/WebCore/dom/default/PlatformMessagePortChannel.h
@@ -63,18 +63,14 @@ namespace WebCore {
public:
static PassRefPtr<MessagePortQueue> create() { return adoptRef(new MessagePortQueue()); }
- bool tryGetMessage(OwnPtr<MessagePortChannel::EventData>& message)
+ PassOwnPtr<MessagePortChannel::EventData> tryGetMessage()
{
- MessagePortChannel::EventData* holder = 0;
- bool messageAvailable = m_queue.tryGetMessage(holder);
- if (messageAvailable)
- message.set(holder);
- return messageAvailable;
+ return m_queue.tryGetMessage();
}
bool appendAndCheckEmpty(PassOwnPtr<MessagePortChannel::EventData> message)
{
- return m_queue.appendAndCheckEmpty(message.release());
+ return m_queue.appendAndCheckEmpty(message);
}
bool isEmpty()
@@ -82,19 +78,10 @@ namespace WebCore {
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;
+ MessageQueue<MessagePortChannel::EventData> m_queue;
};
~PlatformMessagePortChannel();