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