Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* global marked */
- ( function ( $ )
- {
- $.fn.wcTextarea = function ( options )
- {
- let DEFAULTS = {
- livePreview: false,
- buttons: {
- header: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-header fa-fw"></i>'
- },
- bold: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-bold fa-fw"></i>'
- },
- italic: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-italic fa-fw"></i>'
- },
- ul: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-list-ul fa-fw"></i>'
- },
- ol: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-list-ol fa-fw"></i>'
- },
- link: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-link fa-fw"></i>'
- },
- picture: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-picture-o fa-fw"></i>'
- },
- codeInline: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-code fa-fw"></i>'
- },
- quote: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-quote-right fa-fw"></i>'
- },
- paragraph: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-paragraph fa-fw"></i>'
- },
- preview: {
- btnClass: 'btn btn-default',
- html: '<i class="fa fa-eye fa-fw"></i>'
- }
- }
- };
- let option = $.extend(true, DEFAULTS, options || { });
- console.log(option);
- let textarea = $(this),
- wrapper = $('<div>', { class: 'my-textarea', css: { position: 'relative' } }),
- lineSplittPattern = /\r?\n|\r/,
- markedFound = 'function' === typeof marked,
- vars = {
- value: '',
- start: 0,
- end: 0,
- length: 0,
- selectedText: '',
- selectedLength: 0,
- words: 0,
- lines: 0
- },
- buttons = {
- bold: null,
- italic: null,
- codeInline: null,
- h1: null,
- h2: null,
- h3: null,
- h4: null,
- h5: null,
- h6: null,
- quote: null,
- paragraph: null,
- ul: null,
- ol: null,
- link: null,
- picture: null,
- goBack: null,
- goForward: null,
- preview: null
- },
- counters = {
- paragraphs: null,
- lines: null,
- words: null,
- characters: null,
- selected: null
- };
- textarea.wrap(wrapper);
- textarea.prop('rows', 10).addClass('rounded-0 shadow border-0').css({ 'display': 'block' });
- function buildButtons()
- {
- let btnGroup = $('<div>', {
- class: 'btn-group btn-group-xs mb-2 shadow flex-nowrap rounded-0'
- }).insertBefore(textarea);
- let headlineBtnGroup = $('<div>', { class: "btn-group" }).appendTo(btnGroup);
- $('<button>', {
- type: 'button',
- class: 'btn btn-default dropdown-toggle btn-xs',
- 'data-toggle': 'dropdown',
- 'aria-haspopup': 'true',
- 'aria-expanded': 'false',
- html: [
- '<i class="fa fa-header fa-fw"></i> <span class="caret"></span>'
- ].join(''),
- title: 'Überschrift'
- }).appendTo(headlineBtnGroup);
- let dropDownMenu = $('<ul>', { class: 'dropdown-menu' }).appendTo(headlineBtnGroup);
- let li;
- for ( let i = 1; i <= 6; i ++ )
- {
- li = $('<li>').appendTo(dropDownMenu);
- buttons['h' + i] = $('<a>', {
- href: '#',
- html: option.buttons.header.html + ' Überschrift ' + i
- }).appendTo(li);
- }
- buttons.bold = $('<button>', {
- class: option.buttons.bold.btnClass,
- html: option.buttons.bold.html,
- title: 'Fett',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.italic = $('<button>', {
- class: option.buttons.italic.btnClass,
- html: option.buttons.italic.html,
- title: 'Kursiv',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.ul = $('<button>', {
- class: option.buttons.ul.btnClass,
- html: option.buttons.ul.html,
- title: 'unnummerierte Liste',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.ol = $('<button>', {
- class: option.buttons.ol.btnClass,
- html: option.buttons.ol.html,
- title: 'Nummerierte liste',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.link = $('<button>', {
- class: option.buttons.link.btnClass,
- html: option.buttons.link.html,
- title: 'Link',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.picture = $('<button>', {
- class: option.buttons.picture.btnClass,
- html: option.buttons.picture.html,
- title: 'Bild einfügen',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.codeInline = $('<button>', {
- class: option.buttons.codeInline.btnClass,
- html: option.buttons.codeInline.html,
- title: 'Inline Code',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.quote = $('<button>', {
- class: option.buttons.quote.btnClass,
- html: option.buttons.quote.html,
- title: 'Zitat',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- buttons.paragraph = $('<button>', {
- class: option.buttons.paragraph.btnClass,
- html: option.buttons.paragraph.html,
- title: 'neuer Absatz',
- 'data-toggle': 'tooltip'
- }).appendTo(btnGroup);
- if ( markedFound && ! option.livePreview )
- {
- buttons.preview = $('<button>', {
- class: option.buttons.preview.btnClass,
- html: option.buttons.preview.html,
- title: 'Vorschau',
- 'data-toggle': 'tooltip',
- click: showPreview
- }).appendTo(btnGroup);
- }
- }
- function showPreview( e )
- {
- e.preventDefault();
- buildModalPreview();
- }
- function buildModalPreview()
- {
- if ( $('#modal_wc_textarea_preview').length )
- {
- $('#modal_wc_textarea_preview').modal('hide');
- }
- let modal = $('<div>', {
- id: 'modal_wc_textarea_preview',
- class: 'modal',
- tabindex: - 1,
- 'data-backdrop': 'static',
- role: 'dialog',
- html: [
- '<div class="modal-dialog" role="document">',
- '<div class="modal-content rounded-0">',
- '<div class="modal-body" style="max-height:80vh; overflow-y:auto">',
- marked(vars.value) || 'Es wurde kein Inhalt für die Vorschau gefunden.',
- '</div>',
- '<div class="modal-footer border-0 text-left">',
- '<button type="button" class="btn btn-default btn-block rounded-0" data-dismiss="modal">Schließen</button>',
- '</div>',
- '</div>',
- '</div>'
- ].join('')
- }).appendTo('body');
- modal.on('hidden.bs.modal', function ()
- {
- modal.remove();
- });
- modal.modal('show');
- }
- function buildCounters()
- {
- let counter = $('<div>', { class: 'd-flex justify-content-end text-muted', css: { 'position': 'absolute', right: '20px', bottom: '1px', background: 'white' } }).insertAfter(textarea);
- counters.lines = $('<small>', { class: 'ml-2' }).appendTo(counter);
- counters.paragraphs = $('<small>', { class: 'ml-2' }).appendTo(counter);
- counters.words = $('<small>', { class: 'ml-2' }).appendTo(counter);
- counters.characters = $('<small>', { class: 'ml-2' }).appendTo(counter);
- counters.selected = $('<small>', { class: 'ml-2' }).appendTo(counter);
- textarea.css('padding-bottom', '20px');
- }
- function setData( e )
- {
- vars.value = textarea.val();
- vars.start = textarea.prop('selectionStart');
- vars.end = textarea.prop('selectionEnd');
- vars.selectedLength = vars.end - vars.start;
- vars.selectedText = vars.value.substr(vars.start, vars.selectedLength);
- vars.length = vars.value.length;
- vars.lines = ! vars.length ? 0 : vars.value.split(lineSplittPattern).length;
- vars.words = 0;
- let parapgraphs = 0;
- if ( vars.length )
- {
- let lines = vars.value.split(lineSplittPattern);
- for ( let i = 0; i < lines.length; i ++ )
- {
- vars.words += lines[i].trim().replace(/\s\s+/g, ' ').split(' ').length;
- if ( lines[i].length )
- {
- parapgraphs ++;
- }
- }
- }
- counters.lines.text(vars.lines + ( vars.lines === 1 ? ' Zeile' : ' Zeilen' ));
- counters.paragraphs.text(parapgraphs + ( parapgraphs === 1 ? ' Absatz' : ' Absätze' ));
- counters.words.text(vars.words + ( vars.words === 1 ? ' Wort' : ' Wörter' ));
- counters.characters.text(vars.length + ' Zeichen');
- counters.selected.text(vars.selectedLength + ' markiert');
- if ( markedFound && option.livePreview && $(option.livePreview).length )
- {
- $(option.livePreview).html(marked(vars.value));
- }
- }
- function setEvents()
- {
- textarea
- .on('keyup change mousedown touchstart touchend mouseup focusIn click', setData)
- .on('mouseenter', function ()
- {
- })
- .on('mouseleave', function ()
- {
- });
- buttons.bold.on('click', function ( e )
- {
- e.preventDefault();
- wrapWith('**');
- });
- buttons.italic.on('click', function ( e )
- {
- e.preventDefault();
- wrapWith('_');
- });
- buttons.ul.on('click', function ( e )
- {
- e.preventDefault();
- setUl();
- });
- buttons.ol.on('click', function ( e )
- {
- e.preventDefault();
- setOl();
- });
- buttons.link.on('click', function ( e )
- {
- e.preventDefault();
- buildModalLink();
- });
- buttons.picture.on('click', function ( e )
- {
- e.preventDefault();
- buildModalPicture();
- });
- buttons.codeInline.on('click', function ( e )
- {
- e.preventDefault();
- wrapWith('`');
- });
- for ( let i = 1; i <= 6; i ++ )
- {
- buttons['h' + i].on('click', function ( e )
- {
- e.preventDefault();
- setMultiLineStart('#'.repeat(i) + ' ');
- });
- }
- buttons.quote.on('click', function ( e )
- {
- e.preventDefault();
- setMultiLineStart('> ');
- });
- buttons.paragraph.on('click', function ( e )
- {
- e.preventDefault();
- setSingleLineEnd('\n');
- });
- }
- function buildModalLink()
- {
- if ( $('#modal_wc_textarea_link').length )
- {
- $('#modal_wc_textarea_link').modal('hide');
- }
- let modal = $('<div>', {
- id: 'modal_wc_textarea_link',
- class: 'modal',
- tabindex: - 1,
- 'data-backdrop': 'static',
- role: 'dialog',
- html: [
- '<div class="modal-dialog" role="document">',
- '<div class="modal-content rounded-0">',
- '<form>',
- '<div class="modal-body" style="max-height:80vh; overflow-y:auto">',
- '<div class="form-group">',
- '<label class="control-label">URL</label>',
- '<input type="text" name="url" class="form-control" placeholder="https://..." value="' + vars.selectedText + '" required>',
- '</div>',
- '<div class="form-group">',
- '<label class="control-label">Link Text</label>',
- '<input type="text" name="name" class="form-control" placeholder="angezeigter Name" required>',
- '</div>',
- '<div class="form-group">',
- '<label class="control-label">Tooltip</label>',
- '<input type="text" name="tooltip" class="form-control" placeholder="Tooltip">',
- '</div>',
- '</div>',
- '<div class="modal-footer border-0">',
- '<button type="button" class="btn btn-default rounded-0" data-dismiss="modal">Abbrechen</button>',
- '<button type="submit" class="btn btn-success rounded-0">Einfügen</button>',
- '</div>',
- '</form>',
- '</div>',
- '</div>'
- ].join('')
- }).appendTo('body');
- modal.find('form').on('submit', function ( e )
- {
- e.preventDefault();
- setLink($(this).find('[name="url"]').val(), $(this).find('[name="name"]').val(), $(this).find('[name="tooltip"]').val());
- modal.modal('hide');
- });
- modal.on('hidden.bs.modal', function ()
- {
- modal.remove();
- });
- modal.modal('show');
- }
- function buildModalPicture()
- {
- if ( $('#modal_wc_textarea_picture').length )
- {
- $('#modal_wc_textarea_picture').modal('hide');
- }
- let modal = $('<div>', {
- id: 'modal_wc_textarea_picture',
- class: 'modal',
- tabindex: - 1,
- 'data-backdrop': 'static',
- role: 'dialog',
- html: [
- '<div class="modal-dialog" role="document">',
- '<div class="modal-content rounded-0">',
- '<form>',
- '<div class="modal-body" style="max-height:80vh; overflow-y:auto">', '<div class="form-group">',
- '<label class="control-label">Bild URL</label>',
- '<input type="text" name="src" class="form-control" placeholder="https://Bild.url" value="' + vars.selectedText + '" required>',
- '</div>',
- '<div class="form-group">',
- '<label class="control-label">Alternativ Text</label>',
- '<input type="text" name="alt" class="form-control" placeholder="Alternativ Text" required>',
- '</div>',
- '</div>',
- '<div class="modal-footer border-0">',
- '<button type="button" class="btn btn-default rounded-0" data-dismiss="modal">Abbrechen</button>',
- '<button type="submit" class="btn btn-success rounded-0">Einfügen</button>',
- '</div>',
- '</form>',
- '</div>',
- '</div>'
- ].join('')
- }).appendTo('body');
- modal.find('form').on('submit', function ( e )
- {
- e.preventDefault();
- setPicture($(this).find('[name="src"]').val(), $(this).find('[name="alt"]').val());
- modal.modal('hide');
- });
- modal.on('hidden.bs.modal', function ()
- {
- modal.remove();
- });
- modal.modal('show');
- }
- function setPicture( url, alternativeText )
- {
- if ( ! url )
- {
- return false;
- }
- let startWithSpace = vars.selectedLength.length && vars.selectedLength.startsWith(' ');
- let linktext = ( startWithSpace ? ' ' : '' ) + '![' + alternativeText + '](' + url + ')';
- textarea.val(vars.value.slice(0, vars.start) + linktext + vars.value.slice(vars.end));
- textarea.focus();
- textarea.trigger('change');
- }
- function setLink( url, title, tooltip )
- {
- let startWithSpace = vars.selectedLength.length && vars.selectedLength.startsWith(' ');
- if ( ! ( url || title ) )
- {
- return false;
- }
- if ( ! url.startsWith('http') )
- {
- url = '//' + url;
- }
- let linktext = ( startWithSpace ? ' ' : '' ) + '[' + title + '](' + url + ' "' + tooltip + '")';
- textarea.val(vars.value.slice(0, vars.start) + linktext + vars.value.slice(vars.end));
- textarea.focus();
- textarea.trigger('change');
- }
- function setUl()
- {
- let selectedLines = getLineNumForSelection(),
- lines = getLines(selectedLines.start, selectedLines.end),
- result = [ ],
- line;
- for ( let i = 0, currLine = selectedLines.start; i < lines.length; i ++, currLine ++ )
- {
- line = lines[i]
- .replace(/^\d+./, '')
- .replace('-', '')
- .trim();
- lines[i] = '- ' + line;
- result[currLine] = lines[i];
- }
- textarea.val(replaceLines(result));
- textarea.trigger('change');
- }
- function setOl()
- {
- let selectedLines = getLineNumForSelection(),
- lines = getLines(selectedLines.start, selectedLines.end),
- result = [ ],
- line;
- for ( let i = 0, number = 1, currLine = selectedLines.start; i < lines.length; i ++, number ++, currLine ++ )
- {
- line = lines[i].replace(/^\d+./, '').replace('-', '').trim();
- lines[i] = number + '. ' + line;
- result[currLine] = lines[i];
- }
- textarea.val(replaceLines(result));
- textarea.trigger('change');
- }
- /**
- * Holt die komplette Zeile als Zeichenkette
- * @param {Integer} lineNum
- * @returns {String}
- */
- function getLineByNumber( lineNum )
- {
- return vars.value.split(lineSplittPattern)[lineNum - 1];
- }
- /**
- * Holt die Zeilen die markiert worden sind
- * @param {Integer} start
- * @param {Integer} end
- * @returns {Array}
- */
- function getLines( start, end )
- {
- let allLines = vars.value.split(lineSplittPattern);
- let linesSelected = [ ];
- for ( let i = 0; i < allLines.length; i ++ )
- {
- if ( ( i >= ( start - 1 ) ) && ( i <= ( end - 1 ) ) )
- {
- linesSelected.push(allLines[i]);
- }
- }
- return linesSelected;
- }
- function addParagraphBefore( )
- {
- let cache = getLineNumForSelection();
- let lineNum = cache.start;
- let line = getLineByNumber(lineNum);
- textarea.val(replaceLine(lineNum, '\n' + line));
- textarea.trigger('change');
- return cache;
- }
- /**
- * Ersetzt eine Zeile und gibt die komplette Zeichenkette wieder zurück
- * @param {Integer} lineNum
- * @param {String} line
- * @returns {String}
- */
- function replaceLine( lineNum, line )
- {
- let newLines = [ ];
- let lines = vars.value.split(lineSplittPattern);
- for ( let i = 0; i < lines.length; i ++ )
- {
- if ( i === ( lineNum - 1 ) )
- {
- newLines.push(line);
- } else
- {
- newLines.push(lines[i]);
- }
- }
- return newLines.join('\n');
- }
- function replaceLines( replacedlines )
- {
- let lines = vars.value.split(lineSplittPattern);
- for ( let i = 0; i < lines.length; i ++ )
- {
- for ( let line in replacedlines )
- {
- if ( line - 1 === i )
- {
- lines[i] = replacedlines[line];
- }
- }
- }
- return lines.join('\n');
- }
- function setMultiLineStart( str )
- {
- // Hole die Zeilen die betroffen sind
- let selectedLines = getLineNumForSelection(),
- lines = getLines(selectedLines.start, selectedLines.end),
- result = [ ];
- for ( let i = 0, currLine = selectedLines.start; i < lines.length; i ++, currLine ++ )
- {
- // wen die Zeile bereits mit dem gewünschtem Zeichen anfängt, säubere die Zeile
- while ( lines[i].startsWith(str[0]) )
- {
- lines[i] = lines[i].substring(1).trim();
- }
- lines[i] = str + lines[i].trim();
- result[currLine] = lines[i];
- }
- // ersetze die alte mit der neuen Zeile
- textarea.val(replaceLines(result));
- // cursor zurück in die Textarea setzen
- textarea.focus();
- //
- // let cursorAt = vars.start + str.length;
- // textarea
- // .prop('selectionStart', cursorAt)
- // .prop('selectionEnd', cursorAt);
- textarea.trigger('change');
- }
- function setSingleLineEnd( str )
- {
- let lineNum = getLineNumForSelection().end,
- line = getLineByNumber(lineNum) + str;
- textarea.val(replaceLine(lineNum, line));
- textarea.trigger('change');
- }
- function setSingleLineStart( str )
- {
- let lineNum = getLineNumForSelection().start,
- line = getLineByNumber(lineNum);
- while ( line.startsWith(str[0]) )
- {
- line = line.substring(1);
- }
- line = str + line.trim();
- textarea.val(replaceLine(lineNum, line));
- textarea.trigger('change');
- }
- function wrapWith( str )
- {
- let txt = str + vars.selectedText.split(str).join("").trim() + str;
- textarea.val(vars.value.slice(0, vars.start) + txt + vars.value.slice(vars.end));
- textarea.focus();
- if ( vars.selectedLength )
- {
- let cursorAt = vars.start + txt.length;
- textarea.prop('selectionStart', cursorAt);
- textarea.prop('selectionEnd', cursorAt);
- } else
- {
- let cursorAt = vars.start + str.length;
- textarea.prop('selectionStart', cursorAt);
- textarea.prop('selectionEnd', cursorAt);
- }
- textarea.trigger('change');
- }
- function getLineNumForSelection()
- {
- return {
- 'start': vars.value.substr(0, textarea.prop('selectionStart')).split(lineSplittPattern).length,
- 'end': vars.value.substr(0, textarea.prop('selectionEnd')).split(lineSplittPattern).length
- };
- }
- function init()
- {
- buildButtons();
- buildCounters();
- setEvents();
- wrapper.find('[data-toggle="tooltip"]').tooltip();
- textarea.trigger('change');
- return textarea;
- }
- return init();
- };
- }(jQuery) );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement