1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/test/cpp_binding_example.h"
6
7#include <stdio.h>
8
9#include "base/bind.h"
10#include "base/bind_helpers.h"
11
12using webkit_glue::CppArgumentList;
13using webkit_glue::CppBoundClass;
14using webkit_glue::CppVariant;
15
16namespace content {
17
18namespace {
19
20class PropertyCallbackExample : public CppBoundClass::PropertyCallback {
21 public:
22  virtual bool GetValue(CppVariant* value) OVERRIDE {
23    value->Set(value_);
24    return true;
25  }
26
27  virtual bool SetValue(const CppVariant& value) OVERRIDE {
28    value_.Set(value);
29    return true;
30  }
31
32 private:
33  CppVariant value_;
34};
35
36}  // namespace
37
38CppBindingExample::CppBindingExample() {
39  // Map properties.  It's recommended, but not required, that the JavaScript
40  // names (used as the keys in this map) match the names of the member
41  // variables exposed through those names.
42  BindProperty("my_value", &my_value);
43  BindProperty("my_other_value", &my_other_value);
44
45  // Bind property with a callback.
46  BindProperty("my_value_with_callback", new PropertyCallbackExample());
47  // Bind property with a getter callback.
48  BindGetterCallback("same", base::Bind(&CppBindingExample::same,
49                                        base::Unretained(this)));
50
51  // Map methods.  See comment above about names.
52  BindCallback("echoValue", base::Bind(&CppBindingExample::echoValue,
53                                       base::Unretained(this)));
54  BindCallback("echoType", base::Bind(&CppBindingExample::echoType,
55                                      base::Unretained(this)));
56  BindCallback("plus", base::Bind(&CppBindingExample::plus,
57                                  base::Unretained(this)));
58
59  // The fallback method is called when a nonexistent method is called on an
60  // object. If none is specified, calling a nonexistent method causes an
61  // exception to be thrown and the JavaScript execution is stopped.
62  BindFallbackCallback(base::Bind(&CppBindingExample::fallbackMethod,
63                                  base::Unretained(this)));
64
65  my_value.Set(10);
66  my_other_value.Set("Reinitialized!");
67}
68
69void CppBindingExample::echoValue(const CppArgumentList& args,
70                                  CppVariant* result) {
71  if (args.size() < 1) {
72    result->SetNull();
73    return;
74  }
75  result->Set(args[0]);
76}
77
78void CppBindingExample::echoType(const CppArgumentList& args,
79                                 CppVariant* result) {
80  if (args.size() < 1) {
81    result->SetNull();
82    return;
83  }
84  // Note that if args[0] is a string, the following assignment implicitly
85  // makes a copy of that string, which may have an undesirable impact on
86  // performance.
87  CppVariant arg1 = args[0];
88  if (arg1.isBool())
89    result->Set(true);
90  else if (arg1.isInt32())
91    result->Set(7);
92  else if (arg1.isDouble())
93    result->Set(3.14159);
94  else if (arg1.isString())
95    result->Set("Success!");
96}
97
98void CppBindingExample::plus(const CppArgumentList& args,
99                             CppVariant* result) {
100  if (args.size() < 2) {
101    result->SetNull();
102    return;
103  }
104
105  CppVariant arg1 = args[0];
106  CppVariant arg2 = args[1];
107
108  if (!arg1.isNumber() || !arg2.isNumber()) {
109    result->SetNull();
110    return;
111  }
112
113  // The value of a CppVariant may be read directly from its NPVariant struct.
114  // (However, it should only be set using one of the Set() functions.)
115  double sum = 0.;
116  if (arg1.isDouble())
117    sum += arg1.value.doubleValue;
118  else if (arg1.isInt32())
119    sum += arg1.value.intValue;
120
121  if (arg2.isDouble())
122    sum += arg2.value.doubleValue;
123  else if (arg2.isInt32())
124    sum += arg2.value.intValue;
125
126  result->Set(sum);
127}
128
129void CppBindingExample::same(CppVariant* result) {
130  result->Set(42);
131}
132
133void CppBindingExample::fallbackMethod(const CppArgumentList& args,
134                                       CppVariant* result) {
135  printf("Error: unknown JavaScript method invoked.\n");
136}
137
138}  // namespace content
139