vue.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. func (b *VueEventTagBuilder) QueryIf(key interface{}, vs interface{}, add bool) (r *VueEventTagBuilder) {
  88. if !add {
  89. return b
  90. }
  91. b.calls = append(b.calls, jsCall{
  92. method: "query",
  93. args: []interface{}{key, vs},
  94. })
  95. return b
  96. }
  97. // ClearMergeQuery param v use interface{} because you can not only pass []string,
  98. // but also pass in javascript variables by using web.Var("$event")
  99. func (b *VueEventTagBuilder) ClearMergeQuery(v interface{}) (r *VueEventTagBuilder) {
  100. b.calls = append(b.calls, jsCall{
  101. method: "clearMergeQuery",
  102. args: []interface{}{v},
  103. })
  104. return b
  105. }
  106. func (b *VueEventTagBuilder) StringQuery(v interface{}) (r *VueEventTagBuilder) {
  107. b.calls = append(b.calls, jsCall{
  108. method: "stringQuery",
  109. args: []interface{}{v},
  110. })
  111. return b
  112. }
  113. func (b *VueEventTagBuilder) PushState(v interface{}) (r *VueEventTagBuilder) {
  114. b.calls = append(b.calls, jsCall{
  115. method: "pushState",
  116. args: []interface{}{v},
  117. })
  118. return b
  119. }
  120. func (b *VueEventTagBuilder) Location(v *LocationBuilder) (r *VueEventTagBuilder) {
  121. b.calls = append(b.calls, jsCall{
  122. method: "location",
  123. args: []interface{}{v},
  124. })
  125. return b
  126. }
  127. func (b *VueEventTagBuilder) Queries(v url.Values) (r *VueEventTagBuilder) {
  128. b.calls = append(b.calls, jsCall{
  129. method: "queries",
  130. args: []interface{}{v},
  131. })
  132. return b
  133. }
  134. func (b *VueEventTagBuilder) PushStateURL(v string) (r *VueEventTagBuilder) {
  135. b.calls = append(b.calls, jsCall{
  136. method: "pushStateURL",
  137. args: []interface{}{v},
  138. })
  139. return b
  140. }
  141. func (b *VueEventTagBuilder) Form(v interface{}) (r *VueEventTagBuilder) {
  142. b.calls = append(b.calls, jsCall{
  143. method: "form",
  144. args: []interface{}{v},
  145. })
  146. return b
  147. }
  148. func (b *VueEventTagBuilder) FormClear() (r *VueEventTagBuilder) {
  149. b.calls = append(b.calls, jsCall{
  150. method: "formClear",
  151. })
  152. return b
  153. }
  154. func (b *VueEventTagBuilder) FieldValue(name interface{}, v interface{}) (r *VueEventTagBuilder) {
  155. b.calls = append(b.calls, jsCall{
  156. method: "fieldValue",
  157. args: []interface{}{name, v},
  158. })
  159. return b
  160. }
  161. func (b *VueEventTagBuilder) PopState(v interface{}) (r *VueEventTagBuilder) {
  162. b.calls = append(b.calls, jsCall{
  163. method: "popstate",
  164. args: []interface{}{v},
  165. })
  166. return b
  167. }
  168. func (b *VueEventTagBuilder) Raw(script string) (r *VueEventTagBuilder) {
  169. b.calls = append(b.calls, jsCall{
  170. raw: script,
  171. })
  172. return b
  173. }
  174. func (b *VueEventTagBuilder) Go() (r string) {
  175. b.Raw("go()")
  176. return b.String()
  177. }
  178. func (b *VueEventTagBuilder) RunPushState() (r string) {
  179. b.Raw("runPushState()")
  180. return b.String()
  181. }
  182. func (b *VueEventTagBuilder) BeforeScript(script string) (r *VueEventTagBuilder) {
  183. b.beforeScript = script
  184. return b
  185. }
  186. func (b *VueEventTagBuilder) AfterScript(script string) (r *VueEventTagBuilder) {
  187. b.afterScript = script
  188. return b
  189. }
  190. func (b *VueEventTagBuilder) ThenScript(script string) (r *VueEventTagBuilder) {
  191. b.thenScript = script
  192. return b
  193. }
  194. func (b *VueEventTagBuilder) String() string {
  195. var cs []string
  196. for _, c := range b.calls {
  197. if len(c.raw) > 0 {
  198. cs = append(cs, c.raw)
  199. continue
  200. }
  201. if len(c.args) == 0 {
  202. cs = append(cs, fmt.Sprintf("%s()", c.method))
  203. continue
  204. }
  205. if len(c.args) == 1 {
  206. cs = append(cs, fmt.Sprintf("%s(%s)", c.method, toJsValue(c.args[0])))
  207. continue
  208. }
  209. var args []string
  210. for _, arg := range c.args {
  211. args = append(args, toJsValue(arg))
  212. }
  213. cs = append(cs, fmt.Sprintf("%s(%s)", c.method, strings.Join(args, ", ")))
  214. }
  215. if len(b.thenScript) > 0 {
  216. cs = append(cs, fmt.Sprintf("then(function(r){ %s })", b.thenScript))
  217. }
  218. var sems []string
  219. if len(b.beforeScript) > 0 {
  220. sems = append(sems, b.beforeScript)
  221. }
  222. sems = append(sems, strings.Join(cs, "."))
  223. if len(b.afterScript) > 0 {
  224. sems = append(sems, b.afterScript)
  225. }
  226. return strings.Join(sems, "; ")
  227. }
  228. func toJsValue(v interface{}) string {
  229. switch v.(type) {
  230. case Var:
  231. return fmt.Sprint(v)
  232. default:
  233. return h.JSONString(v)
  234. }
  235. }
  236. func (b *VueEventTagBuilder) MarshalJSON() ([]byte, error) {
  237. panic(fmt.Sprintf("call .Go() at the end, value: %s", b.String()))
  238. }
  239. const InitContextVars = "v-init-context:vars"
  240. const InitContextLocals = "v-init-context:locals"
  241. type VFieldNameOption interface {
  242. private()
  243. }
  244. type UseForm string
  245. func (UseForm) private() {}
  246. func VFieldName(v string, opts ...VFieldNameOption) []interface{} {
  247. formVar := "plaidForm"
  248. for _, op := range opts {
  249. if vf, ok := op.(UseForm); ok {
  250. formVar = string(vf)
  251. }
  252. }
  253. return []interface{}{
  254. "v-field-name",
  255. fmt.Sprintf("[%s, %s]", formVar, h.JSONString(v)),
  256. }
  257. }
  258. func GlobalEvents() *h.HTMLTagBuilder {
  259. return h.Tag("global-events")
  260. }