page.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package app
  2. import (
  3. "net/url"
  4. "strings"
  5. )
  6. // Page is the interface that describes a web page.
  7. type Page interface {
  8. // Returns the page title.
  9. Title() string
  10. // Sets the page title.
  11. SetTitle(string)
  12. // Returns the page language.
  13. Lang() string
  14. // Set the page language.
  15. SetLang(string)
  16. // Returns the page description.
  17. Description() string
  18. // Sets the page description.
  19. SetDescription(string)
  20. // Returns the page author.
  21. Author() string
  22. // Sets the page author.
  23. SetAuthor(string)
  24. // Returns the page keywords.
  25. Keywords() string
  26. // Sets the page keywords.
  27. SetKeywords(...string)
  28. // Set the page loading label.
  29. SetLoadingLabel(string)
  30. // Returns the image used by social networks when linking the page.
  31. Image() string
  32. // Set the image used by social networks when linking the page.
  33. SetImage(string)
  34. // Returns the page URL.
  35. URL() *url.URL
  36. // Replace the the current page URL by the given one in the browser history.
  37. //
  38. // Does not work when pre-rendering.
  39. ReplaceURL(*url.URL)
  40. // Returns the page width and height in px.
  41. Size() (w int, h int)
  42. }
  43. type requestPage struct {
  44. title string
  45. lang string
  46. description string
  47. author string
  48. keywords string
  49. loadingLabel string
  50. image string
  51. url *url.URL
  52. width int
  53. height int
  54. }
  55. func (p *requestPage) Title() string {
  56. return p.title
  57. }
  58. func (p *requestPage) SetTitle(v string) {
  59. p.title = v
  60. }
  61. func (p *requestPage) Lang() string {
  62. return p.lang
  63. }
  64. func (p *requestPage) SetLang(v string) {
  65. p.lang = v
  66. }
  67. func (p *requestPage) Description() string {
  68. return p.description
  69. }
  70. func (p *requestPage) SetDescription(v string) {
  71. p.description = v
  72. }
  73. func (p *requestPage) Author() string {
  74. return p.author
  75. }
  76. func (p *requestPage) SetAuthor(v string) {
  77. p.author = v
  78. }
  79. func (p *requestPage) Keywords() string {
  80. return p.keywords
  81. }
  82. func (p *requestPage) SetKeywords(v ...string) {
  83. p.keywords = strings.Join(v, ", ")
  84. }
  85. func (p *requestPage) SetLoadingLabel(v string) {
  86. p.loadingLabel = v
  87. }
  88. func (p *requestPage) Image() string {
  89. return p.image
  90. }
  91. func (p *requestPage) SetImage(v string) {
  92. p.image = v
  93. }
  94. func (p *requestPage) URL() *url.URL {
  95. return p.url
  96. }
  97. func (p *requestPage) ReplaceURL(v *url.URL) {
  98. p.url = v
  99. }
  100. func (p *requestPage) Size() (width int, height int) {
  101. return p.width, p.height
  102. }
  103. type browserPage struct {
  104. url *url.URL
  105. dispatcher Dispatcher
  106. }
  107. func (p browserPage) Title() string {
  108. return Window().
  109. Get("document").
  110. Get("title").
  111. String()
  112. }
  113. func (p browserPage) SetTitle(v string) {
  114. Window().Get("document").Set("title", v)
  115. p.metaByProperty("og:title").setAttr("content", v)
  116. }
  117. func (p browserPage) Lang() string {
  118. return Window().
  119. Get("document").
  120. Get("documentElement").
  121. Get("lang").
  122. String()
  123. }
  124. func (p browserPage) SetLang(v string) {
  125. Window().
  126. Get("document").
  127. Get("documentElement").
  128. Set("lang", v)
  129. }
  130. func (p browserPage) Description() string {
  131. return p.metaByName("description").getAttr("content")
  132. }
  133. func (p browserPage) SetDescription(v string) {
  134. p.metaByName("description").setAttr("content", v)
  135. p.metaByProperty("og:description").setAttr("content", v)
  136. }
  137. func (p browserPage) Author() string {
  138. return p.metaByName("author").getAttr("content")
  139. }
  140. func (p browserPage) SetAuthor(v string) {
  141. p.metaByName("author").setAttr("content", v)
  142. }
  143. func (p browserPage) Keywords() string {
  144. return p.metaByName("keywords").getAttr("content")
  145. }
  146. func (p browserPage) SetKeywords(v ...string) {
  147. p.metaByName("keywords").setAttr("content", strings.Join(v, ", "))
  148. }
  149. func (p browserPage) SetLoadingLabel(v string) {
  150. }
  151. func (p browserPage) Image() string {
  152. return p.metaByProperty("og:image").getAttr("content")
  153. }
  154. func (p browserPage) SetImage(v string) {
  155. p.metaByProperty("og:image").setAttr("content", p.dispatcher.resolveStaticResource(v))
  156. }
  157. func (p browserPage) URL() *url.URL {
  158. if p.url != nil {
  159. return p.url
  160. }
  161. return Window().URL()
  162. }
  163. func (p browserPage) ReplaceURL(v *url.URL) {
  164. Window().replaceHistory(v)
  165. p.metaByProperty("og:url").setAttr("content", v.String())
  166. }
  167. func (p browserPage) Size() (width int, height int) {
  168. return Window().Size()
  169. }
  170. func (p browserPage) metaByName(v string) Value {
  171. meta := Window().
  172. Get("document").
  173. Call("querySelector", "meta[name='"+v+"']")
  174. if meta.IsNull() {
  175. meta, _ = Window().createElement("meta", "")
  176. meta.setAttr("name", v)
  177. Window().Get("document").
  178. Call("getElementsByTagName", "head").
  179. Index(0).
  180. appendChild(meta)
  181. }
  182. return meta
  183. }
  184. func (p browserPage) metaByProperty(v string) Value {
  185. meta := Window().
  186. Get("document").
  187. Call("querySelector", "meta[property='"+v+"']")
  188. if meta.IsNull() {
  189. meta, _ = Window().createElement("meta", "")
  190. meta.setAttr("property", v)
  191. Window().Get("document").
  192. Call("getElementsByTagName", "head").
  193. Index(0).
  194. appendChild(meta)
  195. }
  196. return meta
  197. }