1// Package js provides functions for interacting with native JavaScript APIs. Calls to these functions are treated specially by GopherJS and translated directly to their corresponding JavaScript syntax. 2// 3// Use MakeWrapper to expose methods to JavaScript. When passing values directly, the following type conversions are performed: 4// 5// | Go type | JavaScript type | Conversions back to interface{} | 6// | --------------------- | --------------------- | ------------------------------- | 7// | bool | Boolean | bool | 8// | integers and floats | Number | float64 | 9// | string | String | string | 10// | []int8 | Int8Array | []int8 | 11// | []int16 | Int16Array | []int16 | 12// | []int32, []int | Int32Array | []int | 13// | []uint8 | Uint8Array | []uint8 | 14// | []uint16 | Uint16Array | []uint16 | 15// | []uint32, []uint | Uint32Array | []uint | 16// | []float32 | Float32Array | []float32 | 17// | []float64 | Float64Array | []float64 | 18// | all other slices | Array | []interface{} | 19// | arrays | see slice type | see slice type | 20// | functions | Function | func(...interface{}) *js.Object | 21// | time.Time | Date | time.Time | 22// | - | instanceof Node | *js.Object | 23// | maps, structs | instanceof Object | map[string]interface{} | 24// 25// Additionally, for a struct containing a *js.Object field, only the content of the field will be passed to JavaScript and vice versa. 26package js 27 28// Object is a container for a native JavaScript object. Calls to its methods are treated specially by GopherJS and translated directly to their JavaScript syntax. A nil pointer to Object is equal to JavaScript's "null". Object can not be used as a map key. 29type Object struct{ object *Object } 30 31// Get returns the object's property with the given key. 32func (o *Object) Get(key string) *Object { return o.object.Get(key) } 33 34// Set assigns the value to the object's property with the given key. 35func (o *Object) Set(key string, value interface{}) { o.object.Set(key, value) } 36 37// Delete removes the object's property with the given key. 38func (o *Object) Delete(key string) { o.object.Delete(key) } 39 40// Length returns the object's "length" property, converted to int. 41func (o *Object) Length() int { return o.object.Length() } 42 43// Index returns the i'th element of an array. 44func (o *Object) Index(i int) *Object { return o.object.Index(i) } 45 46// SetIndex sets the i'th element of an array. 47func (o *Object) SetIndex(i int, value interface{}) { o.object.SetIndex(i, value) } 48 49// Call calls the object's method with the given name. 50func (o *Object) Call(name string, args ...interface{}) *Object { return o.object.Call(name, args...) } 51 52// Invoke calls the object itself. This will fail if it is not a function. 53func (o *Object) Invoke(args ...interface{}) *Object { return o.object.Invoke(args...) } 54 55// New creates a new instance of this type object. This will fail if it not a function (constructor). 56func (o *Object) New(args ...interface{}) *Object { return o.object.New(args...) } 57 58// Bool returns the object converted to bool according to JavaScript type conversions. 59func (o *Object) Bool() bool { return o.object.Bool() } 60 61// String returns the object converted to string according to JavaScript type conversions. 62func (o *Object) String() string { return o.object.String() } 63 64// Int returns the object converted to int according to JavaScript type conversions (parseInt). 65func (o *Object) Int() int { return o.object.Int() } 66 67// Int64 returns the object converted to int64 according to JavaScript type conversions (parseInt). 68func (o *Object) Int64() int64 { return o.object.Int64() } 69 70// Uint64 returns the object converted to uint64 according to JavaScript type conversions (parseInt). 71func (o *Object) Uint64() uint64 { return o.object.Uint64() } 72 73// Float returns the object converted to float64 according to JavaScript type conversions (parseFloat). 74func (o *Object) Float() float64 { return o.object.Float() } 75 76// Interface returns the object converted to interface{}. See table in package comment for details. 77func (o *Object) Interface() interface{} { return o.object.Interface() } 78 79// Unsafe returns the object as an uintptr, which can be converted via unsafe.Pointer. Not intended for public use. 80func (o *Object) Unsafe() uintptr { return o.object.Unsafe() } 81 82// Error encapsulates JavaScript errors. Those are turned into a Go panic and may be recovered, giving an *Error that holds the JavaScript error object. 83type Error struct { 84 *Object 85} 86 87// Error returns the message of the encapsulated JavaScript error object. 88func (err *Error) Error() string { 89 return "JavaScript error: " + err.Get("message").String() 90} 91 92// Stack returns the stack property of the encapsulated JavaScript error object. 93func (err *Error) Stack() string { 94 return err.Get("stack").String() 95} 96 97// Global gives JavaScript's global object ("window" for browsers and "GLOBAL" for Node.js). 98var Global *Object 99 100// Module gives the value of the "module" variable set by Node.js. Hint: Set a module export with 'js.Module.Get("exports").Set("exportName", ...)'. 101var Module *Object 102 103// Undefined gives the JavaScript value "undefined". 104var Undefined *Object 105 106// Debugger gets compiled to JavaScript's "debugger;" statement. 107func Debugger() {} 108 109// InternalObject returns the internal JavaScript object that represents i. Not intended for public use. 110func InternalObject(i interface{}) *Object { 111 return nil 112} 113 114// MakeFunc wraps a function and gives access to the values of JavaScript's "this" and "arguments" keywords. 115func MakeFunc(fn func(this *Object, arguments []*Object) interface{}) *Object { 116 return Global.Call("$makeFunc", InternalObject(fn)) 117} 118 119// Keys returns the keys of the given JavaScript object. 120func Keys(o *Object) []string { 121 if o == nil || o == Undefined { 122 return nil 123 } 124 a := Global.Get("Object").Call("keys", o) 125 s := make([]string, a.Length()) 126 for i := 0; i < a.Length(); i++ { 127 s[i] = a.Index(i).String() 128 } 129 return s 130} 131 132// MakeWrapper creates a JavaScript object which has wrappers for the exported methods of i. Use explicit getter and setter methods to expose struct fields to JavaScript. 133func MakeWrapper(i interface{}) *Object { 134 v := InternalObject(i) 135 o := Global.Get("Object").New() 136 o.Set("__internal_object__", v) 137 methods := v.Get("constructor").Get("methods") 138 for i := 0; i < methods.Length(); i++ { 139 m := methods.Index(i) 140 if m.Get("pkg").String() != "" { // not exported 141 continue 142 } 143 o.Set(m.Get("name").String(), func(args ...*Object) *Object { 144 return Global.Call("$externalizeFunction", v.Get(m.Get("prop").String()), m.Get("typ"), true).Call("apply", v, args) 145 }) 146 } 147 return o 148} 149 150// NewArrayBuffer creates a JavaScript ArrayBuffer from a byte slice. 151func NewArrayBuffer(b []byte) *Object { 152 slice := InternalObject(b) 153 offset := slice.Get("$offset").Int() 154 length := slice.Get("$length").Int() 155 return slice.Get("$array").Get("buffer").Call("slice", offset, offset+length) 156} 157 158// M is a simple map type. It is intended as a shorthand for JavaScript objects (before conversion). 159type M map[string]interface{} 160 161// S is a simple slice type. It is intended as a shorthand for JavaScript arrays (before conversion). 162type S []interface{} 163 164func init() { 165 // avoid dead code elimination 166 e := Error{} 167 _ = e 168} 169