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

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

Issue 23506013: Make the embedder responsible for creating the WebFrame (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: address comments Created 7 years, 3 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
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 // 43 //
44 // FrameLoader and Frame are formerly one object that was split apart because 44 // 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. 45 // it got too big. They basically have the same lifetime, hence the double line.
46 // 46 //
47 // WebFrame is refcounted and has one ref on behalf of the FrameLoader/Frame. 47 // WebFrame is refcounted and has one ref on behalf of the FrameLoader/Frame.
48 // This is not a normal reference counted pointer because that would require 48 // This is not a normal reference counted pointer because that would require
49 // changing WebKit code that we don't control. Instead, it is created with this 49 // changing WebKit code that we don't control. Instead, it is created with this
50 // ref initially and it is removed when the FrameLoader is getting destroyed. 50 // ref initially and it is removed when the FrameLoader is getting destroyed.
51 // 51 //
52 // WebFrames are created in two places, first in WebViewImpl when the root 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 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 54 // are created. WebKit will hook up this object to the FrameLoader/Frame
55 // and the refcount will be correct. 55 // and the refcount will be correct.
56 // 56 //
57 // How frames are destroyed 57 // How frames are destroyed
58 // ------------------------ 58 // ------------------------
59 // 59 //
60 // The main frame is never destroyed and is re-used. The FrameLoader is re-used 60 // 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. 61 // and a reference to the main frame is kept by the Page.
62 // 62 //
63 // When frame content is replaced, all subframes are destroyed. This happens 63 // When frame content is replaced, all subframes are destroyed. This happens
64 // in FrameLoader::detachFromParent for each subframe. 64 // in FrameLoader::detachFromParent for each subframe.
65 // 65 //
66 // Frame going away causes the FrameLoader to get deleted. In FrameLoader's 66 // Frame going away causes the FrameLoader to get deleted. In FrameLoader's
67 // destructor, it notifies its client with frameLoaderDestroyed. This calls 67 // destructor, it notifies its client with frameLoaderDestroyed. This derefs
68 // WebFrame::Closing and then derefs the WebFrame and will cause it to be 68 // the WebFrame and will cause it to be deleted (unless an external someone
69 // deleted (unless an external someone is also holding a reference). 69 // is also holding a reference).
70 //
71 // Thie client is expected to be set whenever the WebFrameImpl is attached to
72 // the DOM.
70 73
71 #include "config.h" 74 #include "config.h"
72 #include "WebFrameImpl.h" 75 #include "WebFrameImpl.h"
73 76
74 #include "AssociatedURLLoader.h" 77 #include "AssociatedURLLoader.h"
75 #include "DOMUtilitiesPrivate.h" 78 #include "DOMUtilitiesPrivate.h"
76 #include "EventListenerWrapper.h" 79 #include "EventListenerWrapper.h"
77 #include "FindInPageCoordinates.h" 80 #include "FindInPageCoordinates.h"
78 #include "HTMLNames.h" 81 #include "HTMLNames.h"
79 #include "PageOverlay.h" 82 #include "PageOverlay.h"
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 if (output.length() >= maxChars - frameSeparatorLength) 262 if (output.length() >= maxChars - frameSeparatorLength)
260 return; 263 return;
261 264
262 output.append(frameSeparator, frameSeparatorLength); 265 output.append(frameSeparator, frameSeparatorLength);
263 frameContentAsPlainText(maxChars, curChild, output); 266 frameContentAsPlainText(maxChars, curChild, output);
264 if (output.length() >= maxChars) 267 if (output.length() >= maxChars)
265 return; // Filled up the buffer. 268 return; // Filled up the buffer.
266 } 269 }
267 } 270 }
268 271
269 static long long generateFrameIdentifier()
270 {
271 static long long next = 0;
272 return ++next;
273 }
274
275 WebPluginContainerImpl* WebFrameImpl::pluginContainerFromFrame(Frame* frame) 272 WebPluginContainerImpl* WebFrameImpl::pluginContainerFromFrame(Frame* frame)
276 { 273 {
277 if (!frame) 274 if (!frame)
278 return 0; 275 return 0;
279 if (!frame->document() || !frame->document()->isPluginDocument()) 276 if (!frame->document() || !frame->document()->isPluginDocument())
280 return 0; 277 return 0;
281 PluginDocument* pluginDocument = toPluginDocument(frame->document()); 278 PluginDocument* pluginDocument = toPluginDocument(frame->document());
282 return toPluginContainerImpl(pluginDocument->pluginWidget()); 279 return toPluginContainerImpl(pluginDocument->pluginWidget());
283 } 280 }
284 281
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 WebFrame* WebFrame::frameForContext(v8::Handle<v8::Context> context) 526 WebFrame* WebFrame::frameForContext(v8::Handle<v8::Context> context)
530 { 527 {
531 return WebFrameImpl::fromFrame(toFrameIfNotDetached(context)); 528 return WebFrameImpl::fromFrame(toFrameIfNotDetached(context));
532 } 529 }
533 530
534 WebFrame* WebFrame::fromFrameOwnerElement(const WebElement& element) 531 WebFrame* WebFrame::fromFrameOwnerElement(const WebElement& element)
535 { 532 {
536 return WebFrameImpl::fromFrameOwnerElement(PassRefPtr<Element>(element).get( )); 533 return WebFrameImpl::fromFrameOwnerElement(PassRefPtr<Element>(element).get( ));
537 } 534 }
538 535
536 void WebFrameImpl::close()
537 {
538 m_client = 0;
539 deref(); // Balances ref() acquired in WebFrame::create
540 }
541
539 WebString WebFrameImpl::uniqueName() const 542 WebString WebFrameImpl::uniqueName() const
540 { 543 {
541 return frame()->tree()->uniqueName(); 544 return frame()->tree()->uniqueName();
542 } 545 }
543 546
544 WebString WebFrameImpl::assignedName() const 547 WebString WebFrameImpl::assignedName() const
545 { 548 {
546 return frame()->tree()->name(); 549 return frame()->tree()->name();
547 } 550 }
548 551
549 void WebFrameImpl::setName(const WebString& name) 552 void WebFrameImpl::setName(const WebString& name)
550 { 553 {
551 frame()->tree()->setName(name); 554 frame()->tree()->setName(name);
552 } 555 }
553 556
554 long long WebFrameImpl::identifier() const 557 long long WebFrameImpl::embedderIdentifier() const
555 { 558 {
556 return m_identifier; 559 return m_embedderIdentifier;
557 } 560 }
558 561
559 WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypesMask) const 562 WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypesMask) const
560 { 563 {
561 // The URL to the icon may be in the header. As such, only 564 // The URL to the icon may be in the header. As such, only
562 // ask the loader for the icon if it's finished loading. 565 // ask the loader for the icon if it's finished loading.
563 if (frame()->loader()->state() == FrameStateComplete) 566 if (frame()->loader()->state() == FrameStateComplete)
564 return frame()->loader()->icon()->urlsForTypes(iconTypesMask); 567 return frame()->loader()->icon()->urlsForTypes(iconTypesMask);
565 return WebVector<WebIconURL>(); 568 return WebVector<WebIconURL>();
566 } 569 }
(...skipping 1499 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const 2069 WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const
2067 { 2070 {
2068 if (!frame()) 2071 if (!frame())
2069 return WebString(); 2072 return WebString();
2070 2073
2071 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesD ebugInfo : LayerTreeNormal)); 2074 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesD ebugInfo : LayerTreeNormal));
2072 } 2075 }
2073 2076
2074 // WebFrameImpl public --------------------------------------------------------- 2077 // WebFrameImpl public ---------------------------------------------------------
2075 2078
2076 PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) 2079 WebFrame* WebFrame::create(WebFrameClient* client)
2077 { 2080 {
2078 return adoptRef(new WebFrameImpl(client)); 2081 return WebFrameImpl::create(client);
2079 } 2082 }
2080 2083
2081 WebFrameImpl::WebFrameImpl(WebFrameClient* client) 2084 WebFrame* WebFrame::create(WebFrameClient* client, long long embedderIdentifier)
2085 {
2086 return WebFrameImpl::create(client, embedderIdentifier);
2087 }
2088
2089 long long WebFrame::generateEmbedderIdentifier()
2090 {
2091 static long long next = 0;
2092 // Assume that 64-bit will not wrap to -1.
2093 return ++next;
2094 }
2095
2096 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client)
2097 {
2098 return WebFrameImpl::create(client, generateEmbedderIdentifier());
2099 }
2100
2101 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde ntifier)
2102 {
2103 return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef();
2104 }
2105
2106 WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier)
2082 : FrameDestructionObserver(0) 2107 : FrameDestructionObserver(0)
2083 , m_frameLoaderClient(this) 2108 , m_frameLoaderClient(this)
2084 , m_client(client) 2109 , m_client(client)
2085 , m_currentActiveMatchFrame(0) 2110 , m_currentActiveMatchFrame(0)
2086 , m_activeMatchIndexInCurrentFrame(-1) 2111 , m_activeMatchIndexInCurrentFrame(-1)
2087 , m_locatingActiveRect(false) 2112 , m_locatingActiveRect(false)
2088 , m_resumeScopingFromRange(0) 2113 , m_resumeScopingFromRange(0)
2089 , m_lastMatchCount(-1) 2114 , m_lastMatchCount(-1)
2090 , m_totalMatchCount(-1) 2115 , m_totalMatchCount(-1)
2091 , m_framesScopingCount(-1) 2116 , m_framesScopingCount(-1)
2092 , m_findRequestIdentifier(-1) 2117 , m_findRequestIdentifier(-1)
2093 , m_scopingInProgress(false) 2118 , m_scopingInProgress(false)
2094 , m_lastFindRequestCompletedWithNoMatches(false) 2119 , m_lastFindRequestCompletedWithNoMatches(false)
2095 , m_nextInvalidateAfter(0) 2120 , m_nextInvalidateAfter(0)
2096 , m_findMatchMarkersVersion(0) 2121 , m_findMatchMarkersVersion(0)
2097 , m_findMatchRectsAreValid(false) 2122 , m_findMatchRectsAreValid(false)
2098 , m_identifier(generateFrameIdentifier()) 2123 , m_embedderIdentifier(embedderIdentifier)
2099 , m_inSameDocumentHistoryLoad(false) 2124 , m_inSameDocumentHistoryLoad(false)
2100 { 2125 {
2101 WebKit::Platform::current()->incrementStatsCounter(webFrameActiveCount); 2126 WebKit::Platform::current()->incrementStatsCounter(webFrameActiveCount);
2102 frameCount++; 2127 frameCount++;
2103 } 2128 }
2104 2129
2105 WebFrameImpl::~WebFrameImpl() 2130 WebFrameImpl::~WebFrameImpl()
2106 { 2131 {
2107 WebKit::Platform::current()->decrementStatsCounter(webFrameActiveCount); 2132 WebKit::Platform::current()->decrementStatsCounter(webFrameActiveCount);
2108 frameCount--; 2133 frameCount--;
2109 2134
2110 cancelPendingScopingEffort(); 2135 cancelPendingScopingEffort();
2111 } 2136 }
2112 2137
2113 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame) 2138 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame)
2114 { 2139 {
2115 ASSERT(frame); 2140 ASSERT(frame);
2116 observeFrame(frame); 2141 observeFrame(frame);
2117 } 2142 }
2118 2143
2119 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page) 2144 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page)
2120 { 2145 {
2121 RefPtr<Frame> mainFrame = Frame::create(page, 0, &m_frameLoaderClient); 2146 RefPtr<Frame> mainFrame = Frame::create(page, 0, &m_frameLoaderClient);
2122 setWebCoreFrame(mainFrame.get()); 2147 setWebCoreFrame(mainFrame.get());
2123 2148
2124 // Add reference on behalf of FrameLoader. See comments in 2149 // Add reference on behalf of FrameLoader. See comments in
2125 // WebFrameLoaderClient::frameLoaderDestroyed for more info. 2150 // WebFrameLoaderClient::frameLoaderDestroyed for more info.
2126 ref(); 2151 ref();
2127 2152
2128 // We must call init() after m_frame is assigned because it is referenced 2153 // We must call init() after m_frame is assigned because it is referenced
2129 // during init(). 2154 // during init().
2130 frame()->init(); 2155 frame()->init();
2131 } 2156 }
2132 2157
2133 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement) 2158 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement)
2134 { 2159 {
2135 RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(m_client))); 2160 ASSERT(m_client);
2161 WebFrameImpl* webframe = static_cast<WebFrameImpl*>(m_client->createChildFra me(this, request.frameName()));
2162
2163 // If the embedder is returning 0 from createChildFrame(), it has not been
2164 // updated to the new ownership semantics where the embedder creates the
2165 // WebFrame. In that case, fall back to the old logic where the
2166 // WebFrameImpl is created here and published back to the embedder. To
2167 // bridge between the two ownership semantics, webframeLifetimeHack is
2168 // needeed to balance out the refcounting.
2169 //
2170 // FIXME: Remove once all embedders return non-null from createChildFrame().
2171 RefPtr<WebFrameImpl> webframeLifetimeHack;
2172 bool mustCallDidCreateFrame = false;
2173 if (!webframe) {
2174 mustCallDidCreateFrame = true;
2175 webframeLifetimeHack = adoptRef(WebFrameImpl::create(m_client));
2176 webframe = webframeLifetimeHack.get();
2177 }
2136 2178
2137 // Add an extra ref on behalf of the Frame/FrameLoader, which references the 2179 // Add an extra ref on behalf of the Frame/FrameLoader, which references the
2138 // WebFrame via the FrameLoaderClient interface. See the comment at the top 2180 // WebFrame via the FrameLoaderClient interface. See the comment at the top
2139 // of this file for more info. 2181 // of this file for more info.
2140 webframe->ref(); 2182 webframe->ref();
2141 2183
2142 RefPtr<Frame> childFrame = Frame::create(frame()->page(), ownerElement, &web frame->m_frameLoaderClient); 2184 RefPtr<Frame> childFrame = Frame::create(frame()->page(), ownerElement, &web frame->m_frameLoaderClient);
2143 webframe->setWebCoreFrame(childFrame.get()); 2185 webframe->setWebCoreFrame(childFrame.get());
2144 2186
2145 childFrame->tree()->setName(request.frameName()); 2187 childFrame->tree()->setName(request.frameName());
2146 2188
2147 frame()->tree()->appendChild(childFrame); 2189 frame()->tree()->appendChild(childFrame);
2148 2190
2191 // FIXME: Remove once all embedders return non-null from createChildFrame().
2192 if (mustCallDidCreateFrame && m_client)
dcheng 2013/09/20 02:29:59 Just curious--why do we need to verify m_client is
awong 2013/09/20 23:57:14 You're right. That's vestigial. Fixed.
2193 m_client->didCreateFrame(this, webframe);
2194
2149 // Frame::init() can trigger onload event in the parent frame, 2195 // Frame::init() can trigger onload event in the parent frame,
2150 // which may detach this frame and trigger a null-pointer access 2196 // which may detach this frame and trigger a null-pointer access
2151 // in FrameTree::removeChild. Move init() after appendChild call 2197 // in FrameTree::removeChild. Move init() after appendChild call
2152 // so that webframe->mFrame is in the tree before triggering 2198 // so that webframe->mFrame is in the tree before triggering
2153 // onload event handler. 2199 // onload event handler.
2154 // Because the event handler may set webframe->mFrame to null, 2200 // Because the event handler may set webframe->mFrame to null,
2155 // it is necessary to check the value after calling init() and 2201 // it is necessary to check the value after calling init() and
2156 // return without loading URL. 2202 // return without loading URL.
2157 // (b:791612) 2203 // (b:791612)
2158 childFrame->init(); // create an empty document 2204 childFrame->init(); // create an empty document
2159 if (!childFrame->tree()->parent()) 2205 if (!childFrame->tree()->parent()) {
2206 if (m_client)
2207 m_client->frameDetached(webframe);
2160 return 0; 2208 return 0;
2209 }
2161 2210
2162 HistoryItem* parentItem = frame()->loader()->history()->currentItem(); 2211 HistoryItem* parentItem = frame()->loader()->history()->currentItem();
2163 HistoryItem* childItem = 0; 2212 HistoryItem* childItem = 0;
2164 // If we're moving in the back/forward list, we might want to replace the co ntent 2213 // If we're moving in the back/forward list, we might want to replace the co ntent
2165 // of this child frame with whatever was there at that point. 2214 // of this child frame with whatever was there at that point.
2166 if (parentItem && parentItem->children().size() && isBackForwardLoadType(fra me()->loader()->loadType()) && !frame()->document()->loadEventFinished()) 2215 if (parentItem && parentItem->children().size() && isBackForwardLoadType(fra me()->loader()->loadType()) && !frame()->document()->loadEventFinished())
2167 childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueNa me()); 2216 childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueNa me());
2168 2217
2169 if (childItem) 2218 if (childItem)
2170 childFrame->loader()->loadHistoryItem(childItem); 2219 childFrame->loader()->loadHistoryItem(childItem);
2171 else 2220 else
2172 childFrame->loader()->load(FrameLoadRequest(0, request.resourceRequest() , "_self")); 2221 childFrame->loader()->load(FrameLoadRequest(0, request.resourceRequest() , "_self"));
2173 2222
2174 // A synchronous navigation (about:blank) would have already processed 2223 // A synchronous navigation (about:blank) would have already processed
2175 // onload, so it is possible for the frame to have already been destroyed by 2224 // onload, so it is possible for the frame to have already been destroyed by
2176 // script in the page. 2225 // script in the page.
2177 if (!childFrame->tree()->parent()) 2226 if (!childFrame->tree()->parent()) {
2227 if (m_client)
2228 m_client->frameDetached(webframe);
2178 return 0; 2229 return 0;
2230 }
2179 2231
2180 if (m_client)
2181 m_client->didCreateFrame(this, webframe.get());
2182 2232
2183 return childFrame.release(); 2233 return childFrame.release();
2184 } 2234 }
2185 2235
2186 void WebFrameImpl::didChangeContentsSize(const IntSize& size) 2236 void WebFrameImpl::didChangeContentsSize(const IntSize& size)
2187 { 2237 {
2188 // This is only possible on the main frame. 2238 // This is only possible on the main frame.
2189 if (m_totalMatchCount > 0) { 2239 if (m_totalMatchCount > 0) {
2190 ASSERT(!parent()); 2240 ASSERT(!parent());
2191 ++m_findMatchMarkersVersion; 2241 ++m_findMatchMarkersVersion;
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 2526
2477 // There is a possibility that the frame being detached was the only 2527 // There is a possibility that the frame being detached was the only
2478 // pending one. We need to make sure final replies can be sent. 2528 // pending one. We need to make sure final replies can be sent.
2479 flushCurrentScopingEffort(m_findRequestIdentifier); 2529 flushCurrentScopingEffort(m_findRequestIdentifier);
2480 2530
2481 cancelPendingScopingEffort(); 2531 cancelPendingScopingEffort();
2482 } 2532 }
2483 } 2533 }
2484 2534
2485 } // namespace WebKit 2535 } // namespace WebKit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698