NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Kommentar make-up // @namespace germany.ru // @version 2.0.10 // @match https://*.germany.ru/newreply* // @match https://*.germany.ru/editpost* // @match https://*.germany.ru/newpost* // @match https://*.germany.ru/dialog/* // @match https://*.germany.ru/report.pl* // @match https://*.germany.ru/cgi-bin/my/dialog.cgi* // @match https://*.germany.ru/cgi-bin/my/sendprivate.cgi* // @grant GM.xmlHttpRequest // @grant unsafeWindow // @license MIT // ==/UserScript== /**------------------------------------------------- Globals ------------------------------------------------*/ Function.prototype._memorise = function ( args, value ) { const fn = this; fn._values = fn._values || {}; if ( fn._values[ JSON.stringify( args ) ] === undefined ) { fn._values[ JSON.stringify( args ) ] = value; } }; Function.prototype._memorised = function ( args ) { const fn = this; if ( fn._values && fn._values[ JSON.stringify( args ) ] !== undefined ) { return fn._values[ JSON.stringify( args ) ]; } }; Function.prototype._resolve = function ( callback ) { const fn = this, args = callback && typeof callback === 'function' ? [ ...arguments ].slice( 1 ) : [ ...arguments ], memorised = fn._memorised.bind( fn, args )(); if ( memorised === undefined ) { if ( !fn._pending ) { fn._pending = true; let promise_obj = new Promise( ( resolve ) => { resolve( fn.apply( fn, args ) ); } ); promise_obj.then( ( value ) => { fn._pending = false; fn._memorise.bind( fn, args, value )(); if ( callback && typeof callback === 'function' ) { callback( value ); } }, () => { fn._pending = false; } ); } } else { if ( callback && typeof callback === 'function' ) { callback( memorised ); } return memorised; } }; ( function () { /**------------------------------------------- Util functions -------------------------------------------*/ let getElements = ( name ) => { getElements.cache = getElements.cache || {}; return getElements.cache[ name ] = getElements.cache[ name ] || ( document.getElementsByClassName( name ).length > 0 ? document.getElementsByClassName( name ) : document.getElementsByTagName( name ).length > 0 ? document.getElementsByTagName( name ) : document.getElementsByName( name ).length > 0 ? document.getElementsByName( name ) : undefined ); }; let getElement = ( id ) => { getElement.cache = getElement.cache || {}; return getElement.cache[ id ] = getElement.cache[ id ] || document.getElementById( id ); }; let styleElement = ( element, style_obj ) => { if ( element && element instanceof Element ) { if ( style_obj && typeof style_obj === 'object' ) { element._initial_styles = element._initial_styles || {}; for ( const key in style_obj ) { if ( style_obj.hasOwnProperty( key ) && element.style.hasOwnProperty( key ) ) { if ( !element._initial_styles[ key ] && element._initial_styles[ key ] !== "" ) { element._initial_styles[ key ] = element.style[ key ]; } element.style[ key ] = style_obj[ key ]; } } } else if ( element._initial_styles ) { for ( const key in element._initial_styles ) { element.style[ key ] = element._initial_styles[ key ]; } } } }; /**--------------------------- CSS definitions, new DOM elements & scope vars ---------------------------*/ const css = ' .no-user-selection { opacity: 0.6 }' + ' .no-user-selection:hover { opacity: 0.9 }' + ' .user-selection { opacity: 1 }' + ' .user-selection-disabled { opacity: 0.6 }' + ' textarea { height: 30vh; min-width: 90vw }' + ' textarea::selection { background: #3838BB; color: #FFFFFF; }' + ' textarea::-moz-selection { background: #3838BB; color: #FFFFFF; }' + ' .text-area-full { position:fixed; top:47px; left:1px; height:95vh; width:99.8vw; font-size:16px; padding-right:17px; overflow-x:hidden; z-index:99999 }' + ' .blockheader { display:none }' + ' span > .td-50{ display:none }' + ' .td-20 { display:none }' + ' .td-80 { width:100% }' + ' .float-left-mobile{ float:none; }' + ' #img { width: 0; height: 0; opacity: 0; overflow: hidden; position: absolute; z-index: -1 }' + ' #img + label { background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAABJklE' + 'QVR4Ae3VPYrbUBRA4a+RJ1VSJswvGG8mhYsswRhtxT/YmNEuhtEiAmpcJjBJOQsYyyBMsF0qXcjDjNF7pAnJOd0tTqN3r/yLfPCsFfrsvUj' + 'e+ao91RdvRfBGpX3Fzy6c4UKh0Ua6U+gJKLSJFgKa5FAjoE23W6hRWpp4UKeHNnIZgMzIS0rom1shXHqKDW3cgoHC2tq9PriyiQvl4JPjr8' + 'nBEIxjQo0MA8dguneHTN09VL7ySBfgsXtoCdYnoQpMu4cmZ0Oz7qEHcH8SmoOye6iWoe8QTH+4QWYb8/lHYGj/W+YjyOPe0YtLcGehUpm7A' + 'dfq2BV5coWQa9/TlnYcLG2uTj8jtUdTM6VtxBlJNGCXnGn+1PFfCegl/Y4aKz1/Lf/5CShXgVKz4A8DAAAAAElFTkSuQmCC")' + 'no-repeat center; vertical-align: text-bottom; width: 24px; height: 24px; opacity: 0.6; cursor: pointer;' + '-webkit-user-select: none; -moz-user-select: none; background-size: 24px 24px; display: inline-block}' + ' #img + label:hover{ opacity: 0.9;}' + ' #modal-symbols { box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19); display: none; background-color: #fefefe; margin: 15% 18%;' + 'padding: 20px; border: 1px solid #888; height: auto; width:65%; max-width: 65%; -webkit-user-select: none; -moz-user-select: none }' + ' #modal-symbols > div, #modal-preview > div{ width=100%; margin-top:-15px; margin-right: -5px;}' + ' #modal-symbols > div > span:first-child, #modal-preview > div > span:first-child { position:absolute; width:auto; background-color:#fefefe}' + ' #modal-symbols-close { text-align:right; background-color:#fefefe; cursor: pointer } ' + ' #modal-preview-close { position:absolute; right:7%; background-color:#fefefe; padding:0px 5px; border-radius:11px; cursor: pointer } ' + ' #modal-preview { display: none; background-color: #fefefe; margin: 5% 5%; padding: 20px; border: 1px solid #888; height: 85%; width:90%; max-width: 90%; overflow-y: auto;' + '-webkit-user-select: none; -moz-user-select: none}' + ' #modal-dialogue { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.4) }' + ' #font { float:right; padding-top:7px; width:26px; display:none; cursor:pointer } ' + ' #font, #resize{ -webkit-user-select: none; -moz-user-select: none; }' + ' #resize { float:right; margin-top:-5px; padding-left: 16px; display: inline; width: auto; cursor:pointer}' + ' .resize-el-full { position:fixed; top:15px; right:-20px; z-index:99999; margin-right: 40px}' + ' #preview { float:right; cursor:pointer }' + ' .preview-full { position:fixed; top:15px; right:35px; z-index:99999;}' + ' #upload { font-size: 1.6em; margin: 0px 6px 0px 0px }' + ' .sml-1 { float: left; font-size:1.2em; padding: 10px; cursor: pointer }' + ' .sml-2 { float: left; padding: 10px; cursor:pointer}' + ' #smiley { opacity: 0.7; border: none; background-color: inherit; font-size:1.7em }' + ' #smiley:hover { opacity: 1.0}' + ' #trfrm { display:inline-block}' + ' #markup { margin-top:7px; padding-left:1px; padding-bottom: 2px; width:100% }' + ' .markup-full { position:fixed; top:0; left:0; margin-top:-5px !important; height:100vh !important; width:100vw !important; padding-top:12px; padding-left:2px !important;' + 'background-color:#FFFFFF; font-size:17px; z-index:9999 }' + ' #answer { font-size:18px; background-color:#FFFFFF; cursor:pointer; display:none }' + ' .answer-full { display:inline !important; position:fixed; top:95vh !important; right:5vw}' + ' .answer-opened { display:inline !important; position:fixed; top:66.5vh !important; right:5vw}' + ' .comment-to-answer-full { position: fixed; top:94vh !important; left:0; height:100vh !important; width:99.8vw; overflow:hidden !important; border:1px solid #CCC5BE;' + 'margin: 2px 8px 0px 2px; z-index:9999; padding-top:7px}' + ' .comment-to-answer-opened { position: fixed; top:66vh !important; left:0; height:34vh !important; width:99.8vw; overflow-y:auto !important; overflow-x:hidden !important;' + 'border:1px solid #CCC5BE; margin: 2px 8px 0px 2px; z-index:9999}' + ' input[name="Subject"] { width:auto; float:left; padding:0 }' + ' #subj { float:left; width:101px }' + ' #avatar-spacer { display:inline-block; width:10px }' + '.redactor-toolbar-tooltip { display:none !important }' + '.font-btn { line-height:inherit; color:#999999; width:30px }' + '.quote-btn { line-height:inherit; color:#999999; width:42px }' + '.color-btn { line-height:inherit; width:20px; height: 20px; border: none }' + '#error { margin-top:-2px; padding-left:2%; color:#bb3838 }' + '#redo, #undo { line-height:inherit; color:#999999; font-weight:bold; width:30px }' + '#clear { line-height:inherit; width:auto; color:#999999 }' + '#translate + label + span { float: right; margin-right:5px; display: inline }'; const misc_symbols = [ //funny "🙊", "🙉", "🙈", "🎅", "👹", "😈", "😇", //emoticons "😴", "😷", "😤", "😠", "😬", "😵", "😮", "😭", "😥", "😩", "😫", "😖", "😣", "😒", "😕", "😟", "😞", "😔", "😳", "😑", "😐", "😎", "😉", "😏", "😌", "😊", "😙", "😚", "😘", "😍", "😝", "😜", "😋", "😅", "😂", "😆", "😄", "😃", "😁", "😀", //flowers "🌷", "🌹", "🌻", //hearts "💔", "💕", "💖", //meal & drinks "🍎", "🍭", "🎂", "🍷", "🍺", //gestures "👌", "👏", "✋", "👊", "✊", "✌", //misc "©", "≠", "►", "—", "№", "#" ], smileys_links = [ "https://tt.germany.ru/wwwthreads/images/icons/smile.gif", "https://tt.germany.ru/wwwthreads/images/icons/frown.gif", "https://tt.germany.ru/wwwthreads/images/icons/blush.gif", "https://tt.germany.ru/wwwthreads/images/icons/cool.gif", "https://tt.germany.ru/wwwthreads/images/icons/crazy.gif", "https://tt.germany.ru/wwwthreads/images/icons/laugh.gif", "https://tt.germany.ru/wwwthreads/images/icons/mad.gif", "https://tt.germany.ru/wwwthreads/images/icons/shocked.gif", "https://tt.germany.ru/wwwthreads/images/icons/tongue.gif", "https://tt.germany.ru/wwwthreads/images/icons/wink.gif", "https://tt.germany.ru/wwwthreads/images/icons/up.gif", "https://tt.germany.ru/wwwthreads/images/icons/down.gif", "https://tt.germany.ru/wwwthreads/images/icons/kiss.gif", "https://tt.germany.ru/wwwthreads/images/icons/flower.gif", "https://tt.germany.ru/wwwthreads/images/icons/glass.gif", "https://tt.germany.ru/wwwthreads/images/icons/heart.gif" ], colorize_btns = [ "pre", "l-quote", "strike", "underline", "italic", "bold", "quote" ], color_btns = [ "red", "green", "blue", "black" ], lat = ( '/E_/e_/O_/o_Шh_Йo_Зh_Цh_Сh_Йe_Йu_Йa_Ыo_Ыu_Ыa_ШH_ЙO_ЗH_ЦH_СH_ЙE_ЙU_ЙA_ЫO_ЫU_ЫA_A_B_V_G_D_E_Z_I_J_K_L_M_N_O_P_R_S_T_U_F_X_C_ъ#_Y_ь\'_H_W_Q_шh_йo_зh_цh_сh_йe_йu_йa_ыo_ыa_a_b_v_g_d_e_z_i_j_k_l_m_n_o_p_r_s_t_u_f_x_c_#_y_\'_h_w_q_' + String.fromCharCode( 220 ) + '_' + String.fromCharCode( 214 ) + '_' + String.fromCharCode( 196 ) + '_' + String.fromCharCode( 252 ) + '_' + String.fromCharCode( 246 ) + '_' + String.fromCharCode( 228 ) ).split( '_' ), rus = ( 'E_e_O_o_Щ_Ё_Ж_Ч_Ш_Э_Ю_Я_Ё_Ю_Я_Щ_Ё_Ж_Ч_Ш_Э_Ю_Я_Ё_Ю_Я_А_Б_В_Г_Д_Е_З_И_Й_К_Л_М_Н_О_П_Р_С_Т_У_Ф_Х_Ц_Ъ_Ы_Ь_Х_Щ_Я_щ_ё_ж_ч_ш_э_ю_я_ё_я_а_б_в_г_д_е_з_и_й_к_л_м_н_о_п_р_с_т_у_ф_х_ц_ъ_ы_ь_х_щ_я_Ю_Ё_Э_ю_ё_э' ).split( '_' ), buttons = '<div id="markup">' + '<span style="padding-right:4px"><input type="button" class="font-btn" id="pre" value="{ }"></span>' + '<span style="padding-right:4px"><input type="button" class="font-btn" id="strike" value="а" style="text-decoration:line-through;"></span>' + '<span style="padding-right:4px"><input type="button" class="font-btn" id="underline" value="a" style="text-decoration:underline;"></span>' + '<span style="padding-right:4px"><input type="button" class="font-btn" id="italic" value="к" style="font-style:italic;"></span>' + '<span style="padding-right:4px"><input type="button" class="font-btn" id="bold" value="ж" style="font-weight:bold;"></span>' + '<span style="padding-right:4px"><input type="button" class="quote-btn" id="l-quote" value="«a»"></span>' + '<span style="padding-right:16px"><input type="button" class="quote-btn" id="quote" value="„a“"></span>' + '<span style="padding-right:4px"><input type="button" class="color-btn no-user-selection" id="red" style="background-color:#bb3838;"></span>' + '<span style="padding-right:4px"><input type="button" class="color-btn no-user-selection" id="green" style="background-color:#38BB38;"></span>' + '<span style="padding-right:4px"><input type="button" class="color-btn no-user-selection" id="blue" style="background-color:#3838bb;"></span>' + '<span><input type="button" class="color-btn no-user-selection" id="black" style="background-color:#161619;"></span>' + '<span><input type="button" id="smiley" value="☺"></span>' + '<span id="upload"><input type="file" name="img" id="img"><label for="img"></label></span>' + '<span id="error"></span>' + '<span style="float:right; margin-top: 5px"><input type="button" id="redo" value="↪"></span>' + '<span style="float:right; margin-top: 5px; padding-left:15px; padding-right:4px;"><input type="button" id="undo" value="↩"></span>' + '<span style="float:right; margin-top: 5px; padding-left:15px;"><input type="button" id="clear" value="Убрать тэги" disabled></span>' + '<span id="font">↨<span> a</span></span>' + '</div>', checkboxes = '<input type="checkbox" id="translate"><label for="translate"> Включить транслит</label>' + '<span><a href="http://groups.germany.ru/showmessage.pl?Number=29559602&Board=1015169" target="_blank">' + '<img src="https://tt.germany.ru/wwwthreads/images/icons/exclamation.gif" alt="Справка"/></a></span><br>' + '<input type="checkbox" id="short-links"><label for="short-links"> Сокращать ссылки</label><br>'; let text_area, comment_to_answer, container_well, container_wrap, selected_decorators, text_history = [], undo_clicks = 0, intervals = 100; /**-------------------------------------------- Append styles -------------------------------------------*/ const style = document.createElement( 'style' ); style.type = 'text/css'; style.appendChild( document.createTextNode( css ) ); document.head.appendChild( style ); /**------------------------------------- Editor's set up & clean up -------------------------------------*/ window.onunload = ( event ) => { delFlag( event ); }; window.onclick = ( event ) => { const modal = getElement( 'modal-dialogue' ); if ( event.target === modal ) { hideModal(); } }; let setUp = () => { text_area = getElement( 'trtxt' ) || getElement( 'trtxt-message' ); comment_to_answer = getElement( 'previewedit' ); container_well = getElements( 'well-alt' ); container_wrap = getElements( 'wrap' ); if ( !text_area ) { setTimeout( () => { setUp(); }, 50 ); } else { setTimeout( function removeNativeEditor() { const redactor_box = getElements( 'redactor-box' ); if ( redactor_box && redactor_box.length > 0 ) { text_area.style.display = ""; redactor_box[ 0 ].insertAdjacentElement( 'beforebegin', text_area ); redactor_box[ 0 ].remove(); updateTextArea( [ replaceTags, delNewlines, delWhitespaces ] ); saveState(); } else if ( intervals > 0 ) { intervals--; removeNativeEditor(); } }, 500 ); /** Initial HTML manipulations: modify editor's block styling */ const resize_el = document.createElement( 'SPAN' ); resize_el.setAttribute( 'id', 'resize' ); resize_el.appendChild( document.createTextNode( "↗" ) ); const preview = document.createElement( 'SPAN' ); preview.setAttribute( 'id', 'preview' ); preview.appendChild( document.createElement( "I" ) ); preview.childNodes[ 0 ].classList.add( "iconlarge-views" ); text_area.parentElement.insertBefore( resize_el, text_area ); text_area.parentElement.insertBefore( preview, text_area ); text_area.parentElement.insertBefore( document.createElement( 'BR' ), text_area ); text_area.insertAdjacentHTML( 'beforebegin', buttons ); text_area.insertAdjacentHTML( 'afterend', checkboxes ); const modal_box = document.createElement( 'DIV' ); modal_box.setAttribute( 'id', 'modal-dialogue' ); modal_box.appendChild( document.createElement( 'DIV' ) ); modal_box.childNodes[ 0 ].setAttribute( 'id', 'modal-symbols' ); modal_box.childNodes[ 0 ].appendChild( document.createElement( 'DIV' ) ); modal_box.childNodes[ 0 ].childNodes[ 0 ].appendChild( document.createElement( 'DIV' ) ); modal_box.childNodes[ 0 ].childNodes[ 0 ].childNodes[ 0 ].setAttribute( 'id', 'modal-symbols-close' ); modal_box.childNodes[ 0 ].childNodes[ 0 ].childNodes[ 0 ].appendChild( document.createTextNode( "✕" ) ); modal_box.appendChild( document.createElement( 'DIV' ) ); modal_box.childNodes[ 1 ].setAttribute( 'id', 'modal-preview' ); modal_box.childNodes[ 1 ].appendChild( document.createElement( 'DIV' ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].appendChild( document.createElement( 'SPAN' ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].appendChild( document.createElement( 'SPAN' ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].childNodes[ 0 ].appendChild( document.createTextNode( "Предварительный просмотр сообщения:" ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].childNodes[ 1 ].setAttribute( 'id', 'modal-preview-close' ); modal_box.childNodes[ 1 ].childNodes[ 0 ].childNodes[ 1 ].appendChild( document.createTextNode( "✕" ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].appendChild( document.createElement( 'BR' ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].appendChild( document.createElement( 'BR' ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].appendChild( document.createElement( 'DIV' ) ); modal_box.childNodes[ 1 ].childNodes[ 0 ].childNodes[ 4 ].setAttribute( 'id', 'preview-body' ); text_area.parentElement.insertBefore( modal_box, getElement( 'translate' ) ); const user_pic_pattern = /^<div class="td-\d+">\s*<img/, avatar_pattern = /name="Avatar"/, new_topic_avatar_pattern = /<\/select>\s*<br>\s*<script/, no_avatar_pattern = /club\.germany\.ru/; if ( container_well ) { for ( let i = 0; i < container_well.length; i++ ) { if ( user_pic_pattern.test( container_well[ i ].innerHTML.trim() ) ) { container_well[ i ].firstElementChild.remove(); } if ( avatar_pattern.test( container_well[ i ].innerHTML.trim() ) ) { if ( container_well[ i ].firstElementChild.classList.contains( 'td-80' ) ) { container_well[ i ].firstElementChild.classList.remove( 'td-80' ); } if ( container_well[ i ].firstElementChild.tagName !== 'SCRIPT' ) { container_well[ i ].firstElementChild.style.display = 'inline'; container_well[ i ].firstElementChild.style.padding = '.75em 1em'; } if ( getElements( 'Subject' ) && getElements( 'Subject' )[ 0 ].getAttribute( 'type' ) === 'hidden' ) { container_well[ i ].firstElementChild.style.paddingLeft = '0'; } } if ( new_topic_avatar_pattern.test( container_well[ i ].innerHTML.trim() ) ) { getElement( 'subj' ).nextSibling.remove(); getElement( 'subj' ).nextElementSibling.remove(); if ( getElements( 'Icon' ) ) { getElements( 'Icon' )[ 0 ].nextElementSibling.remove(); const spacer = document.createElement( 'span' ); spacer.setAttribute( 'id', 'avatar-spacer' ); getElements( 'Icon' )[ 0 ].insertAdjacentElement( 'afterend', spacer ); container_well[ i ].firstElementChild.style.padding = '0'; } } if ( no_avatar_pattern.test( container_well[ i ].innerHTML.trim() ) ) { container_well[ i ].firstElementChild.remove(); } } let avatar = getElements( "Avatar" ); if ( avatar ) { avatar[ 0 ].parentElement.innerHTML = avatar[ 0 ].parentElement.innerHTML.replace( "onchange=\"showimage()\"", "" ); } } if ( getElements( 'Subject' ) && getElements( 'Subject' )[ 0 ].previousElementSibling ) { const clear = getElements( 'Subject' )[ 0 ].previousElementSibling.getAttribute( 'class' ); if ( clear && clear.indexOf( 'clear' ) !== -1 ) { getElements( 'Subject' )[ 0 ].previousElementSibling.remove(); } if ( getElements( 'Subject' )[ 0 ].nextElementSibling.tagName === 'BR' ) { getElements( 'Subject' )[ 0 ].nextElementSibling.remove(); } } if ( comment_to_answer ) { comment_to_answer.innerHTML = comment_to_answer.innerHTML.replace( /br>(\s|\S)*?(<br>)/, '/b><br>' ); let answer = document.createElement( 'span' ); answer.setAttribute( 'id', 'answer' ); comment_to_answer.insertBefore( answer, comment_to_answer.firstElementChild ); } const modal_close = getElement( 'modal-symbols-close' ); for ( let i = 0; i < misc_symbols.length; i++ ) { let sml_1 = document.createElement( 'span' ); sml_1.setAttribute( 'id', 'sml-1-' + i ); sml_1.setAttribute( 'class', 'sml-1' ); sml_1.appendChild( document.createTextNode( misc_symbols[ i ] ) ); modal_close.parentElement.insertBefore( sml_1, modal_close.nextSibling ); } for ( let i = smileys_links.length - 1; i >= 0; i-- ) { let sml_2 = document.createElement( 'span' ); let sml_2_img = document.createElement( 'img' ); sml_2.setAttribute( 'id', 'sml-2-' + i ); sml_2.setAttribute( 'class', 'sml-2' ); sml_2.appendChild( sml_2_img ); sml_2_img.setAttribute( 'src', smileys_links[ i ] ); sml_2_img.setAttribute( 'height', '17px' ); modal_close.parentElement.insertBefore( sml_2, modal_close.nextSibling ); } const sibling_elements = [ getElements( 'mail' ) ? getElements( 'mail' )[ 0 ].previousElementSibling.previousElementSibling : null, getElement( 'markup' ).nextElementSibling ]; for ( let i = 0; i < sibling_elements.length; i++ ) { if ( sibling_elements[ i ] && sibling_elements[ i ].tagName === 'BR' ) { sibling_elements[ i ].remove(); } } if ( getElements( 'preview' ) ) { if ( getElements( 'preview' )[ 0 ].nextElementSibling && getElements( 'preview' )[ 0 ].nextElementSibling.tagName !== 'BR' ) { getElements( 'preview' )[ 0 ].nextElementSibling.insertAdjacentHTML( 'beforebegin', '<br>' ); } else if ( getElements( 'preview' )[ 0 ].parentNode.nextElementSibling && getElements( 'preview' )[ 0 ].parentNode.nextElementSibling.tagName !== 'BR' ) { getElements( 'preview' )[ 0 ].parentNode.nextElementSibling.insertAdjacentHTML( 'beforebegin', '<br>' ); } } /** Convert tags into mark-up */ updateTextArea( [ replaceTags, delNewlines, delWhitespaces ] ); saveState(); /** Set translate & short links options on */ checkCookies(); /** Events handling */ /** Text area */ text_area.addEventListener( 'keypress', translateLetter, false ); text_area.addEventListener( 'input', checkMarkup, true ); text_area.addEventListener( 'keyup', decolorizeButtons, false ); text_area.addEventListener( 'focus', delFlag, false ); text_area.addEventListener( 'click', decolorizeButtons, true ); text_area.addEventListener( 'select', colorizeButtons, true ); text_area.addEventListener( 'paste', mkHyperlinks, false ); /** Decorators replace-function */ colorize_btns.concat( color_btns ) .forEach( ( elem ) => { getElement( elem ).addEventListener( 'click', decorate, false ); } ); /** Image upload */ getElement( 'img' ).addEventListener( 'change', fileMonitor, false ); getElement( 'upload' ).addEventListener( 'click', mkFlag, false ); /** Smileys handling */ getElement( 'smiley' ).addEventListener( 'click', mkFlag, false ); getElement( 'smiley' ).addEventListener( 'click', showSmileys, false ); getElement( 'preview' ).addEventListener( 'click', showPreview, false ); getElement( 'modal-symbols-close' ).addEventListener( 'click', defaultState, false ); getElement( 'modal-preview-close' ).addEventListener( 'click', defaultState, false ); for ( let i = 0; i < misc_symbols.length; i++ ) { getElement( 'sml-1-' + i ).addEventListener( 'click', insertSmiley1, false ); } for ( let i = 0; i < smileys_links.length; i++ ) { getElement( 'sml-2-' + i ).addEventListener( 'click', insertSmiley2, false ); } /** Sizing */ resize_el.addEventListener( 'click', fullSize, false ); getElement( 'font' ).addEventListener( 'click', resizeFont, false ); const answer = getElement( 'answer' ); if ( answer ) { answer.addEventListener( 'click', showPrevious, false ); } /** Clear decorators */ getElement( 'clear' ).addEventListener( 'click', delDecorators, false ); /** Undo - redo */ getElement( 'undo' ).addEventListener( 'click', undo, false ); getElement( 'redo' ).addEventListener( 'click', redo, false ); /** Submit */ if ( getElement( 'trtxt' ) ) { getElement( 'trfrm' ).addEventListener( 'submit', normalizeTags, false ); } else { getElement( 'trfrm-dialog' ).addEventListener( 'submit', normalizeTags, false ); } /** Translate & short links */ getElement( 'translate' ).addEventListener( 'change', checkBoxVal, false ); getElement( 'short-links' ).addEventListener( 'change', checkBoxVal, false ); } }; /**----------------------------------------- Editor's functions -----------------------------------------*/ let checkCookies = () => { if ( getCookie( 'translate' ) !== "" && getCookie( 'translate' ) !== 'off' ) { getElement( 'translate' ).checked = true; } if ( getCookie( 'short-links' ) !== "" && getCookie( 'short-links' ) !== 'off' ) { getElement( 'short-links' ).checked = true; } }; let setCookie = ( cname, cvalue ) => { const currentYear = new Date().getFullYear(), nextYear = currentYear + 1, expires = "expires=" + new Date().toUTCString().replace( currentYear.toString(), nextYear.toString() ); document.cookie = cname + "=" + cvalue + "; " + expires + "; domain=.germany.ru; path=/"; }; let getCookie = ( cname ) => { const name = cname + "=", ca = document.cookie.split( ';' ); for ( let i = 0; i < ca.length; i++ ) { let c = ca[ i ]; while ( c.charAt( 0 ) === ' ' ) { c = c.substring( 1 ); } if ( c.indexOf( name ) === 0 ) { return c.substring( name.length, c.length ); } } return ""; }; let checkBoxVal = ( event ) => { if ( event ) { const check_box = getElement( event.target.id ); if ( check_box.checked ) { setCookie( event.target.id, 'on' ); } else { setCookie( event.target.id, 'off' ); } } }; let checkMarkup = () => { let corrupted_index = -1, pair_index, corrupted_length, pair_length; saveState(); updateTextArea( [ ( text ) => { const links_all = /\[[^\s]*?⇄.*?]/g, links = /\[\u200c[^\s]*?⇄.*?]\u200c/g, img = /\[[^\s]*?\.(jpg|png|gif|jpeg|bmp)⇄img]((\(.*?\))[\u200b]|[\u200b])/g, vid = /\[[^\s]*?⇄vid]/g, text_hist = text_history[ text_history.length - 2 ]; if ( text_hist.match( links_all ) ) { const img_count_hist = text_hist.match( img ) ? text_hist.match( img ).length : 0, vid_count_hist = text_hist.match( vid ) ? text_hist.match( vid ).length : 0, links_count_hist = text_hist.match( links ) ? text_hist.match( links ).length : 0, img_count = text.match( img ) ? text.match( img ).length : 0, vid_count = text.match( vid ) ? text.match( vid ).length : 0, links_count = text.match( links ) ? text.match( links ).length : 0; let replace_links = ( all, index ) => { if ( /\[[^\s]*?⇄vid]/.test( all ) || /\[\u200c[^\s]*?⇄.*?]\u200c/.test( all ) || /\[[^\s]*?\.(jpg|png|gif|jpeg|bmp)⇄img](\(.*?\)[\u200b]|[\u200b])/.test( all ) ) { return all; } corrupted_index = index; corrupted_length = all.length; return ""; }; let text_c = text; if ( img_count_hist !== img_count ) { text_c = text_c.replace( /\[(?:.|\s)*?\.(?:jpg|png|gif|jpeg|bmp)⇄img](?:\((?:.|\s)*?\)?[\u200b]|[\u200b])/g, replace_links ); text_c = text_c === text ? text_c.replace( /\[(?:.|\s)*?\.(?:jpg|png|gif|jpeg|bmp)⇄img](?:\(?(?:.|\s)*?\)[\u200b]|[\u200b])/g, replace_links ) : text_c; text_c === text ? text_c = text_c.replace( /\[(?:.|\s)*?\.(?:jpg|png|gif|jpeg|bmp)⇄?img](?:\((?:.|\s)*?\)[\u200b]|[\u200b])/g, replace_links ) : text_c; text_c === text ? text_c = text_c.replace( /\[(?:.|\s)*?\.(?:jpg|png|gif|jpeg|bmp)⇄(?:.|\s)*?](?:\((?:.|\s)*?\)[\u200b]|[\u200b])/g, replace_links ) : text_c; text_c = text_c === text ? text_c.replace( /\[?(?:.|\s)*?\.(?:jpg|png|gif|jpeg|bmp)⇄img](?:\((?:.|\s)*?\)[\u200b]|[\u200b])/g, replace_links ) : text_c; text_c = text_c === text ? text_c.replace( /\[(?:.|\s)*?\.(?:jpg|png|gif|jpeg|bmp)⇄img]?(?:\((?:.|\s)*?\)[\u200b]|[\u200b])/g, replace_links ) : text_c; text_c = text_c === text ? text_c.replace( /\[(?:.|\s)*?\.(?:jpg|png|gif|jpeg|bmp)⇄img](?:\((?:.|\s)*?\)[\u200b]?|[\u200b]?)/g, replace_links ) : text_c; text_c === text ? text_c.replace( /\[(?:.|\s)*?⇄img](?:\((?:.|\s)*?\)[\u200b]|[\u200b])/g, replace_links ) : text_c; } else if ( vid_count_hist !== vid_count ) { text_c = text_c.replace( /\[(?:.|\s)*?⇄?vid]/g, replace_links ); text_c = text_c === text ? text_c.replace( /\[?(?:.|\s)*?⇄vid]/g, replace_links ) : text_c; text_c = text_c === text ? text_c.replace( /\[(?:.|\s)*?⇄(?:.|\s)*?](?!\((?:.|\s)*?\)[\u200b]|[\u200b]|[\u200c])/g, replace_links ) : text_c; text_c === text ? text_c.replace( /\[(?:.|\s)*?⇄vid]?/g, replace_links ) : text_c; } else if ( links_count_hist !== links_count ) { text_c = text_c.replace( /\[\u200c(?:.|\s)*?⇄(?:.|\s)*?]\u200c?/g, replace_links ); text_c = text_c === text ? text_c.replace( /\[\u200c(?:.|\s)*?⇄?(?:.|\s)*?]\u200c/g, replace_links ) : text_c; text_c = text_c === text ? text_c.replace( /\[\u200c(?:.|\s)*?⇄(?:.|\s)*?\u200c/g, replace_links ) : text_c; text_c = text_c === text ? text_c.replace( /\[?\u200c(?:.|\s)*?⇄(?:.|\s)*?]\u200c/g, replace_links ) : text_c; text_c = text_c === text ? text_c.replace( /\[[^\u200c]*?\u200c(?:.|\s)*?⇄(?:.|\s)*?]\u200c/g, replace_links ) : text_c; text_c === text ? text_c.replace( /\[[^\u200c]*?⇄(?:.|\s)*?]\u200c/g, replace_links ) : text_c; } if ( corrupted_index !== -1 ) { return text.substring( 0, corrupted_index ) + text.substring( corrupted_index + corrupted_length ); } } const single_letter_opening = /\[[\u200b]([suib])[\u200b]]/g, single_letter_closing = /\[[\u200b]\/([suib])[\u200b]]/g, single_letter_opened_count = text.match( single_letter_opening ) ? text.match( single_letter_opening ).length : 0, single_letter_closed_count = text.match( single_letter_closing ) ? text.match( single_letter_closing ).length : 0, multi_letter_opening = /\[(red|blue|black|green|quote|pre)]/g, multi_letter_closing = /\[\/(red|blue|black|green|quote|pre)]/g, multi_letter_opened_count = text.match( multi_letter_opening ) ? text.match( multi_letter_opening ).length : 0, multi_letter_closed_count = text.match( multi_letter_closing ) ? text.match( multi_letter_closing ).length : 0; if ( single_letter_opened_count === single_letter_closed_count && multi_letter_opened_count === multi_letter_closed_count ) { return text; } let corrupted, pair_is_closing; if ( single_letter_opened_count !== single_letter_closed_count || multi_letter_opened_count !== multi_letter_closed_count ) { const decorators = [ 's', 'u', 'i', 'b', 'red', 'blue', 'black', 'green', 'quote', 'pre' ]; for ( let i = 0; i < decorators.length; i++ ) { let opening_all, closing_all, opening_and_closing, opening, closing; if ( decorators[ i ].length === 1 ) { opening_all = new RegExp( "\\[\u200b" + decorators[ i ] + "\u200b]", "g" ); closing_all = new RegExp( "\\[\u200b\\/" + decorators[ i ] + "\u200b]", "g" ); opening_and_closing = new RegExp( "\\[\u200b\\/?" + decorators[ i ] + "\u200b]", "g" ); opening = new RegExp( "\\[\u200b" + decorators[ i ] + "\u200b]" ); closing = new RegExp( "\\[\u200b\\/" + decorators[ i ] + "\u200b]" ); } else { opening_all = new RegExp( "\\[" + decorators[ i ] + "]", "g" ); closing_all = new RegExp( "\\[\\/" + decorators[ i ] + "]", "g" ); opening_and_closing = new RegExp( "\\[\\/?" + decorators[ i ] + "]", "g" ); opening = new RegExp( "\\[" + decorators[ i ] + "]" ); closing = new RegExp( "\\[\\/" + decorators[ i ] + "]" ); } const opened = text.match( opening_all ) ? text.match( opening_all ).length : 0, closed = text.match( closing_all ) ? text.match( closing_all ).length : 0; if ( opened === closed ) { continue; } let match, ii = 0, pair_ids = []; while ( ( match = opening_and_closing.exec( text ) ) !== null && pair_index === undefined ) { pair_ids.push( match.index ); if ( opened - closed === 2 ) { if ( opening.test( match[ 0 ] ) && ii % 2 !== 0 ) { corrupted_index = match.index; pair_index = pair_ids[ pair_ids.length - 2 ]; corrupted_length = decorators[ i ].length > 2 ? decorators[ i ].length + 2 : 5; pair_length = corrupted_length; break; } } else if ( opening.test( match[ 0 ] ) && ii % 2 !== 0 ) { pair_index = pair_ids[ pair_ids.length - 2 ]; pair_length = decorators[ i ].length > 2 ? decorators[ i ].length + 2 : 5; break; } else if ( closing.test( match[ 0 ] ) && ii % 2 === 0 ) { pair_index = pair_ids[ pair_ids.length - 1 ]; pair_length = decorators[ i ].length > 2 ? decorators[ i ].length + 3 : 6; break; } ii++; } if ( pair_index === undefined && pair_ids.length > 0 ) { pair_index = pair_ids[ pair_ids.length - 1 ]; } if ( opened > closed ) { corrupted = '/' + decorators[ i ]; if ( !pair_length ) { pair_length = decorators[ i ].length > 2 ? decorators[ i ].length + 2 : 5; } break; } else if ( closed > opened ) { pair_is_closing = true; corrupted = decorators[ i ]; if ( !pair_length ) { pair_length = decorators[ i ].length > 2 ? decorators[ i ].length + 3 : 6; } break; } } } let replace_decorators = ( all, index ) => { if ( new RegExp( "(\\[\u200b" + corrupted.replace( '/', '' ) + "\u200b])" ).test( all ) || new RegExp( "(\\[\u200b\\/" + corrupted.replace( '/', '' ) + "\u200b])" ).test( all ) || new RegExp( "(\\[" + corrupted.replace( '/', '' ) + "])" ).test( all ) || new RegExp( "(\\[\\/" + corrupted.replace( '/', '' ) + "])" ).test( all ) ) { return all; } corrupted_index = index; corrupted_length = all.length; return ""; }; if ( corrupted_index === -1 ) { let text_c = text; if ( corrupted.length <= 2 ) { text_c = text_c.replace( new RegExp( "\\[[^\u200b]*?\u200b" + corrupted + "\u200b]", "g" ), replace_decorators ); text_c = text_c === text ? text_c.replace( new RegExp( "\\[[^\u200b]*?" + corrupted + "\u200b]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\u200b[^s|u|i|b]*?" + corrupted + "\u200b]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\u200b\\/[^s|u|i|b]*?" + corrupted.replace( '/', '' ) + "\u200b]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\u200b" + corrupted + "[^\u200b]*?\u200b]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\u200b" + corrupted + "[^\u200b]*?]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\u200b" + corrupted + "\u200b]?", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[?\u200b" + corrupted + "\u200b]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\u200b\u200b]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\u200b\\/\u200b]", "g" ), replace_decorators ) : text_c; text_c === text ? text_c.replace( new RegExp( "\\[\u200b" + corrupted + "[\u200b]]?", "g" ), replace_decorators ) : text_c; } else { if ( !pair_is_closing ) { corrupted = corrupted.replace( '/', '' ); } let i = corrupted.length - 1; while ( i >= 1 && text_c === text ) { text_c = text_c.replace( new RegExp( "\\[\\/?" + corrupted.replace( corrupted.charAt( i ), "(?:.|\\s)*?" ) + "]", "g" ), replace_decorators ); i--; } text_c = text_c === text ? text_c.replace( new RegExp( "\\[\\/?[^" + corrupted.charAt( 0 ) + "]{1,3}" + corrupted.charAt( 0 ) + "?" + corrupted.substr( 1 ) + "]", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[[^\\/]*?\\/?" + corrupted + "]?", "g" ), replace_decorators ) : text_c; text_c = text_c === text ? text_c.replace( new RegExp( "\\[\\/?" + corrupted + "]?", "g" ), replace_decorators ) : text_c; text_c === text ? text_c.replace( new RegExp( "\\[?\\/?" + corrupted + "]", "g" ), replace_decorators ) : text_c; } } if ( corrupted_index === -1 ) { if ( pair_index === undefined ) { return text; } else { return text.substring( 0, pair_index ) + text.substring( pair_index + pair_length ); } } else if ( pair_is_closing ) { return text.substring( 0, corrupted_index ) + text.substring( corrupted_index + corrupted_length, pair_index ) + text.substring( pair_index + pair_length ); } else { return text.substring( 0, pair_index ) + text.substring( pair_index + pair_length, corrupted_index ) + text.substring( corrupted_index + corrupted_length ); } } ] ); const previous = text_history[ text_history.length - 1 ], diff = previous.length - text_area.value.length; if ( diff !== 0 ) { text_history.splice( text_history.length - 1 ); saveState(); for ( let i = text_area.value.length - 1; i >= 0; i-- ) { if ( text_area.value.charAt( i ) !== previous.charAt( i + diff ) ) { corrupted_index = i + 1; break; } } } setCursor( corrupted_index ); }; let updateTextArea = ( callback ) => { let text = text_area.value, text_initial = text; const args = [ ...callback ]; for ( let i = 0; i < args.length; i++ ) { if ( typeof args[ i ] === 'function' ) { text = args[ i ].call( args[ i ], text.toString() ); } } if ( text_initial !== text ) { text_area.value = text; } }; let replaceTags = ( text ) => { for ( let i = 0; i < smileys_links.length; i++ ) { const smiley = smileys_links[ i ].substring( 46, smileys_links[ i ].length - 4 ), smiley_link_patt = new RegExp( '<img src=\\"http[s]?:\\/\\/tt\\.germany\\.ru\\/wwwthreads\\/images\\/icons\\/' + smiley + '\\.gif\\"\\s\\/>', 'gi' ); text = text.replace( smiley_link_patt, '[' + smiley + ']' ); } return text .replace( /<font color="(red|blue|black|green)">((?:.|\s)*?)<\/font>/gi, '[$1]$2[/$1]' ) .replace( /<blockquote>(<q>)?/gi, '[quote]' ) .replace( /(<\/q>)?<\/blockquote>(<br \/>)?/gi, '[/quote]\n' ) .replace( /<a(?=.*href)/gi, '[\u200c' ) .replace( /"?\s?><\/iframe>/gi, '⇄vid]' ) .replace( /"\s?>(?=.*<\/a>)/gi, '⇄' ) .replace( /<\/a>/gi, ']\u200c' ) .replace( /target="_\w+"?|href="?|src="?|width="\d{3}"?(?!(%|px))|height="\d{3}"?(?!(%|px))|frameborder="\d+"?/gi, '' ) .replace( /(<img|<iframe)/gi, '[' ) .replace( /\[(?![\u200c])\s+(?![\u200c])(?=http.*|ftp.*)/gi, '[' ) .replace( /\[[\u200c]?\s+[\u200c]?(?=http.*|ftp.*)/gi, '[\u200c' ) .replace( /<(br \/|br|p)>/gi, '\n' ) .replace( /<\/p>/gi, '' ) .replace( /"\swidth="(?=(\d+(%|px)))/gi, '⇄img](' ) .replace( /px"\s?\/?>/g, 'px)\u200b' ) .replace( /%"\s?\/?>/g, '%)\u200b' ) .replace( /"\s?\/?>/g, '⇄img](auto)\u200b' ) .replace( /</gi, '[\u200b' ) .replace( />/gi, '\u200b]' ) .replace( /"\s⇄/g, '⇄' ); }; let normalizeTags = ( event ) => { if ( getElements( 'Subject' ) && getElements( 'Subject' )[ 0 ].value.trim() === "" ) { if ( getElement( 'subj' ) ) { getElement( 'subj' ).classList.remove( 'error' ); } event.stopPropagation(); event.preventDefault(); } updateTextArea( [ delNewlines, delWhitespaces, normalize ] ); }; let normalize = ( text ) => { text = text .replace( /\[(red|blue|black|green)]/gi, '<font color="$1">' ) .replace( /\[\/(red|blue|black|green)]/gi, '</font>' ) .replace( /\[quote]/gi, '<blockquote><q>' ) .replace( /\[\/quote]\n?/gi, '</q></blockquote>' ) .replace( /\[(\/?pre)]/gi, '<$1>' ) .replace( /(\[https:\/\/player\.vimeo\.com\/video\/)/gi, '<iframe width="560" height="315" frameborder="0" src="https://player.vimeo.com/video/' ) .replace( /(\[https:\/\/www\.youtube\.com\/embed\/)/gi, '<iframe width="560" height="315" frameborder="0" src="https://www.youtube.com/embed/' ) .replace( /(\[https:\/\/ok\.ru\/videoembed\/)/gi, '<iframe width="560" height="315" frameborder="0" src="https://ok.ru/videoembed/' ) .replace( /⇄vid]/gi, '"></iframe>' ) .replace( /\[(?=.*\.(jpg|png|gif|jpeg|bmp))(?![\u200c])/gi, '<img src="' ) .replace( /⇄img]\((\d+(%|px))\)[\u200b]/gi, '" width="$1">' ) .replace( /⇄img]\(.*?\)[\u200b]/gi, '">' ) .replace( /⇄img][\u200b]/gi, '">' ) .replace( /\[[\u200c]/g, '<a target="_blank" href="' ) .replace( /⇄(.*?)]\u200c/g, '">$1</a>' ) .replace( /⇄[\s].*?]\u200c/g, '">link</a>' ) .replace( /><\/a>/g, '">link</a>' ) .replace( /\[[\u200b]/g, '<' ) .replace( /[\u200b]]/g, '>' ) .replace( /\n/gi, '<br>' ) .replace( /⚐/g, '' ); for ( let i = 0; i < smileys_links.length; i++ ) { const smiley_patt = new RegExp( '\\[' + smileys_links[ i ].substring( 46, smileys_links[ i ].length - 4 ) + '\\]', 'gi' ); text = text.replace( smiley_patt, '<img src="' + smileys_links[ i ] + '" />' ); } return text; }; let fullSize = () => { const resize_state = getElement( 'resize' ).innerHTML; if ( resize_state === "↗" ) { text_area.classList.add( 'text-area-full' ); getElement( 'markup' ).classList.add( 'markup-full' ); getElement( 'resize' ).classList.add( 'resize-el-full' ); getElement( 'preview' ).classList.add( 'preview-full' ); getElement( 'resize' ).innerHTML = "↙"; styleElement( getElement( 'font' ), { 'display': 'inline' } ); styleElement( getElement( 'font' ).children[ 0 ], { 'fontSize': '16px' } ); styleElement( getElement( 'redo' ).parentElement, { 'marginRight': '85px' } ); getElements( "FOOTER" ) ? styleElement( getElements( "FOOTER" )[ 0 ], { 'display': 'none' } ) : null; getElements( "BODY" ) ? styleElement( getElements( "BODY" )[ 0 ], { 'overflowX': 'hidden' } ) : null; const answer = getElement( 'answer' ); if ( answer && comment_to_answer ) { answer.innerHTML = "▲"; answer.classList.add( 'answer-full' ); comment_to_answer.classList.add( 'comment-to-answer-full' ); styleElement( text_area, { 'height': '88vh' } ); } else { styleElement( text_area, { 'height': '94vh' } ); } const native_buttons = getElements( 'btn' ); if ( native_buttons ) { for ( let i = 0; i < native_buttons.length; i++ ) { styleElement( native_buttons[ i ], { 'position': 'static' } ); } } if ( container_well && container_wrap ) { styleElement( container_well[ container_well.length - 1 ], { 'position': 'fixed', 'top': '0', 'left': '0', 'backgroundColor': '#fff', 'height': '100vw' } ); styleElement( container_wrap[ container_wrap.length - 2 ], { 'position': 'fixed' } ); } } else { normalSize(); } setCursor(); }; let normalSize = () => { text_area.classList.remove( 'text-area-full' ); styleElement( text_area ); getElement( 'markup' ).classList.remove( 'markup-full' ); getElement( 'preview' ).classList.remove( 'preview-full' ); getElement( 'resize' ).classList.remove( 'resize-el-full' ); getElement( 'resize' ).innerHTML = "↗"; styleElement( getElement( 'font' ) ); styleElement( getElement( 'font' ).children[ 0 ] ); styleElement( getElement( 'redo' ).parentElement ); getElements( "FOOTER" ) ? styleElement( getElements( "FOOTER" )[ 0 ] ) : null; getElements( "BODY" ) ? styleElement( getElements( "BODY" )[ 0 ] ) : null; if ( comment_to_answer ) { comment_to_answer.classList.remove( 'comment-to-answer-full', 'comment-to-answer-opened' ); getElement( 'answer' ).classList.remove( 'answer-full', 'answer-opened' ); } if ( container_well && container_wrap ) { styleElement( container_well[ container_well.length - 1 ] ); styleElement( container_well[ container_well.length - 2 ] ); } }; let showPrevious = () => { const previous_state = getElement( 'answer' ).innerHTML, answer = getElement( 'answer' ); if ( previous_state === '▲' ) { text_area.style.height = '60vh'; answer.innerHTML = "▼"; answer.classList.replace( 'answer-full', 'answer-opened' ); comment_to_answer.classList.replace( 'comment-to-answer-full', 'comment-to-answer-opened' ); } else { text_area.style.height = '88vh'; answer.innerHTML = "▲"; answer.classList.replace( 'answer-opened', 'answer-full' ); comment_to_answer.classList.replace( 'comment-to-answer-opened', 'comment-to-answer-full' ); } setCursor(); }; let resizeFont = () => { const font_size = window.getComputedStyle( text_area, null ).getPropertyValue( 'font-size' ); switch ( parseFloat( font_size ) ) { case 16: styleElement( text_area, { 'fontSize': '18px' } ); styleElement( getElement( 'font' ).children[ 0 ], { 'fontSize': '18px' } ); break; default: styleElement( text_area, { 'fontSize': '16px' } ); styleElement( getElement( 'font' ).children[ 0 ], { 'fontSize': '16px' } ); } setCursor(); }; let decorate = ( event ) => { const button_id = event.target.getAttribute( 'id' ); if ( button_id ) { if ( !isSelected() ) { errorMsg( "no_text" ); } else { const identical_pattern = /^(red|blue|green|black|quote|pre)$/, first_letter_pattern = /^(strike|underline|italic|bold)$/; if ( identical_pattern.test( button_id ) ) { replace( '[' + button_id + ']', '[/' + button_id + ']' ); } else if ( first_letter_pattern.test( button_id ) ) { replace( '[\u200b' + button_id.substr( 0, 1 ) + '\u200b]', '[\u200b/' + button_id.substr( 0, 1 ) + '\u200b]' ); } else if ( button_id === 'l-quote' ) { replace( '«', '»' ); } } } }; let isSelected = () => { let selected = false; if ( text_area.selectionStart !== null ) { const start_pos = text_area.selectionStart, end_pos = text_area.selectionEnd; if ( end_pos - start_pos > 0 && text_area.value.substr( start_pos, end_pos ).trim() !== '' ) { selected = true; } } return selected; }; let errorMsg = ( msg ) => { const error = getElement( 'error' ); switch ( msg ) { case "no_text": error.innerHTML = "Выделите сначала текст!"; break; case "false_img_file": error.innerHTML = "Неподходящее изображение!"; break; case "upload_broken": error.innerHTML = "Ошибка загрузки изображения :("; break; case "wrong_cursor_position": error.innerHTML = "Курсор внутри спец. разметки!"; break; default: error.innerHTML = "Что-то пошло не так :("; } setTimeout( () => { error.innerHTML = ""; }, 4000 ); }; function isVID( str ) { const youtube = /^https:\/\/www\.youtube\.com\/watch\?v=([a-zA-Z0-9-_]){10,11}(&.*)?$/, vimeo = /^https:\/\/vimeo.com\/\d{4,}$/, ok = /^https:\/\/ok\.ru\/video\/\d{4,}$/; return youtube.test( str ) || vimeo.test( str ) || ok.test( str ); } function isIMG( str ) { const imgRegex = /^(?:http[s]?:\/\/(?:www\.)?|ftp:\/\/(?:www\.)?|www\.)(?:[0-9A-Za-z-.@:%_+~#=]+)+(?:(?:\.[a-zA-Z]{2,3})+)(?:.*)?(?:\.(?:jpg|png|gif|jpeg|bmp))$/i; return str.length < 2083 && imgRegex.test( str ); } function isURL( str ) { const urlRegex = /^(?:http[s]?:\/\/(?:www\.)?|ftp:\/\/(?:www\.)?|www\.)(?:[0-9A-Za-z-.@:%_+~#=]+)+(?:(?:\.[a-zA-Z]{2,3})+)(?:.*)?/i; return str.length < 2083 && urlRegex.test( str ); } function mkShortUrl( callback, inputValue ) { const fn = this; if ( typeof callback === 'function' ) { if ( inputValue.length > 25 && !fn._memorised.bind( fn, inputValue )() ) { const service = 'http://is.gd/api.php?longurl=%URL%', _uri = service.replace( '%URL%', encodeURIComponent( inputValue ) ); GM.xmlHttpRequest( { method : "GET", url : _uri, headers: { 'User-Agent': 'Mozilla/4.0 (compatible) Greasemonkey', 'Accept' : 'application/atom+xml,application/xml,text/xml' }, onload: ( response ) => { callback( response.responseText ); }, onerror: () => { callback( inputValue ); } } ); } else { callback( fn._memorised.bind( fn, inputValue )() || inputValue ); } } } let mkHyperlinks = ( event ) => { if ( event ) { const inputValue = event.clipboardData.getData( 'Text' ).trim(); if ( inputValue ) { isIMG._resolve.bind( isIMG, ( is_img ) => { if ( is_img ) { event.preventDefault(); insert( '[' + inputValue + '⇄img](auto)\u200b', event ); } else { isVID._resolve.bind( isVID, ( is_vid ) => { if ( is_vid ) { event.preventDefault(); const start = inputValue.indexOf( '=' ), end = inputValue.indexOf( '&' ); if ( end !== -1 ) { insert( '[https://www.youtube.com/embed/' + inputValue.substr( start + 1, ( end - start - 1 ) ) + '⇄vid]', event ); } else if ( start !== -1 ) { insert( '[https://www.youtube.com/embed/' + inputValue.substr( start + 1 ) + '⇄vid]', event ); } else if ( /vimeo/.test( inputValue ) ) { insert( '[https://player.vimeo.com/video/' + inputValue.substr( 18 ) + '⇄vid]', event ); } else if ( /ok\.ru/.test( inputValue ) ) { insert( '[https://ok.ru/videoembed/' + inputValue.substr( 20 ) + '⇄vid]', event ); } } else { isURL._resolve.bind( isURL, ( is_url ) => { if ( is_url ) { event.preventDefault(); if ( getElement( 'short-links' ).checked ) { mkShortUrl.bind( mkShortUrl, ( url ) => { mkShortUrl._memorise.bind( mkShortUrl, inputValue, url )(); if ( isSelected() ) { replace( '[\u200c' + ( isURL( url ) ? url : inputValue ) + '⇄', ']\u200c' ); } else { insert( '[\u200c' + ( isURL( url ) ? url : inputValue ) + '⇄link]\u200c', event ); } }, inputValue )(); } else { if ( isSelected() ) { replace( '[\u200c' + inputValue + '⇄', ']\u200c' ); } else { insert( '[\u200c' + inputValue + '⇄link]\u200c', event ); } } } }, inputValue )(); } }, inputValue )(); } }, inputValue )(); } } }; let fileMonitor = ( event ) => { try { const file_obj = getElement( "img" ), formData = new FormData( getElement( 'upload' ) ); if ( formData && file_obj && file_obj.files.length > 0 && ( /image\/jpg|png|gif|jpeg|bmp/i ).test( file_obj.files[ 0 ].type ) ) { formData.append( "file", file_obj.files[ 0 ] ); upload( formData, event ); } else { errorMsg( "false_img_file" ); } } catch ( e ) { errorMsg( "upload_broken" ); } }; let upload = ( image, event ) => { try { GM.xmlHttpRequest( { method: "POST", url : "https://h.germany.ru/abogat/r/upload.php?hash=" + getCookie( 'session' ), data : image, onload: ( response ) => { const msg_obj = JSON.parse( response.responseText ), msg = msg_obj.filelink.toString() .replace( '/\\/g', '' ) .replace( '/"/g', '' ); msg ? insert( '[' + msg + '⇄img](auto)\u200b', event ) : errorMsg( "upload_broken" ); }, onerror: () => { errorMsg( "upload_broken" ); } } ); } catch ( e ) { errorMsg( "upload_broken" ); } }; let undo = () => { let cursor = text_area.selectionEnd; if ( text_history.length - 1 > undo_clicks ) { undo_clicks++; getElement( 'redo' ).style.color = 'inherit'; getElement( 'redo' ).disabled = false; if ( undo_clicks === text_history.length - 1 ) { getElement( 'undo' ).style.color = '#999999'; getElement( 'undo' ).disabled = true; } updateTextArea( [ () => { const previous = text_history[ text_history.length - undo_clicks - 1 ], diff = text_area.value.length - previous.length; for ( let i = previous.length - 1; i >= 0; i-- ) { if ( previous.charAt( i ) !== text_area.value.charAt( i + diff ) ) { cursor = i + 1; break; } } return previous; } ] ); } setCursor( cursor ); }; let redo = () => { let cursor = text_area.selectionEnd; if ( undo_clicks > 0 ) { undo_clicks--; getElement( 'undo' ).style.color = 'inherit'; getElement( 'undo' ).disabled = false; if ( undo_clicks === 0 ) { getElement( 'redo' ).style.color = '#999999'; getElement( 'redo' ).disabled = true; } updateTextArea( [ () => { const previous = text_history[ text_history.length - undo_clicks - 1 ], diff = text_area.value.length - previous.length; for ( let i = previous.length - 1; i >= 0; i-- ) { if ( previous.charAt( i ) !== text_area.value.charAt( i + diff ) ) { cursor = i + 1; break; } } return previous; } ] ); } setCursor( cursor ); }; let colorizeButtons = () => { if ( isSelected() ) { const selected_text = text_area.value.substring( text_area.selectionStart, text_area.selectionEnd ), after_selection = text_area.value.substring( text_area.selectionEnd ), before_selection = text_area.value.substring( 0, text_area.selectionStart ), decorator_patterns = [ /\[[\u200b]\/?([suib])[\u200b]]/g, /\[\/?(red|blue|black|green|quote|pre)]/g, /\[(smile|frown|blush|cool|crazy|laugh|mad|shocked|tongue|wink|up|down|kiss|flower|glass|heart)]/g, /\[.*?\.(jpg|png|gif|jpeg|bmp)⇄img]((\(((\d+(%|px))|auto)\))[\u200b]|[\u200b])/g, /\[.*?⇄.*?]/g ]; let colorize = true; selected_decorators = new Map(); let noteDeletableDecorators = ( letter_pattern, outer_before, outer_after, partial_outer ) => { let match, index, length; while ( ( match = letter_pattern.exec( text_area.value ) ) !== null ) { if ( outer_before ) { if ( match.index <= text_area.selectionStart ) { index = match.index; length = match[ 0 ].length; } else { break; } } else if ( outer_after ) { if ( match.index >= text_area.selectionEnd ) { index = match.index; length = match[ 0 ].length; break; } } else if ( partial_outer ) { if ( match.index <= text_area.selectionEnd ) { index = match.index; length = match[ 0 ].length; } else { break; } } else { if ( match.index >= text_area.selectionStart && match.index <= text_area.selectionEnd ) { index = match.index; length = match[ 0 ].length; } } } if ( index !== undefined && length !== undefined ) { getElement( 'clear' ).disabled = false; getElement( 'clear' ).style.color = 'inherit'; selected_decorators.set( index, length ); } }; const decorators = [ 's', 'u', 'i', 'b', 'red', 'blue', 'black', 'green', 'quote', 'pre' ]; for ( let i = 0; i < decorators.length; i++ ) { let opening_all, closing_all, opening_and_closing, opening, closing; if ( decorators[ i ].length === 1 ) { opening_all = new RegExp( "\\[\u200b" + decorators[ i ] + "\u200b]", "g" ); closing_all = new RegExp( "\\[\u200b\\/" + decorators[ i ] + "\u200b]", "g" ); opening_and_closing = new RegExp( "\\[\u200b\\/?" + decorators[ i ] + "\u200b]", "g" ); opening = new RegExp( "\\[\u200b" + decorators[ i ] + "\u200b]" ); closing = new RegExp( "\\[\u200b\\/" + decorators[ i ] + "\u200b]" ); } else { opening_all = new RegExp( "\\[" + decorators[ i ] + "]", "g" ); closing_all = new RegExp( "\\[\\/" + decorators[ i ] + "]", "g" ); opening_and_closing = new RegExp( "\\[\\/?" + decorators[ i ] + "]", "g" ); opening = new RegExp( "\\[" + decorators[ i ] + "]" ); closing = new RegExp( "\\[\\/" + decorators[ i ] + "]" ); } const opened_inner = selected_text.match( opening_all ) ? selected_text.match( opening_all ).length : 0, closed_inner = selected_text.match( closing_all ) ? selected_text.match( closing_all ).length : 0; if ( opened_inner === closed_inner && opened_inner !== 0 ) { noteDeletableDecorators( opening_all ); noteDeletableDecorators( closing_all ); } else if ( opened_inner > closed_inner ) { noteDeletableDecorators( opening_all ); noteDeletableDecorators( closing_all, false, true ); } else if ( opened_inner < closed_inner ) { noteDeletableDecorators( closing_all ); } const opened_outer_before = before_selection.match( opening_all ) ? before_selection.match( opening_all ).length : 0, closed_outer_before = before_selection.match( closing_all ) ? before_selection.match( closing_all ).length : 0, opened_outer_after = after_selection.match( opening_all ) ? after_selection.match( opening_all ).length : 0, closed_outer_after = after_selection.match( closing_all ) ? after_selection.match( closing_all ).length : 0; if ( opened_outer_before !== 0 ) { if ( ( opened_outer_before + closed_outer_before ) % 2 !== 0 ) { noteDeletableDecorators( opening_all, true ); } } if ( closed_outer_after !== 0 ) { if ( ( opened_outer_after + closed_outer_after ) % 2 !== 0 ) { noteDeletableDecorators( closing_all, false, true ); } } } for ( let i = 0; i < decorator_patterns.length; i++ ) { const all_count = text_area.value.match( decorator_patterns[ i ] ) ? text_area.value.match( decorator_patterns[ i ] ).length : 0, before_count = before_selection.match( decorator_patterns[ i ] ) ? before_selection.match( decorator_patterns[ i ] ).length : 0, within_count = selected_text.match( decorator_patterns[ i ] ) ? selected_text.match( decorator_patterns[ i ] ).length : 0, after_count = after_selection.match( decorator_patterns[ i ] ) ? after_selection.match( decorator_patterns[ i ] ).length : 0; if ( ( before_count + within_count + after_count ) !== all_count ) { if ( i < 2 ) { noteDeletableDecorators( decorator_patterns[ i ], true ); noteDeletableDecorators( new RegExp( decorator_patterns[ i ].source, "g" ), false, false, true ); } colorize = false; break; } } if ( !colorize ) { for ( let i = 0; i < colorize_btns.length; i++ ) { getElement( colorize_btns[ i ] ).style.color = '#999999'; getElement( colorize_btns[ i ] ).disabled = true; } for ( let i = 0; i < color_btns.length; i++ ) { getElement( color_btns[ i ] ).classList.remove( 'no-user-selection', 'user-selection' ); getElement( color_btns[ i ] ).classList.add( 'user-selection-disabled' ); getElement( color_btns[ i ] ).disabled = true; } getElement( 'smiley' ).disabled = true; getElement( 'img' ).disabled = true; return; } for ( let i = 0; i < colorize_btns.length; i++ ) { const single_letter = new RegExp( "\\[\u200b\\/?" + colorize_btns[ i ].substr( 0, 1 ) + "\u200b]" ), multi_letter = new RegExp( "\\[\\/?" + colorize_btns[ i ] + "]" ), single_letter_all = new RegExp( "\\[\u200b\\/?" + colorize_btns[ i ].substr( 0, 1 ) + "\u200b]", "g" ), multi_letter_all = new RegExp( "\\[\\/?" + colorize_btns[ i ] + "]", "g" ), single_before = before_selection.match( single_letter_all ) ? before_selection.match( single_letter_all ).length : 0, single_after = after_selection.match( single_letter_all ) ? after_selection.match( single_letter_all ).length : 0, multi_before = before_selection.match( multi_letter_all ) ? before_selection.match( multi_letter_all ).length : 0, multi_after = after_selection.match( multi_letter_all ) ? after_selection.match( multi_letter_all ).length : 0; if ( !single_letter.test( selected_text ) && !multi_letter.test( selected_text ) && ( single_before + multi_before ) % 2 === 0 && ( single_after + multi_after ) % 2 === 0 ) { getElement( colorize_btns[ i ] ).style.color = 'inherit'; getElement( colorize_btns[ i ] ).disabled = false; } else { getElement( colorize_btns[ i ] ).style.color = '#999999'; getElement( colorize_btns[ i ] ).disabled = true; } } const multi_letter = /\[\/?(red|green|blue|black)]/, multi_letter_all = /\[\/?(red|green|blue|black)]/g, multi_before = before_selection.match( multi_letter_all ) ? before_selection.match( multi_letter_all ).length : 0, multi_after = after_selection.match( multi_letter_all ) ? after_selection.match( multi_letter_all ).length : 0; for ( let i = 0; i < color_btns.length; i++ ) { if ( !multi_letter.test( selected_text ) && ( multi_before % 2 === 0 ) && ( multi_after % 2 === 0 ) ) { getElement( color_btns[ i ] ).classList.remove( 'no-user-selection', 'user-selection-disabled' ); getElement( color_btns[ i ] ).classList.add( 'user-selection' ); getElement( color_btns[ i ] ).disabled = false; } else { getElement( color_btns[ i ] ).classList.remove( 'no-user-selection', 'user-selection' ); getElement( color_btns[ i ] ).classList.add( 'user-selection-disabled' ); getElement( color_btns[ i ] ).disabled = true; } } } }; let decolorizeButtons = () => { for ( let i = 0; i < colorize_btns.length; i++ ) { getElement( colorize_btns[ i ] ).style.color = '#999999'; } for ( let i = 0; i < color_btns.length; i++ ) { getElement( color_btns[ i ] ).classList.remove( 'user-selection', 'user-selection-disabled' ); getElement( color_btns[ i ] ).classList.add( 'no-user-selection' ); } getElement( 'smiley' ).disabled = false; getElement( 'img' ).disabled = false; getElement( 'clear' ).disabled = true; getElement( 'clear' ).style.color = '#999999'; }; let delDecorators = () => { saveState(); updateTextArea( [ ( text ) => { let replaced_chars = 0; const indexes = [ ...selected_decorators.keys() ].sort( ( a, b ) => { return a - b; } ); indexes.forEach( ( index ) => { let length = selected_decorators.get( index ); text = text.substring( 0, ( index - replaced_chars ) ) + text.substr( index - replaced_chars + length ); replaced_chars += length; } ); return text; } ] ); const previous = text_history[ text_history.length - 1 ], diff = previous.length - text_area.value.length; let cursor_index = -1; if ( diff !== 0 ) { saveState(); for ( let i = text_area.value.length - 1; i >= 0; i-- ) { if ( text_area.value.charAt( i ) !== previous.charAt( i + diff ) ) { cursor_index = i + 1; break; } } } setCursor( cursor_index ); }; let defaultState = ( event ) => { decolorizeButtons(); if ( event && event.target.getAttribute( 'id' ) !== "" ) { hideModal(); } }; let saveState = () => { if ( text_history[ text_history.length - 1 ] !== text_area.value.trim() ) { text_history.splice( ( text_history.length - undo_clicks ), undo_clicks + 1, text_area.value ); undo_clicks = 0; getElement( 'redo' ).style.color = '#999999'; getElement( 'redo' ).disabled = true; if ( text_history.length > 1 ) { getElement( 'undo' ).style.color = 'inherit'; getElement( 'undo' ).disabled = false; } } }; let replace = ( open_tag, close_tag, event ) => { const e = event || window.event; if ( isSelected() ) { saveState(); text_area.focus(); const start_pos = text_area.selectionStart, end_pos = text_area.selectionEnd, text = text_area.value, before_selection = text.substring( 0, start_pos ), after_selection = text.substring( end_pos, text.length ); if ( text.substr( start_pos, 1 ) === ' ' ) { open_tag = ' ' + open_tag; } if ( text.substr( end_pos - 1, 1 ) === ' ' ) { close_tag = close_tag + ' '; } const selection = open_tag + text.substring( start_pos, end_pos ).trim() + close_tag; updateTextArea( [ () => { return before_selection + selection + after_selection; } ] ); saveState(); text_area .setSelectionRange( before_selection.length + open_tag.length, before_selection.length + open_tag.length + text .substring( start_pos, end_pos ).trim().length ); defaultState( e ); } }; let insert = ( input, event ) => { if ( input !== "⚐" ) { delFlag( event ); saveState(); } const before_selection = text_area.value.substring( 0, text_area.selectionStart ), after_selection = text_area.value.substring( text_area.selectionStart ), new_text = before_selection + input + after_selection, decorator_patterns = [ /\[[\u200b]\/?([suib])[\u200b]]/g, /\[\/?(red|blue|black|green|quote|pre)]/g, /\[(smile|frown|blush|cool|crazy|laugh|mad|shocked|tongue|wink|up|down|kiss|flower|glass|heart)]/g, /\[.*?\.(jpg|png|gif|jpeg|bmp)⇄img]((\(((\d+(%|px))|auto)\))[\u200b]|[\u200b])/g, /\[.*?⇄.*?]/g ]; let insertable = true; for ( let i = 0; i < decorator_patterns.length; i++ ) { const all_count = text_area.value.match( decorator_patterns[ i ] ) ? text_area.value.match( decorator_patterns[ i ] ).length : 0, before_count = before_selection.match( decorator_patterns[ i ] ) ? before_selection.match( decorator_patterns[ i ] ).length : 0, after_count = after_selection.match( decorator_patterns[ i ] ) ? after_selection.match( decorator_patterns[ i ] ).length : 0; if ( ( i < 2 && ( before_count + after_count ) % 2 !== 0 ) || ( i > 1 && ( before_count + after_count ) !== all_count ) ) { insertable = false; break; } } if ( !insertable ) { event.preventDefault(); event.stopPropagation(); hideModal(); errorMsg( "wrong_cursor_position" ); return; } updateTextArea( [ () => { return new_text; } ] ); if ( input !== "⚐" ) { saveState(); setCursor( new_text.length - after_selection.length ); } }; let setCursor = ( cursor ) => { let cursor_pos_start = cursor || text_area.value.indexOf( "⚐" ), cursor_pos_end = cursor_pos_start; if ( cursor_pos_start === -1 ) { cursor_pos_start = text_area.selectionStart; cursor_pos_end = text_area.selectionEnd; } if ( cursor_pos_start ) { text_area.setSelectionRange( cursor_pos_start, cursor_pos_end ); } text_area.focus(); }; let mkFlag = ( event ) => { const cursor = text_area.value.indexOf( "⚐" ); if ( cursor === -1 ) { insert( "⚐", event ); } }; let delFlag = ( event ) => { const cursor = text_area.value.indexOf( "⚐" ); if ( cursor !== -1 ) { text_area.value = text_area.value.replace( /⚐/g, '' ); if ( event ) { setCursor( cursor ); } } defaultState( event ); }; let delNewlines = ( text ) => { return text.trim().replace( /\n{4,}/g, '\n\n\n' ); }; let delWhitespaces = ( text ) => { let replaceable = true; text = text .replace( /[\u200b][s][\u200b]]\s+(?!\[)/g, '\u200bs\u200b]' ) .replace( /[\u200b][u][\u200b]]\s+(?!\[)/g, '\u200bu\u200b]' ) .replace( /[\u200b][i][\u200b]]\s+(?!\[)/g, '\u200bi\u200b]' ) .replace( /[\u200b][b][\u200b]]\s+(?!\[)/g, '\u200bb\u200b]' ) .replace( /\s+\[[\u200b]\//g, '[\u200b/' ) .replace( /(\/?pre[\u200b])|(\n(?!\n)\s+)/g, ( all, first ) => { if ( first && !/\/pre\u200b/.test( first ) ) { replaceable = false; } else if ( first && /\/pre\u200b/.test( first ) ) { replaceable = true; return first; } if ( replaceable ) { return '\n'; } else { return all; } } ) .replace( /\[quote]\s+/g, '[quote]' ) .replace( /\s+\[\/quote]/g, '[/quote]' ); replaceable = false; text = text .replace( /(\/?quote)|(\n){2,}/g, ( all, first ) => { if ( first && !/\/quote/.test( first ) ) { replaceable = true; return first; } else if ( first && /\/quote/.test( first ) ) { replaceable = false; } if ( replaceable ) { return '\n'; } else { return all; } } ); return text; }; let showSmileys = () => { getElement( 'modal-dialogue' ).style.display = 'block'; getElement( 'modal-dialogue' ).style.zIndex = '99999'; getElement( 'modal-preview' ).style.display = 'none'; getElement( 'modal-symbols' ).style.display = 'inline-block'; }; let hideModal = () => { getElement( 'modal-dialogue' ).style.display = 'none'; getElement( 'modal-symbols' ).style.display = 'none'; getElement( 'modal-preview' ).style.display = 'none'; }; let showPreview = () => { getElement( 'modal-dialogue' ).style.display = 'block'; getElement( 'modal-dialogue' ).style.zIndex = '99999'; getElement( 'modal-symbols' ).style.display = 'none'; getElement( 'modal-preview' ).style.display = 'block'; getElement( 'preview-body' ).innerHTML = normalize( text_area.value ); }; let insertSmiley1 = ( event ) => { const symbol = event.target.innerHTML; insert( symbol, event ); }; let insertSmiley2 = ( event ) => { try { const smiley_tag = event.target.innerHTML.substring( 56, event.target.innerHTML.indexOf( ".gif" ) ) ? event.target.innerHTML.substring( 56, event.target.innerHTML.indexOf( ".gif" ) ) : event.target.outerHTML.substring( 56, event.target.outerHTML.indexOf( ".gif" ) ); insert( '[' + smiley_tag + ']', event ); } catch ( e ) { } }; let translateLetter = ( event ) => { if ( getElement( 'translate' ).checked ) { const input = event.key; if ( !event.which || rus.indexOf( input ) !== -1 ) { return; } if ( input && ( !( event.ctrlKey || event.altKey ) ) ) { event.preventDefault(); const pre_text = text_area.value.substring( 0, text_area.selectionStart ), translated_text = translateSymbolToCyrillic( pre_text + input ), post_text = text_area.value.substr( text_area.selectionEnd ), result = translated_text + post_text; if ( text_area.value !== result ) { updateTextArea( [ () => { return translated_text + post_text; } ] ); saveState(); setCursor( translated_text.length ); } } } }; let translateSymbolToCyrillic = ( text ) => { let pos = 0; for ( let i = 0; i < lat.length; i++ ) { pos = text.length > lat[ i ].length ? ( text.length - lat[ i ].length ) : 0; if ( lat[ i ] === text.substr( pos, text.length - pos ) ) { return text.substr( 0, text.length - lat[ i ].length ) + rus[ i ]; } } return text; }; setUp(); } )();