- // ==UserScript==
- // @name 石墨文档快捷格式插件
- // @namespace QQ421566927
- // @version 0.5
- // @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
- // @license MIT
- // ==/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); background-color: rgb(255, 255, 255);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' +
- ' ' +
- ' </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: 20px;">\n' +
- ' <a name="p_data_brush" href="javascript:void(0)"><i class="layui-icon layui-icon-fonts-clear" style="font-size: 19px; color: #1E9FFF;padding-top: 3px"></i></a>\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"></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)
- }
- }
-
- var replaceSelection = function(replaceText) {
- if (window.getSelection) {
- var selecter = window.getSelection();
- var range = selecter.getRangeAt(0);
- let textEl = document.createRange().createContextualFragment(replaceText).children;
- console.log(textEl)
- selecter.removeAllRanges()
- selecter.empty();
- range.deleteContents()
- range.insertNode(textEl[0]);
- } else if (document.selection) {//ie
- var selecter = document.selection.createRange();
- selecter.select();
- selecter.pasteHTML(replaceText);
- }
- }
-
-
- 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).on('click','a[name="p_data_brush"]',function () {
- let allData = getRecordData()
- var itemEl = $(this).parent().parent()
- var elIndex = ($('#p_data_all div').index(itemEl)/9)+1
- console.log(elIndex)
- layer.msg('请选中需要应用的文字',{zIndex:layer.zIndex})
- var brushOver = false
- //$textElem是指编辑器可编辑区域(详情请查看源码)
- $('div.ql-editor.notranslate').on('mouseup', e => {
- if(brushOver == false){
- brushOver = true
- // document.querySelector('.ql-clean.ql-toolbar-widget').click()
- var selection = window.getSelection() || document.getSelection() || document.selection.createRange();
- console.log(selection)
- console.log(selection.text)
- var item = allData[elIndex]
- if(item.content == ""){
- var selectionStr = window.getSelection().toString()
- }else{
- var strLen = window.getSelection().toString().length
- var selectionStr = ""
- for (var i=0;i<strLen;i++){
- selectionStr += item.content
- }
- }
- var copyStr = item.format.replace('>预览</','>'+selectionStr+'</')
- replaceSelection(copyStr)
- }
- })
- })
-
- });
-
- 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+'</','>预览</')
-
- if(elText == elHtml){
- resHtml = "<span class=\"ql-author-45317226\">预览</span>"
- }
-
- 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 = ''
- }
-
- if(item.format == '预览'){
- // var copyStr = selectionStr
- layer.msg(item.hotkey+' 还没有录制格式呢!',{zIndex:layer.zIndex})
- return false
- }else{
- var copyStr = item.format.replace('>预览</','>'+selectionStr+'</')
- }
-
- if (selection.rangeCount > 0) {
- var originRange = selection.getRangeAt(0);
- }else{
- var originRange = false;
- }
-
-
- var beforeLast = $('body').children().last()
- var text = $(copyStr).appendTo('body')
- console.log(text)
- 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();
- if(originRange){
- selection.addRange(originRange)
- }
- isPaste = true
- // var tempStr = item.content != '' ? "内容:'"+item.content+"' 已复制" : '格式:'+item.name+'已处理完成'
- // layer.msg(tempStr+',使用 Ctrl+V 应用',{zIndex:layer.zIndex})
-
- // document.querySelector('.ql-clean.ql-toolbar-widget').click()
- if(item.content == ""){
- var selectionStr = window.getSelection().toString()
- }else{
- var strLen = window.getSelection().toString().length
- var selectionStr = ""
- if(strLen == 0){
- strLen = 1
- }
- for (var i=0;i<strLen;i++){
- selectionStr += item.content
- }
- }
- var copyStr = item.format.replace('>预览</','>'+selectionStr+'</')
- console.log(copyStr)
- if(originRange){
- replaceSelection(copyStr)
- }
- layer.msg(item.name+' 快捷键格式应用成功!',{zIndex:layer.zIndex})
-
- //
- // if (selectStr.trim() != "") {
- //
- // }else{
- // var tempStr = item.content != '' ? "内容:'"+item.content+"' 已复制" : '格式:'+item.name+'已处理完成'
- // layer.msg(tempStr+',使用 Ctrl+V 应用',{zIndex:layer.zIndex})
- // }
-
- }
-
- }
- });
- });
- })();