summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/gobject
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/gobject')
-rw-r--r--WebCore/bindings/gobject/DOMObjectCache.cpp153
-rw-r--r--WebCore/bindings/gobject/DOMObjectCache.h39
-rw-r--r--WebCore/bindings/gobject/GNUmakefile.am3
-rw-r--r--WebCore/bindings/gobject/GObjectEventListener.cpp1
-rw-r--r--WebCore/bindings/gobject/WebKitDOMBinding.cpp51
-rw-r--r--WebCore/bindings/gobject/WebKitDOMBinding.h16
6 files changed, 214 insertions, 49 deletions
diff --git a/WebCore/bindings/gobject/DOMObjectCache.cpp b/WebCore/bindings/gobject/DOMObjectCache.cpp
new file mode 100644
index 0000000..7bf1679
--- /dev/null
+++ b/WebCore/bindings/gobject/DOMObjectCache.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "DOMObjectCache.h"
+
+#include "Document.h"
+#include "Node.h"
+#include <wtf/HashMap.h>
+
+namespace WebKit {
+
+typedef struct {
+ GObject* object;
+ WebCore::Frame* frame;
+ guint timesReturned;
+} DOMObjectCacheData;
+
+typedef HashMap<void*, DOMObjectCacheData*> DOMObjectMap;
+
+static DOMObjectMap& domObjects()
+{
+ static DOMObjectMap staticDOMObjects;
+ return staticDOMObjects;
+}
+
+static WebCore::Frame* getFrameFromHandle(void* objectHandle)
+{
+ WebCore::Node* node = static_cast<WebCore::Node*>(objectHandle);
+ if (!node->inDocument())
+ return 0;
+ WebCore::Document* document = node->document();
+ if (!document)
+ return 0;
+ return document->frame();
+}
+
+void DOMObjectCache::forget(void* objectHandle)
+{
+ DOMObjectCacheData* cacheData = domObjects().get(objectHandle);
+ ASSERT(cacheData);
+ g_slice_free(DOMObjectCacheData, cacheData);
+ domObjects().take(objectHandle);
+}
+
+static void weakRefNotify(gpointer data, GObject* zombie)
+{
+ gboolean* objectDead = static_cast<gboolean*>(data);
+ *objectDead = TRUE;
+}
+
+void DOMObjectCache::clearByFrame(WebCore::Frame* frame)
+{
+ Vector<DOMObjectCacheData*> toUnref;
+
+ // Unreffing the objects removes them from the cache in their
+ // finalize method, so just save them to do that while we are not
+ // iterating the cache itself.
+ DOMObjectMap::iterator end = domObjects().end();
+ for (DOMObjectMap::iterator iter = domObjects().begin(); iter != end; ++iter) {
+ DOMObjectCacheData* data = iter->second;
+ ASSERT(data);
+ if ((!frame || data->frame == frame) && data->timesReturned)
+ toUnref.append(data);
+ }
+
+ Vector<DOMObjectCacheData*>::iterator last = toUnref.end();
+ for (Vector<DOMObjectCacheData*>::iterator it = toUnref.begin(); it != last; ++it) {
+ DOMObjectCacheData* data = *it;
+ // We can't really know what the user has done with the DOM
+ // objects, so in case any of the external references to them
+ // were unreffed (but not all, otherwise the object would be
+ // dead and out of the cache) we'll add a weak ref before we
+ // start to get rid of the cache's own references; if the
+ // object dies in the middle of the process, we'll just stop.
+ gboolean objectDead = FALSE;
+ g_object_weak_ref(data->object, weakRefNotify, &objectDead);
+ // We need to check objectDead first, otherwise the cache data
+ // might be garbage already.
+ while (!objectDead && data->timesReturned > 0) {
+ // If this is the last unref we are going to do,
+ // disconnect the weak ref. We cannot do it afterwards
+ // because the object might be dead at that point.
+ if (data->timesReturned == 1)
+ g_object_weak_unref(data->object, weakRefNotify, &objectDead);
+ data->timesReturned--;
+ g_object_unref(data->object);
+ }
+ }
+}
+
+DOMObjectCache::~DOMObjectCache()
+{
+ clearByFrame();
+}
+
+void* DOMObjectCache::get(void* objectHandle)
+{
+ DOMObjectCacheData* data = domObjects().get(objectHandle);
+ if (!data)
+ return 0;
+
+ // We want to add one ref each time a wrapper is returned, so that
+ // the user can manually unref them if he chooses to.
+ ASSERT(data->object);
+ data->timesReturned++;
+ return g_object_ref(data->object);
+}
+
+void* DOMObjectCache::put(void* objectHandle, void* wrapper)
+{
+ if (domObjects().get(objectHandle))
+ return wrapper;
+
+ DOMObjectCacheData* data = g_slice_new(DOMObjectCacheData);
+ data->object = static_cast<GObject*>(wrapper);
+ data->frame = 0;
+ data->timesReturned = 1;
+
+ domObjects().set(objectHandle, data);
+ return wrapper;
+}
+
+void* DOMObjectCache::put(WebCore::Node* objectHandle, void* wrapper)
+{
+ // call the ::put version that takes void* to do the basic cache
+ // insertion work
+ put(static_cast<void*>(objectHandle), wrapper);
+
+ DOMObjectCacheData* data = domObjects().get(objectHandle);
+ ASSERT(data);
+
+ data->frame = getFrameFromHandle(objectHandle);
+
+ return wrapper;
+}
+
+}
diff --git a/WebCore/bindings/gobject/DOMObjectCache.h b/WebCore/bindings/gobject/DOMObjectCache.h
new file mode 100644
index 0000000..568e8b6
--- /dev/null
+++ b/WebCore/bindings/gobject/DOMObjectCache.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef DOMObjectCache_h
+#define DOMObjectCache_h
+
+namespace WebCore {
+class Node;
+class Frame;
+};
+
+namespace WebKit {
+class DOMObjectCache {
+public:
+ static void* get(void* objectHandle);
+ static void* put(void* objectHandle, void* wrapper);
+ static void* put(WebCore::Node* objectHandle, void* wrapper);
+ static void clearByFrame(WebCore::Frame* frame = 0);
+ static void forget(void* objectHandle);
+ ~DOMObjectCache();
+};
+} // namespace WebKit
+
+#endif
diff --git a/WebCore/bindings/gobject/GNUmakefile.am b/WebCore/bindings/gobject/GNUmakefile.am
index 338d7f9..bf896bd 100644
--- a/WebCore/bindings/gobject/GNUmakefile.am
+++ b/WebCore/bindings/gobject/GNUmakefile.am
@@ -196,6 +196,8 @@ webkitgtk_gdom_built_sources += \
DerivedSources/webkit/WebKitDOMMediaErrorPrivate.h \
DerivedSources/webkit/WebKitDOMMediaList.cpp \
DerivedSources/webkit/WebKitDOMMediaListPrivate.h \
+ DerivedSources/webkit/WebKitDOMMediaQueryList.cpp \
+ DerivedSources/webkit/WebKitDOMMediaQueryListPrivate.h \
DerivedSources/webkit/WebKitDOMMemoryInfo.cpp \
DerivedSources/webkit/WebKitDOMMemoryInfoPrivate.h \
DerivedSources/webkit/WebKitDOMMessagePort.cpp \
@@ -254,6 +256,7 @@ webkitgtk_built_h_api += \
DerivedSources/webkit/WebKitDOMCSSStyleSheet.h \
DerivedSources/webkit/WebKitDOMCSSValue.h \
DerivedSources/webkit/WebKitDOMMediaList.h \
+ DerivedSources/webkit/WebKitDOMMediaQueryList.h \
DerivedSources/webkit/WebKitDOMStyleMedia.h \
DerivedSources/webkit/WebKitDOMStyleSheet.h \
DerivedSources/webkit/WebKitDOMStyleSheetList.h \
diff --git a/WebCore/bindings/gobject/GObjectEventListener.cpp b/WebCore/bindings/gobject/GObjectEventListener.cpp
index 3e0aa2a..27432b9 100644
--- a/WebCore/bindings/gobject/GObjectEventListener.cpp
+++ b/WebCore/bindings/gobject/GObjectEventListener.cpp
@@ -71,6 +71,7 @@ void GObjectEventListener::handleEvent(ScriptExecutionContext*, Event* event)
gboolean handled = FALSE;
WebKitDOMEvent* gobjectEvent = WEBKIT_DOM_EVENT(WebKit::kit(event));
g_signal_emit_by_name(m_object, m_signalName.data(), gobjectEvent, &handled);
+ g_object_unref(gobjectEvent);
}
bool GObjectEventListener::operator==(const EventListener& listener)
diff --git a/WebCore/bindings/gobject/WebKitDOMBinding.cpp b/WebCore/bindings/gobject/WebKitDOMBinding.cpp
index 3c066e3..a9b0897 100644
--- a/WebCore/bindings/gobject/WebKitDOMBinding.cpp
+++ b/WebCore/bindings/gobject/WebKitDOMBinding.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "WebKitDOMBinding.h"
+#include "DOMObjectCache.h"
#include "Element.h"
#include "Event.h"
#include "EventException.h"
@@ -44,32 +45,6 @@ namespace WebKit {
using namespace WebCore;
using namespace WebCore::HTMLNames;
-// DOMObjectCache
-
-typedef HashMap<void*, gpointer> DOMObjectMap;
-
-static DOMObjectMap& domObjects()
-{
- static DOMObjectMap staticDOMObjects;
- return staticDOMObjects;
-}
-
-gpointer DOMObjectCache::get(void* objectHandle)
-{
- return domObjects().get(objectHandle);
-}
-
-gpointer DOMObjectCache::put(void* objectHandle, gpointer wrapper)
-{
- domObjects().set(objectHandle, wrapper);
- return wrapper;
-}
-
-void DOMObjectCache::forget(void* objectHandle)
-{
- domObjects().take(objectHandle);
-}
-
// kit methods
static gpointer createWrapper(Node* node)
@@ -94,26 +69,26 @@ static gpointer createWrapper(Node* node)
return DOMObjectCache::put(node, wrappedNode);
}
-gpointer kit(Node* node)
+WebKitDOMNode* kit(Node* node)
{
if (!node)
return 0;
gpointer kitNode = DOMObjectCache::get(node);
if (kitNode)
- return kitNode;
+ return static_cast<WebKitDOMNode*>(kitNode);
- return createWrapper(node);
+ return static_cast<WebKitDOMNode*>(createWrapper(node));
}
-gpointer kit(Element* element)
+WebKitDOMElement* kit(Element* element)
{
if (!element)
return 0;
gpointer kitElement = DOMObjectCache::get(element);
if (kitElement)
- return kitElement;
+ return static_cast<WebKitDOMElement*>(kitElement);
gpointer wrappedElement;
@@ -122,17 +97,17 @@ gpointer kit(Element* element)
else
wrappedElement = wrapElement(element);
- return DOMObjectCache::put(element, wrappedElement);
+ return static_cast<WebKitDOMElement*>(DOMObjectCache::put(element, wrappedElement));
}
-gpointer kit(Event* event)
+WebKitDOMEvent* kit(Event* event)
{
if (!event)
return 0;
gpointer kitEvent = DOMObjectCache::get(event);
if (kitEvent)
- return kitEvent;
+ return static_cast<WebKitDOMEvent*>(kitEvent);
gpointer wrappedEvent;
@@ -143,7 +118,7 @@ gpointer kit(Event* event)
else
wrappedEvent = wrapEvent(event);
- return DOMObjectCache::put(event, wrappedEvent);
+ return static_cast<WebKitDOMEvent*>(DOMObjectCache::put(event, wrappedEvent));
}
static gpointer wrapEventTarget(EventTarget* target)
@@ -163,14 +138,14 @@ static gpointer wrapEventTarget(EventTarget* target)
return DOMObjectCache::put(target, wrappedTarget);
}
-gpointer kit(WebCore::EventTarget* obj)
+WebKitDOMEventTarget* kit(WebCore::EventTarget* obj)
{
g_return_val_if_fail(obj, 0);
if (gpointer ret = DOMObjectCache::get(obj))
- return ret;
+ return static_cast<WebKitDOMEventTarget*>(ret);
- return DOMObjectCache::put(obj, WebKit::wrapEventTarget(obj));
+ return static_cast<WebKitDOMEventTarget*>(DOMObjectCache::put(obj, WebKit::wrapEventTarget(obj)));
}
} // namespace WebKit
diff --git a/WebCore/bindings/gobject/WebKitDOMBinding.h b/WebCore/bindings/gobject/WebKitDOMBinding.h
index 2248f78..ca7840e 100644
--- a/WebCore/bindings/gobject/WebKitDOMBinding.h
+++ b/WebCore/bindings/gobject/WebKitDOMBinding.h
@@ -24,6 +24,7 @@
#ifndef WebKitDOMBinding_h
#define WebKitDOMBinding_h
+#include "webkit/webkitdomdefines.h"
#include <glib.h>
namespace WebCore {
@@ -34,17 +35,10 @@ class EventTarget;
} // namespace WebCore
namespace WebKit {
-gpointer kit(WebCore::Node* node);
-gpointer kit(WebCore::Element* element);
-gpointer kit(WebCore::Event* event);
-gpointer kit(WebCore::EventTarget* target);
-
-class DOMObjectCache {
-public:
- static gpointer get(void* objectHandle);
- static gpointer put(void* objectHandle, gpointer wrapper);
- static void forget(void* objectHandle);
-};
+WebKitDOMNode* kit(WebCore::Node* node);
+WebKitDOMElement* kit(WebCore::Element* element);
+WebKitDOMEvent* kit(WebCore::Event* event);
+WebKitDOMEventTarget* kit(WebCore::EventTarget* target);
} // namespace WebKit
#endif // WebKitDOMBinding_h