// Copyright © 2021-present 650 Industries, Inc. (aka Expo) #include "JavaScriptObject.h" #include "JavaScriptValue.h" #include "JavaScriptRuntime.h" #include "JSITypeConverter.h" namespace expo { void JavaScriptObject::registerNatives() { registerHybrid({ makeNativeMethod("hasProperty", JavaScriptObject::jniHasProperty), makeNativeMethod("getProperty", JavaScriptObject::jniGetProperty), makeNativeMethod("getPropertyNames", JavaScriptObject::jniGetPropertyNames), makeNativeMethod("setBoolProperty", JavaScriptObject::setProperty), makeNativeMethod("setDoubleProperty", JavaScriptObject::setProperty), makeNativeMethod("setStringProperty", JavaScriptObject::setProperty>), makeNativeMethod("setJSValueProperty", JavaScriptObject::setProperty>), makeNativeMethod("setJSObjectProperty", JavaScriptObject::setProperty>), makeNativeMethod("unsetProperty", JavaScriptObject::unsetProperty), makeNativeMethod("defineBoolProperty", JavaScriptObject::defineProperty), makeNativeMethod("defineDoubleProperty", JavaScriptObject::defineProperty), makeNativeMethod("defineStringProperty", JavaScriptObject::defineProperty>), makeNativeMethod("defineJSValueProperty", JavaScriptObject::defineProperty>), makeNativeMethod("defineJSObjectProperty", JavaScriptObject::defineProperty>), }); } JavaScriptObject::JavaScriptObject( std::weak_ptr runtime, std::shared_ptr jsObject ) : runtimeHolder(std::move(runtime)), jsObject(std::move(jsObject)) { runtimeHolder.ensureRuntimeIsValid(); } JavaScriptObject::JavaScriptObject( WeakRuntimeHolder runtime, std::shared_ptr jsObject ) : runtimeHolder(std::move(runtime)), jsObject(std::move(jsObject)) { runtimeHolder.ensureRuntimeIsValid(); } std::shared_ptr JavaScriptObject::get() { return jsObject; } bool JavaScriptObject::hasProperty(const std::string &name) { auto &jsRuntime = runtimeHolder.getJSRuntime(); return jsObject->hasProperty(jsRuntime, name.c_str()); } jsi::Value JavaScriptObject::getProperty(const std::string &name) { auto &jsRuntime = runtimeHolder.getJSRuntime(); return jsObject->getProperty(jsRuntime, name.c_str()); } bool JavaScriptObject::jniHasProperty(jni::alias_ref name) { return hasProperty(name->toStdString()); } jni::local_ref JavaScriptObject::jniGetProperty( jni::alias_ref name ) { auto result = std::make_shared(getProperty(name->toStdString())); return JavaScriptValue::newObjectCxxArgs(runtimeHolder, result); } std::vector JavaScriptObject::getPropertyNames() { auto &jsRuntime = runtimeHolder.getJSRuntime(); jsi::Array properties = jsObject->getPropertyNames(jsRuntime); auto size = properties.size(jsRuntime); std::vector names(size); for (size_t i = 0; i < size; i++) { auto propertyName = properties .getValueAtIndex(jsRuntime, i) .asString(jsRuntime) .utf8(jsRuntime); names[i] = propertyName; } return names; } jni::local_ref> JavaScriptObject::jniGetPropertyNames() { std::vector cResult = getPropertyNames(); auto paredResult = jni::JArrayClass::newArray(cResult.size()); for (size_t i = 0; i < cResult.size(); i++) { paredResult->setElement(i, jni::make_jstring(cResult[i]).get()); } return paredResult; } void JavaScriptObject::setProperty(const std::string &name, jsi::Value value) { auto &jsRuntime = runtimeHolder.getJSRuntime(); jsObject->setProperty(jsRuntime, name.c_str(), value); } void JavaScriptObject::unsetProperty(jni::alias_ref name) { auto &jsRuntime = runtimeHolder.getJSRuntime(); auto cName = name->toStdString(); jsObject->setProperty( jsRuntime, cName.c_str(), jsi::Value::undefined() ); } jsi::Object JavaScriptObject::preparePropertyDescriptor( jsi::Runtime &jsRuntime, int options ) { jsi::Object descriptor(jsRuntime); descriptor.setProperty(jsRuntime, "configurable", (bool) ((1 << 0) & options)); descriptor.setProperty(jsRuntime, "enumerable", (bool) ((1 << 1) & options)); descriptor.setProperty(jsRuntime, "writable", (bool) ((1 << 2) & options)); return descriptor; } } // namespace expo