1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/test/cpp_binding_example.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochusing webkit_glue::CppArgumentList; 13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochusing webkit_glue::CppBoundClass; 14bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochusing webkit_glue::CppVariant; 15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace content { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PropertyCallbackExample : public CppBoundClass::PropertyCallback { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetValue(CppVariant* value) OVERRIDE { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->Set(value_); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool SetValue(const CppVariant& value) OVERRIDE { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_.Set(value); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant value_; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CppBindingExample::CppBindingExample() { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map properties. It's recommended, but not required, that the JavaScript 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // names (used as the keys in this map) match the names of the member 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // variables exposed through those names. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindProperty("my_value", &my_value); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindProperty("my_other_value", &my_other_value); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bind property with a callback. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindProperty("my_value_with_callback", new PropertyCallbackExample()); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bind property with a getter callback. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindGetterCallback("same", base::Bind(&CppBindingExample::same, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map methods. See comment above about names. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindCallback("echoValue", base::Bind(&CppBindingExample::echoValue, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindCallback("echoType", base::Bind(&CppBindingExample::echoType, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindCallback("plus", base::Bind(&CppBindingExample::plus, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The fallback method is called when a nonexistent method is called on an 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object. If none is specified, calling a nonexistent method causes an 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exception to be thrown and the JavaScript execution is stopped. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindFallbackCallback(base::Bind(&CppBindingExample::fallbackMethod, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_value.Set(10); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_other_value.Set("Reinitialized!"); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::echoValue(const CppArgumentList& args, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant* result) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.size() < 1) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetNull(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set(args[0]); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::echoType(const CppArgumentList& args, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant* result) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.size() < 1) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetNull(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that if args[0] is a string, the following assignment implicitly 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // makes a copy of that string, which may have an undesirable impact on 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // performance. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant arg1 = args[0]; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg1.isBool()) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set(true); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (arg1.isInt32()) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set(7); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (arg1.isDouble()) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set(3.14159); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (arg1.isString()) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set("Success!"); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::plus(const CppArgumentList& args, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant* result) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.size() < 2) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetNull(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant arg1 = args[0]; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant arg2 = args[1]; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!arg1.isNumber() || !arg2.isNumber()) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetNull(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The value of a CppVariant may be read directly from its NPVariant struct. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (However, it should only be set using one of the Set() functions.) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double sum = 0.; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg1.isDouble()) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum += arg1.value.doubleValue; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (arg1.isInt32()) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum += arg1.value.intValue; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg2.isDouble()) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum += arg2.value.doubleValue; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (arg2.isInt32()) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum += arg2.value.intValue; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set(sum); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::same(CppVariant* result) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set(42); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBindingExample::fallbackMethod(const CppArgumentList& args, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant* result) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Error: unknown JavaScript method invoked.\n"); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 138bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace content 139