富文本编辑器-资源模块

作者:root



export const res={
        /** 节点模板 */
        TP:{
            dropdown:{tag: "div",class:['ck','ck-dropdown']},
            panel_se:{tag:'div',class:['ck','ck-reset','ck-dropdown__panel','ck-dropdown__panel_se']},
            button:{tag: "button",attributes: {type:"button",tabindex:"-1"},class: ["ck","ck-button"]},
            label:{tag: "span",class: ["ck","ck-button__label"]},
            separator:{tag:'span',class: ["ck","ck-toolbar__separator"]},
            balloon:{tag:'div', class: ["ck", "ck-balloon-panel","ck-balloon-panel_with-arrow","ck-balloon-panel_visible","ck-toolbar-container"]},
            figcaption:{tag:'figcaption',class:['ck-editor__nested-editable'],attributes:{'contenteditable':true},children:{tag:'br'}},
            tooltip:{tag: "span",class: ["ck", "ck-tooltip","ck-tooltip_s"],children:{tag: "span",class: ["ck","ck-tooltip__text"]}},
            toolbar:{tag: "div",class: ["ck", "ck-toolbar"]},
            toolPanle:{tag:"div",attributes:{role:"application",dir:"ltr"},class: ["ck","ck-reset","ck-rounded-corners"],children:{tag: "div",attributes: {role:"presentation"},class: ["ck", "ck-editor__top","ck-reset_all"]}},
            toggle:{tag:"span",class:[,"ck-button__toggle"],children:{tag:"span",class:["ck","ck-button__toggle__inner"]}},
            td:{tag:"td",class:['ck-editor__editable','ck-editor__nested-editable'],children:{tag:"br"}},
            figure:{tag:"figure",class:["ck-widget","ck-widget_selectable"]},
            table:{tag:'table',children:{tag:'thead'}},
            input:{tag:'div',class:['ck','ck-labeled-input'],children:{tag:'input',attributes:{type:'text'},class:['ck','ck-input','ck-input-text']}},
        },
        icon:{
            /**下箭头图标 */
            v :'<svg class="ck ck-icon ck-dropdown__arrow" viewBox="0 0 10 10"><path d="M.941 4.523a.75.75 0 1 1 1.06-1.06l3.006 3.005 3.005-3.005a.75.75 0 1 1 1.06 1.06l-3.549 3.55a.75.75 0 0 1-1.168-.136L.941 4.523z"></path></svg>',
        },
        tag2cmd: {
            'b': 'bold',
            'strong': 'bold',
            'i': 'italic',
            'em': 'italic',
            'u': 'underline',
            'sup': 'superscript',
            'sub': 'subscript',
            'img': 'insertimage',
            'a' : 'createlink',
            'ul' : 'insertunorderedlist',
            'ol' : 'insertorderedlist'
        },
        remove_css:['ck-link_selected','ck-widget_selected'],
        extracss:'.ck.ck-icon {width: calc(1.84615*1em);height: calc(1.84615*1em);font-size: .8333350694em;}',
    }
export class btnCalss{
    constructor(o,s,e){
        this.name=s;
        this.hotkey=!1;
        this.button=!1;
        Object.assign(this,o);
        this.E=e;
        this.data=[];
    }
    createButton(){
        let lable=this.E.lang[this.name];
        this.hotkey&&(lable=this.E.lang[this.name]+` (CTRL+${this.hotkey})`);
        this.E.MOD.res.TP.tooltip.children.innerHTML=lable;
        let tooltip=this.E.UI(this.E.MOD.res.TP.tooltip);
        let n= Object.assign(this.E.MOD.res.TP.button,{children:[tooltip]});
        return this.E.UI(this.icon&&n.children.push(this.E.creatNode(this.icon)),n)
    }
    get getButton(){
        let n;
        if(this.name=='|')n=this.button=this.E.UI(this.E.MOD.res.TP.separator);else{
            n=this.button=this.createButton();
            this.E.DOClisten(n,{click:(n,e)=>{
                e.stopPropagation();
                if(n.classList.contains('ck-disabled')) return;
                this.E.btnExample.forEach((v)=>v.panel&&v.name!=this.name&&v.close());
                this.E.lastRange&&this.E.setRange(this.E.lastRange),
                this.command(n,e)
                this.switch||this.E.fire(this.E.editnode,'mouseup');
            }})
        }
        return this.panel&&(n=this.addpanel(n)),
            this.text&&this.addtext(this.button),
            this.other&&this.other(this.button),
            this.state&&this.changeState(this.button),
            this.class&&this.button.classList.add(this.class),
            this.disabled&&this.changeDisabled(this.button),n
    }
    changeDisabled(n){
        this.E.listenTo(n,{from:this.E.editnode,listen:'click',to:(k,e)=>{
            let ary,mixed=[];;
            e&&e.target&&(ary=[...this.E.domPathMap(e.target).keys()]);
            this.disabled.filter(v =>ary.includes(v)&&mixed.push(v))
            mixed.length?this.disabled_off(n):this.disabled_on(n)
        }})
    }
    command(n,e){
        this.panel?this.createPanel(n,e):(this.block&&this.E.SetRangeToBlock(this.block),document.execCommand(this.name,!1,!1),this.E.fire('savechange'))
    }
    changeState(n){
        this.E.listenTo(n,{from:this.E.editnode,listen:['mouseup','keyup'],to:()=>{
            let a =[];
            [...this.E.domPathMap().keys()].filter(i=>{
                this.E.MOD.res.tag2cmd.hasOwnProperty(i)?a.push(this.E.MOD.res.tag2cmd[i]):a.push(i)
            })
            a.includes(this.name)?this.btn_on(n):this.btn_off(n)
        }})
    }
    addtext(n){
        let i=this.E.UI({tag: "span",class: ["ck", "ck-button__label"],innerHTML:this.E.lang[this.name]}),
        fn=(n,e)=>{
            let a =this.text(n,e),b=[];
            Array.isArray(a)||(a=[a]);
            this.panel.list.filter(v =>a.includes(v)&&b.push(v)),
            b.length>0?this.E.flag[this.name]=b[0]:this.E.flag[this.name]=!1
        };
        n.insertBefore(i,n.firstChild),
        n.classList.add('ck-button_with-text'),
        this.bind&&(this.E.bind(this.name,i),
        this.E.listenTo(n,{from:this.E.editnode,listen:'mouseup',to:()=>fn()}),
        this.E.on('savechange',fn)
        )
    }
    addpanel(n){
        this.v&&n.appendChild(this.E.creatNode(this.E.MOD.res.icon['v']));
        n.classList.add('ck','ck-button','ck-dropdown__button')
        let p=this.panel_se=this.E.UI(this.E.MOD.res.TP.panel_se,{listenTo:{from:this.E.editnode,listen:'click',to:()=>this.close()}});
        p.onmouseleave=(e)=>this.close();
        return this.E.UI(this.E.MOD.res.TP.dropdown,{children:[n,p]})
    }
    createPanel(n,e){
        let u;
        if(this.panel&&this.panel.list){
            let css,tp=null,l,t,i;
            u=this.E.creatNode('<ul class="ck ck-reset ck-list">');
            for (let k of this.panel.list){
                if(k=='-')l=l=this.E.creatNode('<li class="ck ck-list__separator">');else{
                    Object.prototype.toString.call(k)==='[object Object]'?(css=k.css,tp=this.E.MOD.res.TP[k.tp],k=k.cmd):(css=`ck-${this.name}_${k}`);
                    l=this.E.creatNode('<li class="ck ck-list__item">');
                    t=l.appendChild(this.E.UI(this.E.MOD.res.TP.button,{
                            children:[[this.E.MOD.res.TP.label,{innerHTML:this.E.lang[k]||k}],tp],
                            listen:{click:(n,e)=>{i=this.onoff(n),this.E.flag[this.name]=k,this.panel.command.call(this,n,k,i),this.E.fire('savechange')}}
                        }));
                    t.classList.add(`ck-button_with-text`,css);
                    this.callback?this.callback(t,k,css):this.E.flag[this.name]==k&&this.btn_on(t);
                }
                u.appendChild(l);
            }
        }else if(typeof this.panel == 'function'){
            u=this.panel(n,e);
        }  
        return this.insertPanel(n,u);
    }
    insertPanel(n,s){
        this.data['panel']?this.close():
        (this.btn_on(n),this.panel_se.appendChild(s),this.panel_se.classList.add('ck-dropdown__panel-visible'),this.data['panel']=!0)
    }
    close(){
        this.btn_off();
        this.data['panel']=!1;
        this.panel_se.innerHTML='',this.panel_se.classList.remove('ck-dropdown__panel-visible')
    }
    btn_on(n){n=n||this.button;let c=n.classList;c.remove('ck-off'),c.add('ck-on')}
    btn_off(n){n=n||this.button;let c=n.classList;c.remove('ck-on'),c.add('ck-off')}
    onoff(n){
        n=n||this.button;
        if(n.classList.contains('ck-on')){
            return this.btn_off(n),false
        }else{
            return this.btn_on(n),true
        }     
    }
    disabled_on(n){n=n||this.button;n.classList.remove('ck-disabled')}
    disabled_off(n){n=n||this.button;n.classList.add('ck-disabled')}
}
export let bold={
    icon  :'<svg class="ck ck-icon ck-button__icon" viewBox="0 0 20 20"><path d="M10.187 17H5.773c-.637 0-1.092-.138-1.364-.415-.273-.277-.409-.718-.409-1.323V4.738c0-.617.14-1.062.419-1.332.279-.27.73-.406 1.354-.406h4.68c.69 0 1.288.041 1.793.124.506.083.96.242 1.36.478.341.197.644.447.906.75a3.262 3.262 0 0 1 .808 2.162c0 1.401-.722 2.426-2.167 3.075C15.05 10.175 16 11.315 16 13.01a3.756 3.756 0 0 1-2.296 3.504 6.1 6.1 0 0 1-1.517.377c-.571.073-1.238.11-2 .11zm-.217-6.217H7v4.087h3.069c1.977 0 2.965-.69 2.965-2.072 0-.707-.256-1.22-.768-1.537-.512-.319-1.277-.478-2.296-.478zM7 5.13v3.619h2.606c.729 0 1.292-.067 1.69-.2a1.6 1.6 0 0 0 .91-.765c.165-.267.247-.566.247-.897 0-.707-.26-1.176-.778-1.409-.519-.232-1.31-.348-2.375-.348H7z"></path></svg>',
    hotkey:'B',//热键
    block:1,//指令影响范围:1范围小,2范围大。
    state:true,//跟随焦点(鼠标点击)位置,显示按键状态。
    disabled:['img','code'],
}
export let italic={
    icon:'<svg class="ck ck-icon ck-button__icon" viewBox="0 0 20 20"><path d="M9.586 14.633l.021.004c-.036.335.095.655.393.962.082.083.173.15.274.201h1.474a.6.6 0 1 1 0 1.2H5.304a.6.6 0 0 1 0-1.2h1.15c.474-.07.809-.182 1.005-.334.157-.122.291-.32.404-.597l2.416-9.55a1.053 1.053 0 0 0-.281-.823 1.12 1.12 0 0 0-.442-.296H8.15a.6.6 0 0 1 0-1.2h6.443a.6.6 0 1 1 0 1.2h-1.195c-.376.056-.65.155-.823.296-.215.175-.423.439-.623.79l-2.366 9.347z"></path></svg>',
    hotkey:'I',
    block:1,
    state:true,
    disabled:['img','code'],
}
export let insertunorderedlist={
    icon:'<svg class="ck ck-icon ck-button__icon" viewBox="0 0 20 20"><path d="M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0C1 4.784 1.777 4 2.75 4c.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75C1.784 7.5 1 6.723 1 5.75zm6 9c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0c0-.966.777-1.75 1.75-1.75.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75-.966 0-1.75-.777-1.75-1.75z"></path></svg>',
    state:true,
    disabled:['img','table','code'],
}
export let insertorderedlist={
    icon:'<svg class="ck ck-icon ck-button__icon" viewBox="0 0 20 20"><path d="M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zM3.5 3v5H2V3.7H1v-1h2.5V3zM.343 17.857l2.59-3.257H2.92a.6.6 0 1 0-1.04 0H.302a2 2 0 1 1 3.995 0h-.001c-.048.405-.16.734-.333.988-.175.254-.59.692-1.244 1.312H4.3v1h-4l.043-.043zM7 14.75a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z"></path></svg>',
    state:true,
    disabled:['img','table','code'],
}
//self.close()