// ==UserScript==
// @name keylol表情包插件
// @namespace http://tampermonkey.net/
// @version 0.01
// @description Keylol论坛的外挂表情包插件
// @require http://cdn.staticfile.org/jquery/3.1.1/jquery.min.js
// @include http*://*keylol.com/*
// @author FoxTaillll
// @run-at document-end
// ==/UserScript==
"use strict";
/** 一个表情集合的类.初始化方式:
* name表示表情集合的名字,是一个字符串;
* srcList是图片链接列表;
* $Parent是一个$对象,表示该表情集应该显示在什么地方,一般是个div
* showDebug是一个布尔值,true的话显示大量debug信息.
*/
class FaceSet{
/* 构造方法 */
constructor(name,srcList,$Parent,showDebug){
// 复制初始数据
this._name = name;
this._srcList = srcList.slice(0); // 复制
this._$Parent = $Parent;
this._showDebug = showDebug;
// 生成_$Element对象需要的html字符串
this._html = this._createHtml();
// 生成的$对象,一个div,用于显示图片集合,初值为null,第一次调用时才生成
this._$Element = null;
}
/* 显示debug用信息,参数可以多个,像console.log一样使用 */
debugMsg(){
if(this._showDebug) {
console.log(...arguments);
}
}
/* 获取名字 */
getName(){
return this._name;
}
/* 生成html用 */
_createHtml(){
var html = "<div>";
for(var i = 0;i < this._srcList.length;i++){
var src = this._srcList[i];
html += `<img src=${src} style=width:50px;height:50px></img>`;
}
html += "</div>";
this.debugMsg(html);
return html;
}
/* 在jaParent中显示图像. */
show(){
// 若尚未生成,先生成
if(!this._$Element){
this._$Element = $(this._html);
this._$Parent.append(this._$Element);
}
// 显示
this._$Element.css({'display':'block'});
}
/* 隐藏 */
hide(){
this._$Element.css({'display':'none'});
}
}
/** setycyas自制的表情插件类.用于在任意textarea上方添加表情插件.初始化方法:
* $textarea:需要使用插件的textarea,$对象;
* faceTable:一个{},key为表情分类字符串,value是一个列表,列表内容为图片链接;
* showDebug:布尔值,设定是否显示debug信息.
* 构造方法不会加入表情包,必须执行main().
*/
class SetycyasFacePlugin {
constructor($textarea,faceTable,showDebug) {
//复制初始变量
this._$textarea = $textarea;
this._faceTable = faceTable;
this._showDebug = showDebug;
//设置菜单
this._$menu = $("<div id=faceMenu></div>");
this._$menu.css({
"line-height":"30px",
});
if (location.href.indexOf('keylol.com') != -1) {
$("#fastpostreturn").before(this._$menu);
} else {
this._$textarea.before(this._$menu);
}
//设置显示图片用的div
this._$faceDiv = $("</div><div id=faceContent style=clear:both></div>");
this._$faceDiv.css({
"border":"1px solid rgb(131,148,150)",
"margin-top":"5px",
"padding":"10px"
});
this._$menu.after(this._$faceDiv);
//FaceSet对象的表,key是FaceSet的name,同时也是this._$menu显示的内容;
//value则是对应的FaceSet对象
this._faceSetTable = {};
//当前显示的表情集合
this._curFaceSet = null;
}
/* 显示debug用信息,参数可以多个,像console.log一样使用 */
debugMsg(){
if(this._showDebug) {
console.log(...arguments);
}
}
//往textarea插入文本
_insertText(textInsert){
//用数组选择方法把$对象变成一般document对象,访问其光标选择位置
var pos = this._$textarea[0].selectionEnd;
// 原文本
var oldText = this._$textarea.val();
// 插入完成后的新文本
var newText = oldText.substr(0,pos)+textInsert+oldText.substr(pos)
// 插入
this._$textarea.val(newText);
}
//初始化菜单与表情table
_initMenuAndFaces(){
//再写入菜单需要的html,记录表情集合对象
var menuHtml = "";
for(var menuKey in this._faceTable){
var srcList = this._faceTable[menuKey];
var objFs = new FaceSet(menuKey,srcList,this._$faceDiv,this._showDebug);
menuHtml += `<div class=faceSetDiv><a class=faceSet>${menuKey}</a></div>`;
this._faceSetTable[menuKey] = objFs;
}
this._$menu.html(menuHtml);
$('.faceSet').css({
"font-size":"12px","margin":"20px","color":"#f2f2f2","cursor":"pointer"
});
$('.faceSetDiv').hover(
function(event){
if(event.target.className != 'faceSetDiv') return;
$(event.target).css({"background-color":"rgb(64,166,228)"});
},
function(event){
if(event.target.className != 'faceSetDiv') return;
$(event.target).css({"background-color":"rgb(64,166,228)"});
}
);
$('.faceSetDiv').css({
"min-width":"40px","float":"left","background-color":"rgb(64,166,228)"
});
}
/* 绑定所有事件,需要冒泡执行 */
_addEvents(){
//添加事件时,需要传入自己,所以要记住自己
var obj = this;
//点击菜单,只有点击了'faceSet'class才生效
var menu = this._$menu[0];
menu.addEventListener('click',function(e){
var target = e.target;
if(target.className != 'faceSet'){
return;
}
//点击的文字
var faceTag = target.textContent;
//如果当前没有已显示图像集,显示;
if(!obj._curFaceSet){
obj._curFaceSet = obj._faceSetTable[faceTag];
obj._curFaceSet.show();
}else{
//若点击的文字不是当前显示的表情集合,把原来的表情集隐藏,显示点击的;
//否则隐藏当前表情集合.
if(obj._curFaceSet.getName() == faceTag){
obj._curFaceSet.hide();
obj._curFaceSet = null;
}else{
obj._curFaceSet.hide();
obj._curFaceSet = obj._faceSetTable[faceTag];
obj._curFaceSet.show();
}
}
});
//点击图片
var faceDiv = this._$faceDiv[0];
faceDiv.addEventListener('click',function(e){
var target = e.target;
// 点击的不是'img',忽略
if(target.tagName.toLowerCase() != 'img'){
return;
}
var src = target.src;
var textInsert = `[img]${src}[/img]`;
obj._insertText(textInsert);
});
}
main(){
//生成menu与表情集合的具体内容
this._initMenuAndFaces();
//绑定事件
this._addEvents();
}
}
/** 执行代码,如无必要,不要修改FaceSet与SetycyasPlugin两个类.
* 在这里修改执行代码,应该足够对应不同论坛的设定以及自定义表情.
*/
(function(){
//这一句指定文本框,应对不同论坛请修改这里
var $textarea = $("form[name=FORM] textarea[name=atc_content]");
if ($textarea.length == 0) {
$textarea = $("#fastpostmessage");
}
if ($textarea.length == 0) {
return;
}
//这一句自定义表情包,注意有些图片可能省略了域名
var faceTable = {
"阿鲁":[
'https://blob.keylol.com/forum/202005/10/192357hpliwiniin43nr3p.png',
'https://blob.keylol.com/forum/202005/10/194135dbljt3q0m3ulluxk.png',
'https://blob.keylol.com/forum/202005/11/084043p1w2crnzvrsbrsv1.png',
'https://blob.keylol.com/forum/202005/11/084043tpf44v69vuu39od9.png',
'https://blob.keylol.com/forum/202005/11/084043nz3olularkx6aaao.png',
'https://blob.keylol.com/forum/202005/11/084044ju4ocm4focsquizi.png',
'https://blob.keylol.com/forum/202005/11/084044zastta6az30qc00q.png',
'https://blob.keylol.com/forum/202005/11/084043zbnbor28nan6rvob.png',
'https://blob.keylol.com/forum/202005/11/084043wl1zaf10lfpyvr0a.png',
'https://blob.keylol.com/forum/202005/12/070831vs9zcv09ue8ahbyn.png',
'https://blob.keylol.com/forum/202005/12/091146c4snkyannuu5cm4k.png',
'https://blob.keylol.com/forum/202005/12/083257r2b1qbx96q463qee.gif',
'https://blob.keylol.com/forum/202005/12/084847baa8zclm36288dmd.gif',
'https://blob.keylol.com/forum/202005/12/085528vcdmiucvnwe1usig.gif'
],
};
// 新建表情包插件,运行main()方法
var showDebug = false;
var plugin = new SetycyasFacePlugin($textarea,faceTable,showDebug);
plugin.main();
})();