js.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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.
  26. package js
  27. // 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.
  28. type Object struct{ object *Object }
  29. // Get returns the object's property with the given key.
  30. func (o *Object) Get(key string) *Object { return o.object.Get(key) }
  31. // Set assigns the value to the object's property with the given key.
  32. func (o *Object) Set(key string, value interface{}) { o.object.Set(key, value) }
  33. // Delete removes the object's property with the given key.
  34. func (o *Object) Delete(key string) { o.object.Delete(key) }
  35. // Length returns the object's "length" property, converted to int.
  36. func (o *Object) Length() int { return o.object.Length() }
  37. // Index returns the i'th element of an array.
  38. func (o *Object) Index(i int) *Object { return o.object.Index(i) }
  39. // SetIndex sets the i'th element of an array.
  40. func (o *Object) SetIndex(i int, value interface{}) { o.object.SetIndex(i, value) }
  41. // Call calls the object's method with the given name.
  42. func (o *Object) Call(name string, args ...interface{}) *Object { return o.object.Call(name, args...) }
  43. // Invoke calls the object itself. This will fail if it is not a function.
  44. func (o *Object) Invoke(args ...interface{}) *Object { return o.object.Invoke(args...) }
  45. // New creates a new instance of this type object. This will fail if it not a function (constructor).
  46. func (o *Object) New(args ...interface{}) *Object { return o.object.New(args...) }
  47. // Bool returns the object converted to bool according to JavaScript type conversions.
  48. func (o *Object) Bool() bool { return o.object.Bool() }
  49. // String returns the object converted to string according to JavaScript type conversions.
  50. func (o *Object) String() string { return o.object.String() }
  51. // Int returns the object converted to int according to JavaScript type conversions (parseInt).
  52. func (o *Object) Int() int { return o.object.Int() }
  53. // Int64 returns the object converted to int64 according to JavaScript type conversions (parseInt).
  54. func (o *Object) Int64() int64 { return o.object.Int64() }
  55. // Uint64 returns the object converted to uint64 according to JavaScript type conversions (parseInt).
  56. func (o *Object) Uint64() uint64 { return o.object.Uint64() }
  57. // Float returns the object converted to float64 according to JavaScript type conversions (parseFloat).
  58. func (o *Object) Float() float64 { return o.object.Float() }
  59. // Interface returns the object converted to interface{}. See table in package comment for details.
  60. func (o *Object) Interface() interface{} { return o.object.Interface() }
  61. // Unsafe returns the object as an uintptr, which can be converted via unsafe.Pointer. Not intended for public use.
  62. func (o *Object) Unsafe() uintptr { return o.object.Unsafe() }
  63. // Error encapsulates JavaScript errors. Those are turned into a Go panic and may be recovered, giving an *Error that holds the JavaScript error object.
  64. type Error struct {
  65. *Object
  66. }
  67. // Error returns the message of the encapsulated JavaScript error object.
  68. func (err *Error) Error() string {
  69. return "JavaScript error: " + err.Get("message").String()
  70. }
  71. // Stack returns the stack property of the encapsulated JavaScript error object.
  72. func (err *Error) Stack() string {
  73. return err.Get("stack").String()
  74. }
  75. // Global gives JavaScript's global object ("window" for browsers and "GLOBAL" for Node.js).
  76. var Global *Object
  77. // Module gives the value of the "module" variable set by Node.js. Hint: Set a module export with 'js.Module.Get("exports").Set("exportName", ...)'.
  78. var Module *Object
  79. // Undefined gives the JavaScript value "undefined".
  80. var Undefined *Object
  81. // Debugger gets compiled to JavaScript's "debugger;" statement.
  82. func Debugger() {}
  83. // InternalObject returns the internal JavaScript object that represents i. Not intended for public use.
  84. func InternalObject(i interface{}) *Object {
  85. return nil
  86. }
  87. // MakeFunc wraps a function and gives access to the values of JavaScript's "this" and "arguments" keywords.
  88. func MakeFunc(fn func(this *Object, arguments []*Object) interface{}) *Object {
  89. return Global.Call("$makeFunc", InternalObject(fn))
  90. }
  91. // Keys returns the keys of the given JavaScript object.
  92. func Keys(o *Object) []string {
  93. if o == nil || o == Undefined {
  94. return nil
  95. }
  96. a := Global.Get("Object").Call("keys", o)
  97. s := make([]string, a.Length())
  98. for i := 0; i < a.Length(); i++ {
  99. s[i] = a.Index(i).String()
  100. }
  101. return s
  102. }
  103. // 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.
  104. func MakeWrapper(i interface{}) *Object {
  105. v := InternalObject(i)
  106. o := Global.Get("Object").New()
  107. o.Set("__internal_object__", v)
  108. methods := v.Get("constructor").Get("methods")
  109. for i := 0; i < methods.Length(); i++ {
  110. m := methods.Index(i)
  111. if m.Get("pkg").String() != "" { // not exported
  112. continue
  113. }
  114. o.Set(m.Get("name").String(), func(args ...*Object) *Object {
  115. return Global.Call("$externalizeFunction", v.Get(m.Get("prop").String()), m.Get("typ"), true).Call("apply", v, args)
  116. })
  117. }
  118. return o
  119. }
  120. // NewArrayBuffer creates a JavaScript ArrayBuffer from a byte slice.
  121. func NewArrayBuffer(b []byte) *Object {
  122. slice := InternalObject(b)
  123. offset := slice.Get("$offset").Int()
  124. length := slice.Get("$length").Int()
  125. return slice.Get("$array").Get("buffer").Call("slice", offset, offset+length)
  126. }
  127. // M is a simple map type. It is intended as a shorthand for JavaScript objects (before conversion).
  128. type M map[string]interface{}
  129. // S is a simple slice type. It is intended as a shorthand for JavaScript arrays (before conversion).
  130. type S []interface{}
  131. func init() {
  132. // avoid dead code elimination
  133. e := Error{}
  134. _ = e
  135. }