summaryrefslogtreecommitdiffstats
path: root/content/test/cpp_binding_example.cc
blob: 3c7630d622a5c37b9b571b6aeb4f159a1e75090c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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