func replace(t jquery.JQuery) { href := t.Attr("href") id := t.Attr("replace") if len(id) == 0 || len(href) == 0 { log.Printf("%s: replace fails id '%s' href '%s'", currentPath, id, href) return } if page, doc, _ := mySite.Match(href); page == nil { log.Printf("page not found %s", href) } else { idSelector := "#" + id elt := jq(idSelector) if elt.Length > 0 { currentPath = href bn := doc.BodyNodeById[id] elt.ReplaceWith(bn.Markup(doc)) doc.AddBodyNodeEventListeners(document, bn) // Select again since we've just changed it. elt := jq(idSelector) jqBind(elt) elt.Call("foundation", "reflow") // Change displayed page path without reloading page. window.Get("history").Call("pushState", "object or string", "Title", href) } } }
func testString(body jquery.JQuery) { logInfo("begin testString") cases := []struct { name string s string valid htmlctrl.Validator }{ {"s1", "abc", nil}, {"s2", "", htmlctrl.ValidateString(func(s string) bool { if s == "hello" { log("s2 can't be 'hello'") } return s != "hello" })}, } strings := jq("<div>").AddClass("strings") for _, c := range cases { logInfo(fmt.Sprintf("test case: %#v", c)) j, e := htmlctrl.String(&c.s, c.name, "string-id", "string-class", c.valid) if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", c.name, e)) } if title := j.Attr("title"); title != c.name { logError(fmt.Sprintf("%s: title is %s, expected %s", c.name, title, c.name)) } strings.Append(j) c := &c strings.Append(jq("<button>").SetText("verify "+c.name).Call(jquery.CLICK, func() { log(c.name, c.s) })) } body.Append(strings) logInfo("end testString") }
func getDrawerListener(c jquery.JQuery) (d canvas.Drawer, l canvas.Listener) { id := c.Attr("id") page := mySite.PageByPath[currentPath] switch p := page.(type) { case canvas.Interface: var ok bool if d, ok = p.Drawer(id); !ok { log.Printf("%s: no canvas drawer for id '%s'", currentPath, id) } l, _ = p.Listener(id) default: log.Printf("%s: found canvas on page with no interface", currentPath) } return }
func canvasContext(c jquery.JQuery) (x *canvas.Context) { x = canvas.GetContext(c) h := float64(c.Width()) w := float64(c.Height()) x.PixelsPerPoint = screenPixelsPerPoint x.PointsPerPixel = 1 / screenPixelsPerPoint x.Size = r2.XY(h*x.PointsPerPixel, w*x.PointsPerPixel) // Always work in points not pixels. x.Scale(r2.XY1(screenPixelsPerPoint)) return }
func submitInput(input jquery.JQuery) { if currentPath != "/exec" { log.Println("ignore non exec ", currentPath) return } cmd := strings.TrimSpace(input.Val()) if cmd == "" { return } go func() { d := mySite.DocByPath[currentPath] page := mySite.PageByPath[currentPath] var pre, result string args := strings.Split(cmd, " ") err := rpc.Call("Listener.Exec", &args, &result) if err != nil { pre = fmt.Sprintf("error: %v", err) } else { pre = result } pre = ghtml.EscapeString(pre) body := d.Pre(&String{pre}).Markup(d) jq(input).SetAttr("disabled", "yes") ec := jq(input).Closest("div.ExecCommand") res := ec.Find("div.ExecResult") jq(res).SetHtml(body) jq(res).Closest("div.row").RemoveClass("hide") parent := jq(ec).Parent() add := page.(*execPage).ExecCommand.Body(d) parent.Append(add.Markup(d)) jqBind(jq(parent)) jq(parent).Find("input:last").Focus() }() }
func testSlice(body jquery.JQuery, cases []sliceCase) { slices := jq("<div>") for _, c := range cases { logInfo(fmt.Sprintf("test case: %#v", c)) min, max, step := c.mms() j, e := htmlctrl.Slice(c.slice(), c.name(), "slice-id", "slice-class", min, max, step, c.valid()) if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", c.name(), e)) } if title := j.Attr("title"); title != c.name() { logError(fmt.Sprintf("%s: title is %s, expected %s", c.name(), title, c.name())) } slices.Append(j) c := c slices.Append(jq("<button>").SetText("verify "+c.name()).Call(jquery.CLICK, func() { log(c.name(), c.slice()) })) } body.Append(slices) }
func testBool(body jquery.JQuery) { logInfo("begin testBool") cases := []struct { name string b bool valid htmlctrl.Validator }{ {"b1", false, nil}, {"b2", true, nil}, {"b3", true, htmlctrl.ValidateBool(func(b bool) bool { log("b3 is locked at true") return b })}, {"b4", false, htmlctrl.ValidateBool(func(b bool) bool { log("b4 is locked at false") return !b })}, } bools := jq("<div>").AddClass("bools") for _, c := range cases { logInfo(fmt.Sprintf("test case: %#v", c)) j, e := htmlctrl.Bool(&c.b, c.name, "bool-id", "bool-class", c.valid) if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", c.name, e)) } if b := j.Prop("checked").(bool); b != c.b { logError(fmt.Sprintf("%s: checked was %t, expected %t", c.name, b, c.b)) } if title := j.Attr("title"); title != c.name { logError(fmt.Sprintf("%s: title is %s, expected %s", c.name, title, c.name)) } bools.Append(j) c := &c bools.Append(jq("<button>").SetText("verify "+c.name).Call(jquery.CLICK, func() { log(c.name, c.b) })) } body.Append(bools) logInfo("end testBool") }
func testChoice(body jquery.JQuery) { logInfo("begin testChoice") opts := []string{ "def", "abc", "invalid", "hi", } cases := []struct { name string s string valid htmlctrl.Validator }{ {"c1", "abc", nil}, {"c2", "", htmlctrl.ValidateString(func(c string) bool { if c == "invalid" { log("c2 can't be 'invalid'") } return c != "invalid" })}, } choices := jq("<div>").AddClass("choices") for _, c := range cases { logInfo(fmt.Sprintf("test case: %#v", c)) j, e := htmlctrl.Choice(&c.s, opts, c.name, "choice-id", "choice-class", c.valid) if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", c.name, e)) } if title := j.Attr("title"); title != c.name { logError(fmt.Sprintf("%s: title is %s, expected %s", c.name, title, c.name)) } choices.Append(j) c := &c choices.Append(jq("<button>").SetText("verify "+c.name).Call(jquery.CLICK, func() { log(c.name, c.s) })) } body.Append(choices) logInfo("end testChoice") }
func testInt(body jquery.JQuery) { logInfo("begin testInt") cases := []struct { name string i int min, max, step float64 valid htmlctrl.Validator }{ {"i1", 0, -10, 10, 3, nil}, {"i2", 2, -100, 100, 1, htmlctrl.ValidateInt(func(i int) bool { if i == 5 { log("i can't be 5") } return i != 5 })}, {"i3", 0, math.NaN(), math.NaN(), math.NaN(), nil}, } ints := jq("<div>").AddClass("ints") for _, c := range cases { logInfo(fmt.Sprintf("test case: %#v", c)) j, e := htmlctrl.Int(&c.i, c.name, "int-id", "int-class", c.min, c.max, c.step, c.valid) if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", c.name, e)) } if title := j.Attr("title"); title != c.name { logError(fmt.Sprintf("%s: title is %s, expected %s", c.name, title, c.name)) } ints.Append(j) c := &c ints.Append(jq("<button>").SetText("verify "+c.name).Call(jquery.CLICK, func() { log(c.name, c.i) })) } body.Append(ints) logInfo("end testInt") }
func testFloat64(body jquery.JQuery) { logInfo("begin testFloat64") cases := []struct { name string f float64 min, max, step float64 valid htmlctrl.Validator }{ {"f1", 0.5, -10, 10, 1.5, nil}, {"f2", 2.1, -100, 100, 1, htmlctrl.ValidateFloat64(func(f float64) bool { if f == 5.5 { log("f can't be 5.5") } return f != 5.5 })}, {"f3", 0, math.NaN(), math.NaN(), math.NaN(), nil}, } float64s := jq("<div>").AddClass("float64s") for _, c := range cases { logInfo(fmt.Sprintf("test case: %#v", c)) j, e := htmlctrl.Float64(&c.f, c.name, "float64-id", "float64-class", c.min, c.max, c.step, c.valid) if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", c.name, e)) } if title := j.Attr("title"); title != c.name { logError(fmt.Sprintf("%s: title is %s, expected %s", c.name, title, c.name)) } float64s.Append(j) c := &c float64s.Append(jq("<button>").SetText("verify "+c.name).Call(jquery.CLICK, func() { log(c.name, c.f) })) } body.Append(float64s) logInfo("end testFloat64") }
func canvasDraw(c jquery.JQuery) { if c.Attr("width") == "" && c.Attr("height") == "" { // Determine height from aspect ratio and parent's width. aspect := 1.5 // 3 by 2 aspect ratio attr := c.Attr("aspect") if attr != "" { _, err := fmt.Sscanf(attr, "%f", &aspect) if err != nil { panic(err) } } parent := c.Parent() w := parent.Width() c.SetAttr("width", w) c.SetAttr("height", float64(w)/aspect) } d, _ := getDrawerListener(c) if d != nil { go d.Draw(canvasContext(c)) } }
func testStruct(body jquery.JQuery) { logInfo("begin testStruct") Bptr := true Iptr := 11 Fptr := 1.1 Sptr := "abc" type St2 struct { B []int `desc:"inner int" id:"St2-B" class:"struct-int-slice" min:"-1" max:"11"` } type St1 struct { A []St2 `desc:"slice of St2 struct" id:"St1-A" class:"struct-struct-slice"` } struct1 := struct { b bool B bool `desc:"a bool"` Bptr *bool `desc:"bool ptr" id:"s1-Bptr" class:"struct-bool-ptr"` Bt bool `desc:"Always true" valid:"BoolTrue"` I int `desc:"an int" id:"s1-I" class:"struct-int"` Iptr *int `desc:"int ptr"` Ilim int `desc:"limited int" min:"1" max:"10" step:"2" valid:"IntNot5"` F float64 `desc:"an float64" id:"s1-F" class:"struct-float64"` Fptr *float64 `desc:"float64 ptr"` Flim float64 `desc:"limited float64" min:"1.2" max:"10.5" step:"1.2" valid:"Float64Not5"` S string `desc:"a string" id:"s1-S" class:"struct-string"` Sptr *string `desc:"string ptr"` Slim string `desc:"limited string" valid:"StringNotHello"` C string `desc:"a choice" choice:"def,abc,invalid,hi" id:"s1-C" class:"struct-choice"` Cptr *string `desc:"choice ptr" choice:"def,abc,invalid,hi"` Clim string `desc:"limited choice" choice:"def,abc,invalid,hi" valid:"ChoiceNotInvalid"` St St1 `desc:"inner struct" id:"s1-St" class:"struct-struct"` }{ false, false, &Bptr, true, 2, &Iptr, 1, 2.5, &Fptr, 1.2, "a", &Sptr, "def", "", &Sptr, "hi", St1{A: []St2{}}, } htmlctrl.RegisterValidator("BoolTrue", htmlctrl.ValidateBool(func(b bool) bool { log("bool is locked at true") return b })) htmlctrl.RegisterValidator("IntNot5", htmlctrl.ValidateInt(func(i int) bool { not5 := i != 5 if !not5 { log("int can't be 5") } return not5 })) htmlctrl.RegisterValidator("Float64Not5", htmlctrl.ValidateFloat64(func(f float64) bool { not5 := f != 5 if !not5 { log("float can't be 5") } return not5 })) htmlctrl.RegisterValidator("StringNotHello", htmlctrl.ValidateString(func(s string) bool { notHello := s != "hello" if !notHello { log("string can't be 'hello'") } return notHello })) htmlctrl.RegisterValidator("ChoiceNotInvalid", htmlctrl.ValidateString(func(c string) bool { if c == "invalid" { log("choice can't be 'invalid'") } return c != "invalid" })) _, e := htmlctrl.Struct(struct1, "error", "struct-id", "struct-class") if e == nil { logError("expected error when passing non-ptr") } _, e = htmlctrl.Struct(&e, "error", "struct-id", "struct-class") if e == nil { logError("expected error when passing ptr to non-slice") } j, e := htmlctrl.Struct(&struct1, "struct1", "struct-id", "struct-class") if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", "struct1", e)) } if title := j.Attr("title"); title != "struct1" { logError(fmt.Sprintf("%s: title is %s, expected %s", "struct1", title, "struct1")) } body.Append(j) body.Append(jq("<button>").SetText("verify struct1").Call(jquery.CLICK, func() { log("struct1", struct1) })) logInfo("end testStruct") }