|
1 /* |
|
2 * Copyright (C) 2010 Apple Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
|
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
|
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
|
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
|
23 * THE POSSIBILITY OF SUCH DAMAGE. |
|
24 */ |
|
25 |
|
26 #include "PluginView.h" |
|
27 |
|
28 #include "Plugin.h" |
|
29 #include <WebCore/DocumentLoader.h> |
|
30 #include <WebCore/Event.h> |
|
31 #include <WebCore/FrameLoadRequest.h> |
|
32 #include <WebCore/FrameLoaderClient.h> |
|
33 #include <WebCore/FrameView.h> |
|
34 #include <WebCore/GraphicsContext.h> |
|
35 #include <WebCore/HTMLPlugInElement.h> |
|
36 #include <WebCore/HostWindow.h> |
|
37 #include <WebCore/NetscapePlugInStreamLoader.h> |
|
38 #include <WebCore/RenderLayer.h> |
|
39 #include <WebCore/ScrollView.h> |
|
40 |
|
41 using namespace JSC; |
|
42 using namespace WebCore; |
|
43 |
|
44 namespace WebKit { |
|
45 |
|
46 class PluginView::URLRequest : public RefCounted<URLRequest> { |
|
47 public: |
|
48 static PassRefPtr<PluginView::URLRequest> create(uint64_t requestID, const FrameLoadRequest& request, bool allowPopups) |
|
49 { |
|
50 return adoptRef(new URLRequest(requestID, request, allowPopups)); |
|
51 } |
|
52 |
|
53 uint64_t requestID() const { return m_requestID; } |
|
54 const String& target() const { return m_request.frameName(); } |
|
55 const ResourceRequest & request() const { return m_request.resourceRequest(); } |
|
56 bool allowPopups() const { return m_allowPopups; } |
|
57 |
|
58 private: |
|
59 URLRequest(uint64_t requestID, const FrameLoadRequest& request, bool allowPopups) |
|
60 : m_requestID(requestID) |
|
61 , m_request(request) |
|
62 , m_allowPopups(allowPopups) |
|
63 { |
|
64 } |
|
65 |
|
66 uint64_t m_requestID; |
|
67 FrameLoadRequest m_request; |
|
68 bool m_allowPopups; |
|
69 }; |
|
70 |
|
71 class PluginView::Stream : public RefCounted<PluginView::Stream>, NetscapePlugInStreamLoaderClient { |
|
72 public: |
|
73 static PassRefPtr<Stream> create(PluginView* pluginView, uint64_t streamID, const ResourceRequest& request) |
|
74 { |
|
75 return adoptRef(new Stream(pluginView, streamID, request)); |
|
76 } |
|
77 ~Stream(); |
|
78 |
|
79 void start(); |
|
80 void cancel(); |
|
81 |
|
82 uint64_t streamID() const { return m_streamID; } |
|
83 |
|
84 private: |
|
85 Stream(PluginView* pluginView, uint64_t streamID, const ResourceRequest& request) |
|
86 : m_pluginView(pluginView) |
|
87 , m_streamID(streamID) |
|
88 , m_request(request) |
|
89 , m_streamWasCancelled(false) |
|
90 { |
|
91 } |
|
92 |
|
93 // NetscapePluginStreamLoaderClient |
|
94 virtual void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&); |
|
95 virtual void didReceiveData(NetscapePlugInStreamLoader*, const char*, int); |
|
96 virtual void didFail(NetscapePlugInStreamLoader*, const ResourceError&); |
|
97 virtual void didFinishLoading(NetscapePlugInStreamLoader*); |
|
98 |
|
99 PluginView* m_pluginView; |
|
100 uint64_t m_streamID; |
|
101 const ResourceRequest m_request; |
|
102 |
|
103 // True if the stream was explicitly cancelled by calling cancel(). |
|
104 // (As opposed to being cancelled by the user hitting the stop button for example. |
|
105 bool m_streamWasCancelled; |
|
106 |
|
107 RefPtr<NetscapePlugInStreamLoader> m_loader; |
|
108 }; |
|
109 |
|
110 PluginView::Stream::~Stream() |
|
111 { |
|
112 ASSERT(!m_pluginView); |
|
113 } |
|
114 |
|
115 void PluginView::Stream::start() |
|
116 { |
|
117 ASSERT(!m_loader); |
|
118 |
|
119 Frame* frame = m_pluginView->m_pluginElement->document()->frame(); |
|
120 ASSERT(frame); |
|
121 |
|
122 m_loader = NetscapePlugInStreamLoader::create(frame, this); |
|
123 m_loader->setShouldBufferData(false); |
|
124 |
|
125 m_loader->documentLoader()->addPlugInStreamLoader(m_loader.get()); |
|
126 m_loader->load(m_request); |
|
127 } |
|
128 |
|
129 void PluginView::Stream::cancel() |
|
130 { |
|
131 ASSERT(m_loader); |
|
132 |
|
133 m_streamWasCancelled = true; |
|
134 m_loader->cancel(m_loader->cancelledError()); |
|
135 m_loader = 0; |
|
136 } |
|
137 |
|
138 void PluginView::Stream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse& response) |
|
139 { |
|
140 // Compute the stream related data from the resource response. |
|
141 const KURL& responseURL = response.url(); |
|
142 const String& mimeType = response.mimeType(); |
|
143 long long expectedContentLength = response.expectedContentLength(); |
|
144 |
|
145 String headers; |
|
146 if (response.isHTTP()) { |
|
147 Vector<UChar> stringBuilder; |
|
148 String separator(": "); |
|
149 |
|
150 String statusLine = String::format("HTTP %d ", response.httpStatusCode()); |
|
151 stringBuilder.append(statusLine.characters(), statusLine.length()); |
|
152 stringBuilder.append(response.httpStatusText().characters(), response.httpStatusText().length()); |
|
153 stringBuilder.append('\n'); |
|
154 |
|
155 HTTPHeaderMap::const_iterator end = response.httpHeaderFields().end(); |
|
156 for (HTTPHeaderMap::const_iterator it = response.httpHeaderFields().begin(); it != end; ++it) { |
|
157 stringBuilder.append(it->first.characters(), it->first.length()); |
|
158 stringBuilder.append(separator.characters(), separator.length()); |
|
159 stringBuilder.append(it->second.characters(), it->second.length()); |
|
160 stringBuilder.append('\n'); |
|
161 } |
|
162 |
|
163 headers = String::adopt(stringBuilder); |
|
164 |
|
165 // If the content is encoded (most likely compressed), then don't send its length to the plugin, |
|
166 // which is only interested in the decoded length, not yet known at the moment. |
|
167 // <rdar://problem/4470599> tracks a request for -[NSURLResponse expectedContentLength] to incorporate this logic. |
|
168 String contentEncoding = response.httpHeaderField("Content-Encoding"); |
|
169 if (!contentEncoding.isNull() && contentEncoding != "identity") |
|
170 expectedContentLength = -1; |
|
171 } |
|
172 |
|
173 uint32_t streamLength = 0; |
|
174 if (expectedContentLength > 0) |
|
175 streamLength = expectedContentLength; |
|
176 |
|
177 m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, response.lastModifiedDate(), mimeType, headers); |
|
178 } |
|
179 |
|
180 void PluginView::Stream::didReceiveData(NetscapePlugInStreamLoader*, const char* bytes, int length) |
|
181 { |
|
182 m_pluginView->m_plugin->streamDidReceiveData(m_streamID, bytes, length); |
|
183 } |
|
184 |
|
185 void PluginView::Stream::didFail(NetscapePlugInStreamLoader*, const ResourceError& error) |
|
186 { |
|
187 // Calling streamDidFail could cause us to be deleted, so we hold on to a reference here. |
|
188 RefPtr<Stream> protect(this); |
|
189 |
|
190 // We only want to call streamDidFail if the stream was not explicitly cancelled by the plug-in. |
|
191 if (!m_streamWasCancelled) |
|
192 m_pluginView->m_plugin->streamDidFail(m_streamID, error.isCancellation()); |
|
193 |
|
194 m_pluginView->removeStream(this); |
|
195 m_pluginView = 0; |
|
196 } |
|
197 |
|
198 void PluginView::Stream::didFinishLoading(NetscapePlugInStreamLoader*) |
|
199 { |
|
200 // Calling streamDidFinishLoading could cause us to be deleted, so we hold on to a reference here. |
|
201 RefPtr<Stream> protect(this); |
|
202 |
|
203 m_pluginView->m_plugin->streamDidFinishLoading(m_streamID); |
|
204 m_pluginView->removeStream(this); |
|
205 m_pluginView = 0; |
|
206 } |
|
207 |
|
208 PluginView::PluginView(WebCore::HTMLPlugInElement* pluginElement, PassRefPtr<Plugin> plugin, const Plugin::Parameters& parameters) |
|
209 : m_pluginElement(pluginElement) |
|
210 , m_plugin(plugin) |
|
211 , m_parameters(parameters) |
|
212 , m_isInitialized(false) |
|
213 , m_isWaitingUntilMediaCanStart(false) |
|
214 , m_pendingURLRequestsTimer(RunLoop::main(), this, &PluginView::pendingURLRequestsTimerFired) |
|
215 , m_npJSObjectMap(this) |
|
216 { |
|
217 } |
|
218 |
|
219 PluginView::~PluginView() |
|
220 { |
|
221 if (m_isWaitingUntilMediaCanStart) |
|
222 m_pluginElement->document()->removeMediaCanStartListener(this); |
|
223 |
|
224 // Cancel all pending frame loads. |
|
225 FrameLoadMap::iterator end = m_pendingFrameLoads.end(); |
|
226 for (FrameLoadMap::iterator it = m_pendingFrameLoads.begin(), end = m_pendingFrameLoads.end(); it != end; ++it) |
|
227 it->first->setLoadListener(0); |
|
228 |
|
229 if (m_plugin && m_isInitialized) |
|
230 m_plugin->destroy(); |
|
231 |
|
232 // Invalidate the NPObject map. |
|
233 m_npJSObjectMap.invalidate(); |
|
234 |
|
235 // Cancel all streams. |
|
236 cancelAllStreams(); |
|
237 } |
|
238 |
|
239 Frame* PluginView::frame() |
|
240 { |
|
241 return m_pluginElement->document()->frame(); |
|
242 } |
|
243 |
|
244 void PluginView::initializePlugin() |
|
245 { |
|
246 if (m_isInitialized) |
|
247 return; |
|
248 |
|
249 if (!m_plugin) { |
|
250 // We've already tried and failed to initialize the plug-in. |
|
251 return; |
|
252 } |
|
253 |
|
254 if (Frame* frame = m_pluginElement->document()->frame()) { |
|
255 if (Page* page = frame->page()) { |
|
256 |
|
257 // We shouldn't initialize the plug-in right now, add a listener. |
|
258 if (!page->canStartMedia()) { |
|
259 if (m_isWaitingUntilMediaCanStart) |
|
260 return; |
|
261 |
|
262 m_isWaitingUntilMediaCanStart = true; |
|
263 m_pluginElement->document()->addMediaCanStartListener(this); |
|
264 return; |
|
265 } |
|
266 } |
|
267 } |
|
268 |
|
269 if (!m_plugin->initialize(this, m_parameters)) { |
|
270 // We failed to initialize the plug-in. |
|
271 m_plugin = 0; |
|
272 |
|
273 return; |
|
274 } |
|
275 |
|
276 m_isInitialized = true; |
|
277 } |
|
278 |
|
279 void PluginView::setFrameRect(const WebCore::IntRect& rect) |
|
280 { |
|
281 Widget::setFrameRect(rect); |
|
282 viewGeometryDidChange(); |
|
283 } |
|
284 |
|
285 void PluginView::paint(GraphicsContext* context, const IntRect& dirtyRect) |
|
286 { |
|
287 if (context->paintingDisabled() || !m_plugin || !m_isInitialized) |
|
288 return; |
|
289 |
|
290 IntRect dirtyRectInWindowCoordinates = parent()->contentsToWindow(dirtyRect); |
|
291 |
|
292 IntRect paintRectInWindowCoordinates = intersection(dirtyRectInWindowCoordinates, clipRectInWindowCoordinates()); |
|
293 if (paintRectInWindowCoordinates.isEmpty()) |
|
294 return; |
|
295 |
|
296 context->save(); |
|
297 |
|
298 // Translate the context so that the origin is at the top left corner of the plug-in view. |
|
299 context->translate(frameRect().x(), frameRect().y()); |
|
300 |
|
301 m_plugin->paint(context, paintRectInWindowCoordinates); |
|
302 context->restore(); |
|
303 } |
|
304 |
|
305 void PluginView::frameRectsChanged() |
|
306 { |
|
307 Widget::frameRectsChanged(); |
|
308 viewGeometryDidChange(); |
|
309 } |
|
310 |
|
311 void PluginView::setParent(ScrollView* scrollView) |
|
312 { |
|
313 Widget::setParent(scrollView); |
|
314 |
|
315 if (scrollView) |
|
316 initializePlugin(); |
|
317 |
|
318 viewGeometryDidChange(); |
|
319 } |
|
320 |
|
321 void PluginView::handleEvent(Event*) |
|
322 { |
|
323 // FIXME: Implement. |
|
324 } |
|
325 |
|
326 void PluginView::viewGeometryDidChange() |
|
327 { |
|
328 if (!parent() || !m_plugin || !m_isInitialized) |
|
329 return; |
|
330 |
|
331 // Get the frame rect in window coordinates. |
|
332 IntRect frameRectInWindowCoordinates = parent()->contentsToWindow(frameRect()); |
|
333 |
|
334 m_plugin->geometryDidChange(frameRectInWindowCoordinates, clipRectInWindowCoordinates()); |
|
335 } |
|
336 |
|
337 IntRect PluginView::clipRectInWindowCoordinates() const |
|
338 { |
|
339 ASSERT(parent()); |
|
340 |
|
341 // Get the frame rect in window coordinates. |
|
342 IntRect frameRectInWindowCoordinates = parent()->contentsToWindow(frameRect()); |
|
343 |
|
344 // Get the window clip rect for the enclosing layer (in window coordinates). |
|
345 RenderLayer* layer = m_pluginElement->renderer()->enclosingLayer(); |
|
346 FrameView* parentView = m_pluginElement->document()->frame()->view(); |
|
347 IntRect windowClipRect = parentView->windowClipRectForLayer(layer, true); |
|
348 |
|
349 // Intersect the two rects to get the view clip rect in window coordinates. |
|
350 return intersection(frameRectInWindowCoordinates, windowClipRect); |
|
351 } |
|
352 |
|
353 void PluginView::pendingURLRequestsTimerFired() |
|
354 { |
|
355 ASSERT(!m_pendingURLRequests.isEmpty()); |
|
356 |
|
357 RefPtr<URLRequest> urlRequest = m_pendingURLRequests.takeFirst(); |
|
358 |
|
359 // If there are more requests to perform, reschedule the timer. |
|
360 if (!m_pendingURLRequests.isEmpty()) |
|
361 m_pendingURLRequestsTimer.startOneShot(0); |
|
362 |
|
363 performURLRequest(urlRequest.get()); |
|
364 } |
|
365 |
|
366 void PluginView::performURLRequest(URLRequest* request) |
|
367 { |
|
368 // First, check if this is a javascript: url. |
|
369 if (protocolIsJavaScript(request->request().url())) { |
|
370 performJavaScriptURLRequest(request); |
|
371 return; |
|
372 } |
|
373 |
|
374 if (!request->target().isNull()) { |
|
375 performFrameLoadURLRequest(request); |
|
376 return; |
|
377 } |
|
378 |
|
379 // This request is to load a URL and create a stream. |
|
380 RefPtr<Stream> stream = PluginView::Stream::create(this, request->requestID(), request->request()); |
|
381 addStream(stream.get()); |
|
382 stream->start(); |
|
383 } |
|
384 |
|
385 void PluginView::performFrameLoadURLRequest(URLRequest* request) |
|
386 { |
|
387 ASSERT(!request->target().isNull()); |
|
388 |
|
389 Frame* frame = m_pluginElement->document()->frame(); |
|
390 if (!frame) |
|
391 return; |
|
392 |
|
393 // Check if this is URL can be loaded. |
|
394 if (!SecurityOrigin::canLoad(request->request().url(), String(), m_pluginElement->document())) { |
|
395 // We can't load the request, send back a reply to the plug-in. |
|
396 m_plugin->frameDidFail(request->requestID(), false); |
|
397 return; |
|
398 } |
|
399 |
|
400 // First, try to find a target frame. |
|
401 Frame* targetFrame = frame->loader()->findFrameForNavigation(request->target()); |
|
402 if (!targetFrame) { |
|
403 // We did not find a target frame. Ask our frame to load the page. This may or may not create a popup window. |
|
404 frame->loader()->load(request->request(), request->target(), false); |
|
405 |
|
406 // FIXME: We don't know whether the window was successfully created here so we just assume that it worked. |
|
407 // It's better than not telling the plug-in anything. |
|
408 m_plugin->frameDidFinishLoading(request->requestID()); |
|
409 return; |
|
410 } |
|
411 |
|
412 // Now ask the frame to load the request. |
|
413 targetFrame->loader()->load(request->request(), false); |
|
414 |
|
415 WebFrame* targetWebFrame = static_cast<WebFrameLoaderClient*>(targetFrame->loader()->client())->webFrame(); |
|
416 if (WebFrame::LoadListener* loadListener = targetWebFrame->loadListener()) { |
|
417 // Check if another plug-in view or even this view is waiting for the frame to load. |
|
418 // If it is, tell it that the load was cancelled because it will be anyway. |
|
419 loadListener->didFailLoad(targetWebFrame, true); |
|
420 } |
|
421 |
|
422 m_pendingFrameLoads.set(targetWebFrame, request); |
|
423 targetWebFrame->setLoadListener(this); |
|
424 } |
|
425 |
|
426 void PluginView::performJavaScriptURLRequest(URLRequest* request) |
|
427 { |
|
428 ASSERT(protocolIsJavaScript(request->request().url())); |
|
429 |
|
430 RefPtr<Frame> frame = m_pluginElement->document()->frame(); |
|
431 if (!frame) |
|
432 return; |
|
433 |
|
434 String jsString = decodeURLEscapeSequences(request->request().url().string().substring(11)); |
|
435 |
|
436 if (!request->target().isNull()) { |
|
437 // For security reasons, only allow JS requests to be made on the frame that contains the plug-in. |
|
438 if (frame->tree()->find(request->target()) != frame) { |
|
439 // Let the plug-in know that its frame load failed. |
|
440 m_plugin->frameDidFail(request->requestID(), false); |
|
441 return; |
|
442 } |
|
443 } |
|
444 |
|
445 // Evaluate the JavaScript code. Note that running JavaScript here could cause the plug-in to be destroyed, so we |
|
446 // grab references to the plug-in here. |
|
447 RefPtr<Plugin> plugin = m_plugin; |
|
448 |
|
449 ScriptValue result = m_pluginElement->document()->frame()->script()->executeScript(jsString); |
|
450 |
|
451 // Check if evaluating the JavaScript destroyed the plug-in. |
|
452 if (!plugin->controller()) |
|
453 return; |
|
454 |
|
455 ScriptState* scriptState = m_pluginElement->document()->frame()->script()->globalObject(pluginWorld())->globalExec(); |
|
456 String resultString; |
|
457 result.getString(scriptState, resultString); |
|
458 |
|
459 if (!request->target().isNull()) { |
|
460 // Just send back whether the frame load succeeded or not. |
|
461 if (resultString.isNull()) |
|
462 m_plugin->frameDidFail(request->requestID(), false); |
|
463 else |
|
464 m_plugin->frameDidFinishLoading(request->requestID()); |
|
465 return; |
|
466 } |
|
467 |
|
468 // Send the result back to the plug-in. |
|
469 plugin->didEvaluateJavaScript(request->requestID(), decodeURLEscapeSequences(request->request().url()), resultString); |
|
470 } |
|
471 |
|
472 void PluginView::addStream(Stream* stream) |
|
473 { |
|
474 ASSERT(!m_streams.contains(stream->streamID())); |
|
475 m_streams.set(stream->streamID(), stream); |
|
476 } |
|
477 |
|
478 void PluginView::removeStream(Stream* stream) |
|
479 { |
|
480 ASSERT(m_streams.get(stream->streamID()) == stream); |
|
481 |
|
482 m_streams.remove(stream->streamID()); |
|
483 } |
|
484 |
|
485 void PluginView::cancelAllStreams() |
|
486 { |
|
487 Vector<RefPtr<Stream> > streams; |
|
488 copyValuesToVector(m_streams, streams); |
|
489 |
|
490 for (size_t i = 0; i < streams.size(); ++i) |
|
491 streams[i]->cancel(); |
|
492 |
|
493 // Cancelling a stream removes it from the m_streams map, so if we cancel all streams the map should be empty. |
|
494 ASSERT(m_streams.isEmpty()); |
|
495 } |
|
496 |
|
497 void PluginView::invalidateRect(const IntRect& dirtyRect) |
|
498 { |
|
499 if (!parent() || !m_plugin || !m_isInitialized) |
|
500 return; |
|
501 |
|
502 IntRect dirtyRectInWindowCoordinates = convertToContainingWindow(dirtyRect); |
|
503 |
|
504 parent()->hostWindow()->invalidateContentsAndWindow(intersection(dirtyRectInWindowCoordinates, clipRectInWindowCoordinates()), false); |
|
505 } |
|
506 |
|
507 void PluginView::mediaCanStart() |
|
508 { |
|
509 ASSERT(m_isWaitingUntilMediaCanStart); |
|
510 m_isWaitingUntilMediaCanStart = false; |
|
511 |
|
512 initializePlugin(); |
|
513 } |
|
514 |
|
515 void PluginView::invalidate(const IntRect& dirtyRect) |
|
516 { |
|
517 invalidateRect(dirtyRect); |
|
518 } |
|
519 |
|
520 String PluginView::userAgent(const KURL& url) |
|
521 { |
|
522 Frame* frame = m_pluginElement->document()->frame(); |
|
523 if (!frame) |
|
524 return String(); |
|
525 |
|
526 return frame->loader()->client()->userAgent(url); |
|
527 } |
|
528 |
|
529 void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, |
|
530 const HTTPHeaderMap& headerFields, const Vector<char>& httpBody, bool allowPopups) |
|
531 { |
|
532 FrameLoadRequest frameLoadRequest; |
|
533 frameLoadRequest.setFrameName(target); |
|
534 frameLoadRequest.resourceRequest().setHTTPMethod(method); |
|
535 frameLoadRequest.resourceRequest().setURL(m_pluginElement->document()->completeURL(urlString)); |
|
536 frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields); |
|
537 frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(httpBody.data(), httpBody.size())); |
|
538 |
|
539 m_pendingURLRequests.append(URLRequest::create(requestID, frameLoadRequest, allowPopups)); |
|
540 m_pendingURLRequestsTimer.startOneShot(0); |
|
541 } |
|
542 |
|
543 void PluginView::cancelStreamLoad(uint64_t streamID) |
|
544 { |
|
545 // Keep a reference to the stream. Stream::cancel might remove the stream from the map, and thus |
|
546 // releasing its last reference. |
|
547 RefPtr<Stream> stream = m_streams.get(streamID).get(); |
|
548 if (!stream) |
|
549 return; |
|
550 |
|
551 // Cancelling the stream here will remove it from the map. |
|
552 stream->cancel(); |
|
553 ASSERT(!m_streams.contains(streamID)); |
|
554 } |
|
555 |
|
556 NPObject* PluginView::windowScriptNPObject() |
|
557 { |
|
558 if (!frame()) |
|
559 return 0; |
|
560 |
|
561 // FIXME: Handle JavaScript being disabled. |
|
562 ASSERT(frame()->script()->canExecuteScripts(NotAboutToExecuteScript)); |
|
563 |
|
564 return m_npJSObjectMap.getOrCreateObject(frame()->script()->windowShell(pluginWorld())->window()); |
|
565 } |
|
566 |
|
567 NPObject* PluginView::pluginElementNPObject() |
|
568 { |
|
569 if (!frame()) |
|
570 return 0; |
|
571 |
|
572 // FIXME: Handle JavaScript being disabled. |
|
573 JSObject* object = frame()->script()->jsObjectForPluginElement(m_pluginElement); |
|
574 ASSERT(object); |
|
575 |
|
576 return m_npJSObjectMap.getOrCreateObject(object); |
|
577 } |
|
578 |
|
579 void PluginView::didFinishLoad(WebFrame* webFrame) |
|
580 { |
|
581 RefPtr<URLRequest> request = m_pendingFrameLoads.take(webFrame); |
|
582 ASSERT(request); |
|
583 webFrame->setLoadListener(0); |
|
584 |
|
585 m_plugin->frameDidFinishLoading(request->requestID()); |
|
586 } |
|
587 |
|
588 void PluginView::didFailLoad(WebFrame* webFrame, bool wasCancelled) |
|
589 { |
|
590 RefPtr<URLRequest> request = m_pendingFrameLoads.take(webFrame); |
|
591 ASSERT(request); |
|
592 webFrame->setLoadListener(0); |
|
593 |
|
594 m_plugin->frameDidFail(request->requestID(), wasCancelled); |
|
595 } |
|
596 |
|
597 } // namespace WebKit |