hugo-theme-roland/static/js/iDisqus.js

1592 lines
72 KiB
JavaScript
Raw Normal View History

2021-07-09 14:54:40 +00:00
/*!
* v 0.2.11
*
* https://github.com/fooleap/disqus-php-api
*
* Copyright 2017-2018 fooleap
* Released under the MIT license
*/
(function (global) {
'use strict';
var d = document,
l = localStorage,
scripts = d.scripts,
lasturl = scripts[scripts.length - 1].src,
filepath = lasturl.substring(0, lasturl.lastIndexOf('/')),
isEdge = navigator.userAgent.indexOf("Edge") > -1,
isIE = !!window.ActiveXObject || "ActiveXObject" in window;
function getLocation(href) {
var link = d.createElement('a');
link.href = href;
return link;
}
function getAjax(url, success, error) {
var xhr = new XMLHttpRequest();
xhr.open ('GET', encodeURI(url));
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
success(xhr.responseText);
}
}
xhr.onerror = error;
xhr.withCredentials = true;
xhr.send();
return xhr;
}
function postAjax(url, data, success, error) {
var params = typeof data == 'string' ? data : Object.keys(data).map(
function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }
).join('&');
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
success(xhr.responseText);
}
};
xhr.onerror = error;
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(params);
return xhr;
}
// matches & closest polyfill https://github.com/jonathantneal/closest
(function (ElementProto) {
if (typeof ElementProto.matches !== 'function') {
ElementProto.matches = ElementProto.msMatchesSelector || ElementProto.mozMatchesSelector || ElementProto.webkitMatchesSelector || function matches(selector) {
var element = this;
var elements = (element.document || element.ownerDocument).querySelectorAll(selector);
var index = 0;
while (elements[index] && elements[index] !== element) {
++index;
}
return Boolean(elements[index]);
};
}
if (typeof ElementProto.closest !== 'function') {
ElementProto.closest = function closest(selector) {
var element = this;
while (element && element.nodeType === 1) {
if (element.matches(selector)) {
return element;
}
element = element.parentNode;
}
return null;
};
}
})(window.Element.prototype);
// 访客信息
var User = function () {
this.dom = arguments[0];
this.opts = arguments[1];
this.init();
this.autologin();
}
User.prototype = {
// 初始化访客信息
init: function(){
var _ = this;
// 读取访客信息
_.name = l.getItem('name');
_.email = l.getItem('email');
_.url = l.getItem('url');
_.avatar = l.getItem('avatar');
_.type = l.getItem('type');
_.logged_in = l.getItem('logged_in');
var boxarr = _.dom.getElementsByClassName('comment-box');
if( _.logged_in == 'true' ) {
[].forEach.call(boxarr,function(item){
if(_.type == '1'){
item.querySelector('.comment-form-wrapper').classList.add('logged-in');
}
item.querySelector('.comment-form-name').value = _.name;
item.querySelector('.comment-form-email').value = _.email;
item.querySelector('.comment-form-url').value = _.url;
item.querySelector('.comment-avatar-image').src = _.avatar;
});
} else {
[].forEach.call(boxarr,function(item){
item.querySelector('.comment-form-wrapper').classList.remove('logged-in');
item.querySelector('.comment-form-name').value = '';
item.querySelector('.comment-form-email').value = '';
item.querySelector('.comment-form-url').value = '';
item.querySelector('.comment-avatar-image').src = _.dom.querySelector('.comment-avatar-image').dataset.avatar;
});
l.setItem('logged_in', 'false');
}
},
// 自动登录
autologin: function(){
var _ = this;
getAjax( _.opts.api +'/user.php', function(resp){
var data = JSON.parse(resp);
if( data.code == 0 ){
_.submit(data.response);
} else {
if( _.type == '1' ){
l.setItem('logged_in', 'false');
_.init();
}
}
}, function(){
})
},
// 登录
login: function(){
var _ = this;
var popup = window.open(_.opts.api+'/login.php', 'Disqus Oauth', 'width=470,height=508');
var timer;
function isLogged(){
if (!popup || !popup.closed) return;
clearInterval(timer);
_.user.autologin();
}
timer = setInterval(isLogged, 100);
},
// 退出登录
logout: function(){
var _ = this;
postAjax( _.opts.api + '/logout.php', {}, function(resp){
l.setItem('logged_in', 'false');
l.removeItem('type');
l.removeItem('email');
l.removeItem('avatar');
l.removeItem('name');
l.removeItem('url');
_.user.init();
})
},
// 提交访客信息
submit: function(user){
l.setItem('email', user.email);
l.setItem('type', user.type);
l.setItem('name', user.name);
l.setItem('url', user.url);
l.setItem('avatar', user.avatar);
l.setItem('logged_in', 'true');
this.init();
}
}
var iDisqus = function () {
var _ = this;
// 配置
_.opts = typeof(arguments[1]) == 'object' ? arguments[1] : arguments[0];
_.dom = d.getElementById(typeof(arguments[0]) == 'string' ? arguments[0] : 'comment');
_.opts.api = _.opts.api.slice(-1) == '/' ? _.opts.api.slice(0,-1) : _.opts.api;
_.opts.site = _.opts.site || location.origin;
if(!!_.opts.url){
var optsUrl = _.opts.url.replace(_.opts.site, '');
_.opts.url = optsUrl.slice(0, 1) != '/' ? '/' + optsUrl : optsUrl;
} else if(isEdge || isIE) {
_.opts.url = encodeURI(location.pathname) + encodeURI(location.search);
} else {
_.opts.url = location.pathname + location.search;
}
_.opts.identifier = _.opts.identifier || _.opts.url;
_.opts.link = _.opts.site + _.opts.url;
_.opts.title = _.opts.title || d.title;
_.opts.slug = !!_.opts.slug ? _.opts.slug.replace(/[^A-Za-z0-9_-]+/g,'') : '';
_.opts.desc = _.opts.desc || (!!d.querySelector('[name="description"]') ? d.querySelector('[name="description"]').content : '');
_.opts.mode = _.opts.mode || 1;
_.opts.timeout = _.opts.timeout || 3000;
_.opts.toggle = !!_.opts.toggle ? d.getElementById(_.opts.toggle) : null;
_.opts.autoCreate = !!_.opts.autoCreate || !!_.opts.auto;
// emoji 表情
_.opts.emojiPath = _.opts.emojiPath || _.opts.emoji_path || 'https://cdn.jsdelivr.net/emojione/assets/png/';
_.emojiList = _.opts.emojiList || _.opts.emoji_list || [{
code:'smile',
title:'笑脸',
unicode:'1f604'
},{
code:'mask',
title:'生病',
unicode:'1f637'
},{
code:'joy',
title:'破涕为笑',
unicode:'1f602'
},{
code:'stuck_out_tongue_closed_eyes',
title:'吐舌',
unicode:'1f61d'
},{
code:'flushed',
title:'脸红',
unicode:'1f633'
},{
code:'scream',
title:'恐惧',
unicode:'1f631'
},{
code:'pensive',
title:'失望',
unicode:'1f614'
},{
code:'unamused',
title:'无语',
unicode:'1f612'
},{
code:'grin',
title:'露齿笑',
unicode:'1f601'
},{
code:'heart_eyes',
title:'色',
unicode:'1f60d'
},{
code:'sweat',
title:'汗',
unicode:'1f613'
},{
code:'smirk',
title:'得意',
unicode:'1f60f'
},{
code:'relieved',
title:'满意',
unicode:'1f60c'
},{
code:'rolling_eyes',
title:'翻白眼',
unicode:'1f644'
},{
code:'ok_hand',
title:'OK',
unicode:'1f44c'
},{
code:'v',
title:'胜利',
unicode:'270c'
}];
if(!!_.opts.emoji_preview || !!_.opts.emojiPreview ){
getAjax(_.opts.api +'/eac.min.php', function(resp){
_.eac = JSON.parse(resp);
}, function(){
})
}
// 默认状态
_.stat = {
current: 'idisqus', // 当前显示评论框
loaded: false, // 评论框已加载
loading: false, // 评论加载中
editing: false, // 评论编辑中
offsetTop: 0, // 高度位置
thread: null, // 本页 thread id
next: null, // 下条评论
message: null, // 新评论
mediaHtml: null, // 新上传图片
root: [], // 根评论
count: 0, // 评论数
users: [], // Disqus 会员
imageSize: [], // 已上传图片大小
disqusLoaded: false // Disqus 已加载
};
// Disqus 评论框设置
window.disqus_config = function () {
this.page.identifier = _.opts.identifier;
this.page.title = _.opts.title;
this.page.url = _.opts.link;
this.callbacks.onReady.push(function() {
_.stat.current = 'disqus';
_.stat.disqusLoaded = true;
_.dom.querySelector('#idisqus').style.display = 'none';
_.dom.querySelector('#disqus_thread').style.display = 'block';
if( _.opts.mode == 3 && !!_.opts.toggle) {
_.opts.toggle.disabled = '';
_.opts.toggle.checked = true;
_.opts.toggle.addEventListener('change', _.handle.toggle, false);
}
});
}
// 自动初始化
if( !!_.opts.init ){
_.init();
//console.log(_);
}
}
// TimeAgo https://coderwall.com/p/uub3pw/javascript-timeago-func-e-g-8-hours-ago
iDisqus.prototype.timeAgo = function() {
var _ = this;
var templates = {
prefix: "",
suffix: "前",
seconds: "几秒",
minute: "1分钟",
minutes: "%d分钟",
hour: "1小时",
hours: "%d小时",
day: "1天",
days: "%d天",
month: "1个月",
months: "%d个月",
year: "1年",
years: "%d年"
};
var template = function (t, n) {
return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n)));
};
var timer = function (time) {
if (!time) return;
time = time.replace(/\.\d+/, ""); // remove milliseconds
time = time.replace(/-/, "/").replace(/-/, "/");
time = time.replace(/T/, " ").replace(/Z/, " UTC");
time = time.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2"); // -04:00 -> -0400
time = new Date(time * 1000 || time);
var now = new Date();
var seconds = ((now.getTime() - time) * .001) >> 0;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
var years = days / 365;
return templates.prefix + ( seconds < 45 && template('seconds', seconds) || seconds < 90 && template('minute', 1) || minutes < 45 && template('minutes', minutes) || minutes < 90 && template('hour', 1) || hours < 24 && template('hours', hours) || hours < 42 && template('day', 1) || days < 30 && template('days', days) || days < 45 && template('month', 1) || days < 365 && template('months', days / 30) || years < 1.5 && template('year', 1) || template('years', years)) + templates.suffix;
};
var elements = _.dom.querySelectorAll('.comment-item-time');
for (var i in elements) {
var $this = elements[i];
if (typeof $this === 'object') {
$this.title = new Date($this.getAttribute('datetime'));
$this.innerHTML = timer($this.getAttribute('datetime'));
}
}
// update time every minute
setTimeout(_.timeAgo.bind(_), 60000);
}
// 初始化评论框
iDisqus.prototype.init = function(){
var _ = this;
if(!_.dom){
//console.log('该页面没有评论框!');
return
}
// 表情
var emojiList = '';
_.emojiList.forEach(function(item){
emojiList += '<li class="emojione-item" title="'+ item.title+'" data-code=":'+item.code+':"><img class="emojione-item-image" src="'+_.opts.emojiPath + item.unicode+'.png" /></li>';
})
_.dom.innerHTML = '<div class="comment loading" id="idisqus">\n'+
' <div class="loading-container" data-tip="正在加载评论……"><svg class="loading-bg" width="72" height="72" viewBox="0 0 720 720" version="1.1" xmlns="http://www.w3.org/2000/svg"><path class="ring" fill="none" stroke="#9d9ea1" d="M 0 -260 A 260 260 0 1 1 -80 -260" transform="translate(400,400)" stroke-width="50" /><polygon transform="translate(305,20)" points="50,0 0,100 18,145 50,82 92,145 100,100" style="fill:#9d9ea1"/></svg></div>\n'+
' <div class="comment-header"><span class="comment-header-item" id="comment-count">评论</span><a target="_blank" class="comment-header-item" id="comment-link">Disqus 讨论区</a></div>\n'+
' <div class="comment-box">\n'+
' <div class="comment-avatar avatar"><img class="comment-avatar-image" src="//a.disquscdn.com/images/noavatar92.png" data-avatar="//a.disquscdn.com/images/noavatar92.png"></div>\n'+
' <div class="comment-form">\n'+
' <div class="comment-form-wrapper">\n'+
' <textarea class="comment-form-textarea" placeholder="加入讨论……"></textarea>\n'+
' <div class="comment-form-alert"></div>\n'+
' <div class="comment-image">\n'+
' <ul class="comment-image-list"></ul>\n'+
' <div class="comment-image-progress">\n'+
' <div class="comment-image-loaded"></div>\n'+
' </div>\n'+
' </div>\n'+
' <div class="comment-actions">\n'+
' <div class="comment-actions-group">\n'+
' <input id="emoji-input" class="comment-actions-input" type="checkbox"> \n'+
' <label class="comment-actions-label emojione" for="emoji-input">\n'+
' <svg class="icon" fill="#c2c6cc" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">\n'+
' <g>\n'+
' <title>选择表情</title>\n'+
' <path d="M512 1024c-282.713043 0-512-229.286957-512-512s229.286957-512 512-512c282.713043 0 512 229.286957 512 512S792.486957 1024 512 1024zM512 44.521739c-258.226087 0-467.478261 209.252174-467.478261 467.478261 0 258.226087 209.252174 467.478261 467.478261 467.478261s467.478261-209.252174 467.478261-467.478261C979.478261 253.773913 768 44.521739 512 44.521739z"></path>\n'+
' <path d="M801.391304 554.295652c0 160.278261-129.113043 289.391304-289.391304 289.391304s-289.391304-129.113043-289.391304-289.391304L801.391304 554.295652z"></path>\n'+
' <path d="M674.504348 349.495652m-57.878261 0a2.6 2.6 0 1 0 115.756522 0 2.6 2.6 0 1 0-115.756522 0Z"></path>\n'+
' <path d="M347.269565 349.495652m-57.878261 0a2.6 2.6 0 1 0 115.756522 0 2.6 2.6 0 1 0-115.756522 0Z"></path>\n'+
' </g>\n'+
' </svg>\n'+
' <ul class="emojione-list">'+emojiList+'</ul>\n'+
' </label>\n'+
' <input id="upload-input" class="comment-actions-input comment-image-input" type="file" accept="image/*" name="file"> \n'+
' <label class="comment-actions-label" for="upload-input">\n'+
' <svg class="icon" fill="#c2c6cc" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">\n'+
' <g>\n'+
' <title>上传图片</title>\n'+
' <path d="M15.515152 15.515152 15.515152 15.515152 15.515152 15.515152Z"></path>\n'+
' <path d="M15.515152 139.636364l0 806.787879 992.969697 0 0-806.787879-992.969697 0zM946.424242 884.363636l-868.848485 0 0-682.666667 868.848485 0 0 682.666667zM698.181818 356.848485c0-51.417212 41.673697-93.090909 93.090909-93.090909s93.090909 41.673697 93.090909 93.090909c0 51.417212-41.673697 93.090909-93.090909 93.090909s-93.090909-41.673697-93.090909-93.090909zM884.363636 822.30303l-744.727273 0 186.181818-496.484848 248.242424 310.30303 124.121212-93.090909z"></path>\n'+
' </g>\n'+
' </svg>\n'+
' </label>\n'+
' </div>\n'+
' <div class="comment-actions-form">\n'+
' <label class="comment-actions-label exit" title="退出登录">\n'+
' <svg class="icon" fill="#c2c6cc" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48">\n'+
' <path d="M348.870666 210.685443l378.570081 0c32.8205 0 58.683541 26.561959 58.683541 58.683541 0 162.043606 0 324.804551 0 486.848157 0 32.81129-26.561959 58.674331-58.683541 58.674331L348.870666 814.891472c-10.477632 0-18.850323-8.363482-18.850323-18.841114l0-37.728276c0-10.477632 8.372691-18.841114 18.850323-18.841114l343.645664 0c10.477632 0 18.850323-8.372691 18.850323-18.850323L711.366653 304.983109c0-10.477632-8.372691-18.841114-18.850323-18.841114L348.870666 286.141996c-10.477632 0-18.850323-8.363482-18.850323-18.841114l0-37.728276C329.98248 219.095997 338.393034 210.685443 348.870666 210.685443z"></path>\n'+
' <path d="M128.152728 526.436804l112.450095 112.450095c6.985088 6.985088 19.567661 6.985088 26.552749 0l26.561959-26.561959c6.985088-6.985088 6.985088-19.567661 0-26.552749l-34.925441-34.925441L494.168889 550.84675c10.477632 0 18.850323-8.372691 18.850323-18.850323l0-37.719066c0-10.477632-8.372691-18.850323-18.850323-18.850323L258.754229 475.427036l34.925441-34.925441c6.985088-6.985088 6.985088-19.567661 0-26.552749l-26.561959-26.524097c-6.985088-6.985088-19.567661-6.985088-26.552749 0L128.152728 499.875868C120.431883 506.859933 120.431883 519.451716 128.152728 526.436804z"></path>\n'+
' </svg>\n'+
' </label>\n'+
' <button class="comment-form-submit">\n'+
' <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">\n'+
' <path d="M565.747623 792.837176l260.819261 112.921839 126.910435-845.424882L66.087673 581.973678l232.843092 109.933785 562.612725-511.653099-451.697589 563.616588-5.996574 239.832274L565.747623 792.837176z" fill="#ffffff"></path>\n'+
' </svg>\n'+
' </button>\n'+
' </div>\n'+
' </div>\n'+
' </div>\n'+
' <div class="comment-form-user">'+ ( _.opts.mode != 1 ? '<div class="comment-form-auth"><button class="comment-form-login" title="使用 Disqus 帐号登录"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 200 200"><path fill="#2E9FFF" d="M102.535 167.5c-16.518 0-31.621-6.036-43.298-16.021L30.5 155.405l11.102-27.401A67.658 67.658 0 0 1 35.564 100c0-37.277 29.984-67.5 66.971-67.5 36.984 0 66.965 30.223 66.965 67.5 0 37.284-29.98 67.5-66.965 67.5zm36.567-67.693v-.188c0-19.478-13.736-33.367-37.42-33.367h-25.58v67.5h25.201c23.868.001 37.799-14.468 37.799-33.945zm-37.138 17.361h-7.482V82.841h7.482c10.989 0 18.283 6.265 18.283 17.07v.188c0 10.896-7.294 17.069-18.283 17.069z"/></svg></button></div><span> 或 </span>' : '' ) + '<div class="comment-form-guest"><input class="comment-form-input comment-form-name" type="text" name="name" placeholder="名字(必填)" autocomplete="name"><input class="comment-form-input comment-form-email" type="email" name="email" placeholder="邮箱(必填)" autocomplete="email"><input class="comment-form-input comment-form-url" type="url" name="url" placeholder="网址(可选)" autocomplete="url"></div></div>\n'+
' </div>\n'+
' </div>\n'+
' <ul id="comments" class="comment-list"></ul>\n'+
' <a href="javascript:;" class="comment-loadmore">加载更多</a>\n'+
'</div>\n'+
'<div class="comment" id="disqus_thread"></div>';
_.user = new User(_.dom,_.opts);
_.box = _.dom.querySelector('.comment-box').outerHTML.replace(/<label class="comment-actions-label exit"(.|\n)*<\/label>\n/,'').replace('comment-form-wrapper','comment-form-wrapper editing').replace(/加入讨论……/,'');
_.handle = {
logout: _.user.logout.bind(_),
login: _.user.login.bind(_),
loadMore: _.loadMore.bind(_),
post: _.post.bind(_),
postThread: _.postThread.bind(_),
remove: _.remove.bind(_),
show: _.show.bind(_),
toggle: _.toggle.bind(_),
upload: _.upload.bind(_),
verify: _.verify.bind(_),
jump: _.jump.bind(_),
mention: _.mention.bind(_),
keySelect: _.keySelect.bind(_),
field: _.field,
focus: _.focus,
input: _.input
};
switch(_.opts.mode){
case 1:
_.disqus();
break;
case 2:
_.getlist();
break;
case 3:
_.getlist();
_.disqus();
break;
default:
_.disqus();
break;
}
}
// 切换评论框
iDisqus.prototype.toggle = function(){
var _ = this;
if( _.stat.current == 'disqus' ){
_.stat.current = 'idisqus';
_.dom.querySelector('#idisqus').style.display = 'block';
_.dom.querySelector('#disqus_thread').style.display = 'none';
} else {
_.disqus();
}
}
// 加载 Disqus 评论
iDisqus.prototype.disqus = function(){
var _ = this;
var _tip = _.dom.querySelector('.loading-container').dataset.tip;
//if(_.opts.site != location.origin){
// //console.log('本地环境不加载 Disqus 评论框!');
// if( _.opts.mode == 1 ){
// _.getlist();
// }
// return;
//}
if(!_.stat.disqusLoaded ){
_tip = '尝试连接 Disqus……';
var s = d.createElement('script');
s.src = '//'+_.opts.forum+'.disqus.com/embed.js';
s.dataset.timestamp = Date.now();
s.onload = function(){
_.stat.disqusLoaded = true;
_tip = '连接成功,加载 Disqus 评论框……'
}
s.onerror = function(){
if( _.opts.mode == 1){
_tip = '连接失败,加载简易评论框……';
_.getlist();
}
}
var xhr = new XMLHttpRequest();
xhr.open('GET', '//disqus.com/next/config.json?' + Date.now(), true);
xhr.timeout = _.opts.timeout;
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
(d.head || d.body).appendChild(s);
}
}
xhr.ontimeout = function () {
xhr.abort();
if( _.opts.mode == 1){
_tip = '连接超时,加载简易评论框……';
_.getlist();
}
}
xhr.onerror = function() {
if( _.opts.mode == 1){
_tip = '连接失败,加载简易评论框……';
_.getlist();
}
}
xhr.send();
} else {
_.stat.current = 'disqus';
_.dom.querySelector('#idisqus').style.display = 'none';
_.dom.querySelector('#disqus_thread').style.display = 'block';
}
}
// 添加事件监听
iDisqus.prototype.addListener = function (els, evt, func){
var _ = this;
var el = _.dom.getElementsByClassName(els);
[].forEach.call(el, function(item){
item.addEventListener(evt, func, false);
});
}
// 移除事件监听
iDisqus.prototype.removeListener = function (els, evt, func){
var _ = this;
var el = _.dom.getElementsByClassName(els);
[].forEach.call(el, function(item){
item.removeEventListener(evt, func, false);
});
}
// 添加所有事件监听
iDisqus.prototype.addAllListeners = function (){
var _ = this;
_.addListener('exit', 'click', _.handle.logout);
_.addListener('comment-form-textarea', 'blur', _.handle.focus);
_.addListener('comment-form-textarea', 'focus', _.handle.focus);
_.addListener('comment-form-textarea', 'input', _.handle.input);
_.addListener('comment-form-textarea', 'keyup', _.handle.mention);
_.addListener('comment-form-email', 'blur', _.handle.verify);
_.addListener('comment-form-submit', 'click', _.handle.post);
_.addListener('comment-form-login', 'click', _.handle.login);
_.addListener('comment-image-input', 'change', _.handle.upload);
_.addListener('emojione-item', 'click', _.handle.field);
}
// 评论计数
iDisqus.prototype.count = function (){
var _ = this;
var counts = d.querySelectorAll('[data-disqus-url]');
var qty = counts.length;
if(qty > 0){
var commentArr = [];
for( var i = 0; i < qty; i++){
commentArr[i] = counts[i].dataset.disqusUrl.replace(_.opts.site, '');
}
getAjax(
_.opts.api + '/count.php?links=' + commentArr.join(','),
function(resp) {
var data = JSON.parse(resp);
var posts = data.response;
posts.forEach(function(item){
var link = document.createElement('a');
link.href = item.link;
var itemLink = link.href.replace(link.origin, '');
var el = d.querySelector('[data-disqus-url$="'+itemLink+'"]')
if(!!el ){
el.innerHTML = item.posts;
el.dataset.disqusCount = item.posts;
}
});
}, function(){
console.log('获取数据失败!')
}
);
}
};
// 热门评论
iDisqus.prototype.popular = function(){
var _ = this;
if(!!_.opts.popular){
getAjax(
_.opts.api + '/popular.php',
function(resp) {
var data = JSON.parse(resp);
if(data.code == 0){
var posts = data.response;
var postsHtml = '';
posts.forEach(function(item){
postsHtml += '<li><a href="' + item.link.replace(_.opts.site, '') + '" title="' + item.title + '">' + item.title + '</a></li>';
});
_.opts.popular.innerHTML = postsHtml;
}
},function(){
console.log('获取数据失败!')
}
);
}
}
// 获取评论列表
iDisqus.prototype.getlist = function(){
var _ = this;
_.stat.loading = true;
_.dom.querySelector('#idisqus').style.display = 'block';
_.dom.querySelector('#disqus_thread').style.display = 'none';
getAjax(
_.opts.api + '/getcomments.php?ident=' + _.opts.identifier + (!!_.stat.next ? '&cursor=' + _.stat.next : ''),
function(resp){
var data = JSON.parse(resp);
if (data.code === 0) {
_.stat.offsetTop = d.documentElement.scrollTop || d.body.scrollTop;
_.stat.thread = data.thread;
_.stat.count = data.posts;
_.opts.avatar = data.forum.avatar;
_.dom.querySelector('.comment-avatar-image').dataset.avatar = data.forum.avatar;
if( _.user.logged_in == 'false' ){
_.dom.querySelector('.comment-avatar-image').src = data.forum.avatar;
}
_.opts.badge = data.forum.moderatorBadgeText;
_.dom.querySelector('#idisqus').classList.remove('loading');
_.dom.querySelector('#comment-link').href = data.link;
_.dom.querySelector('#comment-count').innerHTML = _.stat.count + ' 条评论';
var loadmore = _.dom.querySelector('.comment-loadmore');
var posts = !!data.response ? data.response : [];
_.stat.root = [];
posts.forEach(function(item){
_.load(item);
if(!item.parent){
_.stat.root.unshift(item.id);
}
});
if ( data.cursor.hasPrev ){
_.stat.root.forEach(function(item){
_.dom.querySelector('.comment-list').appendChild(_.dom.querySelector('#comment-' + item));
})
} else {
loadmore.addEventListener('click', _.handle.loadMore, false);
_.addAllListeners();
}
if ( data.cursor.hasNext ){
_.stat.next = data.cursor.next;
loadmore.classList.remove('loading');
} else {
_.stat.next = null;
loadmore.classList.add('hide');
}
if (posts.length == 0) {
return;
}
window.scrollTo(0, _.stat.offsetTop);
_.timeAgo();
if (/^#disqus|^#comment-/.test(location.hash) && !data.cursor.hasPrev && !_.stat.disqusLoaded && !_.stat.loaded) {
var el = _.dom.querySelector('#idisqus ' + location.hash)
if( !!el ){
window.scrollBy(0, el.getBoundingClientRect().top);
}
}
_.stat.loading = false;
_.stat.loaded = true;
} else if ( data.code === 2 ){
_.create();
}
},function(){
alert('获取数据失败,请检查服务器设置。')
}
);
}
// 读取评论
iDisqus.prototype.load = function(post){
var _ = this;
var parentPostDom = _.dom.querySelector('.comment-item[data-id="'+post.parent+'"]');
var user = {
username: post.username,
name: post.name,
avatar: post.avatar
}
if(!!post.username && _.stat.users.map(function(user) { return user.username; }).indexOf(post.username) == -1){
_.stat.users.push(user);
}
var parentPost = !!post.parent ? {
name: '<a class="comment-item-pname" href="#'+parentPostDom.id+'"><svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M1.664 902.144s97.92-557.888 596.352-557.888V129.728L1024 515.84l-425.984 360.448V628.8c-270.464 0-455.232 23.872-596.352 273.28"></path></svg>' + parentPostDom.dataset.name + '</a>',
dom: parentPostDom.querySelector('.comment-item-children'),
insert: 'afterbegin'
} : {
name: '',
dom: _.dom.querySelector('.comment-list'),
insert: post.id == 'preview' || !!post.isPost ? 'afterbegin' : 'beforeend'
};
var mediaHTML = '';
if( post.media.length == 1 ){
mediaHTML = '<div class="comment-item-images"><a class="comment-item-image" target="_blank" href="' + post.media[0] + '" style="background-image: url('+post.media[0]+');width: 167px;height: 167px"></a></div>';
} else if( post.media.length > 1 ){
post.media.forEach(function(item){
mediaHTML += '<a class="comment-item-image" target="_blank" href="' + item + '" style="background-image: url('+item+')"></a>';
})
mediaHTML = '<div class="comment-item-images">' + mediaHTML + '</div>';
}
var html = '<li class="comment-item" data-id="' + post.id + '" data-name="'+ post.name + '" id="comment-' + post.id + '">' +
'<div class="comment-item-body">'+
'<a class="comment-item-avatar" href="#comment-'+post.id+'"><img src="' + post.avatar + '"></a>'+
'<div class="comment-item-main">'+
'<div class="comment-item-header"><a class="comment-item-name" title="' + post.name + '" rel="nofollow" target="_blank" href="' + ( post.url ? post.url : 'javascript:;' ) + '">' + post.name + '</a>'+ (post.isMod ?'<span class="comment-item-badge">'+_.opts.badge+'</span>' :'')+parentPost.name+'<span class="comment-item-bullet"> • </span><time class="comment-item-time" datetime="' + post.createdAt + '"></time></div>'+
'<div class="comment-item-content">' + post.message + mediaHTML + '</div>'+
'<div class="comment-item-footer">' + (!!post.isPost ? '<span class="comment-item-manage"><a class="comment-item-edit" href="javascript:;">编辑</a><span class="comment-item-bullet"> • </span><a class="comment-item-delete" href="javascript:;">删除</a><span class="comment-item-bullet"> • </span></span>' : '') + '<a class="comment-item-reply" href="javascript:;">回复</a> </div>'+
'</div></div>'+
'<ul class="comment-item-children"></ul>'+
'</li>';
// 已删除评论
if(!!post.isDeleted){
html = '<li class="comment-item" data-id="' + post.id + '" id="comment-' + post.id + '" data-name="已删除">' +
'<div class="comment-item-body">'+
'<a class="comment-item-avatar" href="#comment-'+post.id+'"><img src="' + post.avatar + '"></a>'+
'<div class="comment-item-main" data-message="此评论已被删除。"></div></div>'+
'<ul class="comment-item-children"></ul>'+
'</li>';
}
// 更新 or 创建
if(!!_.dom.querySelector('.comment-item[data-id="' + post.id + '"]')){
_.dom.querySelector('.comment-item[data-id="' + post.id + '"]').outerHTML = html;
} else {
parentPost.dom.insertAdjacentHTML(parentPost.insert, html);
}
if(!post.isDeleted){
_.dom.querySelector('.comment-item[data-id="' + post.id + '"] .comment-item-reply').addEventListener('click', _.handle.show, false);
_.dom.querySelector('.comment-item[data-id="' + post.id + '"] .comment-item-avatar').addEventListener('click', _.handle.jump, false);
if( !!post.parent ) {
_.dom.querySelector('.comment-item[data-id="' + post.id + '"] .comment-item-pname').addEventListener('click', _.handle.jump, false);
}
}
// 发布留言,可编辑删除
if(!!post.isPost && !_.stat.editing){
var $this = _.dom.querySelector('.comment-item[data-id="' + post.id + '"]');
var postEdit = setTimeout(function(){
// 十分钟后
if(!!$this.querySelector('.comment-item-manage')){
$this.querySelector('.comment-item-manage').outerHTML = '';
}
}, 600000);
// 删除
$this.querySelector('.comment-item-delete').addEventListener('click',function(e){
var postData = {
id: post.id
}
var delDom = e.currentTarget;
delDom.innerHTML = '删除中';
postAjax( _.opts.api + '/removecomment.php', postData, function(resp){
var data = JSON.parse(resp);
if (data.code === 0) {
if(data.response.isDeleted == true){
$this.outerHTML = '';
} else {
alert(data.response.message);
$this.querySelector('.comment-item-manage').outerHTML = '';
}
} else if (data.code === 2) {
alert(data.response);
$this.querySelector('.comment-item-manage').outerHTML = '';
}
}, function(){
alert('删除出错,请稍后重试');
})
clearTimeout(postEdit);
}, false)
// 编辑
$this.querySelector('.comment-item-edit').addEventListener('click',function(){
_.stat.editing = post;
_.edit(post);
}, false)
}
}
// 读取更多
iDisqus.prototype.loadMore = function(e){
var _ = this;
_.stat.offsetTop = d.documentElement.scrollTop || d.body.scrollTop;
if( !_.stat.loading ){
e.currentTarget.classList.add('loading');
_.getlist();
}
}
// 评论框焦点
iDisqus.prototype.focus = function(e){
var wrapper = e.currentTarget.closest('.comment-form-wrapper');
wrapper.classList.add('editing');
if (wrapper.classList.contains('focus')){
wrapper.classList.remove('focus');
} else{
wrapper.classList.add('focus');
}
}
// 输入事件
iDisqus.prototype.input = function(e){
var form = e.currentTarget.closest('.comment-form');
var alertmsg = form.querySelector('.comment-form-alert');
alertmsg.innerHTML = '';
}
// 提醒用户 @ mention
iDisqus.prototype.mention = function(e){
var _ = this;
var textarea = e.currentTarget;
var selStart = textarea.selectionStart;
var mentionIndex = textarea.value.slice(0, selStart).lastIndexOf('@');
var mentionText = textarea.value.slice(mentionIndex, selStart);
var mentionDom = _.dom.querySelector('.mention-user');
if(mentionText.search(/^@\w+$|^@$/) == 0){
if( e.keyCode == 38 || e.keyCode == 40){
return;
}
var showUsers = _.stat.users.filter(function(user){
var re = new RegExp(mentionText.slice(1), 'i');
return user.username.search(re) > -1;
});
var coord = _.getCaretCoord(textarea);
var list='', html = '';
if( showUsers.length > 0){
showUsers.forEach(function(item, i){
list += '<li class="mention-user-item'+(i == 0 ? ' active' : '')+'" data-username="'+item.username+'"><img class="mention-user-avatar" src="'+item.avatar+'"><div class="mention-user-username">'+item.username+'</div><div class="mention-user-name">'+item.name+'</div></li>';
})
if(!!mentionDom){
mentionDom.innerHTML = '<ul class="mention-user-list">'+list+'</ul>';
mentionDom.style.left = coord.left + 'px';
mentionDom.style.top = coord.top + 'px';
} else {
html = '<div class="mention-user" style="left:'+coord.left+'px;top:'+coord.top+'px"><ul class="mention-user-list">'+list+'</ul></div>';
_.dom.querySelector('#idisqus').insertAdjacentHTML('beforeend', html);
}
// 鼠标悬浮
_.addListener('mention-user-item', 'mouseover', function(){
_.dom.querySelector('.mention-user-item.active').classList.remove('active');
this.classList.add('active');
})
// 鼠标点击
_.addListener('mention-user-item', 'click', function(){
var username = '@' + this.dataset.username + ' ';
textarea.value = textarea.value.slice(0, mentionIndex) + username + textarea.value.slice(selStart);
_.dom.querySelector('.mention-user').outerHTML = '';
textarea.focus();
textarea.setSelectionRange(mentionIndex + username.length, mentionIndex + username.length)
textarea.removeEventListener('keydown', _.handle.keySelect, false);
})
// 键盘事件
textarea.addEventListener('keydown', _.handle.keySelect, false);
} else{
if(!!mentionDom){
mentionDom.outerHTML = '';
textarea.removeEventListener('keydown', _.handle.keySelect, false);
}
}
} else {
if(!!mentionDom){
mentionDom.outerHTML = '';
textarea.removeEventListener('keydown', _.handle.keySelect, false);
}
}
}
// 获取光标坐标 https://medium.com/@_jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a
iDisqus.prototype.getCaretCoord = function(textarea){
var _ = this;
var carPos = textarea.selectionEnd,
div = d.createElement('div'),
span = d.createElement('span'),
copyStyle = getComputedStyle(textarea);
[].forEach.call(copyStyle, function(prop){
div.style[prop] = copyStyle[prop];
});
div.style.position = 'absolute';
_.dom.appendChild(div);
div.textContent = textarea.value.substr(0, carPos);
span.textContent = textarea.value.substr(carPos) || '.';
div.appendChild(span);
var coords = {
'top': textarea.offsetTop - textarea.scrollTop + span.offsetTop + parseFloat(copyStyle.lineHeight),
'left': textarea.offsetLeft - textarea.scrollLeft + span.offsetLeft
};
_.dom.removeChild(div);
return coords;
}
// 键盘选择用户
iDisqus.prototype.keySelect = function(e){
var _ = this;
var textarea = e.currentTarget;
var selStart = textarea.selectionStart;
var mentionIndex = textarea.value.slice(0, selStart).lastIndexOf('@');
var mentionText = textarea.value.slice(mentionIndex, selStart);
var mentionDom = _.dom.querySelector('.mention-user');
var current = _.dom.querySelector('.mention-user-item.active')
switch(e.keyCode){
case 13:
//回车
var username = '@' + current.dataset.username + ' ';
textarea.value = textarea.value.slice(0, mentionIndex) + username + textarea.value.slice(selStart);
textarea.setSelectionRange(mentionIndex + username.length, mentionIndex + username.length)
_.dom.querySelector('.mention-user').outerHTML = '';
textarea.removeEventListener('keydown', _.handle.keySelect, false);
e.preventDefault();
break;
case 38:
//上
if(!!current.previousSibling){
current.previousSibling.classList.add('active');
current.classList.remove('active');
}
e.preventDefault();
break;
case 40:
//下
if(!!current.nextSibling){
current.nextSibling.classList.add('active');
current.classList.remove('active');
}
e.preventDefault();
break;
default:
break;
}
}
// 跳到评论
iDisqus.prototype.jump = function(e){
var _ = this;
var $this = e.currentTarget;
var hash = getLocation($this.href).hash;
var el = _.dom.querySelector('#idisqus ' + hash);
history.replaceState(undefined, undefined, hash);
window.scrollBy(0, el.getBoundingClientRect().top);
e.preventDefault();
}
// 点选表情
iDisqus.prototype.field = function(e){
var item = e.currentTarget;
var form = item.closest('.comment-form');
var textarea = form.querySelector('.comment-form-textarea');
var selStart = textarea.selectionStart;
var shortCode = selStart == 0 ? item.dataset.code + ' ' : ' ' + item.dataset.code + ' '
textarea.value = textarea.value.slice(0, selStart) + shortCode + textarea.value.slice(selStart)
textarea.focus();
textarea.setSelectionRange(selStart + shortCode.length, selStart + shortCode.length);
}
// 显示回复框 or 取消回复框
iDisqus.prototype.show = function(e){
var _ = this;
var $this = e.currentTarget;
var item = $this.closest('.comment-item');
// 无论取消还是回复,移除已显示回复框
var box = _.dom.querySelector('.comment-item .comment-box:not([data-current-id])');
if( box ){
var $show = box.closest('.comment-item');
var cancel = $show.querySelector('.comment-item-cancel')
cancel.outerHTML = cancel.outerHTML.replace('cancel','reply');
box.outerHTML = '';
}
// 回复时,显示评论框
if( $this.className == 'comment-item-reply' ){
$this.outerHTML = $this.outerHTML.replace('reply','cancel');
var commentBox = _.box.replace(/emoji-input/g,'emoji-input-'+item.dataset.id).replace(/upload-input/g,'upload-input-'+item.dataset.id);
item.querySelector('.comment-item-children').insertAdjacentHTML('beforebegin', commentBox);
_.user.init();
_.addAllListeners();
item.querySelector('.comment-form-textarea').focus();
}
// 监听事件
_.addListener('comment-item-reply', 'click', _.handle.show);
_.addListener('comment-item-cancel', 'click', _.handle.show);
}
// 验证表单
iDisqus.prototype.verify = function(e){
var _ = this;
var box = e.currentTarget.closest('.comment-box');
var avatar = box.querySelector('.comment-avatar-image');
var email = box.querySelector('.comment-form-email');
var alertmsg = box.querySelector('.comment-form-alert');
if(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(email.value)){
getAjax(
_.opts.api + '/getgravatar.php?email=' + email.value,
function(resp) {
if (resp == 'false') {
_.errorTips('您所填写的邮箱地址有误。', email);
} else {
avatar.src = resp;
}
}, function(){
}
);
}
}
// 上传图片
iDisqus.prototype.upload = function(e){
var _ = this;
var file = e.currentTarget;
var form = file.closest('.comment-form');
var progress = form.querySelector('.comment-image-progress');
var loaded = form.querySelector('.comment-image-loaded');
var wrapper = form.querySelector('.comment-form-wrapper');
var alertmsg = form.querySelector('.comment-form-alert');
alertmsg.innerHTML = '';
if(file.files.length === 0){
return;
}
// 以文件大小识别是否为同张图片
var size = file.files[0].size;
if( size > 5000000 ){
alertmsg.innerHTML = '请选择 5M 以下图片。';
setTimeout(function(){
alertmsg.innerHTML = '';
}, 3000);
return;
}
if( _.stat.imageSize.indexOf(size) == -1 ){
progress.style.width = '80px';
} else {
alertmsg.innerHTML = '请勿选择已存在的图片。';
setTimeout(function(){
alertmsg.innerHTML = '';
}, 3000);
return;
}
// 展开图片上传界面
wrapper.classList.add('expanded');
// 图片上传请求
var data = new FormData();
data.append('file', file.files[0] );
var filename = file.files[0].name;
var $item;
var xhrUpload = new XMLHttpRequest();
xhrUpload.withCredentials = true;
xhrUpload.onreadystatechange = function(){
if(xhrUpload.readyState == 4 && xhrUpload.status == 200){
var data = JSON.parse(xhrUpload.responseText);
if( data.code == 0 ){
_.stat.imageSize.push(size);
var imageUrl = data.response[filename].url;
var image = new Image();
image.src = imageUrl;
image.onload = function(){
$item.innerHTML = '<img class="comment-image-object" src="'+imageUrl+'">';
$item.dataset.imageUrl = imageUrl;
$item.classList.remove('loading');
$item.addEventListener('click', _.handle.remove, false);
}
} else {
alertmsg.innerHTML = '图片上传出错。';
$item.innerHTML = '';
if( !!form.getElementsByClassName('comment-image-item').length){
wrapper.classList.remove('expanded');
}
setTimeout(function(){
alertmsg.innerHTML = '';
}, 3000);
}
}
};
xhrUpload.upload.addEventListener('progress', function(e){
loaded.style.width = Math.ceil((e.loaded/e.total) * 100)+ '%';
}, false);
xhrUpload.upload.addEventListener('load', function(e){
loaded.style.width = 0;
progress.style.width = 0;
var imageItem = '<li class="comment-image-item loading" data-image-size="' + size + '">\n'+
' <svg version="1.1" class="comment-image-object" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\n'+
' width="24px" height="30px" viewBox="0 0 24 30" style="enable-background: new 0 0 50 50;" xml:space="preserve">\n'+
' <rect x="0" y="10" width="4" height="10" fill="rgba(127,145,158,1)" opacity="0.2">\n'+
' <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0s" dur="0.6s" repeatCount="indefinite" />\n'+
' <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0s" dur="0.6s" repeatCount="indefinite" />\n'+
' <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0s" dur="0.6s" repeatCount="indefinite" />\n'+
' </rect>\n'+
' <rect x="8" y="10" width="4" height="10" fill="rgba(127,145,158,1)" opacity="0.2">\n'+
' <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.15s" dur="0.6s" repeatCount="indefinite" />\n'+
' <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" />\n'+
' <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" />\n'+
' </rect>\n'+
' <rect x="16" y="10" width="4" height="10" fill="rgba(127,145,158,1)" opacity="0.2">\n'+
' <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.3s" dur="0.6s" repeatCount="indefinite" />\n'+
' <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" />\n'+
' <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" />\n'+
' </rect>\n'+
' </svg>\n'+
'</li>\n';
form.querySelector('.comment-image-list').insertAdjacentHTML('beforeend', imageItem);
$item = form.querySelector('[data-image-size="'+size+'"]');
}, false);
xhrUpload.open('POST', _.opts.api + '/upload.php', true);
xhrUpload.send(data);
}
// 移除图片
iDisqus.prototype.remove = function(e){
var _ = this;
var $item = e.currentTarget.closest('.comment-image-item');
var wrapper = e.currentTarget.closest('.comment-form-wrapper');
$item.outerHTML = '';
_.stat.imageSize = [];
var imageArr = wrapper.getElementsByClassName('comment-image-item');
[].forEach.call(imageArr, function(item, i){
_.stat.imageSize[i] = item.dataset.imageSize;
});
if(_.stat.imageSize.length == 0){
wrapper.classList.remove('expanded');
}
wrapper.querySelector('.comment-image-input').value = '';
}
// 错误提示
iDisqus.prototype.errorTips = function(Text, Dom){
var _ = this;
if( _.user.logged_in == 'true' ){
_.handle.logout();
}
var idisqus = _.dom.querySelector('#idisqus');
var errorDom = _.dom.querySelector('.comment-form-error');
if(!!errorDom){
errorDom.outerHTML = '';
}
var Top = Dom.offsetTop;
var Left = Dom.offsetLeft;
var errorHtml = '<div class="comment-form-error" style="top:'+Top+'px;left:'+Left+'px;">'+Text+'</div>';
idisqus.insertAdjacentHTML('beforeend', errorHtml);
setTimeout(function(){
var errorDom = _.dom.querySelector('.comment-form-error');
if(!!errorDom){
errorDom.outerHTML = '';
}
}, 3000);
}
// 发表/回复评论
iDisqus.prototype.post = function(e){
var _ = this;
var item = e.currentTarget.closest('.comment-box[data-current-id]') || e.currentTarget.closest('.comment-item') || e.currentTarget.closest('.comment-box');
var message = item.querySelector('.comment-form-textarea').value;
var parentId = !!item.dataset.id ? item.dataset.id : '';
var imgArr = item.getElementsByClassName('comment-image-item');
var media = [];
var mediaStr = '';
[].forEach.call(imgArr, function(image,i){
media[i] = image.dataset.imageUrl;
mediaStr += ' ' + image.dataset.imageUrl;
});
// 不是编辑框需预览
if( !item.dataset.currentId ){
var elName = item.querySelector('.comment-form-name');
var elEmail = item.querySelector('.comment-form-email');
var elUrl = item.querySelector('.comment-form-url');
var user = {
name: elName.value,
email: elEmail.value,
url: elUrl.value.replace(/\s/g,''),
avatar: item.querySelector('.comment-avatar-image').src,
type: 0
}
var alertmsg = item.querySelector('.comment-form-alert');
var alertClear = function() {
setTimeout(function(){
alertmsg.innerHTML = '';
}, 3000);
}
if(_.user.type != '1'){
if(/^\s*$/i.test(user.name)){
_.errorTips('名字不能为空。', elName);
return;
}
if(/^\s*$/i.test(user.email)){
_.errorTips('邮箱不能为空。', elEmail);
return;
}
if(!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(user.email)){
_.errorTips('请正确填写邮箱。', elEmail);
return;
}
if(!/^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$|^\s*$/i.test(user.url)){
_.errorTips('请正确填写网址。', elUrl);
return;
}
_.user.submit(user);
if( !_.user.name && !_.user.email ){
return;
}
}
if(!_.stat.message && !_.stat.mediaHtml){
_.box = _.dom.querySelector('.comment-box').outerHTML.replace(/<label class="comment-actions-label exit"(.|\n)*<\/label>\n/,'').replace('comment-form-wrapper','comment-form-wrapper editing').replace(/加入讨论……/,'');
}
if( media.length == 0 && /^\s*$/i.test(message)){
alertmsg.innerHTML = '评论不能为空或空格。';
item.querySelector('.comment-form-textarea').focus();
return;
};
var preMessage = message;
if( !!_.opts.emoji_preview ){
preMessage = preMessage.replace(/:([-+\w]+):/g, function (match){
var emojiShort = match.replace(/:/g,'');
var emojiImage = !!_.eac[emojiShort] ? '<img class="emojione" width="24" height="24" alt="'+emojiShort+'" title=":'+emojiShort+':" src="'+_.opts.emojiPath +_.eac[emojiShort]+'.png">' : match;
return emojiImage;
});
} else {
_.emojiList.forEach(function(item){
preMessage = preMessage.replace(':'+item.code+':', '<img class="emojione" width="24" height="24" src="' + _.opts.emojiPath + item.unicode + '.png" />');
});
}
var post = {
'url': !!_.user.url ? _.user.url : '',
'isMod': false,
'username': null,
'name': _.user.name,
'avatar': _.user.avatar,
'id': 'preview',
'parent': parentId,
'createdAt': (new Date()).toJSON(),
'message': '<p>' + preMessage + '</p>',
'media': media
};
_.load(post);
_.timeAgo();
// 清空或移除评论框
_.stat.message = message;
_.stat.mediaHtml = item.querySelector('.comment-image-list').innerHTML;
if( parentId ){
item.querySelector('.comment-item-cancel').click();
} else {
item.querySelector('.comment-form-textarea').value = '';
item.querySelector('.comment-image-list').innerHTML = '';
item.querySelector('.comment-form-wrapper').classList.remove('expanded','editing');
}
}
// @
var mentions = message.match(/@\w+/g);
if( !!mentions ){
mentions = mentions.filter(function(mention) {
return _.stat.users.map(function(user) { return user.username; }).indexOf(mention.slice(1)) > -1;
});
if( mentions.length > 0 ){
var re = new RegExp('('+mentions.join('|')+')','g');
message = message.replace(re,'$1:disqus');
}
}
// 文本 + 图片
message += mediaStr;
// POST 操作
// 编辑框则更新评论
if( !!item.dataset.currentId ){
var postData = {
id: item.dataset.currentId,
message: message,
}
postAjax( _.opts.api + '/updatecomment.php', postData, function(resp){
var data = JSON.parse(resp);
if (data.code === 0) {
_.stat.message = null;
_.stat.mediaHtml = null;
var post = data.response;
_.load(post);
_.timeAgo();
_.stat.editing = false;
} else {
// 取消编辑
_.load(_.stat.editing)
_.timeAgo();
_.stat.editing = false;
}
}, function(){
// 取消编辑
_.load(_.stat.editing)
_.timeAgo();
_.stat.editing = false;
})
} else {
var postData = {
thread: _.stat.thread,
parent: parentId,
message: message,
name: _.user.name,
email: _.user.email,
url: _.user.url,
}
postAjax( _.opts.api + '/postcomment.php', postData, function(resp){
var data = JSON.parse(resp);
if (data.code === 0) {
_.dom.querySelector('.comment-item[data-id="preview"]').outerHTML = '';
_.stat.count += 1;
_.dom.querySelector('#comment-count').innerHTML = _.stat.count + ' 条评论';
var post = data.response;
post.isPost = true;
_.load(post);
_.timeAgo();
} else if (data.code === 2) {
alertmsg.innerHTML = data.response;
_.dom.querySelector('.comment-item[data-id="preview"]').outerHTML = '';
_.reEdit(item);
if( data.response.indexOf('author') > -1){
_.handle.logout();
}
} else {
alertmsg.innerHTML = '提交失败,请稍后重试,错误代码:' + data.code;
alertClear();
_.dom.querySelector('.comment-item[data-id="preview"]').outerHTML = '';
_.reEdit(item);
}
}, function(){
alertmsg.innerHTML = '提交出错,请稍后重试。';
alertClear();
_.dom.querySelector('.comment-item[data-id="preview"]').outerHTML = '';
_.reEdit(item);
})
}
}
// 重新编辑
iDisqus.prototype.reEdit = function(item){
var _ = this;
if( !!item.dataset.id ){
item.querySelector('.comment-item-reply').click();
} else {
item.querySelector('.comment-form-wrapper').classList.add('editing');
}
// 重新填充文本图片
if(!!_.stat.message){
item.querySelector('.comment-form-textarea').value = _.stat.message;
}
if(!!_.stat.mediaHtml){
item.querySelector('.comment-form-wrapper').classList.add('expanded');
item.querySelector('.comment-image-list').innerHTML = _.stat.mediaHtml;
_.addListener('comment-image-item', 'click', _.handle.remove);
}
}
// 编辑
iDisqus.prototype.edit = function(post){
var _ = this;
var commentBox = _.box.replace('comment-box','comment-box comment-box-'+post.id).replace(/emoji-input/g,'emoji-input-'+post.id).replace(/upload-input/g,'upload-input-'+ post.id);
var $this = _.dom.querySelector('.comment-item[data-id="' + post.id + '"] .comment-item-body');
$this.outerHTML = commentBox;
_.user.init();
var item = _.dom.querySelector('.comment-box-' + post.id);
item.dataset.currentId = post.id;
_.addAllListeners();
item.querySelector('.comment-form-textarea').focus();
// 取消编辑
item.querySelector('.comment-actions-form').insertAdjacentHTML('afterbegin', '<a class="comment-form-cancel" href="javascript:;">取消</a>')
item.querySelector('.comment-form-cancel').addEventListener('click', function(){
_.stat.editing = false;
_.load(post);
_.timeAgo();
}, false);
// 重新填充文本图片,连续回复、连续编辑会有 bug
if(!!_.stat.message){
item.querySelector('.comment-form-textarea').value = _.stat.message;
}
if(!!_.stat.mediaHtml){
item.querySelector('.comment-form-wrapper').classList.add('expanded');
item.querySelector('.comment-image-list').innerHTML = _.stat.mediaHtml;
_.addListener('comment-image-item', 'click', _.handle.remove);
}
}
// 创建 Thread 表单
iDisqus.prototype.create = function(){
var _ = this;
if(_.opts.autoCreate){
_.dom.querySelector('.loading-container').dataset.tip = '正在创建 Thread……';
var postData = {
url: _.opts.link,
identifier: _.opts.identifier,
title: _.opts.title,
slug: _.opts.slug,
message: _.opts.desc
}
_.postThread(postData);
return;
}
_.dom.querySelector('#idisqus').classList.remove('loading');
_.dom.querySelector('#idisqus').innerHTML = '<div class="comment-header"><span class="comment-header-item">创建 Thread<\/span><\/div>'+
'<div class="comment-thread-form">'+
'<p>由于 Disqus 没有本页面的相关 Thread故需先创建 Thread<\/p>'+
'<div class="comment-form-item"><label class="comment-form-label">url:<\/label><input class="comment-form-input" id="thread-url" name="url" value="' + _.opts.link + '" disabled \/><\/div>'+
'<div class="comment-form-item"><label class="comment-form-label">identifier:<\/label><input class="comment-form-input" id="thread-identifier" name="identifier" value="'+_.opts.identifier+'" disabled \/><\/div>'+
'<div class="comment-form-item"><label class="comment-form-label">title:<\/label><input class="comment-form-input" id="thread-title" name="title" value="'+_.opts.title+'" disabled \/><\/div>'+
'<div class="comment-form-item"><label class="comment-form-label">slug:<\/label><input class="comment-form-input" id="thread-slug" name="slug" value="' + _.opts.slug + '" \/><\/div>'+
'<div class="comment-form-item"><label class="comment-form-label">message:<\/label><textarea class="comment-form-textarea" id="thread-message" name="message">'+_.opts.desc+'<\/textarea><\/div>'+
'<button id="thread-submit" class="comment-form-submit">提交<\/button><\/div>';
_.dom.querySelector('#thread-submit').addEventListener('click', _.handle.postThread, false);
}
// 创建 Thread 事件
iDisqus.prototype.postThread = function(){
var _ = this;
if( !!arguments[0].target ){
var postData = {
url: _.dom.querySelector('#thread-url').value,
identifier: _.dom.querySelector('#thread-identifier').value,
title: _.dom.querySelector('#thread-title').value,
slug: _.dom.querySelector('#thread-slug').value.replace(/[^A-Za-z0-9_-]+/g,''),
message: _.dom.querySelector('#thread-message').value
}
} else {
var postData = arguments[0];
}
postAjax( _.opts.api + '/createthread.php', postData, function(resp){
var data = JSON.parse(resp);
if( data.code === 0 ) {
alert('创建 Thread 成功,刷新后便可愉快地评论了!');
setTimeout(function(){location.reload();},2000);
} else if( data.code === 2 ) {
if (data.response.indexOf('A thread already exists with link') > -1) {
alert(data.response.replace('A thread already exists with link,', '已存在此链接的相关 Thread'));
return;
}
if (data.response.indexOf('Invalid URL') > -1) {
alert('参数错误,无效的\'URL\'');
return;
}
if (data.response.indexOf('Invalid slug') > -1) {
alert('参数错误,无效的\'slug\'');
return;
}
alert(data.response);
return;
} else {
alert(data.response);
return;
}
}, function(){
alert('创建 Thread 出错,请稍后重试!');
})
}
// 销毁评论框
iDisqus.prototype.destroy = function(){
var _ = this;
_.removeListener('exit', 'click', _.handle.logout);
_.removeListener('comment-form-textarea', 'blur', _.handle.focus);
_.removeListener('comment-form-textarea', 'focus', _.handle.focus);
_.removeListener('comment-form-textarea', 'keyup', _.handle.mention);
_.removeListener('comment-form-email', 'blur', _.handle.verify);
_.removeListener('comment-form-submit', 'click', _.handle.post);
_.removeListener('comment-image-input', 'change', _.handle.upload);
_.removeListener('comment-item-reply', 'click', _.handle.show);
_.removeListener('comment-loadmore', 'click', _.handle.loadMore);
_.removeListener('emojione-item', 'click', _.handle.field);
_.dom.innerHTML = '';
delete _.box;
delete _.dom;
delete _.emojiList;
delete _.user;
delete _.handle;
delete _.opts;
delete _.stat;
}
/* CommonJS */
if (typeof require === 'function' && typeof module === 'object' && module && typeof exports === 'object' && exports)
module.exports = iDisqus;
/* AMD */
else if (typeof define === 'function' && define['amd'])
define(function () {
return iDisqus;
});
/* Global */
else
global['iDisqus'] = global['iDisqus'] || iDisqus;
})(window || this);