Ejemplo n.º 1
0
// synchronously send a string from Node to browser, then return string result from browser to Node
Handle<Value> Window::SendSync(const Arguments& args) {
  HandleScope scope;

  NativeWindow *window = ObjectWrap::Unwrap<NativeWindow> (args.This());

  if (window->GetBrowser()) {
    // find browser's v8 context
    CefRefPtr<CefV8Context> context = window->GetBrowser()->GetMainFrame()->GetV8Context();

    // ensure it's usable and enter
    if (context.get() && context->Enter()) {
      // try to get "appjs.onmessage" function
      CefRefPtr<CefV8Value> appjsObject = context->GetGlobal()->GetValue("appjs");
      CefRefPtr<CefV8Value> callback = appjsObject->GetValue("onmessage");
      if (callback.get()) {

        // convert Node V8 string to Cef V8 string
        CefV8ValueList argsOut;
        argsOut.push_back(CefV8Value::CreateString(V8StringToChar(args[0]->ToString())));

        // execute window.appjs fuction, passing in the string,
        // then convert the return value from a CefValue to a Node V8 string
        Handle<String> ret = CefStringToV8(callback->ExecuteFunction(appjsObject, argsOut)->GetStringValue());

        // exit browser v8 context, return string result to Node caller
        context->Exit();
        return scope.Close(ret);
      }
    }
  }
  // likely error condition
  return scope.Close(Undefined());
}
Ejemplo n.º 2
0
bool ClientApp::OnProcessMessageReceived(
    CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message) {
  ASSERT(source_process == PID_BROWSER);

  bool handled = false;

  RenderDelegateSet::iterator it = render_delegates_.begin();
  for (; it != render_delegates_.end() && !handled; ++it) {
    handled = (*it)->OnProcessMessageReceived(this, browser, source_process,
                                              message);
  }

  if (handled)
    return true;

  // Execute the registered JavaScript callback if any.
  if (!callback_map_.empty()) {
    CefString message_name = message->GetName();
    CallbackMap::const_iterator it = callback_map_.find(
        std::make_pair(message_name.ToString(),
                       browser->GetIdentifier()));
    if (it != callback_map_.end()) {
      // Keep a local reference to the objects. The callback may remove itself
      // from the callback map.
      CefRefPtr<CefV8Context> context = it->second.first;
      CefRefPtr<CefV8Value> callback = it->second.second;

      // Enter the context.
      context->Enter();

      CefV8ValueList arguments;

      // First argument is the message name.
      arguments.push_back(CefV8Value::CreateString(message_name));

      // Second argument is the list of message arguments.
      CefRefPtr<CefListValue> list = message->GetArgumentList();
      CefRefPtr<CefV8Value> args =
          CefV8Value::CreateArray(static_cast<int>(list->GetSize()));
      SetList(list, args);
      arguments.push_back(args);

      // Execute the callback.
      CefRefPtr<CefV8Value> retval = callback->ExecuteFunction(NULL, arguments);
      if (retval.get()) {
        if (retval->IsBool())
          handled = retval->GetBoolValue();
      }

      // Exit the context.
      context->Exit();
    }
  }

  return handled;
}
bool FUnrealCEFSubProcessRemoteScripting::HandleExecuteJSFunctionMessage(CefRefPtr<CefListValue> MessageArguments)
{
	FGuid Guid;

	// Message arguments are CallbackGuid, FunctionArguments, bIsError
	if (MessageArguments->GetSize() != 3
		|| MessageArguments->GetType(0) != VTYPE_STRING
		|| MessageArguments->GetType(1) != VTYPE_LIST
		|| MessageArguments->GetType(2) != VTYPE_BOOL)
	{
		// Wrong message argument types or count
		return false;
	}

	if (!FGuid::Parse(FString(MessageArguments->GetString(0).ToWString().c_str()), Guid))
	{
		// Invalid GUID
		return false;
	}
	if (!CallbackRegistry.Contains(Guid))
	{
		// Unknown callback id
		return false;
	}

	auto Callback = CallbackRegistry[Guid];
	{
		ScopedV8Context ContextScope(Callback.Context);

		bool bIsErrorCallback = MessageArguments->GetBool(2);
		CefRefPtr<CefV8Value> Function = bIsErrorCallback?Callback.OnError:Callback.Function;

		if (!Function.get())
		{
			// Either invalid entry or no error handler
			return false;
		}

		CefV8ValueList FunctionArguments;
		CefToV8Arglist(MessageArguments->GetList(1), FunctionArguments);
		CefRefPtr<CefV8Value> Retval = Function->ExecuteFunction(Callback.Object, FunctionArguments);
		if (!Retval.get())
		{
			// Function call resulted in an error
			return false;
		}

		// Remove callback if it's a one-shot callback and successful.
		if (Callback.bOneShot)
		{
			CallbackRegistry.Remove(Guid);
		}
		return true;
	}
}
Ejemplo n.º 4
0
bool ClientApp::OnProcessMessageReceived(
        CefRefPtr<CefBrowser> browser,
        CefProcessId source_process,
        CefRefPtr<CefProcessMessage> message) {
    ASSERT(source_process == PID_BROWSER);

    bool handled = false;

    // Execute delegate callbacks.
    RenderDelegateSet::iterator it = render_delegates_.begin();
    for (; it != render_delegates_.end() && !handled; ++it) {
        handled = (*it)->OnProcessMessageReceived(this, browser, source_process, message);
    }

    if (!handled) {
        if (message->GetName() == "invokeCallback") {
            // This is called by the appshell extension handler to invoke the asynchronous 
            // callback function
            
            CefRefPtr<CefListValue> messageArgs = message->GetArgumentList();
            int32 callbackId = messageArgs->GetInt(0);
                    
            CefRefPtr<CefV8Context> context = callback_map_[callbackId].first;
            CefRefPtr<CefV8Value> callbackFunction = callback_map_[callbackId].second;
            CefV8ValueList arguments;
            context->Enter();
            
            // Sanity check to make sure the context is still attched to a browser.
            // Async callbacks could be initiated after a browser instance has been deleted,
            // which can lead to bad things. If the browser instance has been deleted, don't
            // invoke this callback. 
            if (context->GetBrowser()) {
                for (size_t i = 1; i < messageArgs->GetSize(); i++) {
                    arguments.push_back(ListValueToV8Value(messageArgs, i));
                }
                
                callbackFunction->ExecuteFunction(NULL, arguments);
            }
            
            context->Exit();
            
            callback_map_.erase(callbackId);
        } else if (message->GetName() == "executeCommand") {
            // This is called by the browser process to execute a command via JavaScript
            // 
            // The first argument is the command name. This is required.
            // The second argument is a message id. This is optional. If set, a response
            // message will be sent back to the browser process.
            
            CefRefPtr<CefListValue> messageArgs = message->GetArgumentList();
            CefString commandName = messageArgs->GetString(0);
            int messageId = messageArgs->GetSize() > 1 ? messageArgs->GetInt(1) : -1;
            bool handled = false;
            
            StContextScope ctx(browser->GetMainFrame()->GetV8Context());
            
            CefRefPtr<CefV8Value> global = ctx.GetContext()->GetGlobal();
            
            if (global->HasValue("brackets")) { 
                
                CefRefPtr<CefV8Value> brackets = global->GetValue("brackets");
                
                if (brackets->HasValue("shellAPI")) {
                    
                    CefRefPtr<CefV8Value> shellAPI = brackets->GetValue("shellAPI");
                    
                    if (shellAPI->HasValue("executeCommand")) {
                        
                        CefRefPtr<CefV8Value> executeCommand = shellAPI->GetValue("executeCommand");
                        
                        if (executeCommand->IsFunction()) {
                            
                            CefRefPtr<CefV8Value> retval;
                            CefV8ValueList args;
                            args.push_back(CefV8Value::CreateString(commandName));
                            
                            retval = executeCommand->ExecuteFunction(global, args);
                            
                            if (retval) {
                                handled = retval->GetBoolValue();
                            }
                        }
                    }
                }
            }
            
            // Return a message saying whether or not the command was handled
            if (messageId != -1) {
                CefRefPtr<CefProcessMessage> result = CefProcessMessage::Create("executeCommandCallback");
                result->GetArgumentList()->SetInt(0, messageId);
                result->GetArgumentList()->SetBool(1, handled);
                
                browser->SendProcessMessage(PID_BROWSER, result);
            }
        }
    }
    
    return handled;
}