diff options
Diffstat (limited to 'WebCore/bindings/gobject')
-rw-r--r-- | WebCore/bindings/gobject/DOMObjectCache.cpp | 153 | ||||
-rw-r--r-- | WebCore/bindings/gobject/DOMObjectCache.h | 39 | ||||
-rw-r--r-- | WebCore/bindings/gobject/GNUmakefile.am | 3 | ||||
-rw-r--r-- | WebCore/bindings/gobject/GObjectEventListener.cpp | 1 | ||||
-rw-r--r-- | WebCore/bindings/gobject/WebKitDOMBinding.cpp | 51 | ||||
-rw-r--r-- | WebCore/bindings/gobject/WebKitDOMBinding.h | 16 |
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 |