Advertisement
Guest User

qr2

a guest
Jul 18th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.62 KB | None | 0 0
  1. /*
  2. * quick-reply.js
  3. * https://github.com/savetheinternet/Tinyboard/blob/master/js/quick-reply.js
  4. *
  5. * Released under the MIT license
  6. * Copyright (c) 2013 Michael Save <savetheinternet@tinyboard.org>
  7. * Copyright (c) 2013-2014 Marcin Łabanowski <marcin@6irc.net>
  8. *
  9. * Usage:
  10. * $config['additional_javascript'][] = 'js/jquery.min.js';
  11. * $config['additional_javascript'][] = 'js/jquery-ui.custom.min.js'; // Optional; if you want the form to be draggable.
  12. * $config['additional_javascript'][] = 'js/quick-reply.js';
  13. *
  14. */
  15.  
  16. (function() {
  17. var settings = new script_settings('quick-reply');
  18.  
  19. var do_css = function() {
  20. $('#quick-reply-css').remove();
  21.  
  22. // Find background of reply posts
  23. var dummy_reply = $('<div class="post reply"></div>').appendTo($('body'));
  24. var reply_background = dummy_reply.css('backgroundColor');
  25. var reply_border_style = dummy_reply.css('borderStyle');
  26. var reply_border_color = dummy_reply.css('borderColor');
  27. var reply_border_width = dummy_reply.css('borderWidth');
  28. dummy_reply.remove();
  29.  
  30. $('<style type="text/css" id="quick-reply-css">\
  31. #quick-reply {\
  32. position: fixed;\
  33. right: 5%;\
  34. top: 5%;\
  35. float: right;\
  36. display: block;\
  37. padding: 0 0 0 0;\
  38. width: 300px;\
  39. z-index: 100;\
  40. }\
  41. #quick-reply table {\
  42. border-collapse: collapse;\
  43. background: ' + reply_background + ';\
  44. border-style: ' + reply_border_style + ';\
  45. border-width: ' + reply_border_width + ';\
  46. border-color: ' + reply_border_color + ';\
  47. margin: 0;\
  48. width: 100%;\
  49. }\
  50. #quick-reply tr td:nth-child(2) {\
  51. white-space: nowrap;\
  52. padding-right: 4px;\
  53. }\
  54. #quick-reply td.post-options > * {\
  55. display: block;\
  56. margin-bottom: 2px;\
  57. }\
  58. #quick-reply tr td:nth-child(2) input[type="submit"] {\
  59. width: 100%;\
  60. }\
  61. #quick-reply th, #quick-reply td {\
  62. margin: 0;\
  63. padding: 0;\
  64. }\
  65. #quick-reply th {\
  66. text-align: center;\
  67. padding: 2px 0;\
  68. border: 1px solid #222;\
  69. }\
  70. #quick-reply th .handle {\
  71. float: left;\
  72. width: 100%;\
  73. display: inline-block;\
  74. }\
  75. #quick-reply th .close-btn {\
  76. float: right;\
  77. padding: 0 5px;\
  78. }\
  79. #quick-reply input[type="text"], #quick-reply select {\
  80. width: 100%;\
  81. padding: 2px;\
  82. font-size: 10pt;\
  83. box-sizing: border-box;\
  84. -webkit-box-sizing:border-box;\
  85. -moz-box-sizing: border-box;\
  86. }\
  87. #quick-reply textarea {\
  88. width: 100%;\
  89. min-width: 100%;\
  90. box-sizing: border-box;\
  91. -webkit-box-sizing:border-box;\
  92. -moz-box-sizing: border-box;\
  93. font-size: 10pt;\
  94. resize: vertical horizontal;\
  95. }\
  96. #quick-reply input, #quick-reply select, #quick-reply textarea {\
  97. margin: 0 0 1px 0;\
  98. }\
  99. #quick-reply input[type="file"] {\
  100. padding: 5px 2px;\
  101. }\
  102. #quick-reply .nonsense {\
  103. display: none;\
  104. }\
  105. #quick-reply td.submit {\
  106. width: 1%;\
  107. }\
  108. #quick-reply td.recaptcha {\
  109. text-align: center;\
  110. padding: 0 0 1px 0;\
  111. }\
  112. #quick-reply td.recaptcha span {\
  113. display: inline-block;\
  114. width: 100%;\
  115. background: white;\
  116. border: 1px solid #ccc;\
  117. cursor: pointer;\
  118. }\
  119. #quick-reply td.recaptcha-response {\
  120. padding: 0 0 1px 0;\
  121. }\
  122. @media screen and (max-width: 400px) {\
  123. #quick-reply {\
  124. display: none !important;\
  125. }\
  126. }\
  127. </style>').appendTo($('head'));
  128. };
  129.  
  130. var show_quick_reply = function(){
  131. if($('div.banner').length == 0)
  132. return;
  133. if($('#quick-reply').length != 0)
  134. return;
  135.  
  136. do_css();
  137.  
  138. var $postForm = $('form[name="post"]').clone();
  139.  
  140. $postForm.clone();
  141.  
  142. $dummyStuff = $('<div class="nonsense"></div>').appendTo($postForm);
  143.  
  144. $postForm.find('table tr').each(function() {
  145. var $th = $(this).children('th:first');
  146. var $td = $(this).children('td:first');
  147. if ($th.length && $td.length) {
  148. $td.attr('colspan', 2);
  149.  
  150. if ($td.find('input[type="text"]').length) {
  151. // Replace <th> with input placeholders
  152. $td.find('input[type="text"]')
  153. .removeAttr('size')
  154. .attr('placeholder', $th.clone().children().remove().end().text());
  155. }
  156.  
  157. // Move anti-spam nonsense and remove <th>
  158. $th.contents().filter(function() {
  159. return this.nodeType == 3; // Node.TEXT_NODE
  160. }).remove();
  161. $th.contents().appendTo($dummyStuff);
  162. $th.remove();
  163.  
  164. if ($td.find('input[name="password"]').length) {
  165. // Hide password field
  166. $(this).hide();
  167. }
  168.  
  169. // reCAPTCHA
  170. if ($td.find('#recaptcha_widget_div').length) {
  171. // Just show the image, and have it interact with the real form.
  172. var $captchaimg = $td.find('#recaptcha_image img');
  173.  
  174. $captchaimg
  175. .removeAttr('id')
  176. .removeAttr('style')
  177. .addClass('recaptcha_image')
  178. .click(function() {
  179. $('#recaptcha_reload').click();
  180. });
  181.  
  182. // When we get a new captcha...
  183. $('#recaptcha_response_field').focus(function() {
  184. if ($captchaimg.attr('src') != $('#recaptcha_image img').attr('src')) {
  185. $captchaimg.attr('src', $('#recaptcha_image img').attr('src'));
  186. $postForm.find('input[name="recaptcha_challenge_field"]').val($('#recaptcha_challenge_field').val());
  187. $postForm.find('input[name="recaptcha_response_field"]').val('').focus();
  188. }
  189. });
  190.  
  191. $postForm.submit(function() {
  192. setTimeout(function() {
  193. $('#recaptcha_reload').click();
  194. }, 200);
  195. });
  196.  
  197. // Make a new row for the response text
  198. var $newRow = $('<tr><td class="recaptcha-response" colspan="2"></td></tr>');
  199. $newRow.children().first().append(
  200. $td.find('input').removeAttr('style')
  201. );
  202. $newRow.find('#recaptcha_response_field')
  203. .removeAttr('id')
  204. .addClass('recaptcha_response_field')
  205. .attr('placeholder', $('#recaptcha_response_field').attr('placeholder'));
  206.  
  207. $('#recaptcha_response_field').addClass('recaptcha_response_field')
  208.  
  209. $td.replaceWith($('<td class="recaptcha" colspan="2"></td>').append($('<span></span>').append($captchaimg)));
  210.  
  211. $newRow.insertAfter(this);
  212. }
  213.  
  214. // Upload section
  215. if ($td.find('input[type="file"]').length) {
  216. if ($td.find('input[name="file_url"]').length) {
  217. $file_url = $td.find('input[name="file_url"]');
  218.  
  219. if (settings.get('show_remote', false)) {
  220. // Make a new row for it
  221. var $newRow = $('<tr><td colspan="2"></td></tr>');
  222.  
  223. $file_url.clone().attr('placeholder', _('Upload URL')).appendTo($newRow.find('td'));
  224.  
  225. $newRow.insertBefore(this);
  226. }
  227. $file_url.parent().remove();
  228.  
  229.  
  230. $td.find('label').remove();
  231. $td.contents().filter(function() {
  232. return this.nodeType == 3; // Node.TEXT_NODE
  233. }).remove();
  234. $td.find('input[name="file_url"]').removeAttr('id');
  235. }
  236.  
  237. if ($(this).find('input[name="spoiler"]').length) {
  238. $td.removeAttr('colspan');
  239. }
  240. }
  241.  
  242. // Remove oekaki if existent
  243. if ($(this).is('#oekaki')) {
  244. $(this).remove();
  245. }
  246.  
  247. // Remove upload selection
  248. if ($td.is('#upload_selection')) {
  249. $(this).remove();
  250. }
  251.  
  252. // Remove mod controls, because it looks shit.
  253. if ($td.find('input[type="checkbox"]').length) {
  254. if ($postForm.find('td.post-options').length == 0)
  255. $postForm.find('input[type="file"]').parent().removeAttr('colspan').after('<td class="post-options"></td>');
  256.  
  257. var tr = this;
  258. $td.find('input[type="checkbox"]').each(function() {
  259. if ($(this).attr('name') == 'spoiler' || $(this).attr('name') == 'no_country') {
  260. $(this).parent('label').appendTo($postForm.find('td.post-options'));
  261. } else {
  262. $(tr).hide();
  263. }
  264. });
  265. }
  266.  
  267. $td.find('small').hide();
  268. }
  269. });
  270.  
  271. $postForm.find('textarea[name="body"]').removeAttr('id').removeAttr('cols').attr('placeholder', _('Comment'));
  272.  
  273. $postForm.find('textarea:not([name="body"]),input[type="hidden"]').removeAttr('id').appendTo($dummyStuff);
  274.  
  275. $postForm.find('br').remove();
  276. $postForm.find('table').prepend('<tr><th colspan="2">\
  277. <span class="handle">\
  278. <a class="close-btn" href="javascript:void(0)">×</a>\
  279. ' + _('Quick Reply') + '\
  280. </span>\
  281. </th></tr>');
  282.  
  283. $postForm.attr('id', 'quick-reply');
  284.  
  285. $postForm.appendTo($('body')).hide();
  286. $origPostForm = $('form[name="post"]:first');
  287.  
  288. // Synchronise body text with original post form
  289. $origPostForm.find('textarea[name="body"]').on('change input propertychange', function() {
  290. $postForm.find('textarea[name="body"]').val($(this).val());
  291. });
  292. $postForm.find('textarea[name="body"]').on('change input propertychange', function() {
  293. $origPostForm.find('textarea[name="body"]').val($(this).val()).trigger('input');
  294. });
  295. $postForm.find('textarea[name="body"]').focus(function() {
  296. $origPostForm.find('textarea[name="body"]').removeAttr('id');
  297. $(this).attr('id', 'body');
  298. });
  299. $origPostForm.find('textarea[name="body"]').focus(function() {
  300. $postForm.find('textarea[name="body"]').removeAttr('id');
  301. $(this).attr('id', 'body');
  302. });
  303. // Synchronise other inputs
  304. $origPostForm.find('input[type="text"],select').on('change input propertychange', function() {
  305. $postForm.find('[name="' + $(this).attr('name') + '"]').val($(this).val());
  306. });
  307. $postForm.find('input[type="text"],select').on('change input propertychange', function() {
  308. $origPostForm.find('[name="' + $(this).attr('name') + '"]').val($(this).val());
  309. });
  310.  
  311. $origPostForm.find('input[type="checkbox"]').on('change input propertychange', function() {
  312. $postForm.find('[name="' + $(this).attr('name') + '"]').prop('checked', $(this).prop('checked'));
  313. });
  314. $postForm.find('input[type="checkbox"]').on('change input propertychange', function() {
  315. $origPostForm.find('[name="' + $(this).attr('name') + '"]').prop('checked', $(this).prop('checked'));
  316. });
  317.  
  318. if (typeof $postForm.draggable != 'undefined') {
  319. if (localStorage.quickReplyPosition) {
  320. var offset = JSON.parse(localStorage.quickReplyPosition);
  321. if (offset.top < 0)
  322. offset.top = 0;
  323. if (offset.right > $(window).width() - $postForm.width())
  324. offset.right = $(window).width() - $postForm.width();
  325. if (offset.top > $(window).height() - $postForm.height())
  326. offset.top = $(window).height() - $postForm.height();
  327. $postForm.css('right', offset.right).css('top', offset.top);
  328. }
  329. $postForm.draggable({
  330. handle: 'th .handle',
  331. containment: 'window',
  332. distance: 10,
  333. scroll: false,
  334. stop: function() {
  335. var offset = {
  336. top: $(this).offset().top - $(window).scrollTop(),
  337. right: $(window).width() - $(this).offset().left - $(this).width(),
  338. };
  339. localStorage.quickReplyPosition = JSON.stringify(offset);
  340.  
  341. $postForm.css('right', offset.right).css('top', offset.top).css('left', 'auto');
  342. }
  343. });
  344. $postForm.find('th .handle').css('cursor', 'move');
  345. }
  346.  
  347. $postForm.find('th .close-btn').click(function() {
  348. $origPostForm.find('textarea[name="body"]').attr('id', 'body');
  349. $postForm.remove();
  350. floating_link();
  351. });
  352.  
  353. // Fix bug when table gets too big for form. Shouldn't exist, but crappy CSS etc.
  354. $postForm.show();
  355. $postForm.width($postForm.find('table').width());
  356. $postForm.hide();
  357.  
  358. $(window).trigger('quick-reply');
  359.  
  360. $(window).ready(function() {
  361. if (settings.get('hide_at_top', true)) {
  362. $(window).scroll(function() {
  363. if ($(this).width() <= 400)
  364. return;
  365. if ($(this).scrollTop() < $origPostForm.offset().top + $origPostForm.height() - 100)
  366. $postForm.fadeOut(100);
  367. else
  368. $postForm.fadeIn(100);
  369. }).scroll();
  370. } else {
  371. $postForm.show();
  372. }
  373.  
  374. $(window).on('stylesheet', function() {
  375. do_css();
  376. if ($('link#stylesheet').attr('href')) {
  377. $('link#stylesheet')[0].onload = do_css;
  378. }
  379. });
  380. });
  381. };
  382.  
  383. $(window).on('cite', function(e, id, with_link) {
  384. if ($(this).width() <= 400)
  385. return;
  386. show_quick_reply();
  387. if (with_link) {
  388. $(document).ready(function() {
  389. if ($('#' + id).length) {
  390. highlightReply(id);
  391. $(document).scrollTop($('#' + id).offset().top);
  392. }
  393.  
  394. // Honestly, I'm not sure why we need setTimeout() here, but it seems to work.
  395. // Same for the "tmp" variable stuff you see inside here:
  396. setTimeout(function() {
  397. var tmp = $('#quick-reply textarea[name="body"]').val();
  398. $('#quick-reply textarea[name="body"]').val('').focus().val(tmp);
  399. }, 1);
  400. });
  401. }
  402. });
  403.  
  404. var floating_link = function() {
  405. if (!settings.get('floating_link', false))
  406. return;
  407. $('<a href="javascript:void(0)" class="quick-reply-btn">'+_('Quick Reply')+'</a>')
  408. .click(function() {
  409. show_quick_reply();
  410. $(this).remove();
  411. }).appendTo($('body'));
  412.  
  413. $(window).on('quick-reply', function() {
  414. $('.quick-reply-btn').remove();
  415. });
  416. };
  417.  
  418. if (settings.get('floating_link', false)) {
  419. $(window).ready(function() {
  420. if($('div.banner').length == 0)
  421. return;
  422. $('<style type="text/css">\
  423. a.quick-reply-btn {\
  424. position: fixed;\
  425. right: 0;\
  426. bottom: 0;\
  427. display: block;\
  428. padding: 5px 13px;\
  429. text-decoration: none;\
  430. }\
  431. </style>').appendTo($('head'));
  432.  
  433. floating_link();
  434.  
  435. if (settings.get('hide_at_top', true)) {
  436. $('.quick-reply-btn').hide();
  437.  
  438. $(window).scroll(function() {
  439. if ($(this).width() <= 400)
  440. return;
  441. if ($(this).scrollTop() < $('form[name="post"]:first').offset().top + $('form[name="post"]:first').height() - 100)
  442. $('.quick-reply-btn').fadeOut(100);
  443. else
  444. $('.quick-reply-btn').fadeIn(100);
  445. }).scroll();
  446. }
  447. });
  448. }
  449. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement