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

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, 11 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
« no previous file with comments | « Source/web/WebFrameImpl.h ('k') | Source/web/WebViewImpl.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 in a pre-order depth-first
65 // 62 // traversal. Note that child node order may not match DOM node order!
66 // Frame going away causes the FrameLoader to get deleted. In FrameLoader's 63 // detachFromParent() calls FrameLoaderClient::detachedFromParent(), which calls
67 // destructor, it notifies its client with frameLoaderDestroyed. This derefs 64 // WebFrame::frameDetached(). This triggers WebFrame to clear its reference to
68 // the WebFrame and will cause it to be deleted (unless an external someone 65 // Frame, and also notifies the embedder via WebFrameClient that the frame is
69 // is also holding a reference). 66 // detached. Most embedders will invoke close() on the WebFrame at this point,
67 // triggering its deletion unless something else is still retaining a reference.
70 // 68 //
71 // Thie client is expected to be set whenever the WebFrameImpl is attached to 69 // Thie client is expected to be set whenever the WebFrameImpl is attached to
72 // the DOM. 70 // the DOM.
73 71
74 #include "config.h" 72 #include "config.h"
75 #include "WebFrameImpl.h" 73 #include "WebFrameImpl.h"
76 74
77 #include <algorithm> 75 #include <algorithm>
78 #include "AssociatedURLLoader.h" 76 #include "AssociatedURLLoader.h"
79 #include "DOMUtilitiesPrivate.h" 77 #include "DOMUtilitiesPrivate.h"
(...skipping 2013 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 { 2091 {
2094 return WebFrameImpl::create(client, generateEmbedderIdentifier()); 2092 return WebFrameImpl::create(client, generateEmbedderIdentifier());
2095 } 2093 }
2096 2094
2097 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde ntifier) 2095 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde ntifier)
2098 { 2096 {
2099 return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef(); 2097 return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef();
2100 } 2098 }
2101 2099
2102 WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier) 2100 WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier)
2103 : FrameDestructionObserver(0) 2101 : m_frameInit(WebFrameInit::create(this, embedderIdentifier))
2104 , m_frameInit(WebFrameInit::create(this, embedderIdentifier))
2105 , m_client(client) 2102 , m_client(client)
2106 , m_permissionClient(0) 2103 , m_permissionClient(0)
2107 , m_currentActiveMatchFrame(0) 2104 , m_currentActiveMatchFrame(0)
2108 , m_activeMatchIndexInCurrentFrame(-1) 2105 , m_activeMatchIndexInCurrentFrame(-1)
2109 , m_locatingActiveRect(false) 2106 , m_locatingActiveRect(false)
2110 , m_resumeScopingFromRange(0) 2107 , m_resumeScopingFromRange(0)
2111 , m_lastMatchCount(-1) 2108 , m_lastMatchCount(-1)
2112 , m_totalMatchCount(-1) 2109 , m_totalMatchCount(-1)
2113 , m_framesScopingCount(-1) 2110 , m_framesScopingCount(-1)
2114 , m_findRequestIdentifier(-1) 2111 , m_findRequestIdentifier(-1)
2115 , m_scopingInProgress(false) 2112 , m_scopingInProgress(false)
2116 , m_lastFindRequestCompletedWithNoMatches(false) 2113 , m_lastFindRequestCompletedWithNoMatches(false)
2117 , m_nextInvalidateAfter(0) 2114 , m_nextInvalidateAfter(0)
2118 , m_findMatchMarkersVersion(0) 2115 , m_findMatchMarkersVersion(0)
2119 , m_findMatchRectsAreValid(false) 2116 , m_findMatchRectsAreValid(false)
2120 , m_inputEventsScaleFactorForEmulation(1) 2117 , m_inputEventsScaleFactorForEmulation(1)
2121 { 2118 {
2122 blink::Platform::current()->incrementStatsCounter(webFrameActiveCount); 2119 blink::Platform::current()->incrementStatsCounter(webFrameActiveCount);
2123 frameCount++; 2120 frameCount++;
2124 } 2121 }
2125 2122
2126 WebFrameImpl::~WebFrameImpl() 2123 WebFrameImpl::~WebFrameImpl()
2127 { 2124 {
2128 blink::Platform::current()->decrementStatsCounter(webFrameActiveCount); 2125 blink::Platform::current()->decrementStatsCounter(webFrameActiveCount);
2129 frameCount--; 2126 frameCount--;
2130 2127
2131 cancelPendingScopingEffort(); 2128 cancelPendingScopingEffort();
2132 } 2129 }
2133 2130
2134 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame) 2131 void WebFrameImpl::setWebCoreFrame(PassRefPtr<WebCore::Frame> frame)
2135 { 2132 {
2136 ASSERT(frame); 2133 m_frame = frame;
2137 observeFrame(frame);
2138 } 2134 }
2139 2135
2140 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page) 2136 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page)
2141 { 2137 {
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()); 2138 m_frameInit->setFrameHost(&page->frameHost());
2146 RefPtr<Frame> mainFrame = Frame::create(m_frameInit); 2139 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 2140
2153 // We must call init() after m_frame is assigned because it is referenced 2141 // We must call init() after m_frame is assigned because it is referenced
2154 // during init(). 2142 // during init().
2155 frame()->init(); 2143 m_frame->init();
2156 } 2144 }
2157 2145
2158 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement) 2146 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement)
2159 { 2147 {
2160 ASSERT(m_client); 2148 ASSERT(m_client);
2161 WebFrameImpl* webframe = toWebFrameImpl(m_client->createChildFrame(this, req uest.frameName())); 2149 WebFrameImpl* webframe = toWebFrameImpl(m_client->createChildFrame(this, req uest.frameName()));
2162 2150
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()); 2151 webframe->m_frameInit->setFrameHost(frame()->host());
2169 webframe->m_frameInit->setOwnerElement(ownerElement); 2152 webframe->m_frameInit->setOwnerElement(ownerElement);
2170 RefPtr<Frame> childFrame = Frame::create(webframe->m_frameInit); 2153 RefPtr<Frame> childFrame = Frame::create(webframe->m_frameInit);
2171 webframe->setWebCoreFrame(childFrame.get()); 2154 webframe->setWebCoreFrame(childFrame);
2172 2155
2173 childFrame->tree().setName(request.frameName()); 2156 childFrame->tree().setName(request.frameName());
2174 2157
2175 frame()->tree().appendChild(childFrame); 2158 frame()->tree().appendChild(childFrame);
2176 2159
2177 // Frame::init() can trigger onload event in the parent frame, 2160 // Frame::init() can trigger onload event in the parent frame,
2178 // which may detach this frame and trigger a null-pointer access 2161 // which may detach this frame and trigger a null-pointer access
2179 // in FrameTree::removeChild. Move init() after appendChild call 2162 // in FrameTree::removeChild. Move init() after appendChild call
2180 // so that webframe->mFrame is in the tree before triggering 2163 // so that webframe->mFrame is in the tree before triggering
2181 // onload event handler. 2164 // onload event handler.
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 ScriptValue result = frame()->script().executeScriptInMainWorldAndReturnValu e(ScriptSourceCode(script)); 2475 ScriptValue result = frame()->script().executeScriptInMainWorldAndReturnValu e(ScriptSourceCode(script));
2493 2476
2494 String scriptResult; 2477 String scriptResult;
2495 if (!result.getString(scriptResult)) 2478 if (!result.getString(scriptResult))
2496 return; 2479 return;
2497 2480
2498 if (!frame()->navigationScheduler().locationChangePending()) 2481 if (!frame()->navigationScheduler().locationChangePending())
2499 frame()->document()->loader()->replaceDocument(scriptResult, ownerDocume nt.get()); 2482 frame()->document()->loader()->replaceDocument(scriptResult, ownerDocume nt.get());
2500 } 2483 }
2501 2484
2502 void WebFrameImpl::willDetachFrameHost() 2485 void WebFrameImpl::willDetachParent()
2503 { 2486 {
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 2487 // Do not expect string scoping results from any frames that got detached
2509 // in the middle of the operation. 2488 // in the middle of the operation.
2510 if (m_scopingInProgress) { 2489 if (m_scopingInProgress) {
2511 2490
2512 // There is a possibility that the frame being detached was the only 2491 // 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. 2492 // pending one. We need to make sure final replies can be sent.
2514 flushCurrentScopingEffort(m_findRequestIdentifier); 2493 flushCurrentScopingEffort(m_findRequestIdentifier);
2515 2494
2516 cancelPendingScopingEffort(); 2495 cancelPendingScopingEffort();
2517 } 2496 }
2518 } 2497 }
2519 2498
2520 } // namespace blink 2499 } // namespace blink
OLDNEW
« no previous file with comments | « Source/web/WebFrameImpl.h ('k') | Source/web/WebViewImpl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698