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();
}
)();