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

1592 lines
72 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* 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);