// ==UserScript==
// @name Setycyas自定义表情包插件
// @namespace https://greasyfork.org/users/14059
// @version 0.03
// @description 适应不同论坛的自定义表情包插件
// @require http://cdn.staticfile.org/jquery/3.1.1/jquery.min.js
// @include http*://*2dkf.com/*
// @include http*://*9moe.com/*
// @include http*://*kfgal.com/*
// @author setycyas
// @run-at document-end
// @license MIT
// ==/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",
});
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(255,107,121)"});
},
function(event){
if(event.target.className != 'faceSetDiv') return;
$(event.target).css({"background-color":"rgb(255,67,81)"});
}
);
$('.faceSetDiv').css({
"min-width":"40px","float":"left","background-color":"rgb(255,67,81)"
});
}
/* 绑定所有事件,需要冒泡执行 */
_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]");
//这一句自定义表情包,注意有些图片可能省略了域名
var faceTable = {
"BILIBILI":[
'http://o6smnd6uw.bkt.clouddn.com/xds/2233%20(11).gif',
'http://o6smnd6uw.bkt.clouddn.com/xds/2233%20(13).gif',
'http://o6smnd6uw.bkt.clouddn.com/xds/2233%20(4).gif'
],
"ACFUN":[
'http://o6smnd6uw.bkt.clouddn.com/xds6/1.png',
'http://o6smnd6uw.bkt.clouddn.com/xds6/2.png',
'http://o6smnd6uw.bkt.clouddn.com/xds6/5.png',
'http://o6smnd6uw.bkt.clouddn.com/xds6/24.png',
'http://o6smnd6uw.bkt.clouddn.com/xds5/23.gif',
'http://o6smnd6uw.bkt.clouddn.com/xds6/21.png'
],
"AKARI":[
'http://o6smnd6uw.bkt.clouddn.com/xds2/akari2.gif',
'http://o6smnd6uw.bkt.clouddn.com/xds2/akari6.gif',
'http://o6smnd6uw.bkt.clouddn.com/xds2/akari9.gif',
'http://o6smnd6uw.bkt.clouddn.com/xds2/akari10.gif',
'http://o6smnd6uw.bkt.clouddn.com/xds2/akari11.gif',
'http://o6smnd6uw.bkt.clouddn.com/xds2/akari12.gif',
'http://o6smnd6uw.bkt.clouddn.com/xds2/akari14.gif'
],
"其他":[
'http://o6smnd6uw.bkt.clouddn.com/xds4/0xx4.png',
'http://o6smnd6uw.bkt.clouddn.com/xds4/0xx10.png',
'http://o6smnd6uw.bkt.clouddn.com/xds4/0xx8.png',
'http://o6smnd6uw.bkt.clouddn.com/xds4/0xx18.png'
]
};
// 新建表情包插件,运行main()方法
var showDebug = false;
var plugin = new SetycyasFacePlugin($textarea,faceTable,showDebug);
plugin.main();
})();