Changeset 180214 in webkit


Ignore:
Timestamp:
Feb 17, 2015 1:57:42 AM (9 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK] GObject DOM bindings object are cached forever
https://bugs.webkit.org/show_bug.cgi?id=141558

Reviewed by Sergio Villar Senin.

Source/WebCore:

Rework the DOMObjectCache to avoid having to manually clear the
objects when the frame is destroyed, using a FrameDestructionObserver
instead. When a new object associated to a Frame is added to the
cache, a FrameDestructionObserver is created for the frame if
needed, and the DOM object is tracked by the observer too. When
the frame is detached from the page all its objects are cleared,
and if the aren't additional references, the object is finalized
and removed from the cache normally.
This patch also simplifies and modernizes the code to make it
easier to read an maintain.

  • bindings/gobject/DOMObjectCache.cpp:

(WebKit::DOMObjectCacheData::DOMObjectCacheData): Add constructor
to initialize its members and simplify the callers.
(WebKit::DOMObjectCacheData::clearObject): Remove the references
added by the cache, ensuring the GObject is not finalized until
the method returns.
(WebKit::DOMObjectCacheData::refObject): Adds a reference owned by
the cache.
(WebKit::domObjectCacheFrameObservers): Map a frame to a FrameDestructionObserver.
(WebKit::getOrCreateDOMObjectCacheFrameObserver): Create a new
FrameDestructionObserver for the given Frame or return the
existing one.
(WebKit::domObjects): Map wrapped object to wrapper object.
(WebKit::DOMObjectCache::forget): Remove the wrapped object from
the cache.
(WebKit::DOMObjectCache::get): Return the wrapped object if it is
in the cache, increasing the cache references.
(WebKit::DOMObjectCache::put): Add the wrapper object to the cache
for the given wrapped object. If it's a Node and has a frame add
the node to the FrameDestructionObserver corresponding to the frame.
(WebKit::getFrameFromHandle): Deleted.
(WebKit::weakRefNotify): Deleted.
(WebKit::DOMObjectCache::clearByFrame): Deleted.
(WebKit::DOMObjectCache::~DOMObjectCache): Deleted.

  • bindings/gobject/DOMObjectCache.h:

Tools:

Add checks for all DOM objects to ensure they are not leaked. Also
add a dedicated test for the DOM Object Cache.

  • TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeFilterTest.cpp:

(WebKitDOMNodeFilterTest::testTreeWalker):
(WebKitDOMNodeFilterTest::testNodeIterator):

  • TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeTest.cpp:

(WebKitDOMNodeTest::testHierarchyNavigation):
(WebKitDOMNodeTest::testInsertion):
(WebKitDOMNodeTest::testTagNames):
(WebKitDOMNodeTest::testDOMCache):
(registerTests):

  • TestWebKitAPI/Tests/WebKit2Gtk/DOMXPathNSResolverTest.cpp:

(WebKitDOMXPathNSResolverTest::evaluateFooChildTextAndCheckResult):
(WebKitDOMXPathNSResolverTest::testXPathNSResolverNative):
(WebKitDOMXPathNSResolverTest::testXPathNSResolverCustom):

  • TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNode.cpp:

(testWebKitDOMObjectCache):
(beforeAll):

  • TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp:

(documentLoadedCallback):

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r180213 r180214  
     12015-02-17  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] GObject DOM bindings object are cached forever
     4        https://bugs.webkit.org/show_bug.cgi?id=141558
     5
     6        Reviewed by Sergio Villar Senin.
     7
     8        Rework the DOMObjectCache to avoid having to manually clear the
     9        objects when the frame is destroyed, using a FrameDestructionObserver
     10        instead. When a new object associated to a Frame is added to the
     11        cache, a FrameDestructionObserver is created for the frame if
     12        needed, and the DOM object is tracked by the observer too. When
     13        the frame is detached from the page all its objects are cleared,
     14        and if the aren't additional references, the object is finalized
     15        and removed from the cache normally.
     16        This patch also simplifies and modernizes the code to make it
     17        easier to read an maintain.
     18
     19        * bindings/gobject/DOMObjectCache.cpp:
     20        (WebKit::DOMObjectCacheData::DOMObjectCacheData): Add constructor
     21        to initialize its members and simplify the callers.
     22        (WebKit::DOMObjectCacheData::clearObject): Remove the references
     23        added by the cache, ensuring the GObject is not finalized until
     24        the method returns.
     25        (WebKit::DOMObjectCacheData::refObject): Adds a reference owned by
     26        the cache.
     27        (WebKit::domObjectCacheFrameObservers): Map a frame to a FrameDestructionObserver.
     28        (WebKit::getOrCreateDOMObjectCacheFrameObserver): Create a new
     29        FrameDestructionObserver for the given Frame or return the
     30        existing one.
     31        (WebKit::domObjects): Map wrapped object to wrapper object.
     32        (WebKit::DOMObjectCache::forget): Remove the wrapped object from
     33        the cache.
     34        (WebKit::DOMObjectCache::get): Return the wrapped object if it is
     35        in the cache, increasing the cache references.
     36        (WebKit::DOMObjectCache::put): Add the wrapper object to the cache
     37        for the given wrapped object. If it's a Node and has a frame add
     38        the node to the FrameDestructionObserver corresponding to the frame.
     39        (WebKit::getFrameFromHandle): Deleted.
     40        (WebKit::weakRefNotify): Deleted.
     41        (WebKit::DOMObjectCache::clearByFrame): Deleted.
     42        (WebKit::DOMObjectCache::~DOMObjectCache): Deleted.
     43        * bindings/gobject/DOMObjectCache.h:
     44
    1452015-02-17  ChangSeok Oh  <changseok.oh@collabora.com>
    246
  • trunk/Source/WebCore/bindings/gobject/DOMObjectCache.cpp

    r165618 r180214  
    11/*
    2  *  Copyright (C) 2010 Igalia S.L.
     2 *  Copyright (C) 2010, 2015 Igalia S.L.
    33 *
    44 *  This library is free software; you can redistribute it and/or
     
    2121
    2222#include "Document.h"
     23#include "FrameDestructionObserver.h"
    2324#include "Node.h"
    2425#include <glib-object.h>
    2526#include <wtf/HashMap.h>
     27#include <wtf/NeverDestroyed.h>
     28#include <wtf/Vector.h>
     29#include <wtf/gobject/GRefPtr.h>
    2630
    2731namespace WebKit {
    2832
    29 typedef struct {
     33struct DOMObjectCacheData {
     34    DOMObjectCacheData(GObject* wrapper)
     35        : object(wrapper)
     36        , cacheReferences(1)
     37    {
     38    }
     39
     40    void clearObject()
     41    {
     42        ASSERT(object);
     43        ASSERT(cacheReferences >= 1);
     44
     45        GRefPtr<GObject> protect(object);
     46        do {
     47            g_object_unref(object);
     48        } while (--cacheReferences);
     49        object = nullptr;
     50    }
     51
     52    void* refObject()
     53    {
     54        ASSERT(object);
     55
     56        cacheReferences++;
     57        return g_object_ref(object);
     58    }
     59
    3060    GObject* object;
    31     WebCore::Frame* frame;
    32     guint timesReturned;
    33 } DOMObjectCacheData;
     61    unsigned cacheReferences;
     62};
    3463
    35 typedef HashMap<void*, DOMObjectCacheData*> DOMObjectMap;
     64class DOMObjectCacheFrameObserver;
     65typedef HashMap<WebCore::Frame*, std::unique_ptr<DOMObjectCacheFrameObserver>> DOMObjectCacheFrameObserverMap;
     66
     67static DOMObjectCacheFrameObserverMap& domObjectCacheFrameObservers()
     68{
     69    static NeverDestroyed<DOMObjectCacheFrameObserverMap> map;
     70    return map;
     71}
     72
     73static DOMObjectCacheFrameObserver& getOrCreateDOMObjectCacheFrameObserver(WebCore::Frame& frame)
     74{
     75    auto observerPtr = domObjectCacheFrameObservers().get(&frame);
     76    if (observerPtr)
     77        return *observerPtr;
     78
     79    std::unique_ptr<DOMObjectCacheFrameObserver> observer = std::make_unique<DOMObjectCacheFrameObserver>(frame);
     80    observerPtr = observer.get();
     81    domObjectCacheFrameObservers().set(&frame, WTF::move(observer));
     82    return *observerPtr;
     83}
     84
     85class DOMObjectCacheFrameObserver final: public WebCore::FrameDestructionObserver {
     86public:
     87    DOMObjectCacheFrameObserver(WebCore::Frame& frame)
     88        : FrameDestructionObserver(&frame)
     89    {
     90    }
     91
     92    ~DOMObjectCacheFrameObserver()
     93    {
     94        ASSERT(m_objects.isEmpty());
     95    }
     96
     97    void addObjectCacheData(DOMObjectCacheData& data)
     98    {
     99        ASSERT(!m_objects.contains(&data));
     100
     101        m_objects.append(&data);
     102        g_object_weak_ref(data.object, DOMObjectCacheFrameObserver::objectFinalizedCallback, this);
     103    }
     104
     105private:
     106    static void objectFinalizedCallback(gpointer userData, GObject* finalizedObject)
     107    {
     108        DOMObjectCacheFrameObserver* observer = static_cast<DOMObjectCacheFrameObserver*>(userData);
     109        observer->m_objects.removeFirstMatching([finalizedObject](DOMObjectCacheData* data) {
     110            return data->object == finalizedObject;
     111        });
     112    }
     113
     114    void clear()
     115    {
     116        if (m_objects.isEmpty())
     117            return;
     118
     119        auto objects = WTF::move(m_objects);
     120        for (auto* data : objects) {
     121            g_object_weak_unref(data->object, DOMObjectCacheFrameObserver::objectFinalizedCallback, this);
     122            data->clearObject();
     123        }
     124    }
     125
     126    virtual void willDetachPage() override
     127    {
     128        clear();
     129    }
     130
     131    virtual void frameDestroyed() override
     132    {
     133        clear();
     134        WebCore::Frame* frame = m_frame;
     135        FrameDestructionObserver::frameDestroyed();
     136        domObjectCacheFrameObservers().remove(frame);
     137    }
     138
     139    Vector<DOMObjectCacheData*, 8> m_objects;
     140};
     141
     142typedef HashMap<void*, std::unique_ptr<DOMObjectCacheData>> DOMObjectMap;
    36143
    37144static DOMObjectMap& domObjects()
    38145{
    39     static DOMObjectMap staticDOMObjects;
     146    static NeverDestroyed<DOMObjectMap> staticDOMObjects;
    40147    return staticDOMObjects;
    41 }
    42 
    43 static WebCore::Frame* getFrameFromHandle(void* objectHandle)
    44 {
    45     WebCore::Node* node = static_cast<WebCore::Node*>(objectHandle);
    46     if (!node->inDocument())
    47         return 0;
    48     return node->document().frame();
    49148}
    50149
    51150void DOMObjectCache::forget(void* objectHandle)
    52151{
    53     DOMObjectCacheData* cacheData = domObjects().get(objectHandle);
    54     ASSERT(cacheData);
    55     g_slice_free(DOMObjectCacheData, cacheData);
    56     domObjects().take(objectHandle);
    57 }
    58 
    59 static void weakRefNotify(gpointer data, GObject*)
    60 {
    61     gboolean* objectDead = static_cast<gboolean*>(data);
    62     *objectDead = TRUE;
    63 }
    64 
    65 void DOMObjectCache::clearByFrame(WebCore::Frame* frame)
    66 {
    67     Vector<DOMObjectCacheData*> toUnref;
    68 
    69     // Unreffing the objects removes them from the cache in their
    70     // finalize method, so just save them to do that while we are not
    71     // iterating the cache itself.
    72     DOMObjectMap::iterator end = domObjects().end();
    73     for (DOMObjectMap::iterator iter = domObjects().begin(); iter != end; ++iter) {
    74         DOMObjectCacheData* data = iter->value;
    75         ASSERT(data);
    76         if ((!frame || data->frame == frame) && data->timesReturned)
    77             toUnref.append(data);
    78     }
    79 
    80     Vector<DOMObjectCacheData*>::iterator last = toUnref.end();
    81     for (Vector<DOMObjectCacheData*>::iterator it = toUnref.begin(); it != last; ++it) {
    82         DOMObjectCacheData* data = *it;
    83         // We can't really know what the user has done with the DOM
    84         // objects, so in case any of the external references to them
    85         // were unreffed (but not all, otherwise the object would be
    86         // dead and out of the cache) we'll add a weak ref before we
    87         // start to get rid of the cache's own references; if the
    88         // object dies in the middle of the process, we'll just stop.
    89         gboolean objectDead = FALSE;
    90         g_object_weak_ref(data->object, weakRefNotify, &objectDead);
    91         // We need to check objectDead first, otherwise the cache data
    92         // might be garbage already.
    93         while (!objectDead && data->timesReturned > 0) {
    94             // If this is the last unref we are going to do,
    95             // disconnect the weak ref. We cannot do it afterwards
    96             // because the object might be dead at that point.
    97             if (data->timesReturned == 1) {
    98                 g_object_weak_unref(data->object, weakRefNotify, &objectDead);
    99                 // At this point, the next time the DOMObject is
    100                 // unref'ed it will be finalized,
    101                 // DOMObject::finalize() will call
    102                 // DOMObjectCache::forget(), which will free 'data'.
    103                 // Toggling 'objectDead' here will ensure we don't
    104                 // dereference an invalid pointer in the next
    105                 // iteration.
    106                 objectDead = TRUE;
    107             }
    108             data->timesReturned--;
    109             g_object_unref(data->object);
    110         }
    111     }
    112 }
    113 
    114 DOMObjectCache::~DOMObjectCache()
    115 {
    116     clearByFrame();
     152    ASSERT(domObjects().contains(objectHandle));
     153    domObjects().remove(objectHandle);
    117154}
    118155
     
    120157{
    121158    DOMObjectCacheData* data = domObjects().get(objectHandle);
    122     if (!data)
    123         return 0;
    124 
    125     // We want to add one ref each time a wrapper is returned, so that
    126     // the user can manually unref them if he chooses to.
    127     ASSERT(data->object);
    128     data->timesReturned++;
    129     return g_object_ref(data->object);
     159    return data ? data->refObject() : nullptr;
    130160}
    131161
    132 void* DOMObjectCache::put(void* objectHandle, void* wrapper)
     162void DOMObjectCache::put(void* objectHandle, void* wrapper)
    133163{
    134     if (domObjects().get(objectHandle))
    135         return wrapper;
    136 
    137     DOMObjectCacheData* data = g_slice_new(DOMObjectCacheData);
    138     data->object = static_cast<GObject*>(wrapper);
    139     data->frame = 0;
    140     data->timesReturned = 1;
    141 
    142     domObjects().set(objectHandle, data);
    143     return wrapper;
     164    if (domObjects().contains(objectHandle))
     165        return;
     166    domObjects().set(objectHandle, std::make_unique<DOMObjectCacheData>(G_OBJECT(wrapper)));
    144167}
    145168
    146 void* DOMObjectCache::put(WebCore::Node* objectHandle, void* wrapper)
     169void DOMObjectCache::put(WebCore::Node* objectHandle, void* wrapper)
    147170{
    148     // call the ::put version that takes void* to do the basic cache
    149     // insertion work
    150     put(static_cast<void*>(objectHandle), wrapper);
     171    if (domObjects().contains(objectHandle))
     172        return;
    151173
    152     DOMObjectCacheData* data = domObjects().get(objectHandle);
    153     ASSERT(data);
     174    std::unique_ptr<DOMObjectCacheData> data = std::make_unique<DOMObjectCacheData>(G_OBJECT(wrapper));
     175    auto dataPtr = data.get();
     176    domObjects().set(objectHandle, WTF::move(data));
    154177
    155     data->frame = getFrameFromHandle(objectHandle);
    156 
    157     return wrapper;
     178    if (WebCore::Frame* frame = objectHandle->document().frame())
     179        getOrCreateDOMObjectCacheFrameObserver(*frame).addObjectCacheData(*dataPtr);
    158180}
    159181
  • trunk/Source/WebCore/bindings/gobject/DOMObjectCache.h

    r95901 r180214  
    2222namespace WebCore {
    2323class Node;
    24 class Frame;
    2524};
    2625
     
    2928public:
    3029    static void* get(void* objectHandle);
    31     static void* put(void* objectHandle, void* wrapper);
    32     static void* put(WebCore::Node* objectHandle, void* wrapper);
    33     static void clearByFrame(WebCore::Frame* frame = 0);
     30    static void put(void* objectHandle, void* wrapper);
     31    static void put(WebCore::Node* objectHandle, void* wrapper);
    3432    static void forget(void* objectHandle);
    35     ~DOMObjectCache();
    3633};
    3734} // namespace WebKit
  • trunk/Tools/ChangeLog

    r180211 r180214  
     12015-02-17  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] GObject DOM bindings object are cached forever
     4        https://bugs.webkit.org/show_bug.cgi?id=141558
     5
     6        Reviewed by Sergio Villar Senin.
     7
     8        Add checks for all DOM objects to ensure they are not leaked. Also
     9        add a dedicated test for the DOM Object Cache.
     10
     11        * TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeFilterTest.cpp:
     12        (WebKitDOMNodeFilterTest::testTreeWalker):
     13        (WebKitDOMNodeFilterTest::testNodeIterator):
     14        * TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeTest.cpp:
     15        (WebKitDOMNodeTest::testHierarchyNavigation):
     16        (WebKitDOMNodeTest::testInsertion):
     17        (WebKitDOMNodeTest::testTagNames):
     18        (WebKitDOMNodeTest::testDOMCache):
     19        (registerTests):
     20        * TestWebKitAPI/Tests/WebKit2Gtk/DOMXPathNSResolverTest.cpp:
     21        (WebKitDOMXPathNSResolverTest::evaluateFooChildTextAndCheckResult):
     22        (WebKitDOMXPathNSResolverTest::testXPathNSResolverNative):
     23        (WebKitDOMXPathNSResolverTest::testXPathNSResolverCustom):
     24        * TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNode.cpp:
     25        (testWebKitDOMObjectCache):
     26        (beforeAll):
     27        * TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp:
     28        (documentLoadedCallback):
     29
    1302015-02-16  Carlos Garcia Campos  <cgarcia@igalia.com>
    231
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeFilterTest.cpp

    r176563 r180214  
    6767        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
    6868        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
     69        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
    6970
    7071        WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root");
    7172        g_assert(WEBKIT_DOM_IS_NODE(root));
     73        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root));
    7274
    7375        // No filter.
    74         WebKitDOMTreeWalker* walker = webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr);
    75         g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker));
    76         g_assert(!webkit_dom_tree_walker_get_filter(walker));
     76        GRefPtr<WebKitDOMTreeWalker> walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr));
     77        g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker.get()));
     78        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(walker.get()));
     79        g_assert(!webkit_dom_tree_walker_get_filter(walker.get()));
    7780
    7881        unsigned i = 0;
    79         for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker), ++i) {
     82        for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) {
     83            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    8084            g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll));
    8185            GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
     
    8690        // Input elements filter.
    8791        GRefPtr<WebKitDOMNodeFilter> filter = adoptGRef(static_cast<WebKitDOMNodeFilter*>(g_object_new(webkit_node_filter_get_type(), nullptr)));
    88         walker = webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr);
    89         g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker));
    90         g_assert(webkit_dom_tree_walker_get_filter(walker) == filter.get());
    91 
    92         i = 0;
    93         for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker), ++i) {
     92        walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr));
     93        g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker.get()));
     94        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(filter.get()));
     95        g_assert(webkit_dom_tree_walker_get_filter(walker.get()) == filter.get());
     96
     97        i = 0;
     98        for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) {
     99            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    94100            g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput));
    95101            GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
     
    99105
    100106        // Show only elements, reusing the input filter.
    101         walker = webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr);
    102         g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker));
    103         g_assert(webkit_dom_tree_walker_get_filter(walker) == filter.get());
    104 
    105         i = 0;
    106         for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker), ++i) {
     107        walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr));
     108        g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker.get()));
     109        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(walker.get()));
     110        g_assert(webkit_dom_tree_walker_get_filter(walker.get()) == filter.get());
     111
     112        i = 0;
     113        for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) {
     114            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    107115            g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput));
    108116            GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
     
    118126        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
    119127        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
     128        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
    120129
    121130        WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root");
    122131        g_assert(WEBKIT_DOM_IS_NODE(root));
     132        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root));
    123133
    124134        // No filter.
    125         WebKitDOMNodeIterator* iter = webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr);
    126         g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter));
    127         g_assert(!webkit_dom_node_iterator_get_filter(iter));
     135        GRefPtr<WebKitDOMNodeIterator> iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr));
     136        g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get()));
     137        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get()));
     138        g_assert(!webkit_dom_node_iterator_get_filter(iter.get()));
    128139
    129140        unsigned i = 0;
    130         while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter, nullptr)) {
     141        while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) {
     142            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    131143            g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll));
    132144            GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
     
    138150        // Input elements filter.
    139151        GRefPtr<WebKitDOMNodeFilter> filter = adoptGRef(static_cast<WebKitDOMNodeFilter*>(g_object_new(webkit_node_filter_get_type(), nullptr)));
    140         iter = webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr);
    141         g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter));
    142         g_assert(webkit_dom_node_iterator_get_filter(iter) == filter.get());
    143 
    144         i = 0;
    145         while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter, nullptr)) {
     152        iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr));
     153        g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get()));
     154        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get()));
     155        g_assert(webkit_dom_node_iterator_get_filter(iter.get()) == filter.get());
     156
     157        i = 0;
     158        while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) {
     159            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    146160            g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput));
    147161            GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
     
    152166
    153167        // Show only elements, reusing the input filter.
    154         iter = webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr);
    155         g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter));
    156         g_assert(webkit_dom_node_iterator_get_filter(iter) == filter.get());
    157 
    158         i = 0;
    159         while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter, nullptr)) {
     168        iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr));
     169        g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get()));
     170        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get()));
     171        g_assert(webkit_dom_node_iterator_get_filter(iter.get()) == filter.get());
     172
     173        i = 0;
     174        while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) {
     175            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    160176            g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput));
    161177            GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeTest.cpp

    r177019 r180214  
    3434        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
    3535        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
     36        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
    3637
    3738        WebKitDOMHTMLHeadElement* head = webkit_dom_document_get_head(document);
    3839        g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(head));
     40        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(head));
    3941
    4042        // Title, head's child.
     
    4244        GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(head)));
    4345        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     46        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
    4447        g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
    4548        WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0);
    4649        g_assert(WEBKIT_DOM_IS_HTML_TITLE_ELEMENT(node));
     50        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    4751
    4852        // Body, Head sibling.
    4953        node = webkit_dom_node_get_next_sibling(WEBKIT_DOM_NODE(head));
    5054        g_assert(WEBKIT_DOM_IS_HTML_BODY_ELEMENT(node));
     55        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    5156        WebKitDOMHTMLBodyElement* body = WEBKIT_DOM_HTML_BODY_ELEMENT(node);
    5257
     
    5762        node = webkit_dom_node_get_previous_sibling(WEBKIT_DOM_NODE(body));
    5863        g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(node));
     64        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    5965
    6066        // Body has 3 children.
    6167        g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
    6268        list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
     69        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     70        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
    6371        unsigned long length = webkit_dom_node_list_get_length(list.get());
    6472        g_assert_cmpint(length, ==, 3);
     
    6876            node = webkit_dom_node_list_item(list.get(), i);
    6977            g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(node));
     78            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    7079        }
    7180
     
    8291        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
    8392        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
     93        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
    8494
    8595        WebKitDOMHTMLElement* body = webkit_dom_document_get_body(document);
    8696        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(body));
     97        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(body));
    8798
    8899        // Body shouldn't have any children at this point.
     
    95106        WebKitDOMElement* p = webkit_dom_document_create_element(document, "P", 0);
    96107        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p));
     108        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p));
    97109        webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), 0);
    98110
     
    101113        GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
    102114        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     115        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
    103116        g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
    104117        WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0);
    105118        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
     119        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    106120        g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node));
    107121
     
    109123        WebKitDOMElement* div = webkit_dom_document_create_element(document, "DIV", 0);
    110124        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div));
     125        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div));
    111126        webkit_dom_node_replace_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p), 0);
    112127        g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
    113128        list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
    114129        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     130        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
    115131        g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
    116132        node = webkit_dom_node_list_item(list.get(), 0);
    117133        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
     134        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    118135        g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node));
    119136
     
    122139        list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
    123140        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     141        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
    124142        g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 0);
    125143
     
    127145        div = webkit_dom_document_create_element(document, "DIV", 0);
    128146        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div));
     147        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div));
    129148        webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), 0, 0);
    130149        g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
    131150        list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
    132151        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     152        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
    133153        g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
    134154        node = webkit_dom_node_list_item(list.get(), 0);
    135155        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
     156        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    136157        g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node));
    137158
     
    139160        p = webkit_dom_document_create_element(document, "P", 0);
    140161        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p));
     162        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p));
    141163        webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), WEBKIT_DOM_NODE(div), 0);
    142164        g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
    143165        list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
    144166        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     167        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
    145168        g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 2);
    146169        node = webkit_dom_node_list_item(list.get(), 0);
    147170        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
     171        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    148172        g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node));
    149173        node = webkit_dom_node_list_item(list.get(), 1);
    150174        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
     175        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    151176        g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node));
    152177
     
    160185        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
    161186        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
    162 
    163         WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_tag_name(document, "*");
    164         gulong nodeCount = webkit_dom_node_list_get_length(list);
     187        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
     188
     189        GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_document_get_elements_by_tag_name(document, "*"));
     190        g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
     191        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get()));
     192        gulong nodeCount = webkit_dom_node_list_get_length(list.get());
    165193        g_assert_cmpuint(nodeCount, ==, G_N_ELEMENTS(expectedTagNames));
    166194        for (unsigned i = 0; i < nodeCount; i++) {
    167             WebKitDOMNode* node = webkit_dom_node_list_item(list, i);
     195            WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), i);
    168196            g_assert(WEBKIT_DOM_IS_NODE(node));
     197            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
    169198            GUniquePtr<char> tagName(webkit_dom_node_get_node_name(node));
    170199            g_assert_cmpstr(tagName.get(), ==, expectedTagNames[i]);
     
    172201
    173202        return true;
     203    }
     204
     205    bool testDOMCache(WebKitWebPage* page)
     206    {
     207        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
     208        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
     209        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
     210
     211        // DOM objects already in the document should be automatically handled by the cache.
     212        WebKitDOMElement* div = webkit_dom_document_get_element_by_id(document, "container");
     213        g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div));
     214        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div));
     215
     216        // Get the same elment twice should return the same pointer.
     217        g_assert(div == webkit_dom_document_get_element_by_id(document, "container"));
     218
     219        // A new DOM object created that is derived from Node should be automatically handled by the cache.
     220        WebKitDOMElement* p = webkit_dom_document_create_element(document, "P", nullptr);
     221        g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(p));
     222        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p));
     223
     224        // A new DOM object created that isn't derived from Node should be manually handled.
     225        GRefPtr<WebKitDOMNodeIterator> iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr));
     226        g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get()));
     227        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get()));
     228
     229        // We can also manually handle a DOM object handled by the cache.
     230        GRefPtr<WebKitDOMElement> p2 = adoptGRef(webkit_dom_document_create_element(document, "P", nullptr));
     231        g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(p2.get()));
     232        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p2.get()));
     233
     234        // DOM objects removed from the document are also correctly handled by the cache.
     235        WebKitDOMElement* a = webkit_dom_document_create_element(document, "A", nullptr);
     236        g_assert(WEBKIT_DOM_IS_ELEMENT(a));
     237        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(a));
     238        webkit_dom_node_remove_child(WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(a), nullptr);
    174239    }
    175240
     
    182247        if (!strcmp(testName, "tag-names"))
    183248            return testTagNames(page);
     249        if (!strcmp(testName, "dom-cache"))
     250            return testDOMCache(page);
    184251
    185252        g_assert_not_reached();
     
    193260    REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/insertion");
    194261    REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/tag-names");
     262    REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/dom-cache");
    195263}
    196264
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMXPathNSResolverTest.cpp

    r176563 r180214  
    6565        WebKitDOMElement* documentElement = webkit_dom_document_get_document_element(document);
    6666        g_assert(WEBKIT_DOM_IS_ELEMENT(documentElement));
     67        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(documentElement));
    6768
    68         WebKitDOMXPathResult* result = webkit_dom_document_evaluate(document, "foo:child/text()", WEBKIT_DOM_NODE(documentElement), resolver, WEBKIT_DOM_XPATH_RESULT_ORDERED_NODE_ITERATOR_TYPE, nullptr, nullptr);
    69         g_assert(WEBKIT_DOM_IS_XPATH_RESULT(result));
     69        GRefPtr<WebKitDOMXPathResult> result = adoptGRef(webkit_dom_document_evaluate(document, "foo:child/text()", WEBKIT_DOM_NODE(documentElement), resolver, WEBKIT_DOM_XPATH_RESULT_ORDERED_NODE_ITERATOR_TYPE, nullptr, nullptr));
     70        g_assert(WEBKIT_DOM_IS_XPATH_RESULT(result.get()));
     71        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(result.get()));
    7072
    71         WebKitDOMNode* nodeResult = webkit_dom_xpath_result_iterate_next(result, nullptr);
     73        WebKitDOMNode* nodeResult = webkit_dom_xpath_result_iterate_next(result.get(), nullptr);
    7274        g_assert(WEBKIT_DOM_IS_NODE(nodeResult));
     75        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(nodeResult));
    7376
    7477        GUniquePtr<char> nodeValue(webkit_dom_node_get_node_value(nodeResult));
     
    8083        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
    8184        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
     85        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
    8286
    83         WebKitDOMXPathNSResolver* resolver = webkit_dom_document_create_ns_resolver(document, WEBKIT_DOM_NODE(webkit_dom_document_get_document_element(document)));
    84         g_assert(WEBKIT_DOM_IS_XPATH_NS_RESOLVER(resolver));
    85         evaluateFooChildTextAndCheckResult(document, resolver);
     87        GRefPtr<WebKitDOMXPathNSResolver> resolver = adoptGRef(webkit_dom_document_create_ns_resolver(document, WEBKIT_DOM_NODE(webkit_dom_document_get_document_element(document))));
     88        g_assert(WEBKIT_DOM_IS_XPATH_NS_RESOLVER(resolver.get()));
     89        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(resolver.get()));
     90        evaluateFooChildTextAndCheckResult(document, resolver.get());
    8691
    8792        return true;
     
    9297        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
    9398        g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
     99        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
    94100
    95101        GRefPtr<WebKitDOMXPathNSResolver> resolver = adoptGRef(WEBKIT_DOM_XPATH_NS_RESOLVER(g_object_new(webkit_xpath_ns_resolver_get_type(), nullptr)));
     102        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(resolver.get()));
    96103        evaluateFooChildTextAndCheckResult(document, resolver.get());
    97104
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNode.cpp

    r176563 r180214  
    6060}
    6161
     62static void testWebKitDOMObjectCache(WebViewTest* test, gconstpointer)
     63{
     64    static const char* testHTML = "<html><body><div id='container'><p>DOM Cache test</p><a id='link href='#'>link</a></div></body></html>";
     65    test->loadHtml(testHTML, nullptr);
     66    test->waitUntilLoadFinished();
     67
     68    g_assert(test->runWebProcessTest("WebKitDOMNode", "dom-cache"));
     69}
     70
     71
    6272void beforeAll()
    6373{
     
    6575    WebViewTest::add("WebKitDOMNode", "insertion", testWebKitDOMNodeInsertion);
    6676    WebViewTest::add("WebKitDOMNode", "tag-names", testWebKitDOMNodeTagNames);
     77    WebViewTest::add("WebKitDOMNode", "dom-cache", testWebKitDOMObjectCache);
    6778}
    6879
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp

    r176393 r180214  
    103103    // FIXME: Too much code just to send a message, we need convenient custom API for this.
    104104    WebKitDOMDocument* document = webkit_web_page_get_dom_document(webPage);
    105     WebKitDOMDOMWindow* window = webkit_dom_document_get_default_view(document);
    106     if (WebKitDOMWebKitNamespace* webkit = webkit_dom_dom_window_get_webkit_namespace(window)) {
     105    GRefPtr<WebKitDOMDOMWindow> window = adoptGRef(webkit_dom_document_get_default_view(document));
     106    if (WebKitDOMWebKitNamespace* webkit = webkit_dom_dom_window_get_webkit_namespace(window.get())) {
    107107        WebKitDOMUserMessageHandlersNamespace* messageHandlers = webkit_dom_webkit_namespace_get_message_handlers(webkit);
    108108        if (WebKitDOMUserMessageHandler* handler = webkit_dom_user_message_handlers_namespace_get_handler(messageHandlers, "dom"))
     
    110110    }
    111111
    112     webkit_dom_dom_window_webkit_message_handlers_post_message(window, "dom-convenience", "DocumentLoaded");
     112    webkit_dom_dom_window_webkit_message_handlers_post_message(window.get(), "dom-convenience", "DocumentLoaded");
    113113
    114114    gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection");
Note: See TracChangeset for help on using the changeset viewer.