vendredi 17 juin 2016

JavaScript: How to get user selection, and insert tag before and after the selection?


I made some really small WYSIWYG text editor, with some very basic functions, and this is the code (See live demo in jsfiddle):

HTML:

<section class="wysiwyg-editor" data-wysiwyg="true">
    <h2 id="hdwysiwygfw3v">WYSIWYG : By @natanel97</h2>
    <textarea id="wysiwyg_ta_ead"></textarea>
    <div class="wysiwyg-editor-toolbar wysiwyg-editor-toolbar-menu">
        <!-- enable only for test purposes
        <button class="wysiwyg-editor-toolbar-menu menu-button" onclick="wysiwyg_save()"><i class="fa fa-floppy-o"></i></button>
        -->
        <button class="wysiwyg-editor-toolbar-menu menu-button" onclick="wysiwyg_addtag( 'strong' )"><i class="fa fa-bold"></i></button>
        <button class="wysiwyg-editor-toolbar-menu menu-button" onclick="wysiwyg_addtag( 'em' )"><i class="fa fa-italic"></i></button>
        <button class="wysiwyg-editor-toolbar-menu menu-button" onclick="wysiwyg_addtag( 'ins' )"><i class="fa fa-underline"></i></button>
        <button class="wysiwyg-editor-toolbar-menu menu-button" onclick="wysiwyg_toggle( 'wtgl_link' )"><i class="fa fa-link"></i></button>
        <div class="wysiwyg-editor-toolbar-menu hover-button-drop-down">
            <button class="wysiwyg-editor-toolbar-menu menu-button">Font Size <i class="fa fa-caret-down"></i></button>
            <ul class="wysiwyg-editor-toolbar-menu drop-down-menu">
                <li><a href="javascript:;" onclick="wysiwyg_addtag( 'span', null, null, '9' )">9pt</a></li>
                <li><a href="javascript:;" onclick="wysiwyg_addtag( 'span', null, null, '11' )">11pt</a></li>
                <li><a href="javascript:;" onclick="wysiwyg_addtag( 'span', null, null, '13' )">13pt</a></li>
                <li><a href="javascript:;" onclick="wysiwyg_addtag( 'span', null, null, '16' )">16pt</a></li>
                <li><a href="javascript:;" onclick="wysiwyg_addtag( 'span', null, null, '19' )">19pt</a></li>
                <li><a href="javascript:;" onclick="wysiwyg_addtag( 'span', null, null, '21' )">21pt</a></li>
                <li><a href="javascript:;" onclick="wysiwyg_addtag( 'span', null, null, '26' )">26pt</a></li>
            </ul>
        </div>
        <div class="wysiwyg-editor-toolbar-menu hover-button-drop-down">
            <button class="wysiwyg-editor-toolbar-menu menu-button">Color <i class="fa fa-caret-down"></i></button>
            <ul class="wysiwyg-editor-toolbar-menu drop-down-menu color-selection">
                <li><a href="javascript:;" style="background:#000;" onclick="wysiwyg_addtag( 'span', null, null, null, '000' )">Black</a></li>
                <li><a href="javascript:;" style="background:#fff;" onclick="wysiwyg_addtag( 'span', null, null, null, 'fff' )">White</a></li>
                <li><a href="javascript:;" style="background:#c60b0b;" onclick="wysiwyg_addtag( 'span', null, null, null, 'c60b0b' )">Dark red</a></li>
                <li><a href="javascript:;" style="background:#f39106;" onclick="wysiwyg_addtag( 'span', null, null, null, 'f39106' )">Orange</a></li>
                <li><a href="javascript:;" style="background:#2597d9;" onclick="wysiwyg_addtag( 'span', null, null, null, '2597d9' )">Ocean blue</a></li>
                <li><a href="javascript:;" style="background:#72b442;" onclick="wysiwyg_addtag( 'span', null, null, null, '72b442' )">Grass green</a></li>
                <li><a href="javascript:;" style="background:#cc3366;" onclick="wysiwyg_addtag( 'span', null, null, null, 'cc3366' )">Fuchsia pink</a></li>
                <li><a href="javascript:;" onclick="wysiwyg_toggle( 'wtgl_color' );"><i class="fa fa-ellipsis-h"></i></a></li>
            </ul>
        </div>
        <div class="wysiwyg-editor-toolbar-menu hover-button-drop-down">
            <button class="wysiwyg-editor-toolbar-menu menu-button">Font <i class="fa fa-caret-down"></i></button>
            <ul class="wysiwyg-editor-toolbar-menu drop-down-menu">
                <li><a href="javascript:;">Default</a></li>
            </ul>
        </div>
        <button class="wysiwyg-editor-toolbar-menu menu-button" onclick="wysiwyg_toggle( 'wtgl_info' )"><i class="fa fa-info"></i></button>
    </div>
    <div class="wysiwyg-editor-contents" id="wysiwyg_ce_ead" contenteditable="true"></div>
    &nbsp;
    <div class="wysiwyg-scenes">
        <div class="scene" id="wtgl_link">
            <div class="wysiwyg-scenes-tables">
                <div class="tr">
                    <div class="td" style="width:120px;">Link url:</div>
                    <div class="td"><input type="text" id="wysiwyg-link-href" placeholder="Must start with &quot;http://&quot;" /></div>
                </div>
                <div class="tr">
                    <div class="td">Text:</div>
                    <div class="td"><input type="text" id="wysiwyg-link-text" placeholder="Describe the link" /></div>
                </div>
                <div class="tr">
                    <div class="td"></div>
                    <div class="td">
                        <button onclick="wysiwyg_addtag( 'a', 'wysiwyg-link-href', 'wysiwyg-link-text' );wysiwyg_toggle( 'wtgl_link' )">Add link</button>
                        <button type="reset" onclick="wysiwyg_toggle( 'wtgl_link' )">Cancel</button>
                    </div>
                </div>
            </div>
        </div>
        <div class="scene" id="wtgl_color">
            <div class="wysiwyg-scenes-tables">
                <div class="tr">
                    <div class="td">Custom HTML Color:</div>
                </div>
                <div class="tr">
                    <div class="td"><input type="text" id="wysiwyg-text-color" maxlength="6"
                    onkeypress="if( this.value == '#' || this.value==' ' ){ this.value = ''; }" onblur="if( this.value == '#' || this.value==' ' ){ this.value = ''; }"
                    placeholder="Without the '#'" /></div>
                </div>
                <div class="tr">
                    <div class="td">
                        <button onclick="wysiwyg_addtag( 'span', null, null, null, 'wysiwyg-text-color' );wysiwyg_toggle( 'wtgl_color' )">Add</button>
                        <button type="reset" onclick="wysiwyg_toggle( 'wtgl_color' )">Cancel</button>
                    </div>
                </div>
            </div>
        </div>
        <div class="scene" id="wtgl_info">
            <div class="wysiwyg-scenes-tables">
                <div class="tr">
                    <div class="td">
                        <p><strong>Untitled WYSIWYG</strong></p>
                        <p>Text editor</p>
                        <p>v0.1</p>
                        <p>
                        Written &amp; Developed by <a href="http://stackoverflow.com/users/6247920/natanel97">@natanel97</a></p>
                        <p>
                            <br />
                            <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
                                <img alt="Creative Commons license" src="https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png" />
                            </a>
                            <br />
                            <span style="font-size:11.6px;">This work is licensed under a
                                <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
                               Attribution-NonCommercial-ShareAlike 4.0 International </a>.
                            </span>
                            <br />
                        </p>
                        <button type="reset" onclick="wysiwyg_toggle( 'wtgl_info' )">Close</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>

JavaScript:

function wysiwyg_convert() {

    var wysiwyg_textarea = document.querySelector( '.wysiwyg-editor textarea' );
    var wysiwyg_div_edit = document.querySelector( '.wysiwyg-editor .wysiwyg-editor-contents' );

    wysiwyg_div_edit.onkeypress = function() {

        if( wysiwyg_textarea.value != wysiwyg_div_edit.innerHTML ) {

            wysiwyg_textarea.value = wysiwyg_div_edit.innerHTML;

        }

        else {

            if( wysiwyg_div_edit.innerHTML != wysiwyg_textarea.value ) {

                wysiwyg_div_edit.innerHTML = wysiwyg_textarea.value;

            }

        }

    }

}

function wysiwyg_addtag( tag, href, title, fontsize, color ) {

    var tag;
    var wysiwyg_div_edit = document.querySelector( '.wysiwyg-editor .wysiwyg-editor-contents' );

    if( tag == 'strong' || tag == 'em' || tag == 'ins' ) {

        wysiwyg_div_edit.innerHTML = wysiwyg_div_edit.innerHTML + ' <' + tag + '>Text</' + tag + '>';

    }

    else if( tag == 'img' || tag == 'br' ) {

        if( tag == 'img' ) {

            wysiwyg_div_edit.innerHTML = wysiwyg_div_edit.innerHTML + ' <' + tag + ' src="' + href + '" alt="' + title + '" />';

        }

        if( tag == 'br' ) {

            wysiwyg_div_edit.innerHTML = wysiwyg_div_edit.innerHTML + ' <' + tag + ' />';

        }

    }

    else {

        if( tag == 'a' ) {

            var href = document.getElementById( href ).value;
            var htxt = document.getElementById( title ).value;

            if( href != null ) {

                wysiwyg_div_edit.innerHTML = wysiwyg_div_edit.innerHTML + ' <' + tag + ' href="' + href + '">' + htxt + '</' + tag + '>';

            }

        }

        if( tag == 'span' ) {

            if( fontsize != null ) {

                wysiwyg_div_edit.innerHTML = wysiwyg_div_edit.innerHTML + ' <' + tag + ' style="font-size:' + fontsize + 'pt;">Text</' + tag + '>';

            }

            else if( color != null ) {

                if( document.getElementById('wtgl_color').style.display == 'block' ) {

                    var color = document.getElementById( color ).value;

                }

                wysiwyg_div_edit.innerHTML = wysiwyg_div_edit.innerHTML + ' <' + tag + ' style="color:#' + color + ';">Text</' + tag + '>';


            }

        }

    }

}

function wysiwyg_save() {

    // enable it only for testing purposes

    var wysiwyg_textarea = document.querySelector( '.wysiwyg-editor textarea' );
    alert( wysiwyg_textarea.value );

}

function wysiwyg_toggle( id ) {

    var id = document.getElementById( id );

    if( id.style.display == 'block' ) {

        id.style.display = 'none';

    }

    else {

        id.style.display = 'block';

    }

}

document.addEventListener( 'DOMContentLoaded', function() {

    wysiwyg_convert();

});

I want to create function that will receive selected text, if selected, inside the div, and when one of the styling buttons will be pressed, it will make something like: <someHTMLtag [...]>Selected Text</someHTMLtag>.

Can I make it using the function that I already have - wysiwyg_addtag and just add some code inside? If I can, how?

and just one more thing... I saw here in some question that &nbsp; helps to get rid of <br />, but whenever I take a look inside the source at the Inspect Element (using firefox) I see many of <br />s and it's annoying... how can I get rid of them for good?

Thank you very much. btw, feel free to test this wysiwyg editor, give notes if you want to, share with me your thoughts. I'd like to hear any feedback - good or bad. this is my first project I ever made from scratch with javascript. I usually use js for learning because I'm not really good at this stuff... but I hope I did it right and had no errors or something. and excuse me for my english, if there's any misspellings.


Aucun commentaire:

Enregistrer un commentaire