CefRefPtr<CefListValue> FUnrealCEFSubProcessRemoteScripting::V8ArrayToCef(CefRefPtr<CefV8Value> Array)
{
	CefRefPtr<CefListValue> Result = CefListValue::Create();
	if (Array->IsArray())
	{
		for (int I = 0; I < Array->GetArrayLength(); ++I)
		{
			V8ToCef(Result, Array, I, Array->GetValue(I));
		}
	}
	return Result;
}
Beispiel #2
0
// Transfer a V8 array to a List.
void SetList(CefRefPtr<CefV8Value> source, CefRefPtr<CefListValue> target) {
    ASSERT(source->IsArray());

    int arg_length = source->GetArrayLength();
    if (arg_length == 0)
        return;

    // Start with null types in all spaces.
    target->SetSize(arg_length);

    for (int i = 0; i < arg_length; ++i)
        SetListValue(target, i, source->GetValue(i));
}
bool FUnrealCEFSubProcessRemoteObject::ExecuteMethod(const CefString& MethodName, CefRefPtr<CefV8Value> Object, const CefV8ValueList& Arguments, CefRefPtr<CefV8Value>& Retval, CefString& InException)
{
	CefRefPtr<CefV8Context> Context = CefV8Context::GetCurrentContext();
	CefRefPtr<CefV8Exception> Exception;
	CefRefPtr<CefV8Value> PromiseObjects;

	// Run JS code that creates and unwraps a Promise object
	if (!Context->Eval(
		"(function() " \
		"{ "
		"	var Accept, Reject, PromiseObject;" \
		"	PromiseObject = new Promise(function(InAccept, InReject) " \
		"	{"
		"		Accept = InAccept;" \
		"		Reject = InReject;" \
		"	});" \
		"	return [PromiseObject, Accept, Reject];" \
		"})()" , PromiseObjects, Exception))
	{
		InException = Exception->GetMessage();
		return false;
	}

	if (!(PromiseObjects.get() && PromiseObjects->IsArray() && PromiseObjects->GetArrayLength() == 3))
	{
		return false;
	}

	Retval = PromiseObjects->GetValue(0);
	CefRefPtr<CefV8Value> Accept = PromiseObjects->GetValue(1);
	CefRefPtr<CefV8Value> Reject = PromiseObjects->GetValue(2);

	check(Retval->IsObject());
	check(Accept->IsFunction());
	check(Reject->IsFunction());

	FGuid CallbackGuid = RemoteScripting->CallbackRegistry.FindOrAdd(Context, Retval, Accept, Reject, true);
	CefRefPtr<CefProcessMessage> Message = CefProcessMessage::Create("UE::ExecuteUObjectMethod");
	CefRefPtr<CefListValue> MessageArguments = Message->GetArgumentList();
	MessageArguments->SetString(0, CefString(*ObjectId.ToString(EGuidFormats::Digits)));
	MessageArguments->SetString(1, MethodName);
	MessageArguments->SetString(2, CefString(*CallbackGuid.ToString(EGuidFormats::Digits)));
	MessageArguments->SetList(3, RemoteScripting->V8ArrayToCef(Arguments));

	Browser->SendProcessMessage(PID_BROWSER, Message);

	return true;
}
Beispiel #4
0
 // Simple function for formatted output of a V8 value.
 void PrintValue(CefRefPtr<CefV8Value> value, std::stringstream &stream,
                 int indent)
 {
   std::stringstream indent_stream;
   for(int i = 0; i < indent; ++i)
     indent_stream << "  ";
   std::string indent_str = indent_stream.str();
   
   if(value->IsUndefined())
     stream << "(undefined)";
   else if(value->IsNull())
     stream << "(null)";
   else if(value->IsBool())
     stream << "(bool) " << (value->GetBoolValue() ? "true" : "false");
   else if(value->IsInt())
     stream << "(int) " << value->GetIntValue();
   else if(value->IsDouble())
     stream << "(double) " << value->GetDoubleValue();
   else if(value->IsString())
     stream << "(string) " << std::string(value->GetStringValue());
   else if(value->IsFunction())
     stream << "(function) " << std::string(value->GetFunctionName());
   else if(value->IsArray()) {
     stream << "(array) [";
     int len = value->GetArrayLength();
     for(int i = 0; i < len; ++i) {
       stream << "\n  " << indent_str.c_str() << i << " = ";
       PrintValue(value->GetValue(i), stream, indent+1);
     }
     stream << "\n" << indent_str.c_str() << "]";
   } else if(value->IsObject()) {
     stream << "(object) [";
     std::vector<CefString> keys;
     if(value->GetKeys(keys)) {
       for(size_t i = 0; i < keys.size(); ++i) {
         stream << "\n  " << indent_str.c_str() << keys[i].c_str() << " = ";
         PrintValue(value->GetValue(keys[i]), stream, indent+1);
       }
     }
     stream << "\n" << indent_str.c_str() << "]";
   }
 }
CefRefPtr<CefV8Value> IPC_Container::GetAttributesV8Value(
    CefRefPtr<CefV8Context> context,
    std::string array_variable,
    int obj_index_in_array,
    ContainerAttribute attr)
{
    CefRefPtr<CefV8Value> containerObjArray = context->GetGlobal()->GetValue(array_variable);

    if (obj_index_in_array < containerObjArray->GetArrayLength())
    {
        CefRefPtr<CefV8Value> containerObj = containerObjArray->GetValue(obj_index_in_array);

        // Get objects attribute by attribute's name
        return containerObj->GetValue(attr.GetName());
    }
    else
    {
        // DLOG(WARNING) << "WARNING: V8ArrayLength not as big as expected!";
        // TODO: Handle NULL in following steps...
        return CefV8Value::CreateNull();
    }
}
Beispiel #6
0
void V8ValueAppendToCefListValue(CefRefPtr<CefV8Value> v8Value,
                                 CefRefPtr<CefListValue> listValue,
                                 int nestingLevel) {
    if (!v8Value->IsValid()) {
        DebugLog("V8ValueAppendToCefListValue(): IsValid() FAILED");
        return;
    }
    if (nestingLevel > 8) {
        DebugLog("V8ValueAppendToCefListValue(): WARNING: max nesting level (8) " \
                "exceeded");
        return;
    }
    if (v8Value->IsUndefined() || v8Value->IsNull()) {
        listValue->SetNull((int)listValue->GetSize());
    } else if (v8Value->IsBool()) {
        listValue->SetBool((int)listValue->GetSize(), v8Value->GetBoolValue());
    } else if (v8Value->IsInt()) {
        listValue->SetInt((int)listValue->GetSize(), v8Value->GetIntValue());
    } else if (v8Value->IsUInt()) {
        uint32 uint32_value = v8Value->GetUIntValue();
        CefRefPtr<CefBinaryValue> binaryValue = CefBinaryValue::Create(
            &uint32_value, sizeof(uint32_value));
        listValue->SetBinary((int)listValue->GetSize(), binaryValue);
    } else if (v8Value->IsDouble()) {
        listValue->SetDouble((int)listValue->GetSize(), v8Value->GetDoubleValue());
    } else if (v8Value->IsDate()) {
        // TODO: in time_utils.pyx there are already functions for
        // converting cef_time_t to python DateTime, we could easily
        // add a new function for converting the python DateTime to
        // string and then to CefString and expose the function using
        // the "public" keyword. But how do we get the cef_time_t
        // structure from the CefTime class? GetDateValue() returns
        // CefTime class.
        listValue->SetNull((int)listValue->GetSize());
    } else if (v8Value->IsString()) {
        listValue->SetString((int)listValue->GetSize(), v8Value->GetStringValue());
    } else if (v8Value->IsArray()) {
        // Check for IsArray() must happen before the IsObject() check.
        int length = v8Value->GetArrayLength();
        CefRefPtr<CefListValue> newListValue = CefListValue::Create();
        for (int i = 0; i < length; ++i) {
            V8ValueAppendToCefListValue(v8Value->GetValue(i), newListValue,
                    nestingLevel + 1);
        }
        listValue->SetList((int)listValue->GetSize(), newListValue);
    } else if (v8Value->IsFunction()) {
        // Check for IsFunction() must happen before the IsObject() check.
        if (CefV8Context::InContext()) {
            CefRefPtr<CefV8Context> context = \
                    CefV8Context::GetCurrentContext();
            CefRefPtr<CefFrame> frame = context->GetFrame();
            std::string strCallbackId = PutJavascriptCallback(frame, v8Value);
            /* strCallbackId = '####cefpython####' \
                               '{"what"=>"javascript-callback", ..}' */
            listValue->SetString((int)listValue->GetSize(), strCallbackId);
        } else {
            listValue->SetNull((int)listValue->GetSize());
            DebugLog("V8ValueAppendToCefListValue() FAILED: not in V8 context"
                    " , FATAL ERROR!");
        }
    } else if (v8Value->IsObject()) {
        // Check for IsObject() must happen after the IsArray()
        // and IsFunction() checks.
        listValue->SetDictionary((int)listValue->GetSize(),
                V8ObjectToCefDictionaryValue(v8Value, nestingLevel + 1));
    } else {
        listValue->SetNull((int)listValue->GetSize());
        DebugLog("V8ValueAppendToCefListValue() FAILED: unknown V8 type");
    }
}
	virtual bool Execute(const CefString& InName,
		CefRefPtr<CefV8Value> InObject,
		const CefV8ValueList& InArguments,
		CefRefPtr<CefV8Value>& OutRetval,
		CefString& OutException)
	{
		bool Handled = false;
		bool ValidAPI = true;

		if (InName == "TriggerEvent")
		{
			// dispatch hook to the browser process for execution on the game thread
			if ((InArguments.size() == 1) && InArguments[0]->IsArray())
			{
				CefRefPtr<CefV8Value> ArgumentArray = InArguments[0];
				if (ArgumentArray->GetArrayLength() > 0)
				{
					CefRefPtr<CefBrowser> Browser = CefV8Context::GetCurrentContext()->GetBrowser();
					ASSERT(Browser.get());

					CefString HookName = ArgumentArray->GetValue(0)->GetStringValue();
					if (!HookName.empty())
					{
						CefRefPtr<CefProcessMessage> Message = CefProcessMessage::Create(HookName);

						// translate remaining args.
						if ((ArgumentArray->GetArrayLength() > 1) && ArgumentArray->GetValue(1)->IsArray())
						{
							CefRefPtr<CefV8Value> InParameters = ArgumentArray->GetValue(1);
							const int NumParameters = InParameters->GetArrayLength();

							CefRefPtr<CefListValue> OutParameters = Message->GetArgumentList();
							OutParameters->SetSize(NumParameters);

							for (int i = 0; i < (int)NumParameters; ++i)
							{
								V8ValueToListItem_RenderThread(InParameters->GetValue(i), OutParameters, i);
							}
						}

						Browser->SendProcessMessage(PID_BROWSER, Message);
						Handled = true;
					}
				}
			}
		}
		else if (InName == "SetHook")
		{
			if ((InArguments.size() == 2) && (InArguments[0]->IsString()) && (InArguments[1]->IsFunction()))
			{
				CefString HookName = InArguments[0]->GetStringValue().ToString();
				CefRefPtr<CefV8Context> Context = CefV8Context::GetCurrentContext();
				App->SetJSHook(HookName, Context->GetBrowser()->GetIdentifier(), Context, InArguments[1]);
				Handled = true;
			}
		}
		else if (InName == "RemoveHook")
		{
			if ((InArguments.size() == 1) && InArguments[0]->IsString())
			{
				CefRefPtr<CefV8Context> Context = CefV8Context::GetCurrentContext();
				App->RemoveJSHook(InArguments[0]->GetStringValue(), Context->GetBrowser()->GetIdentifier());
				Handled = true;
			}
		}
		else
		{
			ValidAPI = false;
			OutException = std::string("Unrecognized JSHook API Call: '") + InName.ToString() + std::string("'");
		}

		if (!Handled && ValidAPI)
		{
			OutException = std::string("Invalid Arguments Passed To '") + InName.ToString() + std::string("'");
		}

		return Handled;
	}