syscall/js: extend ValueOf to support arrays and objects

This commits adds []interface{} and map[string]interface{} as quick
ways to create JavaScript arrays and objects. They correspond to the
JavaScript notations [...] and {...}. A type alias can be used for
a concise notation.

Change-Id: I98bb08dbef1e0f3bd3d65c732d6b09e1520026ba
Reviewed-on: https://go-review.googlesource.com/126855
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Richard Musiol 2018-07-31 15:12:57 +02:00 committed by Richard Musiol
parent 6d0f757bb9
commit a9dcbab0fd
2 changed files with 41 additions and 9 deletions

View file

@ -64,6 +64,9 @@ var (
valueGlobal = predefValue(5) valueGlobal = predefValue(5)
memory = predefValue(6) // WebAssembly linear memory memory = predefValue(6) // WebAssembly linear memory
jsGo = predefValue(7) // instance of the Go class in JavaScript jsGo = predefValue(7) // instance of the Go class in JavaScript
objectConstructor = valueGlobal.Get("Object")
arrayConstructor = valueGlobal.Get("Array")
) )
// Undefined returns the JavaScript value "undefined". // Undefined returns the JavaScript value "undefined".
@ -83,15 +86,17 @@ func Global() Value {
// ValueOf returns x as a JavaScript value: // ValueOf returns x as a JavaScript value:
// //
// | Go | JavaScript | // | Go | JavaScript |
// | --------------------- | --------------------- | // | ---------------------- | ---------------------- |
// | js.Value | [its value] | // | js.Value | [its value] |
// | js.TypedArray | [typed array] | // | js.TypedArray | typed array |
// | js.Callback | function | // | js.Callback | function |
// | nil | null | // | nil | null |
// | bool | boolean | // | bool | boolean |
// | integers and floats | number | // | integers and floats | number |
// | string | string | // | string | string |
// | []interface{} | new array |
// | map[string]interface{} | new object |
func ValueOf(x interface{}) Value { func ValueOf(x interface{}) Value {
switch x := x.(type) { switch x := x.(type) {
case Value: case Value:
@ -138,6 +143,18 @@ func ValueOf(x interface{}) Value {
return floatValue(x) return floatValue(x)
case string: case string:
return makeValue(stringVal(x)) return makeValue(stringVal(x))
case []interface{}:
a := arrayConstructor.New(len(x))
for i, s := range x {
a.SetIndex(i, s)
}
return a
case map[string]interface{}:
o := objectConstructor.New()
for k, v := range x {
o.Set(k, v)
}
return o
default: default:
panic("ValueOf: invalid value") panic("ValueOf: invalid value")
} }

View file

@ -254,6 +254,21 @@ func TestType(t *testing.T) {
} }
} }
type object = map[string]interface{}
type array = []interface{}
func TestValueOf(t *testing.T) {
a := js.ValueOf(array{0, array{0, 42, 0}, 0})
if got := a.Index(1).Index(1).Int(); got != 42 {
t.Errorf("got %v, want %v", got, 42)
}
o := js.ValueOf(object{"x": object{"y": 42}})
if got := o.Get("x").Get("y").Int(); got != 42 {
t.Errorf("got %v, want %v", got, 42)
}
}
func TestCallback(t *testing.T) { func TestCallback(t *testing.T) {
c := make(chan struct{}) c := make(chan struct{})
cb := js.NewCallback(func(args []js.Value) { cb := js.NewCallback(func(args []js.Value) {