summaryrefslogtreecommitdiffstats
path: root/ppapi/examples
diff options
context:
space:
mode:
authordmichael@google.com <dmichael@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 21:07:15 +0000
committerdmichael@google.com <dmichael@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 21:07:15 +0000
commit9888f134c655a95c5922c980eb59d3337341d653 (patch)
tree8ec7b6849cd94196df9bf3ee7810f6a838242e8d /ppapi/examples
parent2752bf6a3120e172d216ab7bde42222a3ae4b5cb (diff)
downloadchromium_src-9888f134c655a95c5922c980eb59d3337341d653.zip
chromium_src-9888f134c655a95c5922c980eb59d3337341d653.tar.gz
chromium_src-9888f134c655a95c5922c980eb59d3337341d653.tar.bz2
A proposal and implementation for an initial postMessage interface. These interfaces will allow JavaScript to send data asynchronously to a module instance, and the module instance to asynchronously send data to a JavaScript message handler.
Note, I did something differently from other per-instance interfaces. While the C interface has 'PPB_Messaging' and 'PPP_Messaging' separate from the Instance interfaces, I stuck the per-instance messaging in to pp::Instance. It seems more intuitive to me, and doesn't have the drawbacks of having too many functions in the C layer instance interfaces. Happy to back off of that position, but it's worth a shot. Overview: From JavaScript, you can invoke 'postMessage' on the embedded module. That results in a call to 'PPP_Messaging::HandleMessage'. From Native Code, you can invoke 'PPB_Messaging::PostMessage', which results in a call to an 'onmessage' function on the DOM element for the module instance in the JavaScript code (if one has been registered). Please see the included example or the examples in the comments of PPB_Messaging and PPP_Messaging. Restrictions: - This implementation is synchronous. A later CL will make it asynchronous. - This implementation supports only intrinsic values and strings (all types that PP_Var supports except for objects). Object & array support will come later. - This implementation only allows for 1 channel per instance. You can not expose other 'channels' or 'ports'. Future CLs will add support for MessagePorts. BUG=None TEST=test_post_message.h/.cc (This CL replaces http://codereview.chromium.org/6538028/ ) Review URL: http://codereview.chromium.org/6716005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79178 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/examples')
-rw-r--r--ppapi/examples/scripting/post_message.cc57
-rw-r--r--ppapi/examples/scripting/post_message.html50
-rw-r--r--ppapi/examples/scripting/reentrant_example.cc74
-rw-r--r--ppapi/examples/scripting/reentrant_example.html48
4 files changed, 229 insertions, 0 deletions
diff --git a/ppapi/examples/scripting/post_message.cc b/ppapi/examples/scripting/post_message.cc
new file mode 100644
index 0000000..24f7927
--- /dev/null
+++ b/ppapi/examples/scripting/post_message.cc
@@ -0,0 +1,57 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+// This is a simple C++ Pepper plugin that demonstrates HandleMessage and
+// PostMessage.
+
+// This object represents one time the page says <embed>.
+class MyInstance : public pp::Instance {
+ public:
+ explicit MyInstance(PP_Instance instance) : pp::Instance(instance) {}
+ virtual ~MyInstance() {}
+ virtual void HandleMessage(const pp::Var& message_data);
+};
+
+// HandleMessage gets invoked when postMessage is called on the DOM element
+// associated with this plugin instance.
+// In this case, if we are given a string, we'll post a message back to
+// JavaScript indicating whether or not that string is a palindrome.
+void MyInstance::HandleMessage(const pp::Var& message_data) {
+ if (message_data.is_string()) {
+ std::string string_copy(message_data.AsString());
+ std::reverse(string_copy.begin(), string_copy.end());
+ bool is_palindrome(message_data.AsString() == string_copy);
+
+ PostMessage(pp::Var(is_palindrome));
+ }
+}
+
+// This object is the global object representing this plugin library as long
+// as it is loaded.
+class MyModule : public pp::Module {
+ public:
+ MyModule() : pp::Module() {}
+ virtual ~MyModule() {}
+
+ // Override CreateInstance to create your customized Instance object.
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
+
diff --git a/ppapi/examples/scripting/post_message.html b/ppapi/examples/scripting/post_message.html
new file mode 100644
index 0000000..883d312
--- /dev/null
+++ b/ppapi/examples/scripting/post_message.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+ <!--
+ Copyright (c) 2011 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+ -->
+<head>
+ <title>postMessage Example</title>
+</head>
+
+<body>
+
+<script type="text/javascript">
+
+function SendString() {
+ plugin = document.getElementById('plugin');
+
+ // If we haven't already done it, set up an 'onmessage' function. This will
+ // get invoked whenever the plugin calls Instance::PostMessage in C++ (or
+ // PPB_Messaging::PostMessage in C). In this case, we're expecting a bool to
+ // tell us whether the string we passed was a palindrome.
+ if (!plugin.onmessage) {
+ plugin.onmessage = function(message_event) {
+ if (message_event.data) {
+ alert("The string was a palindrome.");
+ } else {
+ alert("The string was not a palindrome.");
+ }
+ }
+ }
+
+ var inputBox = document.getElementById("inputBox");
+
+ // Send the string to the plugin using postMessage. This results in a call
+ // to Instance::HandleMessage in C++ (or PPP_Messaging::HandleMessage in C).
+ plugin.postMessage(inputBox.value);
+}
+
+</script>
+
+<input type="text" id="inputBox" name="inputBox" value="ablewasiereisawelba"/>
+<p>
+<button onclick='SendString()'>Is Palindrome</button>
+<object id="plugin" type="application/x-ppapi-post-message-example"
+ width="0" height="0"/>
+<hr>
+</body>
+</html>
+
diff --git a/ppapi/examples/scripting/reentrant_example.cc b/ppapi/examples/scripting/reentrant_example.cc
new file mode 100644
index 0000000..a2fd53e
--- /dev/null
+++ b/ppapi/examples/scripting/reentrant_example.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <sstream>
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+// This is a simple C++ Pepper plugin that demonstrates HandleMessage and
+// PostMessage.
+
+// This object represents one time the page says <embed>.
+class MyInstance : public pp::Instance {
+ public:
+ explicit MyInstance(PP_Instance instance) : pp::Instance(instance) {}
+ virtual ~MyInstance() {}
+ virtual void HandleMessage(const pp::Var& message_data);
+};
+
+// HandleMessage gets invoked when postMessage is called on the DOM element
+// associated with this plugin instance.
+// In this case, if we are given a string, we'll post a message back to
+// JavaScript indicating whether or not that string is a palindrome.
+void MyInstance::HandleMessage(const pp::Var& message_data) {
+ if (message_data.is_string()) {
+ std::string string_copy(message_data.AsString());
+ std::istringstream str_stream(string_copy);
+ std::string id;
+ std::string input_string;
+ // Tokenize the string to get the id and the input_string. If we find both,
+ // post a message back to JavaScript indicating whether the given string is
+ // a palindrome.
+ if (std::getline(str_stream, id, ',') &&
+ std::getline(str_stream, input_string, ',')) {
+ std::string reversed_string(input_string);
+ std::reverse(reversed_string.begin(), reversed_string.end());
+ bool is_palindrome(input_string == reversed_string);
+ // Create a result string of the form "<id>,<result>", where <id> is the
+ // id we were given, and <result> is true if the given string was a
+ // palindrome, false otherwise.
+ std::string result(id);
+ result += ",";
+ result += is_palindrome ? "true" : "false";
+ // Send this result back to JS.
+ PostMessage(pp::Var(result));
+ }
+ }
+}
+
+// This object is the global object representing this plugin library as long
+// as it is loaded.
+class MyModule : public pp::Module {
+ public:
+ MyModule() : pp::Module() {}
+ virtual ~MyModule() {}
+
+ // Override CreateInstance to create your customized Instance object.
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
+
diff --git a/ppapi/examples/scripting/reentrant_example.html b/ppapi/examples/scripting/reentrant_example.html
new file mode 100644
index 0000000..6fa6b34
--- /dev/null
+++ b/ppapi/examples/scripting/reentrant_example.html
@@ -0,0 +1,48 @@
+<body>
+
+<script type="text/javascript">
+
+var id_string_dictionary = new Object;
+var last_id = 0;
+
+function SendString() {
+ plugin = document.getElementById('plugin');
+
+ // If we haven't already done it, set up an 'onmessage' function. This will
+ // get invoked whenever the plugin calls Instance::PostMessage in C++ (or
+ // PPB_Instance::PostMessage in C). In this case, we're expecting a bool to
+ // tell us whether the string we passed was a palindrome.
+ if (!plugin.onmessage) {
+ plugin.onmessage = function(message_event) {
+ var id_bool_pair = message_event.data.split(",");
+ var sent_string = id_string_dictionary[id_bool_pair[0]];
+ delete id_string_dictionary[id_bool_pair[0]];
+ if (id_bool_pair[1] == "true") {
+ alert(sent_string + " was a palindrome.");
+ } else {
+ alert(sent_string + " was not a palindrome.");
+ }
+ }
+ }
+
+ var inputBox = document.getElementById("inputBox");
+
+ // Send an id and a string to the plugin using postMessage. This results in a call
+ // to Instance::HandleMessage in C++ (or PPP_Instance::HandleMessage in C).
+ var id = ++last_id;
+
+ plugin.postMessage(id + "," + inputBox.value);
+ // Now put the string in our dictionary, so when we get a response, we know
+ // which request it goes with.
+ id_string_dictionary[id] = inputBox.value;
+}
+
+</script>
+
+<input type="text" id="inputBox" name="inputBox" value="ablewasiereisawelba"/>
+<p>
+<button onclick='SendString()'>Is Palindrome</button>
+<object id="plugin" type="application/x-ppapi-reentrant-example"
+ width="0" height="0"/>
+<hr>
+</body>