// ==UserScript== // @name 绯月表情增强插件 // @namespace https://greasyfork.org/users/5415 // @version 4.2.2 // @author eddie32 // @description KF论坛专用的回复表情, 插图扩展插件, 在发帖时快速输入自定义表情和论坛BBCODE // @icon https://blog.nekohand.moe/favicon.ico // @homepage https://github.com/liu599/KF-Emotion-UserScript // @include https://*miaola.info/* // @include http://*2dkf.com/* // @include http://*9moe.com/* // @include http://*kfgal.com/* // @copyright 2014-2017, eddie32 // @grant none // @license MIT // @run-at document-end // @downloadURL none // ==/UserScript== 'use strict'; var fun = function fun() { var imgpath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; /* * KF Emotion UserScript * Author: eddie32 * Version: 4.2.1 * Change Log: Rewrite the code based on ES6 recommodation * Add hover:enlarge feature * User option storage locally * License: M.I.T * Publish Date: 2017.01.26 */ var versionNo = '4.2.0'; /* Address function * startNumber: number, indicating the start number; * lengthArray: number, indicating the addrArray length; * strPrefix: string, address Prefix; * strSuffix: string, address Suffix; * leadingZero: boolen, true for leading zero in number; * addrArray: array, address array, default for empty; */ // 创建表情包数组的函数 function emAddrArrayHandler(startNumber, lengthArray, strPrefix, strSuffix) { var addrArray = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : []; var leadingZero = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; var addrTemp = '', addrNumber = 0; for (var j = startNumber; j < lengthArray; j++) { addrNumber = j; if (leadingZero) { addrNumber = j > 9 ? j : '0' + j; } addrTemp = '' + strPrefix + addrNumber + strSuffix; addrArray.push(addrTemp); } return addrArray; } /* 表情包地址数据 */ // B站 var biliEM = emAddrArrayHandler(1, 17, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/EmCol/BiliBili/2233 (', ').gif'); emAddrArrayHandler(0, 14, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/EmCol/BiliBili/bilibiliTV (', ').png', biliEM); // tora酱 emAddrArrayHandler(1, 14, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/EmCol/tora/0', '.jpg', biliEM, true); //阿卡林 from 摇曳百合 var AkariSmile = emAddrArrayHandler(1, 21, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/EmCol/Dynamic/akari', '.gif'); emAddrArrayHandler(1, 72, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/EmCol/akari/akari', '.png', AkariSmile); // New Game kf扩展 var NewGame = emAddrArrayHandler(2, 64, 'http://nekohand.moe/spsmile/01Sora/0xx', '.png'); emAddrArrayHandler(1, 20, 'http://ss.nekohand.moe/Asource/EmotionPic/KFEM (', ').gif', NewGame); // ACFUN var ACSmile4 = emAddrArrayHandler(1, 51, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/EmCol/ACFUN/New/', '.png'); emAddrArrayHandler(1, 40, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/EmCol/ACFUN/Niming/', '.gif', ACSmile4, true); // KF 内置 var KFSmileURL = emAddrArrayHandler(1, 49, (typeof imgpath != 'undefined' ? imgpath : '') + '/post/smile/em/em', '.gif', [], true); var KFSmileCode = emAddrArrayHandler(10, 58, '[s:', ']'); // lovelive专用小 var LoveliveSmalltargetURL = emAddrArrayHandler(1, 41, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion02/Small/Lovelive2nd', '.png'); emAddrArrayHandler(1, 41, 'http://smile.nekohand.moe/blogAcc/LoveliveEmotion01/Small/Lovelive', '.png', LoveliveSmalltargetURL); // kf快捷代码(需要改写解构赋值) var functionDescription = ['出售贴sell=售价', '引用', '隐藏hide=神秘等级', '插入代码', '删除线', '跑马灯', '文字颜色', '粗体', '下划线', '斜体', '水平线', '背景色', '插入图片']; var defaultFunction = ['[sell=100][/sell]', '[quote][/quote]', '[hide=100][/hide]', '[code][/code]', '[strike][/strike]', '[fly][/fly]', '[color=#00FF00][/color]', '[b][/b]', '[u][/u]', '[i][/i]', '[hr]', '[backcolor=][/backcolor]', '[img][/img]']; // 颜文字 var emoji = ['(●・ 8 ・●)', '╰(๑◕ ▽ ◕๑)╯', '(ゝω・)', '〜♪♪', '(゚Д゚≡゚Д゚)', '(^o^)ノ', '(|||゚Д゚)', '(`ε´ )', '(╬゚д゚)', '(|||゚д゚)', '( ̄∇ ̄)', '( ̄3 ̄)', '( ̄ー ̄)', '( ̄ .  ̄)', '( ̄︿ ̄)', '( ̄︶ ̄)', '(*´ω`*)', '(・ω・)', '(⌒▽⌒)', '( ̄▽ ̄)', '(=・ω・=)', '(`・ω・´)', '(〜 ̄△ ̄)〜', '(・∀・)', '(°∀°)ノ', '( ̄3 ̄)', '╮( ̄▽ ̄)╭', '( ´_ゝ`)', 'のヮの', '(ノ؂< ๑)诶嘿☆~', '(<_<)', '(>_>)', '(;¬_¬)', '(▔□▔)/', '(゚Д゚≡゚д゚)!?', 'Σ(゚д゚;)', 'Σ(  ̄□ ̄||)', '(´;ω;`)', '(/TДT)/', '(^・ω・^ )', '(。・ω・。)', '(● ̄(エ) ̄●)', 'ε=ε=(ノ≧∇≦)ノ', '(´・_・`)', '(-_-#)', '( ̄へ ̄)', '( ̄ε(# ̄) Σ', 'ヽ(`Д´)ノ', '(╯°口°)╯(┴—┴', '(#-_-)┯━┯', '_(:3」∠)_', '(笑)', '(汗)', '(泣)', '(苦笑)', '(´・ω・`)', '(╯°□°)╯︵ ┻━┻', '(╯‵□′)╯︵┻━┻', '( ´ρ`)', '( ゚ω゚)', '(o゚ω゚o)', '( ^ω^)', '(。◕∀◕。)', '/( ◕‿‿◕ )\\', 'ε٩( º∀º )۶з', '( ̄ε(# ̄)☆╰╮( ̄▽ ̄///)', '(●´3`)~♪', '_(:з」∠)_', 'хорошо!', '\(^o^)/', '(•̅灬•̅ )', '(゚Д゚)', 'まったく、小学生は最高だぜ!!', 'ε=ε=ε=┏(゜ロ゜;)┛', '(;°ほ°)', ' ⎝≧⏝⏝≦⎠', 'ヽ(✿゚▽゚)ノ', '焔に舞い上がるスパークよ、邪悪な異性交際に、天罰を与え!', '|•ω•`)']; var MenuList = { item4: { datatype: 'imageLink', title: '固有', addr: KFSmileURL, ref: KFSmileCode }, item1: { datatype: 'plain', title: '快捷', addr: defaultFunction, ref: functionDescription }, item2: { datatype: 'plain', title: '颜文字', addr: emoji }, item5: { datatype: 'image', title: 'ACFUN', addr: ACSmile4 }, item6: { datatype: 'image', title: '常用', addr: NewGame }, // item7: { datatype: 'image', title: 'Akari', addr: AkariSmile }, //Akari item8: { datatype: 'image', title: 'BiliBili', addr: biliEM }, //B站 item3: { datatype: 'image', title: 'LoveLive', addr: LoveliveSmalltargetURL } }; /* Event 函数 */ var EventUtil = { getEvent: function getEvent(event) { return event ? event : window.event; }, getTarget: function getTarget(event) { return event.target || event.srcElement; }, preventDefault: function preventDefault(event) { if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } }, stopPropagation: function stopPropagation(event) { if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; } }, addHandler: function addHandler(element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); //DOM2 } else if (element.attachEvent) { element.attachEvent('on' + type, handler); //IE } else { element['on' + type] = handler; //DOM 0 } }, removeHandler: function removeHandler(element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); //DOM2 } else if (element.detachEvent) { element.detachEvent('on' + type, handler); //IE } else { element['on' + type] = null; //DOM 0 } } }; /*Element 函数*/ var EleUtil = { create: function create(ele) { return document.createElement(ele); }, selectID: function selectID(ele) { return document.getElementById(ele); }, select: function select(selector) { return document.querySelector(selector); } }; /*Cookie处理*/ var CookieUtil = { getCookies: function getCookies() { CookieObj = {}; var thisCookie = document.cookie; if (thisCookie === '') return CookieObj; var listObj = thisCookie.split(';'); for (var i = 0, len = listObj.length; i < len; i++) { var w = listObj[i].split('='); var name = decodeURIComponent(w[0].replace(/^\s+|\s+$/g, '')); var value = decodeURIComponent(w[1]); CookieObj[name] = value; } return CookieObj; //console.log(thisCookie); }, setCookies: function setCookies(name, value, path, iDay, domain, secure) { var oDate = new Date(); oDate.setDate(oDate.getDate() + iDay); var cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value); if (iDay) { cookie + ';expires=' + oDate; } if (path) { cookie + ';path=' + path; } if (domain) { cookie + ';domain=' + domain; } if (secure) { cookie + ';secure=' + secure; } document.cookie = cookie; } }; /*模块*/ var createItems = { createContainer: function createContainer(key) { var ItemContainer = EleUtil.create('div'); ItemContainer.id = 'eddie32' + key; EleUtil.selectID('toggleWindow').style.height = '100px'; EleUtil.selectID('toggleWindow').appendChild(ItemContainer); return ItemContainer; }, createImages: function createImages(key) { var outerContainer = createItems.createContainer(key); //console.log(MenuList[key]); var imgList = MenuList[key].addr; var imgLength = imgList.length; for (var k = 0; k < imgLength; k++) { var divElement = EleUtil.create('div'); divElement.className = 'clickItem'; var imgItem = EleUtil.create('img'); imgItem.src = imgList[k]; imgItem.className = 'Ems'; imgItem.onclick = expandMenu.attachEmotion; imgItem.onmouseover = mouseOverAction.showImg; imgItem.onmouseout = mouseOverAction.clearImg; //imgItem.style.cssText = 'cursor:pointer;padding: 10px 10px:width: 75px;height: 75px;'; divElement.appendChild(imgItem); outerContainer.appendChild(divElement); } }, createPlainText: function createPlainText(key) { var outerContainer = createItems.createContainer(key); var txtList = MenuList[key].addr; var txtLength = txtList.length; for (var k = 0; k < txtLength; k++) { var txtItem = EleUtil.create('span'); txtItem.style.cssText = 'cursor:pointer; margin: 10px 10px;'; txtItem.innerHTML = '' + txtList[k] + ''; if (MenuList[key].ref) { txtItem.innerHTML = '' + MenuList[key].ref[k] + ''; EleUtil.selectID('toggleWindow').style.height = '50px'; } txtItem.onclick = expandMenu.attachEmotion; txtItem.style.cssText = 'cursor:pointer;padding: 10px 10px:width: 50px;'; outerContainer.appendChild(txtItem); } }, createImageLink: function createImageLink(key) { var outerContainer = createItems.createContainer(key); var imgList = MenuList[key].addr; var refList = MenuList[key].ref; var imgLength = imgList.length; for (var k = 0; k < imgLength; k++) { var imgItem = EleUtil.create('img'); imgItem.dataset.link = refList[k]; imgItem.src = imgList[k]; imgItem.className = 'Ems'; imgItem.onclick = expandMenu.attachEmotion; imgItem.style.cssText = 'width: 50px !important;height: 50px !important;'; outerContainer.appendChild(imgItem); } } }; var mouseOverAction = { showImg: function showImg(event) { var eventTarget = EventUtil.getTarget(event); if (!eventTarget.src) { return null; } var largeViewContainer = EleUtil.selectID('largeView'); var _ref = [document.body.scrollTop, document.body.scrollLeft], scrollTopValue = _ref[0], scrollLeftValue = _ref[1]; largeViewContainer.innerHTML = ''; largeViewContainer.style.display = 'block'; largeViewContainer.style.top = event.clientY + scrollTopValue + 20 + 'px'; largeViewContainer.style.left = event.clientX + scrollLeftValue + 'px'; //console.log([event.clientY,event.clientX]); //console.log([EleUtil.selectID('largeView').style.top,EleUtil.selectID('largeView').style.left]); //console.log([document.body.scrollTop,document.body.scrollLeft]); }, clearImg: function clearImg(event) { EleUtil.selectID('largeView').style.display = 'none'; } }; var expandMenu = { init: function init(event) { createMenu.clear(); var eventTarget = EventUtil.getTarget(event); EleUtil.selectID('toggleWindow').style.display = 'block'; EleUtil.selectID('toggleWindow').style.width = EleUtil.select('textarea').style.width; var dataType = eventTarget.attributes[2].nodeValue; var dataKey = eventTarget.attributes[1].nodeValue; if (EleUtil.select('#eddie32' + dataKey)) { EleUtil.select('#eddie32' + dataKey).style.display = 'block'; if (dataKey == 'item1') EleUtil.selectID('toggleWindow').style.height = '50px';else EleUtil.selectID('toggleWindow').style.height = '100px'; return; } if (dataType == 'plain') { createItems.createPlainText(dataKey); } else if (dataType == 'image') { createItems.createImages(dataKey); } else if (dataType == 'imageLink') { createItems.createImageLink(dataKey); } }, attachEmotion: function attachEmotion(event) { var eventTarget = EventUtil.getTarget(event); //console.log(eventTarget); var addressTarget = '', emotionAddress = ''; if (eventTarget.attributes.length == 2) { if (eventTarget.src) { addressTarget = eventTarget.src; emotionAddress = expandMenu.addressParse(addressTarget, 'image'); } else { //console.log(eventTarget.attributes); addressTarget = eventTarget.attributes[0].nodeValue; emotionAddress = expandMenu.addressParse(addressTarget, 'plain'); } } else { //console.log(eventTarget.attributes); addressTarget = eventTarget.attributes[0].nodeValue; emotionAddress = expandMenu.addressParse(addressTarget, 'plain'); } var selectTextArea = EleUtil.select('textarea'); var ovalue = selectTextArea.value; var startPos = selectTextArea.selectionStart; var endPos = selectTextArea.selectionEnd; selectTextArea.value = '' + ovalue.slice(0, startPos) + emotionAddress + ovalue.slice(startPos); // console.log(eventTarget); // console.log(emotionAddress); }, addressParse: function addressParse(addStr, pattern) { var stringReturn = ''; if (pattern === 'image') { stringReturn = '[img]' + addStr + '[/img]'; } if (pattern === 'plain') { stringReturn = decodeURI(addStr); } if (pattern === 'imageLink') { stringReturn = addStr; } return stringReturn; } }; var createMenu = { defaultID: 'emotion0000', main: function main() { /*main menu*/ var mainMenu = EleUtil.create('div'); mainMenu.innerHTML = '\u2468\u56E7\u2468'; mainMenu.id = createMenu.defaultID; var MenuLength = Object.keys(MenuList).length; for (var i = 0; i < MenuLength; i++) { var MenuKey = Object.keys(MenuList)[i]; var MenuTitle = MenuList[MenuKey].title; var MenuType = MenuList[MenuKey].datatype; if (!MenuType || !MenuTitle) console.log('dataerror ' + MenuKey); var testMenu = createMenu.subs(MenuTitle, expandMenu.init, MenuKey, MenuType); mainMenu.appendChild(testMenu); } /*close button*/ var closeBtn = EleUtil.create('span'); closeBtn.innerHTML = '[x]'; closeBtn.className = 'subMenu'; closeBtn.id = 'closeEM'; closeBtn.onclick = createMenu.clear; closeBtn.style.cssText = 'cursor:pointer'; mainMenu.appendChild(closeBtn); /*dropdown box*/ var itemWindow = EleUtil.create('div'); itemWindow.id = 'toggleWindow'; mainMenu.appendChild(itemWindow); /*css style*/ var styleItem = EleUtil.create('style'); styleItem.innerHTML = '#emotion0000 {padding:5px 5px; vertical-align: middle; font: 12px/16px \'Hiragino Sans GB\',\'Microsoft YaHei\',\'Arial\',\'sans-serif\'} #largeView{position:absolute; background: #fff;z-index:5000; opacity: 0.8} #largeView img{width: 200px; height:200px;} #toggleWindow a{padding: 5px 5px;line-height:2} #toggleWindow {height: 100px; padding: 3px 3px; overflow-x: auto; margin-top:6px; margin-bottom:6px; border:1px solid #ff4351; display:none;position:relative; z-index:200; } .clickItem{display:inline-block; z-index:300;}\n a.subBut{text-decoration: none;color: #fff;} .Ems{cursor:pointer;width: 50px;height: 50px;display:inline-block; z-index:400;} a.subBut:hover{color: #fff;} a.txtBtnEmotion{text-decoration:none;} a.txtBtnEmotion:hover{background:#ff7680; color:#fff; } .subMenu{display:inline-block;cursor:pointer; text-align:center; padding: 8px 8px; font: 12px/16px \'Hiragino Sans GB\',\'Microsoft YaHei\',\'Arial\',\'sans-serif\'; background-color: #ff4351;border-color: #ff4351;color: #fff;} .subMenu:hover, .subMenu:focus, .subMenu:visited{background-color: #ff7680;border-color: #ff7680;color: #fff;}'; mainMenu.appendChild(styleItem); return mainMenu; }, subs: function subs(title, func, subid, subtype) { var subMenu = EleUtil.create('span'); subMenu.id = subid; subMenu.className = 'subMenu'; var subcontent = '' + title + ''; subMenu.onclick = func; subMenu.title = title; subMenu.innerHTML = subcontent; return subMenu; }, clear: function clear() { var toggleWindow = EleUtil.selectID('toggleWindow'); toggleWindow.style.display = 'none'; var togWinChildren = toggleWindow.childNodes; for (var j = 0, len = togWinChildren.length; j < len; j++) { //console.log(togWinChildren[j]); togWinChildren[j].style.display = 'none'; } } }; if (typeof window !== 'undefined' && document != null) { //let testareaEleSet = new WeakSet(); var elementSet = document.getElementsByTagName('textarea'); var elementSetLength = elementSet.length; if (elementSetLength === 0) { console.log('There is no textarea'); } //testareaEleSet.add(elementSet); var userOption = { userWindowHeight: 120, userSelectTextArea: 'last' }; var mainEmotionMenu = createMenu.main(); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = elementSet[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var elementSingle = _step.value; //console.log(elementSingle); elementSingle.parentNode.insertBefore(mainEmotionMenu, elementSingle); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } }; //var imgpath = '1485412810'; fun(imgpath);