| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |