diff options
Diffstat (limited to 'content/test')
-rw-r--r-- | content/test/cpp_binding_example.cc | 138 | ||||
-rw-r--r-- | content/test/cpp_binding_example.h | 86 |
2 files changed, 224 insertions, 0 deletions
diff --git a/content/test/cpp_binding_example.cc b/content/test/cpp_binding_example.cc new file mode 100644 index 0000000..3c7630d --- /dev/null +++ b/content/test/cpp_binding_example.cc @@ -0,0 +1,138 @@ +// Copyright 2013 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 "content/test/cpp_binding_example.h" + +#include <stdio.h> + +#include "base/bind.h" +#include "base/bind_helpers.h" + +using webkit_glue::CppArgumentList; +using webkit_glue::CppBoundClass; +using webkit_glue::CppVariant; + +namespace content { + +namespace { + +class PropertyCallbackExample : public CppBoundClass::PropertyCallback { + public: + virtual bool GetValue(CppVariant* value) OVERRIDE { + value->Set(value_); + return true; + } + + virtual bool SetValue(const CppVariant& value) OVERRIDE { + value_.Set(value); + return true; + } + + private: + CppVariant value_; +}; + +} // namespace + +CppBindingExample::CppBindingExample() { + // Map properties. It's recommended, but not required, that the JavaScript + // names (used as the keys in this map) match the names of the member + // variables exposed through those names. + BindProperty("my_value", &my_value); + BindProperty("my_other_value", &my_other_value); + + // Bind property with a callback. + BindProperty("my_value_with_callback", new PropertyCallbackExample()); + // Bind property with a getter callback. + BindGetterCallback("same", base::Bind(&CppBindingExample::same, + base::Unretained(this))); + + // Map methods. See comment above about names. + BindCallback("echoValue", base::Bind(&CppBindingExample::echoValue, + base::Unretained(this))); + BindCallback("echoType", base::Bind(&CppBindingExample::echoType, + base::Unretained(this))); + BindCallback("plus", base::Bind(&CppBindingExample::plus, + base::Unretained(this))); + + // The fallback method is called when a nonexistent method is called on an + // object. If none is specified, calling a nonexistent method causes an + // exception to be thrown and the JavaScript execution is stopped. + BindFallbackCallback(base::Bind(&CppBindingExample::fallbackMethod, + base::Unretained(this))); + + my_value.Set(10); + my_other_value.Set("Reinitialized!"); +} + +void CppBindingExample::echoValue(const CppArgumentList& args, + CppVariant* result) { + if (args.size() < 1) { + result->SetNull(); + return; + } + result->Set(args[0]); +} + +void CppBindingExample::echoType(const CppArgumentList& args, + CppVariant* result) { + if (args.size() < 1) { + result->SetNull(); + return; + } + // Note that if args[0] is a string, the following assignment implicitly + // makes a copy of that string, which may have an undesirable impact on + // performance. + CppVariant arg1 = args[0]; + if (arg1.isBool()) + result->Set(true); + else if (arg1.isInt32()) + result->Set(7); + else if (arg1.isDouble()) + result->Set(3.14159); + else if (arg1.isString()) + result->Set("Success!"); +} + +void CppBindingExample::plus(const CppArgumentList& args, + CppVariant* result) { + if (args.size() < 2) { + result->SetNull(); + return; + } + + CppVariant arg1 = args[0]; + CppVariant arg2 = args[1]; + + if (!arg1.isNumber() || !arg2.isNumber()) { + result->SetNull(); + return; + } + + // The value of a CppVariant may be read directly from its NPVariant struct. + // (However, it should only be set using one of the Set() functions.) + double sum = 0.; + if (arg1.isDouble()) + sum += arg1.value.doubleValue; + else if (arg1.isInt32()) + sum += arg1.value.intValue; + + if (arg2.isDouble()) + sum += arg2.value.doubleValue; + else if (arg2.isInt32()) + sum += arg2.value.intValue; + + result->Set(sum); +} + +void CppBindingExample::same(CppVariant* result) { + result->Set(42); +} + +void CppBindingExample::fallbackMethod(const CppArgumentList& args, + CppVariant* result) { + printf("Error: unknown JavaScript method invoked.\n"); +} + +} // namespace content diff --git a/content/test/cpp_binding_example.h b/content/test/cpp_binding_example.h new file mode 100644 index 0000000..f594ae7 --- /dev/null +++ b/content/test/cpp_binding_example.h @@ -0,0 +1,86 @@ +// Copyright 2013 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. + +#ifndef CONTENT_TEST_CPP_BINDING_EXAMPLE_H_ +#define CONTENT_TEST_CPP_BINDING_EXAMPLE_H_ + +/* + CppBindingExample class: + This provides an example of how to use the CppBoundClass to create methods + and properties that can be exposed to JavaScript by an appropriately built + embedding client. It is also used by the CppBoundClass unit test. + + Typically, a class intended to be bound to JavaScript will define a + constructor, any methods and properties to be exposed, and optionally a + destructor. An embedding client can then bind the class to a JavaScript + object in a frame's window using the CppBoundClass::BindToJavascript() method, + generally called from the WebFrameClient's DidClearWindowObject(). + + Once this class has been bound, say to the name "example", it might be called + from JavaScript in the following way: + + <script> + if (window.example) { + document.writeln(example.echoValue(false)); + document.writeln(example.echoType("Hello world!")); + document.writeln(example.plus(2, 3.1)); + + example.my_value = 15; + example.my_other_value = 2.1; + document.writeln(example.plus(example.my_value, example.my_other_value)); + } + </script> +*/ + +#include "webkit/renderer/cpp_bound_class.h" + +namespace content { + +class CppBindingExample : public webkit_glue::CppBoundClass { + public: + // The default constructor initializes the property and method lists needed + // to bind this class to a JS object. + CppBindingExample(); + + // + // These public member variables and methods implement the methods and + // properties that will be exposed to JavaScript. If needed, the class could + // also contain other methods or variables, which will be hidden from JS + // as long as they're not mapped in the property and method lists created in + // the constructor. + // + // The signatures of any methods to be bound must match + // CppBoundClass::Callback. + // + + // Returns the value that was passed in as its first (only) argument. + void echoValue(const webkit_glue::CppArgumentList& args, + webkit_glue::CppVariant* result); + + // Returns a hard-coded value of the same type (bool, number (double), + // string, or null) that was passed in as an argument. + void echoType(const webkit_glue::CppArgumentList& args, + webkit_glue::CppVariant* result); + + // Returns the sum of the (first) two arguments as a double, if they are both + // numbers (integers or doubles). Otherwise returns null. + void plus(const webkit_glue::CppArgumentList& args, + webkit_glue::CppVariant* result); + + // Always returns the same value -- an example of a read-only property. + void same(webkit_glue::CppVariant* result); + + // Invoked when a nonexistent method is called on this example object, this + // prints an error message. + void fallbackMethod(const webkit_glue::CppArgumentList& args, + webkit_glue::CppVariant* result); + + // These properties will also be exposed to JavaScript. + webkit_glue::CppVariant my_value; + webkit_glue::CppVariant my_other_value; +}; + +} // namespace content + +#endif // CONTENT_TEST_CPP_BINDING_EXAMPLE_H_ |