The version of vichan running on lainchan.org
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

426 lines
14KB

  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, do_confirm, confirm_ok_action, confirm_cancel_action) {
  67. var handler, div, bg, closebtn, okbtn;
  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. bg = $("<div id='alert_background'></div>").appendTo(handler);
  74. div = $("<div id='alert_div'></div>").appendTo(handler);
  75. closebtn = $("<a id='alert_close' href='javascript:void(0)'><i class='fa fa-times'></i></div>")
  76. .appendTo(div);
  77. $("<div id='alert_message'></div>").html(a).appendTo(div);
  78. okbtn = $("<button class='button alert_button'>"+_("OK")+"</button>").appendTo(div);
  79. if (do_confirm) {
  80. confirm_ok_action = (typeof confirm_ok_action !== "function") ? function(){} : confirm_ok_action;
  81. confirm_cancel_action = (typeof confirm_cancel_action !== "function") ? function(){} : confirm_cancel_action;
  82. okbtn.click(confirm_ok_action);
  83. $("<button class='button alert_button'>"+_("Cancel")+"</button>").click(confirm_cancel_action).click(close).appendTo(div);
  84. bg.click(confirm_cancel_action);
  85. okbtn.click(confirm_cancel_action);
  86. closebtn.click(confirm_cancel_action);
  87. }
  88. bg.click(close);
  89. okbtn.click(close);
  90. closebtn.click(close);
  91. handler.fadeIn(400);
  92. }
  93. var saved = {};
  94. var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}';
  95. var styles = {
  96. {% endraw %}
  97. {% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
  98. {% endraw %}{% endfor %}{% raw %}
  99. };
  100. var codestyles = {
  101. {% endraw %}
  102. {% for stylesheet in code_stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
  103. {% endraw %}{% endfor %}{% raw %}
  104. };
  105. if (typeof board_name === 'undefined') {
  106. var board_name = false;
  107. }
  108. function changeStyle(styleName, link) {
  109. {% endraw %}
  110. {% if config.stylesheets_board %}{% raw %}
  111. if (board_name) {
  112. stylesheet_choices[board_name] = styleName;
  113. localStorage.board_stylesheets = JSON.stringify(stylesheet_choices);
  114. }
  115. {% endraw %}{% else %}
  116. localStorage.stylesheet = styleName;
  117. {% endif %}
  118. {% raw %}
  119. // Main stylesheet
  120. if (!document.getElementById('stylesheet')) {
  121. var s = document.createElement('link');
  122. s.rel = 'stylesheet';
  123. s.type = 'text/css';
  124. s.id = 'stylesheet';
  125. var x = document.getElementsByTagName('head')[0];
  126. x.appendChild(s);
  127. }
  128. document.getElementById('stylesheet').href = styles[styleName];
  129. selectedstyle = styleName;
  130. // Code stylesheet
  131. if (!document.getElementById('code_stylesheet')) {
  132. var s = document.createElement('link');
  133. s.rel = 'stylesheet';
  134. s.type = 'text/css';
  135. s.id = 'code_stylesheet';
  136. var x = document.getElementsByTagName('head')[0];
  137. x.appendChild(s);
  138. }
  139. document.getElementById('code_stylesheet').href = codestyles[styleName];
  140. if (document.getElementsByClassName('styles').length != 0) {
  141. var styleLinks = document.getElementsByClassName('styles')[0].childNodes;
  142. for (var i = 0; i < styleLinks.length; i++) {
  143. styleLinks[i].className = '';
  144. }
  145. }
  146. if (link) {
  147. link.className = 'selected';
  148. }
  149. if (typeof $ != 'undefined')
  150. $(window).trigger('stylesheet', styleName);
  151. }
  152. {% endraw %}
  153. {% if config.stylesheets_board %}
  154. {% raw %}
  155. if (!localStorage.board_stylesheets) {
  156. localStorage.board_stylesheets = '{}';
  157. }
  158. var stylesheet_choices = JSON.parse(localStorage.board_stylesheets);
  159. if (board_name && stylesheet_choices[board_name]) {
  160. for (var styleName in styles) {
  161. if (styleName == stylesheet_choices[board_name]) {
  162. changeStyle(styleName);
  163. break;
  164. }
  165. }
  166. }
  167. {% endraw%}
  168. {% else %}
  169. {% raw %}
  170. if (localStorage.stylesheet) {
  171. for (var styleName in styles) {
  172. if (styleName == localStorage.stylesheet) {
  173. changeStyle(styleName);
  174. break;
  175. }
  176. }
  177. }
  178. {% endraw %}
  179. {% endif %}
  180. {% raw %}
  181. function init_stylechooser() {
  182. var newElement = document.createElement('div');
  183. newElement.className = 'styles';
  184. for (styleName in styles) {
  185. var style = document.createElement('a');
  186. style.innerHTML = '[' + styleName + ']';
  187. style.onclick = function() {
  188. changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this);
  189. };
  190. if (styleName == selectedstyle) {
  191. style.className = 'selected';
  192. }
  193. style.href = 'javascript:void(0);';
  194. newElement.appendChild(style);
  195. }
  196. document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling);
  197. }
  198. function get_cookie(cookie_name) {
  199. var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
  200. if (results)
  201. return (unescape(results[2]));
  202. else
  203. return null;
  204. }
  205. function highlightReply(id) {
  206. if (typeof window.event != "undefined" && event.which == 2) {
  207. // don't highlight on middle click
  208. return true;
  209. }
  210. var divs = document.getElementsByTagName('div');
  211. for (var i = 0; i < divs.length; i++)
  212. {
  213. if (divs[i].className.indexOf('post') != -1)
  214. divs[i].className = divs[i].className.replace(/highlighted/, '');
  215. }
  216. if (id) {
  217. var post = document.getElementById('reply_'+id);
  218. if (post)
  219. post.className += ' highlighted';
  220. window.location.hash = id;
  221. }
  222. return true;
  223. }
  224. function generatePassword() {
  225. var pass = '';
  226. var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}';
  227. for (var i = 0; i < 8; i++) {
  228. var rnd = Math.floor(Math.random() * chars.length);
  229. pass += chars.substring(rnd, rnd + 1);
  230. }
  231. return pass;
  232. }
  233. function dopost(form) {
  234. if (form.elements['name']) {
  235. localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, '');
  236. }
  237. if (form.elements['password']) {
  238. localStorage.password = form.elements['password'].value;
  239. }
  240. if (form.elements['email'] && form.elements['email'].value != 'sage') {
  241. localStorage.email = form.elements['email'].value;
  242. }
  243. saved[document.location] = form.elements['body'].value;
  244. sessionStorage.body = JSON.stringify(saved);
  245. return form.elements['body'].value != "" || (form.elements['file'] && form.elements['file'].value != "") || (form.elements.file_url && form.elements['file_url'].value != "");
  246. }
  247. function citeReply(id, with_link) {
  248. var textarea = document.getElementById('body');
  249. if (!textarea) return false;
  250. if (document.selection) {
  251. // IE
  252. textarea.focus();
  253. var sel = document.selection.createRange();
  254. sel.text = '>>' + id + '\n';
  255. } else if (textarea.selectionStart || textarea.selectionStart == '0') {
  256. var start = textarea.selectionStart;
  257. var end = textarea.selectionEnd;
  258. textarea.value = textarea.value.substring(0, start) + '>>' + id + '\n' + textarea.value.substring(end, textarea.value.length);
  259. textarea.selectionStart += ('>>' + id).length + 1;
  260. textarea.selectionEnd = textarea.selectionStart;
  261. } else {
  262. // ???
  263. textarea.value += '>>' + id + '\n';
  264. }
  265. if (typeof $ != 'undefined') {
  266. var select = document.getSelection().toString();
  267. if (select) {
  268. var body = $('#reply_' + id + ', #op_' + id).find('div.body'); // TODO: support for OPs
  269. var index = body.text().indexOf(select.replace('\n', '')); // for some reason this only works like this
  270. if (index > -1) {
  271. textarea.value += '>' + select + '\n';
  272. }
  273. }
  274. $(window).trigger('cite', [id, with_link]);
  275. $(textarea).change();
  276. }
  277. return false;
  278. }
  279. function rememberStuff() {
  280. if (document.forms.post) {
  281. if (document.forms.post.password) {
  282. if (!localStorage.password)
  283. localStorage.password = generatePassword();
  284. document.forms.post.password.value = localStorage.password;
  285. }
  286. if (localStorage.name && document.forms.post.elements['name'])
  287. document.forms.post.elements['name'].value = localStorage.name;
  288. if (localStorage.email && document.forms.post.elements['email'])
  289. document.forms.post.elements['email'].value = localStorage.email;
  290. if (window.location.hash.indexOf('q') == 1)
  291. citeReply(window.location.hash.substring(2), true);
  292. if (sessionStorage.body) {
  293. var saved = JSON.parse(sessionStorage.body);
  294. if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) {
  295. // Remove successful posts
  296. var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}'));
  297. for (var url in successful) {
  298. saved[url] = null;
  299. }
  300. sessionStorage.body = JSON.stringify(saved);
  301. document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;';
  302. }
  303. if (saved[document.location]) {
  304. document.forms.post.body.value = saved[document.location];
  305. }
  306. }
  307. if (localStorage.body) {
  308. document.forms.post.body.value = localStorage.body;
  309. localStorage.body = '';
  310. }
  311. }
  312. }
  313. var script_settings = function(script_name) {
  314. this.script_name = script_name;
  315. this.get = function(var_name, default_val) {
  316. if (typeof tb_settings == 'undefined' ||
  317. typeof tb_settings[this.script_name] == 'undefined' ||
  318. typeof tb_settings[this.script_name][var_name] == 'undefined')
  319. return default_val;
  320. return tb_settings[this.script_name][var_name];
  321. }
  322. };
  323. function init() {
  324. init_stylechooser();
  325. {% endraw %}
  326. {% if config.allow_delete %}
  327. if (document.forms.postcontrols) {
  328. document.forms.postcontrols.password.value = localStorage.password;
  329. }
  330. {% endif %}
  331. {% raw %}
  332. if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1))
  333. highlightReply(window.location.hash.substring(1));
  334. }
  335. var RecaptchaOptions = {
  336. theme : 'clean'
  337. };
  338. onready_callbacks = [];
  339. function onready(fnc) {
  340. onready_callbacks.push(fnc);
  341. }
  342. function ready() {
  343. for (var i = 0; i < onready_callbacks.length; i++) {
  344. onready_callbacks[i]();
  345. }
  346. }
  347. {% endraw %}
  348. var post_date = "{{ config.post_date }}";
  349. var max_images = {{ config.max_images }};
  350. onready(init);
  351. {% if config.google_analytics %}{% raw %}
  352. 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 %}
  353. {% if config.statcounter_project and config.statcounter_security %}
  354. var sc = document.createElement('script');
  355. sc.type = 'text/javascript';
  356. 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>");';
  357. var s = document.getElementsByTagName('script')[0];
  358. s.parentNode.insertBefore(sc, s);
  359. {% endif %}