Home | History | Annotate | Download | only in test
      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 
     12 using webkit_glue::CppArgumentList;
     13 using webkit_glue::CppBoundClass;
     14 using webkit_glue::CppVariant;
     15 
     16 namespace content {
     17 
     18 namespace {
     19 
     20 class 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 
     38 CppBindingExample::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 
     69 void 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 
     78 void 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 
     98 void 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 
    129 void CppBindingExample::same(CppVariant* result) {
    130   result->Set(42);
    131 }
    132 
    133 void CppBindingExample::fallbackMethod(const CppArgumentList& args,
    134                                        CppVariant* result) {
    135   printf("Error: unknown JavaScript method invoked.\n");
    136 }
    137 
    138 }  // namespace content
    139