石墨文档快捷格式插件

石墨文档快捷键格式应用,点击左下角小窗口来使用

目前为 2021-02-08 提交的版本。查看 最新版本

// ==UserScript==
// @name         石墨文档快捷格式插件
// @namespace    QQ421566927
// @version      0.1
// @description  石墨文档快捷键格式应用,点击左下角小窗口来使用
// @resource     layuiCss https://www.layuicdn.com/layui-v2.5.7/css/layui.css
// @resource     layDate https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/css/modules/laydate/default/laydate.css?v=5.0.9
// @resource     layerCss https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/css/modules/layer/default/layer.css?v=3.1.1
// @resource     codeCss https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/css/modules/code.css
// @require      https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/layui.all.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/mousetrap/1.6.5/mousetrap.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/mousetrap/1.6.5/plugins/record/mousetrap-record.min.js
// @require      https://cdn.bootcss.com/store.js/1.3.20/store.min.js
// @match        https://shimo.im/docs/*
// @grant        GM_log
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceURL

// ==/UserScript==
    (function() {
      'use strict';

      var defaultData = [
        {
          "key": "shimo_format_1",
          "value": {
            "name": "默认黑字",
            "content":"",
            "format": "<span class=\"ql-author-45317226\" style=\"color: rgb(0, 0, 0);color: #000000;\">预览</span>",
            "hotkey": "ctrl+0",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_2",
          "value": {
            "name": "红字删除线",
            "content":"",
            "format": "<s style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</s>",
            "hotkey": "ctrl+1",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_3",
          "value": {
            "name": "蓝字加粗",
            "content":"",
            "format": "<strong style=\"color: rgb(25, 67, 156);color: #19439c;\">预览</strong>",
            "hotkey": "ctrl+2",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_4",
          "value": {
            "name": "绿字加粗",
            "content":"",
            "format": "<strong style=\"color: rgb(28, 114, 49);color: #1c7231;\">预览</strong>",
            "hotkey": "ctrl+3",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_5",
          "value": {
            "name": "①",
            "content":"①",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+1",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_6",
          "value": {
            "name": "②",
            "content":"②",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+2",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_7",
          "value": {
            "name": "③",
            "content":"③",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+3",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_8",
          "value": {
            "name": "④",
            "content":"④",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+4",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_9",
          "value": {
            "name": "⑤",
            "content":"⑤",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+5",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_10",
          "value": {
            "name": "⑥",
            "content":"⑥",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+6",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_11",
          "value": {
            "name": "⑦",
            "content":"⑦",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+7",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_12",
          "value": {
            "name": "⑧",
            "content":"⑧",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+8",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_13",
          "value": {
            "name": "⑨",
            "content":"⑨",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+9",
            "isDefault": true
          }
        },
        {
          "key": "shimo_format_14",
          "value": {
            "name": "⑩",
            "content":"⑩",
            "format": "<strong style=\"color: rgb(255, 0, 0);color: #ff0000;\">预览</strong>",
            "hotkey": "alt+0",
            "isDefault": true
          }
        }
      ]

      var layuiCss_CssSrc = GM_getResourceText ("layuiCss");
      var layDate_CssSrc = GM_getResourceText ("layDate");
      var layerCss_CssSrc = GM_getResourceText ("layerCss");
      var codeCss_CssSrc = GM_getResourceText ("codeCss");
      GM_addStyle (layuiCss_CssSrc);
      GM_addStyle (layDate_CssSrc);
      GM_addStyle (layerCss_CssSrc);
      GM_addStyle (codeCss_CssSrc);

      var style = document.createElement("style");
      style.type = "text/css";
      var text = document.createTextNode(".layui-layer-ico{background: url('https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/css/modules/layer/default/icon.png') no-repeat;}@font-face {font-family: layui-icon;src: url('https://www.layuicdn.com/layui-v2.5.7/font/iconfont.eot?v=256');src: url('https://www.layuicdn.com/layui-v2.5.7/font/iconfont.eot?v=256#iefix') format('embedded-opentype'),url('https://www.layuicdn.com/layui-v2.5.7/font/iconfont.woff2?v=256') format('woff2'),url('https://www.layuicdn.com/layui-v2.5.7/font/iconfont.woff?v=256') format('woff'),url('https://www.layuicdn.com/layui-v2.5.7/font/iconfont.ttf?v=256')format('truetype'),url('https://www.layuicdn.com/layui-v2.5.7/font/iconfont.svg?v=256#layui-icon') format('svg')}");
      style.appendChild(text);
      var head = document.getElementsByTagName("head")[0];
      head.appendChild(style);

      //全局变量
      var canCopy = false
      var tempNumber = 0
      var isRecord = false
      var hotKeyList = []
      var keyPrefix = 'shimo_format_'
      var isPaste = false


      var getRecordData = function () {
        var formatData = []

        if(!store.get(keyPrefix+'1')){
          defaultData.forEach(function (item) {
            store.set(item.key, item.value)
          })
        }

        store.forEach(function(key, val) {
          if(key.indexOf(keyPrefix) != -1){
            val.number = key.split('_')[2]
            formatData[val.number] = val
            if(val.hotkey != ''){
              hotKeyList[val.hotkey] = val
            }
          }
        })
        return formatData
      }

      var setRecordData = function (number,name,content,format,hotkey,isDefault) {
        var formatData = {
          name:name,
          content:content,
          format:format,
          hotkey:hotkey,
          isDefault:isDefault
        }
        store.set(keyPrefix+number, formatData)
      }

      var getInsertNumber = function () {
        var numberList = []

        store.forEach(function(key, val) {
          if(key.indexOf(keyPrefix) != -1){
            var splitRes = key.split('_')
            if(splitRes.length == 3){
              numberList.push(splitRes[2])
            }
          }
        })

        if(numberList.length > 0){
          var n = Math.max.apply(null, numberList);
          return n + 1
        }else{
          return 1
        }
      }

      var getBaseRowData = function (item) {
        var row =  '<div name="p_data_row_'+item.number+'" isdefault="'+item.isDefault+'" class="layui-row" style="font-size: 16px;margin-left:-160px;padding-left: 50px;">\n' +
          '    <div class="layui-col-sm2">\n' +
          '     &nbsp;'  +
          '    </div>\n' +
          '    <div class="layui-col-sm1" style="text-align: right;">\n' +
          '     名称:'  +
          '    </div>\n' +
          '    <div class="layui-col-sm2">\n' +
          '       <input type="text" style="width: 90px;" value="'+item.name+'" name="p_data_name" autocomplete="off" placeholder="请输入名称" class="layui-input-inline">\n' +
          '    </div>\n' +
          '    <div class="layui-col-sm1" style="text-align: center;margin-left:-30px;">\n' +
          '        <a name="p_data_record" href="javascript:void(0)"><i class="layui-icon layui-icon-radio" style="font-size: 19px; color: #1E9FFF;padding-top: 3px"></i></a>\n' +
          '    </div>\n' +
          '    <div class="layui-col-sm1">\n' +
          '        <span name="p_data_preview">'+item.format+'</span>\n' +
          '    </div>\n' +
          '    <div class="layui-col-sm2">\n' +
          '       <input type="text" style="width: 90px;" value="'+item.content+'" name="p_data_content" autocomplete="off" placeholder="请输入内容" class="layui-input-inline">\n' +
          '    </div>\n' +
          '    <div class="layui-col-sm2" name="p_data_quike" style="padding-top: 2px;">\n' +
          '        <input  style="width: 130px;font-size: 16px;" value="'+item.hotkey+'"  type="text" name="title" lay-verify="title" autocomplete="off" placeholder="录制快捷键" class="layui-input-inline" disabled>\n' +
          '    </div>\n' +
          '    <div class="layui-col-sm1" style="padding-left: 40px;">\n' +
          '        <a name="p_data_del" href="javascript:void(0)"><i class="layui-icon layui-icon-delete" style="font-size: 19px; color: #1E9FFF;padding-top: 3px"></i></a>\n' +
          '    </div>\n' +
          '</div>'

        return row

      }

      var render = function () {
        var htmlStr = ''
        var addDataButton = '<div class="layui-col-md12" style="text-align: center;margin-top: 4%"><button name="p_data_add_button" type="button" style="background-color: #5c5c5c;" class="layui-btn"><i class="layui-icon">&#xe608;</i> 添加</button></div>'
        var dataRes = getRecordData()

        dataRes.forEach(function (item) {
          var tempHtml = getBaseRowData(item)
          htmlStr += tempHtml
        })
        htmlStr += addDataButton
        return htmlStr
      }

      var getRowNum = function(el){
        var prent = $(el).parents('div[name^="p_data_row_"]')
        var num = prent.attr('name').split('_')[3]
        return num
      }

      //记忆窗口
      var setWindow = function(layero,type){
        var top = $(layero).css('top').replace('px','')
        var left = $(layero).css('left').replace('px','')
        var height = $(layero).css('height').replace('px','')
        var width = $(layero).css('width').replace('px','')

        if(type == 'moveWindow'){
          store.set('layer_window_top',parseInt(top) == 0 ? 1 : parseInt(top))
          store.set('layer_window_left',parseInt(left) == 0 ? 1 : parseInt(left))
        }

        if(type == 'reSize'){
          store.set('layer_window_height',height)
          store.set('layer_window_width',width)
        }
      }

      layui.use('layer', function(){
        var $ = layui.jquery
        var active = {
          setTop: function(firstOpen = false){
            var that = this;
            //多窗口模式,层叠置顶
            var top = store.get('layer_window_top')  ?  store.get('layer_window_top') : '280'
            var left = store.get('layer_window_left')  ?  store.get('layer_window_left') : '900'
            var width = store.get('layer_window_width') ? store.get('layer_window_width')+'px' : '700px'
            var height = store.get('layer_window_height') ? store.get('layer_window_height')+'px' : '530px'
            layer.open({
              id:'p_data_all'
              ,type: 1 //此处以iframe举例
              ,title: '快捷格式插件'
              ,area: [ width,height]
              ,shade: 0
              ,maxmin: true
              ,closeBtn: false
              ,offset: [
                top
                ,left
              ]
              ,content: render()
              ,yes: function(){
                $(that).click();
              }
              ,btn2: function(){
                layer.closeAll();
              }
              ,zIndex: layer.zIndex
              ,success: function(layero){
                layer.setTop(layero);
                if(firstOpen){
                  setTimeout(function () {
                    $('.layui-layer-min').click()
                  },1000)
                }
              },
              moveEnd: function(layero){
                setWindow(layero,'moveWindow')
              },
              resizing: function(layero){
                setWindow(layero,'reSize');
              },
            });
          },
          msg:function (msg) {
            layer.msg(msg)
          }
        };
        active.setTop(true)

        //监听部分
        //添加按钮
        $(document).on('click',':button[name="p_data_add_button"]',function () {
          var number =  getInsertNumber()
          setRecordData(number,'','','预览','',false)
          $('#p_data_all').html(render())
        })

        //名称输入框监听
        $(document).on('blur',':input[name="p_data_name"]',function () {
          var input_name = $(this).val()
          var num = getRowNum(this)
          var cur = store.get(keyPrefix+num)
          setRecordData(num,input_name,cur.content,cur.format,cur.hotkey,cur.isDefault)
          layer.msg('保存成功',{zIndex:layer.zIndex})
        })

        //内容输入框监听
        $(document).on('blur',':input[name="p_data_content"]',function () {
          var input_content = $(this).val()
          var num = getRowNum(this)
          var cur = store.get(keyPrefix+num)
          setRecordData(num,cur.name,input_content,cur.format,cur.hotkey,cur.isDefault)
          layer.msg('保存成功',{zIndex:layer.zIndex})
        })

        //录制
        $(document).on('click','a[name="p_data_record"]',function () {
          canCopy = true
          tempNumber  = getRowNum(this)
          layer.msg('请选中文本格式后使用 Ctrl+C 写入格式',{zIndex:layer.zIndex})
        })

        //快捷键
        $(document).on('click','div[name="p_data_quike"]',function () {
          isRecord = true
          layer.msg('请输入快捷键',{zIndex:layer.zIndex})
          tempNumber = getRowNum(this)
        })

        //删除
        $(document).on('click','a[name="p_data_del"]',function () {
          var prent = $(this).parents('div[name^="p_data_row_"]')
          if($(prent).attr('isdefault') == 'true'){
            layer.msg('默认配置不可删除!',{zIndex:layer.zIndex})
            return false;
          }
          var num = prent.attr('name').split('_')[3]
          store.remove(keyPrefix+num)
          $('#p_data_all').html(render())
          layer.msg('删除成功',{zIndex:layer.zIndex})
        })
      });

      document.addEventListener('paste', function (event) {
        if(isPaste){
          isPaste = false
          layer.msg('应用成功!',{zIndex:layer.zIndex})
        }
      })

      document.addEventListener('copy', function (event) {
        if(canCopy){
          var clipboardData = event.clipboardData || window.clipboardData;
          var res =  clipboardData.getData('text/html');
          canCopy = false
          var el = $($(res).children()[0])
          var elHtml = el.prop('innerHTML')
          if($(elHtml).length >1){
            elHtml = $($(elHtml)[0]).prop('outerHTML')
            elText = $($(elHtml)[0]).text()
          }else{
            var elText = $($(res).children()[0]).text()
          }
          var resHtml = elHtml.replace('>'+elText+'</','>预览</')

          var cur = store.get(keyPrefix+tempNumber)
          setRecordData(tempNumber,cur.name,cur.content,resHtml,cur.hotkey,cur.isDefault)
          $('#p_data_all').html(render())
          layer.msg('录制格式成功!',{zIndex:layer.zIndex})
        }
      });


      $(document).keydown(function(event){
        Mousetrap.record(function(sequence) {
          var keyStr = sequence.join(' ')

          if(keyStr == 'ctrl+shift+m'){
              store.remove('layer_window_top')
              store.remove('layer_window_left')
              store.remove('layer_window_height')
              store.remove('layer_window_width')
            layer.msg('重置窗口成功,请刷新页面',{zIndex:layer.zIndex})
          }

          if(isRecord){
            isRecord = false
            var num = tempNumber
            var cur = store.get(keyPrefix+num)
            let allData = getRecordData()
            let isRepeat = false;
            allData.forEach(function (item) {
              if(item.number != num && item.hotkey == keyStr){
                isRepeat = true
              }
            })

            if(isRepeat){
              layer.msg('错误!!快捷键已经存在!!! 快捷键:'+keyStr,{zIndex:layer.zIndex})
              return false;
            }

            setRecordData(num,cur.name,cur.content,cur.format,keyStr,cur.isDefault)
            $('#p_data_all').html(render())
            layer.msg('录制成功:'+keyStr,{zIndex:layer.zIndex})
          }else{
            if(hotKeyList[keyStr] != undefined){
              var item = hotKeyList[keyStr]
              var selection = window.getSelection() || document.getSelection() || document.selection.createRange();
              var selectionStr = selection.toString()
              if(item.content != ''){
                selectionStr = item.content
              }else if(selectionStr == ''){
                selectionStr = '&#65279;'
              }

              if(item.format == '预览'){
                var copyStr = selectionStr
              }else{
                var copyStr = item.format.replace('>预览</','>'+selectionStr+'</')
              }

              var originRange = selection.getRangeAt(0)

              // selection.deleteFromDocument()
              var beforeLast = $('body').children().last()
              var text = $(copyStr).appendTo('body')
              if (document.body.createTextRange) {
                var range = document.body.createTextRange();
                range.moveToElementText(text);
                range.select();
              } else if (window.getSelection) {
                var selection = window.getSelection();
                var range = document.createRange();
                range.selectNodeContents(text[0]);
                selection.removeAllRanges();
                selection.addRange(range);
              }

              document.execCommand('Copy','false',null);

              $(beforeLast).nextAll().remove()

              selection.removeAllRanges();
              selection.addRange(originRange)
              isPaste = true
              var tempStr = item.content != '' ? "内容:'"+item.content+"' 已复制" : '格式:'+item.name+'已处理完成'
              layer.msg(tempStr+',使用 Ctrl+V 应用',{zIndex:layer.zIndex})
            }

          }
        });
      });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址