- 事前提要:此方法无法用于带有PJAX加载的网站,handsome需要取消使用PJAX。
- 因为文章有些杂乱,在2022.02.24对本文进行了重构,你可以在“文章历史记录”中查看之前的版本,虽然已经失去了大部分参考价值。
(更新)一种支持PJAX的方法
这篇文章实在是太长了,就新开一篇文章来写这个东西吧。大致方法如下:
- 将pup.js里的代码封装成一个函数
function chevereto()
。 - 在自定义 JavaScript中调用这个函数
chevereto()
。 - 将
chevereto()
加入PJAX的回调函数中。
本站使用的就是这种方法。嗯,怎么说呢,能用,但是看起来好low!虽然也没人看文章源代码就是了。
算了,又不是不能用,哪天有时间再仔细研究一下吧。(应该不会再研究了) 各位大佬如果有什么好方法,记得评论区留言一下,我先谢谢您。
新文章写好了,如下
https://kanochan.net/archives/1141.html
(更新)一种更简单的办法
经过测试,摸索出了一种比较简单的办法,不用修改js文件。略微遗憾的是,该方法还是不能支持PJAX,使用的话需要关闭主题的PJAX功能。实现方法如下:
关闭PJAX
handsome后台
-主题增强功能
-增强功能开关
里取消勾选启用pjax
放行HTML标签
在后台
-设置
-评论
-允许使用的HTML标签和属性
中添加下列内容,并保存,否则会评论失败。
<img src="">
修改handsome源码(8.3.0版本)
文件路径:/usr/themes/handsome/libs/Content.php
第2324行
将
echo '<textarea id="handsome_md_text" class="hide" >' . htmlspecialchars($content) . '</textarea>';
修改为
echo '<div id="handsome_md_text" class="hide" >' . htmlspecialchars($content) . '</div>';
引入Chevereto上传插件
在handsome后台
-开发者设置
-自定义输出head 头部的HTML代码
中写入以下内容:
<script async src="//pic.6zs.cn/sdk/pup.js" data-url="https://pic.6zs.cn/upload" data-palette="black" data-auto-insert="html-embed"></script>
完成。刷新看一下,在评论输入框下方应该出现了一个上传按钮。如果你想知道具体的原理,可以看看后续的内容。
先上总结
测试发现,通过HTML **data-** 属性引入js的方式,仍然会与本地缓存的js冲突,我觉得这是chevereto的锅。所以采用的方法是直接修改js,放弃使用HTML data-属性。
- 开始
- 放行Typecho评论的HTML标签
- 修改chevereto的上传插件pup.js
- 在评论区新建一个上传图片按钮
- 完成
一、前言
在评论时,我们往往需要附上图片以更明确地表达自己的想法,Typecho中虽然没有原生的评论区图片上传功能,但是也可以通过HTML的img
标签在评论中附加图片。不过,这其中有一个大麻烦:图片需要上传到图床,才能获得图片链接,进而插入img
标签。这是一个很麻烦的过程,也正因为如此,除非迫不得已,没有人愿意选择在评论中添加图片。
现在,我们就来解决这个问题。先附上效果图,如下,你也可以在下方的评论区中验证效果。([font color="#FFFF00"]注意:部分图床会被qq、微信内置浏览器拦截,想要获得完整的演示,请在系统浏览器中打开网页。[/font])
二、为Handsome增加评论图片上传
此方案不兼容手机应用内置的浏览器,如QQ、微信等自带的浏览器。内置浏览器就是逊啦。
因为实现上传操作需要同时打开两个窗口,而内置浏览器往往没有多窗口支持。
放行HTML标签和属性
在后台
-设置
-评论
-允许使用的HTML标签和属性
中添加下列内容,并保存,否则会评论失败。
<img src="">
修改chevereto的上传插件pup.js
此方案是基于Chevereto的上传插件来实现,所有通过Chevereto部署的图床都可以应用到此方案。
chevereto是什么
关于Chevereto,你可以看看我之前写的文章:
[post cid="997" cover="" size=""/]
认识Chevereto的上传插件
Popup Upload Plugin上传插件,可谓是Chevereto的重要功能之一。PUP 将用户可编辑的内容与将触发图像上传对话框的上传按钮绑定,并自动处理图像插入所需的代码。最终用户无需离开原始网站即可体验流畅而整洁的流程。关于上传插件的更多信息,你可以查看官方文档的说明,这里不再详细介绍。说一下有几个值得我们关注的东西:
mode
即插件的模式。在默认情况下,插件绑定到任何匹配的编辑器框。auto-insert
嵌入图片代码自动插入到输入框。
获取插件链接
随便找一个基于Chevereto搭建的图床,如:https://www.picb.cc/
复制得插件链接如下
<script async src="//www.picb.cc/sdk/pup.js" data-url="https://www.picb.cc/upload" data-auto-insert="html-embed"></script>
前面也提到了,通过data-*
属性控制pup.js效果不尽人意,故要想得到好的体验(不出bug),需要修改js后重新引入。
修改pup.js
下载pup.js
pup.js的下载链接可以在上面的插件链接中找到,即https://www.picb.cc/sdk/pup.js,将该链接复制到下载器中下载。没有下载器的话,就打开链接,右键另存为...进行下载。
格式化pup.js
打开下载好的js,如下,可以看到代码是被压缩过的,为了便于修改,我们需要格式化它。推荐使用在线代码格式化工具:JavaScript格式化。
修改pup.js代码
url: "https://demo.chevereto.com/upload"
修改为目标图床的上传链接,如
url: "https://www.picb.cc/upload"
将mode: "auto"
改为mode: "manual"
,即让js默认不自动放置上传按钮。
将autoInsert: "bbcode-embed-medium"
修改为autoInsert: "html-embed"
,即让js自动返回HTML格式的图片链接。
修改完成后的js部分代码如下:
(function() {
for (var t = {
defaultSettings: {
url: "https://www.picb.cc/upload",
vendor: "auto",
mode: "manual",
lang: "auto",
autoInsert: "html-embed",
palette: "default",
init: "onload",
containerClass: 1,
...
...
图片示意如下:
[/hide]
重新引入修改后的pup.js
- 将修改后的pup.js上传到目录
/usr/themes/handsome/assets/js/
下。 - 在
handsome后台
-开发者设置
-自定义输出head 头部的HTML代码
中写入以下内容:
<script async src="/usr/themes/handsome/assets/js/pup.js"></script>
新建图片上传按钮
在主题的评论区配置文件中加入以下代码
<button data-chevereto-pup-trigger data-target="#comment">上传图片</button>
- 代码解析:
data-target="#comment"
是文本框的ID,每个主题的ID不同,你可以在PHP源码中找到ID。如下图,文本框的ID为:comment
。
这个ID用于Chevereto上传插件的回调,即插件上传完图片后,将嵌入代码输入到文本框中。根据主题的不同,你也许需要进行相应修改。 - 按钮添加的位置:
根据不同的需要,你可以将按钮添加到任何地方。你可以通过Chrome控制台的元素指示来确定添加的位置。
对于Handsome(8.3.0版本)主题,添加的位置为/handsome/component/comments.php
中的第137行附近,如下:
<div class="comment-form-comment form-group">
<label class="padder-v-sm" for="comment"><?php _me("评论") ?>
<span class="required text-danger">*</span></label>
<textarea id="comment" class="textarea form-control OwO-textarea" name="text" rows="5" placeholder="<?php _me("说点什么吧……") ?>" onkeydown="if(event.ctrlKey&&event.keyCode==13){document.getElementById('submit').click();return false};"><?php $this->remember('text'); ?></textarea>
代码在这里添加
<div class="OwO padder-v-sm"></div>
<?php $options = mget(); if (in_array('ajaxComment', Utils::checkArray( $options->featuresetup))): ?>
<div class="secret_comment" id="secret_comment" data-toggle="tooltip"
data-original-title="<?php _me("开启该功能,您的评论仅作者和评论双方可见") ?>">
<label class="secret_comment_label control-label"><?php _me("私密评论") ?></label>
图片示意如下:
[/hide]
- 给按钮加个CSS样式
经过上面的配置,理论上图片上传按钮已经处于可用的状态。但相信你也发现了,按钮挺丑的...如果你要给按钮加CSS,在<button中调用CSS样式即可,如下:
<button class="你的样式" data-chevereto-pup-trigger data-target="#comment">上传图片</button>
对于Handsome主题,直接调用主题的按钮样式即可,适用于夜间模式界面,如下:
<button class="btn m-b-xs btn-dark" data-chevereto-pup-trigger data-target="#comment">上传图片</button>
三、Q&A
- 要更换图床怎么办?
答:修改pup.js里的url: "https://www.picb.cc/upload"
,更改图床的链接即可。
四、图床分享
最后,分享一些使用Chevereto搭建的图床(注意:本站不对图床的稳定性负责,仅供分享)
- PICBCC:https://www.picb.cc/
- 路过图床:https://imgtu.com/
- 知晓图床:https://tu.jilu.info/
- SM图床:https://www.imgsm.com/
- 鸡霸图床(老王图床):https://img.gejiba.com/
- 靠谱图床:https://img.bqe.cc/
- 伏名图床:https://ccsyn.org/
- 安享图床:https://img.ax/
本站图床由:https://pic.6zs.cn/提供。
本文<完!>,感谢你的阅览,如果觉得还不错,请随意点赞。
- 前言
在评论时,我们往往需要附上图片以更明确地表达自己的想法,Typecho中虽然没有原生的评论区图片上传功能,但是也可以通过HTML的img
标签在评论中附加图片。不过,这其中有一个大麻烦:图片需要上传到图床,才能获得图片链接,进而插入img
标签。这是一个很麻烦的过程,也正因为如此,除非迫不得已,没有人愿意选择在评论中添加图片。
现在,我们就来解决这个问题。先附上效果图,如下,你也可以在下方的评论区中验证效果。
- 如果你只想配置本站同款...
如果你只想配置本站同款,而且你使用的是Handsome主题,那么按照以下步骤配置即可,后续内容可忽略。
- 在
后台
-设置
-评论
-允许使用的HTML标签和属性
中添加下列内容,并保存。
<img src="">
- 在
后台主题设置
-开发者设置
-自定义输出head 头部的HTML代码
中,填入以下内容,并保存。
<script async src="https://www.guangsu.top/pup.js"></script>
- 修改
/handsome/component/comments.php
文件,137行附近,在
<textarea id="comment" class="textarea form-control OwO-textarea" name="text" rows="5" placeholder="<?php _me("说点什么吧……") ?>" onkeydown="if(event.ctrlKey&&event.keyCode==13){document.getElementById('submit').click();return false};"><?php $this->remember('text'); ?></textarea>
下方添加下列代码:
<button class="btn m-b-xs btn-dark" data-chevereto-pup-trigger data-target="#comment">上传图片</button>
添加代码的详细位置如下:
<div class="comment-form-comment form-group">
<label class="padder-v-sm" for="comment"><?php _me("评论") ?>
<span class="required text-danger">*</span></label>
<textarea id="comment" class="textarea form-control OwO-textarea" name="text" rows="5" placeholder="<?php _me("说点什么吧……") ?>" onkeydown="if(event.ctrlKey&&event.keyCode==13){document.getElementById('submit').click();return false};"><?php $this->remember('text'); ?></textarea>
代码在这里添加
<div class="OwO padder-v-sm"></div>
<?php $options = mget(); if (in_array('ajaxComment', Utils::checkArray( $options->featuresetup))): ?>
<div class="secret_comment" id="secret_comment" data-toggle="tooltip"
data-original-title="<?php _me("开启该功能,您的评论仅作者和评论双方可见") ?>">
<label class="secret_comment_label control-label"><?php _me("私密评论") ?></label>
在关闭PJAX后此步不需要做。后台主题设置
-PJAX
-PJAX回调函数
中写入下列内容,并保存。
$.getScript("https://www.guangsu.top/pup.js");
- 完成
- 开始之前...
- 在
后台
-设置
-评论
-允许使用的HTML标签和属性
中添加要放行的标签:
<a href="">
<img src="">
- 此方案不兼容手机应用内置的浏览器,如QQ、微信等自带的浏览器。
内置浏览器就是逊啦。
- 正式开始
- 关于Chevereto
此方案是基于Chevereto的上传插件来实现,所有通过Chevereto部署的图床都可以应用到此方案。关于Chevereto,你可以看看我之前写的文章:
[post cid="997" cover="" size=""/]
本次教程针对的是Handsome主题,理论上适用于所有Typecho主题,核心方法是一样的。
- 认识Chevereto的上传插件
Popup Upload Plugin上传插件,可谓是Chevereto的重要功能之一。PUP 将用户可编辑的内容与将触发图像上传对话框的上传按钮绑定,并自动处理图像插入所需的代码。最终用户无需离开原始网站即可体验流畅而整洁的流程。关于上传插件的更多信息,你可以查看官方文档的说明,这里不再详细介绍。说一下有几个值得我们关注的东西:
mode
即插件的模式。在默认情况下,插件绑定到任何匹配的编辑器框。auto-insert
嵌入图片代码自动插入到输入框。- 获取插件链接
随便找一个基于Chevereto搭建的图床,如:https://www.picb.cc/
复制得插件链接如下
<script async src="//www.picb.cc/sdk/pup.js" data-url="https://www.picb.cc/upload" data-auto-insert="html-embed"></script>
默认情况下,插件会自动匹配输入框,但是效果往往不尽人意,我们需要手动指定位置。要想自定义位置,我们需要禁用插件得自动匹配功能,即上文所述的mode
,在上面复制出来的链接中添加:data-mode="manual"参数用于禁用插件的自动匹配。关于这些参数的介绍,在前述的官方文档链接中讲有。修改好的插件链接如下:
<script async src="//www.picb.cc/sdk/pup.js" data-url="https://www.picb.cc/upload" data-auto-insert="html-embed" data-mode="manual"></script>
- 部署插件
将修改好的链接,放置到主题的<#head>
...<#/head>
头部里(请忽略#
号),如下
[hide]
[/hide]
对于Hansome主题,可在后台-开发者设置-自定义输出head 头部的HTML代码中添加插件链接。
- 添加
上传图片
按钮
在主题的评论区配置文件中加入以下代码
<button data-chevereto-pup-trigger data-target="#comment">上传图片</button>
代码解析: data-target="#comment"
是文本框的ID,每个主题的ID不同,你可以在PHP源码中找到ID。如下图,文本框的ID为:comment
。
这个ID用于Chevereto上传插件的回调,即插件上传完图片后,将嵌入代码输入到文本框中。根据主题的不同,你也许需要进行相应修改。
按钮添加的位置:
根据不同的需要,你可以将按钮添加到任何地方。你可以通过Chrome控制台的元素指示来确定添加的位置。
对于Handsome(8.3.0版本)主题,添加的位置为/handsome/component/comments.php
中的第137行附近,如下:
<div class="comment-form-comment form-group">
<label class="padder-v-sm" for="comment"><?php _me("评论") ?>
<span class="required text-danger">*</span></label>
<textarea id="comment" class="textarea form-control OwO-textarea" name="text" rows="5" placeholder="<?php _me("说点什么吧……") ?>" onkeydown="if(event.ctrlKey&&event.keyCode==13){document.getElementById('submit').click();return false};"><?php $this->remember('text'); ?></textarea>
代码在这里添加
<div class="OwO padder-v-sm"></div>
<?php $options = mget(); if (in_array('ajaxComment', Utils::checkArray( $options->featuresetup))): ?>
<div class="secret_comment" id="secret_comment" data-toggle="tooltip"
data-original-title="<?php _me("开启该功能,您的评论仅作者和评论双方可见") ?>">
<label class="secret_comment_label control-label"><?php _me("私密评论") ?></label>
图片示意如下:
[/hide]
- 给按钮加个CSS样式
经过上面的配置,理论上图片上传按钮已经处于可用的状态。但相信你也发现了,按钮挺丑的...CSS这东西吧,因人而异,我就不写了懒。如果你要给按钮加CSS,在<button中调用CSS样式即可,如下:
<button class="你的样式" data-chevereto-pup-trigger data-target="#comment">上传图片</button>
对于Handsome主题,直接调用主题的按钮样式即可,适用于夜间模式界面,如下:
<button class="btn m-b-xs btn-dark" data-chevereto-pup-trigger data-target="#comment">上传图片</button>
- PJAX回调
需要注意的是,如果你的网站启用了PJAX,会导致Chevereto的上传插件,也就是pup.js,无法重新加载。非常抱歉的是,我不知道怎么回调带有用户参数的script,在Chevereto的script中带有两个参数,分别是
data-auto-insert="html-embed"
、data-mode="manual"
,其中,前者定义了插件的返回图片地址的代码格式,后者定义了插件的工作模式。
如果只是单独重载pup.js,那么会造成一些错误,如点开上传按钮,跳转到的是https://demo.chevereto.com/upload
,以及出现两个上传按钮的状况。我不知道的是,怎么样才能让PJAX重新加载整个script,使用户信息随之重载。如果有人研究出来了,请务必留言告诉我,多谢!
经过研究,虽然无法从根本上解决上面的问题,但是也可以通过下面的的方法来曲线救国。 没有救,只能把PJAX关了,以下内容失效。
- 修改js文件,再重新引入修改后的js
pup.js存放于图床的服务器上,我们当然不可能更改。可以将目标图床的pup.js下载到本地进行修改。如https://pic.6zs.cn/sdk/pup.js,下载好的js如下:
`(function(){for(var t={defaultSettings:{url:"https://demo.chevereto.com/upload",vendor:"auto",mode:"auto",lang:"auto",autoInsert:"bbcode-embed-medium",palette:"default",init:"onload",containerClass:1,buttonClass:1,sibling:0,siblingPos:"after",fitEditor:0,observe:0,observeCache:1,html:'%iconSvg%text',css:".%cClass{display:inline-block;margin-top:5px;margin-bottom:5px}.%bClass{line-height:normal;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;outline:0;color:%2;border:none;cursor:pointer;border:1px solid rgba(0,0,0,.15);background:%1;border-radius:.2em;padding:.5em 1em;font-size:12px;font-weight:700;text-shadow:none}.%bClass:hover{background:%3;color:%4;border-color:rgba(0,0,0,.1)}.%iClass,.%tClass{display:inline-block;vertical-align:middle}.%iClass svg{display:block;width:1em;height:1em;fill:currentColor}.%tClass{margin-left:.25em}"},ns:{plugin:"chevereto-pup"},palettes:{default:["#ececec","#333","#2980b9","#fff"],clear:["inherit","inherit","inherit","#2980b9"],turquoise:["#16a085","#fff","#1abc9c","#fff"],green:["#27ae60","#fff","#2ecc71","#fff"],blue:["#2980b9","#fff","#3498db","#fff"],purple:["#8e44ad","#fff","#9b59b6","#fff"],darkblue:["#2c3e50","#fff","#34495e","#fff"],yellow:["#f39c12","#fff","#f1c40f","#fff"],orange:["#d35400","#fff","#e67e22","#fff"],red:["#c0392b","#fff","#e74c3c","#fff"],grey:["#ececec","#000","#e0e0e0","#000"],black:["#333","#fff","#666","#fff"]},classProps:["button","container"],iconSvg:'',l10n:{ar:"تحميل الصور",cs:"Nahrát obrázky",da:"Upload billeder",de:"Bilder hochladen",es:"Subir imágenes",fi:"Lataa kuvia",fr:"Importer des images",id:"Unggah gambar",it:"Carica immagini",ja:"画像をアップロード",nb:"Last opp bilder",nl:"Upload afbeeldingen",pl:"Wyślij obrazy",pt_BR:"Enviar imagens",ru:"Загрузить изображения",tr:"Resim Yukle",uk:"Завантажити зображення",zh_CN:"上传图片",zh_TW:"上傳圖片"},vendors:{default:{check:function(){return 1},getEditor:function(){var t={textarea:{name:["recaptcha","search","recipients","coppa","^comment_list","username_list","add"]},ce:{dataset:["gramm"]}},e=["~","|","^","$","*"],i={};for(var s in t){i[s]="";var n=t[s];for(var r in n)for(var o=0;o-1&&(a=d,l=l.substring(1)),i[s]+=":not(["+("dataset"==r?"data-"+l:r+a+'="'+l+'"')+"])"}}return document.querySelectorAll('[contenteditable=""]'+i.ce+',[contenteditable="true"]'+i.ce+",textarea:not([readonly])"+i.textarea)}},bbpress:{settings:{autoInsert:"html-embed-medium",html:'',sibling:"#qt_bbp_reply_content_img",siblingPos:"before"},check:"bbpEngagementJS"},discourse:{settings:{autoInsert:"markdown-embed-medium",html:'',sibling:".upload.btn",siblingPos:"before",observe:".create,#create-topic,.usercard-controls button",observeCache:0,onDemand:1},check:"Discourse"},discuz:{settings:{buttonClass:1,html:'%iconSvg',sibling:".fclr,#e_attach",css:"a.%bClass,.bar a.%bClass{box-sizing:border-box;cursor:pointer;background:%1;color:%2;text-indent:unset;position:relative}.b1r a.%bClass:hover,a.%bClass:hover{background:%3;color:%4}a.%bClass{font-size:14px}.b1r a.%bClass{border:1px solid rgba(0,0,0,.15)!important;font-size:20px;padding:0;height:44px}.%bClass svg{font-size:1em;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}",palette:"purple"},palettes:{default:["transparent","#333","#2980b9","#fff"]},check:"DISCUZCODE",getEditor:function(){return document.querySelector('.area textarea[name="message"]')}},ipb:{settings:{autoInsert:"html-embed-medium",html:'%iconSvg%text',sibling:".cke_button__ipslink",siblingPos:"before",css:".cke_button.%bClass{background:%1;position:relative}.cke_button.%bClass:hover{background:%3;border-color:%5}.cke_button.%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:%2}.cke_button.%bClass:hover svg{fill:%4}"},palettes:{default:["inherit","#444","","inherit"]},check:"ips",getEditorFn:function(){var t=this.getEditor().dataset.ipseditorName;return CKEDITOR.instances[t]},getEditor:function(){return document.querySelector("[data-ipseditor-name]")},editorValue:function(t){var e=CKEDITOR.dom.element.createFromHtml(""+t+"");this.getEditorFn().insertElement(e)},useCustomEditor:function(){return 1}},mybb:{settings:{sibling:"#quickreply_e > tr > td > *:last-child, .sceditor-container",fitEditor:0,extracss:".trow2 .%cClass{margin-bottom:0}"},check:"MyBB",getEditor:function(){return MyBBEditor?MyBBEditor.getContentAreaContainer().parentElement:document.querySelector("#quickreply_e textarea")},editorValue:function(t){if(MyBBEditor){var e=MyBBEditor.inSourceMode()?"insert":"wysiwygEditorInsertHtml";MyBBEditor[e]("insert"==e?t:MyBBEditor.fromBBCode(t))}else this.getEditor().value+=t},useCustomEditor:function(){return!!MyBBEditor}},nodebb:{settings:{autoInsert:"markdown-embed-medium",html:'',sibling:'[data-format="picture-o"]',siblingPos:"before",observe:'[component="category/post"],[component="topic/reply"],[component="topic/reply-as-topic"],[component="post/reply"],[component="post/quote"]',observeCache:0,onDemand:1},check:"__nodebbSpamBeGoneCreateCaptcha__",callback:function(){for(var t=document.querySelectorAll(".btn-toolbar .img-upload-btn"),e=0;e ':' ',sibling:document.querySelector("#format-buttons *:first-child")&&"BUTTON"==document.querySelector("#format-buttons *:first-child").tagName?".bbcode-img":"#message-box textarea.inputbox",siblingPos:"after"},check:"phpbb",getEditor:function(){if("undefined"!=typeof form_name&&"undefined"!=typeof text_name)return document.forms[form_name].elements[text_name]}},proboards:{settings:{html:' ',css:"",sibling:"input[type=submit]",siblingPos:"before"},check:"proboards",editorValue:function(t){var e=$(".wysiwyg-textarea").data("wysiwyg"),i=e.editors[e.currentEditorName];i.setContent(i.getContent()+t)},useCustomEditor:function(){return 1!==$(".container.quick-reply").size()},getEditor:function(){return document.querySelector("textarea[name=message]")}},redactor2:{getEditor:function(){var t=this.getEditorFn();return t?this.useCustomEditor()?t.$box[0]:t[0]:null},getEditorEl:function(){return this.useCustomEditor()?this.getEditorFn().$editor[0]:this.getEditorFn()[0]},editorValue:function(t){var e="",i=this.useCustomEditor()?"innerHTML":"value";if("string"!=typeof t){var s=this.getEditorEl()[i];return this.useCustomEditor()&&""==s?"":this.getEditorEl()[i]}if(this.useCustomEditor()){var n=""+t+"";this.getEditorFn().insert.html(""!==this.editorValue()?e+n:n)}else this.getEditorEl()[i]=t},useCustomEditor:function(){return!(this.getEditorFn()instanceof jQuery)}},smf:{settings:{html:' %iconSvg%text ',css:"%defaultCSS #bbcBox_message .%bClass{margin-right:1px;transition:none;color:%2;padding:0;width:23px;height:21px;border-radius:5px;background-color:%1}#bbcBox_message .%bClass:hover{background-color:%3}#bbcBox_message .%tClass{display:none}",sibling:"#BBCBox_message_button_1_1,.quickReplyContent + div",siblingPos:"before",fitEditor:1},palettes:{default:["#E7E7E7","#333","#B0C4D6","#333"]},check:"smf_scripturl",getEditor:function(){return smf_editorArray.length>0?smf_editorArray[0].oTextHandle:document.querySelector(".quickReplyContent textarea")}},quill:{settings:{autoInsert:"html-embed-medium",html:'%iconSvg',sibling:"ul.richEditor-menuItems li.richEditor-menuItem:last-child",css:".%iClass {display: block; height: 24px; margin: auto; width: 24px;}"},check:"quill",editorValue:function(t){quill.clipboard.dangerouslyPasteHTML("\n"==quill.getText()?0:quill.getLength(),t)},useCustomEditor:function(){return 1},getEditor:function(){return quill.container}},vanilla:{settings:{autoInsert:"markdown-embed-medium",html:'',sibling:".editor-dropdown-upload"},check:"Vanilla",getEditor:function(){return document.getElementById("Form_Body")}},vbulletin:{settings:{autoInsert:"html-embed-medium",html:'%iconSvg',sibling:".b-toolbar__item--secondary:first-child",siblingPos:"before",css:".%bClass{background:%1;color:%2;position:relative}.%bClass:hover{background:%3;color:%4;border-color:%5}.%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}"},palettes:{default:["","#4B6977","","#007EB8"]},check:"vBulletin",getEditorFn:function(){var t=this.getEditor().getAttribute("ck-editorid");return CKEDITOR.instances[t]},getEditor:function(){return document.querySelector("[data-message-type]")},editorValue:function(t){var e=CKEDITOR.dom.element.createFromHtml(""+t+"");this.getEditorFn().insertElement(e)},useCustomEditor:function(){return 1}},WoltLab:{settings:{autoInsert:"html-embed-medium",sibling:'li[data-name="settings"]',html:' %text'},check:"WBB",getEditorFn:function(){var t=$("#text").data("redactor");return t||null}},XF1:{settings:{autoInsert:"html-embed-medium",containerClass:1,buttonClass:1,html:'%iconSvg',sibling:".redactor_btn_container_image",siblingPos:"before",css:"li.%cClass .%bClass{background:%1;color:%2;text-indent:unset;border-radius:3px;position:relative}li.%cClass a.%bClass:hover{background:%3;color:%4;border-color:%5}.%cClass .%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}",observe:".edit.OverlayTrigger",observeCache:1},palettes:{default:["none","inherit","none","inherit",""]},check:"XenForo",getEditorFn:function(){var t=document.querySelector("#exposeMask")&&document.querySelector("#exposeMask").offsetParent?".xenOverlay form":"form";if("form"!==t)for(var e=document.querySelectorAll(t),i=0;i"==s?"":this.getEditorEl()[i]}if(this.useCustomEditor()){var n=""+t+"";this.getEditorFn().insertHtml(""!==this.editorValue()?e+n:n)}else this.getEditorEl()[i]=t},useCustomEditor:function(){return!(this.getEditorFn()instanceof jQuery)}},XF2:{settings:{autoInsert:"html-embed-medium",containerClass:1,buttonClass:"button--link js-attachmentUpload button button--icon button--icon--upload fa--xf",html:'%text',sibling:"",siblingPos:"after",observe:'[data-xf-click="quick-edit"]',observeCache:1},palettes:{default:["transparent","#505050","rgba(20,20,20,0.06)","#141414"]},check:"XF",getEditorFn:function(t){var e=".js-editor";return"string"==typeof t&&(e=this.getEditorSel(t)),XF.getEditorInContainer($(e))},getEditorSel:function(e){return"["+t.ns.dataPluginTarget+'="'+e+'"]'},getEditor:function(t){return"string"==typeof t?document.querySelector(this.getEditorSel(t)):document.querySelectorAll(".js-editor")},getBbCode:function(t){return t.getTextArea()[0].value},editorValue:function(t,e){var i="",s=this.getEditorFn(e),n=s.ed.bbCode.isBbCodeView()?["bbCode","getBbCode","insertBbCode"]:["html","get","insert"],r=s.ed[n[0]];if("string"!=typeof t){if(void 0===r[n[1]])var o=this.getBbCode(r);else o=r[n[1]]();return this.useCustomEditor()&&o==i?"":o}var a=""!==this.editorValue(!1,e);if("html"==n[0]){var l=""+t+"";r[n[2]](a?i+l:l)}else{var d=XF.ajax("POST",XF.canonicalizeUrl("index.php?editor/to-bb-code"),{html:t});d.done(function(t){r[n[2]](a?"\n"+t.bbCode:t.bbCode)})}},useCustomEditor:function(){return void 0!==XF.getEditorInContainer($(".js-editor"))}}},generateGuid:function(){var t=(new Date).getTime();return"undefined"!=typeof performance&&"function"==typeof performance.now&&(t+=performance.now()),"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var i=(t+16*Math.random())%16|0;return t=Math.floor(t/16),("x"===e?i:3&i|8).toString(16)})},getNewValue:function(t,e){var i="string"!=typeof t.getAttribute("contenteditable")?"value":"innerHTML",s="value"==i?"\n":"",n=t[i],r=e,o=!1;if(o&&(r=String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""")),0==n.length)return r;var a="",l=n.match(/\n+$/g),d=l?l[0].split("\n").length:0;if(d<=2){var u=0==d?2:1;a+=s.repeat(u)}return a+r},insertTrigger:function(){var t,e=this.vendors[this.settings.vendor],i=this.settings.sibling?document.querySelectorAll(this.settings.sibling+":not(["+this.ns.dataPlugin+"])")[0]:0;if("auto"==this.settings.mode)t=this.vendors[e.hasOwnProperty("getEditor")?this.settings.vendor:"default"].getEditor();else{for(var s=document.querySelectorAll("["+this.ns.dataPluginTrigger+"][data-target]:not(["+this.ns.dataPluginId+"])"),n=[],r=0;r0&&(t=document.querySelectorAll(n.join(",")))}if(t){if(!document.getElementById(this.ns.pluginStyle)&&this.settings.css){var o=document.createElement("style"),a=this.settings.css;a=this.appyTemplate(a),o.type="text/css",o.innerHTML=a.replace(/%p/g,"."+this.ns.plugin),o.setAttribute("id",this.ns.pluginStyle),document.body.appendChild(o)}t instanceof NodeList||(t=[t]);var l=0;for(r=0;rn[r]&&(s[r]=i[r]*n[r]);var o={l:Math.trunc(i.w/2-s.w/2+i.l),t:Math.trunc(i.h/2-s.h/2+i.t)};this.popups[t].window=window.open(this.settings.url,t,"width="+s.w+",height="+s.h+",top="+o.t+",left="+o.l),this.popups[t].timer=window.setInterval(function(){e.popups[t].window&&!1===e.popups[t].window.closed||(window.clearInterval(e.popups[t].timer),e.popups[t]=void 0)},200)}else this.popups[t].window.focus()}},postSettings:function(t){this.popups[t].window.postMessage({id:t,settings:this.settings},this.settings.url)},liveBind:function(t,e,i){document.addEventListener(e,function(e){var s=document.querySelectorAll(t);if(s){for(var n=e.target,r=-1;n&&-1===(r=Array.prototype.indexOf.call(s,n));)n=n.parentElement;r>-1&&(e.preventDefault(),i.call(e,n))}},!0)},prepare:function(){var t=this;this.ns.dataPlugin="data-"+this.ns.plugin,this.ns.dataPluginId=this.ns.dataPlugin+"-id",this.ns.dataPluginTrigger=this.ns.dataPlugin+"-trigger",this.ns.dataPluginTarget=this.ns.dataPlugin+"-target",this.ns.pluginStyle=this.ns.plugin+"-style",this.ns.selDataPluginTrigger="["+this.ns.dataPluginTrigger+"]";var e=document.currentScript||document.getElementById(this.ns.plugin+"-src");e?e.dataset.buttonTemplate&&(e.dataset.html=e.dataset.buttonTemplate):e={dataset:{}};var i=0;for(var s in this.settings={},this.defaultSettings){var n=e&&e.dataset[s]?e.dataset[s]:this.defaultSettings[s];"1"!==n&&"0"!==n||(n="true"==n),"string"==typeof n&&this.classProps.indexOf(s.replace(/Class$/,""))>-1&&(i=1),this.settings[s]=n}if("auto"==this.settings.vendor)for(var s in this.settings.vendor="default",this.settings.fitEditor=0,this.vendors)if("default"!=s&&void 0!==window[this.vendors[s].check]){this.settings.vendor=s;break}var r=["lang","url","vendor","target"];"default"==this.settings.vendor&&(this.vendors.default.settings={});var o=this.vendors[this.settings.vendor];if(o.settings)for(var s in o.settings)e&&e.dataset.hasOwnProperty(s)||(this.settings[s]=o.settings[s]);else for(var s in o.settings={},this.defaultSettings)-1==r.indexOf(s)&&(o.settings[s]=this.defaultSettings[s]);if("default"!==this.settings.vendor)if(o.settings.hasOwnProperty("fitEditor")||e.dataset.hasOwnProperty("fitEditor")||(this.settings.fitEditor=1),this.settings.fitEditor)i=!o.settings.css;else{r=["autoInsert","observe","observeCache"];for(var s in o.settings)-1!=r.indexOf(s)||e.dataset.hasOwnProperty(s)||(this.settings[s]=this.defaultSettings[s])}if(i)this.settings.css="";else{this.settings.css=this.settings.css.replace("%defaultCSS",this.defaultSettings.css),o.settings.extracss&&this.settings.css&&(this.settings.css+=o.settings.extracss);var a=this.settings.palette.split(",");a.length>1?this.palette=a:this.palettes.hasOwnProperty(a)||(this.settings.palette="default"),this.palette||(this.palette=(this.settings.fitEditor&&o.palettes&&o.palettes[this.settings.palette]?o:this).palettes[this.settings.palette])}for(var l=this.classProps,d=0;d0)for(d=0;d
为了便于理解,我们需要格式化js代码,可以通过在线工具JavaScript格式化来格式化代码。
格式化后的js代码如下:
(function() {
for (var t = {
defaultSettings: {
url: "https://demo.chevereto.com/upload",
vendor: "auto",
mode: "auto",
lang: "auto",
autoInsert: "bbcode-embed-medium",
palette: "default",
init: "onload",
containerClass: 1,
buttonClass: 1,
sibling: 0,
siblingPos: "after",
fitEditor: 0,
observe: 0,
observeCache: 1,
html: '<div class="%cClass"><button %x class="%bClass"><span class="%iClass">%iconSvg</span><span class="%tClass">%text</span></button></div>',
css: ".%cClass{display:inline-block;margin-top:5px;margin-bottom:5px}.%bClass{line-height:normal;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;outline:0;color:%2;border:none;cursor:pointer;border:1px solid rgba(0,0,0,.15);background:%1;border-radius:.2em;padding:.5em 1em;font-size:12px;font-weight:700;text-shadow:none}.%bClass:hover{background:%3;color:%4;border-color:rgba(0,0,0,.1)}.%iClass,.%tClass{display:inline-block;vertical-align:middle}.%iClass svg{display:block;width:1em;height:1em;fill:currentColor}.%tClass{margin-left:.25em}"
},
ns: {
plugin: "chevereto-pup"
},
palettes: {
default:
["#ececec", "#333", "#2980b9", "#fff"],
clear: ["inherit", "inherit", "inherit", "#2980b9"],
turquoise: ["#16a085", "#fff", "#1abc9c", "#fff"],
green: ["#27ae60", "#fff", "#2ecc71", "#fff"],
blue: ["#2980b9", "#fff", "#3498db", "#fff"],
purple: ["#8e44ad", "#fff", "#9b59b6", "#fff"],
darkblue: ["#2c3e50", "#fff", "#34495e", "#fff"],
yellow: ["#f39c12", "#fff", "#f1c40f", "#fff"],
orange: ["#d35400", "#fff", "#e67e22", "#fff"],
red: ["#c0392b", "#fff", "#e74c3c", "#fff"],
grey: ["#ececec", "#000", "#e0e0e0", "#000"],
black: ["#333", "#fff", "#666", "#fff"]
},
classProps: ["button", "container"],
iconSvg: '<svg class="%iClass" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M76.7 87.5c12.8 0 23.3-13.3 23.3-29.4 0-13.6-5.2-25.7-15.4-27.5 0 0-3.5-0.7-5.6 1.7 0 0 0.6 9.4-2.9 12.6 0 0 8.7-32.4-23.7-32.4 -29.3 0-22.5 34.5-22.5 34.5 -5-6.4-0.6-19.6-0.6-19.6 -2.5-2.6-6.1-2.5-6.1-2.5C10.9 25 0 39.1 0 54.6c0 15.5 9.3 32.7 29.3 32.7 2 0 6.4 0 11.7 0V68.5h-13l22-22 22 22H59v18.8C68.6 87.4 76.7 87.5 76.7 87.5z" style="fill: currentcolor;"/></svg>',
l10n: {
ar: "تحميل الصور",
cs: "Nahrát obrázky",
da: "Upload billeder",
de: "Bilder hochladen",
es: "Subir imágenes",
fi: "Lataa kuvia",
fr: "Importer des images",
id: "Unggah gambar",
it: "Carica immagini",
ja: "画像をアップロード",
nb: "Last opp bilder",
nl: "Upload afbeeldingen",
pl: "Wyślij obrazy",
pt_BR: "Enviar imagens",
ru: "Загрузить изображения",
tr: "Resim Yukle",
uk: "Завантажити зображення",
zh_CN: "上传图片",
zh_TW: "上傳圖片"
},
vendors: {
default:
{
check:
function() {
return 1
},
getEditor: function() {
var t = {
textarea: {
name: ["recaptcha", "search", "recipients", "coppa", "^comment_list", "username_list", "add"]
},
ce: {
dataset: ["gramm"]
}
},
e = ["~", "|", "^", "$", "*"],
i = {};
for (var s in t) {
i[s] = "";
var n = t[s];
for (var r in n) for (var o = 0; o < n[r].length; o++) {
var a = "",
l = n[r][o],
d = l.charAt(0);
e.indexOf(d) > -1 && (a = d, l = l.substring(1)),
i[s] += ":not([" + ("dataset" == r ? "data-" + l: r + a + '="' + l + '"') + "])"
}
}
return document.querySelectorAll('[contenteditable=""]' + i.ce + ',[contenteditable="true"]' + i.ce + ",textarea:not([readonly])" + i.textarea)
}
},
bbpress: {
settings: {
autoInsert: "html-embed-medium",
html: '<input %x type="button" class="ed_button button button-small" aria-label="%text" value="%text">',
sibling: "#qt_bbp_reply_content_img",
siblingPos: "before"
},
check: "bbpEngagementJS"
},
discourse: {
settings: {
autoInsert: "markdown-embed-medium",
html: '<button %x title="%text" class="upload btn no-text btn-icon ember-view"><i class="fa fa-cloud-upload d-icon d-icon-upload"></i></button>',
sibling: ".upload.btn",
siblingPos: "before",
observe: ".create,#create-topic,.usercard-controls button",
observeCache: 0,
onDemand: 1
},
check: "Discourse"
},
discuz: {
settings: {
buttonClass: 1,
html: '<a %x title="%text" class="%bClass">%iconSvg</a>',
sibling: ".fclr,#e_attach",
css: "a.%bClass,.bar a.%bClass{box-sizing:border-box;cursor:pointer;background:%1;color:%2;text-indent:unset;position:relative}.b1r a.%bClass:hover,a.%bClass:hover{background:%3;color:%4}a.%bClass{font-size:14px}.b1r a.%bClass{border:1px solid rgba(0,0,0,.15)!important;font-size:20px;padding:0;height:44px}.%bClass svg{font-size:1em;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}",
palette: "purple"
},
palettes: {
default:
["transparent", "#333", "#2980b9", "#fff"]
},
check: "DISCUZCODE",
getEditor: function() {
return document.querySelector('.area textarea[name="message"]')
}
},
ipb: {
settings: {
autoInsert: "html-embed-medium",
html: '<a %x class="cke_button cke_button_off %bClass" title="%text" tabindex="-1" hidefocus="true" role="button"><span class="cke_button_icon">%iconSvg</span><span class="cke_button_label" aria-hidden="false">%text</span><span class="cke_button_label" aria-hidden="false"></span></a>',
sibling: ".cke_button__ipslink",
siblingPos: "before",
css: ".cke_button.%bClass{background:%1;position:relative}.cke_button.%bClass:hover{background:%3;border-color:%5}.cke_button.%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:%2}.cke_button.%bClass:hover svg{fill:%4}"
},
palettes: {
default:
["inherit", "#444", "", "inherit"]
},
check: "ips",
getEditorFn: function() {
var t = this.getEditor().dataset.ipseditorName;
return CKEDITOR.instances[t]
},
getEditor: function() {
return document.querySelector("[data-ipseditor-name]")
},
editorValue: function(t) {
var e = CKEDITOR.dom.element.createFromHtml("<p>" + t + "</p>");
this.getEditorFn().insertElement(e)
},
useCustomEditor: function() {
return 1
}
},
mybb: {
settings: {
sibling: "#quickreply_e > tr > td > *:last-child, .sceditor-container",
fitEditor: 0,
extracss: ".trow2 .%cClass{margin-bottom:0}"
},
check: "MyBB",
getEditor: function() {
return MyBBEditor ? MyBBEditor.getContentAreaContainer().parentElement: document.querySelector("#quickreply_e textarea")
},
editorValue: function(t) {
if (MyBBEditor) {
var e = MyBBEditor.inSourceMode() ? "insert": "wysiwygEditorInsertHtml";
MyBBEditor[e]("insert" == e ? t: MyBBEditor.fromBBCode(t))
} else this.getEditor().value += t
},
useCustomEditor: function() {
return !! MyBBEditor
}
},
nodebb: {
settings: {
autoInsert: "markdown-embed-medium",
html: '<li %x tabindex="-1" title="%text"><i class="fa fa-cloud-upload"></i></li>',
sibling: '[data-format="picture-o"]',
siblingPos: "before",
observe: '[component="category/post"],[component="topic/reply"],[component="topic/reply-as-topic"],[component="post/reply"],[component="post/quote"]',
observeCache: 0,
onDemand: 1
},
check: "__nodebbSpamBeGoneCreateCaptcha__",
callback: function() {
for (var t = document.querySelectorAll(".btn-toolbar .img-upload-btn"), e = 0; e < t.length; e++) t[e].parentNode.removeChild(t[e])
}
},
phpbb: {
settings: {
html: document.querySelector("#format-buttons *:first-child") && "BUTTON" == document.querySelector("#format-buttons *:first-child").tagName ? ' <button %x type="button" class="button button-icon-only" title="%text"><i class="icon fa-cloud-upload fa-fw" aria-hidden="true"></i></button> ': ' <input %x type="button" class="button2" value="%text"> ',
sibling: document.querySelector("#format-buttons *:first-child") && "BUTTON" == document.querySelector("#format-buttons *:first-child").tagName ? ".bbcode-img": "#message-box textarea.inputbox",
siblingPos: "after"
},
check: "phpbb",
getEditor: function() {
if ("undefined" != typeof form_name && "undefined" != typeof text_name) return document.forms[form_name].elements[text_name]
}
},
proboards: {
settings: {
html: ' <input %x type="submit" value="%text"> ',
css: "",
sibling: "input[type=submit]",
siblingPos: "before"
},
check: "proboards",
editorValue: function(t) {
var e = $(".wysiwyg-textarea").data("wysiwyg"),
i = e.editors[e.currentEditorName];
i.setContent(i.getContent() + t)
},
useCustomEditor: function() {
return 1 !== $(".container.quick-reply").size()
},
getEditor: function() {
return document.querySelector("textarea[name=message]")
}
},
redactor2: {
getEditor: function() {
var t = this.getEditorFn();
return t ? this.useCustomEditor() ? t.$box[0] : t[0] : null
},
getEditorEl: function() {
return this.useCustomEditor() ? this.getEditorFn().$editor[0] : this.getEditorFn()[0]
},
editorValue: function(t) {
var e = "<p><br></p>",
i = this.useCustomEditor() ? "innerHTML": "value";
if ("string" != typeof t) {
var s = this.getEditorEl()[i];
return this.useCustomEditor() && "<p><br></p>" == s ? "": this.getEditorEl()[i]
}
if (this.useCustomEditor()) {
var n = "<p>" + t + "</p>";
this.getEditorFn().insert.html("" !== this.editorValue() ? e + n: n)
} else this.getEditorEl()[i] = t
},
useCustomEditor: function() {
return ! (this.getEditorFn() instanceof jQuery)
}
},
smf: {
settings: {
html: ' <button %x title="%text" class="%bClass"><span class="%iClass">%iconSvg</span><span class="%tClass">%text</span></button> ',
css: "%defaultCSS #bbcBox_message .%bClass{margin-right:1px;transition:none;color:%2;padding:0;width:23px;height:21px;border-radius:5px;background-color:%1}#bbcBox_message .%bClass:hover{background-color:%3}#bbcBox_message .%tClass{display:none}",
sibling: "#BBCBox_message_button_1_1,.quickReplyContent + div",
siblingPos: "before",
fitEditor: 1
},
palettes: {
default:
["#E7E7E7", "#333", "#B0C4D6", "#333"]
},
check: "smf_scripturl",
getEditor: function() {
return smf_editorArray.length > 0 ? smf_editorArray[0].oTextHandle: document.querySelector(".quickReplyContent textarea")
}
},
quill: {
settings: {
autoInsert: "html-embed-medium",
html: '<li class="richEditor-menuItem richEditor-menuItem_f1af88yq" role="menuitem"><button %x class="richEditor-button richEditor-embedButton richEditor-button_f1fodmu3" type="button" aria-pressed="false"><span class="richEditor-iconWrap_f13bdese"></span>%iconSvg</button></li>',
sibling: "ul.richEditor-menuItems li.richEditor-menuItem:last-child",
css: ".%iClass {display: block; height: 24px; margin: auto; width: 24px;}"
},
check: "quill",
editorValue: function(t) {
quill.clipboard.dangerouslyPasteHTML("\n" == quill.getText() ? 0 : quill.getLength(), t)
},
useCustomEditor: function() {
return 1
},
getEditor: function() {
return quill.container
}
},
vanilla: {
settings: {
autoInsert: "markdown-embed-medium",
html: '<span %x class="fas fa-cloud-upload-alt" title="%text"></span>',
sibling: ".editor-dropdown-upload"
},
check: "Vanilla",
getEditor: function() {
return document.getElementById("Form_Body")
}
},
vbulletin: {
settings: {
autoInsert: "html-embed-medium",
html: '<li %x class="%bClass b-toolbar__item b-toolbar__item--secondary" title="%text" tabindex="0">%iconSvg</li>',
sibling: ".b-toolbar__item--secondary:first-child",
siblingPos: "before",
css: ".%bClass{background:%1;color:%2;position:relative}.%bClass:hover{background:%3;color:%4;border-color:%5}.%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}"
},
palettes: {
default:
["", "#4B6977", "", "#007EB8"]
},
check: "vBulletin",
getEditorFn: function() {
var t = this.getEditor().getAttribute("ck-editorid");
return CKEDITOR.instances[t]
},
getEditor: function() {
return document.querySelector("[data-message-type]")
},
editorValue: function(t) {
var e = CKEDITOR.dom.element.createFromHtml("<p>" + t + "</p>");
this.getEditorFn().insertElement(e)
},
useCustomEditor: function() {
return 1
}
},
WoltLab: {
settings: {
autoInsert: "html-embed-medium",
sibling: 'li[data-name="settings"]',
html: '<li %x><a><span class="icon icon16 fa-cloud-upload"></span> <span>%text</span></a></li>'
},
check: "WBB",
getEditorFn: function() {
var t = $("#text").data("redactor");
return t || null
}
},
XF1: {
settings: {
autoInsert: "html-embed-medium",
containerClass: 1,
buttonClass: 1,
html: '<li class="%cClass"><a %x class="%bClass" unselectable="on" title="%text">%iconSvg</a></li>',
sibling: ".redactor_btn_container_image",
siblingPos: "before",
css: "li.%cClass .%bClass{background:%1;color:%2;text-indent:unset;border-radius:3px;position:relative}li.%cClass a.%bClass:hover{background:%3;color:%4;border-color:%5}.%cClass .%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}",
observe: ".edit.OverlayTrigger",
observeCache: 1
},
palettes: {
default:
["none", "inherit", "none", "inherit", ""]
},
check: "XenForo",
getEditorFn: function() {
var t = document.querySelector("#exposeMask") && document.querySelector("#exposeMask").offsetParent ? ".xenOverlay form": "form";
if ("form" !== t) for (var e = document.querySelectorAll(t), i = 0; i < e.length; i++) if (e[i].offsetParent) {
t += '[action="' + e[i].getAttribute("action") + '"]';
break
}
return XenForo.getEditorInForm(t)
},
getEditor: function() {
var t = this.getEditorFn();
return t ? this.useCustomEditor() ? t.$box[0] : t[0] : null
},
getEditorEl: function() {
return this.useCustomEditor() ? this.getEditorFn().$editor[0] : this.getEditorFn()[0]
},
editorValue: function(t) {
var e = "<p><br></p>",
i = this.useCustomEditor() ? "innerHTML": "value";
if ("string" != typeof t) {
var s = this.getEditorEl()[i];
return this.useCustomEditor() && "<p><br></p>" == s ? "": this.getEditorEl()[i]
}
if (this.useCustomEditor()) {
var n = "<p>" + t + "</p>";
this.getEditorFn().insertHtml("" !== this.editorValue() ? e + n: n)
} else this.getEditorEl()[i] = t
},
useCustomEditor: function() {
return ! (this.getEditorFn() instanceof jQuery)
}
},
XF2: {
settings: {
autoInsert: "html-embed-medium",
containerClass: 1,
buttonClass: "button--link js-attachmentUpload button button--icon button--icon--upload fa--xf",
html: '<div class="formButtonGroup"><div class="formButtonGroup-extra"><button type="button" tabindex="-1" role="button" title="%text" class="%bClass" %x><span class="button-text">%text</span></button></div></div>',
sibling: "",
siblingPos: "after",
observe: '[data-xf-click="quick-edit"]',
observeCache: 1
},
palettes: {
default:
["transparent", "#505050", "rgba(20,20,20,0.06)", "#141414"]
},
check: "XF",
getEditorFn: function(t) {
var e = ".js-editor";
return "string" == typeof t && (e = this.getEditorSel(t)),
XF.getEditorInContainer($(e))
},
getEditorSel: function(e) {
return "[" + t.ns.dataPluginTarget + '="' + e + '"]'
},
getEditor: function(t) {
return "string" == typeof t ? document.querySelector(this.getEditorSel(t)) : document.querySelectorAll(".js-editor")
},
getBbCode: function(t) {
return t.getTextArea()[0].value
},
editorValue: function(t, e) {
var i = "<p><br></p>",
s = this.getEditorFn(e),
n = s.ed.bbCode.isBbCodeView() ? ["bbCode", "getBbCode", "insertBbCode"] : ["html", "get", "insert"],
r = s.ed[n[0]];
if ("string" != typeof t) {
if (void 0 === r[n[1]]) var o = this.getBbCode(r);
else o = r[n[1]]();
return this.useCustomEditor() && o == i ? "": o
}
var a = "" !== this.editorValue(!1, e);
if ("html" == n[0]) {
var l = "<p>" + t + "</p>";
r[n[2]](a ? i + l: l)
} else {
var d = XF.ajax("POST", XF.canonicalizeUrl("index.php?editor/to-bb-code"), {
html: t
});
d.done(function(t) {
r[n[2]](a ? "\n" + t.bbCode: t.bbCode)
})
}
},
useCustomEditor: function() {
return void 0 !== XF.getEditorInContainer($(".js-editor"))
}
}
},
generateGuid: function() {
var t = (new Date).getTime();
return "undefined" != typeof performance && "function" == typeof performance.now && (t += performance.now()),
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,
function(e) {
var i = (t + 16 * Math.random()) % 16 | 0;
return t = Math.floor(t / 16),
("x" === e ? i: 3 & i | 8).toString(16)
})
},
getNewValue: function(t, e) {
var i = "string" != typeof t.getAttribute("contenteditable") ? "value": "innerHTML",
s = "value" == i ? "\n": "<br>",
n = t[i],
r = e,
o = !1;
if (o && (r = String(e).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """)), 0 == n.length) return r;
var a = "",
l = n.match(/\n+$/g),
d = l ? l[0].split("\n").length: 0;
if (d <= 2) {
var u = 0 == d ? 2 : 1;
a += s.repeat(u)
}
return a + r
},
insertTrigger: function() {
var t, e = this.vendors[this.settings.vendor],
i = this.settings.sibling ? document.querySelectorAll(this.settings.sibling + ":not([" + this.ns.dataPlugin + "])")[0] : 0;
if ("auto" == this.settings.mode) t = this.vendors[e.hasOwnProperty("getEditor") ? this.settings.vendor: "default"].getEditor();
else {
for (var s = document.querySelectorAll("[" + this.ns.dataPluginTrigger + "][data-target]:not([" + this.ns.dataPluginId + "])"), n = [], r = 0; r < s.length; r++) n.push(s[r].dataset.target);
n.length > 0 && (t = document.querySelectorAll(n.join(",")))
}
if (t) {
if (!document.getElementById(this.ns.pluginStyle) && this.settings.css) {
var o = document.createElement("style"),
a = this.settings.css;
a = this.appyTemplate(a),
o.type = "text/css",
o.innerHTML = a.replace(/%p/g, "." + this.ns.plugin),
o.setAttribute("id", this.ns.pluginStyle),
document.body.appendChild(o)
}
t instanceof NodeList || (t = [t]);
var l = 0;
for (r = 0; r < t.length; r++) if (!t[r].getAttribute(this.ns.dataPluginTarget)) {
var d = i || t[r];
d.setAttribute(this.ns.dataPlugin, "sibling"),
d.insertAdjacentHTML({
before: "beforebegin",
after: "afterend"
} [this.settings.siblingPos], this.appyTemplate(this.settings.html));
var u = d.parentElement.querySelector("[" + this.ns.dataPluginTrigger + "]");
this.setBoundId(u, t[r]),
l++
}
this.triggerCounter = l,
"function" == typeof e.callback && e.callback.call()
}
},
appyTemplate: function(t) {
if (!this.cacheTable) {
var e = [{
"%iconSvg": this.iconSvg
},
{
"%text": this.settings.langString
}];
if (this.palette) {
for (var i = /%(\d+)/g,
s = i.exec(t), n = []; null !== s;) - 1 == n.indexOf(s[1]) && n.push(s[1]),
s = i.exec(t);
if (n) {
n.sort(function(t, e) {
return e - t
});
this.vendors[this.settings.vendor];
for (var r = 0; r < n.length; r++) {
var o = n[r] - 1,
a = this.palette[o] || "";
a || "default" === this.settings.vendor || "default" === this.settings.palette || (a = this.palette[o - 2]);
var l = {};
l["%" + n[r]] = a,
e.push(l)
}
}
}
var d = this.settings.buttonClass || this.ns.plugin + "-button",
u = [{
"%cClass": this.settings.containerClass || this.ns.plugin + "-container"
},
{
"%bClass": d
},
{
"%iClass": d + "-icon"
},
{
"%tClass": d + "-text"
},
{
"%x": this.ns.dataPluginTrigger
},
{
"%p": this.ns.plugin
}];
for (r = 0; r < u.length; r++) e.push(u[r]);
this.cacheTable = e
}
return this.strtr(t, this.cacheTable)
},
strtr: function(t, e) {
t = t.toString();
if (!t || void 0 === e) return t;
for (var i = 0; i < e.length; i++) {
var s = e[i];
for (var n in s) void 0 !== s[n] && (re = new RegExp(n, "g"), t = t.replace(re, s[n]))
}
return t
},
setBoundId: function(t, e) {
var i = this.generateGuid();
t.setAttribute(this.ns.dataPluginId, i),
e.setAttribute(this.ns.dataPluginTarget, i)
},
openPopup: function(t) {
if ("string" == typeof t) {
var e = this;
if (void 0 === this.popups && (this.popups = {}), void 0 === this.popups[t]) {
this.popups[t] = {};
var i = {
l: null != window.screenLeft ? window.screenLeft: screen.left,
t: null != window.screenTop ? window.screenTop: screen.top,
w: window.innerWidth ? window.innerWidth: document.documentElement.clientWidth ? document.documentElement.clientWidth: screen.width,
h: window.innerHeight ? window.innerHeight: document.documentElement.clientHeight ? document.documentElement.clientHeight: screen.height
},
s = {
w: 720,
h: 690
},
n = {
w: .5,
h: .85
};
for (var r in s) s[r] / i[r] > n[r] && (s[r] = i[r] * n[r]);
var o = {
l: Math.trunc(i.w / 2 - s.w / 2 + i.l),
t: Math.trunc(i.h / 2 - s.h / 2 + i.t)
};
this.popups[t].window = window.open(this.settings.url, t, "width=" + s.w + ",height=" + s.h + ",top=" + o.t + ",left=" + o.l),
this.popups[t].timer = window.setInterval(function() {
e.popups[t].window && !1 === e.popups[t].window.closed || (window.clearInterval(e.popups[t].timer), e.popups[t] = void 0)
},
200)
} else this.popups[t].window.focus()
}
},
postSettings: function(t) {
this.popups[t].window.postMessage({
id: t,
settings: this.settings
},
this.settings.url)
},
liveBind: function(t, e, i) {
document.addEventListener(e,
function(e) {
var s = document.querySelectorAll(t);
if (s) {
for (var n = e.target,
r = -1; n && -1 === (r = Array.prototype.indexOf.call(s, n));) n = n.parentElement;
r > -1 && (e.preventDefault(), i.call(e, n))
}
},
!0)
},
prepare: function() {
var t = this;
this.ns.dataPlugin = "data-" + this.ns.plugin,
this.ns.dataPluginId = this.ns.dataPlugin + "-id",
this.ns.dataPluginTrigger = this.ns.dataPlugin + "-trigger",
this.ns.dataPluginTarget = this.ns.dataPlugin + "-target",
this.ns.pluginStyle = this.ns.plugin + "-style",
this.ns.selDataPluginTrigger = "[" + this.ns.dataPluginTrigger + "]";
var e = document.currentScript || document.getElementById(this.ns.plugin + "-src");
e ? e.dataset.buttonTemplate && (e.dataset.html = e.dataset.buttonTemplate) : e = {
dataset: {}
};
var i = 0;
for (var s in this.settings = {},
this.defaultSettings) {
var n = e && e.dataset[s] ? e.dataset[s] : this.defaultSettings[s];
"1" !== n && "0" !== n || (n = "true" == n),
"string" == typeof n && this.classProps.indexOf(s.replace(/Class$/, "")) > -1 && (i = 1),
this.settings[s] = n
}
if ("auto" == this.settings.vendor) for (var s in this.settings.vendor = "default",
this.settings.fitEditor = 0,
this.vendors) if ("default" != s && void 0 !== window[this.vendors[s].check]) {
this.settings.vendor = s;
break
}
var r = ["lang", "url", "vendor", "target"];
"default" == this.settings.vendor && (this.vendors.
default.settings = {});
var o = this.vendors[this.settings.vendor];
if (o.settings) for (var s in o.settings) e && e.dataset.hasOwnProperty(s) || (this.settings[s] = o.settings[s]);
else for (var s in o.settings = {},
this.defaultSettings) - 1 == r.indexOf(s) && (o.settings[s] = this.defaultSettings[s]);
if ("default" !== this.settings.vendor) if (o.settings.hasOwnProperty("fitEditor") || e.dataset.hasOwnProperty("fitEditor") || (this.settings.fitEditor = 1), this.settings.fitEditor) i = !o.settings.css;
else {
r = ["autoInsert", "observe", "observeCache"];
for (var s in o.settings) - 1 != r.indexOf(s) || e.dataset.hasOwnProperty(s) || (this.settings[s] = this.defaultSettings[s])
}
if (i) this.settings.css = "";
else {
this.settings.css = this.settings.css.replace("%defaultCSS", this.defaultSettings.css),
o.settings.extracss && this.settings.css && (this.settings.css += o.settings.extracss);
var a = this.settings.palette.split(",");
a.length > 1 ? this.palette = a: this.palettes.hasOwnProperty(a) || (this.settings.palette = "default"),
this.palette || (this.palette = (this.settings.fitEditor && o.palettes && o.palettes[this.settings.palette] ? o: this).palettes[this.settings.palette])
}
for (var l = this.classProps,
d = 0; d < l.length; d++) {
var u = l[d] + "Class";
"string" != typeof this.settings[u] && (this.settings[u] = this.ns.plugin + "-" + l[d], this.settings.fitEditor && (this.settings[u] += "--" + this.settings.vendor))
}
var c = ("auto" == this.settings.lang ? navigator.language || navigator.userLanguage: this.settings.lang).replace("-", "_");
this.settings.langString = "Upload images";
var g = c in this.l10n ? c: c.substring(0, 2) in this.l10n ? c.substring(0, 2) : null;
g && (this.settings.langString = this.l10n[g]);
var h = document.createElement("a");
h.href = this.settings.url,
this.originUrlPattern = "^" + (h.protocol + "//" + h.hostname).replace(/\./g, "\\.").replace(/\//g, "\\/") + "$";
var f = document.querySelectorAll(this.ns.selDataPluginTrigger + "[data-target]");
if (f.length > 0) for (d = 0; d < f.length; d++) {
var p = document.querySelector(f[d].dataset.target);
this.setBoundId(f[d], p)
}
if (this.settings.observe) {
var b = this.settings.observe;
this.settings.observeCache && (b += ":not([" + this.ns.dataPlugin + "])"),
this.liveBind(b, "click",
function(e) {
e.setAttribute(t.ns.dataPlugin, 1),
t.observe()
}.bind(this))
}
this.settings.sibling && !this.settings.onDemand ? this.waitForSibling() : "onload" == this.settings.init ? "loading" === document.readyState ? document.addEventListener("DOMContentLoaded",
function(e) {
t.init()
},
!1) : this.init() : this.observe()
},
observe: function() {
this.waitForSibling("observe")
},
waitForSibling: function(t) {
var e = this.initialized ? "insertTrigger": "init";
if (this.settings.sibling) var i = document.querySelector(this.settings.sibling + ":not([" + this.ns.dataPlugin + "])");
else if ("observe" == t && (this[e](), this.triggerCounter)) return;
if (i) this[e]();
else {
if ("complete" === document.readyState && "observe" !== t) return;
setTimeout(("observe" == t ? this.observe: this.waitForSibling).bind(this), 250)
}
},
init: function() {
this.insertTrigger();
var t = this,
e = this.vendors[this.settings.vendor];
this.liveBind(this.ns.selDataPluginTrigger, "click",
function(e) {
var i = e.getAttribute(t.ns.dataPluginId);
t.openPopup(i)
}),
window.addEventListener("message",
function(i) {
var s = new RegExp(t.originUrlPattern, "i");
if (s.test(i.origin) || void 0 !== i.data.id && void 0 !== i.data.message) {
var n = i.data.id;
if (n && i.source === t.popups[n].window) if (i.data.requestAction && t.hasOwnProperty(i.data.requestAction)) t[i.data.requestAction](n);
else {
var r;
if ("default" !== t.settings.vendor) {
if (e.hasOwnProperty("useCustomEditor") && e.useCustomEditor()) return void e.editorValue(i.data.message, n);
e.hasOwnProperty("getEditor") && (r = e.getEditor())
}
if (r || (r = document.querySelector("[" + t.ns.dataPluginTarget + '="' + n + '"]'), r)) {
var o = null === r.getAttribute("contenteditable") ? "value": "innerHTML";
r[o] += t.getNewValue(r, i.data.message);
for (var a = ["blur", "focus", "input", "change", "paste"], l = 0; l < a.length; l++) {
var d = new Event(a[l]);
r.dispatchEvent(d)
}
} else alert("Target not found")
}
}
},
!1),
this.initialized = 1
}
},
e = ["WoltLab", "XF1"], i = 0; i < e.length; i++) t.vendors[e[i]] = Object.assign(Object.assign({},
t.vendors.redactor2), t.vendors[e[i]]);
t.prepare()
})();
url: "https://demo.chevereto.com/upload"
修改为目标图床的上传链接,如
url: "https://pic.6zs.cn/upload"
将mode: "auto"
改为mode: "manual"
,即让js默认不自动放置上传按钮。
将autoInsert: "bbcode-embed-medium"
修改为autoInsert: "html-embed"
,即让js自动返回HTML格式的图片链接。
另外一个可选的修改项是上传按钮的外观样式,palette: "default"
,有下面多种外观可选,如果你想使用black样式,将palette: "default"
修改为palette: "black"
即可。
default:
["#ececec", "#333", "#2980b9", "#fff"],
clear: ["inherit", "inherit", "inherit", "#2980b9"],
turquoise: ["#16a085", "#fff", "#1abc9c", "#fff"],
green: ["#27ae60", "#fff", "#2ecc71", "#fff"],
blue: ["#2980b9", "#fff", "#3498db", "#fff"],
purple: ["#8e44ad", "#fff", "#9b59b6", "#fff"],
darkblue: ["#2c3e50", "#fff", "#34495e", "#fff"],
yellow: ["#f39c12", "#fff", "#f1c40f", "#fff"],
orange: ["#d35400", "#fff", "#e67e22", "#fff"],
red: ["#c0392b", "#fff", "#e74c3c", "#fff"],
grey: ["#ececec", "#000", "#e0e0e0", "#000"],
black: ["#333", "#fff", "#666", "#fff"]
修改完成的部分代码如下:
(function() {
for (var t = {
defaultSettings: {
url: "https://pic.6zs.cn/upload",
vendor: "auto",
mode: "manual",
lang: "auto",
autoInsert: "html-embed",
palette: "black",
init: "onload",
containerClass: 1,
buttonClass: 1,
sibling: 0,
siblingPos: "after",
fitEditor: 0,
observe: 0,
observeCache: 1,
html: '<div class="%cClass"><button %x class="%bClass"><span class="%iClass">%iconSvg</span><span class="%tClass">%text</span></button></div>',
css: ".%cClass{display:inline-block;margin-top:5px;margin-bottom:5px}.%bClass{line-height:normal;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;outline:0;color:%2;border:none;cursor:pointer;border:1px solid rgba(0,0,0,.15);background:%1;border-radius:.2em;padding:.5em 1em;font-size:12px;font-weight:700;text-shadow:none}.%bClass:hover{background:%3;color:%4;border-color:rgba(0,0,0,.1)}.%iClass,.%tClass{display:inline-block;vertical-align:middle}.%iClass svg{display:block;width:1em;height:1em;fill:currentColor}.%tClass{margin-left:.25em}"
},
将修改后的pup.js保存到网站的js目录,如放到/usr/themes/handsome/assets/js
目录下,此时pup.js的文件路径为/usr/themes/handsome/assets/js/pup.js
之后和前边一样,将
<script async src="/usr/themes/handsome/assets/js/pup.js"></script>
放入到head之中,此时只是单纯引入js即可,不必指定参数data-auto-insert="html-embed" data-mode="manual"
和上传链接url="https://pic.6zs.cn/upload"
,因为参数已经在js里边写死了。
最后一步,需要增加PJAX回调函数使pup.js跟随页面重载,在回调函数中写入
$.getScript("/usr/themes/handsome/assets/js/pup.js")
到这了,本文差不多结束了,来总结一下:
- 放行HTML标签
- 获取图床上传插件
- 将插件代码插入到<#head>中
- 新建按钮,并放在合适的位置
- 给按钮美化一下
- 配置PJAX函数回调
如果要更换图床怎么办?如果你能够解决PJAX回调,只需要把插件链接里的
src="//www.picb.cc/sdk/pup.js" data-url="https://www.picb.cc/upload"
替换掉即可。注意要保留data-auto-insert="html-embed" data-mode="manual"
这两个参数。
如果你不会PJAX回调,直接修改js文件里的url: "https://pic.6zs.cn/upload"
,将链接修改为目标图床的链接即可。
最后,分享一些使用Chevereto搭建的图床
- PICBCC:https://www.picb.cc/
- 路过图床:https://imgtu.com/
- 知晓图床:https://tu.jilu.info/
- SM图床:https://www.imgsm.com/
- 鸡霸图床(老王图床):https://img.gejiba.com/
- 靠谱图床:https://img.bqe.cc/
- 伏名图床:https://ccsyn.org/
- 安享图床:https://img.ax/
本站图床由:https://pic.6zs.cn/提供。
完结!感谢您的阅览。
Comments 7 条评论
zc
@Sky390