From 1fb3e02dbcd9ce73960300e4b3650a5b4e67ebb6 Mon Sep 17 00:00:00 2001 From: brettlangdon Date: Mon, 17 Sep 2018 10:19:26 -0400 Subject: [PATCH] Keep working on prototype --- document.go | 51 ++++++++---- element.go | 39 ++++++--- elementiface.go | 7 ++ event.go | 35 ++++++++ eventiface.go | 8 ++ eventtarget.go => eventtargetiface.go | 2 +- generate/document.json | 28 ++----- generate/element.json | 15 +--- generate/elementiface.json | 40 +++++++++ generate/event.json | 6 ++ generate/eventiface.json | 37 +++++++++ ...eventtarget.json => eventtargetiface.json} | 2 +- generate/main.go | 83 ++++++++++--------- generate/node.json | 58 +------------ generate/nodeiface.json | 67 +++++++++++++++ generate/window.json | 3 + helpers.go | 14 ---- init.go | 5 +- node.go | 58 ++++++++++++- nodeiface.go | 6 ++ value.go | 14 ++++ window.go | 10 +++ 22 files changed, 414 insertions(+), 174 deletions(-) create mode 100644 elementiface.go create mode 100644 event.go create mode 100644 eventiface.go rename eventtarget.go => eventtargetiface.go (77%) create mode 100644 generate/elementiface.json create mode 100644 generate/event.json create mode 100644 generate/eventiface.json rename generate/{eventtarget.json => eventtargetiface.json} (90%) create mode 100644 generate/nodeiface.json create mode 100644 generate/window.json delete mode 100644 helpers.go create mode 100644 nodeiface.go create mode 100644 value.go create mode 100644 window.go diff --git a/document.go b/document.go index a11364b..efefb89 100644 --- a/document.go +++ b/document.go @@ -7,32 +7,21 @@ type document struct { js.Value } +func (d *document) JSValue() js.Value { return d.Value } func (d *document) GetBody() *Element { val := d.Get("body") return &Element{Value: val} } func (d *document) CreateElement(tagName string) *Element { - val := d.Call("createElement", ToValue(tagName)) + val := d.Call("createElement", ToJSValue(tagName)) return &Element{Value: val} } func (d *document) GetElementById(id string) *Element { - val := d.Call("getElementById", ToValue(id)) + val := d.Call("getElementById", ToJSValue(id)) return &Element{Value: val} } -func (d *document) QuerySelector(selector string) *Element { - val := d.Call("querySelector", ToValue(selector)) - return &Element{Value: val} -} -func (d *document) QuerySelectorAll(selector string) []*Element { - val := d.Call("querySelectorAll", ToValue(selector)) - elms := make([]*Element, 0) - for i := 0; i < val.Length(); i += 1 { - elms = append(elms, &Element{Value: val.Index(i)}) - } - return elms -} func (d *document) GetElementsByName(name string) []*Element { - val := d.Call("getElementsByName", ToValue(name)) + val := d.Call("getElementsByName", ToJSValue(name)) elms := make([]*Element, 0) for i := 0; i < val.Length(); i += 1 { elms = append(elms, &Element{Value: val.Index(i)}) @@ -40,13 +29,13 @@ func (d *document) GetElementsByName(name string) []*Element { return elms } func (d *document) Write(markup string) { - d.Call("write", ToValue(markup)) + d.Call("write", ToJSValue(markup)) } func (d *document) AddEventListener(t string, listener js.Callback) { - d.Call("addEventListener", ToValue(t), ToValue(listener)) + d.Call("addEventListener", ToJSValue(t), ToJSValue(listener)) } func (d *document) AppendChild(aChild *Element) *Element { - val := d.Call("appendChild", ToValue(aChild)) + val := d.Call("appendChild", ToJSValue(aChild)) return &Element{Value: val} } func (d *document) GetBaseURI() string { @@ -92,3 +81,29 @@ func (d *document) GetTextContent() string { func (d *document) SetTextContent(v string) { d.Set("textContent", v) } +func (d *document) QuerySelector(selector string) *Element { + val := d.Call("querySelector", ToJSValue(selector)) + return &Element{Value: val} +} +func (d *document) QuerySelectorAll(selector string) []*Element { + val := d.Call("querySelectorAll", ToJSValue(selector)) + elms := make([]*Element, 0) + for i := 0; i < val.Length(); i += 1 { + elms = append(elms, &Element{Value: val.Index(i)}) + } + return elms +} +func (d *document) GetClassName() string { + val := d.Get("className") + return val.String() +} +func (d *document) SetClassName(v string) { + d.Set("className", v) +} +func (d *document) GetId() string { + val := d.Get("id") + return val.String() +} +func (d *document) SetId(v string) { + d.Set("id", v) +} diff --git a/element.go b/element.go index e84bdea..6cfb2a9 100644 --- a/element.go +++ b/element.go @@ -7,19 +7,12 @@ type Element struct { js.Value } -func (e *Element) GetClassName() string { - val := e.Get("className") - return val.String() -} -func (e *Element) GetId() string { - val := e.Get("id") - return val.String() -} +func (e *Element) JSValue() js.Value { return e.Value } func (e *Element) AddEventListener(t string, listener js.Callback) { - e.Call("addEventListener", ToValue(t), ToValue(listener)) + e.Call("addEventListener", ToJSValue(t), ToJSValue(listener)) } func (e *Element) AppendChild(aChild *Element) *Element { - val := e.Call("appendChild", ToValue(aChild)) + val := e.Call("appendChild", ToJSValue(aChild)) return &Element{Value: val} } func (e *Element) GetBaseURI() string { @@ -65,3 +58,29 @@ func (e *Element) GetTextContent() string { func (e *Element) SetTextContent(v string) { e.Set("textContent", v) } +func (e *Element) QuerySelector(selector string) *Element { + val := e.Call("querySelector", ToJSValue(selector)) + return &Element{Value: val} +} +func (e *Element) QuerySelectorAll(selector string) []*Element { + val := e.Call("querySelectorAll", ToJSValue(selector)) + elms := make([]*Element, 0) + for i := 0; i < val.Length(); i += 1 { + elms = append(elms, &Element{Value: val.Index(i)}) + } + return elms +} +func (e *Element) GetClassName() string { + val := e.Get("className") + return val.String() +} +func (e *Element) SetClassName(v string) { + e.Set("className", v) +} +func (e *Element) GetId() string { + val := e.Get("id") + return val.String() +} +func (e *Element) SetId(v string) { + e.Set("id", v) +} diff --git a/elementiface.go b/elementiface.go new file mode 100644 index 0000000..fe7dc53 --- /dev/null +++ b/elementiface.go @@ -0,0 +1,7 @@ +// DO NOT EDIT - generated file +package dom + +type ElementIFace interface { + QuerySelector(selector string) *Element + QuerySelectorAll(selector string) []*Element +} diff --git a/event.go b/event.go new file mode 100644 index 0000000..57f9c9f --- /dev/null +++ b/event.go @@ -0,0 +1,35 @@ +// DO NOT EDIT - generated file +package dom + +import "syscall/js" + +type Event struct { + js.Value +} + +func (e *Event) JSValue() js.Value { return e.Value } +func (e *Event) PreventDefault() { + e.Call("preventDefault") +} +func (e *Event) StopPropagation() { + e.Call("stopPropagation") +} +func (e *Event) StopImmediatePropagation() { + e.Call("stopImmediatePropagation") +} +func (e *Event) GetCurrentTarget() js.Value { + val := e.Get("currentTarget") + return val +} +func (e *Event) GetTarget() js.Value { + val := e.Get("target") + return val +} +func (e *Event) GetType() string { + val := e.Get("type") + return val.String() +} +func (e *Event) GetSrcElement() js.Value { + val := e.Get("srcElement") + return val +} diff --git a/eventiface.go b/eventiface.go new file mode 100644 index 0000000..9d99cb2 --- /dev/null +++ b/eventiface.go @@ -0,0 +1,8 @@ +// DO NOT EDIT - generated file +package dom + +type EventIFace interface { + PreventDefault() + StopPropagation() + StopImmediatePropagation() +} diff --git a/eventtarget.go b/eventtargetiface.go similarity index 77% rename from eventtarget.go rename to eventtargetiface.go index ff3e7c3..76ea8c4 100644 --- a/eventtarget.go +++ b/eventtargetiface.go @@ -3,6 +3,6 @@ package dom import "syscall/js" -type EventTarget interface { +type EventTargetIFace interface { AddEventListener(t string, listener js.Callback) } diff --git a/generate/document.json b/generate/document.json index 43aa723..63e0909 100644 --- a/generate/document.json +++ b/generate/document.json @@ -1,13 +1,15 @@ { "Type": "document", "Implements": [ - "EventTarget", - "Node" + "EventTargetIFace", + "NodeIFace", + "ElementIFace" ], "Properties": [ { "Name": "body", - "Type": "*Element" + "Type": "*Element", + "ReadOnly": true } ], "Functions": [ @@ -31,26 +33,6 @@ ], "ReturnType": "*Element" }, - { - "Name": "querySelector", - "Arguments": [ - { - "Name": "selector", - "Type": "string" - } - ], - "ReturnType": "*Element" - }, - { - "Name": "querySelectorAll", - "Arguments": [ - { - "Name": "selector", - "Type": "string" - } - ], - "ReturnType": "[]*Element" - }, { "Name": "getElementsByName", "Arguments": [ diff --git a/generate/element.json b/generate/element.json index 7cca74b..cfe68e8 100644 --- a/generate/element.json +++ b/generate/element.json @@ -1,17 +1,8 @@ { "Type": "Element", "Implements": [ - "EventTarget", - "Node" - ], - "Properties": [ - { - "Name": "className", - "Type": "string" - }, - { - "Name": "id", - "Type": "string" - } + "EventTargetIFace", + "NodeIFace", + "ElementIFace" ] } diff --git a/generate/elementiface.json b/generate/elementiface.json new file mode 100644 index 0000000..6081430 --- /dev/null +++ b/generate/elementiface.json @@ -0,0 +1,40 @@ +{ + "Type": "ElementIFace", + "Interface": true, + "Implements": [ + "EventTarget", + "Node" + ], + "Properties": [ + { + "Name": "className", + "Type": "string" + }, + { + "Name": "id", + "Type": "string" + } + ], + "Functions": [ + { + "Name": "querySelector", + "Arguments": [ + { + "Name": "selector", + "Type": "string" + } + ], + "ReturnType": "*Element" + }, + { + "Name": "querySelectorAll", + "Arguments": [ + { + "Name": "selector", + "Type": "string" + } + ], + "ReturnType": "[]*Element" + } + ] +} diff --git a/generate/event.json b/generate/event.json new file mode 100644 index 0000000..a93362a --- /dev/null +++ b/generate/event.json @@ -0,0 +1,6 @@ +{ + "Type": "Event", + "Implements": [ + "EventIFace" + ] +} diff --git a/generate/eventiface.json b/generate/eventiface.json new file mode 100644 index 0000000..c4d7f7d --- /dev/null +++ b/generate/eventiface.json @@ -0,0 +1,37 @@ +{ + "Type": "EventIFace", + "Interface": true, + "Properties": [ + { + "Name": "currentTarget", + "Type": "js.Value", + "ReadOnly": true + }, + { + "Name": "target", + "Type": "js.Value", + "ReadOnly": true + }, + { + "Name": "type", + "Type": "string", + "ReadOnly": true + }, + { + "Name": "srcElement", + "Type": "js.Value", + "ReadOnly": true + } + ], + "Functions": [ + { + "Name": "preventDefault" + }, + { + "Name": "stopPropagation" + }, + { + "Name": "stopImmediatePropagation" + } + ] +} diff --git a/generate/eventtarget.json b/generate/eventtargetiface.json similarity index 90% rename from generate/eventtarget.json rename to generate/eventtargetiface.json index 67f48b1..a91cb55 100644 --- a/generate/eventtarget.json +++ b/generate/eventtargetiface.json @@ -1,5 +1,5 @@ { - "Type": "EventTarget", + "Type": "EventTargetIFace", "ImportJS": true, "Interface": true, "Functions": [ diff --git a/generate/main.go b/generate/main.go index 9da3f61..6bce522 100644 --- a/generate/main.go +++ b/generate/main.go @@ -13,9 +13,9 @@ import ( ) type TypeProperty struct { - Name string - Type string - Setter bool + Name string + Type string + ReadOnly bool } func (p TypeProperty) GetterName() string { @@ -68,6 +68,31 @@ func (t TypeStructure) writeArguments(out *bytes.Buffer, args []FunctionArgument } } +func (t TypeStructure) writeReturnValue(out *bytes.Buffer, rt string) error { + switch rt { + case "string": + out.WriteString("return val.String()\r\n") + case "js.Value": + out.WriteString("return val") + case "NodeIFace": + out.WriteString("return &Node{ Value: val }\r\n") + case "*Element": + out.WriteString("return &Element{ Value: val }\r\n") + case "[]*Element": + out.WriteString("elms := make([]*Element, 0)\r\n") + out.WriteString("for i := 0; i < val.Length(); i += 1 {\r\n") + out.WriteString("\telms = append(elms, &Element{Value: val.Index(i)})\r\n") + out.WriteString("}\r\n") + out.WriteString("return elms\r\n") + case "": + // skip + default: + return fmt.Errorf("Unknown function return type %s", rt) + } + + return nil +} + func (t TypeStructure) writeFunctions(out *bytes.Buffer, funcs []TypeFunction) error { for _, f := range funcs { out.WriteString(fmt.Sprintf("func (%s *%s) %s(", t.ShortName(), t.Type, f.GoName())) @@ -85,26 +110,12 @@ func (t TypeStructure) writeFunctions(out *bytes.Buffer, funcs []TypeFunction) e out.WriteString(fmt.Sprintf("%s.Call(\"%s\"", t.ShortName(), f.Name)) for _, arg := range f.Arguments { out.WriteString(",") - out.WriteString(fmt.Sprintf("ToValue(%s)", arg.Name)) + out.WriteString(fmt.Sprintf("ToJSValue(%s)", arg.Name)) } out.WriteString(")\r\n") - switch f.ReturnType { - case "string": - out.WriteString("return val.String()\r\n") - case "*Element": - out.WriteString("return &Element{ Value: val }\r\n") - case "[]*Element": - out.WriteString("elms := make([]*Element, 0)\r\n") - out.WriteString("for i := 0; i < val.Length(); i += 1 {\r\n") - out.WriteString("\telms = append(elms, &Element{Value: val.Index(i)})\r\n") - out.WriteString("}\r\n") - out.WriteString("return elms\r\n") - case "": - // skip - default: - return fmt.Errorf("Unknown function return type %s", f.ReturnType) - } + // Return value + t.writeReturnValue(out, f.ReturnType) out.WriteString("}\r\n") } @@ -114,26 +125,18 @@ func (t TypeStructure) writeFunctions(out *bytes.Buffer, funcs []TypeFunction) e func (t TypeStructure) writeProperties(out *bytes.Buffer, props []TypeProperty) error { for _, p := range props { out.WriteString(fmt.Sprintf("func (%s *%s) %s() %s {\r\n", t.ShortName(), t.Type, p.GetterName(), p.Type)) - out.WriteString(fmt.Sprintf("\tval := %s.Get(\"%s\")\r\n", t.ShortName(), p.Name)) - switch p.Type { - case "string": - out.WriteString("return val.String()\r\n") - case "*Element": - out.WriteString("return &Element{ Value: val }\r\n") - case "[]*Element": - out.WriteString("elms := make([]*Element, 0)\r\n") - out.WriteString("for i := 0; i < val.Length(); i += 1 {\r\n") - out.WriteString("\telms = append(elms, &Element{Value: val.Index(i)})\r\n") - out.WriteString("}\r\n") - out.WriteString("return elms\r\n") - case "": - // skip - default: - return fmt.Errorf("Unknown property return type %s", p.Type) + if p.Type == "" { + return fmt.Errorf("Property %q must have a type defined", p.Name) + out.WriteString("\tval := ") } + out.WriteString(fmt.Sprintf("val := %s.Get(\"%s\")\r\n", t.ShortName(), p.Name)) + + // Return value + t.writeReturnValue(out, p.Type) + out.WriteString(fmt.Sprintf("}\r\n")) - if p.Setter { + if !p.ReadOnly { out.WriteString(fmt.Sprintf("func (%s *%s) %s(v %s){\r\n", t.ShortName(), t.Type, p.SetterName(), p.Type)) out.WriteString(fmt.Sprintf("\t%s.Set(\"%s\", v)\r\n", t.ShortName(), p.Name)) out.WriteString("}\r\n") @@ -165,6 +168,12 @@ func (t TypeStructure) generateStruct(out *bytes.Buffer, types map[string]TypeSt out.WriteString("}\r\n") + // Convert to type + out.WriteString(fmt.Sprintf("func JSTo%s (v js.Value) *%s { return &%s{ Value: v }}", t.Type, t.Type, t.Type)) + + // JSValue + out.WriteString(fmt.Sprintf("func (%s *%s) JSValue() js.Value { return %s.Value }\r\n", t.ShortName(), t.Type, t.ShortName())) + // Properties err = t.writeProperties(out, t.Properties) if err != nil { diff --git a/generate/node.json b/generate/node.json index b9dedb9..b93d65b 100644 --- a/generate/node.json +++ b/generate/node.json @@ -1,59 +1,7 @@ { "Type": "Node", - "Interface": true, - "Properties": [ - { - "Name": "baseURI", - "Type": "string" - }, - { - "Name": "firstChild", - "Type": "*Element" - }, - { - "Name": "lastChild", - "Type": "*Element" - }, - { - "Name": "nextSibling", - "Type": "*Element" - }, - { - "Name": "previousSibling", - "Type": "*Element" - }, - { - "Name": "parentElement", - "Type": "*Element" - }, - { - "Name": "rootElement", - "Type": "*Element" - }, - { - "Name": "prefix", - "Type": "string" - }, - { - "Name": "nodeName", - "Type": "string" - }, - { - "Name": "textContent", - "Type": "string", - "Setter": true - } - ], - "Functions": [ - { - "Name": "appendChild", - "Arguments": [ - { - "Name": "aChild", - "Type": "*Element" - } - ], - "ReturnType": "*Element" - } + "Implements": [ + "EventTargetIFace", + "NodeIFace" ] } diff --git a/generate/nodeiface.json b/generate/nodeiface.json new file mode 100644 index 0000000..bb17323 --- /dev/null +++ b/generate/nodeiface.json @@ -0,0 +1,67 @@ +{ + "Type": "NodeIFace", + "Interface": true, + "Properties": [ + { + "Name": "baseURI", + "Type": "string", + "ReadOnly": true + }, + { + "Name": "firstChild", + "Type": "*Element", + "ReadOnly": true + }, + { + "Name": "lastChild", + "Type": "*Element", + "ReadOnly": true + }, + { + "Name": "nextSibling", + "Type": "*Element", + "ReadOnly": true + }, + { + "Name": "previousSibling", + "Type": "*Element", + "ReadOnly": true + }, + { + "Name": "parentElement", + "Type": "*Element", + "ReadOnly": true + }, + { + "Name": "rootElement", + "Type": "*Element", + "ReadOnly": true + }, + { + "Name": "prefix", + "Type": "string", + "ReadOnly": true + }, + { + "Name": "nodeName", + "Type": "string", + "ReadOnly": true + }, + { + "Name": "textContent", + "Type": "string" + } + ], + "Functions": [ + { + "Name": "appendChild", + "Arguments": [ + { + "Name": "aChild", + "Type": "*Element" + } + ], + "ReturnType": "*Element" + } + ] +} diff --git a/generate/window.json b/generate/window.json new file mode 100644 index 0000000..891a3b8 --- /dev/null +++ b/generate/window.json @@ -0,0 +1,3 @@ +{ + "Type": "window" +} diff --git a/helpers.go b/helpers.go deleted file mode 100644 index 4ecb95d..0000000 --- a/helpers.go +++ /dev/null @@ -1,14 +0,0 @@ -package dom - -import "syscall/js" - -func ToValue(v interface{}) js.Value { - switch t := v.(type) { - case *Element: - return t.Value - case *document: - return t.Value - default: - return js.ValueOf(v) - } -} diff --git a/init.go b/init.go index 5c90010..bff59f3 100644 --- a/init.go +++ b/init.go @@ -5,8 +5,11 @@ import "syscall/js" var ( Document *document + Window *window ) func init() { - Document = &document{Value: js.Global().Get("document")} + g := js.Global() + Document = &document{Value: g.Get("document")} + Window = &window{Value: g.Get("window")} } diff --git a/node.go b/node.go index d7e51fe..dc64170 100644 --- a/node.go +++ b/node.go @@ -1,6 +1,60 @@ // DO NOT EDIT - generated file package dom -type Node interface { - AppendChild(aChild *Element) *Element +import "syscall/js" + +type Node struct { + js.Value +} + +func (n *Node) JSValue() js.Value { return n.Value } +func (n *Node) AddEventListener(t string, listener js.Callback) { + n.Call("addEventListener", ToJSValue(t), ToJSValue(listener)) +} +func (n *Node) AppendChild(aChild *Element) *Element { + val := n.Call("appendChild", ToJSValue(aChild)) + return &Element{Value: val} +} +func (n *Node) GetBaseURI() string { + val := n.Get("baseURI") + return val.String() +} +func (n *Node) GetFirstChild() *Element { + val := n.Get("firstChild") + return &Element{Value: val} +} +func (n *Node) GetLastChild() *Element { + val := n.Get("lastChild") + return &Element{Value: val} +} +func (n *Node) GetNextSibling() *Element { + val := n.Get("nextSibling") + return &Element{Value: val} +} +func (n *Node) GetPreviousSibling() *Element { + val := n.Get("previousSibling") + return &Element{Value: val} +} +func (n *Node) GetParentElement() *Element { + val := n.Get("parentElement") + return &Element{Value: val} +} +func (n *Node) GetRootElement() *Element { + val := n.Get("rootElement") + return &Element{Value: val} +} +func (n *Node) GetPrefix() string { + val := n.Get("prefix") + return val.String() +} +func (n *Node) GetNodeName() string { + val := n.Get("nodeName") + return val.String() +} +func (n *Node) GetTextContent() string { + val := n.Get("textContent") + return val.String() +} +func (n *Node) SetTextContent(v string) { + n.Set("textContent", v) } diff --git a/nodeiface.go b/nodeiface.go new file mode 100644 index 0000000..f4e36b6 --- /dev/null +++ b/nodeiface.go @@ -0,0 +1,6 @@ +// DO NOT EDIT - generated file +package dom + +type NodeIFace interface { + AppendChild(aChild *Element) *Element +} diff --git a/value.go b/value.go new file mode 100644 index 0000000..b2679ef --- /dev/null +++ b/value.go @@ -0,0 +1,14 @@ +package dom + +import "syscall/js" + +type JSValue interface { + JSValue() js.Value +} + +func ToJSValue(x interface{}) js.Value { + if v, ok := x.(JSValue); ok { + return v.JSValue() + } + return js.ValueOf(x) +} diff --git a/window.go b/window.go new file mode 100644 index 0000000..97f9be2 --- /dev/null +++ b/window.go @@ -0,0 +1,10 @@ +// DO NOT EDIT - generated file +package dom + +import "syscall/js" + +type window struct { + js.Value +} + +func (w *window) JSValue() js.Value { return w.Value }