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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 WebFrame* WebFrame::frameForContext(v8::Handle<v8::Context> context) | 516 WebFrame* WebFrame::frameForContext(v8::Handle<v8::Context> context) |
520 { | 517 { |
521 return WebFrameImpl::fromFrame(toFrameIfNotDetached(context)); | 518 return WebFrameImpl::fromFrame(toFrameIfNotDetached(context)); |
522 } | 519 } |
523 | 520 |
524 WebFrame* WebFrame::fromFrameOwnerElement(const WebElement& element) | 521 WebFrame* WebFrame::fromFrameOwnerElement(const WebElement& element) |
525 { | 522 { |
526 return WebFrameImpl::fromFrameOwnerElement(PassRefPtr<Element>(element).get(
)); | 523 return WebFrameImpl::fromFrameOwnerElement(PassRefPtr<Element>(element).get(
)); |
527 } | 524 } |
528 | 525 |
| 526 void WebFrameImpl::close() |
| 527 { |
| 528 m_client = 0; |
| 529 deref(); // Balances ref() acquired in WebFrame::create |
| 530 } |
| 531 |
529 WebString WebFrameImpl::uniqueName() const | 532 WebString WebFrameImpl::uniqueName() const |
530 { | 533 { |
531 return frame()->tree()->uniqueName(); | 534 return frame()->tree()->uniqueName(); |
532 } | 535 } |
533 | 536 |
534 WebString WebFrameImpl::assignedName() const | 537 WebString WebFrameImpl::assignedName() const |
535 { | 538 { |
536 return frame()->tree()->name(); | 539 return frame()->tree()->name(); |
537 } | 540 } |
538 | 541 |
539 void WebFrameImpl::setName(const WebString& name) | 542 void WebFrameImpl::setName(const WebString& name) |
540 { | 543 { |
541 frame()->tree()->setName(name); | 544 frame()->tree()->setName(name); |
542 } | 545 } |
543 | 546 |
544 long long WebFrameImpl::identifier() const | 547 long long WebFrameImpl::embedderIdentifier() const |
545 { | 548 { |
546 return m_identifier; | 549 return m_embedderIdentifier; |
547 } | 550 } |
548 | 551 |
549 WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypesMask) const | 552 WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypesMask) const |
550 { | 553 { |
551 // The URL to the icon may be in the header. As such, only | 554 // The URL to the icon may be in the header. As such, only |
552 // ask the loader for the icon if it's finished loading. | 555 // ask the loader for the icon if it's finished loading. |
553 if (frame()->loader()->state() == FrameStateComplete) | 556 if (frame()->loader()->state() == FrameStateComplete) |
554 return frame()->loader()->icon()->urlsForTypes(iconTypesMask); | 557 return frame()->loader()->icon()->urlsForTypes(iconTypesMask); |
555 return WebVector<WebIconURL>(); | 558 return WebVector<WebIconURL>(); |
556 } | 559 } |
(...skipping 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2054 WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const | 2057 WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const |
2055 { | 2058 { |
2056 if (!frame()) | 2059 if (!frame()) |
2057 return WebString(); | 2060 return WebString(); |
2058 | 2061 |
2059 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesD
ebugInfo : LayerTreeNormal)); | 2062 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesD
ebugInfo : LayerTreeNormal)); |
2060 } | 2063 } |
2061 | 2064 |
2062 // WebFrameImpl public --------------------------------------------------------- | 2065 // WebFrameImpl public --------------------------------------------------------- |
2063 | 2066 |
2064 PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) | 2067 WebFrame* WebFrame::create(WebFrameClient* client) |
2065 { | 2068 { |
2066 return adoptRef(new WebFrameImpl(client)); | 2069 return WebFrameImpl::create(client); |
2067 } | 2070 } |
2068 | 2071 |
2069 WebFrameImpl::WebFrameImpl(WebFrameClient* client) | 2072 WebFrame* WebFrame::create(WebFrameClient* client, long long embedderIdentifier) |
| 2073 { |
| 2074 return WebFrameImpl::create(client, embedderIdentifier); |
| 2075 } |
| 2076 |
| 2077 long long WebFrame::generateEmbedderIdentifier() |
| 2078 { |
| 2079 static long long next = 0; |
| 2080 // Assume that 64-bit will not wrap to -1. |
| 2081 return ++next; |
| 2082 } |
| 2083 |
| 2084 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client) |
| 2085 { |
| 2086 return WebFrameImpl::create(client, generateEmbedderIdentifier()); |
| 2087 } |
| 2088 |
| 2089 WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde
ntifier) |
| 2090 { |
| 2091 return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef(); |
| 2092 } |
| 2093 |
| 2094 WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier) |
2070 : FrameDestructionObserver(0) | 2095 : FrameDestructionObserver(0) |
2071 , m_frameLoaderClient(this) | 2096 , m_frameLoaderClient(this) |
2072 , m_client(client) | 2097 , m_client(client) |
2073 , m_currentActiveMatchFrame(0) | 2098 , m_currentActiveMatchFrame(0) |
2074 , m_activeMatchIndexInCurrentFrame(-1) | 2099 , m_activeMatchIndexInCurrentFrame(-1) |
2075 , m_locatingActiveRect(false) | 2100 , m_locatingActiveRect(false) |
2076 , m_resumeScopingFromRange(0) | 2101 , m_resumeScopingFromRange(0) |
2077 , m_lastMatchCount(-1) | 2102 , m_lastMatchCount(-1) |
2078 , m_totalMatchCount(-1) | 2103 , m_totalMatchCount(-1) |
2079 , m_framesScopingCount(-1) | 2104 , m_framesScopingCount(-1) |
2080 , m_findRequestIdentifier(-1) | 2105 , m_findRequestIdentifier(-1) |
2081 , m_scopingInProgress(false) | 2106 , m_scopingInProgress(false) |
2082 , m_lastFindRequestCompletedWithNoMatches(false) | 2107 , m_lastFindRequestCompletedWithNoMatches(false) |
2083 , m_nextInvalidateAfter(0) | 2108 , m_nextInvalidateAfter(0) |
2084 , m_findMatchMarkersVersion(0) | 2109 , m_findMatchMarkersVersion(0) |
2085 , m_findMatchRectsAreValid(false) | 2110 , m_findMatchRectsAreValid(false) |
2086 , m_identifier(generateFrameIdentifier()) | 2111 , m_embedderIdentifier(embedderIdentifier) |
2087 , m_inSameDocumentHistoryLoad(false) | 2112 , m_inSameDocumentHistoryLoad(false) |
2088 { | 2113 { |
2089 WebKit::Platform::current()->incrementStatsCounter(webFrameActiveCount); | 2114 WebKit::Platform::current()->incrementStatsCounter(webFrameActiveCount); |
2090 frameCount++; | 2115 frameCount++; |
2091 } | 2116 } |
2092 | 2117 |
2093 WebFrameImpl::~WebFrameImpl() | 2118 WebFrameImpl::~WebFrameImpl() |
2094 { | 2119 { |
2095 WebKit::Platform::current()->decrementStatsCounter(webFrameActiveCount); | 2120 WebKit::Platform::current()->decrementStatsCounter(webFrameActiveCount); |
2096 frameCount--; | 2121 frameCount--; |
2097 | 2122 |
2098 cancelPendingScopingEffort(); | 2123 cancelPendingScopingEffort(); |
2099 } | 2124 } |
2100 | 2125 |
2101 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame) | 2126 void WebFrameImpl::setWebCoreFrame(WebCore::Frame* frame) |
2102 { | 2127 { |
2103 ASSERT(frame); | 2128 ASSERT(frame); |
2104 observeFrame(frame); | 2129 observeFrame(frame); |
2105 } | 2130 } |
2106 | 2131 |
2107 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page) | 2132 void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page) |
2108 { | 2133 { |
2109 RefPtr<Frame> mainFrame = Frame::create(page, 0, &m_frameLoaderClient); | 2134 RefPtr<Frame> mainFrame = Frame::create(page, 0, &m_frameLoaderClient); |
2110 setWebCoreFrame(mainFrame.get()); | 2135 setWebCoreFrame(mainFrame.get()); |
2111 | 2136 |
2112 // Add reference on behalf of FrameLoader. See comments in | 2137 // Add reference on behalf of FrameLoader. See comments in |
2113 // WebFrameLoaderClient::frameLoaderDestroyed for more info. | 2138 // WebFrameLoaderClient::frameLoaderDestroyed for more info. |
2114 ref(); | 2139 ref(); |
2115 | 2140 |
2116 // 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 |
2117 // during init(). | 2142 // during init(). |
2118 frame()->init(); | 2143 frame()->init(); |
2119 } | 2144 } |
2120 | 2145 |
2121 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request
, HTMLFrameOwnerElement* ownerElement) | 2146 PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request
, HTMLFrameOwnerElement* ownerElement) |
2122 { | 2147 { |
2123 RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(m_client))); | 2148 ASSERT(m_client); |
| 2149 WebFrameImpl* webframe = toWebFrameImpl(m_client->createChildFrame(this, req
uest.frameName())); |
| 2150 |
| 2151 // If the embedder is returning 0 from createChildFrame(), it has not been |
| 2152 // updated to the new ownership semantics where the embedder creates the |
| 2153 // WebFrame. In that case, fall back to the old logic where the |
| 2154 // WebFrameImpl is created here and published back to the embedder. To |
| 2155 // bridge between the two ownership semantics, webframeLifetimeHack is |
| 2156 // needeed to balance out the refcounting. |
| 2157 // |
| 2158 // FIXME: Remove once all embedders return non-null from createChildFrame(). |
| 2159 RefPtr<WebFrameImpl> webframeLifetimeHack; |
| 2160 bool mustCallDidCreateFrame = false; |
| 2161 if (!webframe) { |
| 2162 mustCallDidCreateFrame = true; |
| 2163 webframeLifetimeHack = adoptRef(WebFrameImpl::create(m_client)); |
| 2164 webframe = webframeLifetimeHack.get(); |
| 2165 } |
2124 | 2166 |
2125 // Add an extra ref on behalf of the Frame/FrameLoader, which references the | 2167 // Add an extra ref on behalf of the Frame/FrameLoader, which references the |
2126 // WebFrame via the FrameLoaderClient interface. See the comment at the top | 2168 // WebFrame via the FrameLoaderClient interface. See the comment at the top |
2127 // of this file for more info. | 2169 // of this file for more info. |
2128 webframe->ref(); | 2170 webframe->ref(); |
2129 | 2171 |
2130 RefPtr<Frame> childFrame = Frame::create(frame()->page(), ownerElement, &web
frame->m_frameLoaderClient); | 2172 RefPtr<Frame> childFrame = Frame::create(frame()->page(), ownerElement, &web
frame->m_frameLoaderClient); |
2131 webframe->setWebCoreFrame(childFrame.get()); | 2173 webframe->setWebCoreFrame(childFrame.get()); |
2132 | 2174 |
2133 childFrame->tree()->setName(request.frameName()); | 2175 childFrame->tree()->setName(request.frameName()); |
2134 | 2176 |
2135 frame()->tree()->appendChild(childFrame); | 2177 frame()->tree()->appendChild(childFrame); |
2136 | 2178 |
| 2179 // FIXME: Remove once all embedders return non-null from createChildFrame(). |
| 2180 if (mustCallDidCreateFrame) |
| 2181 m_client->didCreateFrame(this, webframe); |
| 2182 |
2137 // Frame::init() can trigger onload event in the parent frame, | 2183 // Frame::init() can trigger onload event in the parent frame, |
2138 // which may detach this frame and trigger a null-pointer access | 2184 // which may detach this frame and trigger a null-pointer access |
2139 // in FrameTree::removeChild. Move init() after appendChild call | 2185 // in FrameTree::removeChild. Move init() after appendChild call |
2140 // so that webframe->mFrame is in the tree before triggering | 2186 // so that webframe->mFrame is in the tree before triggering |
2141 // onload event handler. | 2187 // onload event handler. |
2142 // Because the event handler may set webframe->mFrame to null, | 2188 // Because the event handler may set webframe->mFrame to null, |
2143 // it is necessary to check the value after calling init() and | 2189 // it is necessary to check the value after calling init() and |
2144 // return without loading URL. | 2190 // return without loading URL. |
| 2191 // NOTE: m_client will be null if this frame has been detached. |
2145 // (b:791612) | 2192 // (b:791612) |
2146 childFrame->init(); // create an empty document | 2193 childFrame->init(); // create an empty document |
2147 if (!childFrame->tree()->parent()) | 2194 if (!childFrame->tree()->parent()) |
2148 return 0; | 2195 return 0; |
2149 | 2196 |
2150 HistoryItem* parentItem = frame()->loader()->history()->currentItem(); | 2197 HistoryItem* parentItem = frame()->loader()->history()->currentItem(); |
2151 HistoryItem* childItem = 0; | 2198 HistoryItem* childItem = 0; |
2152 // If we're moving in the back/forward list, we might want to replace the co
ntent | 2199 // If we're moving in the back/forward list, we might want to replace the co
ntent |
2153 // of this child frame with whatever was there at that point. | 2200 // of this child frame with whatever was there at that point. |
2154 if (parentItem && parentItem->children().size() && isBackForwardLoadType(fra
me()->loader()->loadType()) && !frame()->document()->loadEventFinished()) | 2201 if (parentItem && parentItem->children().size() && isBackForwardLoadType(fra
me()->loader()->loadType()) && !frame()->document()->loadEventFinished()) |
2155 childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueNa
me()); | 2202 childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueNa
me()); |
2156 | 2203 |
2157 if (childItem) | 2204 if (childItem) |
2158 childFrame->loader()->loadHistoryItem(childItem); | 2205 childFrame->loader()->loadHistoryItem(childItem); |
2159 else | 2206 else |
2160 childFrame->loader()->load(FrameLoadRequest(0, request.resourceRequest()
, "_self")); | 2207 childFrame->loader()->load(FrameLoadRequest(0, request.resourceRequest()
, "_self")); |
2161 | 2208 |
2162 // A synchronous navigation (about:blank) would have already processed | 2209 // A synchronous navigation (about:blank) would have already processed |
2163 // onload, so it is possible for the frame to have already been destroyed by | 2210 // onload, so it is possible for the frame to have already been destroyed by |
2164 // script in the page. | 2211 // script in the page. |
| 2212 // NOTE: m_client will be null if this frame has been detached. |
2165 if (!childFrame->tree()->parent()) | 2213 if (!childFrame->tree()->parent()) |
2166 return 0; | 2214 return 0; |
2167 | 2215 |
2168 if (m_client) | |
2169 m_client->didCreateFrame(this, webframe.get()); | |
2170 | |
2171 return childFrame.release(); | 2216 return childFrame.release(); |
2172 } | 2217 } |
2173 | 2218 |
2174 void WebFrameImpl::didChangeContentsSize(const IntSize& size) | 2219 void WebFrameImpl::didChangeContentsSize(const IntSize& size) |
2175 { | 2220 { |
2176 // This is only possible on the main frame. | 2221 // This is only possible on the main frame. |
2177 if (m_totalMatchCount > 0) { | 2222 if (m_totalMatchCount > 0) { |
2178 ASSERT(!parent()); | 2223 ASSERT(!parent()); |
2179 ++m_findMatchMarkersVersion; | 2224 ++m_findMatchMarkersVersion; |
2180 } | 2225 } |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2464 | 2509 |
2465 // There is a possibility that the frame being detached was the only | 2510 // There is a possibility that the frame being detached was the only |
2466 // pending one. We need to make sure final replies can be sent. | 2511 // pending one. We need to make sure final replies can be sent. |
2467 flushCurrentScopingEffort(m_findRequestIdentifier); | 2512 flushCurrentScopingEffort(m_findRequestIdentifier); |
2468 | 2513 |
2469 cancelPendingScopingEffort(); | 2514 cancelPendingScopingEffort(); |
2470 } | 2515 } |
2471 } | 2516 } |
2472 | 2517 |
2473 } // namespace WebKit | 2518 } // namespace WebKit |
OLD | NEW |