summaryrefslogtreecommitdiffstats
path: root/webkit/renderer/cpp_binding_example.cc
blob: 43b4ede4823445ae9293feae9299d8e0f143945c (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
// Copyright (c) 2012 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.

// This file contains the definition for CppBindingExample, which is used in
// cpp_bound_class_unittest.

#include "cpp_binding_example.h"

#include <stdio.h>

#include "base/bind.h"
#include "base/bind_helpers.h"

namespace webkit_glue {

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_;
};

}

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 webkit_glue