mirror of
https://github.com/oven-sh/bun
synced 2026-02-16 22:01:47 +00:00
Compare commits
1 Commits
claude/fix
...
cursor/cre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddb5866a94 |
@@ -92,6 +92,10 @@ src/bun.js/bindings/JSWrappingFunction.cpp
|
||||
src/bun.js/bindings/JSX509Certificate.cpp
|
||||
src/bun.js/bindings/JSX509CertificateConstructor.cpp
|
||||
src/bun.js/bindings/JSX509CertificatePrototype.cpp
|
||||
src/bun.js/bindings/JSYogaConfig.cpp
|
||||
src/bun.js/bindings/JSYogaConstructor.cpp
|
||||
src/bun.js/bindings/JSYogaNode.cpp
|
||||
src/bun.js/bindings/JSYogaPrototype.cpp
|
||||
src/bun.js/bindings/linux_perf_tracing.cpp
|
||||
src/bun.js/bindings/MarkingConstraint.cpp
|
||||
src/bun.js/bindings/ModuleLoader.cpp
|
||||
|
||||
58
src/bun.js/bindings/JSYogaConfig.cpp
Normal file
58
src/bun.js/bindings/JSYogaConfig.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "root.h"
|
||||
#include "JSYogaConfig.h"
|
||||
#include <JavaScriptCore/ObjectConstructor.h>
|
||||
|
||||
namespace Bun {
|
||||
|
||||
const JSC::ClassInfo JSYogaConfig::s_info = { "Yoga.Config"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSYogaConfig) };
|
||||
|
||||
JSYogaConfig::JSYogaConfig(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure)
|
||||
, m_config(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
JSYogaConfig::~JSYogaConfig()
|
||||
{
|
||||
if (m_config) {
|
||||
YGConfigFree(m_config);
|
||||
}
|
||||
}
|
||||
|
||||
JSYogaConfig* JSYogaConfig::create(JSC::VM& vm, JSC::Structure* structure)
|
||||
{
|
||||
JSYogaConfig* config = new (NotNull, JSC::allocateCell<JSYogaConfig>(vm)) JSYogaConfig(vm, structure);
|
||||
config->finishCreation(vm);
|
||||
return config;
|
||||
}
|
||||
|
||||
void JSYogaConfig::finishCreation(JSC::VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
m_config = YGConfigNew();
|
||||
}
|
||||
|
||||
void JSYogaConfig::destroy(JSC::JSCell* cell)
|
||||
{
|
||||
static_cast<JSYogaConfig*>(cell)->~JSYogaConfig();
|
||||
}
|
||||
|
||||
JSC::Structure* JSYogaConfig::createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
|
||||
}
|
||||
|
||||
template<typename, JSC::SubspaceAccess mode>
|
||||
JSC::GCClient::IsoSubspace* JSYogaConfig::subspaceFor(JSC::VM& vm)
|
||||
{
|
||||
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
|
||||
return nullptr;
|
||||
return WebCore::subspaceForImpl<JSYogaConfig, WebCore::UseCustomHeapCellType::No>(
|
||||
vm,
|
||||
[](auto& spaces) { return spaces.m_clientSubspaceForJSYogaConfig.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSYogaConfig = std::forward<decltype(space)>(space); },
|
||||
[](auto& spaces) { return spaces.m_subspaceForJSYogaConfig.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForJSYogaConfig = std::forward<decltype(space)>(space); });
|
||||
}
|
||||
|
||||
} // namespace Bun
|
||||
31
src/bun.js/bindings/JSYogaConfig.h
Normal file
31
src/bun.js/bindings/JSYogaConfig.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "root.h"
|
||||
#include "vendor/yoga/yoga/Yoga.h"
|
||||
#include <JavaScriptCore/JSDestructibleObject.h>
|
||||
#include <memory>
|
||||
|
||||
namespace Bun {
|
||||
|
||||
class JSYogaConfig final : public JSC::JSDestructibleObject {
|
||||
public:
|
||||
using Base = JSC::JSDestructibleObject;
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
static constexpr JSC::DestructionMode needsDestruction = JSC::NeedsDestruction;
|
||||
|
||||
static JSYogaConfig* create(JSC::VM&, JSC::Structure*);
|
||||
static void destroy(JSC::JSCell*);
|
||||
static JSC::Structure* createStructure(JSC::VM&, JSC::JSGlobalObject*, JSC::JSValue);
|
||||
~JSYogaConfig();
|
||||
|
||||
template<typename, JSC::SubspaceAccess> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM&);
|
||||
DECLARE_INFO;
|
||||
|
||||
YGConfigRef internal() { return m_config; }
|
||||
|
||||
private:
|
||||
JSYogaConfig(JSC::VM&, JSC::Structure*);
|
||||
void finishCreation(JSC::VM&);
|
||||
YGConfigRef m_config;
|
||||
};
|
||||
|
||||
} // namespace Bun
|
||||
102
src/bun.js/bindings/JSYogaConstructor.cpp
Normal file
102
src/bun.js/bindings/JSYogaConstructor.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "root.h"
|
||||
#include "JSYogaConfig.h"
|
||||
#include "JSYogaNode.h"
|
||||
#include "JSYogaPrototype.h"
|
||||
#include "JSYogaConstructor.h"
|
||||
#include <JavaScriptCore/JSCInlines.h>
|
||||
#include <JavaScriptCore/ObjectConstructor.h>
|
||||
#include "ZigGlobalObject.h"
|
||||
|
||||
namespace Bun {
|
||||
|
||||
// ================ JSYogaConfig Constructor ================
|
||||
|
||||
const JSC::ClassInfo JSYogaConfigConstructor::s_info = { "ConfigConstructor"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSYogaConfigConstructor) };
|
||||
|
||||
void JSYogaConfigConstructor::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype)
|
||||
{
|
||||
Base::finishCreation(vm, 0, "Config"_s);
|
||||
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(constructJSYogaConfig, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto* zigGlobal = Bun::defaultGlobalObject(globalObject);
|
||||
|
||||
// Get the pre-initialized structure from the global object
|
||||
JSC::Structure* structure = zigGlobal->m_JSYogaConfigClassStructure.get(zigGlobal);
|
||||
|
||||
// Create new Config instance
|
||||
return JSC::JSValue::encode(JSYogaConfig::create(vm, structure));
|
||||
}
|
||||
|
||||
// ================ JSYogaNode Constructor ================
|
||||
|
||||
const JSC::ClassInfo JSYogaNodeConstructor::s_info = { "NodeConstructor"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSYogaNodeConstructor) };
|
||||
|
||||
void JSYogaNodeConstructor::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype)
|
||||
{
|
||||
Base::finishCreation(vm, 1, "Node"_s);
|
||||
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(constructJSYogaNode, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
auto* zigGlobal = Bun::defaultGlobalObject(globalObject);
|
||||
|
||||
// Get the pre-initialized structure from the global object
|
||||
JSC::Structure* structure = zigGlobal->m_JSYogaNodeClassStructure.get(zigGlobal);
|
||||
|
||||
// Check if a config was provided as the first argument
|
||||
YGConfigRef config = nullptr;
|
||||
if (callFrame->argumentCount() > 0) {
|
||||
JSC::JSValue configValue = callFrame->argument(0);
|
||||
if (!configValue.isUndefinedOrNull()) {
|
||||
auto* configObject = jsDynamicCast<JSYogaConfig*>(configValue);
|
||||
if (UNLIKELY(!configObject)) {
|
||||
return JSC::JSValue::encode(throwTypeError(globalObject, scope, "First argument must be a Yoga.Config instance"_s));
|
||||
}
|
||||
config = configObject->internal();
|
||||
}
|
||||
}
|
||||
|
||||
// Create new Node instance
|
||||
return JSC::JSValue::encode(JSYogaNode::create(vm, structure, config));
|
||||
}
|
||||
|
||||
// ================ Setup Functions ================
|
||||
|
||||
void setupJSYogaConfigClassStructure(JSC::LazyClassStructure::Initializer& init)
|
||||
{
|
||||
auto* prototypeStructure = JSYogaConfigPrototype::createStructure(init.vm, init.global, init.global->objectPrototype());
|
||||
auto* prototype = JSYogaConfigPrototype::create(init.vm, init.global, prototypeStructure);
|
||||
|
||||
auto* constructorStructure = JSYogaConfigConstructor::createStructure(init.vm, init.global, init.global->functionPrototype());
|
||||
auto* constructor = JSYogaConfigConstructor::create(init.vm, init.global, constructorStructure, prototype);
|
||||
|
||||
auto* structure = JSYogaConfig::createStructure(init.vm, init.global, prototype);
|
||||
|
||||
init.setPrototype(prototype);
|
||||
init.setStructure(structure);
|
||||
init.setConstructor(constructor);
|
||||
}
|
||||
|
||||
void setupJSYogaNodeClassStructure(JSC::LazyClassStructure::Initializer& init)
|
||||
{
|
||||
auto* prototypeStructure = JSYogaNodePrototype::createStructure(init.vm, init.global, init.global->objectPrototype());
|
||||
auto* prototype = JSYogaNodePrototype::create(init.vm, init.global, prototypeStructure);
|
||||
|
||||
auto* constructorStructure = JSYogaNodeConstructor::createStructure(init.vm, init.global, init.global->functionPrototype());
|
||||
auto* constructor = JSYogaNodeConstructor::create(init.vm, init.global, constructorStructure, prototype);
|
||||
|
||||
auto* structure = JSYogaNode::createStructure(init.vm, init.global, prototype);
|
||||
|
||||
init.setPrototype(prototype);
|
||||
init.setStructure(structure);
|
||||
init.setConstructor(constructor);
|
||||
}
|
||||
|
||||
} // namespace Bun
|
||||
73
src/bun.js/bindings/JSYogaConstructor.h
Normal file
73
src/bun.js/bindings/JSYogaConstructor.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
#include "root.h"
|
||||
#include <JavaScriptCore/InternalFunction.h>
|
||||
|
||||
namespace Bun {
|
||||
|
||||
// JSYogaConfig Constructor
|
||||
class JSYogaConfigConstructor final : public JSC::InternalFunction {
|
||||
public:
|
||||
using Base = JSC::InternalFunction;
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
|
||||
static JSYogaConfigConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype)
|
||||
{
|
||||
JSYogaConfigConstructor* constructor = new (NotNull, JSC::allocateCell<JSYogaConfigConstructor>(vm)) JSYogaConfigConstructor(vm, structure);
|
||||
constructor->finishCreation(vm, globalObject, prototype);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
DECLARE_INFO;
|
||||
|
||||
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
|
||||
}
|
||||
|
||||
private:
|
||||
JSYogaConfigConstructor(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure, constructJSYogaConfig, constructJSYogaConfig)
|
||||
{
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM&, JSC::JSGlobalObject*, JSC::JSObject*);
|
||||
};
|
||||
|
||||
// JSYogaNode Constructor
|
||||
class JSYogaNodeConstructor final : public JSC::InternalFunction {
|
||||
public:
|
||||
using Base = JSC::InternalFunction;
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
|
||||
static JSYogaNodeConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype)
|
||||
{
|
||||
JSYogaNodeConstructor* constructor = new (NotNull, JSC::allocateCell<JSYogaNodeConstructor>(vm)) JSYogaNodeConstructor(vm, structure);
|
||||
constructor->finishCreation(vm, globalObject, prototype);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
DECLARE_INFO;
|
||||
|
||||
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
|
||||
}
|
||||
|
||||
private:
|
||||
JSYogaNodeConstructor(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure, constructJSYogaNode, constructJSYogaNode)
|
||||
{
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM&, JSC::JSGlobalObject*, JSC::JSObject*);
|
||||
};
|
||||
|
||||
// Forward declarations for construct functions
|
||||
JSC_DECLARE_HOST_FUNCTION(constructJSYogaConfig);
|
||||
JSC_DECLARE_HOST_FUNCTION(constructJSYogaNode);
|
||||
|
||||
// Setup functions for lazy class structure initialization
|
||||
void setupJSYogaConfigClassStructure(JSC::LazyClassStructure::Initializer&);
|
||||
void setupJSYogaNodeClassStructure(JSC::LazyClassStructure::Initializer&);
|
||||
|
||||
} // namespace Bun
|
||||
79
src/bun.js/bindings/JSYogaNode.cpp
Normal file
79
src/bun.js/bindings/JSYogaNode.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "root.h"
|
||||
#include "JSYogaNode.h"
|
||||
#include <JavaScriptCore/ObjectConstructor.h>
|
||||
|
||||
namespace Bun {
|
||||
|
||||
const JSC::ClassInfo JSYogaNode::s_info = { "Yoga.Node"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSYogaNode) };
|
||||
|
||||
JSYogaNode::JSYogaNode(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure)
|
||||
, m_node(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
JSYogaNode::~JSYogaNode()
|
||||
{
|
||||
if (m_node) {
|
||||
YGNodeFreeRecursive(m_node);
|
||||
}
|
||||
}
|
||||
|
||||
JSYogaNode* JSYogaNode::create(JSC::VM& vm, JSC::Structure* structure, YGConfigRef config)
|
||||
{
|
||||
JSYogaNode* node = new (NotNull, JSC::allocateCell<JSYogaNode>(vm)) JSYogaNode(vm, structure);
|
||||
node->finishCreation(vm, config);
|
||||
return node;
|
||||
}
|
||||
|
||||
void JSYogaNode::finishCreation(JSC::VM& vm, YGConfigRef config)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
if (config) {
|
||||
m_node = YGNodeNewWithConfig(config);
|
||||
} else {
|
||||
m_node = YGNodeNew();
|
||||
}
|
||||
// This is the essential link that enables callbacks and hierarchy traversal
|
||||
YGNodeSetContext(m_node, this);
|
||||
}
|
||||
|
||||
void JSYogaNode::destroy(JSC::JSCell* cell)
|
||||
{
|
||||
static_cast<JSYogaNode*>(cell)->~JSYogaNode();
|
||||
}
|
||||
|
||||
JSC::Structure* JSYogaNode::createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
|
||||
}
|
||||
|
||||
JSYogaNode* JSYogaNode::fromYGNode(YGNodeRef nodeRef)
|
||||
{
|
||||
if (!nodeRef) return nullptr;
|
||||
return static_cast<JSYogaNode*>(YGNodeGetContext(nodeRef));
|
||||
}
|
||||
|
||||
DEFINE_VISIT_CHILDREN(JSYogaNode);
|
||||
void JSYogaNode::visitChildrenImpl(JSC::JSCell* cell, JSC::Visitor& visitor)
|
||||
{
|
||||
JSYogaNode* thisObject = jsCast<JSYogaNode*>(cell);
|
||||
Base::visitChildren(thisObject, visitor);
|
||||
visitor.append(thisObject->m_measureFunc);
|
||||
visitor.append(thisObject->m_dirtiedFunc);
|
||||
}
|
||||
|
||||
template<typename, JSC::SubspaceAccess mode>
|
||||
JSC::GCClient::IsoSubspace* JSYogaNode::subspaceFor(JSC::VM& vm)
|
||||
{
|
||||
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
|
||||
return nullptr;
|
||||
return WebCore::subspaceForImpl<JSYogaNode, WebCore::UseCustomHeapCellType::No>(
|
||||
vm,
|
||||
[](auto& spaces) { return spaces.m_clientSubspaceForJSYogaNode.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSYogaNode = std::forward<decltype(space)>(space); },
|
||||
[](auto& spaces) { return spaces.m_subspaceForJSYogaNode.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForJSYogaNode = std::forward<decltype(space)>(space); });
|
||||
}
|
||||
|
||||
} // namespace Bun
|
||||
37
src/bun.js/bindings/JSYogaNode.h
Normal file
37
src/bun.js/bindings/JSYogaNode.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include "root.h"
|
||||
#include "vendor/yoga/yoga/Yoga.h"
|
||||
#include <JavaScriptCore/JSDestructibleObject.h>
|
||||
#include <JavaScriptCore/Strong.h>
|
||||
#include <memory>
|
||||
|
||||
namespace Bun {
|
||||
|
||||
class JSYogaNode final : public JSC::JSDestructibleObject {
|
||||
public:
|
||||
using Base = JSC::JSDestructibleObject;
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
static constexpr JSC::DestructionMode needsDestruction = JSC::NeedsDestruction;
|
||||
|
||||
static JSYogaNode* create(JSC::VM&, JSC::Structure*, YGConfigRef config = nullptr);
|
||||
static void destroy(JSC::JSCell*);
|
||||
static JSC::Structure* createStructure(JSC::VM&, JSC::JSGlobalObject*, JSC::JSValue);
|
||||
static JSYogaNode* fromYGNode(YGNodeRef);
|
||||
~JSYogaNode();
|
||||
|
||||
template<typename, JSC::SubspaceAccess> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM&);
|
||||
DECLARE_INFO;
|
||||
DECLARE_VISIT_CHILDREN;
|
||||
|
||||
YGNodeRef internal() { return m_node; }
|
||||
|
||||
JSC::Strong<JSC::JSObject> m_measureFunc;
|
||||
JSC::Strong<JSC::JSObject> m_dirtiedFunc;
|
||||
|
||||
private:
|
||||
JSYogaNode(JSC::VM&, JSC::Structure*);
|
||||
void finishCreation(JSC::VM&, YGConfigRef config);
|
||||
YGNodeRef m_node;
|
||||
};
|
||||
|
||||
} // namespace Bun
|
||||
535
src/bun.js/bindings/JSYogaPrototype.cpp
Normal file
535
src/bun.js/bindings/JSYogaPrototype.cpp
Normal file
@@ -0,0 +1,535 @@
|
||||
#include "root.h"
|
||||
#include "JSYogaConfig.h"
|
||||
#include "JSYogaNode.h"
|
||||
#include "JSYogaPrototype.h"
|
||||
#include <JavaScriptCore/JSCInlines.h>
|
||||
#include <JavaScriptCore/PropertyTable.h>
|
||||
|
||||
namespace Bun {
|
||||
|
||||
// ================ JSYogaConfigPrototype Implementation ================
|
||||
|
||||
// Declare all host functions for the Config prototype
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaConfigProtoFuncSetUseWebDefaults);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaConfigProtoFuncUseWebDefaults);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaConfigProtoFuncSetPointScaleFactor);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaConfigProtoFuncIsExperimentalFeatureEnabled);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaConfigProtoFuncSetExperimentalFeatureEnabled);
|
||||
|
||||
// Define the static hash table for Config properties
|
||||
static const JSC::HashTableValue JSYogaConfigPrototypeTableValues[] = {
|
||||
{ "setUseWebDefaults"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaConfigProtoFuncSetUseWebDefaults, 1 } },
|
||||
{ "useWebDefaults"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaConfigProtoFuncUseWebDefaults, 0 } },
|
||||
{ "setPointScaleFactor"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaConfigProtoFuncSetPointScaleFactor, 1 } },
|
||||
{ "isExperimentalFeatureEnabled"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaConfigProtoFuncIsExperimentalFeatureEnabled, 1 } },
|
||||
{ "setExperimentalFeatureEnabled"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaConfigProtoFuncSetExperimentalFeatureEnabled, 2 } },
|
||||
};
|
||||
|
||||
const JSC::ClassInfo JSYogaConfigPrototype::s_info = { "Yoga.Config"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSYogaConfigPrototype) };
|
||||
|
||||
void JSYogaConfigPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
reifyStaticProperties(vm, JSYogaConfig::info(), JSYogaConfigPrototypeTableValues, *this);
|
||||
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
|
||||
}
|
||||
|
||||
// Config method implementations
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaConfigProtoFuncSetUseWebDefaults, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaConfig*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Config", "setUseWebDefaults"));
|
||||
}
|
||||
|
||||
bool enabled = callFrame->argument(0).toBoolean(globalObject);
|
||||
YGConfigSetUseWebDefaults(thisObject->internal(), enabled);
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaConfigProtoFuncUseWebDefaults, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaConfig*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Config", "useWebDefaults"));
|
||||
}
|
||||
|
||||
bool result = YGConfigGetUseWebDefaults(thisObject->internal());
|
||||
return JSC::JSValue::encode(JSC::jsBoolean(result));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaConfigProtoFuncSetPointScaleFactor, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaConfig*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Config", "setPointScaleFactor"));
|
||||
}
|
||||
|
||||
float factor = callFrame->argument(0).toFloat(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
YGConfigSetPointScaleFactor(thisObject->internal(), factor);
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaConfigProtoFuncIsExperimentalFeatureEnabled, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaConfig*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Config", "isExperimentalFeatureEnabled"));
|
||||
}
|
||||
|
||||
int featureInt = callFrame->argument(0).toInt32(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
bool result = YGConfigIsExperimentalFeatureEnabled(thisObject->internal(), static_cast<YGExperimentalFeature>(featureInt));
|
||||
return JSC::JSValue::encode(JSC::jsBoolean(result));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaConfigProtoFuncSetExperimentalFeatureEnabled, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaConfig*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Config", "setExperimentalFeatureEnabled"));
|
||||
}
|
||||
|
||||
int featureInt = callFrame->argument(0).toInt32(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
bool enabled = callFrame->argument(1).toBoolean(globalObject);
|
||||
YGConfigSetExperimentalFeatureEnabled(thisObject->internal(), static_cast<YGExperimentalFeature>(featureInt), enabled);
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
// ================ JSYogaNodePrototype Implementation ================
|
||||
|
||||
// Declare all host functions for the Node prototype
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncCalculateLayout);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncCopyStyle);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncFree);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncFreeRecursive);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetChild);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetChildCount);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedBorder);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedBottom);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedHeight);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedLayout);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedLeft);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedMargin);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedPadding);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedRight);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedTop);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedWidth);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetParent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncInsertChild);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncIsDirty);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncMarkDirty);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncRemoveChild);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncReset);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAlignContent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAlignItems);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAlignSelf);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAspectRatio);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetBorder);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetDisplay);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlex);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexBasis);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexBasisPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexDirection);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexGrow);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexShrink);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexWrap);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetGap);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetHeight);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetHeightAuto);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetHeightPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetJustifyContent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMargin);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMarginAuto);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMarginPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxHeight);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxHeightPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxWidth);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxWidthPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMeasureFunc);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinHeight);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinHeightPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinWidth);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinWidthPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetOverflow);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPadding);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPaddingPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPosition);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPositionPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPositionType);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetWidth);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetWidthAuto);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetWidthPercent);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncUnsetMeasureFunc);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncSetDirtiedFunc);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncUnsetDirtiedFunc);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsYogaNodeProtoFuncGetDirtiedFunc);
|
||||
|
||||
// Define the static hash table for Node properties (partial implementation)
|
||||
static const JSC::HashTableValue JSYogaNodePrototypeTableValues[] = {
|
||||
{ "calculateLayout"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncCalculateLayout, 3 } },
|
||||
{ "copyStyle"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncCopyStyle, 1 } },
|
||||
{ "free"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncFree, 0 } },
|
||||
{ "freeRecursive"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncFreeRecursive, 0 } },
|
||||
{ "getChild"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncGetChild, 1 } },
|
||||
{ "getChildCount"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncGetChildCount, 0 } },
|
||||
{ "getComputedLayout"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncGetComputedLayout, 0 } },
|
||||
{ "getParent"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncGetParent, 0 } },
|
||||
{ "insertChild"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncInsertChild, 2 } },
|
||||
{ "isDirty"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncIsDirty, 0 } },
|
||||
{ "markDirty"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncMarkDirty, 0 } },
|
||||
{ "removeChild"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncRemoveChild, 1 } },
|
||||
{ "reset"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncReset, 0 } },
|
||||
{ "setWidth"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncSetWidth, 1 } },
|
||||
{ "setHeight"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncSetHeight, 1 } },
|
||||
{ "setMeasureFunc"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncSetMeasureFunc, 1 } },
|
||||
{ "unsetMeasureFunc"_s, JSC::PropertyAttribute::Function, JSC::NoIntrinsic, { JSC::HashTableValue::NativeFunctionType, jsYogaNodeProtoFuncUnsetMeasureFunc, 0 } },
|
||||
};
|
||||
|
||||
const JSC::ClassInfo JSYogaNodePrototype::s_info = { "Yoga.Node"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSYogaNodePrototype) };
|
||||
|
||||
void JSYogaNodePrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
reifyStaticProperties(vm, JSYogaNode::info(), JSYogaNodePrototypeTableValues, *this);
|
||||
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
|
||||
}
|
||||
|
||||
// Node method implementations (partial - just a few key ones)
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncCalculateLayout, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "calculateLayout"));
|
||||
}
|
||||
|
||||
float width = YGUndefined;
|
||||
float height = YGUndefined;
|
||||
YGDirection direction = YGDirectionLTR;
|
||||
|
||||
if (callFrame->argumentCount() > 0) {
|
||||
width = callFrame->argument(0).toFloat(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
}
|
||||
if (callFrame->argumentCount() > 1) {
|
||||
height = callFrame->argument(1).toFloat(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
}
|
||||
if (callFrame->argumentCount() > 2) {
|
||||
direction = static_cast<YGDirection>(callFrame->argument(2).toInt32(globalObject));
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
}
|
||||
|
||||
YGNodeCalculateLayout(thisObject->internal(), width, height, direction);
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedLayout, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "getComputedLayout"));
|
||||
}
|
||||
|
||||
auto* node = thisObject->internal();
|
||||
JSC::JSObject* result = JSC::constructEmptyObject(globalObject);
|
||||
|
||||
result->putDirect(vm, vm.propertyNames->left, JSC::jsNumber(YGNodeLayoutGetLeft(node)));
|
||||
result->putDirect(vm, vm.propertyNames->top, JSC::jsNumber(YGNodeLayoutGetTop(node)));
|
||||
result->putDirect(vm, vm.propertyNames->width, JSC::jsNumber(YGNodeLayoutGetWidth(node)));
|
||||
result->putDirect(vm, vm.propertyNames->height, JSC::jsNumber(YGNodeLayoutGetHeight(node)));
|
||||
|
||||
return JSC::JSValue::encode(result);
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetChild, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "getChild"));
|
||||
}
|
||||
|
||||
int index = callFrame->argument(0).toInt32(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
YGNodeRef childRef = YGNodeGetChild(thisObject->internal(), index);
|
||||
if (!childRef) {
|
||||
return JSC::JSValue::encode(JSC::jsNull());
|
||||
}
|
||||
|
||||
return JSC::JSValue::encode(JSYogaNode::fromYGNode(childRef));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetParent, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "getParent"));
|
||||
}
|
||||
|
||||
YGNodeRef parentRef = YGNodeGetParent(thisObject->internal());
|
||||
if (!parentRef) {
|
||||
return JSC::JSValue::encode(JSC::jsNull());
|
||||
}
|
||||
|
||||
return JSC::JSValue::encode(JSYogaNode::fromYGNode(parentRef));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncInsertChild, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "insertChild"));
|
||||
}
|
||||
|
||||
auto* child = jsDynamicCast<JSYogaNode*>(callFrame->argument(0));
|
||||
if (UNLIKELY(!child)) {
|
||||
return JSC::JSValue::encode(throwTypeError(globalObject, scope, "First argument must be a Yoga.Node instance"_s));
|
||||
}
|
||||
|
||||
int index = callFrame->argument(1).toInt32(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
YGNodeInsertChild(thisObject->internal(), child->internal(), index);
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncRemoveChild, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "removeChild"));
|
||||
}
|
||||
|
||||
auto* child = jsDynamicCast<JSYogaNode*>(callFrame->argument(0));
|
||||
if (UNLIKELY(!child)) {
|
||||
return JSC::JSValue::encode(throwTypeError(globalObject, scope, "First argument must be a Yoga.Node instance"_s));
|
||||
}
|
||||
|
||||
YGNodeRemoveChild(thisObject->internal(), child->internal());
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetChildCount, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "getChildCount"));
|
||||
}
|
||||
|
||||
return JSC::JSValue::encode(JSC::jsNumber(YGNodeGetChildCount(thisObject->internal())));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncIsDirty, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "isDirty"));
|
||||
}
|
||||
|
||||
return JSC::JSValue::encode(JSC::jsBoolean(YGNodeIsDirty(thisObject->internal())));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncMarkDirty, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "markDirty"));
|
||||
}
|
||||
|
||||
YGNodeMarkDirty(thisObject->internal());
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncReset, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "reset"));
|
||||
}
|
||||
|
||||
YGNodeReset(thisObject->internal());
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncCopyStyle, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "copyStyle"));
|
||||
}
|
||||
|
||||
auto* srcNode = jsDynamicCast<JSYogaNode*>(callFrame->argument(0));
|
||||
if (UNLIKELY(!srcNode)) {
|
||||
return JSC::JSValue::encode(throwTypeError(globalObject, scope, "First argument must be a Yoga.Node instance"_s));
|
||||
}
|
||||
|
||||
YGNodeCopyStyle(thisObject->internal(), srcNode->internal());
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncFree, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "free"));
|
||||
}
|
||||
|
||||
// Note: The actual freeing is handled by the destructor
|
||||
// This just marks it for cleanup
|
||||
YGNodeFree(thisObject->internal());
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncFreeRecursive, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "freeRecursive"));
|
||||
}
|
||||
|
||||
YGNodeFreeRecursive(thisObject->internal());
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
// Stub implementations for now
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetWidth, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
// TODO: Implement complex value setter pattern
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetHeight, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
// TODO: Implement complex value setter pattern
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMeasureFunc, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
// TODO: Implement callback pattern
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncUnsetMeasureFunc, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<JSYogaNode*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSC::JSValue::encode(throwThisTypeError(globalObject, scope, "Yoga.Node", "unsetMeasureFunc"));
|
||||
}
|
||||
|
||||
thisObject->m_measureFunc.clear();
|
||||
YGNodeSetMeasureFunc(thisObject->internal(), nullptr);
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
// Stub implementations for remaining methods
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedBorder, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedBottom, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedHeight, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedLeft, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedMargin, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedPadding, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedRight, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedTop, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetComputedWidth, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAlignContent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAlignItems, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAlignSelf, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetAspectRatio, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetBorder, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetDisplay, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlex, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexBasis, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexBasisPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexDirection, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexGrow, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexShrink, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetFlexWrap, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetGap, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetHeightAuto, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetHeightPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetJustifyContent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMargin, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMarginAuto, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMarginPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxHeight, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxHeightPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxWidth, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMaxWidthPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinHeight, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinHeightPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinWidth, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetMinWidthPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetOverflow, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPadding, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPaddingPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPosition, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPositionPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetPositionType, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetWidthAuto, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetWidthPercent, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncSetDirtiedFunc, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncUnsetDirtiedFunc, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
JSC_DEFINE_HOST_FUNCTION(jsYogaNodeProtoFuncGetDirtiedFunc, (JSC::JSGlobalObject*, JSC::CallFrame*)) { return JSC::JSValue::encode(JSC::jsUndefined()); }
|
||||
|
||||
} // namespace Bun
|
||||
65
src/bun.js/bindings/JSYogaPrototype.h
Normal file
65
src/bun.js/bindings/JSYogaPrototype.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
#include "root.h"
|
||||
#include <JavaScriptCore/JSNonFinalObject.h>
|
||||
|
||||
namespace Bun {
|
||||
|
||||
// JSYogaConfig Prototype
|
||||
class JSYogaConfigPrototype final : public JSC::JSNonFinalObject {
|
||||
public:
|
||||
using Base = JSC::JSNonFinalObject;
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
|
||||
static JSYogaConfigPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
|
||||
{
|
||||
JSYogaConfigPrototype* prototype = new (NotNull, JSC::allocateCell<JSYogaConfigPrototype>(vm)) JSYogaConfigPrototype(vm, structure);
|
||||
prototype->finishCreation(vm, globalObject);
|
||||
return prototype;
|
||||
}
|
||||
|
||||
DECLARE_INFO;
|
||||
|
||||
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
|
||||
}
|
||||
|
||||
private:
|
||||
JSYogaConfigPrototype(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure)
|
||||
{
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
|
||||
};
|
||||
|
||||
// JSYogaNode Prototype
|
||||
class JSYogaNodePrototype final : public JSC::JSNonFinalObject {
|
||||
public:
|
||||
using Base = JSC::JSNonFinalObject;
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
|
||||
static JSYogaNodePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
|
||||
{
|
||||
JSYogaNodePrototype* prototype = new (NotNull, JSC::allocateCell<JSYogaNodePrototype>(vm)) JSYogaNodePrototype(vm, structure);
|
||||
prototype->finishCreation(vm, globalObject);
|
||||
return prototype;
|
||||
}
|
||||
|
||||
DECLARE_INFO;
|
||||
|
||||
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
|
||||
}
|
||||
|
||||
private:
|
||||
JSYogaNodePrototype(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure)
|
||||
{
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
|
||||
};
|
||||
|
||||
} // namespace Bun
|
||||
@@ -177,6 +177,7 @@
|
||||
#include "JSPrivateKeyObject.h"
|
||||
#include "webcore/JSMIMEParams.h"
|
||||
#include "JSNodePerformanceHooksHistogram.h"
|
||||
#include "JSYogaConstructor.h"
|
||||
#include "JSS3File.h"
|
||||
#include "S3Error.h"
|
||||
#include "ProcessBindingBuffer.h"
|
||||
@@ -2808,6 +2809,16 @@ void GlobalObject::finishCreation(VM& vm)
|
||||
Bun::setupJSNodePerformanceHooksHistogramClassStructure(init);
|
||||
});
|
||||
|
||||
m_JSYogaConfigClassStructure.initLater(
|
||||
[](LazyClassStructure::Initializer& init) {
|
||||
Bun::setupJSYogaConfigClassStructure(init);
|
||||
});
|
||||
|
||||
m_JSYogaNodeClassStructure.initLater(
|
||||
[](LazyClassStructure::Initializer& init) {
|
||||
Bun::setupJSYogaNodeClassStructure(init);
|
||||
});
|
||||
|
||||
m_lazyStackCustomGetterSetter.initLater(
|
||||
[](const Initializer<CustomGetterSetter>& init) {
|
||||
init.set(CustomGetterSetter::create(init.vm, errorInstanceLazyStackCustomGetter, errorInstanceLazyStackCustomSetter));
|
||||
@@ -3783,6 +3794,32 @@ extern "C" void JSC__JSGlobalObject__addGc(JSC::JSGlobalObject* globalObject)
|
||||
|
||||
// ====================== end conditional builtin globals ======================
|
||||
|
||||
extern "C" void JSC__JSGlobalObject__exposeYoga(JSC::JSGlobalObject* lexicalGlobalObject)
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto& vm = globalObject->vm();
|
||||
|
||||
// Create the Yoga namespace object
|
||||
JSC::JSObject* yogaObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
|
||||
|
||||
// Attach Config constructor
|
||||
yogaObject->putDirect(vm, JSC::Identifier::fromString(vm, "Config"_s),
|
||||
globalObject->m_JSYogaConfigClassStructure.constructor(globalObject),
|
||||
PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
|
||||
// Attach Node constructor
|
||||
yogaObject->putDirect(vm, JSC::Identifier::fromString(vm, "Node"_s),
|
||||
globalObject->m_JSYogaNodeClassStructure.constructor(globalObject),
|
||||
PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
|
||||
// TODO: Add all the Yoga enums here
|
||||
// Align, Direction, Edge, etc...
|
||||
|
||||
// Expose Yoga globally
|
||||
globalObject->putDirect(vm, JSC::Identifier::fromString(vm, "Yoga"_s), yogaObject,
|
||||
PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
}
|
||||
|
||||
void GlobalObject::drainMicrotasks()
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
@@ -546,6 +546,8 @@ public:
|
||||
V(public, LazyClassStructure, m_JSMIMEParamsClassStructure) \
|
||||
V(public, LazyClassStructure, m_JSMIMETypeClassStructure) \
|
||||
V(public, LazyClassStructure, m_JSNodePerformanceHooksHistogramClassStructure) \
|
||||
V(public, LazyClassStructure, m_JSYogaConfigClassStructure) \
|
||||
V(public, LazyClassStructure, m_JSYogaNodeClassStructure) \
|
||||
\
|
||||
V(public, LazyClassStructure, m_JSConnectionsListClassStructure) \
|
||||
V(public, LazyClassStructure, m_JSHTTPParserClassStructure) \
|
||||
|
||||
@@ -71,6 +71,8 @@ public:
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSS3File;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSX509Certificate;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSNodePerformanceHooksHistogram;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSYogaConfig;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSYogaNode;
|
||||
#include "ZigGeneratedClasses+DOMClientIsoSubspaces.h"
|
||||
/* --- bun --- */
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSS3File;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSX509Certificate;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSNodePerformanceHooksHistogram;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSYogaConfig;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSYogaNode;
|
||||
#include "ZigGeneratedClasses+DOMIsoSubspaces.h"
|
||||
/*-- BUN --*/
|
||||
|
||||
|
||||
160
test/js/builtins/yoga.test.js
Normal file
160
test/js/builtins/yoga.test.js
Normal file
@@ -0,0 +1,160 @@
|
||||
import { test, expect } from "bun:test";
|
||||
|
||||
test("Yoga global exists", () => {
|
||||
expect(globalThis.Yoga).toBeDefined();
|
||||
expect(typeof globalThis.Yoga).toBe("object");
|
||||
});
|
||||
|
||||
test("Yoga.Config exists and can be constructed", () => {
|
||||
expect(Yoga.Config).toBeDefined();
|
||||
expect(typeof Yoga.Config).toBe("function");
|
||||
|
||||
const config = new Yoga.Config();
|
||||
expect(config).toBeDefined();
|
||||
expect(config.constructor.name).toBe("Config");
|
||||
|
||||
// Test basic Config methods
|
||||
expect(typeof config.setUseWebDefaults).toBe("function");
|
||||
expect(typeof config.useWebDefaults).toBe("function");
|
||||
expect(typeof config.setPointScaleFactor).toBe("function");
|
||||
expect(typeof config.isExperimentalFeatureEnabled).toBe("function");
|
||||
expect(typeof config.setExperimentalFeatureEnabled).toBe("function");
|
||||
});
|
||||
|
||||
test("Yoga.Config.setUseWebDefaults/useWebDefaults", () => {
|
||||
const config = new Yoga.Config();
|
||||
|
||||
// Default should be false
|
||||
expect(config.useWebDefaults()).toBe(false);
|
||||
|
||||
// Set to true
|
||||
config.setUseWebDefaults(true);
|
||||
expect(config.useWebDefaults()).toBe(true);
|
||||
|
||||
// Set back to false
|
||||
config.setUseWebDefaults(false);
|
||||
expect(config.useWebDefaults()).toBe(false);
|
||||
});
|
||||
|
||||
test("Yoga.Config.setPointScaleFactor", () => {
|
||||
const config = new Yoga.Config();
|
||||
|
||||
// Should not throw
|
||||
expect(() => config.setPointScaleFactor(2.0)).not.toThrow();
|
||||
expect(() => config.setPointScaleFactor(1.5)).not.toThrow();
|
||||
expect(() => config.setPointScaleFactor(1.0)).not.toThrow();
|
||||
});
|
||||
|
||||
test("Yoga.Node exists and can be constructed", () => {
|
||||
expect(Yoga.Node).toBeDefined();
|
||||
expect(typeof Yoga.Node).toBe("function");
|
||||
|
||||
const node = new Yoga.Node();
|
||||
expect(node).toBeDefined();
|
||||
expect(node.constructor.name).toBe("Node");
|
||||
|
||||
// Test that basic methods exist
|
||||
expect(typeof node.calculateLayout).toBe("function");
|
||||
expect(typeof node.getComputedLayout).toBe("function");
|
||||
expect(typeof node.insertChild).toBe("function");
|
||||
expect(typeof node.removeChild).toBe("function");
|
||||
expect(typeof node.getChild).toBe("function");
|
||||
expect(typeof node.getChildCount).toBe("function");
|
||||
expect(typeof node.getParent).toBe("function");
|
||||
expect(typeof node.markDirty).toBe("function");
|
||||
expect(typeof node.isDirty).toBe("function");
|
||||
expect(typeof node.reset).toBe("function");
|
||||
expect(typeof node.copyStyle).toBe("function");
|
||||
expect(typeof node.free).toBe("function");
|
||||
expect(typeof node.freeRecursive).toBe("function");
|
||||
});
|
||||
|
||||
test("Yoga.Node can be constructed with Config", () => {
|
||||
const config = new Yoga.Config();
|
||||
const node = new Yoga.Node(config);
|
||||
expect(node).toBeDefined();
|
||||
expect(node.constructor.name).toBe("Node");
|
||||
});
|
||||
|
||||
test("Yoga.Node hierarchy operations", () => {
|
||||
const parent = new Yoga.Node();
|
||||
const child1 = new Yoga.Node();
|
||||
const child2 = new Yoga.Node();
|
||||
|
||||
// Initially no children
|
||||
expect(parent.getChildCount()).toBe(0);
|
||||
expect(parent.getChild(0)).toBeNull();
|
||||
|
||||
// Insert first child
|
||||
parent.insertChild(child1, 0);
|
||||
expect(parent.getChildCount()).toBe(1);
|
||||
expect(parent.getChild(0)).toBe(child1);
|
||||
expect(child1.getParent()).toBe(parent);
|
||||
|
||||
// Insert second child
|
||||
parent.insertChild(child2, 1);
|
||||
expect(parent.getChildCount()).toBe(2);
|
||||
expect(parent.getChild(1)).toBe(child2);
|
||||
expect(child2.getParent()).toBe(parent);
|
||||
|
||||
// Remove first child
|
||||
parent.removeChild(child1);
|
||||
expect(parent.getChildCount()).toBe(1);
|
||||
expect(parent.getChild(0)).toBe(child2);
|
||||
expect(child1.getParent()).toBeNull();
|
||||
});
|
||||
|
||||
test("Yoga.Node calculateLayout and getComputedLayout", () => {
|
||||
const node = new Yoga.Node();
|
||||
|
||||
// Should have default layout values
|
||||
const layout = node.getComputedLayout();
|
||||
expect(layout).toBeDefined();
|
||||
expect(typeof layout.left).toBe("number");
|
||||
expect(typeof layout.top).toBe("number");
|
||||
expect(typeof layout.width).toBe("number");
|
||||
expect(typeof layout.height).toBe("number");
|
||||
|
||||
// Calculate layout
|
||||
node.calculateLayout(100, 100);
|
||||
const newLayout = node.getComputedLayout();
|
||||
expect(newLayout).toBeDefined();
|
||||
// After calculation, width and height should reflect the constraints
|
||||
expect(newLayout.width).toBe(100);
|
||||
expect(newLayout.height).toBe(100);
|
||||
});
|
||||
|
||||
test("Yoga.Node dirty state", () => {
|
||||
const node = new Yoga.Node();
|
||||
|
||||
// New nodes start dirty
|
||||
expect(node.isDirty()).toBe(true);
|
||||
|
||||
// After calculating layout, should not be dirty
|
||||
node.calculateLayout();
|
||||
expect(node.isDirty()).toBe(false);
|
||||
|
||||
// Can mark as dirty again
|
||||
node.markDirty();
|
||||
expect(node.isDirty()).toBe(true);
|
||||
});
|
||||
|
||||
test("Yoga.Node reset", () => {
|
||||
const parent = new Yoga.Node();
|
||||
const child = new Yoga.Node();
|
||||
|
||||
parent.insertChild(child, 0);
|
||||
expect(parent.getChildCount()).toBe(1);
|
||||
|
||||
// Reset should clear all style properties but not children
|
||||
parent.reset();
|
||||
expect(parent.getChildCount()).toBe(1);
|
||||
});
|
||||
|
||||
test("Yoga.Node copyStyle", () => {
|
||||
const source = new Yoga.Node();
|
||||
const target = new Yoga.Node();
|
||||
|
||||
// Should not throw
|
||||
expect(() => target.copyStyle(source)).not.toThrow();
|
||||
});
|
||||
Reference in New Issue
Block a user