// // // // // // // // DDMenu // // // // // // /* Menucool Drop Down Menu v2015.9.4 Copyright www.menucool.com */ function Ddmenu(k){"use strict";var r=function(a,b){return a.getElementsByTagName(b)},o=navigator,F=function(a,c){if(typeof getComputedStyle!="undefined")var b=getComputedStyle(a,null);else if(a.currentStyle)b=a.currentStyle;else b=a.style;return b[c]},q=function(a){if(a&&a.stopPropagation)a.stopPropagation();else if(window.event)window.event.cancelBubble=true},fb=function(b){var a=b?b:window.event;if(a.preventDefault)a.preventDefault();else if(a)a.returnValue=false},i,e,v,g=document,m="className",a="length",z="addEventListener",lb=["$1$2$3","$1$2$3","$1$24","$1$23","$1$22"],B="offsetWidth",C="zIndex",j="onclick",b=[],x=-1,l=0,H=function(a){if(l)l[e][v]=a?"block":"none"},f,nb,c,h=function(){return c&&c[B]},p=function(a,c,b){if(a[z])a[z](c,b,false);else a.attachEvent&&a.attachEvent("on"+c,b)},E=function(a,b){if(b)K(a,"over");else J(a,"over");a[e][C]=b?2:1},cb="ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch,T=(o.msPointerEnabled||o.pointerEnabled)&&(o.msMaxTouchPoints||o.maxTouchPoints);if(T)if(o.msPointerEnabled)var O="MSPointerOver",P="MSPointerOut";else{O="pointerover";P="pointerout"}var n=function(e){for(var c=r(g,"li"),b=0,f=c[a];b8)try{b=(new Function("$","_","e","a","b","c",L(f,c[a]))).apply(this,[e,b,c,d,g,A])}catch(h){}},t=function(a,b){return b?g[a](b):g[a]},L=function(e,b){for(var d=[],c=0;c7?b:3));return d.join("")},gb=function(b,d){var c=b[a];while(c--)if(b[c]===d)return true;return false},d=function(a,c){var b=false;if(a[m])b=gb(a[m].split(" "),c);return b},K=function(a,b){if(!d(a,b))if(a[m]=="")a[m]=b;else a[m]+=" "+b},J=function(d,f){if(d[m]){for(var e="",c=d[m].split(" "),b=0,g=c[a];b8&&j==9&&e.shiftKey){w();return}for(var f=0;f=c[a])b=0;if(c[b].a.getAttribute("tabindex")!=null){c[b].a.focus();D(c[b],c[b].a)}else{var d=r(c[b].a,"a");if(d[a]){d[0].focus();D(c[b],c[b].a)}else u(c,b,e)}}function bb(b,a){return!a||a.nodeType!=1?0:a[i]==b?1:a[i]&&a[i][i]==b?1:0}function D(a){n(0);a.l(1)}function w(){d(c,"menu-icon-active")&&c[j]()}function ib(t,e){var f=g.activeElement;if(f==c){if(e==9)!d(c,"menu-icon-active")&&c[j]();if(e==27){w();c.blur()}e==40&&u(b,-1,1);return}var h=-1;if(f)for(var m=0;m=0&&o[k].focus()}}}var W=function(b){var a;if(window.XMLHttpRequest)a=new XMLHttpRequest;else a=new ActiveXObject("Microsoft.XMLHTTP");a.onreadystatechange=function(){if(a.readyState==4&&a.status==200){var d=a.responseText,f=/^[\s\S]*]*>([\s\S]+)<\/body>[\s\S]*$/i;if(f.test(d))d=d.replace(f,"$1");var c=t(A,"div");c[e].padding=c[e].margin="0";b[i].insertBefore(c,b);c.innerHTML=d;b[e][v]="none";Q()}};a.open("GET",b.href,true);a.send()},R=function(){i="parentNode",e="style",v="display";if(f.e){var a=t("getElementById",f.e);if(a)W(a);else alert('Cannot find the anchor (id="'+f.e+'")')}else Q()},I=0,G=0,Q=function(){if(!I){var b=t("getElementById",f.b);if(b){for(var i=r(b,"*"),h=0;h 0) } function toggle(element) { element = $(element); if (element.style.display == 'none') element.style.display = ''; else element.style.display = 'none'; } var form_submitted = false; function submit_form() { if(form_submitted == true) { return; } document.myform.mysubmit.value = 'Sending...'; document.myform.mysubmit.disabled = true; form_submitted = true; document.myform.submit(); } // //// // ////// COOKIE.JS // //// // var today = new Date(); var expiryyear = new Date(today.getTime() + 365 * 24 * 60 * 60 * 1000); var expirymonth = new Date(today.getTime() + 30 * 24 * 60 * 60 * 1000); var expiryday = new Date(today.getTime() + 24 * 60 * 60 * 1000); function getCookie(name) { var reg= new RegExp("; "+name+";|; "+name+"=([^;]*)"); var matches=reg.exec('; '+document.cookie+';'); if (matches) return ((matches[1])?unescape(matches[1]):''); return null; } // not supplying domain restricts cookie to current domain only. // supplying it includes the given domain and all subdomains. function setCookie(name,value,expires,path,domain,samesite) { document.cookie = name + '=' + escape (value) + ((expires) ? '; expires=' + expires.toGMTString() : '') + ((path) ? '; path=' + path : '') + ((domain) ? '; domain=' + domain : '') + '; SameSite='+(samesite?samesite:'Lax') + '; secure'; return getCookie(name)!=null?true:false; } function deleteCookie(name,path,domain) { if (getCookie(name)!=null) { document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-1970 00:00:01 GMT"; } } // //// // ////// TEXTAREA control functions // //// // /** * Insert the given text before and after the selected text is a specified textarea, * OR * Insert both pre- and post-pended text at the caret position in the specified textarea. * * @author Original script: guys at http://www.mybboard.net/, this modification: yak, yak@furaffinity.net * @param {DOMNode} elm Any element inside the form * @param {String} open_tag Prepend the selected text with the value of thos variable * @param {String} close_tag Append the value of this variable to the selected text. Can be FALSE in case of a self-closing tag. * @final */ function performInsert(elm, open_tag, close_tag) { var textarea = elm.up('form').down('textarea'); if(!close_tag) { close_tag = ''; } textarea.focus(); if(document.selection) { // IE var selection = document.selection; var range = selection.createRange(); if((selection.type == 'Text' || selection.type == 'None') && range != null) { if(close_tag != '' && range.text.length > 0) { range.text = open_tag+range.text+close_tag; } else { range.text = open_tag+close_tag+range.text; } range.select(); } else { textarea.value += open_tag+close_tag; } } else if(textarea.selectionEnd) { // Mozilla var select_start = textarea.selectionStart; var select_end = textarea.selectionEnd; var scroll_top = textarea.scrollTop; if(select_end <= 2) { select_end = textarea.textLength; } var start = textarea.value.substring(0, select_start); var middle = textarea.value.substring(select_start, select_end); var end = textarea.value.substring(select_end, textarea.textLength); var keep_selected; if(select_end - select_start > 0 && close_tag != '') { keep_selected = true; middle = open_tag+middle+close_tag; } else { keep_selected = false; middle = open_tag+close_tag+middle; } textarea.value = start+middle+end; if(keep_selected === true) { textarea.selectionStart = select_start; textarea.selectionEnd = select_start + middle.length; } else { textarea.selectionStart = select_start + middle.length; textarea.selectionEnd = textarea.selectionStart; } textarea.scrollTop = scroll_top; } else { textarea.value += open_tag+close_tag; } } function check_password_strength(password) { // // Calculate password bits // var alpha = "abcdefghijklmnopqrstuvwxyz"; var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var upper_punct = "~`!@#$%^&*()-_+="; var digits = "1234567890"; var totalChars = 0x7f - 0x20; var alphaChars = alpha.length; var upperChars = upper.length; var upper_punctChars = upper_punct.length; var digitChars = digits.length; var otherChars = totalChars - (alphaChars + upperChars + upper_punctChars + digitChars); var bits = 0; if(password.length) { var fAlpha = false; var fUpper = false; var fUpperPunct = false; var fDigit = false; var fOther = false; var charset = 0; for(var i=0; i= 128) { return 'best'; } else if(bits < 128 && bits >= 64) { return 'strong'; } else if(bits<64 && bits>=56) { return 'medium'; } else if(bits<56 && bits>0) { return 'weak'; } else { return 'unrated'; } } function parse_bbcode(text) { return text. gsub(/(\r?\n){3,}/, "\n\n").gsub("\n", '
'). gsub(/:(icon|link)([^:]+):/, function(match){return ''+match[2]+'';}). gsub(/:([^:]+)(icon|link):/, function(match){return ''+match[1]+'';}). gsub(/\[url=[^\]]+\](.+?)\[\/url\]/, function(match){return ''+match[1]+'';}). gsub(/\[url\](.+?)\[\/url\]/, function(match){return ''+match[1]+'';}). gsub(/\[b\](.+?)\[\/b\]/, function(match){return ''+match[1]+'';}). gsub(/\[i\](.+?)\[\/i\]/, function(match){return ''+match[1]+'';}). gsub(/\[s\](.+?)\[\/s\]/, function(match){return ''+match[1]+'';}). gsub(/\[u\](.+?)\[\/u\]/, function(match){return ''+match[1]+'';}). gsub(/\[\/?(center|b|i|s|u)\]/, function(match){return '';}); } function highlight_new_comments(minutes) { var comments = $$('.container-comment'); var comment_timestamp; var highlight_period = 60*minutes; for(var i=0, cnt=comments.length; i server_timestamp) { // comment is new comments[i].addClassName('new'); } else { // comment is old comments[i].removeClassName('new'); } } } function edit_links_hide_handler() { var edit_links = $$('a.edit_link'); var current_server_datetime = parseInt(((new Date()).getTime())/1000 + server_timestamp_delta, 10); if(edit_links.length) { var num_active = 0; for(var i=0, cnt=edit_links.length, container, comment_date; iby ' + username; if(!avatar_mtime) { var d = new Date(); var month = d.getUTCMonth() + 1; var day = d.getUTCDate(); var year = d.getUTCFullYear(); day = day < 10 ? '0'+day :''+day; month = month < 10 ? '0'+month:''+month; avatar_mtime = year+month+day; } var avatar_elm = new Element('img', { src: _faurl.a+'/'+avatar_mtime+'/'+lower+'.gif', className: 'avatar' }); description_elm.insert({top:avatar_elm}); } popup_elm.appendChild(description_elm); document.body.appendChild(popup_elm); // // positioning // var thumb = tile.down('b a'); var thumb_position = thumb.cumulativeOffset(); var thumb_width = thumb.getWidth(); var popup_width = popup_elm.getWidth(); var document_width = document.viewport.getWidth(); var center_point = parseInt(thumb_position.left + thumb_width/2, 10); console.log('thumb_position: %o', thumb_position); console.log('thumb_width: %d', thumb_width); console.log('popup_width: %d', popup_width); console.log('document_width: %d', document_width); console.log('center_point: %d; half the document width: %d', center_point, document_width/2); var position_left, position_top, width, diff; width = popup_width; if(center_point > document_width/2) { console.log('thumb on the right side of the screen'); console.log('more space on the left side'); position_left = thumb_position.left - 10 - popup_width; position_top = thumb_position.top; // popup width correction if(position_left < 0) { console.log('popup will go offscreen on the left, correcting width') diff = -position_left + 5; console.log('diff: %d', diff); width -= diff; position_left = 5; console.log('width: %d', width); } console.log('position_left: %d', position_left); console.log('position_top: %d', position_top); } else { console.log('thumb on the left side of the screen'); console.log('more space on the right side'); position_left = thumb_position.left + thumb_width + 8; position_top = thumb_position.top; // popup width correction if(position_left+popup_width > document_width) { console.log('popup will go offscreen on the right, correcting width') diff = position_left+popup_width + 5 - document_width; console.log('diff: %d', diff); width -= diff; console.log('width: %d', width); } console.log('position_left: %d', position_left); console.log('position_top: %d', position_top); } popup_elm.setStyle({ left: position_left + 'px', top: position_top + 'px', width: width + 'px' }); popup_elm.removeClassName('invisible'); document.observe('click', description_popup_hide2); popup_elm.observe('click', function(evt) { console.log('click insude popup'); description_popup_hide2(); }); } else { console.log('description data not found'); } } else { console.log('image id was not found'); } console.groupEnd(); } function description_popup_hide2(evt){ console.group('description_popup_hide2()'); if(!evt || (evt && !evt.findElement('#description_popup'))) { console.log('removing description popup'); var popup_elm = $('description_popup'); popup_elm && popup_elm.remove(); window.description_icon_current_tile_id = false; console.log('unregistering the popup hide on click anywhere on page callback'); document.stopObserving('click', description_popup_hide2); console.groupEnd(); } } // // // // // // // gallery layout // // // // // // function init_gallery(container) { // container = $(container); // reflow the gallery right now _reflow_gallery(container); // reflow the gallery on browser window size change Event.observe(window, 'resize', _reflow_gallery.bind(this, container)); // register event observers container.select('figure').each(function(figure){ // figure.observe('mouseenter', gallery_mouseenter_handler); figure.observe('mouseleave', gallery_mouseleave_handler); // var desc_icon = figure.down('b i'); if(desc_icon) { desc_icon.observe('click', description_icon_click2); } }); // deal with the toggle titles button $$('.toggle_titles').each(function(elm) { // if(elm.readAttribute('data-initialized')) { return; } elm.writeAttribute('data-initialized', 1); elm.observe('click', function(){ gallery_toggle_titles(); $$('section.gallery').map(_reflow_gallery); }); }); } // function _reflow_gallery(container) { // container = $(container); // var images = container.select('img'); var tmp = container.className.match(/rows-(\d+)/); var max_rows = tmp ? parseInt(tmp[1], 10) : false; tmp = container.className.match(/\ss-(\d+)/); var thumb_height = tmp ? parseInt(tmp[1], 10) : 200; // proceed only if the gallery contains thumbnail tiles if(!images.length) { return; } // // reset gallery to original state // images.each(function(elm) { // no need to reset inline stlye on the tag because those are just overwritten var figure = $(elm.parentNode.parentNode.parentNode.parentNode); figure.writeAttribute('style', ''); //figure.className = figure.className.replace(/\s*row-\d+\s*/, ''); }); // // get various metrics of the tile and its contents // var first_tile = $(images[0].parentNode.parentNode.parentNode.parentNode); var link_border = 1; var cell_padding_right = 4; var tile_height = parseInt(first_tile.getStyle('height') , 10) - 2*link_border; var tile_margin_left = 4; //parseInt(first_tile.getStyle('margin-left') , 10); var tile_margin_right = 4; //parseInt(first_tile.getStyle('margin-right'), 10); var cell_spacing = 2*link_border + cell_padding_right; var tile_spacing = tile_margin_left + cell_spacing + tile_margin_right; var container_width = container.getWidth() - 20; // margin of error for odd differences between browsers // // allow the number of rows to grow as container width diminishes // if(max_rows && !container.hasClassName('noautoscalerows')) { var w = window.innerWidth; if (w < 1550) max_rows += 1; if (w < 1200) max_rows += 1; if (w < 1000) max_rows += 1; if (w < 850) max_rows += 1; if (w < 700) max_rows += 1; if (w < 550) max_rows += 1; if (w < 450) max_rows += 1; if (w < 430) max_rows += 1; if (w < 415) max_rows += 1; if (w < 395) max_rows += 1; if (w < 365) max_rows += 1; } // // process images // var tile, image; var image_width, image_height, is_small_thumbnail; var tile_width, tile_min_width; var row_width, row_height; var row, num_rows=0; // loop over images, build rows while(images.length > 0) { // row = []; row_width = 0; row_height = 0; // // build row // while(row_width < container_width) { // image = images.shift(); if(!image) { // no more images left to process break; } // get tile metrics tile = $(image.parentNode.parentNode.parentNode.parentNode); if(container.hasClassName('nodesc')) { tile_min_width = 0; } else if(container.hasClassName('s-150')) { tile_min_width = 96; } else if(tile.hasClassName('t-audio') || tile.hasClassName('t-text')) { tile_min_width = 206; } else { tile_min_width = 126; } image_width = Math.ceil(parseFloat(image.readAttribute('data-width'))) || 120; image_height = Math.ceil(parseFloat(image.readAttribute('data-height'))) || 120; // if(image_width + cell_spacing < tile_min_width) { // image contained is smaller than min tile width // min-width of the tile defines how wide the tile is is_small_thumbnail = true; // min-width includes the width of the border around the image tile_width = tile_min_width + tile_margin_left + tile_margin_right; } else { //console.log('not small') // image contained is larger than min tile width // image width defines the width of the tile is_small_thumbnail = false; tile_width = image_width + tile_spacing; } row_width += tile_width; row.push({ tile: tile, image: image, width: image_width, height: image_height, tile_min_width: tile_min_width, is_small: is_small_thumbnail }); } // // process row // //console.time('justify row'); if(row_width >= container_width) { // row content is wider than container // true for all rows but the last num_rows++; // var combined_tile_spacing = row.length * tile_spacing; var scale_ratio = (container_width - combined_tile_spacing) / (row_width - combined_tile_spacing); // var current_height=0; var new_width, new_height, new_min_width, cell; for(var i=0, cnt=row.length; i expected_height) { new_height = expected_height; new_width = Math.round(cell.width * (new_height/cell.height)); current_height = new_height; } } // if(new_width && new_height) { cell.image.setStyle('width:'+new_width+'px;height:'+new_height+'px'); } if(new_min_width) { cell.tile.style.minWidth = new_min_width + 'px'; } //cell.tile.className += ' row-'+num_rows; if(current_height > row_height) { row_height = current_height; } } } else { // last row, with content not wider than container // reset image height in the last row // for rows that are being justified this is already being done for(var i=0, cnt=row.length; i= max_rows) { break; } } // if(max_rows) { // hide the remaining images, if any are left images.each(function(elm) { elm.up('figure').hide(); }); } } // function gallery_toggle_titles(){ var galleries = $$('section.gallery'); var cookie_name = 'nodesc'; var cookie_path = '/'; var cookie_domain = '.furaffinity.net'; var titles_on; if(galleries){ if(galleries[0].hasClassName(cookie_name)) { titles_on = true; deleteCookie(cookie_name, cookie_path, cookie_domain); } else { titles_on = false; setCookie(cookie_name, 1, expiryyear, cookie_path, cookie_domain); } galleries.invoke('toggleClassName', cookie_name); // update all toggle buttons $$('.toggle_titles').each(function(elm){ elm.innerHTML = (titles_on ? 'Disable' : 'Enable') + ' Titles'; }); } return titles_on; } // function gallery_mouseenter_handler(evt) { // we can also just pass the element itself var tile, ignore_state; if(typeof(evt.element) === 'function') { tile = evt.findElement('figure'); ignore_state = false; } else { tile = evt; ignore_state = true; } var container = tile.up('section.gallery'); // work only if the gallery is in no-desc mode if(container.hasClassName('nodesc')) { var caption = tile.down('> figcaption'); if(caption) { // var checkbox = caption.down('input'); if(checkbox) { caption.down('p').insert({top:checkbox}); } // tile.down('b a').insert({ bottom: caption }); } } } // // function gallery_mouseleave_handler(evt) { // we can also just pass the element itself var tile, ignore_state; if(typeof(evt.element) === 'function') { tile = evt.findElement('figure'); ignore_state = false; } else { tile = evt; ignore_state = true; } var container = tile.up('section.gallery'); // work only if the gallery is in no-desc mode and the container isn't "checked" // also work if called directly, and not on an actual event if((container.hasClassName('nodesc') && !tile.hasClassName('checked')) || ignore_state) { var caption = tile.down('a > figcaption'); if(caption) { // var checkbox = caption.down('input'); if(checkbox) { caption.down('div').insert({top:checkbox}); } // tile.insert({ bottom: caption }); } } } // // // // // // function comment_replyto_onclick_handler(evt){ // var selectors = { // inside the clicked comment comment_container : '.comment_container', comment_anchor : '.comment_anchor', comment_username : '.js-displayName-block span', comment_useravatar: '.comment_useravatar', comment_text : '.comment_text', // elsewhere on the page loggedin_user_avatar: '.loggedin_user_avatar', reply_form: '#add_comment_form', reply_form_submit_button: 'button[type="submit"]', reply_form_noreply_warning: '.unable-reply-warning', // generated reply_box: '.generated_replyto_box' }; var textarea_id = 'reply-box-'+((new Date()).getTime()); // // // //stop click event on tag from propagating evt.stop(); // remove other reply boxes from the page $$(selectors.reply_box).invoke('remove'); // // obtain references to all page elements we will be working with // var elements = {}; elements.comment_container = evt.findElement(selectors.comment_container); elements.comment_anchor = elements.comment_container.down(selectors.comment_anchor); // elements.comment_clone = elements.comment_container.clone(true); elements.comment_clone_anchor = elements.comment_clone.down(selectors.comment_anchor); elements.comment_clone_avatar = elements.comment_clone.select(selectors.comment_useravatar); elements.comment_clone_username = elements.comment_clone.down(selectors.comment_username); elements.comment_clone_text_container = elements.comment_clone.down(selectors.comment_text); // elements.replyform_clone = $$(selectors.reply_form).first().clone(true); elements.replyform_clone_action = elements.replyform_clone.down('input[name=action]'); elements.replyform_clone_replyto = elements.replyform_clone.down('input[name=replyto]'); elements.reply_form_noreply_warning = elements.replyform_clone.down(selectors.reply_form_noreply_warning); elements.replyform_clone_submit_button = elements.replyform_clone.down(selectors.reply_form_submit_button); // elements.loggedin_user_avatar = $$(selectors.loggedin_user_avatar).first(); console.info('HTML element references'); console.dir(elements); // // obtain all data bits we will be working with // var data = {}; data.comment_id = elements.comment_anchor.id.replace('cid:', ''); data.comment_width = parseInt(elements.comment_clone.getStyle('width'), 10); data.comment_level = (100-data.comment_width)/3; data.comment_clone_width = 100 - (data.comment_level+1)*3; data.loggedin_user_avatar_url = elements.loggedin_user_avatar.src; data.loggedin_user_username = elements.loggedin_user_avatar.readAttribute('alt'); data.loggedin_user_pagelink = elements.loggedin_user_avatar.up('a').href; console.info('Data bits'); console.dir(data); // // clean up and prepare the reply form clone we will be using for a reply-to // elements.replyform_clone.removeAttribute('id'); // elements.replyform_clone_action.removeAttribute('id'); elements.replyform_clone_action.value = 'replyto'; // elements.replyform_clone_replyto.removeAttribute('id'); elements.replyform_clone_replyto.value = data.comment_id; elements.reply_form_noreply_warning && elements.reply_form_noreply_warning.remove(); // add the cancel button left of the post button var cancel_button = elements.replyform_clone_submit_button.clone(true); cancel_button.type = 'button'; cancel_button.innerHTML = 'Cancel'; cancel_button.removeAttribute('value'); cancel_button.removeAttribute('name'); cancel_button.removeAttribute('onclick'); cancel_button.removeClassName('go').addClassName('stop'); cancel_button.observe('click', function(evt){ evt.findElement(selectors.reply_box).remove(); }); elements.replyform_clone_submit_button.insert({after:cancel_button}); // // cleanup and prepare the comment container we are making a reply to // elements.comment_clone.removeAttribute('data-timestamp'); elements.comment_clone.removeClassName('admin-comment'); elements.comment_clone.addClassName(selectors.reply_box.replace('.', '')); // elements.comment_clone_anchor.remove(); // replace user's avatar and link to userpage with our own elements.comment_clone_avatar.each(function(elm){ elm.writeAttribute('alt', data.loggedin_user_username); elm.src = data.loggedin_user_avatar_url; elm.up('a').href = data.loggedin_user_pagelink; }); // elements.comment_clone_username.innerHTML = data.loggedin_user_username; elements.comment_clone_username.up('a').href = data.loggedin_user_pagelink; // var rem_selectors = ['.js-userName-block', '.comment_op_marker', 'usericon-block-before', 'usericon-block-after', 'comment-title', 'comment-anchor', 'comment-date', 'comment-footer']; rem_selectors.each(function(sel){ elements.comment_clone.select(sel).invoke('remove'); }); // // replace the comment's text with a clone of the reply form elements.comment_clone_text_container.innerHTML = ''; elements.comment_clone_text_container.appendChild(elements.replyform_clone); // calculate the width of the reply-to box based on the width of the original comment, so it's positioned under it and offset correctly elements.comment_clone.setStyle({ width: data.comment_clone_width + '%' }); // append the reply-to box under the original comment elements.comment_container.insert({after: elements.comment_clone}); // var textarea = elements.replyform_clone.down('textarea'); textarea.id = textarea_id; textarea.focus(); init_bbcode_hotkeys(textarea_id); }; // // simple lightbox // function lightbox_init() { // When the image is clicked, show a light box of the image. const img = document.querySelector('img#submissionImg'); if (!img) { return; } // Create the "lightbox" const container = new Element('div', { className: 'lightbox lightbox-submission hidden' }); // Append desired content to the content container const img_content = img.cloneNode(true); img_content.src = img.readAttribute('data-fullview-src'); img_content.classList.remove('blocked-content'); // Remove the spoiler // Add the copied content to the lightbox before appending it to the body of our page container.appendChild(img_content); document.body.appendChild(container); document.body.addEventListener('click', (event) => { // Clicked on the image itself. if (event.target == img && !event.target.classList.contains('blocked-content')) { // Show the lightbox // Only show it when the blocked content spoiler is removed. event.preventDefault(); container.classList.remove('hidden'); } else if (!container.classList.contains('hidden')) { // Hide the lightbox event.preventDefault(); container.classList.add('hidden'); } }, { capture: true, // We want this to be called earlier than everything else. passive: false }); } // // register a click observer on any element that will collapse a parent element with // "container" classname when clicked // function init_close_button(arg) { var elms; if(typeof arg == 'string') { elms = $$(arg); } else { if(arg.length) { elms = arg; } else { elms = [arg]; } } elms.invoke('observe', 'click', function(evt){ evt.element().up('.container').addClassName('hidden'); }); } // // value widget // number input box with a "+" and "-" buttons // function init_value_widget(elm) { // var callback = elm.readAttribute('data-onchange-callback'); elm.down('._field').observe('keyup', function(evt){ var elm = evt.element(); elm.value = elm.value.replace(/[^\d]/, ''); }); elm.select('._control').each(function(elm) { elm.observe('click', function(evt){ var elm = evt.element(); var container = elm.up('._value-widget'); var input = container.down('._field'); var min_value = Math.abs(parseInt(input.readAttribute('data-min-value') || 0, 10)); var value = parseInt($F(input), 10); if (elm.hasClassName('_up')) { value = value+1 < min_value ? min_value : value+1; } else { value = value > min_value ? value-1 : min_value; } input.value = value; // run callback if specified if(callback && typeof window[callback] == 'function') { window[callback](container, value); } }); }); // run callback on init if(callback && typeof window[callback] == 'function') { window[callback](elm, $F(elm.down('._field'))); } } // // save client viewport size to a cookie. // returns a false-y value on failure. // function save_viewport_size() { try { setCookie('sz', document.viewport.getWidth() + 'x' + document.viewport.getHeight(), expiryyear, '/'); return getCookie('sz'); } catch(e){} return false; } // prevent multiple clicks on buttons triggering parallel requests function debounce_button(selector, delay) { $$(selector).each(function(elm){ elm.observe('click', function(){ elm.disabled = true; setTimeout(function() { elm.disabled = false; }, delay || 1000); }) }); } // // function EnhancedUploader(containerId, dropCallback, debug) { // if (!this.isSupported()) { return; } this.containerId = containerId; this.container = $(containerId); this.dropCallback = typeof dropCallback == 'function' ? dropCallback : function(){}; this.debug = debug; this.defaultPreviewImage = null; this.init(); } EnhancedUploader.prototype = { // classNames: { // elements dropContainer: 'dragDrop__dropContainer', manualSelect: 'dragDrop__manualSelect', fileInfo: 'dragDrop__fileInfo', errorMsg: 'dragDrop__errorMsg', previewContainer: 'dragDrop__preview', // modifiers fileOk: 'dragDrop--selectedFileOk', fileError: 'dragDrop--selectedFileError', // mode class platformDesktop: 'dragDrop--platformDesktop', platformMobile: 'dragDrop--platformMobile', }, previewMimeTypes: [ 'image/apng', 'image/gif', 'image/jpeg', 'image/pjpeg', 'image/png', ], // isMobile: /Mobi|Android/i.test(navigator.userAgent) || 'ontouchstart' in document.documentElement, // init: function() { if (this.debug) this.checkAllElements(); this.registerGlobalObservers(); this.defaultPreviewImage = this.isMobile ? '' : this.ref('previewContainer').down('img'); this.input = $(this.ref('manualSelect').readAttribute('for')); this.input.observe('change', (function() { this.onFileChange(); }).bind(this)); if (this.isMobile) { this.initMobile(); } else { this.initDesktop(); } // account for preselected values this.onFileChange(); }, isSupported: function() { var isSupported = 'draggable' in document.createElement('span'); try { new DataTransfer(); } catch (e) { isSupported = false; }; return isSupported; }, // ref: function(className) { return this.container.down('.'+this.classNames[className]); }, checkAllElements: function() { console.group('checking drag&drop container: ', this.containerId); try { console.info('device type: %s', this.isMobileDevice() ? 'mobile' : 'desktop'); console.log('container: %o', this.container); if (!this.container) throw new Error(''); console.log('drop container: %o', this.ref('dropContainer')); console.log('manual select label: %o', this.ref('manualSelect')); console.log('manual select label target ID: %s', this.ref('manualSelect').readAttribute('for')); console.log('file input field: %o', $(this.ref('manualSelect').readAttribute('for'))); console.log('file info container: %o', this.ref('fileInfo')); console.log('error container: %o', this.ref('errorMsg')); console.log('preview container: %o', this.ref('previewContainer')); } catch (e) { // } console.groupEnd(); }, registerGlobalObservers: function() { var className = 'EnhancedUploader--loaded'; if (!document.body.hasClassName(className)) { ['dragenter', 'dragover', 'dragleave', 'drop'].each(function(name) { document.body.observe(name, function(evt) { evt.stop(); }); }); document.body.addClassName(className); } }, // // initDesktop: function() { // this.container.removeClassName(this.classNames['platformMobile']).addClassName(this.classNames['platformDesktop']); // this.ref('dropContainer').observe('drop', this.processDropEvent.bindAsEventListener(this)); this.input.addClassName('hidden'); this.container.removeClassName('hidden'); }, initMobile: function() { // this.container.removeClassName(this.classNames['platformDesktop']).addClassName(this.classNames['platformMobile']); this.input.observe('change', (function() { if(this.input.files[0]) { this.container.removeClassName('hidden'); } else { this.container.addClassName('hidden'); } }).bind(this)); if(this.input.files[0]) { this.container.removeClassName('hidden'); } else { this.container.addClassName('hidden'); } }, onFileChange: function() { this.updateFileInfo(); this.updateImagePreview(); this.dropCallback(this.input.files[0], this); }, // // // processDropEvent: function(evt) { // use only the first out of possibly several dropped files var file = evt.dataTransfer.files[0]; var tmp = new DataTransfer(); tmp.items.add(file); this.input.files = tmp.files; this.onFileChange(); }, updateFileInfo: function() { this.container.removeClassName(this.classNames['fileOk']).removeClassName(this.classNames['fileError']); var info_str = err_str = ''; if (this.input.files.length) { var file = this.input.files[0]; info_str = file.name + ', ' + this.formatFileSize(file.size); if (!this.checkFileTypeAllowed()) { err_str = 'File type is not allowed.'; } if (file.size == 0) { err_str = 'Selected file is empty.'; } var max_file_size = this.getMaxFileSize(); if (max_file_size && file.size > max_file_size) { err_str = 'Selected file is over the size limit.'; } this.container.addClassName(err_str ? this.classNames['fileError'] : this.classNames['fileOk']); } this.ref('fileInfo').update(info_str); this.ref('errorMsg').update(err_str); }, updateImagePreview: function() { var file = this.input.files[0]; if (file && file.size && this.previewMimeTypes.include(file.type)) { var img = document.createElement('img'); img.onload = (function(evt, container) { container.update(evt.element()); }).bindAsEventListener(this, this.ref('previewContainer')); img.src = URL.createObjectURL(file); } else { this.ref('previewContainer').update(this.defaultPreviewImage); } }, formatFileSize: function(number) { if(number < 1024) { return number + 'bytes'; } else if(number >= 1024 && number < 1048576) { return (number/1024).toFixed(1) + 'KB'; } else if(number >= 1048576) { return (number/1048576).toFixed(1) + 'MB'; } }, checkFileTypeAllowed: function() { var accept = this.input.readAttribute('accept'), file = this.input.files[0]; if (!file) return false; if (!accept) return true; for(var i=0, accept=accept.split(','); i