or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants.mdcontent-management.mddom-manipulation.mdindex.mdjavascript-integration.mdlegacy-webkit.mdmodern-webkit.mdnavigation.md

javascript-integration.mddocs/

0

# JavaScript Integration

1

2

JavaScript execution environment and value management through Apple's JavaScriptCore framework. Provides a complete JavaScript interpreter that can execute JavaScript code, bridge between Python and JavaScript objects, handle exceptions, and manage JavaScript values within Python applications.

3

4

## Capabilities

5

6

### Core JavaScript Context

7

8

#### JSContext

9

10

JavaScript execution context that manages the global JavaScript environment.

11

12

```python { .api }

13

class JSContext:

14

def init(self) -> JSContext: ...

15

def initWithVirtualMachine_(self, virtualMachine: JSVirtualMachine) -> JSContext: ...

16

17

# Script execution

18

def evaluateScript_(self, script: str) -> JSValue: ...

19

def evaluateScript_withSourceURL_(self, script: str, sourceURL: NSURL) -> JSValue: ...

20

21

# Exception handling

22

@property

23

def exception(self) -> JSValue: ...

24

@property

25

def exceptionHandler(self) -> callable: ...

26

def setExceptionHandler_(self, handler: callable): ...

27

28

# Global object access

29

@property

30

def globalObject(self) -> JSValue: ...

31

32

# Virtual machine

33

@property

34

def virtualMachine(self) -> JSVirtualMachine: ...

35

36

# Inspection

37

def isInspectable(self) -> bool: ...

38

def setInspectable_(self, inspectable: bool): ...

39

@property

40

def name(self) -> str: ...

41

42

# Object lookup

43

def objectForKeyedSubscript_(self, key: str) -> JSValue: ...

44

def setObject_forKeyedSubscript_(self, object: JSValue, key: str): ...

45

```

46

47

#### JSVirtualMachine

48

49

JavaScript virtual machine for managing JavaScript execution.

50

51

```python { .api }

52

class JSVirtualMachine:

53

def init(self) -> JSVirtualMachine: ...

54

55

def addManagedReference_withOwner_(self, object: JSValue, owner: JSValue): ...

56

def removeManagedReference_withOwner_(self, object: JSValue, owner: JSValue): ...

57

```

58

59

### JavaScript Values

60

61

#### JSValue

62

63

Represents a JavaScript value and provides methods for type checking, conversion, and property access.

64

65

```python { .api }

66

class JSValue:

67

# Context creation

68

@classmethod

69

def valueWithObject_inContext_(cls, value: object, context: JSContext) -> JSValue: ...

70

@classmethod

71

def valueWithBool_inContext_(cls, value: bool, context: JSContext) -> JSValue: ...

72

@classmethod

73

def valueWithDouble_inContext_(cls, value: float, context: JSContext) -> JSValue: ...

74

@classmethod

75

def valueWithInt32_inContext_(cls, value: int, context: JSContext) -> JSValue: ...

76

@classmethod

77

def valueWithUInt32_inContext_(cls, value: int, context: JSContext) -> JSValue: ...

78

@classmethod

79

def valueWithPoint_inContext_(cls, point: CGPoint, context: JSContext) -> JSValue: ...

80

@classmethod

81

def valueWithRange_inContext_(cls, range: NSRange, context: JSContext) -> JSValue: ...

82

@classmethod

83

def valueWithRect_inContext_(cls, rect: CGRect, context: JSContext) -> JSValue: ...

84

@classmethod

85

def valueWithSize_inContext_(cls, size: CGSize, context: JSContext) -> JSValue: ...

86

@classmethod

87

def valueWithNullInContext_(cls, context: JSContext) -> JSValue: ...

88

@classmethod

89

def valueWithUndefinedInContext_(cls, context: JSContext) -> JSValue: ...

90

@classmethod

91

def valueWithNewObjectInContext_(cls, context: JSContext) -> JSValue: ...

92

@classmethod

93

def valueWithNewArrayInContext_(cls, context: JSContext) -> JSValue: ...

94

@classmethod

95

def valueWithNewRegularExpressionFromPattern_flags_inContext_(cls, pattern: str, flags: str, context: JSContext) -> JSValue: ...

96

@classmethod

97

def valueWithNewErrorFromMessage_inContext_(cls, message: str, context: JSContext) -> JSValue: ...

98

@classmethod

99

def valueWithNewPromiseInContext_fromExecutor_(cls, context: JSContext, executor: callable) -> JSValue: ...

100

@classmethod

101

def valueWithNewPromiseResolvedWithResult_inContext_(cls, result: JSValue, context: JSContext) -> JSValue: ...

102

@classmethod

103

def valueWithNewPromiseRejectedWithReason_inContext_(cls, reason: JSValue, context: JSContext) -> JSValue: ...

104

105

# Type checking

106

def isUndefined(self) -> bool: ...

107

def isNull(self) -> bool: ...

108

def isBoolean(self) -> bool: ...

109

def isNumber(self) -> bool: ...

110

def isString(self) -> bool: ...

111

def isObject(self) -> bool: ...

112

def isArray(self) -> bool: ...

113

def isDate(self) -> bool: ...

114

def isSymbol(self) -> bool: ...

115

116

# Type conversion

117

def toBool(self) -> bool: ...

118

def toNumber(self) -> float: ...

119

def toInt32(self) -> int: ...

120

def toUInt32(self) -> int: ...

121

def toString(self) -> str: ...

122

def toDate(self) -> NSDate: ...

123

def toArray(self) -> list: ...

124

def toDictionary(self) -> dict: ...

125

def toObject(self) -> object: ...

126

def toObjectOfClass_(self, expectedClass: type) -> object: ...

127

def toPoint(self) -> CGPoint: ...

128

def toRange(self) -> NSRange: ...

129

def toRect(self) -> CGRect: ...

130

def toSize(self) -> CGSize: ...

131

132

# Property access

133

def hasProperty_(self, property: str) -> bool: ...

134

def deleteProperty_(self, property: str) -> bool: ...

135

def valueForProperty_(self, property: str) -> JSValue: ...

136

def setValue_forProperty_(self, value: JSValue, property: str): ...

137

def defineProperty_descriptor_(self, property: str, descriptor: dict) -> bool: ...

138

139

# Array/object access

140

def valueAtIndex_(self, index: int) -> JSValue: ...

141

def setValue_atIndex_(self, value: JSValue, index: int): ...

142

def objectForKeyedSubscript_(self, key: str) -> JSValue: ...

143

def setObject_forKeyedSubscript_(self, object: JSValue, key: str): ...

144

def objectAtIndexedSubscript_(self, index: int) -> JSValue: ...

145

def setObject_atIndexedSubscript_(self, object: JSValue, index: int): ...

146

147

# Function calls

148

def callWithArguments_(self, arguments: list) -> JSValue: ...

149

def constructWithArguments_(self, arguments: list) -> JSValue: ...

150

def invokeMethod_withArguments_(self, method: str, arguments: list) -> JSValue: ...

151

152

# Comparison

153

def isEqualToObject_(self, value: JSValue) -> bool: ...

154

def isEqualWithTypeCoercionToObject_(self, value: JSValue) -> bool: ...

155

def isInstanceOf_(self, constructor: JSValue) -> bool: ...

156

157

# Context and prototype

158

@property

159

def context(self) -> JSContext: ...

160

@property

161

def prototype(self) -> JSValue: ...

162

def setPrototype_(self, prototype: JSValue): ...

163

```

164

165

#### JSManagedValue

166

167

Managed JavaScript value for memory management in Objective-C contexts.

168

169

```python { .api }

170

class JSManagedValue:

171

@classmethod

172

def managedValueWithValue_(cls, value: JSValue) -> JSManagedValue: ...

173

@classmethod

174

def managedValueWithValue_andOwner_(cls, value: JSValue, owner: object) -> JSManagedValue: ...

175

176

@property

177

def value(self) -> JSValue: ...

178

```

179

180

### Export System

181

182

#### JSExport Protocol

183

184

Base protocol for exporting Python classes to JavaScript.

185

186

```python { .api }

187

# JSExport is a protocol - implement in your Python classes

188

class MyExportedClass:

189

# Methods to be exported to JavaScript

190

def exportedMethod(self): ...

191

def anotherExportedMethod_(self, parameter): ...

192

```

193

194

#### JSExportAs Function

195

196

Decorator function for customizing JavaScript method names.

197

198

```python { .api }

199

def JSExportAs(PropertyName: str, Selector: callable) -> tuple:

200

"""

201

Export a Python method to JavaScript with a custom name.

202

203

Args:

204

PropertyName: The name to use in JavaScript

205

Selector: The Python method to export

206

207

Returns:

208

Tuple of selectors for the export system

209

"""

210

...

211

```

212

213

### Low-Level C API Functions

214

215

Direct access to JavaScriptCore C functions for advanced use cases.

216

217

#### Value Creation Functions

218

219

```python { .api }

220

def JSValueMakeString(context: JSContextRef, string: JSStringRef) -> JSValueRef: ...

221

def JSValueMakeNumber(context: JSContextRef, number: float) -> JSValueRef: ...

222

def JSValueMakeBoolean(context: JSContextRef, boolean: bool) -> JSValueRef: ...

223

def JSValueMakeNull(context: JSContextRef) -> JSValueRef: ...

224

def JSValueMakeUndefined(context: JSContextRef) -> JSValueRef: ...

225

```

226

227

#### Type Functions

228

229

```python { .api }

230

def JSValueGetType(context: JSContextRef, value: JSValueRef) -> JSType: ...

231

def JSValueToBoolean(context: JSContextRef, value: JSValueRef) -> bool: ...

232

def JSValueToNumber(context: JSContextRef, value: JSValueRef, exception: JSValueRef) -> float: ...

233

def JSValueCreateJSONString(context: JSContextRef, value: JSValueRef, indent: int, exception: JSValueRef) -> JSStringRef: ...

234

```

235

236

#### Object Functions

237

238

```python { .api }

239

def JSObjectSetPropertyForKey(context: JSContextRef, object: JSObjectRef, propertyKey: JSValueRef, value: JSValueRef, attributes: JSPropertyAttributes, exception: JSValueRef): ...

240

def JSObjectDeletePropertyForKey(context: JSContextRef, object: JSObjectRef, propertyKey: JSValueRef, exception: JSValueRef) -> bool: ...

241

def JSObjectMakeError(context: JSContextRef, argumentCount: int, arguments: JSValueRef, exception: JSValueRef) -> JSValueRef: ...

242

def JSObjectMakeTypedArray(context: JSContextRef, arrayType: JSTypedArrayType, length: int, exception: JSValueRef) -> JSValueRef: ...

243

def JSObjectGetArrayBufferBytesPtr(context: JSContextRef, object: JSObjectRef, exception: JSValueRef) -> bytes: ...

244

def JSObjectGetTypedArrayByteOffset(context: JSContextRef, object: JSObjectRef, exception: JSValueRef) -> int: ...

245

def JSValueGetTypedArrayType(context: JSContextRef, value: JSValueRef, exception: JSValueRef) -> JSTypedArrayType: ...

246

```

247

248

#### String Functions

249

250

```python { .api }

251

def JSStringCreateWithCFString(string: CFStringRef) -> JSStringRef: ...

252

def JSStringCopyCFString(allocator: CFAllocatorRef, string: JSStringRef) -> CFStringRef: ...

253

```

254

255

#### Memory Management Functions

256

257

```python { .api }

258

def JSClassRetain(jsClass: JSClassRef) -> JSClassRef: ...

259

```

260

261

### Constants and Types

262

263

#### JavaScript Types

264

265

```python { .api }

266

# JSType enumeration

267

kJSTypeUndefined = 0

268

kJSTypeNull = 1

269

kJSTypeBoolean = 2

270

kJSTypeNumber = 3

271

kJSTypeString = 4

272

kJSTypeObject = 5

273

kJSTypeSymbol = 6

274

```

275

276

#### Property Attributes

277

278

```python { .api }

279

# JSPropertyAttributes

280

kJSPropertyAttributeNone = 0

281

kJSPropertyAttributeReadOnly = 2

282

kJSPropertyAttributeDontEnum = 4

283

kJSPropertyAttributeDontDelete = 8

284

```

285

286

#### Class Attributes

287

288

```python { .api }

289

# JSClassAttributes

290

kJSClassAttributeNone = 0

291

kJSClassAttributeNoAutomaticPrototype = 2

292

```

293

294

#### Typed Array Types

295

296

```python { .api }

297

# JSTypedArrayType enumeration

298

kJSTypedArrayTypeInt8Array = 0

299

kJSTypedArrayTypeInt16Array = 1

300

kJSTypedArrayTypeInt32Array = 2

301

kJSTypedArrayTypeUint8Array = 3

302

kJSTypedArrayTypeUint8ClampedArray = 4

303

kJSTypedArrayTypeUint16Array = 5

304

kJSTypedArrayTypeUint32Array = 6

305

kJSTypedArrayTypeFloat32Array = 7

306

kJSTypedArrayTypeFloat64Array = 8

307

kJSTypedArrayTypeArrayBuffer = 9

308

kJSTypedArrayTypeNone = 10

309

kJSTypedArrayTypeBigInt64Array = 11

310

kJSTypedArrayTypeBigUint64Array = 12

311

```

312

313

#### Property Descriptor Keys

314

315

```python { .api }

316

JSPropertyDescriptorConfigurableKey = "configurable"

317

JSPropertyDescriptorEnumerableKey = "enumerable"

318

JSPropertyDescriptorGetKey = "get"

319

JSPropertyDescriptorSetKey = "set"

320

JSPropertyDescriptorValueKey = "value"

321

JSPropertyDescriptorWritableKey = "writable"

322

```

323

324

### Usage Examples

325

326

#### Basic JavaScript Execution

327

328

```python

329

import JavaScriptCore

330

331

# Create context

332

context = JavaScriptCore.JSContext.alloc().init()

333

334

# Execute JavaScript

335

result = context.evaluateScript_("2 + 3 * 4")

336

print(result.toNumber()) # Output: 14.0

337

338

# Work with JavaScript objects

339

context.evaluateScript_("var person = {name: 'John', age: 30};")

340

person = context.objectForKeyedSubscript_("person")

341

name = person.valueForProperty_("name")

342

print(name.toString()) # Output: John

343

```

344

345

#### Exception Handling

346

347

```python

348

import JavaScriptCore

349

350

context = JavaScriptCore.JSContext.alloc().init()

351

352

def exception_handler(context, exception):

353

print(f"JavaScript Error: {exception.toString()}")

354

print(f"Stack trace: {exception.valueForProperty_('stack').toString()}")

355

356

context.setExceptionHandler_(exception_handler)

357

358

# This will trigger the exception handler

359

context.evaluateScript_("throw new Error('Something went wrong');")

360

```

361

362

#### Exporting Python Objects to JavaScript

363

364

```python

365

import JavaScriptCore

366

from objc import protocol

367

368

@protocol("JSExport")

369

class Calculator:

370

def add_to_(self, a, b):

371

return a + b

372

373

def multiply_by_(self, a, b):

374

return a * b

375

376

context = JavaScriptCore.JSContext.alloc().init()

377

calculator = Calculator()

378

379

# Make calculator available in JavaScript

380

context.setObject_forKeyedSubscript_(calculator, "calculator")

381

382

# Use from JavaScript

383

result = context.evaluateScript_("calculator.add_to_(5, 3)")

384

print(result.toNumber()) # Output: 8.0

385

```

386

387

#### Working with JavaScript Arrays

388

389

```python

390

import JavaScriptCore

391

392

context = JavaScriptCore.JSContext.alloc().init()

393

394

# Create JavaScript array

395

js_array = JavaScriptCore.JSValue.valueWithNewArrayInContext_(context)

396

397

# Add elements

398

js_array.setValue_atIndex_(JavaScriptCore.JSValue.valueWithDouble_inContext_(1.5, context), 0)

399

js_array.setValue_atIndex_(JavaScriptCore.JSValue.valueWithObject_inContext_("hello", context), 1)

400

js_array.setValue_atIndex_(JavaScriptCore.JSValue.valueWithBool_inContext_(True, context), 2)

401

402

# Make available in JavaScript context

403

context.setObject_forKeyedSubscript_(js_array, "myArray")

404

405

# Access from JavaScript

406

length = context.evaluateScript_("myArray.length")

407

print(length.toNumber()) # Output: 3.0

408

409

first_element = context.evaluateScript_("myArray[0]")

410

print(first_element.toNumber()) # Output: 1.5

411

```

412

413

#### Promise Handling

414

415

```python

416

import JavaScriptCore

417

418

context = JavaScriptCore.JSContext.alloc().init()

419

420

def promise_executor(resolve, reject):

421

# Simulate async operation

422

import time

423

time.sleep(0.1)

424

resolve.callWithArguments_(["Success!"])

425

426

# Create promise

427

promise = JavaScriptCore.JSValue.valueWithNewPromiseInContext_fromExecutor_(context, promise_executor)

428

429

# Make available in JavaScript

430

context.setObject_forKeyedSubscript_(promise, "myPromise")

431

432

# Handle promise in JavaScript

433

context.evaluateScript_("""

434

myPromise.then(function(result) {

435

console.log('Promise resolved:', result);

436

}).catch(function(error) {

437

console.log('Promise rejected:', error);

438

});

439

""")

440

```