html_output.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #pragma once
  2. #include "concat_strings.h"
  3. #include <util/generic/string.h>
  4. #include <util/stream/output.h>
  5. #include <library/cpp/html/pcdata/pcdata.h>
  6. #include <util/system/tls.h>
  7. extern Y_POD_THREAD(IOutputStream*) HtmlOutputStreamPtr;
  8. static IOutputStream& HtmlOutputStream() {
  9. Y_ABORT_UNLESS(!!HtmlOutputStreamPtr);
  10. return *HtmlOutputStreamPtr;
  11. }
  12. struct THtmlOutputStreamPushPop {
  13. IOutputStream* const Prev;
  14. THtmlOutputStreamPushPop(IOutputStream* outputStream)
  15. : Prev(HtmlOutputStreamPtr)
  16. {
  17. HtmlOutputStreamPtr = outputStream;
  18. }
  19. ~THtmlOutputStreamPushPop() {
  20. HtmlOutputStreamPtr = Prev;
  21. }
  22. };
  23. struct TChars {
  24. TString Text;
  25. bool NeedEscape;
  26. TChars(TStringBuf text)
  27. : Text(text)
  28. , NeedEscape(true)
  29. {
  30. }
  31. TChars(TStringBuf text, bool escape)
  32. : Text(text)
  33. , NeedEscape(escape)
  34. {
  35. }
  36. TChars(const char* text)
  37. : Text(text)
  38. , NeedEscape(true)
  39. {
  40. }
  41. TChars(const char* text, bool escape)
  42. : Text(text)
  43. , NeedEscape(escape)
  44. {
  45. }
  46. TString Escape() {
  47. if (NeedEscape) {
  48. return EncodeHtmlPcdata(Text);
  49. } else {
  50. return Text;
  51. }
  52. }
  53. };
  54. struct TAttr {
  55. TString Name;
  56. TString Value;
  57. TAttr(TStringBuf name, TStringBuf value)
  58. : Name(name)
  59. , Value(value)
  60. {
  61. }
  62. TAttr() {
  63. }
  64. bool operator!() const {
  65. return !Name;
  66. }
  67. };
  68. static inline void Doctype() {
  69. HtmlOutputStream() << "<!doctype html>\n";
  70. }
  71. static inline void Nl() {
  72. HtmlOutputStream() << "\n";
  73. }
  74. static inline void Sp() {
  75. HtmlOutputStream() << " ";
  76. }
  77. static inline void Text(TStringBuf text) {
  78. HtmlOutputStream() << EncodeHtmlPcdata(text);
  79. }
  80. static inline void Line(TStringBuf text) {
  81. Text(text);
  82. Nl();
  83. }
  84. static inline void WriteAttr(TAttr a) {
  85. if (!!a) {
  86. HtmlOutputStream() << " " << a.Name << "='" << EncodeHtmlPcdata(a.Value) << "'";
  87. }
  88. }
  89. static inline void Open(TStringBuf tag, TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr(), TAttr a4 = TAttr()) {
  90. HtmlOutputStream() << "<" << tag;
  91. WriteAttr(a1);
  92. WriteAttr(a2);
  93. WriteAttr(a3);
  94. WriteAttr(a4);
  95. HtmlOutputStream() << ">";
  96. }
  97. static inline void Open(TStringBuf tag, TStringBuf cssClass, TStringBuf id = "") {
  98. Open(tag, TAttr("class", cssClass), !!id ? TAttr("id", id) : TAttr());
  99. }
  100. static inline void OpenBlock(TStringBuf tag, TStringBuf cssClass = "") {
  101. Open(tag, cssClass);
  102. Nl();
  103. }
  104. static inline void Close(TStringBuf tag) {
  105. HtmlOutputStream() << "</" << tag << ">\n";
  106. }
  107. static inline void CloseBlock(TStringBuf tag) {
  108. Close(tag);
  109. Nl();
  110. }
  111. static inline void TagWithContent(TStringBuf tag, TChars content) {
  112. HtmlOutputStream() << "<" << tag << ">" << content.Escape() << "</" << tag << ">";
  113. }
  114. static inline void BlockTagWithContent(TStringBuf tag, TStringBuf content) {
  115. TagWithContent(tag, content);
  116. Nl();
  117. }
  118. static inline void TagWithClass(TStringBuf tag, TStringBuf cssClass) {
  119. Open(tag, cssClass);
  120. Close(tag);
  121. }
  122. static inline void Hn(unsigned n, TStringBuf title) {
  123. BlockTagWithContent(ConcatStrings("h", n), title);
  124. }
  125. static inline void Small(TStringBuf text) {
  126. TagWithContent("small", text);
  127. }
  128. static inline void HnWithSmall(unsigned n, TStringBuf title, TStringBuf small) {
  129. TString tagName = ConcatStrings("h", n);
  130. Open(tagName);
  131. HtmlOutputStream() << title;
  132. Sp();
  133. Small(small);
  134. Close(tagName);
  135. }
  136. static inline void H1(TStringBuf title) {
  137. Hn(1, title);
  138. }
  139. static inline void H2(TStringBuf title) {
  140. Hn(2, title);
  141. }
  142. static inline void H3(TStringBuf title) {
  143. Hn(3, title);
  144. }
  145. static inline void H4(TStringBuf title) {
  146. Hn(4, title);
  147. }
  148. static inline void H5(TStringBuf title) {
  149. Hn(5, title);
  150. }
  151. static inline void H6(TStringBuf title) {
  152. Hn(6, title);
  153. }
  154. static inline void Pre(TStringBuf content) {
  155. HtmlOutputStream() << "<pre>" << EncodeHtmlPcdata(content) << "</pre>\n";
  156. }
  157. static inline void Li(TStringBuf content) {
  158. BlockTagWithContent("li", content);
  159. }
  160. static inline void LiWithClass(TStringBuf cssClass, TStringBuf content) {
  161. Open("li", cssClass);
  162. Text(content);
  163. Close("li");
  164. }
  165. static inline void OpenA(TStringBuf href) {
  166. Open("a", TAttr("href", href));
  167. }
  168. static inline void A(TStringBuf href, TStringBuf text) {
  169. OpenA(href);
  170. Text(text);
  171. Close("a");
  172. }
  173. static inline void Td(TStringBuf content) {
  174. TagWithContent("td", content);
  175. }
  176. static inline void Th(TStringBuf content, TStringBuf cssClass = "") {
  177. OpenBlock("th", cssClass);
  178. Text(content);
  179. CloseBlock("th");
  180. }
  181. static inline void DivWithClassAndContent(TStringBuf cssClass, TStringBuf content) {
  182. Open("div", cssClass);
  183. Text(content);
  184. Close("div");
  185. }
  186. static inline void BootstrapError(TStringBuf text) {
  187. DivWithClassAndContent("alert alert-danger", text);
  188. }
  189. static inline void BootstrapInfo(TStringBuf text) {
  190. DivWithClassAndContent("alert alert-info", text);
  191. }
  192. static inline void ScriptHref(TStringBuf href) {
  193. Open("script",
  194. TAttr("language", "javascript"),
  195. TAttr("type", "text/javascript"),
  196. TAttr("src", href));
  197. Close("script");
  198. Nl();
  199. }
  200. static inline void LinkStylesheet(TStringBuf href) {
  201. Open("link", TAttr("rel", "stylesheet"), TAttr("href", href));
  202. Close("link");
  203. Nl();
  204. }
  205. static inline void LinkFavicon(TStringBuf href) {
  206. Open("link", TAttr("rel", "shortcut icon"), TAttr("href", href));
  207. Close("link");
  208. Nl();
  209. }
  210. static inline void Title(TChars title) {
  211. TagWithContent("title", title);
  212. Nl();
  213. }
  214. static inline void Code(TStringBuf content) {
  215. TagWithContent("code", content);
  216. }
  217. struct TTagGuard {
  218. const TString TagName;
  219. TTagGuard(TStringBuf tagName, TStringBuf cssClass, TStringBuf id = "")
  220. : TagName(tagName)
  221. {
  222. Open(TagName, cssClass, id);
  223. }
  224. TTagGuard(TStringBuf tagName, TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr(), TAttr a4 = TAttr())
  225. : TagName(tagName)
  226. {
  227. Open(tagName, a1, a2, a3, a4);
  228. }
  229. ~TTagGuard() {
  230. Close(TagName);
  231. }
  232. };
  233. struct TDivGuard: public TTagGuard {
  234. TDivGuard(TStringBuf cssClass, TStringBuf id = "")
  235. : TTagGuard("div", cssClass, id)
  236. {
  237. }
  238. TDivGuard(TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr())
  239. : TTagGuard("div", a1, a2, a3)
  240. {
  241. }
  242. };
  243. struct TAGuard {
  244. TAGuard(TStringBuf href) {
  245. OpenA(href);
  246. }
  247. ~TAGuard() {
  248. Close("a");
  249. }
  250. };
  251. struct TScriptFunctionGuard {
  252. TTagGuard Script;
  253. TScriptFunctionGuard()
  254. : Script("script")
  255. {
  256. Line("$(function() {");
  257. }
  258. ~TScriptFunctionGuard() {
  259. Line("});");
  260. }
  261. };