func printValueAt(e js.Object, name string, value string) { targets := []js.Object{} if e.Get("name").Str() == name { targets = append(targets, e) } query := fmt.Sprintf("*[name=\"%s\"]", html.EscapeString(name)) es := e.Call("querySelectorAll", query) for i := 0; i < es.Length(); i++ { targets = append(targets, es.Index(i)) } if e.Get("dataset").Get(toDatasetProp(datasetAttrKey)).Str() == name { targets = append(targets, e) } query = fmt.Sprintf( "*[data-%s=\"%s\"]", html.EscapeString(datasetAttrKey), html.EscapeString(name)) es = e.Call("querySelectorAll", query) for i := 0; i < es.Length(); i++ { targets = append(targets, es.Index(i)) } for _, e := range targets { if e.Call("hasAttribute", "value").Bool() { e.Set("value", value) } else { e.Set("textContent", value) } } }
func copyStruct(dst, src *js.Object, typ Type) { fields := jsType(typ).Get("fields") for i := 0; i < fields.Length(); i++ { prop := fields.Index(i).Get("prop").String() dst.Set(prop, src.Get(prop)) } }
func copyStruct(dst, src js.Object, typ Type) { fields := jsType(typ).Get("fields") for i := 0; i < fields.Length(); i++ { name := fields.Index(i).Index(0).Str() dst.Set(name, src.Get(name)) } }
func Set(obj *js.Object, path string, value interface{}) { ps := sep(path) n := len(ps) p := ps[n-1] ps = ps[:n-1] obj = getProterty(obj, ps) if obj == js.Undefined { return } obj.Set(p, value) }
func setResolution( gl *webgl.Context, canvas *js.Object, uResolution *js.Object) { width := canvas.Get("clientWidth").Int() height := canvas.Get("clientHeight").Int() if (canvas.Get("width").Int() != width) || (canvas.Get("height").Int() != height) { canvas.Set("width", width) canvas.Set("height", height) } gl.Viewport(0, 0, width, height) gl.Uniform2f(uResolution, float32(width), float32(height)) }
func newChatController(scope *js.Object) *chatController { controller := &chatController{scope, &MessagesSender{createJsWebsocket(scope)}} controller.setDefaults() scope.Set("sendMessage", func() { controller.sendMessage() }) scope.Set("showMessage", func(message *js.Object) { controller.showMessage(message) }) return controller }
func reflectType(typ *js.Object) *rtype { if typ.Get("reflectType") == js.Undefined { rt := &rtype{ size: uintptr(typ.Get("size").Int()), kind: uint8(typ.Get("kind").Int()), string: newStringPtr(typ.Get("string")), } js.InternalObject(rt).Set("jsType", typ) typ.Set("reflectType", js.InternalObject(rt)) methodSet := js.Global.Call("$methodSet", typ) if typ.Get("typeName").String() != "" || methodSet.Length() != 0 { reflectMethods := make([]method, methodSet.Length()) for i := range reflectMethods { m := methodSet.Index(i) t := m.Get("typ") reflectMethods[i] = method{ name: newStringPtr(m.Get("name")), pkgPath: newStringPtr(m.Get("pkg")), mtyp: reflectType(t), typ: reflectType(js.Global.Call("$funcType", js.Global.Get("Array").New(typ).Call("concat", t.Get("params")), t.Get("results"), t.Get("variadic"))), } } rt.uncommonType = &uncommonType{ name: newStringPtr(typ.Get("typeName")), pkgPath: newStringPtr(typ.Get("pkg")), methods: reflectMethods, } js.InternalObject(rt.uncommonType).Set("jsType", typ) } switch rt.Kind() { case Array: setKindType(rt, &arrayType{ elem: reflectType(typ.Get("elem")), len: uintptr(typ.Get("len").Int()), }) case Chan: dir := BothDir if typ.Get("sendOnly").Bool() { dir = SendDir } if typ.Get("recvOnly").Bool() { dir = RecvDir } setKindType(rt, &chanType{ elem: reflectType(typ.Get("elem")), dir: uintptr(dir), }) case Func: params := typ.Get("params") in := make([]*rtype, params.Length()) for i := range in { in[i] = reflectType(params.Index(i)) } results := typ.Get("results") out := make([]*rtype, results.Length()) for i := range out { out[i] = reflectType(results.Index(i)) } setKindType(rt, &funcType{ rtype: *rt, dotdotdot: typ.Get("variadic").Bool(), in: in, out: out, }) case Interface: methods := typ.Get("methods") imethods := make([]imethod, methods.Length()) for i := range imethods { m := methods.Index(i) imethods[i] = imethod{ name: newStringPtr(m.Get("name")), pkgPath: newStringPtr(m.Get("pkg")), typ: reflectType(m.Get("typ")), } } setKindType(rt, &interfaceType{ rtype: *rt, methods: imethods, }) case Map: setKindType(rt, &mapType{ key: reflectType(typ.Get("key")), elem: reflectType(typ.Get("elem")), }) case Ptr: setKindType(rt, &ptrType{ elem: reflectType(typ.Get("elem")), }) case Slice: setKindType(rt, &sliceType{ elem: reflectType(typ.Get("elem")), }) case Struct: fields := typ.Get("fields") reflectFields := make([]structField, fields.Length()) for i := range reflectFields { f := fields.Index(i) reflectFields[i] = structField{ name: newStringPtr(f.Get("name")), pkgPath: newStringPtr(f.Get("pkg")), typ: reflectType(f.Get("typ")), tag: newStringPtr(f.Get("tag")), offset: uintptr(i), } } setKindType(rt, &structType{ rtype: *rt, fields: reflectFields, }) } } return (*rtype)(unsafe.Pointer(typ.Get("reflectType").Unsafe())) }
// SetInnerHTML calls the innerHTML setter with the given string func SetInnerHTML(o *js.Object, html string) { o.Set("innerHTML", html) }
func NewTerrain(el *js.Object) *client.Terrain { size := 1 t := client.NewTerrain(el) t.Reset(size) el.Set("width", size*message.BlockLen*res) el.Set("height", size*message.BlockLen*res) var pressing bool var fromX, fromY, lastX, lastY int el.Call("addEventListener", "mousedown", func(event *js.Object) { fromX, fromY = getMouseCoords(event) lastX, lastY = fromX, fromY pressing = true }) el.Call("addEventListener", "mousemove", func(event *js.Object) { if !pressing { return } x, y := getMouseCoords(event) t.DrawRegion(fromX, fromY, lastX-fromX, lastY-fromY) t.Canvas.SetFillStyle("rgba(0,0,255,0.1)") t.Canvas.FillRect(fromX*res, fromY*res, (x-fromX)*res, (y-fromY)*res) lastX, lastY = x, y }) el.Call("addEventListener", "mouseup", func(event *js.Object) { t.DrawRegion(fromX, fromY, lastX-fromX, lastY-fromY) pressing = false if fromX == lastX && fromY == lastY { x, y := fromX, fromY pt, _ := t.GetPointAt(x, y) t.SetPointAt(x, y, invertPoint(pt), 0) t.DrawPoint(x, y) } else { if fromX > lastX { fromX, lastX = lastX, fromX } if fromY > lastY { fromY, lastY = lastY, fromY } for i := fromX; i < lastX; i++ { for j := fromY; j < lastY; j++ { pt, _ := t.GetPointAt(i, j) t.SetPointAt(i, j, invertPoint(pt), 0) t.DrawPoint(i, j) } } } }) saveBtn := js.Global.Get("document").Call("getElementById", "save-btn") saveBtn.Call("addEventListener", "click", func() { w := &ExportWriter{} blk, _ := t.GetBlockAt(0, 0) builder.WriteBlock(w, blk) w.Export() }) loadInput := js.Global.Get("document").Call("getElementById", "load-input") loadInput.Call("addEventListener", "change", func() { file := loadInput.Get("files").Get("0") if file == nil { return } go (func() { r := &ExportReader{} r.File = file blk := handler.ReadBlock(r) t.SetBlock(blk, 0) t.Draw() })() }) return t }
func reflectType(typ *js.Object) *rtype { if typ.Get("reflectType") == js.Undefined { rt := &rtype{ size: uintptr(typ.Get("size").Int()), kind: uint8(typ.Get("kind").Int()), str: newNameOff(newName(internalStr(typ.Get("string")), "", "", typ.Get("exported").Bool())), } js.InternalObject(rt).Set("jsType", typ) typ.Set("reflectType", js.InternalObject(rt)) methodSet := js.Global.Call("$methodSet", typ) if methodSet.Length() != 0 || typ.Get("named").Bool() { rt.tflag |= tflagUncommon if typ.Get("named").Bool() { rt.tflag |= tflagNamed } reflectMethods := make([]method, methodSet.Length()) for i := range reflectMethods { m := methodSet.Index(i) reflectMethods[i] = method{ name: newNameOff(newName(internalStr(m.Get("name")), "", "", internalStr(m.Get("pkg")) == "")), mtyp: newTypeOff(reflectType(m.Get("typ"))), } } ut := &uncommonType{ pkgPath: newNameOff(newName(internalStr(typ.Get("pkg")), "", "", false)), mcount: uint16(methodSet.Length()), _methods: reflectMethods, } uncommonTypeMap[rt] = ut js.InternalObject(ut).Set("jsType", typ) } switch rt.Kind() { case Array: setKindType(rt, &arrayType{ elem: reflectType(typ.Get("elem")), len: uintptr(typ.Get("len").Int()), }) case Chan: dir := BothDir if typ.Get("sendOnly").Bool() { dir = SendDir } if typ.Get("recvOnly").Bool() { dir = RecvDir } setKindType(rt, &chanType{ elem: reflectType(typ.Get("elem")), dir: uintptr(dir), }) case Func: params := typ.Get("params") in := make([]*rtype, params.Length()) for i := range in { in[i] = reflectType(params.Index(i)) } results := typ.Get("results") out := make([]*rtype, results.Length()) for i := range out { out[i] = reflectType(results.Index(i)) } outCount := uint16(results.Length()) if typ.Get("variadic").Bool() { outCount |= 1 << 15 } setKindType(rt, &funcType{ rtype: *rt, inCount: uint16(params.Length()), outCount: outCount, _in: in, _out: out, }) case Interface: methods := typ.Get("methods") imethods := make([]imethod, methods.Length()) for i := range imethods { m := methods.Index(i) imethods[i] = imethod{ name: newNameOff(newName(internalStr(m.Get("name")), "", "", internalStr(m.Get("pkg")) == "")), typ: newTypeOff(reflectType(m.Get("typ"))), } } setKindType(rt, &interfaceType{ rtype: *rt, methods: imethods, }) case Map: setKindType(rt, &mapType{ key: reflectType(typ.Get("key")), elem: reflectType(typ.Get("elem")), }) case Ptr: setKindType(rt, &ptrType{ elem: reflectType(typ.Get("elem")), }) case Slice: setKindType(rt, &sliceType{ elem: reflectType(typ.Get("elem")), }) case Struct: fields := typ.Get("fields") reflectFields := make([]structField, fields.Length()) for i := range reflectFields { f := fields.Index(i) reflectFields[i] = structField{ name: newName(internalStr(f.Get("name")), internalStr(f.Get("tag")), "", f.Get("exported").Bool()), typ: reflectType(f.Get("typ")), offset: uintptr(i), } } setKindType(rt, &structType{ rtype: *rt, pkgPath: newName(internalStr(typ.Get("pkgPath")), "", "", false), fields: reflectFields, }) } } return (*rtype)(unsafe.Pointer(typ.Get("reflectType").Unsafe())) }
func (p *pod) Draw(ctx *js.Object) { if p.selected { ctx.Set("fillStyle", "rgb(0, 255, 0)") } else { ctx.Set("fillStyle", "rgb(0, 0, 0)") } ctx.Call("fillRect", p.x, p.y, p.dx, p.dy) switch { case p.disk != "": ctx.Set("fillStyle", "rgb(225, 225, 225)") case p.port != 0: ctx.Set("fillStyle", "rgb(195, 240, 215)") case p.manifest != nil: ctx.Set("fillStyle", "rgb(220, 220, 240)") default: ctx.Set("fillStyle", "rgb(255, 0, 0)") } ctx.Call("fillRect", p.x+1, p.y+1, p.dx-2, p.dy-2) ctx.Set("fillStyle", "rgb(0, 0, 0)") ctx.Set("textAlign", "center") ctx.Set("font", "15px Monaco") switch { case p.manifest != nil: ctx.Call("fillText", p.manifest.Name, p.x+p.dx/2, p.y+p.dy/2) case p.disk != "": ctx.Call("fillText", p.disk, p.x+p.dx/2, p.y+p.dy/2) case p.port > 0: ctx.Call("fillText", fmt.Sprintf("port %d", p.port), p.x+p.dx/2, p.y+p.dy/2) } for _, anchor := range p.anchors { ctx.Call("fillText", anchor.text, anchor.textPt.x+p.x, anchor.textPt.y+p.y) ctx.Call("beginPath") ctx.Call("arc", anchor.edgePt.x+p.x, anchor.edgePt.y+p.y, 5, 0, 7) ctx.Call("fill") } }
func MakePod(manifest *schema.ImageManifest, ctx *js.Object) *pod { if manifest.App == nil { return nil } p := &pod{ manifest: manifest, x: 10, y: 10, dy: 75, } ctx.Set("fillStyle", "rgb(0, 0, 0)") ctx.Set("textAlign", "center") ctx.Set("textBaseline", "middle") ctx.Set("font", "20px Monaco") imageNameWidth := ctx.Call("measureText", p.manifest.Name.String()).Get("width").Int() var topAnchors, botAnchors []*podAnchor for _, port := range p.manifest.App.Ports { topAnchors = append(topAnchors, &podAnchor{ pod: p, edgePt: point{0, 0}, textPt: point{0, 0 + 12}, text: fmt.Sprintf("%s:%d", port.Name.String(), port.Port), obj: &port, }) } for _, mount := range p.manifest.App.MountPoints { botAnchors = append(botAnchors, &podAnchor{ pod: p, edgePt: point{0, p.dy}, textPt: point{0, p.dy - 12}, text: mount.Name.String(), obj: &mount, }) } for _, ann := range p.manifest.Annotations { r := annotationToRequiredFlag(ann) if r != nil { botAnchors = append(botAnchors, &podAnchor{ pod: p, edgePt: point{0, p.dy}, textPt: point{0, p.dy - 12}, text: r.name, obj: r, }) } } const buffer = 75 topWidth := buffer for _, anch := range topAnchors { topWidth += ctx.Call("measureText", anch.text).Get("width").Int() topWidth += buffer } botWidth := buffer for _, anch := range botAnchors { botWidth += ctx.Call("measureText", anch.text).Get("width").Int() botWidth += buffer } p.dx = imageNameWidth if topWidth > p.dx { p.dx = topWidth } if botWidth > p.dx { p.dx = botWidth } for i, anch := range topAnchors { x := ((i + 1) * p.dx) / (1 + len(topAnchors)) anch.edgePt.x = x anch.textPt.x = x p.anchors = append(p.anchors, anch) } for i, anch := range botAnchors { x := ((i + 1) * p.dx) / (1 + len(botAnchors)) anch.edgePt.x = x anch.textPt.x = x p.anchors = append(p.anchors, anch) } return p }