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

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: wordmith a comment 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::identifier() const
555 { 558 {
556 return m_identifier; 559 return embedderIdentifier();
darin (slow to review) 2013/09/19 22:36:19 maybe identifier() should just be implemented as a
awong 2013/09/20 00:36:24 sure. de-virtualized and put into WebFrame.h.
560 }
561
562 long long WebFrameImpl::embedderIdentifier() const
563 {
564 return m_embedderIdentifier;
557 } 565 }
558 566
559 WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypesMask) const 567 WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypesMask) const
560 { 568 {
561 // The URL to the icon may be in the header. As such, only 569 // 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. 570 // ask the loader for the icon if it's finished loading.
563 if (frame()->loader()->state() == FrameStateComplete) 571 if (frame()->loader()->state() == FrameStateComplete)
564 return frame()->loader()->icon()->urlsForTypes(iconTypesMask); 572 return frame()->loader()->icon()->urlsForTypes(iconTypesMask);
565 return WebVector<WebIconURL>(); 573 return WebVector<WebIconURL>();
566 } 574 }
(...skipping 1499 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const 2074 WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const
2067 { 2075 {
2068 if (!frame()) 2076 if (!frame())
2069 return WebString(); 2077 return WebString();
2070 2078
2071 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesD ebugInfo : LayerTreeNormal)); 2079 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesD ebugInfo : LayerTreeNormal));
2072 } 2080 }
2073 2081
2074 // WebFrameImpl public --------------------------------------------------------- 2082 // WebFrameImpl public ---------------------------------------------------------
2075 2083
2076 PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) 2084 WebFrame* WebFrame::create(WebFrameClient* client)
2077 { 2085 {
2078 return adoptRef(new WebFrameImpl(client)); 2086 return WebFrameImpl::create(client);
2079 } 2087 }
2080 2088
2081 WebFrameImpl::WebFrameImpl(WebFrameClient* client) 2089 WebFrame* WebFrame::create(WebFrameClient* client, long long embedderIdentifier)
2090 {
2091 return WebFrameImpl::create(client, embedderIdentifier);
2092 }
2093
2094 long long WebFrame::generateEmbedderIdentifier()
2095 {
2096 static long long next = 0;
2097 // Assume that 64-bit will not wrap to -1.
2098 return ++next;
2099 }
2100
2101 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client)
2102 {
2103 return WebFrameImpl::create(client, generateEmbedderIdentifier());
2104 }
2105
2106 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde ntifier)
2107 {
2108 return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef();
2109 }
2110
2111 WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier)
2082 : FrameDestructionObserver(0) 2112 : FrameDestructionObserver(0)
2083 , m_frameLoaderClient(this) 2113 , m_frameLoaderClient(this)
2084 , m_client(client) 2114 , m_client(client)
2085 , m_currentActiveMatchFrame(0) 2115 , m_currentActiveMatchFrame(0)
2086 , m_activeMatchIndexInCurrentFrame(-1) 2116 , m_activeMatchIndexInCurrentFrame(-1)
2087 , m_locatingActiveRect(false) 2117 , m_locatingActiveRect(false)
2088 , m_resumeScopingFromRange(0) 2118 , m_resumeScopingFromRange(0)
2089 , m_lastMatchCount(-1) 2119 , m_lastMatchCount(-1)
2090 , m_totalMatchCount(-1) 2120 , m_totalMatchCount(-1)
2091 , m_framesScopingCount(-1) 2121 , m_framesScopingCount(-1)
2092 , m_findRequestIdentifier(-1) 2122 , m_findRequestIdentifier(-1)
2093 , m_scopingInProgress(false) 2123 , m_scopingInProgress(false)
2094 , m_lastFindRequestCompletedWithNoMatches(false) 2124 , m_lastFindRequestCompletedWithNoMatches(false)
2095 , m_nextInvalidateAfter(0) 2125 , m_nextInvalidateAfter(0)
2096 , m_findMatchMarkersVersion(0) 2126 , m_findMatchMarkersVersion(0)
2097 , m_findMatchRectsAreValid(false) 2127 , m_findMatchRectsAreValid(false)
2098 , m_identifier(generateFrameIdentifier()) 2128 , m_embedderIdentifier(embedderIdentifier)
2099 , m_inSameDocumentHistoryLoad(false) 2129 , m_inSameDocumentHistoryLoad(false)
2100 { 2130 {
2101 WebKit::Platform::current()->incrementStatsCounter(webFrameActiveCount); 2131 WebKit::Platform::current()->incrementStatsCounter(webFrameActiveCount);
2102 frameCount++; 2132 frameCount++;
2103 } 2133 }
2104 2134
2105 WebFrameImpl::~WebFrameImpl() 2135 WebFrameImpl::~WebFrameImpl()
2106 { 2136 {
2107 WebKit::Platform::current()->decrementStatsCounter(webFrameActiveCount); 2137 WebKit::Platform::current()->decrementStatsCounter(webFrameActiveCount);
2108 frameCount--; 2138 frameCount--;
2109 2139
2110 cancelPendingScopingEffort(); 2140 cancelPendingScopingEffort();
2111 } 2141 }
2112 2142
2113 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame) 2143 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame)
2114 { 2144 {
2115 ASSERT(frame); 2145 ASSERT(frame);
2116 observeFrame(frame); 2146 observeFrame(frame);
2117 } 2147 }
2118 2148
2119 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page) 2149 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page)
2120 { 2150 {
2121 RefPtr<Frame> mainFrame = Frame::create(page, 0, &m_frameLoaderClient); 2151 RefPtr<Frame> mainFrame = Frame::create(page, 0, &m_frameLoaderClient);
2122 setWebCoreFrame(mainFrame.get()); 2152 setWebCoreFrame(mainFrame.get());
2123 2153
2124 // Add reference on behalf of FrameLoader. See comments in 2154 // Add reference on behalf of FrameLoader. See comments in
2125 // WebFrameLoaderClient::frameLoaderDestroyed for more info. 2155 // WebFrameLoaderClient::frameLoaderDestroyed for more info.
2126 ref(); 2156 ref();
2127 2157
2128 // We must call init() after m_frame is assigned because it is referenced 2158 // We must call init() after m_frame is assigned because it is referenced
2129 // during init(). 2159 // during init().
2130 frame()->init(); 2160 frame()->init();
2131 } 2161 }
2132 2162
2133 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement) 2163 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request , HTMLFrameOwnerElement* ownerElement)
2134 { 2164 {
2135 RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(m_client))); 2165 ASSERT(m_client);
2166 WebFrameImpl* webframe = static_cast<WebFrameImpl*>(m_client->createChildFra me(this, request.frameName()));
2167
2168 // If the embedder is returning 0 from createChildFrame(), it has not been
2169 // updated to the new ownership semantics where the embedder creates the
2170 // WebFrame. In that case, fall back to the old logic where the
2171 // WebFrameImpl is created here and published back to the embedder. To
2172 // bridge between the two ownership semantics, webframeLifetimeHack is
2173 // needeed to balance out the refcounting.
2174 //
2175 // FIXME: Remove once all embedders return non-null from createChildFrame().
2176 RefPtr<WebFrameImpl> webframeLifetimeHack;
2177 bool mustCallDidCreateFrame = false;
2178 if (!webframe) {
2179 mustCallDidCreateFrame = true;
2180 webframeLifetimeHack = adoptRef(WebFrameImpl::create(m_client));
2181 webframe = webframeLifetimeHack.get();
2182 }
2136 2183
2137 // Add an extra ref on behalf of the Frame/FrameLoader, which references the 2184 // 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 2185 // WebFrame via the FrameLoaderClient interface. See the comment at the top
2139 // of this file for more info. 2186 // of this file for more info.
2140 webframe->ref(); 2187 webframe->ref();
2141 2188
2142 RefPtr<Frame> childFrame = Frame::create(frame()->page(), ownerElement, &web frame->m_frameLoaderClient); 2189 RefPtr<Frame> childFrame = Frame::create(frame()->page(), ownerElement, &web frame->m_frameLoaderClient);
2143 webframe->setWebCoreFrame(childFrame.get()); 2190 webframe->setWebCoreFrame(childFrame.get());
2144 2191
2145 childFrame->tree()->setName(request.frameName()); 2192 childFrame->tree()->setName(request.frameName());
2146 2193
2147 frame()->tree()->appendChild(childFrame); 2194 frame()->tree()->appendChild(childFrame);
2148 2195
2196 // FIXME: Remove once all embedders return non-null from createChildFrame().
2197 if (mustCallDidCreateFrame && m_client)
2198 m_client->didCreateFrame(this, webframe);
2199
2149 // Frame::init() can trigger onload event in the parent frame, 2200 // Frame::init() can trigger onload event in the parent frame,
2150 // which may detach this frame and trigger a null-pointer access 2201 // which may detach this frame and trigger a null-pointer access
2151 // in FrameTree::removeChild. Move init() after appendChild call 2202 // in FrameTree::removeChild. Move init() after appendChild call
2152 // so that webframe->mFrame is in the tree before triggering 2203 // so that webframe->mFrame is in the tree before triggering
2153 // onload event handler. 2204 // onload event handler.
2154 // Because the event handler may set webframe->mFrame to null, 2205 // Because the event handler may set webframe->mFrame to null,
2155 // it is necessary to check the value after calling init() and 2206 // it is necessary to check the value after calling init() and
2156 // return without loading URL. 2207 // return without loading URL.
2157 // (b:791612) 2208 // (b:791612)
2158 childFrame->init(); // create an empty document 2209 childFrame->init(); // create an empty document
2159 if (!childFrame->tree()->parent()) 2210 if (!childFrame->tree()->parent()) {
2211 if (m_client)
2212 m_client->frameDetached(webframe);
2160 return 0; 2213 return 0;
2214 }
2161 2215
2162 HistoryItem* parentItem = frame()->loader()->history()->currentItem(); 2216 HistoryItem* parentItem = frame()->loader()->history()->currentItem();
2163 HistoryItem* childItem = 0; 2217 HistoryItem* childItem = 0;
2164 // If we're moving in the back/forward list, we might want to replace the co ntent 2218 // 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. 2219 // 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()) 2220 if (parentItem && parentItem->children().size() && isBackForwardLoadType(fra me()->loader()->loadType()) && !frame()->document()->loadEventFinished())
2167 childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueNa me()); 2221 childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueNa me());
2168 2222
2169 if (childItem) 2223 if (childItem)
2170 childFrame->loader()->loadHistoryItem(childItem); 2224 childFrame->loader()->loadHistoryItem(childItem);
2171 else 2225 else
2172 childFrame->loader()->load(FrameLoadRequest(0, request.resourceRequest() , "_self")); 2226 childFrame->loader()->load(FrameLoadRequest(0, request.resourceRequest() , "_self"));
2173 2227
2174 // A synchronous navigation (about:blank) would have already processed 2228 // A synchronous navigation (about:blank) would have already processed
2175 // onload, so it is possible for the frame to have already been destroyed by 2229 // onload, so it is possible for the frame to have already been destroyed by
2176 // script in the page. 2230 // script in the page.
2177 if (!childFrame->tree()->parent()) 2231 if (!childFrame->tree()->parent()) {
2232 if (m_client)
2233 m_client->frameDetached(webframe);
2178 return 0; 2234 return 0;
2235 }
2179 2236
2180 if (m_client)
2181 m_client->didCreateFrame(this, webframe.get());
2182 2237
2183 return childFrame.release(); 2238 return childFrame.release();
2184 } 2239 }
2185 2240
2186 void WebFrameImpl::didChangeContentsSize(const IntSize& size) 2241 void WebFrameImpl::didChangeContentsSize(const IntSize& size)
2187 { 2242 {
2188 // This is only possible on the main frame. 2243 // This is only possible on the main frame.
2189 if (m_totalMatchCount > 0) { 2244 if (m_totalMatchCount > 0) {
2190 ASSERT(!parent()); 2245 ASSERT(!parent());
2191 ++m_findMatchMarkersVersion; 2246 ++m_findMatchMarkersVersion;
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 2531
2477 // There is a possibility that the frame being detached was the only 2532 // 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. 2533 // pending one. We need to make sure final replies can be sent.
2479 flushCurrentScopingEffort(m_findRequestIdentifier); 2534 flushCurrentScopingEffort(m_findRequestIdentifier);
2480 2535
2481 cancelPendingScopingEffort(); 2536 cancelPendingScopingEffort();
2482 } 2537 }
2483 } 2538 }
2484 2539
2485 } // namespace WebKit 2540 } // namespace WebKit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698