The version of vichan running on lainchan.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
13KB

  1. {% raw %}
  2. /* gettext-compatible _ function, example of usage:
  3. *
  4. * > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php)
  5. * > alert(_("Hello!"));
  6. * Witaj!
  7. */
  8. function _(s) {
  9. return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s;
  10. }
  11. /* printf-like formatting function, example of usage:
  12. *
  13. * > alert(fmt("There are {0} birds on {1} trees", [3,4]));
  14. * There are 3 birds on 4 trees
  15. * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php)
  16. * > alert(fmt(_("{0} users"), [3]));
  17. * 3 uzytkownikow
  18. */
  19. function fmt(s,a) {
  20. return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; });
  21. }
  22. function until($timestamp) {
  23. var $difference = $timestamp - Date.now()/1000|0, $num;
  24. switch(true){
  25. case ($difference < 60):
  26. return "" + $difference + ' ' + _('second(s)');
  27. case ($difference < 3600): //60*60 = 3600
  28. return "" + ($num = Math.round($difference/(60))) + ' ' + _('minute(s)');
  29. case ($difference < 86400): //60*60*24 = 86400
  30. return "" + ($num = Math.round($difference/(3600))) + ' ' + _('hour(s)');
  31. case ($difference < 604800): //60*60*24*7 = 604800
  32. return "" + ($num = Math.round($difference/(86400))) + ' ' + _('day(s)');
  33. case ($difference < 31536000): //60*60*24*365 = 31536000
  34. return "" + ($num = Math.round($difference/(604800))) + ' ' + _('week(s)');
  35. default:
  36. return "" + ($num = Math.round($difference/(31536000))) + ' ' + _('year(s)');
  37. }
  38. }
  39. function ago($timestamp) {
  40. var $difference = (Date.now()/1000|0) - $timestamp, $num;
  41. switch(true){
  42. case ($difference < 60) :
  43. return "" + $difference + ' ' + _('second(s)');
  44. case ($difference < 3600): //60*60 = 3600
  45. return "" + ($num = Math.round($difference/(60))) + ' ' + _('minute(s)');
  46. case ($difference < 86400): //60*60*24 = 86400
  47. return "" + ($num = Math.round($difference/(3600))) + ' ' + _('hour(s)');
  48. case ($difference < 604800): //60*60*24*7 = 604800
  49. return "" + ($num = Math.round($difference/(86400))) + ' ' + _('day(s)');
  50. case ($difference < 31536000): //60*60*24*365 = 31536000
  51. return "" + ($num = Math.round($difference/(604800))) + ' ' + _('week(s)');
  52. default:
  53. return "" + ($num = Math.round($difference/(31536000))) + ' ' + _('year(s)');
  54. }
  55. }
  56. var datelocale =
  57. { days: [_('Sunday'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday')]
  58. , shortDays: [_("Sun"), _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat")]
  59. , months: [_('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'), _('September'), _('October'), _('November'), _('December')]
  60. , shortMonths: [_('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'), _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')]
  61. , AM: _('AM')
  62. , PM: _('PM')
  63. , am: _('am')
  64. , pm: _('pm')
  65. };
  66. function alert(a) {
  67. var handler, div;
  68. var close = function() {
  69. handler.fadeOut(400, function() { handler.remove(); });
  70. return false;
  71. };
  72. handler = $("<div id='alert_handler'></div>").hide().appendTo('body');
  73. $("<div id='alert_background'></div>").click(close).appendTo(handler);
  74. div = $("<div id='alert_div'></div>").appendTo(handler);
  75. $("<a id='alert_close' href='javascript:void(0)'><i class='fa fa-times'></i></div>")
  76. .click(close).appendTo(div);
  77. $("<div id='alert_message'></div>").html(a).appendTo(div);
  78. $("<button class='button alert_button'>"+_("OK")+"</button>").click(close).appendTo(div);
  79. handler.fadeIn(400);
  80. }
  81. var saved = {};
  82. var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}';
  83. var styles = {
  84. {% endraw %}
  85. {% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
  86. {% endraw %}{% endfor %}{% raw %}
  87. };
  88. var board_name = false;
  89. function changeStyle(styleName, link) {
  90. {% endraw %}
  91. {% if config.stylesheets_board %}{% raw %}
  92. if (board_name) {
  93. stylesheet_choices[board_name] = styleName;
  94. localStorage.board_stylesheets = JSON.stringify(stylesheet_choices);
  95. }
  96. {% endraw %}{% else %}
  97. localStorage.stylesheet = styleName;
  98. {% endif %}
  99. {% raw %}
  100. if (!document.getElementById('stylesheet')) {
  101. var s = document.createElement('link');
  102. s.rel = 'stylesheet';
  103. s.type = 'text/css';
  104. s.id = 'stylesheet';
  105. var x = document.getElementsByTagName('head')[0];
  106. x.appendChild(s);
  107. }
  108. document.getElementById('stylesheet').href = styles[styleName];
  109. selectedstyle = styleName;
  110. if (document.getElementsByClassName('styles').length != 0) {
  111. var styleLinks = document.getElementsByClassName('styles')[0].childNodes;
  112. for (var i = 0; i < styleLinks.length; i++) {
  113. styleLinks[i].className = '';
  114. }
  115. }
  116. if (link) {
  117. link.className = 'selected';
  118. }
  119. if (typeof $ != 'undefined')
  120. $(window).trigger('stylesheet', styleName);
  121. }
  122. {% endraw %}
  123. {% if config.stylesheets_board %}
  124. {# This is such an unacceptable mess. There needs to be an easier way. #}
  125. var matches = document.URL.match(/\/(\w+)\/($|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.file_index|replace({'.': '\\.'}) }}|{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }})/);
  126. {% raw %}
  127. if (matches) {
  128. board_name = matches[1];
  129. }
  130. if (!localStorage.board_stylesheets) {
  131. localStorage.board_stylesheets = '{}';
  132. }
  133. var stylesheet_choices = JSON.parse(localStorage.board_stylesheets);
  134. if (board_name && stylesheet_choices[board_name]) {
  135. for (var styleName in styles) {
  136. if (styleName == stylesheet_choices[board_name]) {
  137. changeStyle(styleName);
  138. break;
  139. }
  140. }
  141. }
  142. {% endraw%}
  143. {% else %}
  144. {% raw %}
  145. if (localStorage.stylesheet) {
  146. for (var styleName in styles) {
  147. if (styleName == localStorage.stylesheet) {
  148. changeStyle(styleName);
  149. break;
  150. }
  151. }
  152. }
  153. {% endraw %}
  154. {% endif %}
  155. {% raw %}
  156. function init_stylechooser() {
  157. var newElement = document.createElement('div');
  158. newElement.className = 'styles';
  159. for (styleName in styles) {
  160. var style = document.createElement('a');
  161. style.innerHTML = '[' + styleName + ']';
  162. style.onclick = function() {
  163. changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this);
  164. };
  165. if (styleName == selectedstyle) {
  166. style.className = 'selected';
  167. }
  168. style.href = 'javascript:void(0);';
  169. newElement.appendChild(style);
  170. }
  171. document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling);
  172. }
  173. function get_cookie(cookie_name) {
  174. var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
  175. if (results)
  176. return (unescape(results[2]));
  177. else
  178. return null;
  179. }
  180. function highlightReply(id) {
  181. if (typeof window.event != "undefined" && event.which == 2) {
  182. // don't highlight on middle click
  183. return true;
  184. }
  185. var divs = document.getElementsByTagName('div');
  186. for (var i = 0; i < divs.length; i++)
  187. {
  188. if (divs[i].className.indexOf('post') != -1)
  189. divs[i].className = divs[i].className.replace(/highlighted/, '');
  190. }
  191. if (id) {
  192. var post = document.getElementById('reply_'+id);
  193. if (post)
  194. post.className += ' highlighted';
  195. window.location.hash = id;
  196. }
  197. return true;
  198. }
  199. function generatePassword() {
  200. var pass = '';
  201. var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}';
  202. for (var i = 0; i < 8; i++) {
  203. var rnd = Math.floor(Math.random() * chars.length);
  204. pass += chars.substring(rnd, rnd + 1);
  205. }
  206. return pass;
  207. }
  208. function dopost(form) {
  209. if (form.elements['name']) {
  210. localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, '');
  211. }
  212. if (form.elements['password']) {
  213. localStorage.password = form.elements['password'].value;
  214. }
  215. if (form.elements['email'] && form.elements['email'].value != 'sage') {
  216. localStorage.email = form.elements['email'].value;
  217. }
  218. saved[document.location] = form.elements['body'].value;
  219. sessionStorage.body = JSON.stringify(saved);
  220. return form.elements['body'].value != "" || form.elements['file'].value != "" || (form.elements.file_url && form.elements['file_url'].value != "");
  221. }
  222. function citeReply(id, with_link) {
  223. var textarea = document.getElementById('body');
  224. if (!textarea) return false;
  225. if (document.selection) {
  226. // IE
  227. textarea.focus();
  228. var sel = document.selection.createRange();
  229. sel.text = '>>' + id + '\n';
  230. } else if (textarea.selectionStart || textarea.selectionStart == '0') {
  231. var start = textarea.selectionStart;
  232. var end = textarea.selectionEnd;
  233. textarea.value = textarea.value.substring(0, start) + '>>' + id + '\n' + textarea.value.substring(end, textarea.value.length);
  234. textarea.selectionStart += ('>>' + id).length + 1;
  235. textarea.selectionEnd = textarea.selectionStart;
  236. } else {
  237. // ???
  238. textarea.value += '>>' + id + '\n';
  239. }
  240. if (typeof $ != 'undefined') {
  241. var select = document.getSelection().toString();
  242. if (select) {
  243. var body = $('#reply_' + id + ', #op_' + id).find('div.body'); // TODO: support for OPs
  244. var index = body.text().indexOf(select.replace('\n', '')); // for some reason this only works like this
  245. if (index > -1) {
  246. textarea.value += '>' + select + '\n';
  247. }
  248. }
  249. $(window).trigger('cite', [id, with_link]);
  250. $(textarea).change();
  251. }
  252. return false;
  253. }
  254. function rememberStuff() {
  255. if (document.forms.post) {
  256. if (document.forms.post.password) {
  257. if (!localStorage.password)
  258. localStorage.password = generatePassword();
  259. document.forms.post.password.value = localStorage.password;
  260. }
  261. if (localStorage.name && document.forms.post.elements['name'])
  262. document.forms.post.elements['name'].value = localStorage.name;
  263. if (localStorage.email && document.forms.post.elements['email'])
  264. document.forms.post.elements['email'].value = localStorage.email;
  265. if (window.location.hash.indexOf('q') == 1)
  266. citeReply(window.location.hash.substring(2), true);
  267. if (sessionStorage.body) {
  268. var saved = JSON.parse(sessionStorage.body);
  269. if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) {
  270. // Remove successful posts
  271. var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}'));
  272. for (var url in successful) {
  273. saved[url] = null;
  274. }
  275. sessionStorage.body = JSON.stringify(saved);
  276. document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;';
  277. }
  278. if (saved[document.location]) {
  279. document.forms.post.body.value = saved[document.location];
  280. }
  281. }
  282. if (localStorage.body) {
  283. document.forms.post.body.value = localStorage.body;
  284. localStorage.body = '';
  285. }
  286. }
  287. }
  288. var script_settings = function(script_name) {
  289. this.script_name = script_name;
  290. this.get = function(var_name, default_val) {
  291. if (typeof tb_settings == 'undefined' ||
  292. typeof tb_settings[this.script_name] == 'undefined' ||
  293. typeof tb_settings[this.script_name][var_name] == 'undefined')
  294. return default_val;
  295. return tb_settings[this.script_name][var_name];
  296. }
  297. };
  298. function init() {
  299. init_stylechooser();
  300. {% endraw %}
  301. {% if config.allow_delete %}
  302. if (document.forms.postcontrols) {
  303. document.forms.postcontrols.password.value = localStorage.password;
  304. }
  305. {% endif %}
  306. {% raw %}
  307. if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1))
  308. highlightReply(window.location.hash.substring(1));
  309. }
  310. var RecaptchaOptions = {
  311. theme : 'clean'
  312. };
  313. onready_callbacks = [];
  314. function onready(fnc) {
  315. onready_callbacks.push(fnc);
  316. }
  317. function ready() {
  318. for (var i = 0; i < onready_callbacks.length; i++) {
  319. onready_callbacks[i]();
  320. }
  321. }
  322. {% endraw %}
  323. var post_date = "{{ config.post_date }}";
  324. var max_images = {{ config.max_images }};
  325. onready(init);
  326. {% if config.google_analytics %}{% raw %}
  327. var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %}
  328. {% if config.statcounter_project and config.statcounter_security %}
  329. var sc = document.createElement('script');
  330. sc.type = 'text/javascript';
  331. sc.innerHTML = 'var sc_project={{ config.statcounter_project }};var sc_invisible=1;var sc_security="{{ config.statcounter_security }}";var scJsHost=(("https:" == document.location.protocol) ? "https://secure." : "http://www.");document.write("<sc"+"ript type=text/javascript src="+scJsHost+"statcounter.com/counter/counter.js></"+"script>");';
  332. var s = document.getElementsByTagName('script')[0];
  333. s.parentNode.insertBefore(sc, s);
  334. {% endif %}