Index: content/renderer/browser_plugin/browser_plugin_bindings.cc |
diff --git a/content/renderer/browser_plugin/browser_plugin_bindings.cc b/content/renderer/browser_plugin/browser_plugin_bindings.cc |
index d8c75ad5bece01eaafc258f690db6a230278023b..cc1bd61dc2911c53b1c80ceeefb9263dc5c72c48 100644 |
--- a/content/renderer/browser_plugin/browser_plugin_bindings.cc |
+++ b/content/renderer/browser_plugin/browser_plugin_bindings.cc |
@@ -38,8 +38,9 @@ namespace content { |
namespace { |
-const char kAddEventListener[] = "addEventListener"; |
-const char kRemoveEventListener[] = "removeEventListener"; |
+const char kAddEventListener[] = "addCustomEventListener"; |
+const char kRemoveEventListener[] = "removeCustomEventListener"; |
+const char kPostMessageMethod[] = "postMessage"; |
const char kSrcAttribute[] = "src"; |
BrowserPluginBindings* GetBindings(NPObject* object) { |
@@ -55,6 +56,10 @@ bool IdentifierIsRemoveEventListener(NPIdentifier identifier) { |
return WebBindings::getStringIdentifier(kRemoveEventListener) == identifier; |
} |
+bool IdentifierIsPostMessage(NPIdentifier identifier) { |
+ return WebBindings::getStringIdentifier(kPostMessageMethod) == identifier; |
+} |
+ |
bool IdentifierIsSrcAttribute(NPIdentifier identifier) { |
return WebBindings::getStringIdentifier(kSrcAttribute) == identifier; |
} |
@@ -90,6 +95,7 @@ bool StringToNPVariant(const std::string &in, NPVariant *variant) { |
//------------------------------------------------------------------------------ |
// Implementations of NPClass functions. These are here to: |
+// - Implement postMessage behavior. |
// - Implement src attribute. |
//------------------------------------------------------------------------------ |
NPObject* BrowserPluginBindingsAllocate(NPP npp, NPClass* the_class) { |
@@ -106,6 +112,9 @@ bool BrowserPluginBindingsHasMethod(NPObject* np_obj, NPIdentifier name) { |
if (!np_obj) |
return false; |
+ if (IdentifierIsPostMessage(name)) |
+ return true; |
+ |
if (IdentifierIsAddEventListener(name)) |
return true; |
@@ -125,6 +134,37 @@ bool BrowserPluginBindingsInvoke(NPObject* np_obj, NPIdentifier name, |
if (!bindings) |
return false; |
+ if (IdentifierIsPostMessage(name) && (arg_count == 2)) { |
+ v8::Handle<v8::Value> v8_val = WebBindings::toV8Value(&args[0]); |
+ // If serialization fails, there may be a V8 exception pending. |
+ // Don't touch the V8 state (eg, to raise our own 'error calling |
+ // method on NPObject' exception). |
+ if (v8_val.IsEmpty()) |
+ // This might happen if toV8Value fails an allocation. |
+ // Does SafeAllocation::newInstance throw an exception in this case? |
+ return true; |
nasko
2012/09/19 21:19:59
return false?
Fady Samuel
2012/09/20 15:24:28
Done.
|
+ WebSerializedScriptValue serialized_v8_val = |
+ WebSerializedScriptValue::serialize(v8_val); |
+ WebString message_string = serialized_v8_val.toString(); |
+ // Serialization can sometimes fail (the user might try to fax the |
+ // |window|, for example); ::serialize will result in a |
+ // DATA_CLONE_ERR being raised, but we still need to abort |
+ // the postMessage() operation. There's no clear way to test |
+ // for failure in WebSerializedScriptValue, but an empty string |
+ // should signal an invalid object. (The serializer at a nonzero |
+ // version will always write a version tag.) |
+ // v8::TryCatch, for some reason, was not catching DATA_CLONE_ERR; |
+ // if this worked, it would be the right way to go. |
+ // (This isn't the only way that serialization might fail! Other |
+ // exceptions are possible.) |
+ if (!message_string.length()) |
+ return true; |
nasko
2012/09/19 21:19:59
return false?
Fady Samuel
2012/09/20 15:24:28
Done.
|
+ string16 message(message_string); |
+ string16 target_origin = String16FromNPVariant(args[1]); |
+ bindings->instance()->PostMessage(message, target_origin); |
+ return true; |
+ } |
+ |
if (IdentifierIsAddEventListener(name) && (arg_count == 2)) { |
std::string event_name = StringFromNPVariant(args[0]); |
if (event_name.empty()) |