diff options
Diffstat (limited to 'js/quick-reply.js')
| -rw-r--r-- | js/quick-reply.js | 374 |
1 files changed, 346 insertions, 28 deletions
diff --git a/js/quick-reply.js b/js/quick-reply.js index bee204b7..267b6915 100644 --- a/js/quick-reply.js +++ b/js/quick-reply.js @@ -3,45 +3,363 @@ * https://github.com/savetheinternet/Tinyboard/blob/master/js/quick-reply.js * * Released under the MIT license - * Copyright (c) 2012 Michael Save <savetheinternet@tinyboard.org> + * Copyright (c) 2013 Michael Save <savetheinternet@tinyboard.org> * * Usage: - * $config['quick_reply'] = true; * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/jquery-ui.custom.min.js'; // Optional; if you want the form to be draggable. * $config['additional_javascript'][] = 'js/quick-reply.js'; * */ -if (active_page == 'index') { -$(document).ready(function(){ - if($('div.banner').length != 0) - return; // not index +var do_css = function() { + $('#quick-reply-css').remove(); - txt_new_topic = $('form[name=post] input[type=submit]').val(); - txt_new_reply = txt_new_topic == _('Submit') ? txt_new_topic : new_reply_string; + // Find background of reply posts + var dummy_reply = $('<div class="post reply"></div>').appendTo($('body')); + var reply_background = dummy_reply.css('backgroundColor'); + var reply_border_style = dummy_reply.css('borderStyle'); + var reply_border_color = dummy_reply.css('borderColor'); + var reply_border_width = dummy_reply.css('borderWidth'); + dummy_reply.remove(); - undo_quick_reply = function() { - $('div.banner').remove(); - $('form[name=post] input[type=submit]').val(txt_new_topic); - $('form[name=post] input[name=quick-reply]').remove(); - } + $('<style type="text/css" id="quick-reply-css">\ + #quick-reply {\ + position: fixed;\ + right: 0;\ + top: 5%;\ + float: right;\ + display: block;\ + padding: 0 0 0 0;\ + width: 300px;\ + }\ + #quick-reply table {\ + border-collapse: collapse;\ + background: ' + reply_background + ';\ + border-style: ' + reply_border_style + ';\ + border-width: ' + reply_border_width + ';\ + border-color: ' + reply_border_color + ';\ + margin: 0;\ + width: 100%;\ + }\ + #quick-reply tr td:nth-child(2) {\ + white-space: nowrap;\ + text-align: right;\ + padding-right: 4px;\ + }\ + #quick-reply tr td:nth-child(2) input[type="submit"] {\ + width: 100%;\ + }\ + #quick-reply th, #quick-reply td {\ + margin: 0;\ + padding: 0;\ + }\ + #quick-reply th {\ + text-align: center;\ + padding: 2px 0;\ + border: 1px solid #222;\ + }\ + #quick-reply th .handle {\ + float: left;\ + width: 100%;\ + display: inline-block;\ + }\ + #quick-reply th .close-btn {\ + float: right;\ + padding: 0 5px;\ + }\ + #quick-reply input[type="text"], #quick-reply select {\ + width: 100%;\ + padding: 2px;\ + font-size: 10pt;\ + box-sizing: border-box;\ + -webkit-box-sizing:border-box;\ + -moz-box-sizing: border-box;\ + }\ + #quick-reply textarea {\ + width: 100%;\ + box-sizing: border-box;\ + -webkit-box-sizing:border-box;\ + -moz-box-sizing: border-box;\ + font-size: 10pt;\ + resize: vertical;\ + }\ + #quick-reply input, #quick-reply select, #quick-reply textarea {\ + margin: 0 0 1px 0;\ + }\ + #quick-reply input[type="file"] {\ + padding: 5px 2px;\ + }\ + #quick-reply .nonsense {\ + display: none;\ + }\ + #quick-reply td.submit {\ + width: 1%;\ + }\ + #quick-reply td.recaptcha {\ + text-align: center;\ + padding: 0 0 1px 0;\ + }\ + #quick-reply td.recaptcha span {\ + display: inline-block;\ + width: 100%;\ + background: white;\ + border: 1px solid #ccc;\ + cursor: pointer;\ + }\ + #quick-reply td.recaptcha-response {\ + padding: 0 0 1px 0;\ + }\ + @media screen and (max-width: 800px) {\ + #quick-reply {\ + display: none !important;\ + }\ + }\ + </style>').appendTo($('head')); +}; + +var show_quick_reply = function(){ + if($('div.banner').length == 0) + return; + if($('#quick-reply').length != 0) + return; - $('div.post.op').each(function() { - var id = $(this).children('p.intro').children('a.post_no:eq(1)').text(); - $('<a href="#">['+_("Quick reply")+']</a>').insertAfter($(this).children('p.intro').children('a:last')).click(function() { - $('div.banner').remove(); - $('<div class="banner">'+fmt(_("Posting mode: Replying to <small>>>{0}</small>"), [id])+' <a class="unimportant" onclick="undo_quick_reply()" href="javascript:void(0)">['+_("Return")+']</a></div>') - .insertBefore('form[name=post]'); - $('form[name=post] input[type=submit]').val(txt_new_reply); - - $('<input type="hidden" name="quick-reply" value="' + id + '">').appendTo($('form[name=post]')); - - $('form[name=post] textarea').select(); + do_css(); + + var $postForm = $('form[name="post"]').clone(); + + $postForm.clone(); + + $dummyStuff = $('<div class="nonsense"></div>').appendTo($postForm); + + $postForm.find('table tr').each(function() { + var $th = $(this).children('th:first'); + var $td = $(this).children('td:first'); + if ($th.length && $td.length) { + $td.attr('colspan', 2); + + if ($td.find('input[type="text"]').length) { + // Replace <th> with input placeholders + $td.find('input[type="text"]') + .removeAttr('size') + .attr('placeholder', $th.clone().children().remove().end().text()); + } + + // Move anti-spam nonsense and remove <th> + $th.contents().filter(function() { + return this.nodeType == 3; // Node.TEXT_NODE + }).remove(); + $th.contents().appendTo($dummyStuff); + $th.remove(); + + if ($td.find('input[name="password"]').length) { + // Hide password field + $(this).hide(); + } + + // Fix submit button + if ($td.find('input[type="submit"]').length) { + $td.removeAttr('colspan'); + $('<td class="submit"></td>').append($td.find('input[type="submit"]')).insertAfter($td); + } + + // reCAPTCHA + if ($td.find('#recaptcha_widget_div').length) { + // Just show the image, and have it interact with the real form. + var $captchaimg = $td.find('#recaptcha_image img'); + + $captchaimg + .removeAttr('id') + .removeAttr('style') + .addClass('recaptcha_image') + .click(function() { + $('#recaptcha_reload').click(); + }); + + // When we get a new captcha... + $('#recaptcha_response_field').focus(function() { + if ($captchaimg.attr('src') != $('#recaptcha_image img').attr('src')) { + $captchaimg.attr('src', $('#recaptcha_image img').attr('src')); + $postForm.find('input[name="recaptcha_challenge_field"]').val($('#recaptcha_challenge_field').val()); + $postForm.find('input[name="recaptcha_response_field"]').val('').focus(); + } + }); + + $postForm.submit(function() { + setTimeout(function() { + $('#recaptcha_reload').click(); + }, 200); + }); + + // Make a new row for the response text + var $newRow = $('<tr><td class="recaptcha-response" colspan="2"></td></tr>'); + $newRow.children().first().append( + $td.find('input').removeAttr('style') + ); + $newRow.find('#recaptcha_response_field') + .removeAttr('id') + .addClass('recaptcha_response_field') + .attr('placeholder', $('#recaptcha_response_field').attr('placeholder')); + + $('#recaptcha_response_field').addClass('recaptcha_response_field') + + $td.replaceWith($('<td class="recaptcha" colspan="2"></td>').append($('<span></span>').append($captchaimg))); + + $newRow.insertAfter(this); + } + + // Upload section + if ($td.find('input[type="file"]').length) { + if ($td.find('input[name="file_url"]').length) { + $file_url = $td.find('input[name="file_url"]'); + + // Make a new row for it + var $newRow = $('<tr><td colspan="2"></td></tr>'); + + $file_url.clone().attr('placeholder', _('Upload URL')).appendTo($newRow.find('td')); + $file_url.parent().remove(); + + $newRow.insertBefore(this); + + $td.find('label').remove(); + $td.contents().filter(function() { + return this.nodeType == 3; // Node.TEXT_NODE + }).remove(); + $td.find('input[name="file_url"]').removeAttr('id'); + } + + if ($(this).find('input[name="spoiler"]').length) { + $td.removeAttr('colspan'); + } + } - window.scrollTo(0, 0); + // Remove mod controls, because it looks shit. + if ($td.find('input[type="checkbox"]').length) { + var tr = this; + $td.find('input[type="checkbox"]').each(function() { + if ($(this).attr('name') == 'spoiler') { + $td.find('label').remove(); + $(this).attr('id', 'q-spoiler-image'); + $postForm.find('input[type="file"]').parent() + .removeAttr('colspan') + .after($('<td class="spoiler"></td>').append(this, ' ', $('<label for="q-spoiler-image">').text(_('Spoiler Image')))); + } else { + $(tr).remove(); + } + }); + } - return false; - }); + $td.find('small').hide(); + } + }); + + $postForm.find('textarea[name="body"]').removeAttr('id').removeAttr('cols').attr('placeholder', _('Comment')); + + $postForm.find('textarea:not([name="body"]),input[type="hidden"]').removeAttr('id').appendTo($dummyStuff); + + $postForm.find('br').remove(); + $postForm.find('table').prepend('<tr><th colspan="2">\ + <span class="handle">\ + <a class="close-btn" href="javascript:void(0)">X</a>\ + ' + _('Quick Reply') + '\ + </span>\ + </th></tr>'); + + $postForm.attr('id', 'quick-reply'); + + $postForm.appendTo($('body')).hide(); + $origPostForm = $('form[name="post"]:first'); + + // Synchronise body text with original post form + $origPostForm.find('textarea[name="body"]').bind('change input propertychange', function() { + $postForm.find('textarea[name="body"]').val($(this).val()); + }); + $postForm.find('textarea[name="body"]').bind('change input propertychange', function() { + $origPostForm.find('textarea[name="body"]').val($(this).val()); + }); + $postForm.find('textarea[name="body"]').focus(function() { + $origPostForm.find('textarea[name="body"]').removeAttr('id'); + $(this).attr('id', 'body'); + }); + $origPostForm.find('textarea[name="body"]').focus(function() { + $postForm.find('textarea[name="body"]').removeAttr('id'); + $(this).attr('id', 'body'); + }); + // Synchronise other inputs + $origPostForm.find('input[type="text"],select').bind('change input propertychange', function() { + $postForm.find('[name="' + $(this).attr('name') + '"]').val($(this).val()); + }); + $postForm.find('input[type="text"],select').bind('change input propertychange', function() { + $origPostForm.find('[name="' + $(this).attr('name') + '"]').val($(this).val()); + }); + + if (typeof $postForm.draggable != 'undefined') { + if (localStorage.quickReplyPosition) { + var offset = JSON.parse(localStorage.quickReplyPosition); + if (offset.right > $(window).width() - $postForm.width()) + offset.right = $(window).width() - $postForm.width(); + if (offset.top > $(window).height() - $postForm.height()) + offset.top = $(window).height() - $postForm.height(); + $postForm.css('right', offset.right).css('top', offset.top); + } + $postForm.draggable({ + handle: 'th .handle', + containment: 'window', + distance: 10, + scroll: false, + stop: function() { + var offset = { + top: $(this).offset().top - $(window).scrollTop(), + right: $(window).width() - $(this).offset().left - $(this).width(), + }; + localStorage.quickReplyPosition = JSON.stringify(offset); + + $postForm.css('right', offset.right).css('top', offset.top).css('left', 'auto'); + } + }); + $postForm.find('th .handle').css('cursor', 'move'); + } + + $postForm.find('th .close-btn').click(function() { + $origPostForm.find('textarea[name="body"]').attr('id', 'body'); + $postForm.remove(); }); + + // Fix bug when table gets too big for form. Shouldn't exist, but crappy CSS etc. + $postForm.show(); + $postForm.width($postForm.find('table').width()); + $postForm.hide(); + + $(window).trigger('quick-reply'); + + $(window).ready(function() { + $(window).scroll(function() { + if ($(this).width() <= 800) + return; + if ($(this).scrollTop() < $origPostForm.offset().top + $origPostForm.height() - 100) + $postForm.fadeOut(100); + else + $postForm.fadeIn(100); + }).on('stylesheet', function() { + do_css(); + if ($('link#stylesheet').attr('href')) { + $('link#stylesheet')[0].onload = do_css; + } + }).scroll(); + }); +}; + +$(window).on('cite', function(e, id, with_link) { + if ($(this).width() <= 800) + return; + show_quick_reply(); + $('#quick-reply textarea').focus(); + if (with_link) { + $(window).ready(function() { + if ($('#' + id).length) { + highlightReply(id); + $(window).scrollTop($('#' + id).offset().top); + } + }); + } }); -} |
