summaryrefslogtreecommitdiffstats
path: root/WebKit/mac/Plugins
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-04-27 16:31:00 +0100
committerSteve Block <steveblock@google.com>2010-05-11 14:42:12 +0100
commitdcc8cf2e65d1aa555cce12431a16547e66b469ee (patch)
tree92a8d65cd5383bca9749f5327fb5e440563926e6 /WebKit/mac/Plugins
parentccac38a6b48843126402088a309597e682f40fe6 (diff)
downloadexternal_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebKit/mac/Plugins')
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h18
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm118
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h12
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm156
-rw-r--r--WebKit/mac/Plugins/Hosted/ProxyInstance.h9
-rw-r--r--WebKit/mac/Plugins/Hosted/ProxyInstance.mm54
-rw-r--r--WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.h53
-rw-r--r--WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.mm55
-rw-r--r--WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h1
-rw-r--r--WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm45
-rw-r--r--WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs2
-rw-r--r--WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs6
-rw-r--r--WebKit/mac/Plugins/WebBaseNetscapePluginView.h18
-rw-r--r--WebKit/mac/Plugins/WebBaseNetscapePluginView.mm41
-rw-r--r--WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm11
-rw-r--r--WebKit/mac/Plugins/WebNetscapePluginView.mm22
-rw-r--r--WebKit/mac/Plugins/WebNullPluginView.h41
-rw-r--r--WebKit/mac/Plugins/WebNullPluginView.mm100
-rw-r--r--WebKit/mac/Plugins/WebPluginController.mm107
19 files changed, 554 insertions, 315 deletions
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h
index cd3729f..d35503f 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h
@@ -43,8 +43,8 @@ class NetscapePluginHostProxy {
public:
NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort, const ProcessSerialNumber& pluginHostPSN, bool shouldCacheMissingPropertiesAndMethods);
- mach_port_t port() const { return m_pluginHostPort; }
- mach_port_t clientPort() const { return m_clientPort; }
+ mach_port_t port() const { ASSERT(fastMallocSize(this)); return m_pluginHostPort; }
+ mach_port_t clientPort() const { ASSERT(fastMallocSize(this)); return m_clientPort; }
void addPluginInstance(NetscapePluginInstanceProxy*);
void removePluginInstance(NetscapePluginInstanceProxy*);
@@ -54,15 +54,15 @@ public:
bool isMenuBarVisible() const { return m_menuBarIsVisible; }
void setMenuBarVisible(bool);
- bool isFullScreenWindowShowing() const { return m_fullScreenWindowIsShowing; }
- void setFullScreenWindowIsShowing(bool);
+ bool isFullscreenWindowShowing() const { return m_fullscreenWindowIsShowing; }
+ void setFullscreenWindowIsShowing(bool);
void setModal(bool);
void applicationDidBecomeActive();
bool processRequests();
- bool isProcessingRequests() const { return m_processingRequests; }
+ static bool isProcessingRequests() { return s_processingRequests; }
bool shouldCacheMissingPropertiesAndMethods() const { return m_shouldCacheMissingPropertiesAndMethods; }
@@ -73,8 +73,8 @@ private:
void beginModal();
void endModal();
- void didEnterFullScreen() const;
- void didExitFullScreen() const;
+ void didEnterFullscreen() const;
+ void didExitFullscreen() const;
static void deadNameNotificationCallback(CFMachPortRef, void *msg, CFIndex size, void *info);
@@ -96,10 +96,10 @@ private:
RetainPtr<WebPlaceholderModalWindow *> m_placeholderWindow;
unsigned m_isModal;
bool m_menuBarIsVisible;
- bool m_fullScreenWindowIsShowing;
+ bool m_fullscreenWindowIsShowing;
const ProcessSerialNumber m_pluginHostPSN;
- unsigned m_processingRequests;
+ static unsigned s_processingRequests;
bool m_shouldCacheMissingPropertiesAndMethods;
};
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
index 836277c..b437012 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
@@ -89,15 +89,16 @@ static PluginProxyMap& pluginProxyMap()
return pluginProxyMap;
}
+unsigned NetscapePluginHostProxy::s_processingRequests;
+
NetscapePluginHostProxy::NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort, const ProcessSerialNumber& pluginHostPSN, bool shouldCacheMissingPropertiesAndMethods)
: m_clientPort(clientPort)
, m_portSet(MACH_PORT_NULL)
, m_pluginHostPort(pluginHostPort)
, m_isModal(false)
, m_menuBarIsVisible(true)
- , m_fullScreenWindowIsShowing(false)
+ , m_fullscreenWindowIsShowing(false)
, m_pluginHostPSN(pluginHostPSN)
- , m_processingRequests(0)
, m_shouldCacheMissingPropertiesAndMethods(shouldCacheMissingPropertiesAndMethods)
{
pluginProxyMap().add(m_clientPort, this);
@@ -184,7 +185,9 @@ void NetscapePluginHostProxy::removePluginInstance(NetscapePluginInstanceProxy*
NetscapePluginInstanceProxy* NetscapePluginHostProxy::pluginInstance(uint32_t pluginID)
{
- return m_instances.get(pluginID).get();
+ NetscapePluginInstanceProxy* result = m_instances.get(pluginID).get();
+ ASSERT(!result || result->hostProxy() == this);
+ return result;
}
void NetscapePluginHostProxy::deadNameNotificationCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
@@ -202,12 +205,12 @@ void NetscapePluginHostProxy::setMenuBarVisible(bool visible)
[NSMenu setMenuBarVisible:visible];
}
-void NetscapePluginHostProxy::didEnterFullScreen() const
+void NetscapePluginHostProxy::didEnterFullscreen() const
{
SetFrontProcess(&m_pluginHostPSN);
}
-void NetscapePluginHostProxy::didExitFullScreen() const
+void NetscapePluginHostProxy::didExitFullscreen() const
{
// If the plug-in host is the current application then we should bring ourselves to the front when it exits full-screen mode.
@@ -223,16 +226,16 @@ void NetscapePluginHostProxy::didExitFullScreen() const
SetFrontProcess(&currentProcess);
}
-void NetscapePluginHostProxy::setFullScreenWindowIsShowing(bool isShowing)
+void NetscapePluginHostProxy::setFullscreenWindowIsShowing(bool isShowing)
{
- if (m_fullScreenWindowIsShowing == isShowing)
+ if (m_fullscreenWindowIsShowing == isShowing)
return;
- m_fullScreenWindowIsShowing = isShowing;
- if (m_fullScreenWindowIsShowing)
- didEnterFullScreen();
+ m_fullscreenWindowIsShowing = isShowing;
+ if (m_fullscreenWindowIsShowing)
+ didEnterFullscreen();
else
- didExitFullScreen();
+ didExitFullscreen();
}
@@ -294,7 +297,7 @@ void NetscapePluginHostProxy::setModal(bool modal)
bool NetscapePluginHostProxy::processRequests()
{
- m_processingRequests++;
+ s_processingRequests++;
if (!m_portSet) {
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &m_portSet);
@@ -310,7 +313,7 @@ bool NetscapePluginHostProxy::processRequests()
if (kr != KERN_SUCCESS) {
LOG_ERROR("Could not receive mach message, error %x", kr);
- m_processingRequests--;
+ s_processingRequests--;
return false;
}
@@ -323,24 +326,24 @@ bool NetscapePluginHostProxy::processRequests()
if (kr != KERN_SUCCESS) {
LOG_ERROR("Could not send mach message, error %x", kr);
- m_processingRequests--;
+ s_processingRequests--;
return false;
}
}
- m_processingRequests--;
+ s_processingRequests--;
return true;
}
if (msg->msgh_local_port == CFMachPortGetPort(m_deadNameNotificationPort.get())) {
ASSERT(msg->msgh_id == MACH_NOTIFY_DEAD_NAME);
pluginHostDied();
- m_processingRequests--;
+ s_processingRequests--;
return false;
}
ASSERT_NOT_REACHED();
- m_processingRequests--;
+ s_processingRequests--;
return false;
}
@@ -437,7 +440,7 @@ kern_return_t WKPCInvalidateRect(mach_port_t clientPort, uint32_t pluginID, doub
if (NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID))
instanceProxy->invalidateRect(x, y, width, height);
return KERN_SUCCESS;
- }
+ }
// Defer the work
CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{
@@ -578,7 +581,11 @@ kern_return_t WKPCEvaluate(mach_port_t clientPort, uint32_t pluginID, uint32_t r
data_t resultData = 0;
mach_msg_type_number_t resultLength = 0;
boolean_t returnValue = instanceProxy->evaluate(objectID, script, resultData, resultLength, allowPopups);
-
+
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
if (resultData)
mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
@@ -610,7 +617,7 @@ static Identifier identifierFromIdentifierRep(IdentifierRep* identifier)
ASSERT(identifier->isString());
const char* str = identifier->string();
- return Identifier(JSDOMWindow::commonJSGlobalData(), String::fromUTF8WithLatin1Fallback(str, strlen(str)));
+ return Identifier(JSDOMWindow::commonJSGlobalData(), stringToUString(String::fromUTF8WithLatin1Fallback(str, strlen(str))));
}
kern_return_t WKPCInvoke(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier,
@@ -637,7 +644,11 @@ kern_return_t WKPCInvoke(mach_port_t clientPort, uint32_t pluginID, uint32_t req
data_t resultData = 0;
mach_msg_type_number_t resultLength = 0;
boolean_t returnValue = instanceProxy->invoke(objectID, methodNameIdentifier, argumentsData, argumentsLength, resultData, resultLength);
-
+
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
if (resultData)
mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
@@ -663,7 +674,11 @@ kern_return_t WKPCInvokeDefault(mach_port_t clientPort, uint32_t pluginID, uint3
data_t resultData = 0;
mach_msg_type_number_t resultLength = 0;
boolean_t returnValue = instanceProxy->invokeDefault(objectID, argumentsData, argumentsLength, resultData, resultLength);
-
+
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
if (resultData)
mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
@@ -701,7 +716,7 @@ kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
if (!instanceProxy)
return KERN_FAILURE;
-
+
IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
if (!IdentifierRep::isValid(identifier))
return KERN_FAILURE;
@@ -717,7 +732,11 @@ kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
returnValue = instanceProxy->getProperty(objectID, propertyNameIdentifier, resultData, resultLength);
} else
returnValue = instanceProxy->setProperty(objectID, identifier->number(), resultData, resultLength);
-
+
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
if (resultData)
mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
@@ -750,6 +769,10 @@ kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
} else
result = instanceProxy->setProperty(objectID, identifier->number(), valueData, valueLength);
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, result);
return KERN_SUCCESS;
@@ -778,6 +801,10 @@ kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint
} else
result = instanceProxy->removeProperty(objectID, identifier->number());
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, result);
return KERN_SUCCESS;
@@ -805,7 +832,11 @@ kern_return_t WKPCHasProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
returnValue = instanceProxy->hasProperty(objectID, propertyNameIdentifier);
} else
returnValue = instanceProxy->hasProperty(objectID, identifier->number());
-
+
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue);
return KERN_SUCCESS;
@@ -830,6 +861,10 @@ kern_return_t WKPCHasMethod(mach_port_t clientPort, uint32_t pluginID, uint32_t
Identifier methodNameIdentifier = identifierFromIdentifierRep(identifier);
boolean_t returnValue = instanceProxy->hasMethod(objectID, methodNameIdentifier);
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue);
return KERN_SUCCESS;
@@ -872,7 +907,11 @@ kern_return_t WKPCEnumerate(mach_port_t clientPort, uint32_t pluginID, uint32_t
data_t resultData = 0;
mach_msg_type_number_t resultLength = 0;
boolean_t returnValue = instanceProxy->enumerate(objectID, resultData, resultLength);
-
+
+ hostProxy = instanceProxy->hostProxy();
+ if (!hostProxy)
+ return KERN_FAILURE;
+
_WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
if (resultData)
@@ -892,13 +931,13 @@ kern_return_t WKPCSetMenuBarVisible(mach_port_t clientPort, boolean_t menuBarVis
return KERN_SUCCESS;
}
-kern_return_t WKPCSetFullScreenWindowIsShowing(mach_port_t clientPort, boolean_t fullScreenWindowIsShowing)
+kern_return_t WKPCSetFullscreenWindowIsShowing(mach_port_t clientPort, boolean_t fullscreenWindowIsShowing)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
- hostProxy->setFullScreenWindowIsShowing(fullScreenWindowIsShowing);
+ hostProxy->setFullscreenWindowIsShowing(fullscreenWindowIsShowing);
return KERN_SUCCESS;
}
@@ -908,9 +947,18 @@ kern_return_t WKPCSetModal(mach_port_t clientPort, boolean_t modal)
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
-
- hostProxy->setModal(modal);
-
+
+ if (!hostProxy->isProcessingRequests()) {
+ hostProxy->setModal(modal);
+ return KERN_SUCCESS;
+ }
+
+ // Defer the work
+ CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{
+ if (NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort))
+ hostProxy->setModal(modal);
+ });
+
return KERN_SUCCESS;
}
@@ -1090,7 +1138,7 @@ kern_return_t WKPCRunSyncOpenPanel(mach_port_t clientPort, data_t panelData, mac
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
-
+
NSOpenPanel *sheet = [NSOpenPanel openPanel];
NSDictionary *panelState = [NSPropertyListSerialization propertyListFromData:[NSData dataWithBytes:panelData length:panelDataLength]
mutabilityOption:NSPropertyListImmutable
@@ -1114,7 +1162,11 @@ kern_return_t WKPCRunSyncOpenPanel(mach_port_t clientPort, data_t panelData, mac
[sheet setRequiredFileType:[panelState objectForKey:@"requiredFileType"]];
[sheet setTitle:[panelState objectForKey:@"title"]];
[sheet runModal];
-
+
+ NetscapePluginHostProxy* newHostProxy = pluginProxyMap().get(clientPort);
+ if (newHostProxy != hostProxy)
+ return KERN_FAILURE;
+
NSDictionary *ret = [NSDictionary dictionaryWithObjectsAndKeys:
[sheet filenames], @"filenames",
WKNoteOpenPanelFiles([sheet filenames]), @"extensions",
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
index 29a5a2d..593d336 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
@@ -72,14 +72,14 @@ public:
return m_pluginID;
}
- uint32_t renderContextID() const { return m_renderContextID; }
+ uint32_t renderContextID() const { ASSERT(fastMallocSize(this)); return m_renderContextID; }
void setRenderContextID(uint32_t renderContextID) { m_renderContextID = renderContextID; }
bool useSoftwareRenderer() const { return m_useSoftwareRenderer; }
void setUseSoftwareRenderer(bool useSoftwareRenderer) { m_useSoftwareRenderer = useSoftwareRenderer; }
- WebHostedNetscapePluginView *pluginView() const { return m_pluginView; }
- NetscapePluginHostProxy* hostProxy() const { return m_pluginHostProxy; }
+ WebHostedNetscapePluginView *pluginView() const { ASSERT(fastMallocSize(this)); return m_pluginView; }
+ NetscapePluginHostProxy* hostProxy() const { ASSERT(fastMallocSize(this)); return m_pluginHostProxy; }
bool cancelStreamLoad(uint32_t streamID, NPReason);
void disconnectStream(HostedNetscapePluginStream*);
@@ -89,7 +89,7 @@ public:
void pluginHostDied();
- void resize(NSRect size, NSRect clipRect, bool sync);
+ void resize(NSRect size, NSRect clipRect);
void destroy();
void focusChanged(bool hasFocus);
void windowFocusChanged(bool hasFocus);
@@ -102,6 +102,7 @@ public:
void syntheticKeyDownWithCommandModifier(int keyCode, char character);
void flagsChanged(NSEvent *);
void print(CGContextRef, unsigned width, unsigned height);
+ void snapshot(CGContextRef, unsigned width, unsigned height);
void startTimers(bool throttleTimers);
void stopTimers();
@@ -256,8 +257,9 @@ public:
template <typename T>
std::auto_ptr<T> waitForReply(uint32_t requestID)
{
+ RefPtr<NetscapePluginInstanceProxy> protect(this); // Plug-in host may crash while we are waiting for reply, releasing all instances to the instance proxy.
+
willCallPluginFunction();
-
m_waitingForReply = true;
Reply* reply = processRequestsAndWaitForReply(requestID);
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
index 515f9f7..f027534 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
@@ -30,6 +30,7 @@
#import "HostedNetscapePluginStream.h"
#import "NetscapePluginHostProxy.h"
#import "ProxyInstance.h"
+#import "ProxyRuntimeObject.h"
#import "WebDataSourceInternal.h"
#import "WebFrameInternal.h"
#import "WebHostedNetscapePluginView.h"
@@ -43,7 +44,6 @@
#import <JavaScriptCore/Error.h>
#import <JavaScriptCore/JSLock.h>
#import <JavaScriptCore/PropertyNameArray.h>
-#import <WebCore/CString.h>
#import <WebCore/CookieJar.h>
#import <WebCore/DocumentLoader.h>
#import <WebCore/Frame.h>
@@ -60,6 +60,7 @@
#import <mach/mach.h>
#import <utility>
#import <wtf/RefCountedLeakCounter.h>
+#import <wtf/text/CString.h>
extern "C" {
#import "WebKitPluginClientServer.h"
@@ -116,6 +117,9 @@ inline bool NetscapePluginInstanceProxy::LocalObjectMap::contains(uint32_t objec
inline JSC::JSObject* NetscapePluginInstanceProxy::LocalObjectMap::get(uint32_t objectID) const
{
+ if (objectID == HashTraits<uint32_t>::emptyValue() || HashTraits<uint32_t>::isDeletedValue(objectID))
+ return 0;
+
return m_idToJSObjectMap.get(objectID);
}
@@ -178,8 +182,16 @@ void NetscapePluginInstanceProxy::LocalObjectMap::clear()
bool NetscapePluginInstanceProxy::LocalObjectMap::forget(uint32_t objectID)
{
+ if (objectID == HashTraits<uint32_t>::emptyValue() || HashTraits<uint32_t>::isDeletedValue(objectID)) {
+ LOG_ERROR("NetscapePluginInstanceProxy::LocalObjectMap::forget: local object id %u is not valid.", objectID);
+ return true;
+ }
+
HashMap<uint32_t, JSC::ProtectedPtr<JSC::JSObject> >::iterator iter = m_idToJSObjectMap.find(objectID);
- ASSERT(iter != m_idToJSObjectMap.end());
+ if (iter == m_idToJSObjectMap.end()) {
+ LOG_ERROR("NetscapePluginInstanceProxy::LocalObjectMap::forget: local object %u doesn't exist.", objectID);
+ return true;
+ }
HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> >::iterator rIter = m_jsObjectToIDMap.find(iter->second.get());
@@ -245,19 +257,17 @@ NetscapePluginInstanceProxy::~NetscapePluginInstanceProxy()
#endif
}
-void NetscapePluginInstanceProxy::resize(NSRect size, NSRect clipRect, bool sync)
+void NetscapePluginInstanceProxy::resize(NSRect size, NSRect clipRect)
{
uint32_t requestID = 0;
- if (sync)
- requestID = nextRequestID();
+ requestID = nextRequestID();
_WKPHResizePluginInstance(m_pluginHostProxy->port(), m_pluginID, requestID,
size.origin.x, size.origin.y, size.size.width, size.size.height,
clipRect.origin.x, clipRect.origin.y, clipRect.size.width, clipRect.size.height);
- if (sync)
- waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
+ waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
}
void NetscapePluginInstanceProxy::stopAllStreams()
@@ -464,9 +474,6 @@ bool NetscapePluginInstanceProxy::wheelEvent(NSView *pluginView, NSEvent *event)
pluginPoint.x, pluginPoint.y, [event buttonNumber],
[event deltaX], [event deltaY], [event deltaZ]);
- // Protect ourselves in case waiting for the reply causes us to be deleted.
- RefPtr<NetscapePluginInstanceProxy> protect(this);
-
auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
if (!reply.get() || !reply->m_result)
return false;
@@ -497,6 +504,22 @@ void NetscapePluginInstanceProxy::print(CGContextRef context, unsigned width, un
CGContextRestoreGState(context);
}
+void NetscapePluginInstanceProxy::snapshot(CGContextRef context, unsigned width, unsigned height)
+{
+ uint32_t requestID = nextRequestID();
+ _WKPHPluginInstanceSnapshot(m_pluginHostProxy->port(), m_pluginID, requestID, width, height);
+
+ auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
+ if (!reply.get() || !reply->m_returnValue)
+ return;
+
+ RetainPtr<CGDataProvider> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(reply->m_result.get()));
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGImageRef> image(AdoptCF, CGImageCreate(width, height, 8, 32, width * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
+
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.get());
+}
+
void NetscapePluginInstanceProxy::stopTimers()
{
_WKPHPluginInstanceStopTimers(m_pluginHostProxy->port(), m_pluginID);
@@ -765,10 +788,16 @@ NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const ch
NetscapePluginInstanceProxy::Reply* NetscapePluginInstanceProxy::processRequestsAndWaitForReply(uint32_t requestID)
{
Reply* reply = 0;
-
+
+ ASSERT(m_pluginHostProxy);
while (!(reply = m_replies.take(requestID))) {
if (!m_pluginHostProxy->processRequests())
return 0;
+
+ // The host proxy can be destroyed while executing a nested processRequests() call, in which case it's normal
+ // to get a success result, but be unable to keep looping.
+ if (!m_pluginHostProxy)
+ return 0;
}
ASSERT(reply);
@@ -782,7 +811,7 @@ bool NetscapePluginInstanceProxy::getWindowNPObject(uint32_t& objectID)
if (!frame)
return false;
- if (!frame->script()->canExecuteScripts())
+ if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript))
objectID = 0;
else
objectID = m_localObjects.idForObject(frame->script()->windowShell(pluginWorld())->window());
@@ -814,8 +843,10 @@ bool NetscapePluginInstanceProxy::evaluate(uint32_t objectID, const String& scri
resultData = 0;
resultLength = 0;
- if (!m_localObjects.contains(objectID))
+ if (!m_localObjects.contains(objectID)) {
+ LOG_ERROR("NetscapePluginInstanceProxy::evaluate: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -857,8 +888,10 @@ bool NetscapePluginInstanceProxy::invoke(uint32_t objectID, const Identifier& me
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::invoke: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -891,8 +924,10 @@ bool NetscapePluginInstanceProxy::invokeDefault(uint32_t objectID, data_t argume
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::invokeDefault: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -924,8 +959,10 @@ bool NetscapePluginInstanceProxy::construct(uint32_t objectID, data_t argumentsD
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::construct: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -958,8 +995,10 @@ bool NetscapePluginInstanceProxy::getProperty(uint32_t objectID, const Identifie
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::getProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -977,8 +1016,10 @@ bool NetscapePluginInstanceProxy::getProperty(uint32_t objectID, const Identifie
bool NetscapePluginInstanceProxy::getProperty(uint32_t objectID, unsigned propertyName, data_t& resultData, mach_msg_type_number_t& resultLength)
{
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::getProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -999,8 +1040,10 @@ bool NetscapePluginInstanceProxy::setProperty(uint32_t objectID, const Identifie
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::setProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1023,8 +1066,10 @@ bool NetscapePluginInstanceProxy::setProperty(uint32_t objectID, unsigned proper
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::setProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1046,8 +1091,10 @@ bool NetscapePluginInstanceProxy::removeProperty(uint32_t objectID, const Identi
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::removeProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1071,8 +1118,10 @@ bool NetscapePluginInstanceProxy::removeProperty(uint32_t objectID, unsigned pro
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::removeProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1096,8 +1145,10 @@ bool NetscapePluginInstanceProxy::hasProperty(uint32_t objectID, const Identifie
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::hasProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1116,8 +1167,10 @@ bool NetscapePluginInstanceProxy::hasProperty(uint32_t objectID, unsigned proper
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::hasProperty: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1136,8 +1189,10 @@ bool NetscapePluginInstanceProxy::hasMethod(uint32_t objectID, const Identifier&
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::hasMethod: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1156,8 +1211,10 @@ bool NetscapePluginInstanceProxy::enumerate(uint32_t objectID, data_t& resultDat
return false;
JSObject* object = m_localObjects.get(objectID);
- if (!object)
+ if (!object) {
+ LOG_ERROR("NetscapePluginInstanceProxy::enumerate: local object %u doesn't exist.", objectID);
return false;
+ }
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
@@ -1171,7 +1228,7 @@ bool NetscapePluginInstanceProxy::enumerate(uint32_t objectID, data_t& resultDat
RetainPtr<NSMutableArray*> array(AdoptNS, [[NSMutableArray alloc] init]);
for (unsigned i = 0; i < propertyNames.size(); i++) {
- uint64_t methodName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(propertyNames[i].ustring().UTF8String().c_str()));
+ uint64_t methodName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(propertyNames[i].ustring().UTF8String().data()));
[array.get() addObject:[NSNumber numberWithLongLong:methodName]];
}
@@ -1195,7 +1252,7 @@ void NetscapePluginInstanceProxy::addValueToArray(NSMutableArray *array, ExecSta
if (value.isString()) {
[array addObject:[NSNumber numberWithInt:StringValueType]];
- [array addObject:String(value.toString(exec))];
+ [array addObject:ustringToString(value.toString(exec))];
} else if (value.isNumber()) {
[array addObject:[NSNumber numberWithInt:DoubleValueType]];
[array addObject:[NSNumber numberWithDouble:value.toNumber(exec)]];
@@ -1206,9 +1263,9 @@ void NetscapePluginInstanceProxy::addValueToArray(NSMutableArray *array, ExecSta
[array addObject:[NSNumber numberWithInt:NullValueType]];
else if (value.isObject()) {
JSObject* object = asObject(value);
- if (object->classInfo() == &RuntimeObjectImp::s_info) {
- RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(object);
- if (ProxyInstance* instance = static_cast<ProxyInstance*>(imp->getInternalInstance())) {
+ if (object->classInfo() == &ProxyRuntimeObject::s_info) {
+ ProxyRuntimeObject* runtimeObject = static_cast<ProxyRuntimeObject*>(object);
+ if (ProxyInstance* instance = runtimeObject->getInternalProxyInstance()) {
[array addObject:[NSNumber numberWithInt:NPObjectValueType]];
[array addObject:[NSNumber numberWithInt:instance->objectID()]];
}
@@ -1287,7 +1344,7 @@ bool NetscapePluginInstanceProxy::demarshalValueFromArray(ExecState* exec, NSArr
if (!frame)
return false;
- if (!frame->script()->canExecuteScripts())
+ if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript))
return false;
RefPtr<RootObject> rootObject = frame->script()->createRootObject(m_pluginView);
@@ -1335,26 +1392,18 @@ void NetscapePluginInstanceProxy::demarshalValues(ExecState* exec, data_t values
void NetscapePluginInstanceProxy::retainLocalObject(JSC::JSValue value)
{
- if (!value.isObject())
- return;
-
- JSObject* object = asObject(value);
- if (object->classInfo() == &RuntimeObjectImp::s_info)
+ if (!value.isObject() || value.inherits(&ProxyRuntimeObject::s_info))
return;
- m_localObjects.retain(object);
+ m_localObjects.retain(asObject(value));
}
void NetscapePluginInstanceProxy::releaseLocalObject(JSC::JSValue value)
{
- if (!value.isObject())
+ if (!value.isObject() || value.inherits(&ProxyRuntimeObject::s_info))
return;
- JSObject* object = asObject(value);
- if (object->classInfo() == &RuntimeObjectImp::s_info)
- return;
-
- m_localObjects.release(object);
+ m_localObjects.release(asObject(value));
}
PassRefPtr<Instance> NetscapePluginInstanceProxy::createBindingsInstance(PassRefPtr<RootObject> rootObject)
@@ -1364,10 +1413,6 @@ PassRefPtr<Instance> NetscapePluginInstanceProxy::createBindingsInstance(PassRef
if (_WKPHGetScriptableNPObject(m_pluginHostProxy->port(), m_pluginID, requestID) != KERN_SUCCESS)
return 0;
- // If the plug-in host crashes while we're waiting for a reply, the last reference to the instance proxy
- // will go away. Prevent this by protecting it here.
- RefPtr<NetscapePluginInstanceProxy> protect(this);
-
auto_ptr<GetScriptableNPObjectReply> reply = waitForReply<GetScriptableNPObjectReply>(requestID);
if (!reply.get())
return 0;
@@ -1375,6 +1420,7 @@ PassRefPtr<Instance> NetscapePluginInstanceProxy::createBindingsInstance(PassRef
if (!reply->m_objectID)
return 0;
+ // Since the reply was non-null, "this" is still a valid pointer.
return ProxyInstance::create(rootObject, this, reply->m_objectID);
}
@@ -1458,7 +1504,7 @@ bool NetscapePluginInstanceProxy::getCookies(data_t urlData, mach_msg_type_numbe
if (Frame* frame = core([m_pluginView webFrame])) {
String cookieString = cookies(frame->document(), url);
- WebCore::CString cookieStringUTF8 = cookieString.utf8();
+ WTF::CString cookieStringUTF8 = cookieString.utf8();
if (cookieStringUTF8.isNull())
return false;
@@ -1500,7 +1546,7 @@ bool NetscapePluginInstanceProxy::getProxy(data_t urlData, mach_msg_type_number_
if (!url)
return false;
- WebCore::CString proxyStringUTF8 = proxiesForURL(url);
+ WTF::CString proxyStringUTF8 = proxiesForURL(url);
proxyLength = proxyStringUTF8.length();
mig_allocate(reinterpret_cast<vm_address_t*>(&proxyData), proxyLength);
@@ -1512,8 +1558,8 @@ bool NetscapePluginInstanceProxy::getProxy(data_t urlData, mach_msg_type_number_
bool NetscapePluginInstanceProxy::getAuthenticationInfo(data_t protocolData, data_t hostData, uint32_t port, data_t schemeData, data_t realmData,
data_t& usernameData, mach_msg_type_number_t& usernameLength, data_t& passwordData, mach_msg_type_number_t& passwordLength)
{
- WebCore::CString username;
- WebCore::CString password;
+ WTF::CString username;
+ WTF::CString password;
if (!WebKit::getAuthenticationInfo(protocolData, hostData, port, schemeData, realmData, username, password))
return false;
@@ -1583,7 +1629,7 @@ void NetscapePluginInstanceProxy::resolveURL(const char* url, const char* target
{
ASSERT(m_pluginView);
- WebCore::CString resolvedURL = [m_pluginView resolvedURLStringForURL:url target:target];
+ WTF::CString resolvedURL = [m_pluginView resolvedURLStringForURL:url target:target];
resolvedURLLength = resolvedURL.length();
mig_allocate(reinterpret_cast<vm_address_t*>(&resolvedURLData), resolvedURLLength);
@@ -1613,10 +1659,10 @@ void NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(ExecState* exec
{
JSLock lock(SilenceAssertionsOnly);
- throwError(exec, GeneralError, globalExceptionString());
+ throwError(exec, GeneralError, stringToUString(globalExceptionString()));
}
- globalExceptionString() = UString();
+ globalExceptionString() = String();
}
} // namespace WebKit
diff --git a/WebKit/mac/Plugins/Hosted/ProxyInstance.h b/WebKit/mac/Plugins/Hosted/ProxyInstance.h
index 6e8ac47..c8fb118 100644
--- a/WebKit/mac/Plugins/Hosted/ProxyInstance.h
+++ b/WebKit/mac/Plugins/Hosted/ProxyInstance.h
@@ -58,10 +58,13 @@ public:
private:
ProxyInstance(PassRefPtr<JSC::Bindings::RootObject>, NetscapePluginInstanceProxy*, uint32_t objectID);
-
- virtual JSC::Bindings::Class *getClass() const;
- virtual JSC::JSValue invokeMethod(JSC::ExecState*, const JSC::Bindings::MethodList&, const JSC::ArgList& args);
+ virtual JSC::Bindings::RuntimeObject* newRuntimeObject(JSC::ExecState*);
+
+ virtual JSC::Bindings::Class* getClass() const;
+
+ virtual JSC::JSValue getMethod(JSC::ExecState* exec, const JSC::Identifier& propertyName);
+ virtual JSC::JSValue invokeMethod(JSC::ExecState*, JSC::RuntimeMethod*, const JSC::ArgList& args);
virtual bool supportsInvokeDefaultMethod() const;
virtual JSC::JSValue invokeDefaultMethod(JSC::ExecState*, const JSC::ArgList&);
diff --git a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
index c7a0ebe..9a976f9 100644
--- a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
+++ b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
@@ -28,9 +28,12 @@
#import "ProxyInstance.h"
#import "NetscapePluginHostProxy.h"
+#import "ProxyRuntimeObject.h"
#import <WebCore/IdentifierRep.h>
#import <WebCore/JSDOMWindow.h>
#import <WebCore/npruntime_impl.h>
+#import <WebCore/runtime_method.h>
+#import <runtime/Error.h>
#import <runtime/PropertyNameArray.h>
extern "C" {
@@ -128,7 +131,12 @@ ProxyInstance::~ProxyInstance()
invalidate();
}
-JSC::Bindings::Class *ProxyInstance::getClass() const
+RuntimeObject* ProxyInstance::newRuntimeObject(ExecState* exec)
+{
+ return new (exec) ProxyRuntimeObject(exec, this);
+}
+
+JSC::Bindings::Class* ProxyInstance::getClass() const
{
return proxyClass();
}
@@ -147,16 +155,20 @@ JSValue ProxyInstance::invoke(JSC::ExecState* exec, InvokeType type, uint64_t id
if (_WKPHNPObjectInvoke(m_instanceProxy->hostProxy()->port(), m_instanceProxy->pluginID(), requestID, m_objectID,
type, identifier, (char*)[arguments.get() bytes], [arguments.get() length]) != KERN_SUCCESS) {
- for (unsigned i = 0; i < args.size(); i++)
- m_instanceProxy->releaseLocalObject(args.at(i));
+ if (m_instanceProxy) {
+ for (unsigned i = 0; i < args.size(); i++)
+ m_instanceProxy->releaseLocalObject(args.at(i));
+ }
return jsUndefined();
}
auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(exec);
- for (unsigned i = 0; i < args.size(); i++)
- m_instanceProxy->releaseLocalObject(args.at(i));
+ if (m_instanceProxy) {
+ for (unsigned i = 0; i < args.size(); i++)
+ m_instanceProxy->releaseLocalObject(args.at(i));
+ }
if (!reply.get() || !reply->m_returnValue)
return jsUndefined();
@@ -164,8 +176,33 @@ JSValue ProxyInstance::invoke(JSC::ExecState* exec, InvokeType type, uint64_t id
return m_instanceProxy->demarshalValue(exec, (char*)CFDataGetBytePtr(reply->m_result.get()), CFDataGetLength(reply->m_result.get()));
}
-JSValue ProxyInstance::invokeMethod(ExecState* exec, const MethodList& methodList, const ArgList& args)
+class ProxyRuntimeMethod : public RuntimeMethod {
+public:
+ ProxyRuntimeMethod(ExecState* exec, const Identifier& name, Bindings::MethodList& list)
+ : RuntimeMethod(exec, name, list)
+ {
+ }
+
+ virtual const ClassInfo* classInfo() const { return &s_info; }
+
+ static const ClassInfo s_info;
+};
+
+const ClassInfo ProxyRuntimeMethod::s_info = { "ProxyRuntimeMethod", &RuntimeMethod::s_info, 0, 0 };
+
+JSValue ProxyInstance::getMethod(JSC::ExecState* exec, const JSC::Identifier& propertyName)
+{
+ MethodList methodList = getClass()->methodsNamed(propertyName, this);
+ return new (exec) ProxyRuntimeMethod(exec, propertyName, methodList);
+}
+
+JSValue ProxyInstance::invokeMethod(ExecState* exec, JSC::RuntimeMethod* runtimeMethod, const ArgList& args)
{
+ if (!asObject(runtimeMethod)->inherits(&ProxyRuntimeMethod::s_info))
+ return throwError(exec, TypeError, "Attempt to invoke non-plug-in method on plug-in object.");
+
+ const MethodList& methodList = *runtimeMethod->methods();
+
ASSERT(methodList.size() == 1);
ProxyMethod* method = static_cast<ProxyMethod*>(methodList[0]);
@@ -280,7 +317,7 @@ void ProxyInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArr
if (identifier->isString()) {
const char* str = identifier->string();
- nameArray.add(Identifier(JSDOMWindow::commonJSGlobalData(), String::fromUTF8WithLatin1Fallback(str, strlen(str))));
+ nameArray.add(Identifier(JSDOMWindow::commonJSGlobalData(), stringToUString(String::fromUTF8WithLatin1Fallback(str, strlen(str)))));
} else
nameArray.add(Identifier::from(exec, identifier->number()));
}
@@ -396,7 +433,8 @@ void ProxyInstance::setFieldValue(ExecState* exec, const Field* field, JSValue v
m_instanceProxy->pluginID(), requestID,
m_objectID, serverIdentifier, valueData, valueLength);
mig_deallocate(reinterpret_cast<vm_address_t>(valueData), valueLength);
- m_instanceProxy->releaseLocalObject(value);
+ if (m_instanceProxy)
+ m_instanceProxy->releaseLocalObject(value);
if (kr != KERN_SUCCESS)
return;
diff --git a/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.h b/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.h
new file mode 100644
index 0000000..af3c5db
--- /dev/null
+++ b/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if USE(PLUGIN_HOST_PROCESS)
+
+#ifndef ProxyRuntimeObject_h
+#define ProxyRuntimeObject_h
+
+#include <WebCore/runtime_object.h>
+
+namespace WebKit {
+
+class ProxyInstance;
+
+class ProxyRuntimeObject : public JSC::Bindings::RuntimeObject {
+public:
+ ProxyRuntimeObject(JSC::ExecState*, PassRefPtr<ProxyInstance>);
+ virtual ~ProxyRuntimeObject();
+
+ ProxyInstance* getInternalProxyInstance() const;
+
+ static const JSC::ClassInfo s_info;
+
+private:
+ virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
+};
+
+}
+
+#endif
+#endif
diff --git a/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.mm b/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.mm
new file mode 100644
index 0000000..5ba6e15
--- /dev/null
+++ b/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.mm
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if USE(PLUGIN_HOST_PROCESS)
+
+#include "ProxyInstance.h"
+#include "ProxyRuntimeObject.h"
+
+using namespace JSC;
+
+namespace WebKit {
+
+
+const ClassInfo ProxyRuntimeObject::s_info = { "ProxyRuntimeObject", &RuntimeObject::s_info, 0, 0 };
+
+ProxyRuntimeObject::ProxyRuntimeObject(ExecState* exec, PassRefPtr<ProxyInstance> instance)
+ : RuntimeObject(exec, instance)
+{
+}
+
+ProxyRuntimeObject::~ProxyRuntimeObject()
+{
+}
+
+ProxyInstance* ProxyRuntimeObject::getInternalProxyInstance() const
+{
+ return static_cast<ProxyInstance*>(getInternalInstance());
+}
+
+
+}
+
+#endif
diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h
index 5313ff2..1eb164d 100644
--- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h
+++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h
@@ -45,7 +45,6 @@ namespace WebKit {
NSSize _previousSize;
RefPtr<WebKit::NetscapePluginInstanceProxy> _proxy;
- BOOL _pluginHostDied;
}
- (id)initWithFrame:(NSRect)r
diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
index 0ad76f0..cd3724e 100644
--- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
@@ -41,8 +41,9 @@
#import <WebCore/Frame.h>
#import <WebCore/FrameLoaderTypes.h>
#import <WebCore/HTMLPlugInElement.h>
-#import <WebCore/runtime_root.h>
+#import <WebCore/RenderEmbeddedObject.h>
#import <WebCore/WebCoreObjCExtras.h>
+#import <WebCore/runtime_root.h>
#import <runtime/InitializeThreading.h>
#import <wtf/Assertions.h>
@@ -180,10 +181,9 @@ extern "C" {
if (!shouldClipOutPlugin)
visibleRectInWindow.origin.y = borderViewHeight - NSMaxY(visibleRectInWindow);
- BOOL sizeChanged = !NSEqualSizes(_previousSize, boundsInWindow.size);
_previousSize = boundsInWindow.size;
- _proxy->resize(boundsInWindow, visibleRectInWindow, sizeChanged);
+ _proxy->resize(boundsInWindow, visibleRectInWindow);
}
- (void)windowFocusChanged:(BOOL)hasFocus
@@ -287,6 +287,9 @@ extern "C" {
- (void)handleMouseEntered:(NSEvent *)event
{
+ // Set cursor to arrow. Plugins often handle cursor internally, but those that don't will just get this default one.
+ [[NSCursor arrowCursor] set];
+
if (_isStarted && _proxy)
_proxy->mouseEvent(self, event, NPCocoaEventMouseEntered);
}
@@ -295,6 +298,11 @@ extern "C" {
{
if (_isStarted && _proxy)
_proxy->mouseEvent(self, event, NPCocoaEventMouseExited);
+
+ // Set cursor back to arrow cursor. Because NSCursor doesn't know about changes that the plugin made, we could get confused about what we think the
+ // current cursor is otherwise. Therefore we have no choice but to unconditionally reset the cursor when the mouse exits the plugin.
+ // FIXME: This should be job of plugin host, see <rdar://problem/7654434>.
+ [[NSCursor arrowCursor] set];
}
- (void)scrollWheel:(NSEvent *)event
@@ -348,7 +356,9 @@ extern "C" {
- (void)pluginHostDied
{
- _pluginHostDied = YES;
+ RenderEmbeddedObject* renderer = toRenderEmbeddedObject(_element->renderer());
+ if (renderer)
+ renderer->setShowsCrashedPluginIndicator();
_pluginLayer = nil;
_proxy = 0;
@@ -359,6 +369,11 @@ extern "C" {
[self invalidatePluginContentRect:[self bounds]];
}
+- (void)visibleRectDidChange
+{
+ [super visibleRectDidChange];
+ WKSyncSurfaceToView(self);
+}
- (void)drawRect:(NSRect)rect
{
@@ -369,28 +384,12 @@ extern "C" {
_proxy->didDraw();
} else
_proxy->print(reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]), [self bounds].size.width, [self bounds].size.height);
+ } else if ([self inFlatteningPaint] && [self supportsSnapshotting]) {
+ _proxy->snapshot(reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]), [self bounds].size.width, [self bounds].size.height);
}
-
+
return;
}
-
- if (_pluginHostDied) {
- static NSImage *nullPlugInImage;
- if (!nullPlugInImage) {
- NSBundle *bundle = [NSBundle bundleForClass:[WebHostedNetscapePluginView class]];
- nullPlugInImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"nullplugin" ofType:@"tiff"]];
- [nullPlugInImage setFlipped:YES];
- }
-
- if (!nullPlugInImage)
- return;
-
- NSSize imageSize = [nullPlugInImage size];
- NSSize viewSize = [self bounds].size;
-
- NSPoint point = NSMakePoint((viewSize.width - imageSize.width) / 2.0, (viewSize.height - imageSize.height) / 2.0);
- [nullPlugInImage drawAtPoint:point fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
- }
}
- (PassRefPtr<JSC::Bindings::Instance>)createPluginBindingsInstance:(PassRefPtr<JSC::Bindings::RootObject>)rootObject
diff --git a/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs b/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
index 6522bf7..6b1a319 100644
--- a/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
+++ b/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
@@ -234,7 +234,7 @@ simpleroutine PCBooleanAndDataReply(clientPort :mach_port_t;
simpleroutine PCRunSyncOpenPanel(clientPort :mach_port_t;
panelData :data_t);
-simpleroutine PCSetFullScreenWindowIsShowing(clientPort :mach_port_t;
+simpleroutine PCSetFullscreenWindowIsShowing(clientPort :mach_port_t;
isShowing :boolean_t);
simpleroutine PCSetException(clientPort :mach_port_t;
diff --git a/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs b/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs
index c7cec89..5d9df45 100644
--- a/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs
+++ b/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs
@@ -242,3 +242,9 @@ simpleroutine PHPluginInstancePrivateBrowsingModeDidChange(pluginHostPort :mach_
simpleroutine PHSyncOpenPanelReply(pluginHostPort :mach_port_t;
filenames :data_t);
+
+simpleroutine PHPluginInstanceSnapshot(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ width :uint32_t;
+ height :uint32_t);
diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginView.h b/WebKit/mac/Plugins/WebBaseNetscapePluginView.h
index 18dc004..81d801a 100644
--- a/WebKit/mac/Plugins/WebBaseNetscapePluginView.h
+++ b/WebKit/mac/Plugins/WebBaseNetscapePluginView.h
@@ -41,13 +41,21 @@
@class WebFrame;
@class WebView;
-namespace WebCore {
+namespace WTF {
class CString;
+}
+
+namespace WebCore {
class HTMLPlugInElement;
}
class WebHaltablePlugin;
+// Also declared in WebCore/WidgetMac.mm
+@interface NSView (Widget)
+- (void)visibleRectDidChange;
+@end
+
@interface WebBaseNetscapePluginView : NSView
{
RetainPtr<WebNetscapePluginPackage> _pluginPackage;
@@ -123,10 +131,12 @@ class WebHaltablePlugin;
- (void)addWindowObservers;
- (void)removeWindowObservers;
- (BOOL)shouldClipOutPlugin;
+- (BOOL)inFlatteningPaint;
+- (BOOL)supportsSnapshotting;
- (BOOL)convertFromX:(double)sourceX andY:(double)sourceY space:(NPCoordinateSpace)sourceSpace
toX:(double *)destX andY:(double *)destY space:(NPCoordinateSpace)destSpace;
-- (WebCore::CString)resolvedURLStringForURL:(const char*)url target:(const char*)target;
+- (WTF::CString)resolvedURLStringForURL:(const char*)url target:(const char*)target;
- (void)invalidatePluginContentRect:(NSRect)rect;
@@ -135,11 +145,11 @@ class WebHaltablePlugin;
namespace WebKit {
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
-WebCore::CString proxiesForURL(NSURL *);
+WTF::CString proxiesForURL(NSURL *);
#endif
bool getAuthenticationInfo(const char* protocolStr, const char* hostStr, int32_t port, const char* schemeStr, const char* realmStr,
- WebCore::CString& username, WebCore::CString& password);
+ WTF::CString& username, WTF::CString& password);
}
#endif
diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
index 04a42ea..eec80f8 100644
--- a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
@@ -46,7 +46,6 @@
#import <WebCore/BitmapImage.h>
#import <WebCore/Credential.h>
#import <WebCore/CredentialStorage.h>
-#import <WebCore/CString.h>
#import <WebCore/Document.h>
#import <WebCore/Element.h>
#import <WebCore/Frame.h>
@@ -60,6 +59,7 @@
#import <WebKit/DOMPrivate.h>
#import <runtime/InitializeThreading.h>
#import <wtf/Assertions.h>
+#import <wtf/text/CString.h>
#define LoginWindowDidSwitchFromUserNotification @"WebLoginWindowDidSwitchFromUserNotification"
#define LoginWindowDidSwitchToUserNotification @"WebLoginWindowDidSwitchToUserNotification"
@@ -337,13 +337,10 @@ String WebHaltablePlugin::pluginName() const
- (NSRect)_windowClipRect
{
RenderObject* renderer = _element->renderer();
-
- if (renderer && renderer->view()) {
- if (FrameView* frameView = renderer->view()->frameView())
- return frameView->windowClipRectForLayer(renderer->enclosingLayer(), true);
- }
-
- return NSZeroRect;
+ if (!renderer || !renderer->view())
+ return NSZeroRect;
+
+ return toRenderWidget(renderer)->windowClipRect();
}
- (NSRect)visibleRect
@@ -353,6 +350,11 @@ String WebHaltablePlugin::pluginName() const
return NSIntersectionRect([self convertRect:[self _windowClipRect] fromView:nil], [super visibleRect]);
}
+- (void)visibleRectDidChange
+{
+ [self renewGState];
+}
+
- (BOOL)acceptsFirstResponder
{
return YES;
@@ -560,7 +562,30 @@ String WebHaltablePlugin::pluginName() const
NSWindow *window = [self window];
return !window || [window isMiniaturized] || [NSApp isHidden] || ![self isDescendantOf:[[self window] contentView]] || [self isHiddenOrHasHiddenAncestor];
}
+
+- (BOOL)inFlatteningPaint
+{
+ RenderObject* renderer = _element->renderer();
+ if (renderer && renderer->view()) {
+ if (FrameView* frameView = renderer->view()->frameView())
+ return frameView->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
+ }
+
+ return NO;
+}
+
+- (BOOL)supportsSnapshotting
+{
+ NSBundle *pluginBundle = [_pluginPackage.get() bundle];
+ if (![[pluginBundle bundleIdentifier] isEqualToString:@"com.macromedia.Flash Player.plugin"])
+ return YES;
+ // Flash has a bogus Info.plist entry for CFBundleVersionString, so use CFBundleShortVersionString.
+ NSString *versionString = [pluginBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
+ // Flash 10.1d51 has a crashing bug if sent a drawRect event when using the CA rendering model: <rdar://problem/7739922>
+ return ![versionString isEqual:@"10.1.51.95"];
+}
+
- (BOOL)hasBeenHalted
{
return _hasBeenHalted;
diff --git a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm
index d8324f7..a5e8f73 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm
@@ -199,8 +199,17 @@ void WebNetscapePluginEventHandlerCarbon::mouseDragged(NSEvent*)
{
}
-void WebNetscapePluginEventHandlerCarbon::mouseMoved(NSEvent*)
+void WebNetscapePluginEventHandlerCarbon::mouseMoved(NSEvent* theEvent)
{
+ EventRecord event;
+
+ getCarbonEvent(&event, theEvent);
+ event.what = adjustCursorEvent;
+
+ BOOL acceptedEvent;
+ acceptedEvent = sendEvent(&event);
+
+ LOG(PluginEvents, "NPP_HandleEvent(mouseMoved): %d", acceptedEvent);
}
void WebNetscapePluginEventHandlerCarbon::keyDown(NSEvent *theEvent)
diff --git a/WebKit/mac/Plugins/WebNetscapePluginView.mm b/WebKit/mac/Plugins/WebNetscapePluginView.mm
index 8fb1503..388b84b 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginView.mm
@@ -50,7 +50,6 @@
#import "WebPluginContainerCheck.h"
#import "WebNetscapeContainerCheckContextInfo.h"
#import "WebNetscapePluginEventHandler.h"
-#import "WebNullPluginView.h"
#import "WebPreferences.h"
#import "WebPluginRequest.h"
#import "WebViewInternal.h"
@@ -59,7 +58,6 @@
#import <runtime/JSLock.h>
#import <WebCore/npruntime_impl.h>
#import <WebCore/CookieJar.h>
-#import <WebCore/CString.h>
#import <WebCore/DocumentLoader.h>
#import <WebCore/Element.h>
#import <WebCore/Frame.h>
@@ -77,12 +75,13 @@
#import <WebKit/WebUIDelegate.h>
#import <runtime/InitializeThreading.h>
#import <wtf/Assertions.h>
+#import <wtf/text/CString.h>
#import <objc/objc-runtime.h>
#define LoginWindowDidSwitchFromUserNotification @"WebLoginWindowDidSwitchFromUserNotification"
#define LoginWindowDidSwitchToUserNotification @"WebLoginWindowDidSwitchToUserNotification"
#define WKNVSupportsCompositingCoreAnimationPluginsBool 74656 /* TRUE if the browser supports hardware compositing of Core Animation plug-ins */
-static const int WKNVSilverlightFullScreenPerformanceIssueFixed = 7288546; /* TRUE if Siverlight addressed its underlying bug in <rdar://problem/7288546> */
+static const int WKNVSilverlightFullscreenPerformanceIssueFixed = 7288546; /* TRUE if Siverlight addressed its underlying bug in <rdar://problem/7288546> */
using namespace WebCore;
using namespace WebKit;
@@ -754,6 +753,9 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
if (!_isStarted)
return;
+ // Set cursor to arrow. Plugins often handle cursor internally, but those that don't will just get this default one.
+ [[NSCursor arrowCursor] set];
+
_eventHandler->mouseEntered(theEvent);
}
@@ -1394,7 +1396,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
- (void)drawRect:(NSRect)rect
{
- if (drawingModel == NPDrawingModelCoreAnimation)
+ if (drawingModel == NPDrawingModelCoreAnimation && (![self inFlatteningPaint] || ![self supportsSnapshotting]))
return;
if (!_isStarted)
@@ -2276,7 +2278,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
- (char*)resolveURL:(const char*)url forTarget:(const char*)target
{
- WebCore::CString location = [self resolvedURLStringForURL:url target:target];
+ CString location = [self resolvedURLStringForURL:url target:target];
if (location.isNull())
return 0;
@@ -2307,13 +2309,13 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
// 1) Microsoft releases a genuine fix for 7288546.
// 2) Enough Silverlight users update to the new Silverlight.
// For now, we'll distinguish older broken versions of Silverlight by asking the plug-in if it resolved its full screen badness.
-- (void)_workaroundSilverlightFullScreenBug:(BOOL)initializedPlugin
+- (void)_workaroundSilverlightFullscreenBug:(BOOL)initializedPlugin
{
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
ASSERT(_isSilverlight);
- NPBool isFullScreenPerformanceIssueFixed = 0;
+ NPBool isFullscreenPerformanceIssueFixed = 0;
NPPluginFuncs *pluginFuncs = [_pluginPackage.get() pluginFuncs];
- if (pluginFuncs->getvalue && pluginFuncs->getvalue(plugin, static_cast<NPPVariable>(WKNVSilverlightFullScreenPerformanceIssueFixed), &isFullScreenPerformanceIssueFixed) == NPERR_NO_ERROR && isFullScreenPerformanceIssueFixed)
+ if (pluginFuncs->getvalue && pluginFuncs->getvalue(plugin, static_cast<NPPVariable>(WKNVSilverlightFullscreenPerformanceIssueFixed), &isFullscreenPerformanceIssueFixed) == NPERR_NO_ERROR && isFullscreenPerformanceIssueFixed)
return;
static CGLPixelFormatObj pixelFormatObject = 0;
@@ -2354,7 +2356,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
NPError npErr = [_pluginPackage.get() pluginFuncs]->newp((char *)[_MIMEType.get() cString], plugin, _mode, argsCount, cAttributes, cValues, NULL);
[[self class] setCurrentPluginView:nil];
if (_isSilverlight)
- [self _workaroundSilverlightFullScreenBug:YES];
+ [self _workaroundSilverlightFullscreenBug:YES];
LOG(Plugins, "NPP_New: %d", npErr);
return npErr;
}
@@ -2364,7 +2366,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
PluginMainThreadScheduler::scheduler().unregisterPlugin(plugin);
if (_isSilverlight)
- [self _workaroundSilverlightFullScreenBug:NO];
+ [self _workaroundSilverlightFullscreenBug:NO];
NPError npErr;
npErr = ![_pluginPackage.get() pluginFuncs]->destroy(plugin, NULL);
diff --git a/WebKit/mac/Plugins/WebNullPluginView.h b/WebKit/mac/Plugins/WebNullPluginView.h
deleted file mode 100644
index 3ca1532..0000000
--- a/WebKit/mac/Plugins/WebNullPluginView.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import <AppKit/AppKit.h>
-
-@class DOMElement;
-
-@interface WebNullPluginView : NSImageView
-{
- NSError *error;
- DOMElement *element;
-}
-
-- (id)initWithFrame:(NSRect)frame error:(NSError *)error DOMElement:(DOMElement *)element;
-
-@end
diff --git a/WebKit/mac/Plugins/WebNullPluginView.mm b/WebKit/mac/Plugins/WebNullPluginView.mm
deleted file mode 100644
index bcc7a4b..0000000
--- a/WebKit/mac/Plugins/WebNullPluginView.mm
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "WebNullPluginView.h"
-
-#import "DOMElementInternal.h"
-#import "WebDelegateImplementationCaching.h"
-#import "WebFrameInternal.h"
-#import "WebViewInternal.h"
-#import <WebCore/Document.h>
-#import <WebCore/Element.h>
-
-@implementation WebNullPluginView
-
-- initWithFrame:(NSRect)frame error:(NSError *)err DOMElement:(DOMElement *)elem
-{
- static NSImage *nullPlugInImage;
- if (!nullPlugInImage) {
- NSBundle *bundle = [NSBundle bundleForClass:[WebNullPluginView class]];
- NSString *imagePath = [bundle pathForResource:@"nullplugin" ofType:@"tiff"];
- nullPlugInImage = [[NSImage alloc] initWithContentsOfFile:imagePath];
- }
-
- self = [super initWithFrame:frame];
- if (!self)
- return nil;
-
- error = [err retain];
- if (err)
- element = [elem retain];
-
- [self setImage:nullPlugInImage];
-
- return self;
-}
-
-- (void)dealloc
-
-{
- [error release];
- [element release];
- [super dealloc];
-}
-
-- (void)reportFailure
-{
- NSError *localError = error;
- DOMElement *localElement = element;
-
- error = nil;
- element = nil;
-
- WebFrame *webFrame = kit(core(localElement)->document()->frame());
- if (webFrame) {
- WebView *webView = [webFrame webView];
- WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
- if (implementations->plugInFailedWithErrorFunc)
- CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, webView,
- @selector(webView:plugInFailedWithError:dataSource:), localError, [webFrame _dataSource]);
- }
-
- [localError release];
- [localElement release];
-}
-
-- (void)viewDidMoveToWindow
-{
- if (!error)
- return;
-
- if ([self window])
- [self reportFailure];
-}
-
-@end
diff --git a/WebKit/mac/Plugins/WebPluginController.mm b/WebKit/mac/Plugins/WebPluginController.mm
index 4343119..1c85862 100644
--- a/WebKit/mac/Plugins/WebPluginController.mm
+++ b/WebKit/mac/Plugins/WebPluginController.mm
@@ -36,6 +36,7 @@
#import "WebHTMLViewPrivate.h"
#import "WebKitErrorsPrivate.h"
#import "WebKitLogging.h"
+#import "WebNSObjectExtras.h"
#import "WebNSURLExtras.h"
#import "WebNSViewExtras.h"
#import "WebPlugin.h"
@@ -57,6 +58,7 @@
#import <WebCore/ResourceRequest.h>
#import <WebCore/ScriptController.h>
#import <WebCore/WebCoreURLResponse.h>
+#import <objc/objc-runtime.h>
#import <runtime/JSLock.h>
using namespace WebCore;
@@ -78,6 +80,10 @@ using namespace HTMLNames;
- (void)pluginDestroy;
@end
+static bool isKindOfClass(id, NSString* className);
+static void installFlip4MacPlugInWorkaroundIfNecessary();
+
+
static NSMutableSet *pluginViews = nil;
@implementation WebPluginController
@@ -209,7 +215,10 @@ static NSMutableSet *pluginViews = nil;
BOOL oldDefersCallbacks = [[self webView] defersCallbacks];
if (!oldDefersCallbacks)
[[self webView] setDefersCallbacks:YES];
-
+
+ if (isKindOfClass(view, @"WmvPlugin"))
+ installFlip4MacPlugInWorkaroundIfNecessary();
+
LOG(Plugins, "initializing plug-in %@", view);
if ([view respondsToSelector:@selector(webPlugInInitialize)]) {
JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
@@ -351,21 +360,11 @@ static void cancelOutstandingCheck(const void *item, void *context)
}
}
-// For compatibility only.
-- (void)showURL:(NSURL *)URL inFrame:(NSString *)target
-{
- [self webPlugInContainerLoadRequest:[NSURLRequest requestWithURL:URL] inFrame:target];
-}
-
- (void)webPlugInContainerShowStatus:(NSString *)message
{
- if (!message) {
+ if (!message)
message = @"";
- }
- if (!_documentView) {
- LOG_ERROR("could not show status message (%@) because plug-in has already been destroyed", message);
- return;
- }
+
WebView *v = [_dataSource _webView];
[[v _UIDelegateForwarder] webView:v setStatusText:message];
}
@@ -475,3 +474,85 @@ static WebCore::HTMLMediaElement* mediaProxyClient(DOMElement* element)
#endif
@end
+
+static bool isKindOfClass(id object, NSString *className)
+{
+ Class cls = NSClassFromString(className);
+
+ if (!cls)
+ return false;
+
+ return [object isKindOfClass:cls];
+}
+
+
+// Existing versions of the Flip4Mac WebKit plug-in have an object lifetime bug related to an NSAlert that is
+// used to notify the user about updates to the plug-in. This bug can result in Safari crashing if the page
+// containing the plug-in navigates while the alert is displayed (<rdar://problem/7313430>).
+//
+// The gist of the bug is thus: Flip4Mac sets an instance of the TSUpdateCheck class as the modal delegate of the
+// NSAlert instance. This TSUpdateCheck instance itself has a delegate. The delegate is set to the WmvPlugin
+// instance which is the NSView subclass that is exposed to WebKit as the plug-in view. Since this relationship
+// is that of delegates the TSUpdateCheck does not retain the WmvPlugin. This leads to a bug if the WmvPlugin
+// instance is destroyed before the TSUpdateCheck instance as the TSUpdateCheck instance will be left with a
+// pointer to a stale object. This will happen if a page containing the Flip4Mac plug-in triggers a navigation
+// while the update sheet is visible as the WmvPlugin instance is removed from the view hierarchy and there are
+// no other references to keep the object alive.
+//
+// We work around this bug by patching the following two messages:
+//
+// 1) -[NSAlert beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:]
+// 2) -[TSUpdateCheck alertDidEnd:returnCode:contextInfo:]
+//
+// Our override of 1) detects whether it is Flip4Mac's update sheet triggering the alert by checking whether the
+// modal delegate is an instance of TSUpdateCheck. If it is, it retains the modal delegate's delegate.
+//
+// Our override of 2) then autoreleases the delegate, balancing the retain we added in 1).
+//
+// These two overrides have the effect of ensuring that the WmvPlugin instance will always outlive the TSUpdateCheck
+// instance, preventing the TSUpdateCheck instance from accessing a stale delegate pointer and crashing the application.
+
+
+typedef void (*beginSheetModalForWindowIMP)(id, SEL, NSWindow *, id, SEL, void*);
+static beginSheetModalForWindowIMP original_NSAlert_beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_;
+
+typedef void (*alertDidEndIMP)(id, SEL, NSAlert *, NSInteger, void*);
+static alertDidEndIMP original_TSUpdateCheck_alertDidEnd_returnCode_contextInfo_;
+
+static void WebKit_TSUpdateCheck_alertDidEnd_returnCode_contextInfo_(id object, SEL selector, NSAlert *alert, NSInteger returnCode, void* contextInfo)
+{
+ [[object delegate] autorelease];
+
+ original_TSUpdateCheck_alertDidEnd_returnCode_contextInfo_(object, selector, alert, returnCode, contextInfo);
+}
+
+static void WebKit_NSAlert_beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_(id object, SEL selector, NSWindow *window, id modalDelegate, SEL didEndSelector, void* contextInfo)
+{
+ if (isKindOfClass(modalDelegate, @"TSUpdateCheck"))
+ [[modalDelegate delegate] retain];
+
+ original_NSAlert_beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_(object, selector, window, modalDelegate, didEndSelector, contextInfo);
+}
+
+static void installFlip4MacPlugInWorkaroundIfNecessary()
+{
+ static bool hasInstalledFlip4MacPlugInWorkaround;
+ if (!hasInstalledFlip4MacPlugInWorkaround) {
+ Class TSUpdateCheck = objc_lookUpClass("TSUpdateCheck");
+ if (!TSUpdateCheck)
+ return;
+
+ Method methodToPatch = class_getInstanceMethod(TSUpdateCheck, @selector(alertDidEnd:returnCode:contextInfo:));
+ if (!methodToPatch)
+ return;
+
+ IMP originalMethod = method_setImplementation(methodToPatch, reinterpret_cast<IMP>(WebKit_TSUpdateCheck_alertDidEnd_returnCode_contextInfo_));
+ original_TSUpdateCheck_alertDidEnd_returnCode_contextInfo_ = reinterpret_cast<alertDidEndIMP>(originalMethod);
+
+ methodToPatch = class_getInstanceMethod(objc_getRequiredClass("NSAlert"), @selector(beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:));
+ originalMethod = method_setImplementation(methodToPatch, reinterpret_cast<IMP>(WebKit_NSAlert_beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_));
+ original_NSAlert_beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_ = reinterpret_cast<beginSheetModalForWindowIMP>(originalMethod);
+
+ hasInstalledFlip4MacPlugInWorkaround = true;
+ }
+}