From a9dcbab0fd4b5adfb40cb924f14ee2af9c8938eb Mon Sep 17 00:00:00 2001 From: Richard Musiol Date: Tue, 31 Jul 2018 15:12:57 +0200 Subject: [PATCH] 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 --- src/syscall/js/js.go | 35 ++++++++++++++++++++++++++--------- src/syscall/js/js_test.go | 15 +++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/syscall/js/js.go b/src/syscall/js/js.go index 5deef35c2b..336586ca2d 100644 --- a/src/syscall/js/js.go +++ b/src/syscall/js/js.go @@ -64,6 +64,9 @@ var ( valueGlobal = predefValue(5) memory = predefValue(6) // WebAssembly linear memory jsGo = predefValue(7) // instance of the Go class in JavaScript + + objectConstructor = valueGlobal.Get("Object") + arrayConstructor = valueGlobal.Get("Array") ) // Undefined returns the JavaScript value "undefined". @@ -83,15 +86,17 @@ func Global() Value { // ValueOf returns x as a JavaScript value: // -// | Go | JavaScript | -// | --------------------- | --------------------- | -// | js.Value | [its value] | -// | js.TypedArray | [typed array] | -// | js.Callback | function | -// | nil | null | -// | bool | boolean | -// | integers and floats | number | -// | string | string | +// | Go | JavaScript | +// | ---------------------- | ---------------------- | +// | js.Value | [its value] | +// | js.TypedArray | typed array | +// | js.Callback | function | +// | nil | null | +// | bool | boolean | +// | integers and floats | number | +// | string | string | +// | []interface{} | new array | +// | map[string]interface{} | new object | func ValueOf(x interface{}) Value { switch x := x.(type) { case Value: @@ -138,6 +143,18 @@ func ValueOf(x interface{}) Value { return floatValue(x) case string: 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: panic("ValueOf: invalid value") } diff --git a/src/syscall/js/js_test.go b/src/syscall/js/js_test.go index 753e262d52..9cc931a31d 100644 --- a/src/syscall/js/js_test.go +++ b/src/syscall/js/js_test.go @@ -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) { c := make(chan struct{}) cb := js.NewCallback(func(args []js.Value) {