// Copyright © 2018 The CefSharp Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. #pragma once #include "include/cef_v8.h" #include "RegisterBoundObjectRegistry.h" #include "..\CefSharp.Core.Runtime\Internals\Messaging\Messages.h" #include "..\CefSharp.Core.Runtime\Internals\Serialization\Primitives.h" using namespace System; using namespace CefSharp::Internals::Messaging; using namespace CefSharp::Internals::Serialization; namespace CefSharp { namespace BrowserSubprocess { const CefString kIsObjectCached = CefString("IsObjectCached"); const CefString kIsObjectCachedCamelCase = CefString("isObjectCached"); const CefString kRemoveObjectFromCache = CefString("RemoveObjectFromCache"); const CefString kRemoveObjectFromCacheCamelCase = CefString("removeObjectFromCache"); const CefString kDeleteBoundObject = CefString("DeleteBoundObject"); const CefString kDeleteBoundObjectCamelCase = CefString("deleteBoundObject"); private class RegisterBoundObjectHandler : public CefV8Handler { private: gcroot^> _javascriptObjects; public: RegisterBoundObjectHandler(Dictionary^ javascriptObjects) { _javascriptObjects = javascriptObjects; } bool Execute(const CefString& name, CefRefPtr object, const CefV8ValueList& arguments, CefRefPtr& retval, CefString& exception) override { auto context = CefV8Context::GetCurrentContext(); if (context.get()) { if (context.get() && context->Enter()) { try { if (name == kIsObjectCached || name == kIsObjectCachedCamelCase) { if (arguments.size() == 0 || arguments.size() > 1) { //TODO: Improve error message exception = "Must specify the name of a single bound object to check the cache for"; return true; } auto objectName = arguments[0]->GetStringValue(); auto managedObjectName = StringUtils::ToClr(objectName); //Check to see if the object name is within the cache retval = CefV8Value::CreateBool(_javascriptObjects->ContainsKey(managedObjectName)); } else if (name == kRemoveObjectFromCache || name == kRemoveObjectFromCacheCamelCase) { if (arguments.size() == 0 || arguments.size() > 1) { //TODO: Improve error message exception = "Must specify the name of a single bound object to remove from cache"; return true; } auto objectName = arguments[0]->GetStringValue(); auto managedObjectName = StringUtils::ToClr(objectName); if (_javascriptObjects->ContainsKey(managedObjectName)) { //Remove object from cache retval = CefV8Value::CreateBool(_javascriptObjects->Remove(managedObjectName)); } else { retval = CefV8Value::CreateBool(false); } } //TODO: Better name for this function else if (name == kDeleteBoundObject || name == kDeleteBoundObjectCamelCase) { if (arguments.size() == 0 || arguments.size() > 1) { //TODO: Improve error message exception = "Must specify the name of a bound object to unbind, one object at a time."; return true; } auto objectName = arguments[0]->GetStringValue(); auto global = context->GetGlobal(); auto success = global->DeleteValue(objectName); retval = CefV8Value::CreateBool(success); } } finally { context->Exit(); } } else { exception = "Unable to Enter Context"; } } else { exception = "Unable to get current context"; } return true; } IMPLEMENT_REFCOUNTINGM(RegisterBoundObjectHandler); }; } }