1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/test/cpp_binding_example.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochusing webkit_glue::CppArgumentList;
13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochusing webkit_glue::CppBoundClass;
14bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochusing webkit_glue::CppVariant;
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace content {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PropertyCallbackExample : public CppBoundClass::PropertyCallback {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool GetValue(CppVariant* value) OVERRIDE {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value->Set(value_);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SetValue(const CppVariant& value) OVERRIDE {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value_.Set(value);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppVariant value_;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CppBindingExample::CppBindingExample() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map properties.  It's recommended, but not required, that the JavaScript
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // names (used as the keys in this map) match the names of the member
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // variables exposed through those names.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindProperty("my_value", &my_value);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindProperty("my_other_value", &my_other_value);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bind property with a callback.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindProperty("my_value_with_callback", new PropertyCallbackExample());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bind property with a getter callback.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindGetterCallback("same", base::Bind(&CppBindingExample::same,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        base::Unretained(this)));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map methods.  See comment above about names.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindCallback("echoValue", base::Bind(&CppBindingExample::echoValue,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       base::Unretained(this)));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindCallback("echoType", base::Bind(&CppBindingExample::echoType,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      base::Unretained(this)));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindCallback("plus", base::Bind(&CppBindingExample::plus,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  base::Unretained(this)));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The fallback method is called when a nonexistent method is called on an
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object. If none is specified, calling a nonexistent method causes an
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // exception to be thrown and the JavaScript execution is stopped.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BindFallbackCallback(base::Bind(&CppBindingExample::fallbackMethod,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  base::Unretained(this)));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  my_value.Set(10);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  my_other_value.Set("Reinitialized!");
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::echoValue(const CppArgumentList& args,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  CppVariant* result) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (args.size() < 1) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->SetNull();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->Set(args[0]);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::echoType(const CppArgumentList& args,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 CppVariant* result) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (args.size() < 1) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->SetNull();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that if args[0] is a string, the following assignment implicitly
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // makes a copy of that string, which may have an undesirable impact on
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // performance.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppVariant arg1 = args[0];
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (arg1.isBool())
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->Set(true);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (arg1.isInt32())
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->Set(7);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (arg1.isDouble())
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->Set(3.14159);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (arg1.isString())
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->Set("Success!");
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::plus(const CppArgumentList& args,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CppVariant* result) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (args.size() < 2) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->SetNull();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppVariant arg1 = args[0];
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppVariant arg2 = args[1];
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!arg1.isNumber() || !arg2.isNumber()) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->SetNull();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The value of a CppVariant may be read directly from its NPVariant struct.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (However, it should only be set using one of the Set() functions.)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double sum = 0.;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (arg1.isDouble())
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sum += arg1.value.doubleValue;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (arg1.isInt32())
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sum += arg1.value.intValue;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (arg2.isDouble())
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sum += arg2.value.doubleValue;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (arg2.isInt32())
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sum += arg2.value.intValue;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->Set(sum);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::same(CppVariant* result) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->Set(42);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::fallbackMethod(const CppArgumentList& args,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       CppVariant* result) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("Error: unknown JavaScript method invoked.\n");
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
138bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace content
139