vue.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package web
  2. import (
  3. "fmt"
  4. "net/url"
  5. "strings"
  6. h "github.com/theplant/htmlgo"
  7. )
  8. type jsCall struct {
  9. method string
  10. args []interface{}
  11. raw string
  12. }
  13. type Var string
  14. type VueEventTagBuilder struct {
  15. beforeScript string
  16. calls []jsCall
  17. afterScript string
  18. thenScript string
  19. }
  20. func Plaid() (r *VueEventTagBuilder) {
  21. r = &VueEventTagBuilder{
  22. calls: []jsCall{
  23. {
  24. method: "$plaid",
  25. },
  26. },
  27. }
  28. r.Vars(Var("vars")).
  29. Form(Var("plaidForm"))
  30. return
  31. }
  32. func GET() (r *VueEventTagBuilder) {
  33. return Plaid().Method("GET")
  34. }
  35. func POST() (r *VueEventTagBuilder) {
  36. return Plaid().Method("POST")
  37. }
  38. // URL is request page url without push state
  39. func (b *VueEventTagBuilder) URL(url interface{}) (r *VueEventTagBuilder) {
  40. b.calls = append(b.calls, jsCall{
  41. method: "url",
  42. args: []interface{}{url},
  43. })
  44. return b
  45. }
  46. func (b *VueEventTagBuilder) EventFunc(id interface{}) (r *VueEventTagBuilder) {
  47. c := jsCall{
  48. method: "eventFunc",
  49. args: []interface{}{id},
  50. }
  51. b.calls = append(b.calls, c)
  52. return b
  53. }
  54. func (b *VueEventTagBuilder) Method(v interface{}) (r *VueEventTagBuilder) {
  55. c := jsCall{
  56. method: "method",
  57. args: []interface{}{v},
  58. }
  59. b.calls = append(b.calls, c)
  60. return b
  61. }
  62. func (b *VueEventTagBuilder) Reload() (r *VueEventTagBuilder) {
  63. b.Raw("reload()")
  64. return b
  65. }
  66. func (b *VueEventTagBuilder) Vars(v interface{}) (r *VueEventTagBuilder) {
  67. b.calls = append(b.calls, jsCall{
  68. method: "vars",
  69. args: []interface{}{v},
  70. })
  71. return b
  72. }
  73. func (b *VueEventTagBuilder) MergeQuery(v interface{}) (r *VueEventTagBuilder) {
  74. b.calls = append(b.calls, jsCall{
  75. method: "mergeQuery",
  76. args: []interface{}{v},
  77. })
  78. return b
  79. }
  80. func (b *VueEventTagBuilder) Query(key interface{}, vs interface{}) (r *VueEventTagBuilder) {
  81. b.calls = append(b.calls, jsCall{
  82. method: "query",
  83. args: []interface{}{key, vs},
  84. })
  85. return b
  86. }
  87. // ClearMergeQuery param v use interface{} because you can not only pass []string,
  88. // but also pass in javascript variables by using web.Var("$event")
  89. func (b *VueEventTagBuilder) ClearMergeQuery(v interface{}) (r *VueEventTagBuilder) {
  90. b.calls = append(b.calls, jsCall{
  91. method: "clearMergeQuery",
  92. args: []interface{}{v},
  93. })
  94. return b
  95. }
  96. func (b *VueEventTagBuilder) StringQuery(v interface{}) (r *VueEventTagBuilder) {
  97. b.calls = append(b.calls, jsCall{
  98. method: "stringQuery",
  99. args: []interface{}{v},
  100. })
  101. return b
  102. }
  103. func (b *VueEventTagBuilder) PushState(v interface{}) (r *VueEventTagBuilder) {
  104. b.calls = append(b.calls, jsCall{
  105. method: "pushState",
  106. args: []interface{}{v},
  107. })
  108. return b
  109. }
  110. func (b *VueEventTagBuilder) Location(v *LocationBuilder) (r *VueEventTagBuilder) {
  111. b.calls = append(b.calls, jsCall{
  112. method: "location",
  113. args: []interface{}{v},
  114. })
  115. return b
  116. }
  117. func (b *VueEventTagBuilder) Queries(v url.Values) (r *VueEventTagBuilder) {
  118. b.calls = append(b.calls, jsCall{
  119. method: "queries",
  120. args: []interface{}{v},
  121. })
  122. return b
  123. }
  124. func (b *VueEventTagBuilder) PushStateURL(v string) (r *VueEventTagBuilder) {
  125. b.calls = append(b.calls, jsCall{
  126. method: "pushStateURL",
  127. args: []interface{}{v},
  128. })
  129. return b
  130. }
  131. func (b *VueEventTagBuilder) Form(v interface{}) (r *VueEventTagBuilder) {
  132. b.calls = append(b.calls, jsCall{
  133. method: "form",
  134. args: []interface{}{v},
  135. })
  136. return b
  137. }
  138. func (b *VueEventTagBuilder) FormClear() (r *VueEventTagBuilder) {
  139. b.calls = append(b.calls, jsCall{
  140. method: "formClear",
  141. })
  142. return b
  143. }
  144. func (b *VueEventTagBuilder) FieldValue(name interface{}, v interface{}) (r *VueEventTagBuilder) {
  145. b.calls = append(b.calls, jsCall{
  146. method: "fieldValue",
  147. args: []interface{}{name, v},
  148. })
  149. return b
  150. }
  151. func (b *VueEventTagBuilder) PopState(v interface{}) (r *VueEventTagBuilder) {
  152. b.calls = append(b.calls, jsCall{
  153. method: "popstate",
  154. args: []interface{}{v},
  155. })
  156. return b
  157. }
  158. func (b *VueEventTagBuilder) Raw(script string) (r *VueEventTagBuilder) {
  159. b.calls = append(b.calls, jsCall{
  160. raw: script,
  161. })
  162. return b
  163. }
  164. func (b *VueEventTagBuilder) Go() (r string) {
  165. b.Raw("go()")
  166. return b.String()
  167. }
  168. func (b *VueEventTagBuilder) RunPushState() (r string) {
  169. b.Raw("runPushState()")
  170. return b.String()
  171. }
  172. func (b *VueEventTagBuilder) BeforeScript(script string) (r *VueEventTagBuilder) {
  173. b.beforeScript = script
  174. return b
  175. }
  176. func (b *VueEventTagBuilder) AfterScript(script string) (r *VueEventTagBuilder) {
  177. b.afterScript = script
  178. return b
  179. }
  180. func (b *VueEventTagBuilder) ThenScript(script string) (r *VueEventTagBuilder) {
  181. b.thenScript = script
  182. return b
  183. }
  184. func (b *VueEventTagBuilder) String() string {
  185. var cs []string
  186. for _, c := range b.calls {
  187. if len(c.raw) > 0 {
  188. cs = append(cs, c.raw)
  189. continue
  190. }
  191. if len(c.args) == 0 {
  192. cs = append(cs, fmt.Sprintf("%s()", c.method))
  193. continue
  194. }
  195. if len(c.args) == 1 {
  196. cs = append(cs, fmt.Sprintf("%s(%s)", c.method, toJsValue(c.args[0])))
  197. continue
  198. }
  199. var args []string
  200. for _, arg := range c.args {
  201. args = append(args, toJsValue(arg))
  202. }
  203. cs = append(cs, fmt.Sprintf("%s(%s)", c.method, strings.Join(args, ", ")))
  204. }
  205. if len(b.thenScript) > 0 {
  206. cs = append(cs, fmt.Sprintf("then(function(r){ %s })", b.thenScript))
  207. }
  208. var sems []string
  209. if len(b.beforeScript) > 0 {
  210. sems = append(sems, b.beforeScript)
  211. }
  212. sems = append(sems, strings.Join(cs, "."))
  213. if len(b.afterScript) > 0 {
  214. sems = append(sems, b.afterScript)
  215. }
  216. return strings.Join(sems, "; ")
  217. }
  218. func toJsValue(v interface{}) string {
  219. switch v.(type) {
  220. case Var:
  221. return fmt.Sprint(v)
  222. default:
  223. return h.JSONString(v)
  224. }
  225. }
  226. func (b *VueEventTagBuilder) MarshalJSON() ([]byte, error) {
  227. panic(fmt.Sprintf("call .Go() at the end, value: %s", b.String()))
  228. }
  229. const InitContextVars = "v-init-context:vars"
  230. const InitContextLocals = "v-init-context:locals"
  231. type VFieldNameOption interface {
  232. private()
  233. }
  234. type UseForm string
  235. func (UseForm) private() {}
  236. func VFieldName(v string, opts ...VFieldNameOption) []interface{} {
  237. formVar := "plaidForm"
  238. for _, op := range opts {
  239. if vf, ok := op.(UseForm); ok {
  240. formVar = string(vf)
  241. }
  242. }
  243. return []interface{}{
  244. "v-field-name",
  245. fmt.Sprintf("[%s, %s]", formVar, h.JSONString(v)),
  246. }
  247. }
  248. func GlobalEvents() *h.HTMLTagBuilder {
  249. return h.Tag("global-events")
  250. }