Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1274)

Side by Side Diff: Source/web/WebFrameImpl.cpp

Issue 117493002: Invert the owning relationship between WebFrame and Frame. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 17 matching lines...) Expand all
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 // How ownership works 31 // How ownership works
32 // ------------------- 32 // -------------------
33 // 33 //
34 // Big oh represents a refcounted relationship: owner O--- ownee 34 // Big oh represents a refcounted relationship: owner O--- ownee
35 // 35 //
36 // WebView (for the toplevel frame only) 36 // WebView (for the toplevel frame only)
37 // O 37 // O
38 // | 38 // | WebFrame
39 // | O
40 // | |
39 // Page O------- Frame (m_mainFrame) O-------O FrameView 41 // Page O------- Frame (m_mainFrame) O-------O FrameView
40 // || 42 // ||
41 // || 43 // ||
42 // FrameLoader O-------- WebFrame (via FrameLoaderClient) 44 // FrameLoader
43 // 45 //
44 // FrameLoader and Frame are formerly one object that was split apart because 46 // FrameLoader and Frame are formerly one object that was split apart because
45 // it got too big. They basically have the same lifetime, hence the double line. 47 // it got too big. They basically have the same lifetime, hence the double line.
46 // 48 //
47 // WebFrame is refcounted and has one ref on behalf of the FrameLoader/Frame. 49 // From the perspective of the embedder, WebFrame is simply an object that it
48 // This is not a normal reference counted pointer because that would require 50 // allocates by calling WebFrame::create() and must be freed by calling close().
49 // changing WebKit code that we don't control. Instead, it is created with this 51 // Internally, WebFrame is actually refcounted and it holds a reference to its
50 // ref initially and it is removed when the FrameLoader is getting destroyed. 52 // corresponding Frame in WebCore.
51 //
52 // WebFrames are created in two places, first in WebViewImpl when the root
53 // frame is created, and second in WebFrame::createChildFrame when sub-frames
54 // are created. WebKit will hook up this object to the FrameLoader/Frame
55 // and the refcount will be correct.
56 // 53 //
57 // How frames are destroyed 54 // How frames are destroyed
58 // ------------------------ 55 // ------------------------
59 // 56 //
60 // The main frame is never destroyed and is re-used. The FrameLoader is re-used 57 // The main frame is never destroyed and is re-used. The FrameLoader is re-used
61 // and a reference to the main frame is kept by the Page. 58 // and a reference to the main frame is kept by the Page.
62 // 59 //
63 // When frame content is replaced, all subframes are destroyed. This happens 60 // When frame content is replaced, all subframes are destroyed. This happens
64 // in FrameLoader::detachFromParent for each subframe. 61 // in FrameLoader::detachFromParent for each subframe. detachFromParent()
eseidel 2013/12/28 01:18:40 Might be nice to know the call order of detachFrom
dcheng 2013/12/28 01:51:05 Done.
65 // 62 // calls FrameLoaderClient::detachedFromParent(), which calls
66 // Frame going away causes the FrameLoader to get deleted. In FrameLoader's 63 // WebFrame::frameDetached(). This triggers WebFrame to clear its reference to
67 // destructor, it notifies its client with frameLoaderDestroyed. This derefs 64 // Frame, and also notifies the embedder via WebFrameClient that the frame is
68 // the WebFrame and will cause it to be deleted (unless an external someone 65 // detached. Most embedders will invoke close() on the WebFrame at this point,
69 // is also holding a reference). 66 // triggering its deletion unless something else is still retaining a reference.
70 // 67 //
71 // Thie client is expected to be set whenever the WebFrameImpl is attached to 68 // Thie client is expected to be set whenever the WebFrameImpl is attached to
72 // the DOM. 69 // the DOM.
73 70
74 #include "config.h" 71 #include "config.h"
75 #include "WebFrameImpl.h" 72 #include "WebFrameImpl.h"
76 73
77 #include <algorithm> 74 #include <algorithm>
78 #include "AssociatedURLLoader.h" 75 #include "AssociatedURLLoader.h"
79 #include "DOMUtilitiesPrivate.h" 76 #include "DOMUtilitiesPrivate.h"
(...skipping 2013 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 { 2090 {
2094 return WebFrameImpl::create(client, generateEmbedderIdentifier()); 2091 return WebFrameImpl::create(client, generateEmbedderIdentifier());
2095 } 2092 }
2096 2093
2097 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde ntifier) 2094 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde ntifier)
2098 { 2095 {
2099 return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef(); 2096 return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef();
2100 } 2097 }
2101 2098
2102 WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier) 2099 WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier)
2103 : FrameDestructionObserver(0) 2100 : m_frameInit(WebFrameInit::create(this, embedderIdentifier))
2104 , m_frameInit(WebFrameInit::create(this, embedderIdentifier))
2105 , m_client(client) 2101 , m_client(client)
2106 , m_permissionClient(0) 2102 , m_permissionClient(0)
2107 , m_currentActiveMatchFrame(0) 2103 , m_currentActiveMatchFrame(0)
2108 , m_activeMatchIndexInCurrentFrame(-1) 2104 , m_activeMatchIndexInCurrentFrame(-1)
2109 , m_locatingActiveRect(false) 2105 , m_locatingActiveRect(false)
2110 , m_resumeScopingFromRange(0) 2106 , m_resumeScopingFromRange(0)
2111 , m_lastMatchCount(-1) 2107 , m_lastMatchCount(-1)
2112 , m_totalMatchCount(-1) 2108 , m_totalMatchCount(-1)
2113 , m_framesScopingCount(-1) 2109 , m_framesScopingCount(-1)
2114 , m_findRequestIdentifier(-1) 2110 , m_findRequestIdentifier(-1)
2115 , m_scopingInProgress(false) 2111 , m_scopingInProgress(false)
2116 , m_lastFindRequestCompletedWithNoMatches(false) 2112 , m_lastFindRequestCompletedWithNoMatches(false)
2117 , m_nextInvalidateAfter(0) 2113 , m_nextInvalidateAfter(0)
2118 , m_findMatchMarkersVersion(0) 2114 , m_findMatchMarkersVersion(0)
2119 , m_findMatchRectsAreValid(false) 2115 , m_findMatchRectsAreValid(false)
2120 , m_inputEventsScaleFactorForEmulation(1) 2116 , m_inputEventsScaleFactorForEmulation(1)
2121 { 2117 {
2122 blink::Platform::current()->incrementStatsCounter(webFrameActiveCount); 2118 blink::Platform::current()->incrementStatsCounter(webFrameActiveCount);
2123 frameCount++; 2119 frameCount++;
2124 } 2120 }
2125 2121
2126 WebFrameImpl::~WebFrameImpl() 2122 WebFrameImpl::~WebFrameImpl()
2127 { 2123 {
2128 blink::Platform::current()->decrementStatsCounter(webFrameActiveCount); 2124 blink::Platform::current()->decrementStatsCounter(webFrameActiveCount);
2129 frameCount--; 2125 frameCount--;
2130 2126
2131 cancelPendingScopingEffort(); 2127 cancelPendingScopingEffort();
2132 } 2128 }
2133 2129
2134 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame) 2130 void WebFrameImpl::setWebCoreFrame(PassRefPtr<WebCore::Frame> frame)
2135 { 2131 {
2136 ASSERT(frame); 2132 m_frame = frame;
2137 observeFrame(frame);
2138 } 2133 }
2139 2134
2140 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page) 2135 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page)
2141 { 2136 {
2142 // FIXME: This whole function can go away once ownerhip of WebFrame is rever sed.
2143 // Page should create it's main WebFrame, not have FrameLoader do it only
2144 // to have to mark the frame as main later.
2145 m_frameInit->setFrameHost(&page->frameHost()); 2137 m_frameInit->setFrameHost(&page->frameHost());
2146 RefPtr<Frame> mainFrame = Frame::create(m_frameInit); 2138 setWebCoreFrame(Frame::create(m_frameInit));
2147 setWebCoreFrame(mainFrame.get());
2148
2149 // Add reference on behalf of FrameLoader. See comments in
2150 // WebFrameLoaderClient::frameLoaderDestroyed for more info.
2151 ref();
2152 2139
2153 // We must call init() after m_frame is assigned because it is referenced 2140 // We must call init() after m_frame is assigned because it is referenced
2154 // during init(). 2141 // during init().
2155 frame()->init(); 2142 m_frame->init();
2156 } 2143 }
2157 2144
2158 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement) 2145 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement)
2159 { 2146 {
2160 ASSERT(m_client); 2147 ASSERT(m_client);
2161 WebFrameImpl* webframe = toWebFrameImpl(m_client->createChildFrame(this, req uest.frameName())); 2148 WebFrameImpl* webframe = toWebFrameImpl(m_client->createChildFrame(this, req uest.frameName()));
2162 2149
2163 // Add an extra ref on behalf of the page/FrameLoader, which references the
2164 // WebFrame via the FrameLoaderClient interface. See the comment at the top
2165 // of this file for more info.
2166 webframe->ref();
2167
2168 webframe->m_frameInit->setFrameHost(frame()->host()); 2150 webframe->m_frameInit->setFrameHost(frame()->host());
2169 webframe->m_frameInit->setOwnerElement(ownerElement); 2151 webframe->m_frameInit->setOwnerElement(ownerElement);
2170 RefPtr<Frame> childFrame = Frame::create(webframe->m_frameInit); 2152 RefPtr<Frame> childFrame = Frame::create(webframe->m_frameInit);
2171 webframe->setWebCoreFrame(childFrame.get()); 2153 webframe->setWebCoreFrame(childFrame);
2172 2154
2173 childFrame->tree().setName(request.frameName()); 2155 childFrame->tree().setName(request.frameName());
2174 2156
2175 frame()->tree().appendChild(childFrame); 2157 frame()->tree().appendChild(childFrame);
2176 2158
2177 // Frame::init() can trigger onload event in the parent frame, 2159 // Frame::init() can trigger onload event in the parent frame,
2178 // which may detach this frame and trigger a null-pointer access 2160 // which may detach this frame and trigger a null-pointer access
2179 // in FrameTree::removeChild. Move init() after appendChild call 2161 // in FrameTree::removeChild. Move init() after appendChild call
2180 // so that webframe->mFrame is in the tree before triggering 2162 // so that webframe->mFrame is in the tree before triggering
2181 // onload event handler. 2163 // onload event handler.
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 ScriptValue result = frame()->script().executeScriptInMainWorldAndReturnValu e(ScriptSourceCode(script)); 2474 ScriptValue result = frame()->script().executeScriptInMainWorldAndReturnValu e(ScriptSourceCode(script));
2493 2475
2494 String scriptResult; 2476 String scriptResult;
2495 if (!result.getString(scriptResult)) 2477 if (!result.getString(scriptResult))
2496 return; 2478 return;
2497 2479
2498 if (!frame()->navigationScheduler().locationChangePending()) 2480 if (!frame()->navigationScheduler().locationChangePending())
2499 frame()->document()->loader()->replaceDocument(scriptResult, ownerDocume nt.get()); 2481 frame()->document()->loader()->replaceDocument(scriptResult, ownerDocume nt.get());
2500 } 2482 }
2501 2483
2502 void WebFrameImpl::willDetachFrameHost() 2484 void WebFrameImpl::willDetachParent()
2503 { 2485 {
2504 // FIXME: This should never be called if the Frame has already been detached ?
2505 if (!frame() || !frame()->page())
2506 return;
2507
2508 // Do not expect string scoping results from any frames that got detached 2486 // Do not expect string scoping results from any frames that got detached
2509 // in the middle of the operation. 2487 // in the middle of the operation.
2510 if (m_scopingInProgress) { 2488 if (m_scopingInProgress) {
2511 2489
2512 // There is a possibility that the frame being detached was the only 2490 // There is a possibility that the frame being detached was the only
2513 // pending one. We need to make sure final replies can be sent. 2491 // pending one. We need to make sure final replies can be sent.
2514 flushCurrentScopingEffort(m_findRequestIdentifier); 2492 flushCurrentScopingEffort(m_findRequestIdentifier);
2515 2493
2516 cancelPendingScopingEffort(); 2494 cancelPendingScopingEffort();
2517 } 2495 }
2518 } 2496 }
2519 2497
2520 } // namespace blink 2498 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698