HOME


Mini Shell 1.0
DIR: /home/islapiiu/sites/faithlinkint/control-panel/plugins/tinymce/plugins/lists/
Upload File :
Current File : /home/islapiiu/sites/faithlinkint/control-panel/plugins/tinymce/plugins/lists/plugin.js
/**
 
 * plugin.js
 
 *
 
 * Released under LGPL License.
 
 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
 
 *
 
 * License: http://www.tinymce.com/license
 
 * Contributing: http://www.tinymce.com/contributing
 
 */



/*global tinymce:true */

/*eslint consistent-this:0 */



tinymce.PluginManager.add('lists', function (editor) {

    var self = this;



    function isChildOfBody(elm) {

        return editor.$.contains(editor.getBody(), elm);

    }



    function isBr(node) {

        return node && node.nodeName == 'BR';

    }



    function isListNode(node) {

        return node && (/^(OL|UL|DL)$/).test(node.nodeName) && isChildOfBody(node);

    }



    function isFirstChild(node) {

        return node.parentNode.firstChild == node;

    }



    function isLastChild(node) {

        return node.parentNode.lastChild == node;

    }



    function isTextBlock(node) {

        return node && !!editor.schema.getTextBlockElements()[node.nodeName];

    }



    function isEditorBody(elm) {

        return elm === editor.getBody();

    }



    editor.on('init', function () {

        var dom = editor.dom, selection = editor.selection;



        function isEmpty(elm, keepBookmarks) {

            var empty = dom.isEmpty(elm);



            if (keepBookmarks && dom.select('span[data-mce-type=bookmark]').length > 0) {

                return false;

            }



            return empty;

        }



        /**
         
         * Returns a range bookmark. This will convert indexed bookmarks into temporary span elements with
         
         * index 0 so that they can be restored properly after the DOM has been modified. Text bookmarks will not have spans
         
         * added to them since they can be restored after a dom operation.
         
         *
         
         * So this: <p><b>|</b><b>|</b></p>
         
         * becomes: <p><b><span data-mce-type="bookmark">|</span></b><b data-mce-type="bookmark">|</span></b></p>
         
         *
         
         * @param  {DOMRange} rng DOM Range to get bookmark on.
         
         * @return {Object} Bookmark object.
         
         */

        function createBookmark(rng) {

            var bookmark = {};



            function setupEndPoint(start) {

                var offsetNode, container, offset;



                container = rng[start ? 'startContainer' : 'endContainer'];

                offset = rng[start ? 'startOffset' : 'endOffset'];



                if (container.nodeType == 1) {

                    offsetNode = dom.create('span', {'data-mce-type': 'bookmark'});



                    if (container.hasChildNodes()) {

                        offset = Math.min(offset, container.childNodes.length - 1);



                        if (start) {

                            container.insertBefore(offsetNode, container.childNodes[offset]);

                        } else {

                            dom.insertAfter(offsetNode, container.childNodes[offset]);

                        }

                    } else {

                        container.appendChild(offsetNode);

                    }



                    container = offsetNode;

                    offset = 0;

                }



                bookmark[start ? 'startContainer' : 'endContainer'] = container;

                bookmark[start ? 'startOffset' : 'endOffset'] = offset;

            }



            setupEndPoint(true);



            if (!rng.collapsed) {

                setupEndPoint();

            }



            return bookmark;

        }



        /**
         
         * Moves the selection to the current bookmark and removes any selection container wrappers.
         
         *
         
         * @param {Object} bookmark Bookmark object to move selection to.
         
         */

        function moveToBookmark(bookmark) {

            function restoreEndPoint(start) {

                var container, offset, node;



                function nodeIndex(container) {

                    var node = container.parentNode.firstChild, idx = 0;



                    while (node) {

                        if (node == container) {

                            return idx;

                        }



                        // Skip data-mce-type=bookmark nodes

                        if (node.nodeType != 1 || node.getAttribute('data-mce-type') != 'bookmark') {

                            idx++;

                        }



                        node = node.nextSibling;

                    }



                    return -1;

                }



                container = node = bookmark[start ? 'startContainer' : 'endContainer'];

                offset = bookmark[start ? 'startOffset' : 'endOffset'];



                if (!container) {

                    return;

                }



                if (container.nodeType == 1) {

                    offset = nodeIndex(container);

                    container = container.parentNode;

                    dom.remove(node);

                }



                bookmark[start ? 'startContainer' : 'endContainer'] = container;

                bookmark[start ? 'startOffset' : 'endOffset'] = offset;

            }



            restoreEndPoint(true);

            restoreEndPoint();



            var rng = dom.createRng();



            rng.setStart(bookmark.startContainer, bookmark.startOffset);



            if (bookmark.endContainer) {

                rng.setEnd(bookmark.endContainer, bookmark.endOffset);

            }



            selection.setRng(rng);

        }



        function createNewTextBlock(contentNode, blockName) {

            var node, textBlock, fragment = dom.createFragment(), hasContentNode;

            var blockElements = editor.schema.getBlockElements();



            if (editor.settings.forced_root_block) {

                blockName = blockName || editor.settings.forced_root_block;

            }



            if (blockName) {

                textBlock = dom.create(blockName);



                if (textBlock.tagName === editor.settings.forced_root_block) {

                    dom.setAttribs(textBlock, editor.settings.forced_root_block_attrs);

                }



                fragment.appendChild(textBlock);

            }



            if (contentNode) {

                while ((node = contentNode.firstChild)) {

                    var nodeName = node.nodeName;



                    if (!hasContentNode && (nodeName != 'SPAN' || node.getAttribute('data-mce-type') != 'bookmark')) {

                        hasContentNode = true;

                    }



                    if (blockElements[nodeName]) {

                        fragment.appendChild(node);

                        textBlock = null;

                    } else {

                        if (blockName) {

                            if (!textBlock) {

                                textBlock = dom.create(blockName);

                                fragment.appendChild(textBlock);

                            }



                            textBlock.appendChild(node);

                        } else {

                            fragment.appendChild(node);

                        }

                    }

                }

            }



            if (!editor.settings.forced_root_block) {

                fragment.appendChild(dom.create('br'));

            } else {

                // BR is needed in empty blocks on non IE browsers

                if (!hasContentNode && (!tinymce.Env.ie || tinymce.Env.ie > 10)) {

                    textBlock.appendChild(dom.create('br', {'data-mce-bogus': '1'}));

                }

            }



            return fragment;

        }



        function getSelectedListItems() {

            return tinymce.grep(selection.getSelectedBlocks(), function (block) {

                return /^(LI|DT|DD)$/.test(block.nodeName);

            });

        }



        function splitList(ul, li, newBlock) {

            var tmpRng, fragment, bookmarks, node;



            function removeAndKeepBookmarks(targetNode) {

                tinymce.each(bookmarks, function (node) {

                    targetNode.parentNode.insertBefore(node, li.parentNode);

                });



                dom.remove(targetNode);

            }



            bookmarks = dom.select('span[data-mce-type="bookmark"]', ul);

            newBlock = newBlock || createNewTextBlock(li);

            tmpRng = dom.createRng();

            tmpRng.setStartAfter(li);

            tmpRng.setEndAfter(ul);

            fragment = tmpRng.extractContents();



            for (node = fragment.firstChild; node; node = node.firstChild) {

                if (node.nodeName == 'LI' && dom.isEmpty(node)) {

                    dom.remove(node);

                    break;

                }

            }



            if (!dom.isEmpty(fragment)) {

                dom.insertAfter(fragment, ul);

            }



            dom.insertAfter(newBlock, ul);



            if (isEmpty(li.parentNode)) {

                removeAndKeepBookmarks(li.parentNode);

            }



            dom.remove(li);



            if (isEmpty(ul)) {

                dom.remove(ul);

            }

        }



        var shouldMerge = function (listBlock, sibling) {

            var targetStyle = editor.dom.getStyle(listBlock, 'list-style-type', true);

            var style = editor.dom.getStyle(sibling, 'list-style-type', true);

            return targetStyle === style;

        };



        function mergeWithAdjacentLists(listBlock) {

            var sibling, node;



            sibling = listBlock.nextSibling;

            if (sibling && isListNode(sibling) && sibling.nodeName == listBlock.nodeName && shouldMerge(listBlock, sibling)) {

                while ((node = sibling.firstChild)) {

                    listBlock.appendChild(node);

                }



                dom.remove(sibling);

            }



            sibling = listBlock.previousSibling;

            if (sibling && isListNode(sibling) && sibling.nodeName == listBlock.nodeName && shouldMerge(listBlock, sibling)) {

                while ((node = sibling.firstChild)) {

                    listBlock.insertBefore(node, listBlock.firstChild);

                }



                dom.remove(sibling);

            }

        }



        /**
         
         * Normalizes the all lists in the specified element.
         
         */

        function normalizeList(element) {

            tinymce.each(tinymce.grep(dom.select('ol,ul', element)), function (ul) {

                var sibling, parentNode = ul.parentNode;



                // Move UL/OL to previous LI if it's the only child of a LI

                if (parentNode.nodeName == 'LI' && parentNode.firstChild == ul) {

                    sibling = parentNode.previousSibling;

                    if (sibling && sibling.nodeName == 'LI') {

                        sibling.appendChild(ul);



                        if (isEmpty(parentNode)) {

                            dom.remove(parentNode);

                        }

                    }

                }



                // Append OL/UL to previous LI if it's in a parent OL/UL i.e. old HTML4

                if (isListNode(parentNode)) {

                    sibling = parentNode.previousSibling;

                    if (sibling && sibling.nodeName == 'LI') {

                        sibling.appendChild(ul);

                    }

                }

            });

        }



        function outdent(li) {

            var ul = li.parentNode, ulParent = ul.parentNode, newBlock;



            function removeEmptyLi(li) {

                if (isEmpty(li)) {

                    dom.remove(li);

                }

            }



            if (isEditorBody(ul)) {

                return true;

            }



            if (li.nodeName == 'DD') {

                dom.rename(li, 'DT');

                return true;

            }



            if (isFirstChild(li) && isLastChild(li)) {

                if (ulParent.nodeName == "LI") {

                    dom.insertAfter(li, ulParent);

                    removeEmptyLi(ulParent);

                    dom.remove(ul);

                } else if (isListNode(ulParent)) {

                    dom.remove(ul, true);

                } else {

                    ulParent.insertBefore(createNewTextBlock(li), ul);

                    dom.remove(ul);

                }



                return true;

            } else if (isFirstChild(li)) {

                if (ulParent.nodeName == "LI") {

                    dom.insertAfter(li, ulParent);

                    li.appendChild(ul);

                    removeEmptyLi(ulParent);

                } else if (isListNode(ulParent)) {

                    ulParent.insertBefore(li, ul);

                } else {

                    ulParent.insertBefore(createNewTextBlock(li), ul);

                    dom.remove(li);

                }



                return true;

            } else if (isLastChild(li)) {

                if (ulParent.nodeName == "LI") {

                    dom.insertAfter(li, ulParent);

                } else if (isListNode(ulParent)) {

                    dom.insertAfter(li, ul);

                } else {

                    dom.insertAfter(createNewTextBlock(li), ul);

                    dom.remove(li);

                }



                return true;

            }



            if (ulParent.nodeName == 'LI') {

                ul = ulParent;

                newBlock = createNewTextBlock(li, 'LI');

            } else if (isListNode(ulParent)) {

                newBlock = createNewTextBlock(li, 'LI');

            } else {

                newBlock = createNewTextBlock(li);

            }



            splitList(ul, li, newBlock);

            normalizeList(ul.parentNode);



            return true;

        }



        function indent(li) {

            var sibling, newList, listStyle;



            function mergeLists(from, to) {

                var node;



                if (isListNode(from)) {

                    while ((node = li.lastChild.firstChild)) {

                        to.appendChild(node);

                    }



                    dom.remove(from);

                }

            }



            if (li.nodeName == 'DT') {

                dom.rename(li, 'DD');

                return true;

            }



            sibling = li.previousSibling;



            if (sibling && isListNode(sibling)) {

                sibling.appendChild(li);

                return true;

            }



            if (sibling && sibling.nodeName == 'LI' && isListNode(sibling.lastChild)) {

                sibling.lastChild.appendChild(li);

                mergeLists(li.lastChild, sibling.lastChild);

                return true;

            }



            sibling = li.nextSibling;



            if (sibling && isListNode(sibling)) {

                sibling.insertBefore(li, sibling.firstChild);

                return true;

            }



            /*if (sibling && sibling.nodeName == 'LI' && isListNode(li.lastChild)) {
             
             return false;
             
             }*/



            sibling = li.previousSibling;

            if (sibling && sibling.nodeName == 'LI') {

                newList = dom.create(li.parentNode.nodeName);

                listStyle = dom.getStyle(li.parentNode, 'listStyleType');

                if (listStyle) {

                    dom.setStyle(newList, 'listStyleType', listStyle);

                }

                sibling.appendChild(newList);

                newList.appendChild(li);

                mergeLists(li.lastChild, newList);

                return true;

            }



            return false;

        }



        function indentSelection() {

            var listElements = getSelectedListItems();



            if (listElements.length) {

                var bookmark = createBookmark(selection.getRng(true));



                for (var i = 0; i < listElements.length; i++) {

                    if (!indent(listElements[i]) && i === 0) {

                        break;

                    }

                }



                moveToBookmark(bookmark);

                editor.nodeChanged();



                return true;

            }

        }



        function outdentSelection() {

            var listElements = getSelectedListItems();



            if (listElements.length) {

                var bookmark = createBookmark(selection.getRng(true));

                var i, y, root = editor.getBody();



                i = listElements.length;

                while (i--) {

                    var node = listElements[i].parentNode;



                    while (node && node != root) {

                        y = listElements.length;

                        while (y--) {

                            if (listElements[y] === node) {

                                listElements.splice(i, 1);

                                break;

                            }

                        }



                        node = node.parentNode;

                    }

                }



                for (i = 0; i < listElements.length; i++) {

                    if (!outdent(listElements[i]) && i === 0) {

                        break;

                    }

                }



                moveToBookmark(bookmark);

                editor.nodeChanged();



                return true;

            }

        }



        function applyList(listName, detail) {

            var rng = selection.getRng(true), bookmark, listItemName = 'LI';



            if (dom.getContentEditable(selection.getNode()) === "false") {

                return;

            }



            listName = listName.toUpperCase();



            if (listName == 'DL') {

                listItemName = 'DT';

            }



            function getSelectedTextBlocks() {

                var textBlocks = [], root = editor.getBody();



                function getEndPointNode(start) {

                    var container, offset;



                    container = rng[start ? 'startContainer' : 'endContainer'];

                    offset = rng[start ? 'startOffset' : 'endOffset'];



                    // Resolve node index

                    if (container.nodeType == 1) {

                        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;

                    }



                    while (container.parentNode != root) {

                        if (isTextBlock(container)) {

                            return container;

                        }



                        if (/^(TD|TH)$/.test(container.parentNode.nodeName)) {

                            return container;

                        }



                        container = container.parentNode;

                    }



                    return container;

                }



                var startNode = getEndPointNode(true);

                var endNode = getEndPointNode();

                var block, siblings = [];



                for (var node = startNode; node; node = node.nextSibling) {

                    siblings.push(node);



                    if (node == endNode) {

                        break;

                    }

                }



                tinymce.each(siblings, function (node) {

                    if (isTextBlock(node)) {

                        textBlocks.push(node);

                        block = null;

                        return;

                    }



                    if (dom.isBlock(node) || isBr(node)) {

                        if (isBr(node)) {

                            dom.remove(node);

                        }



                        block = null;

                        return;

                    }



                    var nextSibling = node.nextSibling;

                    if (tinymce.dom.BookmarkManager.isBookmarkNode(node)) {

                        if (isTextBlock(nextSibling) || (!nextSibling && node.parentNode == root)) {

                            block = null;

                            return;

                        }

                    }



                    if (!block) {

                        block = dom.create('p');

                        node.parentNode.insertBefore(block, node);

                        textBlocks.push(block);

                    }



                    block.appendChild(node);

                });



                return textBlocks;

            }



            bookmark = createBookmark(rng);



            tinymce.each(getSelectedTextBlocks(), function (block) {

                var listBlock, sibling;



                var hasCompatibleStyle = function (sib) {

                    var sibStyle = dom.getStyle(sib, 'list-style-type');

                    var detailStyle = detail ? detail['list-style-type'] : '';



                    detailStyle = detailStyle === null ? '' : detailStyle;



                    return sibStyle === detailStyle;

                };



                sibling = block.previousSibling;

                if (sibling && isListNode(sibling) && sibling.nodeName == listName && hasCompatibleStyle(sibling)) {

                    listBlock = sibling;

                    block = dom.rename(block, listItemName);

                    sibling.appendChild(block);

                } else {

                    listBlock = dom.create(listName);

                    block.parentNode.insertBefore(listBlock, block);

                    listBlock.appendChild(block);

                    block = dom.rename(block, listItemName);

                }



                updateListStyle(listBlock, detail);

                mergeWithAdjacentLists(listBlock);

            });



            moveToBookmark(bookmark);

        }



        var updateListStyle = function (el, detail) {

            dom.setStyle(el, 'list-style-type', detail ? detail['list-style-type'] : null);

        };



        function removeList() {

            var bookmark = createBookmark(selection.getRng(true)), root = editor.getBody();



            tinymce.each(getSelectedListItems(), function (li) {

                var node, rootList;



                if (isEditorBody(li.parentNode)) {

                    return;

                }



                if (isEmpty(li)) {

                    outdent(li);

                    return;

                }



                for (node = li; node && node != root; node = node.parentNode) {

                    if (isListNode(node)) {

                        rootList = node;

                    }

                }



                splitList(rootList, li);

            });



            moveToBookmark(bookmark);

        }



        function toggleList(listName, detail) {

            var parentList = dom.getParent(selection.getStart(), 'OL,UL,DL');



            if (isEditorBody(parentList)) {

                return;

            }



            if (parentList) {

                if (parentList.nodeName == listName) {

                    removeList(listName);

                } else {

                    var bookmark = createBookmark(selection.getRng(true));

                    updateListStyle(parentList, detail);

                    mergeWithAdjacentLists(dom.rename(parentList, listName));



                    moveToBookmark(bookmark);

                }

            } else {

                applyList(listName, detail);

            }

        }



        function queryListCommandState(listName) {

            return function () {

                var parentList = dom.getParent(editor.selection.getStart(), 'UL,OL,DL');



                return parentList && parentList.nodeName == listName;

            };

        }



        function isBogusBr(node) {

            if (!isBr(node)) {

                return false;

            }



            if (dom.isBlock(node.nextSibling) && !isBr(node.previousSibling)) {

                return true;

            }



            return false;

        }



        self.backspaceDelete = function (isForward) {

            function findNextCaretContainer(rng, isForward) {

                var node = rng.startContainer, offset = rng.startOffset;

                var nonEmptyBlocks, walker;



                if (node.nodeType == 3 && (isForward ? offset < node.data.length : offset > 0)) {

                    return node;

                }



                nonEmptyBlocks = editor.schema.getNonEmptyElements();

                if (node.nodeType == 1) {

                    node = tinymce.dom.RangeUtils.getNode(node, offset);

                }



                walker = new tinymce.dom.TreeWalker(node, editor.getBody());



                // Delete at <li>|<br></li> then jump over the bogus br

                if (isForward) {

                    if (isBogusBr(node)) {

                        walker.next();

                    }

                }



                while ((node = walker[isForward ? 'next' : 'prev2']())) {

                    if (node.nodeName == 'LI' && !node.hasChildNodes()) {

                        return node;

                    }



                    if (nonEmptyBlocks[node.nodeName]) {

                        return node;

                    }



                    if (node.nodeType == 3 && node.data.length > 0) {

                        return node;

                    }

                }

            }



            function mergeLiElements(fromElm, toElm) {

                var node, listNode, ul = fromElm.parentNode;



                if (!isChildOfBody(fromElm) || !isChildOfBody(toElm)) {

                    return;

                }



                if (isListNode(toElm.lastChild)) {

                    listNode = toElm.lastChild;

                }



                if (ul == toElm.lastChild) {

                    if (isBr(ul.previousSibling)) {

                        dom.remove(ul.previousSibling);

                    }

                }



                node = toElm.lastChild;

                if (node && isBr(node) && fromElm.hasChildNodes()) {

                    dom.remove(node);

                }



                if (isEmpty(toElm, true)) {

                    dom.$(toElm).empty();

                }



                if (!isEmpty(fromElm, true)) {

                    while ((node = fromElm.firstChild)) {

                        toElm.appendChild(node);

                    }

                }



                if (listNode) {

                    toElm.appendChild(listNode);

                }



                dom.remove(fromElm);



                if (isEmpty(ul) && !isEditorBody(ul)) {

                    dom.remove(ul);

                }

            }



            if (selection.isCollapsed()) {

                var li = dom.getParent(selection.getStart(), 'LI'), ul, rng, otherLi;



                if (li) {

                    ul = li.parentNode;

                    if (isEditorBody(ul) && dom.isEmpty(ul)) {

                        return true;

                    }



                    rng = selection.getRng(true);

                    otherLi = dom.getParent(findNextCaretContainer(rng, isForward), 'LI');



                    if (otherLi && otherLi != li) {

                        var bookmark = createBookmark(rng);



                        if (isForward) {

                            mergeLiElements(otherLi, li);

                        } else {

                            mergeLiElements(li, otherLi);

                        }



                        moveToBookmark(bookmark);



                        return true;

                    } else if (!otherLi) {

                        if (!isForward && removeList(ul.nodeName)) {

                            return true;

                        }

                    }

                }

            }

        };



        editor.on('BeforeExecCommand', function (e) {

            var cmd = e.command.toLowerCase(), isHandled;



            if (cmd == "indent") {

                if (indentSelection()) {

                    isHandled = true;

                }

            } else if (cmd == "outdent") {

                if (outdentSelection()) {

                    isHandled = true;

                }

            }



            if (isHandled) {

                editor.fire('ExecCommand', {command: e.command});

                e.preventDefault();

                return true;

            }

        });



        editor.addCommand('InsertUnorderedList', function (ui, detail) {

            toggleList('UL', detail);

        });



        editor.addCommand('InsertOrderedList', function (ui, detail) {

            toggleList('OL', detail);

        });



        editor.addCommand('InsertDefinitionList', function (ui, detail) {

            toggleList('DL', detail);

        });



        editor.addQueryStateHandler('InsertUnorderedList', queryListCommandState('UL'));

        editor.addQueryStateHandler('InsertOrderedList', queryListCommandState('OL'));

        editor.addQueryStateHandler('InsertDefinitionList', queryListCommandState('DL'));



        editor.on('keydown', function (e) {

            // Check for tab but not ctrl/cmd+tab since it switches browser tabs

            if (e.keyCode != 9 || tinymce.util.VK.metaKeyPressed(e)) {

                return;

            }



            if (editor.dom.getParent(editor.selection.getStart(), 'LI,DT,DD')) {

                e.preventDefault();



                if (e.shiftKey) {

                    outdentSelection();

                } else {

                    indentSelection();

                }

            }

        });

    });



    editor.addButton('indent', {

        icon: 'indent',

        title: 'Increase indent',

        cmd: 'Indent',

        onPostRender: function () {

            var ctrl = this;



            editor.on('nodechange', function () {

                var blocks = editor.selection.getSelectedBlocks();

                var disable = false;



                for (var i = 0, l = blocks.length; !disable && i < l; i++) {

                    var tag = blocks[i].nodeName;



                    disable = (tag == 'LI' && isFirstChild(blocks[i]) || tag == 'UL' || tag == 'OL' || tag == 'DD');

                }



                ctrl.disabled(disable);

            });

        }

    });



    editor.on('keydown', function (e) {

        if (e.keyCode == tinymce.util.VK.BACKSPACE) {

            if (self.backspaceDelete()) {

                e.preventDefault();

            }

        } else if (e.keyCode == tinymce.util.VK.DELETE) {

            if (self.backspaceDelete(true)) {

                e.preventDefault();

            }

        }

    });

});