Tinymce编辑器块级元素前后插入空行插件,解决无法跳出元素问题

原创
2021/04/30 13:15
阅读数 1.3K

编辑img h1 h2 h3 h4 h5 h6 pre table blockquote ul ol元素时,经常会遇到换行无法跳出元素,或无法在元素前或后写内容,所以写了一个插件用来在这些元素前后插入空行并设置焦点

配置

名称 默认 说明
blankline false 是否启用插件
blankline_merge false 设置自定义的blankline_tagmap标签,是否和默认合并使用
blankline_tagmap img h1 h2 h3 h4 h5 h6 pre music div>p>a>code>li>td>th>tr>table|blockquote|ul|ol 支持的tag标签,多个子标签请使用>分割,多个父标签请用|分割
blankline_keymap w s 配合Alt+快捷方式按键,默认Alt+w在上方插入,Alt+s在下方插入
blankline_tab false 是否将Tab键设置为制表符,作用域当前节点,类似首行缩进Shift+Tab撤回缩进

使用说明

默认键位情况:

使用快捷键Alt+w可以在元素上方插入空行,用来输入内容。

使用快捷键Alt+s可以在元素下方插入空行,用来输入内容。

使用快捷键Ctrl+z可以撤回插入的空行,这个是编辑器自带快捷方式

使用快捷键Tab可以使当前元素缩进。

使用快捷键Shift+Tab可以把使用Tab设置的缩进撤回。

安装说明

把插件代码保存到你的编辑器目录插件目录plugins/blankline/plugin(.min).js

然后在编辑器配置选项新增上面的配置即可

插件代码

(function () {
    'use strict';

    var tag = [], tagP = [];
    var defaultTag = 'img h1 h2 h3 h4 h5 h6 pre music div>p>a>code>li>td>th>tr>table|blockquote|ul|ol';

    var $ = tinymce.util.Tools.resolve('tinymce.dom.DomQuery');
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');

    var focus = function (editor, elem) {
        let range = editor.dom.createRng();
        range.selectNodeContents(elem);
        range.collapse(!1);
        editor.selection.setRng(range);
    }

    var mergeTags = function (data) {
        for(var i = 0; i < data.length; i++) {
            var v = data[i];
            if(v.indexOf('>') === -1) {
                tag.push(v);
            } else {
                tagP.push(v);
            }
        }
    }

    var getTagParent = function(arr, node) {
        var cNames = [], pName = '', pNames = [];
        for(var i = 0; i < arr.length; i++) {
            cNames = arr[i].split('>'), pName = cNames.pop();
            if(node.tagName && $.inArray(node.tagName, cNames) !== -1) {
                if(pName.indexOf('|') === -1) {
                    pNames.push(pName);
                } else {
                    pNames = pName.split('|');
                }
                if(pNames && pNames.length) {
                    for(var o = 0; o < pNames.length; o++) {
                        var pElem = $(node).parents(pNames[o]);
                        if(pElem.length) {
                            return pElem.slice(-1) || null;
                        }
                    }
                }
            }
        }
    }

	function Plugin () {
		global.add('blankline', function (editor) {

            var isOpen = editor.getParam('blankline', !1, 'boolean');
            if(!isOpen) {
                return !1;
            }

            var isMerge = editor.getParam('blankline_merge', !1, 'boolean');
            var _tagmap = editor.getParam('blankline_tagmap', defaultTag, 'string');
            var _keymap = editor.getParam('blankline_keymap', 'w s', 'string');

            if(!_tagmap || !_keymap) {
                return !1;
            }

            _tagmap = _tagmap.toUpperCase().split(' ');
            _keymap = _keymap.toUpperCase().split(' ');

            var beforeKey = 'Key' + _keymap[0];
            var afterKey = 'Key' + _keymap[1];

            mergeTags(_tagmap);

            if(isMerge) {
                mergeTags(defaultTag.toUpperCase().split(' '));
            }
            
            editor.on('init', function (e) {
                editor.on('keydown', function (e) {
                    if (e.altKey === !0 && (e.code == beforeKey || e.code == afterKey)) {
                        var _node = null;
                        var node = editor.selection.getNode();

                        // 无嵌套标签
                        if(node && $.inArray(node.tagName, tag) !== -1) {
                            _node = node;
                        }
                        
                        // 处理子标签嵌套
                        if(tagP.length) {
                            var _pp = getTagParent(tagP, node);
                            if(_pp) {
                                _node = _pp;
                            }
                        }

                        if(_node) {

                            var blank = $('<p><br /></p>')[0];

                            if(e.code == beforeKey) {
                                _node.before(blank);
                            } else {
                                _node.after(blank);
                            }
    
                            focus(editor, blank);
                            
                            e.preventDefault();
                            e.stopPropagation();
                        }
                    } else if (e.key == 'Tab') {
                        if (e.shiftKey) {
                            editor.execCommand('Outdent');
                        } else {
                            editor.execCommand('Indent');
                        }
    
                        e.preventDefault();
                        e.stopPropagation();
                    }
                });
            });
		});
	}

	Plugin();

}());
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部