Changeset 180214 in webkit
- Timestamp:
- Feb 17, 2015 1:57:42 AM (9 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r180213 r180214 1 2015-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 1 45 2015-02-17 ChangSeok Oh <changseok.oh@collabora.com> 2 46 -
trunk/Source/WebCore/bindings/gobject/DOMObjectCache.cpp
r165618 r180214 1 1 /* 2 * Copyright (C) 2010 Igalia S.L.2 * Copyright (C) 2010, 2015 Igalia S.L. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 21 21 22 22 #include "Document.h" 23 #include "FrameDestructionObserver.h" 23 24 #include "Node.h" 24 25 #include <glib-object.h> 25 26 #include <wtf/HashMap.h> 27 #include <wtf/NeverDestroyed.h> 28 #include <wtf/Vector.h> 29 #include <wtf/gobject/GRefPtr.h> 26 30 27 31 namespace WebKit { 28 32 29 typedef struct { 33 struct 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 30 60 GObject* object; 31 WebCore::Frame* frame; 32 guint timesReturned; 33 } DOMObjectCacheData; 61 unsigned cacheReferences; 62 }; 34 63 35 typedef HashMap<void*, DOMObjectCacheData*> DOMObjectMap; 64 class DOMObjectCacheFrameObserver; 65 typedef HashMap<WebCore::Frame*, std::unique_ptr<DOMObjectCacheFrameObserver>> DOMObjectCacheFrameObserverMap; 66 67 static DOMObjectCacheFrameObserverMap& domObjectCacheFrameObservers() 68 { 69 static NeverDestroyed<DOMObjectCacheFrameObserverMap> map; 70 return map; 71 } 72 73 static 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 85 class DOMObjectCacheFrameObserver final: public WebCore::FrameDestructionObserver { 86 public: 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 105 private: 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 142 typedef HashMap<void*, std::unique_ptr<DOMObjectCacheData>> DOMObjectMap; 36 143 37 144 static DOMObjectMap& domObjects() 38 145 { 39 static DOMObjectMapstaticDOMObjects;146 static NeverDestroyed<DOMObjectMap> staticDOMObjects; 40 147 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();49 148 } 50 149 51 150 void DOMObjectCache::forget(void* objectHandle) 52 151 { 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); 117 154 } 118 155 … … 120 157 { 121 158 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; 130 160 } 131 161 132 void *DOMObjectCache::put(void* objectHandle, void* wrapper)162 void DOMObjectCache::put(void* objectHandle, void* wrapper) 133 163 { 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))); 144 167 } 145 168 146 void *DOMObjectCache::put(WebCore::Node* objectHandle, void* wrapper)169 void DOMObjectCache::put(WebCore::Node* objectHandle, void* wrapper) 147 170 { 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; 151 173 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)); 154 177 155 data->frame = getFrameFromHandle(objectHandle); 156 157 return wrapper; 178 if (WebCore::Frame* frame = objectHandle->document().frame()) 179 getOrCreateDOMObjectCacheFrameObserver(*frame).addObjectCacheData(*dataPtr); 158 180 } 159 181 -
trunk/Source/WebCore/bindings/gobject/DOMObjectCache.h
r95901 r180214 22 22 namespace WebCore { 23 23 class Node; 24 class Frame;25 24 }; 26 25 … … 29 28 public: 30 29 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); 34 32 static void forget(void* objectHandle); 35 ~DOMObjectCache();36 33 }; 37 34 } // namespace WebKit -
trunk/Tools/ChangeLog
r180211 r180214 1 2015-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 1 30 2015-02-16 Carlos Garcia Campos <cgarcia@igalia.com> 2 31 -
trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeFilterTest.cpp
r176563 r180214 67 67 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); 68 68 g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); 69 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); 69 70 70 71 WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root"); 71 72 g_assert(WEBKIT_DOM_IS_NODE(root)); 73 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root)); 72 74 73 75 // 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())); 77 80 78 81 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)); 80 84 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll)); 81 85 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); … … 86 90 // Input elements filter. 87 91 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)); 94 100 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput)); 95 101 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); … … 99 105 100 106 // 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)); 107 115 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput)); 108 116 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); … … 118 126 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); 119 127 g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); 128 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); 120 129 121 130 WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root"); 122 131 g_assert(WEBKIT_DOM_IS_NODE(root)); 132 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root)); 123 133 124 134 // 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())); 128 139 129 140 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)); 131 143 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll)); 132 144 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); … … 138 150 // Input elements filter. 139 151 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)); 146 160 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput)); 147 161 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); … … 152 166 153 167 // 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)); 160 176 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput)); 161 177 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); -
trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeTest.cpp
r177019 r180214 34 34 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); 35 35 g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); 36 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); 36 37 37 38 WebKitDOMHTMLHeadElement* head = webkit_dom_document_get_head(document); 38 39 g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(head)); 40 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(head)); 39 41 40 42 // Title, head's child. … … 42 44 GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(head))); 43 45 g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); 46 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); 44 47 g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); 45 48 WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0); 46 49 g_assert(WEBKIT_DOM_IS_HTML_TITLE_ELEMENT(node)); 50 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 47 51 48 52 // Body, Head sibling. 49 53 node = webkit_dom_node_get_next_sibling(WEBKIT_DOM_NODE(head)); 50 54 g_assert(WEBKIT_DOM_IS_HTML_BODY_ELEMENT(node)); 55 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 51 56 WebKitDOMHTMLBodyElement* body = WEBKIT_DOM_HTML_BODY_ELEMENT(node); 52 57 … … 57 62 node = webkit_dom_node_get_previous_sibling(WEBKIT_DOM_NODE(body)); 58 63 g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(node)); 64 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 59 65 60 66 // Body has 3 children. 61 67 g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); 62 68 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())); 63 71 unsigned long length = webkit_dom_node_list_get_length(list.get()); 64 72 g_assert_cmpint(length, ==, 3); … … 68 76 node = webkit_dom_node_list_item(list.get(), i); 69 77 g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(node)); 78 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 70 79 } 71 80 … … 82 91 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); 83 92 g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); 93 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); 84 94 85 95 WebKitDOMHTMLElement* body = webkit_dom_document_get_body(document); 86 96 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(body)); 97 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(body)); 87 98 88 99 // Body shouldn't have any children at this point. … … 95 106 WebKitDOMElement* p = webkit_dom_document_create_element(document, "P", 0); 96 107 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p)); 108 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p)); 97 109 webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), 0); 98 110 … … 101 113 GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); 102 114 g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); 115 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); 103 116 g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); 104 117 WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0); 105 118 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); 119 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 106 120 g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node)); 107 121 … … 109 123 WebKitDOMElement* div = webkit_dom_document_create_element(document, "DIV", 0); 110 124 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div)); 125 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div)); 111 126 webkit_dom_node_replace_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p), 0); 112 127 g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); 113 128 list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); 114 129 g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); 130 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); 115 131 g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); 116 132 node = webkit_dom_node_list_item(list.get(), 0); 117 133 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); 134 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 118 135 g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); 119 136 … … 122 139 list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); 123 140 g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); 141 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); 124 142 g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 0); 125 143 … … 127 145 div = webkit_dom_document_create_element(document, "DIV", 0); 128 146 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div)); 147 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div)); 129 148 webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), 0, 0); 130 149 g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); 131 150 list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); 132 151 g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); 152 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); 133 153 g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); 134 154 node = webkit_dom_node_list_item(list.get(), 0); 135 155 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); 156 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 136 157 g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); 137 158 … … 139 160 p = webkit_dom_document_create_element(document, "P", 0); 140 161 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p)); 162 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p)); 141 163 webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), WEBKIT_DOM_NODE(div), 0); 142 164 g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); 143 165 list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); 144 166 g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); 167 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); 145 168 g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 2); 146 169 node = webkit_dom_node_list_item(list.get(), 0); 147 170 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); 171 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 148 172 g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node)); 149 173 node = webkit_dom_node_list_item(list.get(), 1); 150 174 g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); 175 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 151 176 g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); 152 177 … … 160 185 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); 161 186 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()); 165 193 g_assert_cmpuint(nodeCount, ==, G_N_ELEMENTS(expectedTagNames)); 166 194 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); 168 196 g_assert(WEBKIT_DOM_IS_NODE(node)); 197 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); 169 198 GUniquePtr<char> tagName(webkit_dom_node_get_node_name(node)); 170 199 g_assert_cmpstr(tagName.get(), ==, expectedTagNames[i]); … … 172 201 173 202 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); 174 239 } 175 240 … … 182 247 if (!strcmp(testName, "tag-names")) 183 248 return testTagNames(page); 249 if (!strcmp(testName, "dom-cache")) 250 return testDOMCache(page); 184 251 185 252 g_assert_not_reached(); … … 193 260 REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/insertion"); 194 261 REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/tag-names"); 262 REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/dom-cache"); 195 263 } 196 264 -
trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMXPathNSResolverTest.cpp
r176563 r180214 65 65 WebKitDOMElement* documentElement = webkit_dom_document_get_document_element(document); 66 66 g_assert(WEBKIT_DOM_IS_ELEMENT(documentElement)); 67 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(documentElement)); 67 68 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())); 70 72 71 WebKitDOMNode* nodeResult = webkit_dom_xpath_result_iterate_next(result , nullptr);73 WebKitDOMNode* nodeResult = webkit_dom_xpath_result_iterate_next(result.get(), nullptr); 72 74 g_assert(WEBKIT_DOM_IS_NODE(nodeResult)); 75 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(nodeResult)); 73 76 74 77 GUniquePtr<char> nodeValue(webkit_dom_node_get_node_value(nodeResult)); … … 80 83 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); 81 84 g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); 85 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); 82 86 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()); 86 91 87 92 return true; … … 92 97 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); 93 98 g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); 99 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); 94 100 95 101 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())); 96 103 evaluateFooChildTextAndCheckResult(document, resolver.get()); 97 104 -
trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNode.cpp
r176563 r180214 60 60 } 61 61 62 static 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 62 72 void beforeAll() 63 73 { … … 65 75 WebViewTest::add("WebKitDOMNode", "insertion", testWebKitDOMNodeInsertion); 66 76 WebViewTest::add("WebKitDOMNode", "tag-names", testWebKitDOMNodeTagNames); 77 WebViewTest::add("WebKitDOMNode", "dom-cache", testWebKitDOMObjectCache); 67 78 } 68 79 -
trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp
r176393 r180214 103 103 // FIXME: Too much code just to send a message, we need convenient custom API for this. 104 104 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())) { 107 107 WebKitDOMUserMessageHandlersNamespace* messageHandlers = webkit_dom_webkit_namespace_get_message_handlers(webkit); 108 108 if (WebKitDOMUserMessageHandler* handler = webkit_dom_user_message_handlers_namespace_get_handler(messageHandlers, "dom")) … … 110 110 } 111 111 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"); 113 113 114 114 gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection");
Note: See TracChangeset
for help on using the changeset viewer.