Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zhaohuabing/hugo-theme-cleanwhite.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhaohuabing <zhaohuabing@gmail.com>2022-03-14 12:01:29 +0300
committerzhaohuabing <zhaohuabing@gmail.com>2022-03-14 12:01:29 +0300
commited6fb67adaeb226e88fface3d063cddd4e5d4bb8 (patch)
tree782393fa2dbca2c3561292bb1094add0cb3e60ac
parent9f6503328301606922042288cd74a669fff11a22 (diff)
show disqus even in local env
Signed-off-by: zhaohuabing <zhaohuabing@gmail.com>
-rw-r--r--static/js/iDisqus.js2
1 files changed, 1 insertions, 1 deletions
diff --git a/static/js/iDisqus.js b/static/js/iDisqus.js
index 19f658c..89ee644 100644
--- a/static/js/iDisqus.js
+++ b/static/js/iDisqus.js
@@ -159,7 +159,7 @@ eval("module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
-eval("/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_RESULT__;/*!\r\n * \r\n * @author fooleap\r\n * @email fooleap@gmail.com\r\n * @create 2017-06-17 20:48:25\r\n * @update 2021-05-11 11:58:38\r\n * @version 0.2.31\r\n * Copyright 2017-2021 fooleap\r\n * Released under the MIT license\r\n */\r\n__webpack_require__(/*! ./iDisqus.scss */ \"./src/iDisqus.scss\");\r\n(function (global) {\r\n 'use strict';\r\n\r\n var d = document,\r\n l = localStorage,\r\n scripts = d.scripts,\r\n lasturl = scripts[scripts.length - 1].src,\r\n filepath = lasturl.substring(0, lasturl.lastIndexOf('/')),\r\n isEdge = navigator.userAgent.indexOf(\"Edge\") > -1,\r\n isIE = !!window.ActiveXObject || \"ActiveXObject\" in window;\r\n\r\n function getLocation(href) {\r\n var link = d.createElement('a');\r\n link.href = href;\r\n return link;\r\n }\r\n\r\n function getAjax(url, success, error) {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', encodeURI(url));\r\n xhr.onreadystatechange = function () {\r\n if (xhr.readyState == 4 && xhr.status == 200) {\r\n success(xhr.responseText);\r\n }\r\n }\r\n xhr.onerror = error;\r\n xhr.withCredentials = true;\r\n xhr.send();\r\n return xhr;\r\n }\r\n\r\n function postAjax(url, data, success, error) {\r\n var params = typeof data == 'string' ? data : Object.keys(data).filter(function (k) {\r\n return data[k] != null;\r\n }).map(function (k) {\r\n return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])\r\n }).join('&');\r\n\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('POST', url);\r\n xhr.onreadystatechange = function () {\r\n if (xhr.readyState == 4 && xhr.status == 200) {\r\n success(xhr.responseText);\r\n }\r\n };\r\n xhr.onerror = error;\r\n xhr.withCredentials = true;\r\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\r\n xhr.send(params);\r\n return xhr;\r\n }\r\n\r\n function generateGUID() {\r\n var time = Number(new Date().getTime().toString().substring(3));\r\n var guid = Math.abs(time + Math.floor(Math.random() * 1e5) - 48 * 1e6 + Math.floor(Math.random() * 1e6)).toString(32);\r\n guid += Math.floor(Math.random() * 1e9).toString(32);\r\n return guid;\r\n }\r\n\r\n (function (ElementProto) {\r\n // matches & closest polyfill https://github.com/jonathantneal/closest\r\n if (typeof ElementProto.matches !== 'function') {\r\n ElementProto.matches = ElementProto.msMatchesSelector || ElementProto.mozMatchesSelector || ElementProto.webkitMatchesSelector || function matches(selector) {\r\n var element = this;\r\n var elements = (element.document || element.ownerDocument).querySelectorAll(selector);\r\n var index = 0;\r\n\r\n while (elements[index] && elements[index] !== element) {\r\n ++index;\r\n }\r\n\r\n return Boolean(elements[index]);\r\n };\r\n }\r\n\r\n if (typeof ElementProto.closest !== 'function') {\r\n ElementProto.closest = function closest(selector) {\r\n var element = this;\r\n\r\n while (element && element.nodeType === 1) {\r\n if (element.matches(selector)) {\r\n return element;\r\n }\r\n\r\n element = element.parentNode;\r\n }\r\n\r\n return null;\r\n };\r\n }\r\n\r\n // 事件委托\r\n ElementProto.on = function on(eventName, selector, handler) {\r\n this.addEventListener(eventName, function (e) {\r\n for (var target = e.target; target && target != this; target = target.parentNode) {\r\n if (target.matches(selector)) {\r\n handler.call(null, e, target);\r\n break;\r\n }\r\n }\r\n }, true);\r\n };\r\n\r\n })(window.Element.prototype);\r\n\r\n // 访客信息\r\n var User = function () {\r\n this.dom = arguments[0];\r\n this.opts = arguments[1];\r\n this.init();\r\n this.autologin();\r\n }\r\n\r\n User.prototype = {\r\n // 初始化访客信息\r\n init: function () {\r\n var _ = this;\r\n // 读取访客信息\r\n _.name = l.getItem('name');\r\n _.email = l.getItem('email');\r\n _.url = l.getItem('url');\r\n _.avatar = l.getItem('avatar');\r\n _.type = l.getItem('type');\r\n _.logged_in = l.getItem('logged_in');\r\n _.unique = l.getItem('disqus_unique')\r\n if (!l.getItem('vote')) {\r\n l.setItem('vote', JSON.stringify({}));\r\n }\r\n if (!l.getItem('reaction_vote')) {\r\n l.setItem('reaction_vote', JSON.stringify({}));\r\n }\r\n _.vote = JSON.parse(l.getItem('vote'));\r\n _.reactionVote = JSON.parse(l.getItem('reaction_vote'));\r\n\r\n var boxarr = _.dom.getElementsByClassName('comment-box');\r\n if (_.logged_in == 'true') {\r\n [].forEach.call(boxarr, function (item) {\r\n if (_.type == '1') {\r\n item.querySelector('.comment-form-wrapper').classList.add('logged-in');\r\n }\r\n item.querySelector('.comment-form-name').value = _.name;\r\n item.querySelector('.comment-form-email').value = _.email;\r\n item.querySelector('.comment-form-url').value = _.url;\r\n item.querySelector('.comment-avatar-image').src = _.avatar;\r\n });\r\n } else {\r\n [].forEach.call(boxarr, function (item) {\r\n item.querySelector('.comment-form-wrapper').classList.remove('logged-in');\r\n item.querySelector('.comment-form-name').value = '';\r\n item.querySelector('.comment-form-email').value = '';\r\n item.querySelector('.comment-form-url').value = '';\r\n item.querySelector('.comment-avatar-image').src = _.dom.querySelector('.comment-avatar-image').dataset.avatar;\r\n });\r\n l.setItem('logged_in', 'false');\r\n }\r\n\r\n if (_.type == '1' && _.logged_in == 'true') {\r\n var $login = _.dom.querySelector('.comment-login');\r\n if (!!$login) {\r\n $login.innerHTML = _.name + '<label class=\"comment-logout\" title=\"退出\" for=\"comment-user\">退出登录</label>';\r\n $login.title = _.name;\r\n $login.classList.add('comment-user');\r\n $login.classList.remove('comment-login');\r\n _.dom.querySelector('#comment-user').checked = false;\r\n }\r\n } else {\r\n var $user = _.dom.querySelector('.comment-user');\r\n if (!!$user) {\r\n $user.innerHTML = '登录';\r\n $user.title = '使用 Disqus 帐号授权登录';\r\n $user.classList.add('comment-login');\r\n $user.classList.remove('comment-user');\r\n }\r\n }\r\n\r\n },\r\n\r\n // 自动登录\r\n autologin: function () {\r\n var _ = this;\r\n getAjax(_.opts.api + '/user.php', function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n var user = data.response;\r\n _.avatar = user.avatar;\r\n _.name = user.name;\r\n _.username = user.username;\r\n _.url = user.url;\r\n _.type = user.type\r\n _.submit();\r\n } else {\r\n if (_.type == '1') {\r\n l.setItem('logged_in', 'false');\r\n _.init();\r\n } else {\r\n l.setItem('type', '0');\r\n if (!_.unique) {\r\n l.setItem('disqus_unique', generateGUID());\r\n }\r\n _.init();\r\n }\r\n }\r\n }, function () {\r\n })\r\n },\r\n\r\n // 登录\r\n login: function () {\r\n\r\n var _ = this;\r\n var popup = window.open(_.opts.api + '/login.php', 'Disqus Oauth', 'width=470,height=508');\r\n var timer;\r\n function isLogged() {\r\n if (!popup || !popup.closed) return;\r\n clearInterval(timer);\r\n _.user.autologin();\r\n }\r\n timer = setInterval(isLogged, 100);\r\n\r\n },\r\n\r\n // 退出登录\r\n logout: function () {\r\n var _ = this;\r\n postAjax(_.opts.api + '/logout.php', {}, function (resp) {\r\n l.setItem('logged_in', 'false');\r\n l.removeItem('type');\r\n l.removeItem('email');\r\n l.removeItem('avatar');\r\n l.removeItem('name');\r\n l.removeItem('url');\r\n l.removeItem('disqus_unique');\r\n l.removeItem('vote');\r\n l.removeItem('reaction_vote');\r\n _.user.init();\r\n })\r\n },\r\n\r\n // 提交访客信息\r\n submit: function () {\r\n var _ = this;\r\n l.setItem('email', _.email);\r\n l.setItem('type', _.type);\r\n l.setItem('name', _.name);\r\n l.setItem('url', _.url);\r\n l.setItem('avatar', _.avatar);\r\n l.setItem('disqus_unique', _.unique);\r\n l.setItem('logged_in', 'true');\r\n this.init();\r\n }\r\n }\r\n\r\n var iDisqus = function () {\r\n var _ = this;\r\n\r\n // 配置\r\n _.opts = typeof (arguments[1]) == 'object' ? arguments[1] : arguments[0];\r\n _.dom = d.getElementById(typeof (arguments[0]) == 'string' ? arguments[0] : 'comment');\r\n _.opts.api = _.opts.api.slice(-1) == '/' ? _.opts.api.slice(0, -1) : _.opts.api;\r\n _.opts.site = _.opts.site || location.origin;\r\n if (!!_.opts.url) {\r\n var optsUrl = _.opts.url.replace(_.opts.site, '');\r\n _.opts.url = optsUrl.slice(0, 1) != '/' ? '/' + optsUrl : optsUrl;\r\n } else if (isEdge || isIE) {\r\n _.opts.url = encodeURI(location.pathname) + encodeURI(location.search);\r\n } else {\r\n _.opts.url = location.pathname + location.search;\r\n }\r\n _.opts.identifier = _.opts.identifier || _.opts.url;\r\n _.opts.link = _.opts.site + _.opts.url;\r\n _.opts.title = _.opts.title || d.title;\r\n _.opts.slug = !!_.opts.slug ? _.opts.slug.replace(/[^A-Za-z0-9_-]+/g, '') : '';\r\n _.opts.desc = _.opts.desc || (!!d.querySelector('[name=\"description\"]') ? d.querySelector('[name=\"description\"]').content : '');\r\n _.opts.mode = _.opts.mode || 1;\r\n _.opts.timeout = _.opts.timeout || 3000;\r\n _.opts.toggle = !!_.opts.toggle ? d.getElementById(_.opts.toggle) : null;\r\n _.opts.autoCreate = !!_.opts.autoCreate || !!_.opts.auto;\r\n _.opts.relatedType = _.opts.relatedType || 'related'\r\n\r\n // emoji 表情\r\n _.opts.emojiPath = _.opts.emojiPath || _.opts.emoji_path || 'https://github.githubassets.com/images/icons/emoji/unicode/';\r\n _.emojiList = _.opts.emojiList || _.opts.emoji_list || [{\r\n code: 'smile',\r\n title: '笑脸',\r\n unicode: '1f604'\r\n }, {\r\n code: 'mask',\r\n title: '生病',\r\n unicode: '1f637'\r\n }, {\r\n code: 'joy',\r\n title: '破涕为笑',\r\n unicode: '1f602'\r\n }, {\r\n code: 'stuck_out_tongue_closed_eyes',\r\n title: '吐舌',\r\n unicode: '1f61d'\r\n }, {\r\n code: 'flushed',\r\n title: '脸红',\r\n unicode: '1f633'\r\n }, {\r\n code: 'scream',\r\n title: '恐惧',\r\n unicode: '1f631'\r\n }, {\r\n code: 'pensive',\r\n title: '失望',\r\n unicode: '1f614'\r\n }, {\r\n code: 'unamused',\r\n title: '无语',\r\n unicode: '1f612'\r\n }, {\r\n code: 'grin',\r\n title: '露齿笑',\r\n unicode: '1f601'\r\n }, {\r\n code: 'heart_eyes',\r\n title: '色',\r\n unicode: '1f60d'\r\n }, {\r\n code: 'sweat',\r\n title: '汗',\r\n unicode: '1f613'\r\n }, {\r\n code: 'smirk',\r\n title: '得意',\r\n unicode: '1f60f'\r\n }, {\r\n code: 'relieved',\r\n title: '满意',\r\n unicode: '1f60c'\r\n }, {\r\n code: 'rolling_eyes',\r\n title: '翻白眼',\r\n unicode: '1f644'\r\n }, {\r\n code: 'ok_hand',\r\n title: 'OK',\r\n unicode: '1f44c'\r\n }, {\r\n code: 'v',\r\n title: '胜利',\r\n unicode: '270c'\r\n }];\r\n\r\n if (!!_.opts.emoji_preview || !!_.opts.emojiPreview) {\r\n getAjax(_.opts.api + '/eac.php', function (resp) {\r\n _.eac = JSON.parse(resp);\r\n }, function () {\r\n })\r\n }\r\n\r\n // 默认状态\r\n _.stat = {\r\n current: 'idisqus', // 当前显示评论框\r\n loaded: false, // 评论框已加载\r\n loading: false, // 评论加载中\r\n editing: false, // 评论编辑中\r\n offsetTop: 0, // 高度位置\r\n next: null, // 下条评论\r\n message: null, // 新评论\r\n mediaHtml: null, // 新上传图片\r\n forum: {}, // 站点信息\r\n thread: {}, // 文章信息\r\n post: {}, // 评论数据\r\n media: {}, // 媒体信息\r\n root: [], // 根评论\r\n order: 'desc', // 排序\r\n users: [], // Disqus 会员\r\n imageSize: [], // 已上传图片大小\r\n disqusLoaded: false // Disqus 已加载\r\n };\r\n\r\n // Disqus 评论框设置\r\n window.disqus_config = function () {\r\n this.page.identifier = _.opts.identifier;\r\n this.page.title = _.opts.title;\r\n this.page.url = _.opts.link;\r\n this.callbacks.onReady.push(function () {\r\n _.stat.current = 'disqus';\r\n _.stat.disqusLoaded = true;\r\n _.dom.querySelector('#idisqus').style.display = 'none';\r\n _.dom.querySelector('#disqus_thread').style.display = 'block';\r\n if (_.opts.mode == 3 && !!_.opts.toggle) {\r\n _.opts.toggle.disabled = '';\r\n _.opts.toggle.checked = true;\r\n _.opts.toggle.addEventListener('change', _.handle.toggle, false);\r\n }\r\n });\r\n // 原生评论框发邮件\r\n this.callbacks.onNewComment = [function (comment, a) {\r\n var postData = {\r\n id: comment.id\r\n }\r\n // 异步发送邮件\r\n setTimeout(function () {\r\n postAjax(_.opts.api + '/sendemail.php', postData, function (resp) {\r\n console.info('邮件发送成功!');\r\n })\r\n }, 2000);\r\n }];\r\n }\r\n\r\n // 自动初始化\r\n if (!!_.opts.init) {\r\n _.init();\r\n //console.log(_);\r\n }\r\n }\r\n\r\n // TimeAgo https://coderwall.com/p/uub3pw/javascript-timeago-func-e-g-8-hours-ago\r\n iDisqus.prototype.timeAgo = function () {\r\n\r\n var _ = this;\r\n var templates = {\r\n prefix: \"\",\r\n suffix: \"前\",\r\n seconds: \"几秒\",\r\n minute: \"1分钟\",\r\n minutes: \"%d分钟\",\r\n hour: \"1小时\",\r\n hours: \"%d小时\",\r\n day: \"1天\",\r\n days: \"%d天\",\r\n week: \"1周\",\r\n weeks: \"%d周\",\r\n month: \"1个月\",\r\n months: \"%d个月\",\r\n year: \"1年\",\r\n years: \"%d年\"\r\n };\r\n var template = function (t, n) {\r\n return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n)));\r\n };\r\n\r\n var timer = function (time) {\r\n if (!time) return;\r\n time = time.replace(/\\.\\d+/, \"\"); // remove milliseconds\r\n time = time.replace(/-/, \"/\").replace(/-/, \"/\");\r\n time = time.replace(/T/, \" \").replace(/Z/, \" UTC\");\r\n time = time.replace(/([\\+\\-]\\d\\d)\\:?(\\d\\d)/, \" $1$2\"); // -04:00 -> -0400\r\n time = new Date(time * 1000 || time);\r\n\r\n var now = new Date();\r\n var seconds = ((now.getTime() - time) * .001) >> 0;\r\n var minutes = seconds / 60;\r\n var hours = minutes / 60;\r\n var days = hours / 24;\r\n var weeks = days / 7;\r\n var months = days / 30;\r\n var years = days / 365;\r\n\r\n 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', months) || years < 1.5 && template('year', 1) || template('years', years)) + templates.suffix;\r\n };\r\n\r\n var elements = _.dom.querySelectorAll('time[datetime]');\r\n for (var i in elements) {\r\n var $this = elements[i];\r\n if (typeof $this === 'object') {\r\n $this.title = new Date($this.getAttribute('datetime'));\r\n $this.innerHTML = timer($this.getAttribute('datetime'));\r\n }\r\n }\r\n\r\n // update time every minute\r\n setTimeout(_.timeAgo.bind(_), 60000);\r\n\r\n }\r\n\r\n // 初始化评论框\r\n iDisqus.prototype.init = function () {\r\n var _ = this;\r\n if (!_.dom) {\r\n //console.log('该页面没有评论框!');\r\n return\r\n }\r\n // 表情\r\n var emojiList = '';\r\n _.emojiList.forEach(function (item) {\r\n emojiList += '<li class=\"emojione-item\" title=\"' + item.title + '\" data-code=\":' + item.code + ':\"><img class=\"emojione-item-image\" src=\"' + _.opts.emojiPath + item.unicode + '.png\" /></li>';\r\n })\r\n _.dom.innerHTML = `<div class=\"comment init\" id=\"idisqus\">\r\n <div class=\"comment-reaction\">\r\n <div class=\"comment-reaction-header\">\r\n <div class=\"comment-reaction-prompt\"></div>\r\n <div class=\"comment-reaction-total\"></div>\r\n </div>\r\n <div class=\"comment-reaction-list\"></div>\r\n </div>\r\n <div class=\"init-container\" data-tips=\"正在初始化……\"><svg class=\"init-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>\r\n <div class=\"comment-header\">\r\n <div class=\"comment-header-primary\">\r\n <span class=\"comment-header-item\" id=\"comment-count\">评论</span>\r\n <a class=\"comment-header-item\" id=\"comment-link\" target=\"_blank\">在线讨论</a>\r\n </div>\r\n <div class=\"comment-header-menu\">\r\n <input class=\"comment-header-checkbox\" type=\"checkbox\" id=\"comment-user\">\r\n <label class=\"comment-header-item comment-login\" title=\"使用 Disqus 帐号授权登录\" for=\"comment-user\">登录</label>\r\n </div>\r\n </div>\r\n <div class=\"comment-navbar\">\r\n <div class=\"comment-navbar-item\">\r\n <a class=\"comment-recommend\" href=\"javascript:;\"><svg t=\"1537508059126\" class=\"icon\" style=\"\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"3234\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24\" height=\"24\"><path d=\"M489.993 887.107 177.906 586.021c-4.002-3.501-114.033-104.031-114.033-224.063 0-146.54 89.526-234.065 239.069-234.065 87.523 0 169.546 69.019 209.058 108.03 39.512-39.011 121.535-108.03 209.059-108.03 149.542 0 239.068 87.525 239.068 234.065 0 120.033-110.031 220.563-114.533 225.065L534.007 887.107c-6 6-14.003 9-22.007 9C503.997 896.107 495.993 893.107 489.993 887.107z\" p-id=\"3235\"></path></svg><span class=\"comment-recommend-text\">推荐</span><span class=\"comment-recommend-count\"></span></a>\r\n </div>\r\n <div class=\"comment-navbar-item comment-order\">\r\n <input class=\"comment-order-radio\" id=\"order-popular\" type=\"radio\" name=\"comment-order\" value=\"popular\" />\r\n <label class=\"comment-order-label\" for=\"order-popular\" title=\"按评分高低排序\">最佳</label>\r\n <input class=\"comment-order-radio\" id=\"order-desc\" type=\"radio\" name=\"comment-order\" value=\"desc\" />\r\n <label class=\"comment-order-label\" for=\"order-desc\" title=\"按从新到旧排序\">最新</label>\r\n <input class=\"comment-order-radio\" id=\"order-asc\" type=\"radio\" name=\"comment-order\" value=\"asc\" />\r\n <label class=\"comment-order-label\" for=\"order-asc\" title=\"按从旧到新排序\">最早</label>\r\n </div>\r\n </div>\r\n <div class=\"comment-box\">\r\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>\r\n <div class=\"comment-form\">\r\n <div class=\"comment-form-wrapper\">\r\n <textarea class=\"comment-form-textarea\" placeholder=\"加入讨论……\"></textarea>\r\n <div class=\"comment-form-alert\"></div>\r\n <div class=\"comment-image\">\r\n <ul class=\"comment-image-list\"></ul>\r\n <div class=\"comment-image-progress\"><div class=\"comment-image-loaded\"></div></div>\r\n </div>\r\n \r\n <div class=\"comment-actions\">\r\n \r\n <div class=\"comment-actions-group\">\r\n <input id=\"emoji-input\" class=\"comment-actions-input\" type=\"checkbox\">\r\n <label class=\"comment-actions-label emojione\" for=\"emoji-input\">\r\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\">\r\n <g>\r\n <title>选择表情</title>\r\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>\r\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>\r\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>\r\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>\r\n </g>\r\n </svg>\r\n <ul class=\"emojione-list\">${ emojiList}</ul>\r\n </label>\r\n <input id=\"upload-input\" class=\"comment-actions-input comment-image-input\" type=\"file\" accept=\"image/*\" name=\"file\">\r\n <label class=\"comment-actions-label\" for=\"upload-input\">\r\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\">\r\n <g>\r\n <title>上传图片</title>\r\n <path d=\"M15.515152 15.515152 15.515152 15.515152 15.515152 15.515152Z\"></path>\r\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>\r\n </g>\r\n </svg>\r\n </label>\r\n </div>\r\n \r\n <div class=\"comment-actions-form\">\r\n <button class=\"comment-form-submit\">\r\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\">\r\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>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"comment-form-user\">\r\n <form 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\" /></form>\r\n </div>\r\n </div>\r\n </div>\r\n <ul id=\"comments\" class=\"comment-list\" data-tips=\"评论加载中……\"></ul>\r\n <a href=\"javascript:;\" class=\"comment-loadmore hide\">加载更多</a>\r\n <div class=\"comment-related\"></div>\r\n </div>\r\n <div class=\"comment\" id=\"disqus_thread\"></div>`;\r\n\r\n _.user = new User(_.dom, _.opts);\r\n _.handle = {\r\n logout: _.user.logout.bind(_),\r\n login: _.user.login.bind(_),\r\n loadMore: _.loadMore.bind(_),\r\n loadMoreReply: _.loadMoreReply.bind(_),\r\n post: _.post.bind(_),\r\n threadCreate: _.threadCreate.bind(_),\r\n threadVote: _.threadVote.bind(_),\r\n reactionVote: _.reactionVote.bind(_),\r\n remove: _.remove.bind(_),\r\n show: _.show.bind(_),\r\n toggle: _.toggle.bind(_),\r\n upload: _.upload.bind(_),\r\n verify: _.verify.bind(_),\r\n jump: _.jump.bind(_),\r\n mention: _.mention.bind(_),\r\n keySelect: _.keySelect.bind(_),\r\n field: _.field.bind(_),\r\n focus: _.focus,\r\n input: _.input.bind(_),\r\n parentShow: _.parentShow.bind(_),\r\n selectOrder: _.selectOrder.bind(_)\r\n };\r\n\r\n var $iDisqus = _.dom.querySelector('#idisqus');\r\n $iDisqus.on('blur', '.comment-form-textarea', _.handle.focus);\r\n $iDisqus.on('focus', '.comment-form-textarea', _.handle.focus);\r\n $iDisqus.on('input', '.comment-form-textarea', _.handle.input);\r\n $iDisqus.on('propertychange', '.comment-form-textarea', _.handle.input);\r\n $iDisqus.on('keyup', '.comment-form-textarea', _.handle.mention);\r\n $iDisqus.on('keydown', '.comment-form-textarea', _.handle.keySelect);\r\n $iDisqus.on('blur', '.comment-form-name', _.handle.verify);\r\n $iDisqus.on('blur', '.comment-form-email', _.handle.verify);\r\n $iDisqus.on('click', '.comment-form-submit', _.handle.post);\r\n $iDisqus.on('click', '.comment-login', _.handle.login);\r\n $iDisqus.on('change', '.comment-image-input', _.handle.upload);\r\n $iDisqus.on('click', '.emojione-item', _.handle.field);\r\n $iDisqus.on('click', '.comment-logout', _.handle.logout);\r\n $iDisqus.on('click', '.comment-item-reply', _.handle.show);\r\n $iDisqus.on('click', '.comment-item-cancel', _.handle.show);\r\n $iDisqus.on('click', '.comment-item-avatar', _.handle.jump);\r\n $iDisqus.on('click', '.comment-item-pname', _.handle.jump);\r\n $iDisqus.on('mouseover', '.comment-item-pname', _.handle.parentShow);\r\n $iDisqus.on('click', '.comment-loadmore', _.handle.loadMore);\r\n $iDisqus.on('click', '.comment-item-loadmore', _.handle.loadMoreReply);\r\n $iDisqus.on('click', '#thread-submit', _.handle.threadCreate);\r\n $iDisqus.on('click', '.comment-recommend', _.handle.threadVote);\r\n $iDisqus.on('click', '.comment-reaction-btn:not(.selected)', _.handle.reactionVote);\r\n $iDisqus.on('change', '.comment-order-radio', _.handle.selectOrder);\r\n\r\n switch (_.opts.mode) {\r\n case 1:\r\n _.disqus();\r\n break;\r\n case 2:\r\n _.threadInit();\r\n break;\r\n case 3:\r\n _.threadInit();\r\n _.disqus();\r\n break;\r\n default:\r\n _.disqus();\r\n break;\r\n }\r\n }\r\n\r\n // 切换评论框\r\n iDisqus.prototype.toggle = function () {\r\n var _ = this;\r\n if (_.stat.current == 'disqus') {\r\n _.stat.current = 'idisqus';\r\n _.dom.querySelector('#idisqus').style.display = 'block';\r\n _.dom.querySelector('#disqus_thread').style.display = 'none';\r\n } else {\r\n _.disqus();\r\n }\r\n }\r\n\r\n // 加载 Disqus 评论\r\n iDisqus.prototype.disqus = function () {\r\n var _ = this;\r\n var _tips = _.dom.querySelector('.init-container').dataset.tips;\r\n if (_.opts.site != location.origin) {\r\n console.log('本地环境不加载 Disqus 评论框!');\r\n if (_.opts.mode == 1) {\r\n _.threadInit();\r\n }\r\n return;\r\n }\r\n if (!_.stat.disqusLoaded) {\r\n _tips = '尝试连接 Disqus……';\r\n\r\n var s = d.createElement('script');\r\n s.src = '//' + _.opts.forum + '.disqus.com/embed.js';\r\n s.dataset.timestamp = Date.now();\r\n s.onload = function () {\r\n _.stat.disqusLoaded = true;\r\n _tips = '连接成功,加载 Disqus 评论框……'\r\n }\r\n s.onerror = function () {\r\n if (_.opts.mode == 1) {\r\n _tips = '连接失败,加载简易评论框……';\r\n _.threadInit();\r\n }\r\n }\r\n\r\n\r\n var img = new Image();\r\n img.onerror = function () {\r\n if (_.opts.mode == 1) {\r\n _tips = '连接超时,加载简易评论框……';\r\n _.threadInit();\r\n }\r\n }\r\n img.onload = function () {\r\n (d.head || d.body).appendChild(s);\r\n clearTimeout(timer)\r\n };\r\n img.src = 'https://disqus.com/favicon.ico?' + Date.now();\r\n var timer = setTimeout(function () {\r\n if ( !img.complete || !img.naturalWidth ) {\r\n if (_.opts.mode == 1) {\r\n _tips = '连接失败,加载简易评论框……';\r\n _.threadInit();\r\n }\r\n }\r\n }, _.opts.timeout);\r\n } else {\r\n _.stat.current = 'disqus';\r\n _.dom.querySelector('#idisqus').style.display = 'none';\r\n _.dom.querySelector('#disqus_thread').style.display = 'block';\r\n }\r\n }\r\n\r\n // 添加事件监听\r\n iDisqus.prototype.addListener = function (els, evt, func) {\r\n var _ = this;\r\n var el = _.dom.getElementsByClassName(els);\r\n [].forEach.call(el, function (item) {\r\n item.addEventListener(evt, func, false);\r\n });\r\n }\r\n\r\n // 评论计数\r\n iDisqus.prototype.count = function () {\r\n var _ = this;\r\n var counts = d.querySelectorAll('[data-disqus-url]');\r\n var qty = counts.length;\r\n if (qty > 0) {\r\n var commentArr = [];\r\n for (var i = 0; i < qty; i++) {\r\n commentArr[i] = counts[i].dataset.disqusUrl.replace(_.opts.site, '');\r\n }\r\n getAjax(\r\n _.opts.api + '/threadsList.php?links=' + commentArr.join(','),\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n var posts = data.response;\r\n posts.forEach(function (item) {\r\n var link = document.createElement('a');\r\n link.href = item.link;\r\n var itemLink = link.href.replace(link.origin, '');\r\n var el = d.querySelector('[data-disqus-url$=\"' + itemLink + '\"]')\r\n if (!!el) {\r\n el.innerHTML = item.posts;\r\n el.dataset.disqusCount = item.posts;\r\n }\r\n });\r\n }, function () {\r\n console.log('获取数据失败!')\r\n }\r\n );\r\n }\r\n };\r\n\r\n // 加载最近评论\r\n iDisqus.prototype.postsList = function (listLimit, containerId) {\r\n var _ = this;\r\n listLimit = listLimit || 5;\r\n var listContainer = d.getElementById(typeof (containerId) == 'string' ? containerId : 'disqusPostsList');\r\n if (listContainer) {\r\n getAjax(\r\n _.opts.api + '/postsList.php?limit=' + listLimit,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n var posts = data.response;\r\n var popHtml = '';\r\n posts.forEach(function (item) {\r\n popHtml += `<li style=\"list-style-type: none;\">${item.name}: ${item.raw_message}</br>评: <a href=\"${item.thread.link}\">${item.thread.title}</a></li>`;\r\n });\r\n popHtml = `<ul>${popHtml}</ul`;\r\n listContainer.innerHTML = popHtml;\r\n }, function () {\r\n console.log('获取数据失败!')\r\n }\r\n );\r\n }\r\n };\r\n\r\n // 加载相关话题\r\n iDisqus.prototype.loadRelated = function () {\r\n var _ = this;\r\n if (_.stat.forum.settings.organicDiscoveryEnabled == false || _.stat.relatedLoaded) {\r\n return;\r\n }\r\n getAjax(\r\n _.opts.api + '/threadsList.php?type=' + _.opts.relatedType.toLowerCase() + '&thread=' + _.stat.thread.id,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n _.stat.relatedLoaded = true;\r\n var threads = data.response;\r\n var popHtml = '';\r\n threads.forEach(function (item) {\r\n var message = item.topPost.message.replace(/<[^>]*>/g, '');\r\n popHtml += `<li class=\"related-item\">\r\n <a class=\"related-item-link\" href=\"${item.link}\" title=\"${item.title}\">\r\n <div class=\"related-item-title\">${item.title}</div>\r\n <div class=\"related-item-desc\">${item.posts}条评论<span class=\"related-item-bullet\"> • </span><time class=\"related-item-time\" datetime=\"${item.createdAt}\"></time></div></a>\r\n <a class=\"related-item-link\" href=\"${item.link}?#comment-${item.topPost.id}\" title=\"${message}\">\r\n <div class=\"related-item-post\">\r\n <div class=\"related-item-avatar\"><img src=\"${item.topPost.avatar}\" /></div>\r\n <div class=\"related-item-main\">\r\n <div class=\"related-item-name\">${ item.topPost.name}</div>\r\n <div class=\"related-item-message\">${ message}</div>\r\n </div>\r\n </div></a>\r\n </li>`;\r\n });\r\n popHtml = `<div class=\"comment-related-title\">在<span class=\"comment-related-forumname\">${_.stat.forum.name}</span>上还有</div><div class=\"comment-related-content\"><ul class=\"related-list\">${popHtml}</ul></div>`;\r\n _.dom.querySelector('.comment-related').innerHTML = popHtml;\r\n _.timeAgo();\r\n }\r\n }, function () {\r\n console.log('获取数据失败!')\r\n }\r\n );\r\n };\r\n\r\n // 加载反应\r\n iDisqus.prototype.loadReactions = function () {\r\n var _ = this;\r\n if (_.stat.forum.settings.threadReactionsEnabled == false) {\r\n return;\r\n }\r\n getAjax(_.opts.api + '/threadReactionsLoadReations.php' + '?thread=' + _.stat.thread.id, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.response.eligible) {\r\n _.dom.querySelector('.comment-reaction-prompt').innerHTML = data.response.prompt;\r\n var reactions = data.response.reactions;\r\n var total = 0;\r\n var reaListHtml = '';\r\n var selectedId = _.user.reactionVote[_.stat.thread.id];\r\n selectedId = selectedId || (!!data.selected ? data.selected.id : 0);\r\n reactions.forEach(function (item) {\r\n total += item.votes;\r\n reaListHtml += `<li class=\"comment-reaction-item\"><a class=\"comment-reaction-btn${(selectedId == item.id ? ' selected' : '')}\" data-id=\"${item.id}\" href=\"javascript:;\"><img class=\"comment-reaction-image\" src=\"${item.imageUrl}\"> ${item.text}</a><div class=\"comment-reaction-count\">${item.votes}</div></li>`;\r\n })\r\n _.dom.querySelector('.comment-reaction-list').innerHTML = reaListHtml;\r\n _.dom.querySelector('.comment-reaction-total').innerHTML = total + ' 人次参与';\r\n }\r\n }, function () { })\r\n\r\n };\r\n\r\n // 反应打分事件\r\n iDisqus.prototype.reactionVote = function (e, target) {\r\n var _ = this;\r\n var $reaction = target.closest('.comment-reaction-item');\r\n var $count = $reaction.querySelector('.comment-reaction-count');\r\n var reactionId = target.dataset.id;\r\n var postData = {\r\n thread: _.stat.thread.id,\r\n unique: _.user.unique,\r\n reaction: reactionId\r\n }\r\n postAjax(_.opts.api + '/threadReactionsVote.php', postData, function (resp) {\r\n _.user.reactionVote[_.stat.thread.id] = reactionId;\r\n l.setItem('reaction_vote', JSON.stringify(_.user.reactionVote));\r\n target.classList.add('selected');\r\n $count.innerHTML++\r\n })\r\n }\r\n\r\n // 排序\r\n iDisqus.prototype.selectOrder = function (e, target) {\r\n var _ = this;\r\n var order = target.value;\r\n sessionStorage.setItem('order', order);\r\n _.stat.order = order;\r\n _.dom.querySelector('.comment-list').innerHTML = '';\r\n _.dom.querySelector('.comment-loadmore').classList.add('hide');\r\n _.stat.next = null;\r\n _.getlist();\r\n }\r\n\r\n // 获取评论列表\r\n iDisqus.prototype.getlist = function () {\r\n var _ = this;\r\n _.stat.loading = true;\r\n _.dom.querySelector('#idisqus').classList.add('loading');\r\n _.dom.querySelector('.comment-list').dataset.tips = '评论加载中……';\r\n getAjax(\r\n _.opts.api + '/getcomments.php?thread=' + _.stat.thread.id + (!!_.stat.next ? '&cursor=' + _.stat.next : '') + '&order=' + _.stat.order,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n _.stat.offsetTop = d.documentElement.scrollTop || d.body.scrollTop;\r\n\r\n _.dom.querySelector('#idisqus').classList.remove('loading')\r\n var loadmore = _.dom.querySelector('.comment-loadmore');\r\n var posts = !!data.response ? data.response : [];\r\n _.stat.root = [];\r\n posts.forEach(function (item) {\r\n _.load(item);\r\n if (!item.parent) {\r\n _.stat.root.unshift(item.id);\r\n }\r\n });\r\n\r\n if (data.cursor.hasPrev) {\r\n _.stat.root.forEach(function (item) {\r\n _.dom.querySelector('.comment-list').appendChild(_.dom.querySelector('#comment-' + item));\r\n })\r\n }\r\n if (data.cursor.hasNext) {\r\n _.stat.next = data.cursor.next;\r\n loadmore.classList.remove('loading');\r\n loadmore.classList.remove('hide');\r\n } else {\r\n _.stat.next = null;\r\n loadmore.classList.add('hide');\r\n }\r\n\r\n if (_.stat.thread.posts == 0) {\r\n _.dom.querySelector('.comment-list').dataset.tips = '来做第一个留言的人吧!';\r\n return;\r\n }\r\n\r\n if (posts.length == 0) {\r\n return;\r\n }\r\n _.timeAgo();\r\n\r\n var iframe = _.dom.querySelectorAll('.comment-item-body iframe');\r\n [].forEach.call(iframe, function (item) {\r\n item.style.width = item.clientWidth + 'px';\r\n item.style.height = item.clientWidth * 9 / 16 + 'px';\r\n setTimeout(function () {\r\n item.src = item.src;\r\n }, 1000)\r\n })\r\n var tweet = _.dom.querySelectorAll('.comment-item-body .twitter-tweet');\r\n if (tweet.length > 0) {\r\n var head = document.getElementsByTagName('head')[0];\r\n var script = document.createElement('script');\r\n script.type = 'text/javascript';\r\n script.src = '//platform.twitter.com/widgets.js';\r\n head.appendChild(script);\r\n }\r\n\r\n window.scrollTo(0, _.stat.offsetTop);\r\n\r\n if (/^#disqus|^#comment-/.test(location.hash) && !data.cursor.hasPrev && !_.stat.disqusLoaded && !_.stat.loaded) {\r\n var el = _.dom.querySelector('#idisqus ' + location.hash)\r\n if (!!el) {\r\n window.scrollBy(0, el.getBoundingClientRect().top);\r\n }\r\n }\r\n _.stat.loading = false;\r\n _.stat.loaded = true;\r\n }\r\n }, function () {\r\n alert('获取数据失败,请检查服务器设置。')\r\n }\r\n );\r\n }\r\n\r\n // 读取评论\r\n iDisqus.prototype.load = function (post) {\r\n\r\n var _ = this;\r\n\r\n _.stat.post[post.id] = post;\r\n\r\n var parentPostDom = _.dom.querySelector('.comment-item[data-id=\"' + post.parent + '\"]');\r\n\r\n var user = {\r\n username: post.username,\r\n name: post.name,\r\n avatar: post.avatar\r\n }\r\n if (!!post.username && _.stat.users.map(function (user) { return user.username; }).indexOf(post.username) == -1) {\r\n _.stat.users.push(user);\r\n }\r\n\r\n var parentPost = !!post.parent ? {\r\n name: `<a class=\"comment-item-pname\" data-parent=\"${post.parent}\" 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>`,\r\n dom: parentPostDom.querySelector('.comment-item-children'),\r\n insert: 'afterbegin'\r\n } : {\r\n name: '',\r\n dom: _.dom.querySelector('.comment-list'),\r\n insert: post.id == 'preview' || !!post.isPost ? 'afterbegin' : 'beforeend'\r\n };\r\n\r\n\r\n var html = `<li class=\"comment-item\" data-id=\"${post.id}\" data-name=\"${post.name}\" id=\"comment-${post.id}\">\r\n <div class=\"comment-item-body\">\r\n <a class=\"comment-item-avatar\" href=\"#comment-${ post.id}\"><img src=\"${post.avatar}\"></a>\r\n <div class=\"comment-item-main\">\r\n <div class=\"comment-item-header\"><a class=\"comment-item-name\" title=\"${ post.name}\" rel=\"nofollow\" target=\"_blank\" href=\"${(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>\r\n <div class=\"comment-item-content\">${ post.message}</div>\r\n <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>\r\n </div></div>\r\n <ul class=\"comment-item-children\">\r\n ${ post.hasMore ? `<li><a class=\"comment-item-loadmore\" href=\"javascript:;\">显示更多回复</a></li>` : `` }\r\n </ul>\r\n </li>`;\r\n\r\n // 已删除评论\r\n if (!!post.isDeleted) {\r\n html = `<li class=\"comment-item\" data-id=\"${post.id}\" id=\"comment-${post.id}\" data-name=\"${post.name}\">\r\n <div class=\"comment-item-body\">\r\n <a class=\"comment-item-avatar\" href=\"#comment-${ post.id}\"><img src=\"${post.avatar}\"></a>\r\n <div class=\"comment-item-main\" data-message=\"此评论已被删除。\"></div></div>\r\n <ul class=\"comment-item-children\">\r\n ${ post.hasMore ? `<li><a class=\"comment-item-loadmore\" href=\"javascript:;\">显示更多回复</a></li>` : `` }\r\n </ul>\r\n </li>`;\r\n }\r\n\r\n\r\n // 更新 or 创建\r\n if (!!_.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"]')) {\r\n _.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"]').outerHTML = html;\r\n } else {\r\n parentPost.dom.insertAdjacentHTML(parentPost.insert, html);\r\n }\r\n\r\n // 发布留言,可编辑删除\r\n if (!!post.isPost && !_.stat.editing) {\r\n var $this = _.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"]');\r\n\r\n var postEdit = setTimeout(function () {\r\n // 十分钟后\r\n if (!!$this.querySelector('.comment-item-manage')) {\r\n $this.querySelector('.comment-item-manage').outerHTML = '';\r\n }\r\n }, 6 * 1e5);\r\n\r\n // 删除\r\n $this.querySelector('.comment-item-delete').addEventListener('click', function (e) {\r\n var postData = {\r\n id: post.id\r\n }\r\n var delDom = e.currentTarget;\r\n delDom.innerHTML = '删除中';\r\n postAjax(_.opts.api + '/removecomment.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n if (data.response.isDeleted == true) {\r\n $this.outerHTML = '';\r\n _.stat.thread.posts = parseInt(_.dom.querySelector('#comment-count').innerHTML) - 1;\r\n _.dom.querySelector('#comment-count').innerHTML = _.stat.thread.posts + ' 条评论';\r\n } else {\r\n alert(data.response.message);\r\n $this.querySelector('.comment-item-manage').outerHTML = '';\r\n }\r\n } else if (data.code === 2) {\r\n alert(data.response);\r\n $this.querySelector('.comment-item-manage').outerHTML = '';\r\n }\r\n }, function () {\r\n alert('删除出错,请稍后重试');\r\n })\r\n clearTimeout(postEdit);\r\n }, false)\r\n\r\n // 编辑\r\n $this.querySelector('.comment-item-edit').addEventListener('click', function () {\r\n _.stat.editing = post;\r\n _.edit(post);\r\n }, false)\r\n }\r\n }\r\n\r\n // 读取更多\r\n iDisqus.prototype.loadMore = function (e, target) {\r\n var _ = this;\r\n _.stat.offsetTop = d.documentElement.scrollTop || d.body.scrollTop;\r\n if (!_.stat.loading) {\r\n target.classList.add('loading');\r\n _.getlist();\r\n }\r\n }\r\n\r\n // 读取更多回复\r\n iDisqus.prototype.loadMoreReply = function (e, target) {\r\n var _ = this;\r\n target.innerHTML = '加载中……';\r\n var $children = target.closest('.comment-item-children');\r\n var $post = target.closest('.comment-item');\r\n getAjax(\r\n _.opts.api + '/descendants.php?post=' + $post.dataset.id,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if( data.code == 0 ){\r\n $children.removeChild(target.parentNode);\r\n var posts = data.response;\r\n posts.forEach(function (item) {\r\n _.load(item);\r\n });\r\n _.timeAgo();\r\n } else {\r\n target.innerHTML = '读取失败';\r\n }\r\n }, function () {\r\n target.innerHTML = '读取出错';\r\n }\r\n );\r\n }\r\n\r\n // 评论框焦点\r\n iDisqus.prototype.focus = function (e, target) {\r\n var wrapper = target.closest('.comment-form-wrapper');\r\n wrapper.classList.add('editing');\r\n if (wrapper.classList.contains('focus')) {\r\n wrapper.classList.remove('focus');\r\n } else {\r\n wrapper.classList.add('focus');\r\n }\r\n }\r\n\r\n // 输入事件\r\n iDisqus.prototype.input = function (e, target) {\r\n var _ = this;\r\n var form = target.closest('.comment-form');\r\n var alertmsg = form.querySelector('.comment-form-alert');\r\n alertmsg.innerHTML = '';\r\n var wrapper = form.querySelector('.comment-form-wrapper');\r\n var filterText = target.value.replace(/<code>.*?<\\/code>/g, '');\r\n var urls = filterText.match(/(^|\\s|\\r|\\n)*(http:\\/\\/|https:\\/\\/)(\\w|-|\\.)*(disqus|sinaimg|giphy|imgur|instagram|twimg|twitter|youtube|youtu\\.be)((\\w|=|\\?|\\.|\\/|&|\\%|-)*)(jpg|png|gif|gallery\\/\\w+|p\\/[a-zA-Z0-9]{11}.*|status\\/\\d{19}|v=[a-zA-Z0-9]{11}|\\/[a-zA-Z0-9]{11})(\\s|$|\\n)/g);\r\n form.querySelector('.comment-image-list').innerHTML = '';\r\n if (!!urls) {\r\n urls.forEach(function (item, i) {\r\n item = item.replace('/\\n|\\r\\n|^\\s|\\s$/g', '');\r\n var image = _.stat.media[item];\r\n if (!!image) {\r\n var imageHtml = `<li class=\"comment-image-item\" data-image-url=\"${image.thumbnailUrl}\"><img class=\"comment-image-object\" src=\"https:${image.thumbnailUrl}\"></li>`;\r\n form.querySelector('.comment-image-list').insertAdjacentHTML('beforeend', imageHtml);\r\n wrapper.classList.add('expanded');\r\n return;\r\n }\r\n postAjax(_.opts.api + '/media.php', { url: item }, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n image = data.response;\r\n var imageHtml = `<li class=\"comment-image-item\" data-image-url=\"${image.thumbnailUrl}\"><img class=\"comment-image-object\" src=\"https:${image.thumbnailUrl}\"></li>`;\r\n form.querySelector('.comment-image-list').insertAdjacentHTML('beforeend', imageHtml);\r\n _.stat.media[item] = image;\r\n wrapper.classList.add('expanded');\r\n }\r\n }, function () {\r\n })\r\n })\r\n } else {\r\n wrapper.classList.remove('expanded');\r\n }\r\n\r\n }\r\n\r\n // 提醒用户 @ mention \r\n iDisqus.prototype.mention = function (e, target) {\r\n var _ = this;\r\n var textarea = target;\r\n var selStart = textarea.selectionStart;\r\n var mentionIndex = textarea.value.slice(0, selStart).lastIndexOf('@');\r\n var mentionText = textarea.value.slice(mentionIndex, selStart);\r\n var mentionDom = _.dom.querySelector('.mention-user');\r\n var showUsers = _.stat.users.filter(function (user) {\r\n var re = new RegExp(mentionText.slice(1), 'i');\r\n return user.username.search(re) > -1;\r\n });\r\n if (mentionText.search(/^@\\w+$|^@$/) == 0 && showUsers.length > 0) {\r\n if (e.keyCode == 38 || e.keyCode == 40) {\r\n return;\r\n }\r\n var coord = _.getCaretCoord(textarea);\r\n var list = '', html = '';\r\n\r\n showUsers.forEach(function (item, i) {\r\n 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>`;\r\n })\r\n if (!!mentionDom) {\r\n mentionDom.innerHTML = '<ul class=\"mention-user-list\">' + list + '</ul>';\r\n mentionDom.style.left = coord.left + 'px';\r\n mentionDom.style.top = coord.top + 'px';\r\n } else {\r\n html = `<div class=\"mention-user\" style=\"left:${coord.left}px;top:${coord.top}px\"><ul class=\"mention-user-list\">${list}</ul></div>`;\r\n _.dom.querySelector('#idisqus').insertAdjacentHTML('beforeend', html);\r\n }\r\n\r\n // 鼠标悬浮\r\n _.addListener('mention-user-item', 'mouseover', function () {\r\n _.dom.querySelector('.mention-user-item.active').classList.remove('active');\r\n this.classList.add('active');\r\n })\r\n\r\n // 鼠标点击\r\n _.addListener('mention-user-item', 'click', function () {\r\n var username = '@' + this.dataset.username + ' ';\r\n textarea.value = textarea.value.slice(0, mentionIndex) + username + textarea.value.slice(selStart);\r\n mentionDom.outerHTML = '';\r\n textarea.focus();\r\n textarea.setSelectionRange(mentionIndex + username.length, mentionIndex + username.length)\r\n })\r\n } else if (!!mentionDom) {\r\n mentionDom.outerHTML = '';\r\n }\r\n }\r\n\r\n // 获取光标坐标 https://medium.com/@_jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a\r\n iDisqus.prototype.getCaretCoord = function (textarea) {\r\n var _ = this;\r\n var carPos = textarea.selectionEnd,\r\n div = d.createElement('div'),\r\n span = d.createElement('span'),\r\n copyStyle = getComputedStyle(textarea);\r\n [].forEach.call(copyStyle, function (prop) {\r\n div.style[prop] = copyStyle[prop];\r\n });\r\n div.style.position = 'absolute';\r\n _.dom.appendChild(div);\r\n div.textContent = textarea.value.substr(0, carPos);\r\n span.textContent = textarea.value.substr(carPos) || '.';\r\n div.appendChild(span);\r\n var coords = {\r\n 'top': textarea.offsetTop - textarea.scrollTop + span.offsetTop + parseFloat(copyStyle.lineHeight),\r\n 'left': textarea.offsetLeft - textarea.scrollLeft + span.offsetLeft\r\n };\r\n _.dom.removeChild(div);\r\n return coords;\r\n }\r\n\r\n // 键盘选择用户\r\n iDisqus.prototype.keySelect = function (e, target) {\r\n var _ = this;\r\n var textarea = target;\r\n var selStart = textarea.selectionStart;\r\n var mentionIndex = textarea.value.slice(0, selStart).lastIndexOf('@');\r\n var mentionText = textarea.value.slice(mentionIndex, selStart);\r\n var mentionDom = _.dom.querySelector('.mention-user');\r\n if (!mentionDom) {\r\n return;\r\n }\r\n var current = _.dom.querySelector('.mention-user-item.active')\r\n switch (e.keyCode) {\r\n case 13:\r\n //回车\r\n var username = '@' + current.dataset.username + ' ';\r\n textarea.value = textarea.value.slice(0, mentionIndex) + username + textarea.value.slice(selStart);\r\n textarea.setSelectionRange(mentionIndex + username.length, mentionIndex + username.length)\r\n _.dom.querySelector('.mention-user').outerHTML = '';\r\n e.preventDefault();\r\n break;\r\n case 38:\r\n //上\r\n if (!!current.previousSibling) {\r\n current.previousSibling.classList.add('active');\r\n current.classList.remove('active');\r\n }\r\n e.preventDefault();\r\n break;\r\n case 40:\r\n //下\r\n if (!!current.nextSibling) {\r\n current.nextSibling.classList.add('active');\r\n current.classList.remove('active');\r\n }\r\n e.preventDefault();\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n // 跳到评论\r\n iDisqus.prototype.jump = function (e, target) {\r\n var _ = this;\r\n var hash = getLocation(target.href).hash;\r\n var el = _.dom.querySelector('#idisqus ' + hash);\r\n history.replaceState(undefined, undefined, hash);\r\n window.scrollBy(0, el.getBoundingClientRect().top);\r\n e.preventDefault();\r\n }\r\n\r\n // 显示父评论\r\n iDisqus.prototype.parentShow = function (e, target) {\r\n var _ = this;\r\n if (!!target.querySelector('.comment-item-parent')) {\r\n return;\r\n }\r\n var comment = _.stat.post[target.dataset.parent];\r\n if (comment.isDeleted) {\r\n return;\r\n }\r\n var message = comment.message.replace(/<[^>]*>/g, '');\r\n var parentHtml = `<div class=\"comment-item-parent\"><a class=\"comment-item-avatar\" href=\"javascript:;\"><img src=\"${comment.avatar}\"></a><div class=\"comment-item-pmain\"><div class=\"comment-item-pheader\">${comment.name}</div><div class=\"comment-item-pcontent\" title=\"${message}\">${message}</div></div></div>`;\r\n target.insertAdjacentHTML('beforeend', parentHtml);\r\n }\r\n\r\n // 点选表情\r\n iDisqus.prototype.field = function (e, target) {\r\n var _ = this;\r\n var item = target;\r\n var form = item.closest('.comment-form');\r\n var textarea = form.querySelector('.comment-form-textarea');\r\n _.appendText(textarea, item.dataset.code);\r\n }\r\n\r\n // 显示回复框 or 取消回复框\r\n iDisqus.prototype.show = function (e, target) {\r\n var _ = this;\r\n\r\n var $this = target;\r\n var item = $this.closest('.comment-item');\r\n\r\n // 无论取消还是回复,移除已显示回复框\r\n var box = _.dom.querySelector('.comment-item .comment-box:not([data-current-id])');\r\n if (box) {\r\n var $show = box.closest('.comment-item');\r\n var cancel = $show.querySelector('.comment-item-cancel')\r\n cancel.outerHTML = cancel.outerHTML.replace('cancel', 'reply');\r\n box.outerHTML = '';\r\n }\r\n\r\n // 回复时,显示评论框\r\n if ($this.className == 'comment-item-reply') {\r\n $this.outerHTML = $this.outerHTML.replace('reply', 'cancel');\r\n var commentBox = _.box.replace(/emoji-input/g, 'emoji-input-' + item.dataset.id).replace(/upload-input/g, 'upload-input-' + item.dataset.id);\r\n item.querySelector('.comment-item-children').insertAdjacentHTML('beforebegin', commentBox);\r\n _.user.init();\r\n\r\n item.querySelector('.comment-form-textarea').focus();\r\n }\r\n\r\n }\r\n\r\n // 验证表单\r\n iDisqus.prototype.verify = function (e, target) {\r\n var _ = this;\r\n var $this = target;\r\n var box = $this.closest('.comment-box');\r\n var $avatar = box.querySelector('.comment-avatar-image');\r\n var $name = box.querySelector('.comment-form-name');\r\n var $email = box.querySelector('.comment-form-email');\r\n var alertmsg = box.querySelector('.comment-form-alert');\r\n if ($email.value == '') {\r\n return;\r\n }\r\n getAjax(\r\n _.opts.api + '/getgravatar.php?email=' + $email.value + '&name=' + $name.value,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if (!data.isEmail && $this == $email) {\r\n _.errorTips('您所填写的邮箱地址有误。', $email);\r\n }\r\n if ($name.value != '') {\r\n $avatar.src = data.gravatar;\r\n }\r\n }, function () {\r\n }\r\n );\r\n }\r\n\r\n // 添加文本\r\n iDisqus.prototype.appendText = function (textarea, text) {\r\n var _ = this;\r\n var selStart = textarea.selectionStart;\r\n var text = selStart == 0 ? text + ' ' : ' ' + text + ' ';\r\n textarea.value = textarea.value.slice(0, selStart) + text + textarea.value.slice(selStart);\r\n textarea.focus();\r\n textarea.setSelectionRange(selStart + text.length, selStart + text.length);\r\n }\r\n\r\n // 上传图片\r\n iDisqus.prototype.upload = function (e, target) {\r\n var _ = this;\r\n var file = target;\r\n var form = file.closest('.comment-form');\r\n var progress = form.querySelector('.comment-image-progress');\r\n var loaded = form.querySelector('.comment-image-loaded');\r\n var wrapper = form.querySelector('.comment-form-wrapper');\r\n var alertmsg = form.querySelector('.comment-form-alert');\r\n alertmsg.innerHTML = '';\r\n if (file.files.length === 0) {\r\n return;\r\n }\r\n\r\n // 以文件大小识别是否为同张图片\r\n var size = file.files[0].size;\r\n\r\n if (size > 5 * 1e6) {\r\n alertmsg.innerHTML = '请选择 5M 以下图片。';\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n return;\r\n }\r\n\r\n if (_.stat.imageSize.indexOf(size) == -1) {\r\n progress.style.width = '80px';\r\n } else {\r\n alertmsg.innerHTML = '请勿选择已存在的图片。';\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n return;\r\n }\r\n\r\n // 展开图片上传界面\r\n wrapper.classList.add('expanded');\r\n\r\n // 图片上传请求\r\n var data = new FormData();\r\n data.append('file', file.files[0]);\r\n var filename = file.files[0].name;\r\n\r\n var $item;\r\n\r\n var xhrUpload = new XMLHttpRequest();\r\n xhrUpload.withCredentials = true;\r\n xhrUpload.onreadystatechange = function () {\r\n if (xhrUpload.readyState == 4 && xhrUpload.status == 200) {\r\n var data = JSON.parse(xhrUpload.responseText);\r\n if (data.code == 0) {\r\n _.stat.imageSize.push(size);\r\n var imageUrl = data.response.thumbnailUrl;\r\n var textarea = form.querySelector('.comment-form-textarea');\r\n _.appendText(textarea, 'https:'+imageUrl);\r\n\r\n var image = new Image();\r\n image.src = imageUrl;\r\n image.onload = function () {\r\n $item.innerHTML = '<img class=\"comment-image-object\" src=\"https:' + imageUrl + '\">';\r\n $item.dataset.imageUrl = imageUrl;\r\n $item.classList.remove('loading');\r\n }\r\n } else {\r\n alertmsg.innerHTML = '图片上传出错。';\r\n $item.innerHTML = '';\r\n if (!!form.getElementsByClassName('comment-image-item').length) {\r\n wrapper.classList.remove('expanded');\r\n }\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n }\r\n }\r\n };\r\n xhrUpload.upload.addEventListener('progress', function (e) {\r\n loaded.style.width = Math.ceil((e.loaded / e.total) * 100) + '%';\r\n }, false);\r\n xhrUpload.upload.addEventListener('load', function (e) {\r\n loaded.style.width = 0;\r\n progress.style.width = 0;\r\n var imageItem = `<li class=\"comment-image-item loading\" data-image-size=\"${size}\">\r\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\" width=\"24px\" height=\"30px\" viewBox=\"0 0 24 30\" style=\"enable-background: new 0 0 50 50;\" xml:space=\"preserve\">\r\n <rect x=\"0\" y=\"10\" width=\"4\" height=\"10\" fill=\"rgba(127,145,158,1)\" opacity=\"0.2\">\r\n <animate attributeName=\"opacity\" attributeType=\"XML\" values=\"0.2; 1; .2\" begin=\"0s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"height\" attributeType=\"XML\" values=\"10; 20; 10\" begin=\"0s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"y\" attributeType=\"XML\" values=\"10; 5; 10\" begin=\"0s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n </rect>\r\n <rect x=\"8\" y=\"10\" width=\"4\" height=\"10\" fill=\"rgba(127,145,158,1)\" opacity=\"0.2\">\r\n <animate attributeName=\"opacity\" attributeType=\"XML\" values=\"0.2; 1; .2\" begin=\"0.15s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"height\" attributeType=\"XML\" values=\"10; 20; 10\" begin=\"0.15s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"y\" attributeType=\"XML\" values=\"10; 5; 10\" begin=\"0.15s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n </rect>\r\n <rect x=\"16\" y=\"10\" width=\"4\" height=\"10\" fill=\"rgba(127,145,158,1)\" opacity=\"0.2\">\r\n <animate attributeName=\"opacity\" attributeType=\"XML\" values=\"0.2; 1; .2\" begin=\"0.3s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"height\" attributeType=\"XML\" values=\"10; 20; 10\" begin=\"0.3s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"y\" attributeType=\"XML\" values=\"10; 5; 10\" begin=\"0.3s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n </rect>\r\n </svg>\r\n </li>`;\r\n form.querySelector('.comment-image-list').insertAdjacentHTML('beforeend', imageItem);\r\n $item = form.querySelector('[data-image-size=\"' + size + '\"]');\r\n }, false);\r\n xhrUpload.open('POST', _.opts.api + '/media.php', true);\r\n xhrUpload.send(data);\r\n }\r\n\r\n // 移除图片\r\n iDisqus.prototype.remove = function (e) {\r\n var _ = this;\r\n var $item = e.currentTarget.closest('.comment-image-item');\r\n var wrapper = e.currentTarget.closest('.comment-form-wrapper');\r\n $item.outerHTML = '';\r\n _.stat.imageSize = [];\r\n var imageArr = wrapper.getElementsByClassName('comment-image-item');\r\n [].forEach.call(imageArr, function (item, i) {\r\n _.stat.imageSize[i] = item.dataset.imageSize;\r\n });\r\n if (_.stat.imageSize.length == 0) {\r\n wrapper.classList.remove('expanded');\r\n }\r\n wrapper.querySelector('.comment-image-input').value = '';\r\n }\r\n\r\n // 错误提示\r\n iDisqus.prototype.errorTips = function (Text, Dom) {\r\n var _ = this;\r\n if (_.user.logged_in == 'true') {\r\n _.handle.logout();\r\n }\r\n var idisqus = _.dom.querySelector('#idisqus');\r\n var errorDom = _.dom.querySelector('.comment-form-error');\r\n if (!!errorDom) {\r\n errorDom.outerHTML = '';\r\n }\r\n var Top = Dom.offsetTop;\r\n var Left = Dom.offsetLeft;\r\n var errorHtml = '<div class=\"comment-form-error\" style=\"top:' + Top + 'px;left:' + Left + 'px;\">' + Text + '</div>';\r\n idisqus.insertAdjacentHTML('beforeend', errorHtml);\r\n setTimeout(function () {\r\n var errorDom = _.dom.querySelector('.comment-form-error');\r\n if (!!errorDom) {\r\n errorDom.outerHTML = '';\r\n }\r\n }, 3000);\r\n }\r\n\r\n // 发表/回复评论\r\n iDisqus.prototype.post = function (e, target) {\r\n var _ = this;\r\n var item = target.closest('.comment-box[data-current-id]') || target.closest('.comment-item') || target.closest('.comment-box');\r\n var message = item.querySelector('.comment-form-textarea').value;\r\n var parentId = !!item.dataset.id ? item.dataset.id : '';\r\n var imgArr = item.getElementsByClassName('comment-image-item');\r\n\r\n // 不是编辑框需预览\r\n if (!item.dataset.currentId) {\r\n var elName = item.querySelector('.comment-form-name');\r\n var elEmail = item.querySelector('.comment-form-email');\r\n var elUrl = item.querySelector('.comment-form-url');\r\n var alertmsg = item.querySelector('.comment-form-alert');\r\n var alertClear = function () {\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n }\r\n\r\n if (_.user.type != '1') {\r\n var anonName = elName.value;\r\n var anonEmail = elEmail.value;\r\n var anonUrl = elUrl.value.replace(/\\s/g, '');\r\n if (/^\\s*$/i.test(anonName)) {\r\n _.errorTips('名字不能为空或空格。', elName);\r\n return;\r\n }\r\n if (/^\\s*$/i.test(anonEmail)) {\r\n _.errorTips('邮箱不能为空或空格。', elEmail);\r\n return;\r\n }\r\n if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i.test(anonEmail)) {\r\n _.errorTips('请正确填写邮箱。', elEmail);\r\n return;\r\n }\r\n if (!/^([hH][tT]{2}[pP]:\\/\\/|[hH][tT]{2}[pP][sS]:\\/\\/)(([A-Za-z0-9-~]+)\\.)+([A-Za-z0-9-~\\/])+$|^\\s*$/i.test(anonUrl)) {\r\n _.errorTips('请正确填写网址。', elUrl);\r\n return;\r\n }\r\n _.user.unique = _.user.email == anonEmail ? _.user.unique : generateGUID();\r\n _.user.name = anonName;\r\n _.user.email = anonEmail;\r\n _.user.url = anonUrl;\r\n _.user.avatar = item.querySelector('.comment-avatar-image').src;\r\n _.user.submit();\r\n\r\n if (!_.user.name && !_.user.email) {\r\n return;\r\n }\r\n }\r\n\r\n if (!_.stat.message && !_.stat.mediaHtml) {\r\n _.box = _.dom.querySelector('.comment-box').outerHTML.replace('comment-form-wrapper', 'comment-form-wrapper editing').replace(/加入讨论……/, '');\r\n }\r\n\r\n if (/^\\s*$/i.test(message)) {\r\n alertmsg.innerHTML = '评论不能为空或空格。';\r\n item.querySelector('.comment-form-textarea').focus();\r\n return;\r\n };\r\n\r\n var preMessage = message;\r\n\r\n if (!!_.opts.emoji_preview) {\r\n preMessage = preMessage.replace(/:([-+\\w]+):/g, function (match) {\r\n var emojiShort = match.replace(/:/g, '');\r\n var emojiImage = !!_.eac[emojiShort] ? `<img class=\"emojione\" width=\"24\" height=\"24\" alt=\"'+emojiShort+'\" title=\":${emojiShort}:\" src=\"${_.opts.emojiPath + _.eac[emojiShort]}.png\">` : match;\r\n return emojiImage;\r\n });\r\n } else {\r\n _.emojiList.forEach(function (item) {\r\n preMessage = preMessage.replace(`:${item.code}:`, `<img class=\"emojione\" width=\"24\" height=\"24\" src=\"${_.opts.emojiPath + item.unicode}.png\" />`);\r\n });\r\n }\r\n\r\n var post = {\r\n 'url': !!_.user.url ? _.user.url : '',\r\n 'isMod': false,\r\n 'username': null,\r\n 'name': _.user.name,\r\n 'avatar': _.user.avatar,\r\n 'id': 'preview',\r\n 'parent': parentId,\r\n 'createdAt': (new Date()).toJSON(),\r\n 'message': '<p>' + preMessage + '</p>',\r\n };\r\n\r\n _.load(post);\r\n\r\n _.timeAgo();\r\n\r\n // 清空或移除评论框\r\n _.stat.message = message;\r\n _.stat.mediaHtml = item.querySelector('.comment-image-list').innerHTML;\r\n\r\n if (parentId) {\r\n item.querySelector('.comment-item-cancel').click();\r\n } else {\r\n item.querySelector('.comment-form-textarea').value = '';\r\n item.querySelector('.comment-image-list').innerHTML = '';\r\n item.querySelector('.comment-form-wrapper').classList.remove('expanded', 'editing');\r\n }\r\n }\r\n\r\n // @\r\n var mentions = message.match(/@\\w+/g);\r\n if (!!mentions) {\r\n mentions = mentions.filter(function (mention) {\r\n return _.stat.users.map(function (user) { return user.username; }).indexOf(mention.slice(1)) > -1;\r\n });\r\n if (mentions.length > 0) {\r\n var re = new RegExp('(' + mentions.join('|') + ')', 'g');\r\n message = message.replace(re, '$1:disqus');\r\n }\r\n }\r\n\r\n // POST 操作\r\n // 编辑框则更新评论\r\n if (!!item.dataset.currentId) {\r\n var postData = {\r\n id: item.dataset.currentId,\r\n message: message,\r\n unique: _.user.unique\r\n }\r\n postAjax(_.opts.api + '/updatecomment.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n _.stat.message = null;\r\n _.stat.mediaHtml = null;\r\n var post = data.response;\r\n _.load(post);\r\n _.timeAgo();\r\n _.stat.editing = false;\r\n } else {\r\n // 取消编辑\r\n _.load(_.stat.editing)\r\n _.timeAgo();\r\n _.stat.editing = false;\r\n }\r\n }, function () {\r\n // 取消编辑\r\n _.load(_.stat.editing)\r\n _.timeAgo();\r\n _.stat.editing = false;\r\n })\r\n } else {\r\n var postData = {\r\n thread: _.stat.thread.id,\r\n parent: parentId,\r\n message: message,\r\n name: _.user.name,\r\n email: _.user.email,\r\n url: _.user.url,\r\n unique: _.user.unique\r\n }\r\n postAjax(_.opts.api + '/postcomment.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.stat.thread = data.thread;\r\n _.stat.thread.posts = parseInt(_.dom.querySelector('#comment-count').innerHTML) + 1;\r\n _.dom.querySelector('#comment-count').innerHTML = _.stat.thread.posts + ' 条评论';\r\n var post = data.response;\r\n post.isPost = true;\r\n _.load(post);\r\n _.timeAgo();\r\n var postData = {\r\n post: JSON.stringify(post),\r\n thread: JSON.stringify(_.stat.thread),\r\n parent: JSON.stringify(_.stat.post[parentId]),\r\n code: data.verifyCode\r\n }\r\n if (!!data.verifyCode) {\r\n // 异步发送邮件\r\n postAjax(_.opts.api + '/sendemail.php', postData, function (resp) {\r\n console.info('邮件发送成功!');\r\n })\r\n }\r\n } else if (data.code === 2) {\r\n alertmsg.innerHTML = data.response;\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.reEdit(item);\r\n\r\n if (data.response.indexOf('author') > -1) {\r\n _.handle.logout();\r\n }\r\n } else {\r\n alertmsg.innerHTML = '提交失败,请稍后重试,错误代码:' + data.code;\r\n alertClear();\r\n\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.reEdit(item);\r\n }\r\n\r\n }, function () {\r\n alertmsg.innerHTML = '提交出错,请稍后重试。';\r\n alertClear();\r\n\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.reEdit(item);\r\n })\r\n }\r\n }\r\n\r\n // 重新编辑\r\n iDisqus.prototype.reEdit = function (item) {\r\n var _ = this;\r\n\r\n if (!!item.dataset.id) {\r\n item.querySelector('.comment-item-reply').click();\r\n } else {\r\n item.querySelector('.comment-form-wrapper').classList.add('editing');\r\n }\r\n\r\n // 重新填充文本图片\r\n if (!!_.stat.message) {\r\n item.querySelector('.comment-form-textarea').value = _.stat.message;\r\n }\r\n if (!!_.stat.mediaHtml) {\r\n item.querySelector('.comment-form-wrapper').classList.add('expanded');\r\n item.querySelector('.comment-image-list').innerHTML = _.stat.mediaHtml;\r\n }\r\n }\r\n\r\n // 编辑\r\n iDisqus.prototype.edit = function (post) {\r\n var _ = this;\r\n 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);\r\n var $this = _.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"] .comment-item-body');\r\n $this.outerHTML = commentBox;\r\n _.user.init();\r\n var item = _.dom.querySelector('.comment-box-' + post.id);\r\n item.dataset.currentId = post.id;\r\n item.querySelector('.comment-form-textarea').focus();\r\n\r\n // 取消编辑\r\n item.querySelector('.comment-actions-form').insertAdjacentHTML('afterbegin', '<a class=\"comment-form-cancel\" href=\"javascript:;\">取消</a>')\r\n item.querySelector('.comment-form-cancel').addEventListener('click', function () {\r\n _.stat.editing = false;\r\n _.load(post);\r\n _.timeAgo();\r\n }, false);\r\n\r\n // 重新填充文本图片,连续回复、连续编辑会有 bug\r\n if (!!_.stat.message) {\r\n item.querySelector('.comment-form-textarea').value = _.stat.message;\r\n }\r\n if (!!_.stat.mediaHtml) {\r\n item.querySelector('.comment-form-wrapper').classList.add('expanded');\r\n item.querySelector('.comment-image-list').innerHTML = _.stat.mediaHtml;\r\n }\r\n\r\n }\r\n\r\n // Thread 初始化\r\n iDisqus.prototype.threadInit = function (e, target) {\r\n var _ = this;\r\n _.dom.querySelector('#idisqus').style.display = 'block';\r\n _.dom.querySelector('#disqus_thread').style.display = 'none';\r\n getAjax(_.opts.api + '/threadsDetails.php?ident=' + _.opts.identifier + '&link=' + _.opts.url, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n _.stat.thread = data.response;\r\n _.stat.forum = data.forum;\r\n _.dom.querySelector('#comment-link').href = `https://disqus.com/home/discussion/${_.stat.forum.id}/${_.stat.thread.slug}/?l=zh`;\r\n _.dom.querySelector('.comment-avatar-image').dataset.avatar = _.stat.forum.avatar;\r\n _.dom.querySelector('.comment-recommend-count').innerHTML = _.stat.thread.likes || '';\r\n if (_.stat.forum.settings.mediaembedEnabled == false) {\r\n _.dom.querySelector('.comment-image-input').outerHTML = ''\r\n _.dom.querySelector('[for=\"upload-input\"]').outerHTML = ''\r\n }\r\n if (_.user.logged_in == 'false') {\r\n _.dom.querySelector('.comment-avatar-image').src = _.stat.forum.avatar;\r\n }\r\n _.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(/加入讨论……/, '');\r\n _.opts.badge = _.stat.forum.moderatorBadgeText;\r\n if (!_.stat.order) {\r\n switch (_.stat.forum.order) {\r\n case 1:\r\n _.stat.order = 'asc';\r\n break;\r\n case 2:\r\n _.stat.order = 'desc';\r\n break;\r\n case 4:\r\n _.stat.order = 'popular';\r\n break;\r\n }\r\n }\r\n _.dom.querySelector('.comment-order-radio[value=\"' + _.stat.order + '\"]').checked = true;\r\n\r\n var users = data.votedusers;\r\n var vote = 0;\r\n if (_.user.type == 1) {\r\n // 已登录\r\n vote = users.filter(function (user) {\r\n return user.username == _.user.username;\r\n }).length > 0 ? 1 : 0;\r\n } else {\r\n // 未登录\r\n vote = !!_.user.vote[_.stat.thread.id] ? 1 : 0;;\r\n }\r\n _.user.vote[_.stat.thread.id] = vote;\r\n l.setItem('vote', JSON.stringify(_.user.vote));\r\n if (!!vote) {\r\n _.dom.querySelector('.comment-recommend').classList.add('voted');\r\n _.dom.querySelector('.comment-recommend-text').innerHTML = '已推荐';\r\n }\r\n _.dom.querySelector('#idisqus').classList.remove('init')\r\n _.loadRelated();\r\n _.loadReactions();\r\n _.dom.querySelector('#comment-count').innerHTML = _.stat.thread.posts + ' 条评论';\r\n _.getlist();\r\n } else if (data.code === 2) {\r\n // 自动创建\r\n if (_.opts.autoCreate) {\r\n _.dom.querySelector('.init-container').dataset.tips = '正在创建 Thread……';\r\n var postData = {\r\n url: _.opts.link,\r\n identifier: _.opts.identifier,\r\n title: _.opts.title,\r\n slug: _.opts.slug,\r\n message: _.opts.desc\r\n }\r\n _.threadCreate(postData);\r\n return;\r\n }\r\n _.dom.querySelector('#idisqus').classList.remove('init');\r\n var threadForm = `<div class=\"comment-header\"><span class=\"comment-header-item\">创建 Thread</span></div>\r\n <div class=\"comment-thread-form\">\r\n <p>由于 Disqus 没有本页面的相关 Thread,故需先创建 Thread</p>\r\n <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>\r\n <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>\r\n <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>\r\n <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>\r\n <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>\r\n <button id=\"thread-submit\" class=\"comment-form-submit\">提交</button></div>`;\r\n _.dom.querySelector('#idisqus').innerHTML = threadForm;\r\n }\r\n }, function () { })\r\n }\r\n\r\n // Thread 打分事件\r\n iDisqus.prototype.threadVote = function (e, target) {\r\n var _ = this;\r\n var vote = !!_.user.vote[_.stat.thread.id] ? 0 : 1;\r\n var postData = {\r\n thread: _.stat.thread.id,\r\n unique: _.user.unique,\r\n vote: vote\r\n }\r\n postAjax(_.opts.api + '/threadsVote.php', postData, function (resp) {\r\n _.user.vote[_.stat.thread.id] = vote;\r\n l.setItem('vote', JSON.stringify(_.user.vote));\r\n if (!!vote) {\r\n _.dom.querySelector('.comment-recommend').classList.add('voted');\r\n _.stat.thread.likes++;\r\n } else {\r\n _.dom.querySelector('.comment-recommend').classList.remove('voted');\r\n _.stat.thread.likes = _.stat.thread.likes == 0 ? 0 : _.stat.thread.likes - 1;\r\n }\r\n _.dom.querySelector('.comment-recommend-count').innerHTML = _.stat.thread.likes || '';\r\n })\r\n }\r\n\r\n // Thread Create 事件\r\n iDisqus.prototype.threadCreate = function (e, target) {\r\n var _ = this;\r\n if (!!target) {\r\n var postData = {\r\n url: _.dom.querySelector('#thread-url').value,\r\n identifier: _.dom.querySelector('#thread-identifier').value,\r\n title: _.dom.querySelector('#thread-title').value,\r\n slug: _.dom.querySelector('#thread-slug').value.replace(/[^A-Za-z0-9_-]+/g, ''),\r\n message: _.dom.querySelector('#thread-message').value\r\n }\r\n } else {\r\n var postData = arguments[0];\r\n }\r\n postAjax(_.opts.api + '/createthread.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n alert('创建 Thread 成功,刷新后便可愉快地评论了!');\r\n setTimeout(function () { location.reload(); }, 2000);\r\n } else if (data.code === 2) {\r\n if (data.response.indexOf('A thread already exists with link') > -1) {\r\n alert(data.response.replace('A thread already exists with link,', '已存在此链接的相关 Thread,'));\r\n return;\r\n }\r\n if (data.response.indexOf('Invalid URL') > -1) {\r\n alert('参数错误,无效的\\'URL\\'');\r\n return;\r\n }\r\n if (data.response.indexOf('Invalid slug') > -1) {\r\n alert('参数错误,无效的\\'slug\\'');\r\n return;\r\n }\r\n alert(data.response);\r\n return;\r\n } else {\r\n alert(data.response);\r\n return;\r\n }\r\n }, function () {\r\n alert('创建 Thread 出错,请稍后重试!');\r\n })\r\n }\r\n\r\n // 销毁评论框\r\n iDisqus.prototype.destroy = function () {\r\n var _ = this;\r\n _.dom.innerHTML = '';\r\n delete _.dom;\r\n delete _.box;\r\n delete _.emojiList;\r\n delete _.user;\r\n delete _.handle;\r\n delete _.stat;\r\n delete _.opts;\r\n }\r\n\r\n /* CommonJS */\r\n if ( true && module && typeof exports === 'object' && exports)\r\n module.exports = iDisqus;\r\n /* AMD */\r\n else if (true)\r\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {\r\n return iDisqus;\r\n }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n /* Global */\r\n else\r\n {}\r\n\r\n})(window || this);\r\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://%5Bname%5D/./src/iDisqus.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_RESULT__;/*!\r\n * \r\n * @author fooleap\r\n * @email fooleap@gmail.com\r\n * @create 2017-06-17 20:48:25\r\n * @update 2021-05-11 11:58:38\r\n * @version 0.2.31\r\n * Copyright 2017-2021 fooleap\r\n * Released under the MIT license\r\n */\r\n__webpack_require__(/*! ./iDisqus.scss */ \"./src/iDisqus.scss\");\r\n(function (global) {\r\n 'use strict';\r\n\r\n var d = document,\r\n l = localStorage,\r\n scripts = d.scripts,\r\n lasturl = scripts[scripts.length - 1].src,\r\n filepath = lasturl.substring(0, lasturl.lastIndexOf('/')),\r\n isEdge = navigator.userAgent.indexOf(\"Edge\") > -1,\r\n isIE = !!window.ActiveXObject || \"ActiveXObject\" in window;\r\n\r\n function getLocation(href) {\r\n var link = d.createElement('a');\r\n link.href = href;\r\n return link;\r\n }\r\n\r\n function getAjax(url, success, error) {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', encodeURI(url));\r\n xhr.onreadystatechange = function () {\r\n if (xhr.readyState == 4 && xhr.status == 200) {\r\n success(xhr.responseText);\r\n }\r\n }\r\n xhr.onerror = error;\r\n xhr.withCredentials = true;\r\n xhr.send();\r\n return xhr;\r\n }\r\n\r\n function postAjax(url, data, success, error) {\r\n var params = typeof data == 'string' ? data : Object.keys(data).filter(function (k) {\r\n return data[k] != null;\r\n }).map(function (k) {\r\n return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])\r\n }).join('&');\r\n\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('POST', url);\r\n xhr.onreadystatechange = function () {\r\n if (xhr.readyState == 4 && xhr.status == 200) {\r\n success(xhr.responseText);\r\n }\r\n };\r\n xhr.onerror = error;\r\n xhr.withCredentials = true;\r\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\r\n xhr.send(params);\r\n return xhr;\r\n }\r\n\r\n function generateGUID() {\r\n var time = Number(new Date().getTime().toString().substring(3));\r\n var guid = Math.abs(time + Math.floor(Math.random() * 1e5) - 48 * 1e6 + Math.floor(Math.random() * 1e6)).toString(32);\r\n guid += Math.floor(Math.random() * 1e9).toString(32);\r\n return guid;\r\n }\r\n\r\n (function (ElementProto) {\r\n // matches & closest polyfill https://github.com/jonathantneal/closest\r\n if (typeof ElementProto.matches !== 'function') {\r\n ElementProto.matches = ElementProto.msMatchesSelector || ElementProto.mozMatchesSelector || ElementProto.webkitMatchesSelector || function matches(selector) {\r\n var element = this;\r\n var elements = (element.document || element.ownerDocument).querySelectorAll(selector);\r\n var index = 0;\r\n\r\n while (elements[index] && elements[index] !== element) {\r\n ++index;\r\n }\r\n\r\n return Boolean(elements[index]);\r\n };\r\n }\r\n\r\n if (typeof ElementProto.closest !== 'function') {\r\n ElementProto.closest = function closest(selector) {\r\n var element = this;\r\n\r\n while (element && element.nodeType === 1) {\r\n if (element.matches(selector)) {\r\n return element;\r\n }\r\n\r\n element = element.parentNode;\r\n }\r\n\r\n return null;\r\n };\r\n }\r\n\r\n // 事件委托\r\n ElementProto.on = function on(eventName, selector, handler) {\r\n this.addEventListener(eventName, function (e) {\r\n for (var target = e.target; target && target != this; target = target.parentNode) {\r\n if (target.matches(selector)) {\r\n handler.call(null, e, target);\r\n break;\r\n }\r\n }\r\n }, true);\r\n };\r\n\r\n })(window.Element.prototype);\r\n\r\n // 访客信息\r\n var User = function () {\r\n this.dom = arguments[0];\r\n this.opts = arguments[1];\r\n this.init();\r\n this.autologin();\r\n }\r\n\r\n User.prototype = {\r\n // 初始化访客信息\r\n init: function () {\r\n var _ = this;\r\n // 读取访客信息\r\n _.name = l.getItem('name');\r\n _.email = l.getItem('email');\r\n _.url = l.getItem('url');\r\n _.avatar = l.getItem('avatar');\r\n _.type = l.getItem('type');\r\n _.logged_in = l.getItem('logged_in');\r\n _.unique = l.getItem('disqus_unique')\r\n if (!l.getItem('vote')) {\r\n l.setItem('vote', JSON.stringify({}));\r\n }\r\n if (!l.getItem('reaction_vote')) {\r\n l.setItem('reaction_vote', JSON.stringify({}));\r\n }\r\n _.vote = JSON.parse(l.getItem('vote'));\r\n _.reactionVote = JSON.parse(l.getItem('reaction_vote'));\r\n\r\n var boxarr = _.dom.getElementsByClassName('comment-box');\r\n if (_.logged_in == 'true') {\r\n [].forEach.call(boxarr, function (item) {\r\n if (_.type == '1') {\r\n item.querySelector('.comment-form-wrapper').classList.add('logged-in');\r\n }\r\n item.querySelector('.comment-form-name').value = _.name;\r\n item.querySelector('.comment-form-email').value = _.email;\r\n item.querySelector('.comment-form-url').value = _.url;\r\n item.querySelector('.comment-avatar-image').src = _.avatar;\r\n });\r\n } else {\r\n [].forEach.call(boxarr, function (item) {\r\n item.querySelector('.comment-form-wrapper').classList.remove('logged-in');\r\n item.querySelector('.comment-form-name').value = '';\r\n item.querySelector('.comment-form-email').value = '';\r\n item.querySelector('.comment-form-url').value = '';\r\n item.querySelector('.comment-avatar-image').src = _.dom.querySelector('.comment-avatar-image').dataset.avatar;\r\n });\r\n l.setItem('logged_in', 'false');\r\n }\r\n\r\n if (_.type == '1' && _.logged_in == 'true') {\r\n var $login = _.dom.querySelector('.comment-login');\r\n if (!!$login) {\r\n $login.innerHTML = _.name + '<label class=\"comment-logout\" title=\"退出\" for=\"comment-user\">退出登录</label>';\r\n $login.title = _.name;\r\n $login.classList.add('comment-user');\r\n $login.classList.remove('comment-login');\r\n _.dom.querySelector('#comment-user').checked = false;\r\n }\r\n } else {\r\n var $user = _.dom.querySelector('.comment-user');\r\n if (!!$user) {\r\n $user.innerHTML = '登录';\r\n $user.title = '使用 Disqus 帐号授权登录';\r\n $user.classList.add('comment-login');\r\n $user.classList.remove('comment-user');\r\n }\r\n }\r\n\r\n },\r\n\r\n // 自动登录\r\n autologin: function () {\r\n var _ = this;\r\n getAjax(_.opts.api + '/user.php', function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n var user = data.response;\r\n _.avatar = user.avatar;\r\n _.name = user.name;\r\n _.username = user.username;\r\n _.url = user.url;\r\n _.type = user.type\r\n _.submit();\r\n } else {\r\n if (_.type == '1') {\r\n l.setItem('logged_in', 'false');\r\n _.init();\r\n } else {\r\n l.setItem('type', '0');\r\n if (!_.unique) {\r\n l.setItem('disqus_unique', generateGUID());\r\n }\r\n _.init();\r\n }\r\n }\r\n }, function () {\r\n })\r\n },\r\n\r\n // 登录\r\n login: function () {\r\n\r\n var _ = this;\r\n var popup = window.open(_.opts.api + '/login.php', 'Disqus Oauth', 'width=470,height=508');\r\n var timer;\r\n function isLogged() {\r\n if (!popup || !popup.closed) return;\r\n clearInterval(timer);\r\n _.user.autologin();\r\n }\r\n timer = setInterval(isLogged, 100);\r\n\r\n },\r\n\r\n // 退出登录\r\n logout: function () {\r\n var _ = this;\r\n postAjax(_.opts.api + '/logout.php', {}, function (resp) {\r\n l.setItem('logged_in', 'false');\r\n l.removeItem('type');\r\n l.removeItem('email');\r\n l.removeItem('avatar');\r\n l.removeItem('name');\r\n l.removeItem('url');\r\n l.removeItem('disqus_unique');\r\n l.removeItem('vote');\r\n l.removeItem('reaction_vote');\r\n _.user.init();\r\n })\r\n },\r\n\r\n // 提交访客信息\r\n submit: function () {\r\n var _ = this;\r\n l.setItem('email', _.email);\r\n l.setItem('type', _.type);\r\n l.setItem('name', _.name);\r\n l.setItem('url', _.url);\r\n l.setItem('avatar', _.avatar);\r\n l.setItem('disqus_unique', _.unique);\r\n l.setItem('logged_in', 'true');\r\n this.init();\r\n }\r\n }\r\n\r\n var iDisqus = function () {\r\n var _ = this;\r\n\r\n // 配置\r\n _.opts = typeof (arguments[1]) == 'object' ? arguments[1] : arguments[0];\r\n _.dom = d.getElementById(typeof (arguments[0]) == 'string' ? arguments[0] : 'comment');\r\n _.opts.api = _.opts.api.slice(-1) == '/' ? _.opts.api.slice(0, -1) : _.opts.api;\r\n _.opts.site = _.opts.site || location.origin;\r\n if (!!_.opts.url) {\r\n var optsUrl = _.opts.url.replace(_.opts.site, '');\r\n _.opts.url = optsUrl.slice(0, 1) != '/' ? '/' + optsUrl : optsUrl;\r\n } else if (isEdge || isIE) {\r\n _.opts.url = encodeURI(location.pathname) + encodeURI(location.search);\r\n } else {\r\n _.opts.url = location.pathname + location.search;\r\n }\r\n _.opts.identifier = _.opts.identifier || _.opts.url;\r\n _.opts.link = _.opts.site + _.opts.url;\r\n _.opts.title = _.opts.title || d.title;\r\n _.opts.slug = !!_.opts.slug ? _.opts.slug.replace(/[^A-Za-z0-9_-]+/g, '') : '';\r\n _.opts.desc = _.opts.desc || (!!d.querySelector('[name=\"description\"]') ? d.querySelector('[name=\"description\"]').content : '');\r\n _.opts.mode = _.opts.mode || 1;\r\n _.opts.timeout = _.opts.timeout || 3000;\r\n _.opts.toggle = !!_.opts.toggle ? d.getElementById(_.opts.toggle) : null;\r\n _.opts.autoCreate = !!_.opts.autoCreate || !!_.opts.auto;\r\n _.opts.relatedType = _.opts.relatedType || 'related'\r\n\r\n // emoji 表情\r\n _.opts.emojiPath = _.opts.emojiPath || _.opts.emoji_path || 'https://github.githubassets.com/images/icons/emoji/unicode/';\r\n _.emojiList = _.opts.emojiList || _.opts.emoji_list || [{\r\n code: 'smile',\r\n title: '笑脸',\r\n unicode: '1f604'\r\n }, {\r\n code: 'mask',\r\n title: '生病',\r\n unicode: '1f637'\r\n }, {\r\n code: 'joy',\r\n title: '破涕为笑',\r\n unicode: '1f602'\r\n }, {\r\n code: 'stuck_out_tongue_closed_eyes',\r\n title: '吐舌',\r\n unicode: '1f61d'\r\n }, {\r\n code: 'flushed',\r\n title: '脸红',\r\n unicode: '1f633'\r\n }, {\r\n code: 'scream',\r\n title: '恐惧',\r\n unicode: '1f631'\r\n }, {\r\n code: 'pensive',\r\n title: '失望',\r\n unicode: '1f614'\r\n }, {\r\n code: 'unamused',\r\n title: '无语',\r\n unicode: '1f612'\r\n }, {\r\n code: 'grin',\r\n title: '露齿笑',\r\n unicode: '1f601'\r\n }, {\r\n code: 'heart_eyes',\r\n title: '色',\r\n unicode: '1f60d'\r\n }, {\r\n code: 'sweat',\r\n title: '汗',\r\n unicode: '1f613'\r\n }, {\r\n code: 'smirk',\r\n title: '得意',\r\n unicode: '1f60f'\r\n }, {\r\n code: 'relieved',\r\n title: '满意',\r\n unicode: '1f60c'\r\n }, {\r\n code: 'rolling_eyes',\r\n title: '翻白眼',\r\n unicode: '1f644'\r\n }, {\r\n code: 'ok_hand',\r\n title: 'OK',\r\n unicode: '1f44c'\r\n }, {\r\n code: 'v',\r\n title: '胜利',\r\n unicode: '270c'\r\n }];\r\n\r\n if (!!_.opts.emoji_preview || !!_.opts.emojiPreview) {\r\n getAjax(_.opts.api + '/eac.php', function (resp) {\r\n _.eac = JSON.parse(resp);\r\n }, function () {\r\n })\r\n }\r\n\r\n // 默认状态\r\n _.stat = {\r\n current: 'idisqus', // 当前显示评论框\r\n loaded: false, // 评论框已加载\r\n loading: false, // 评论加载中\r\n editing: false, // 评论编辑中\r\n offsetTop: 0, // 高度位置\r\n next: null, // 下条评论\r\n message: null, // 新评论\r\n mediaHtml: null, // 新上传图片\r\n forum: {}, // 站点信息\r\n thread: {}, // 文章信息\r\n post: {}, // 评论数据\r\n media: {}, // 媒体信息\r\n root: [], // 根评论\r\n order: 'desc', // 排序\r\n users: [], // Disqus 会员\r\n imageSize: [], // 已上传图片大小\r\n disqusLoaded: false // Disqus 已加载\r\n };\r\n\r\n // Disqus 评论框设置\r\n window.disqus_config = function () {\r\n this.page.identifier = _.opts.identifier;\r\n this.page.title = _.opts.title;\r\n this.page.url = _.opts.link;\r\n this.callbacks.onReady.push(function () {\r\n _.stat.current = 'disqus';\r\n _.stat.disqusLoaded = true;\r\n _.dom.querySelector('#idisqus').style.display = 'none';\r\n _.dom.querySelector('#disqus_thread').style.display = 'block';\r\n if (_.opts.mode == 3 && !!_.opts.toggle) {\r\n _.opts.toggle.disabled = '';\r\n _.opts.toggle.checked = true;\r\n _.opts.toggle.addEventListener('change', _.handle.toggle, false);\r\n }\r\n });\r\n // 原生评论框发邮件\r\n this.callbacks.onNewComment = [function (comment, a) {\r\n var postData = {\r\n id: comment.id\r\n }\r\n // 异步发送邮件\r\n setTimeout(function () {\r\n postAjax(_.opts.api + '/sendemail.php', postData, function (resp) {\r\n console.info('邮件发送成功!');\r\n })\r\n }, 2000);\r\n }];\r\n }\r\n\r\n // 自动初始化\r\n if (!!_.opts.init) {\r\n _.init();\r\n //console.log(_);\r\n }\r\n }\r\n\r\n // TimeAgo https://coderwall.com/p/uub3pw/javascript-timeago-func-e-g-8-hours-ago\r\n iDisqus.prototype.timeAgo = function () {\r\n\r\n var _ = this;\r\n var templates = {\r\n prefix: \"\",\r\n suffix: \"前\",\r\n seconds: \"几秒\",\r\n minute: \"1分钟\",\r\n minutes: \"%d分钟\",\r\n hour: \"1小时\",\r\n hours: \"%d小时\",\r\n day: \"1天\",\r\n days: \"%d天\",\r\n week: \"1周\",\r\n weeks: \"%d周\",\r\n month: \"1个月\",\r\n months: \"%d个月\",\r\n year: \"1年\",\r\n years: \"%d年\"\r\n };\r\n var template = function (t, n) {\r\n return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n)));\r\n };\r\n\r\n var timer = function (time) {\r\n if (!time) return;\r\n time = time.replace(/\\.\\d+/, \"\"); // remove milliseconds\r\n time = time.replace(/-/, \"/\").replace(/-/, \"/\");\r\n time = time.replace(/T/, \" \").replace(/Z/, \" UTC\");\r\n time = time.replace(/([\\+\\-]\\d\\d)\\:?(\\d\\d)/, \" $1$2\"); // -04:00 -> -0400\r\n time = new Date(time * 1000 || time);\r\n\r\n var now = new Date();\r\n var seconds = ((now.getTime() - time) * .001) >> 0;\r\n var minutes = seconds / 60;\r\n var hours = minutes / 60;\r\n var days = hours / 24;\r\n var weeks = days / 7;\r\n var months = days / 30;\r\n var years = days / 365;\r\n\r\n 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', months) || years < 1.5 && template('year', 1) || template('years', years)) + templates.suffix;\r\n };\r\n\r\n var elements = _.dom.querySelectorAll('time[datetime]');\r\n for (var i in elements) {\r\n var $this = elements[i];\r\n if (typeof $this === 'object') {\r\n $this.title = new Date($this.getAttribute('datetime'));\r\n $this.innerHTML = timer($this.getAttribute('datetime'));\r\n }\r\n }\r\n\r\n // update time every minute\r\n setTimeout(_.timeAgo.bind(_), 60000);\r\n\r\n }\r\n\r\n // 初始化评论框\r\n iDisqus.prototype.init = function () {\r\n var _ = this;\r\n if (!_.dom) {\r\n //console.log('该页面没有评论框!');\r\n return\r\n }\r\n // 表情\r\n var emojiList = '';\r\n _.emojiList.forEach(function (item) {\r\n emojiList += '<li class=\"emojione-item\" title=\"' + item.title + '\" data-code=\":' + item.code + ':\"><img class=\"emojione-item-image\" src=\"' + _.opts.emojiPath + item.unicode + '.png\" /></li>';\r\n })\r\n _.dom.innerHTML = `<div class=\"comment init\" id=\"idisqus\">\r\n <div class=\"comment-reaction\">\r\n <div class=\"comment-reaction-header\">\r\n <div class=\"comment-reaction-prompt\"></div>\r\n <div class=\"comment-reaction-total\"></div>\r\n </div>\r\n <div class=\"comment-reaction-list\"></div>\r\n </div>\r\n <div class=\"init-container\" data-tips=\"正在初始化……\"><svg class=\"init-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>\r\n <div class=\"comment-header\">\r\n <div class=\"comment-header-primary\">\r\n <span class=\"comment-header-item\" id=\"comment-count\">评论</span>\r\n <a class=\"comment-header-item\" id=\"comment-link\" target=\"_blank\">在线讨论</a>\r\n </div>\r\n <div class=\"comment-header-menu\">\r\n <input class=\"comment-header-checkbox\" type=\"checkbox\" id=\"comment-user\">\r\n <label class=\"comment-header-item comment-login\" title=\"使用 Disqus 帐号授权登录\" for=\"comment-user\">登录</label>\r\n </div>\r\n </div>\r\n <div class=\"comment-navbar\">\r\n <div class=\"comment-navbar-item\">\r\n <a class=\"comment-recommend\" href=\"javascript:;\"><svg t=\"1537508059126\" class=\"icon\" style=\"\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"3234\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24\" height=\"24\"><path d=\"M489.993 887.107 177.906 586.021c-4.002-3.501-114.033-104.031-114.033-224.063 0-146.54 89.526-234.065 239.069-234.065 87.523 0 169.546 69.019 209.058 108.03 39.512-39.011 121.535-108.03 209.059-108.03 149.542 0 239.068 87.525 239.068 234.065 0 120.033-110.031 220.563-114.533 225.065L534.007 887.107c-6 6-14.003 9-22.007 9C503.997 896.107 495.993 893.107 489.993 887.107z\" p-id=\"3235\"></path></svg><span class=\"comment-recommend-text\">推荐</span><span class=\"comment-recommend-count\"></span></a>\r\n </div>\r\n <div class=\"comment-navbar-item comment-order\">\r\n <input class=\"comment-order-radio\" id=\"order-popular\" type=\"radio\" name=\"comment-order\" value=\"popular\" />\r\n <label class=\"comment-order-label\" for=\"order-popular\" title=\"按评分高低排序\">最佳</label>\r\n <input class=\"comment-order-radio\" id=\"order-desc\" type=\"radio\" name=\"comment-order\" value=\"desc\" />\r\n <label class=\"comment-order-label\" for=\"order-desc\" title=\"按从新到旧排序\">最新</label>\r\n <input class=\"comment-order-radio\" id=\"order-asc\" type=\"radio\" name=\"comment-order\" value=\"asc\" />\r\n <label class=\"comment-order-label\" for=\"order-asc\" title=\"按从旧到新排序\">最早</label>\r\n </div>\r\n </div>\r\n <div class=\"comment-box\">\r\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>\r\n <div class=\"comment-form\">\r\n <div class=\"comment-form-wrapper\">\r\n <textarea class=\"comment-form-textarea\" placeholder=\"加入讨论……\"></textarea>\r\n <div class=\"comment-form-alert\"></div>\r\n <div class=\"comment-image\">\r\n <ul class=\"comment-image-list\"></ul>\r\n <div class=\"comment-image-progress\"><div class=\"comment-image-loaded\"></div></div>\r\n </div>\r\n \r\n <div class=\"comment-actions\">\r\n \r\n <div class=\"comment-actions-group\">\r\n <input id=\"emoji-input\" class=\"comment-actions-input\" type=\"checkbox\">\r\n <label class=\"comment-actions-label emojione\" for=\"emoji-input\">\r\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\">\r\n <g>\r\n <title>选择表情</title>\r\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>\r\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>\r\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>\r\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>\r\n </g>\r\n </svg>\r\n <ul class=\"emojione-list\">${ emojiList}</ul>\r\n </label>\r\n <input id=\"upload-input\" class=\"comment-actions-input comment-image-input\" type=\"file\" accept=\"image/*\" name=\"file\">\r\n <label class=\"comment-actions-label\" for=\"upload-input\">\r\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\">\r\n <g>\r\n <title>上传图片</title>\r\n <path d=\"M15.515152 15.515152 15.515152 15.515152 15.515152 15.515152Z\"></path>\r\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>\r\n </g>\r\n </svg>\r\n </label>\r\n </div>\r\n \r\n <div class=\"comment-actions-form\">\r\n <button class=\"comment-form-submit\">\r\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\">\r\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>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"comment-form-user\">\r\n <form 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\" /></form>\r\n </div>\r\n </div>\r\n </div>\r\n <ul id=\"comments\" class=\"comment-list\" data-tips=\"评论加载中……\"></ul>\r\n <a href=\"javascript:;\" class=\"comment-loadmore hide\">加载更多</a>\r\n <div class=\"comment-related\"></div>\r\n </div>\r\n <div class=\"comment\" id=\"disqus_thread\"></div>`;\r\n\r\n _.user = new User(_.dom, _.opts);\r\n _.handle = {\r\n logout: _.user.logout.bind(_),\r\n login: _.user.login.bind(_),\r\n loadMore: _.loadMore.bind(_),\r\n loadMoreReply: _.loadMoreReply.bind(_),\r\n post: _.post.bind(_),\r\n threadCreate: _.threadCreate.bind(_),\r\n threadVote: _.threadVote.bind(_),\r\n reactionVote: _.reactionVote.bind(_),\r\n remove: _.remove.bind(_),\r\n show: _.show.bind(_),\r\n toggle: _.toggle.bind(_),\r\n upload: _.upload.bind(_),\r\n verify: _.verify.bind(_),\r\n jump: _.jump.bind(_),\r\n mention: _.mention.bind(_),\r\n keySelect: _.keySelect.bind(_),\r\n field: _.field.bind(_),\r\n focus: _.focus,\r\n input: _.input.bind(_),\r\n parentShow: _.parentShow.bind(_),\r\n selectOrder: _.selectOrder.bind(_)\r\n };\r\n\r\n var $iDisqus = _.dom.querySelector('#idisqus');\r\n $iDisqus.on('blur', '.comment-form-textarea', _.handle.focus);\r\n $iDisqus.on('focus', '.comment-form-textarea', _.handle.focus);\r\n $iDisqus.on('input', '.comment-form-textarea', _.handle.input);\r\n $iDisqus.on('propertychange', '.comment-form-textarea', _.handle.input);\r\n $iDisqus.on('keyup', '.comment-form-textarea', _.handle.mention);\r\n $iDisqus.on('keydown', '.comment-form-textarea', _.handle.keySelect);\r\n $iDisqus.on('blur', '.comment-form-name', _.handle.verify);\r\n $iDisqus.on('blur', '.comment-form-email', _.handle.verify);\r\n $iDisqus.on('click', '.comment-form-submit', _.handle.post);\r\n $iDisqus.on('click', '.comment-login', _.handle.login);\r\n $iDisqus.on('change', '.comment-image-input', _.handle.upload);\r\n $iDisqus.on('click', '.emojione-item', _.handle.field);\r\n $iDisqus.on('click', '.comment-logout', _.handle.logout);\r\n $iDisqus.on('click', '.comment-item-reply', _.handle.show);\r\n $iDisqus.on('click', '.comment-item-cancel', _.handle.show);\r\n $iDisqus.on('click', '.comment-item-avatar', _.handle.jump);\r\n $iDisqus.on('click', '.comment-item-pname', _.handle.jump);\r\n $iDisqus.on('mouseover', '.comment-item-pname', _.handle.parentShow);\r\n $iDisqus.on('click', '.comment-loadmore', _.handle.loadMore);\r\n $iDisqus.on('click', '.comment-item-loadmore', _.handle.loadMoreReply);\r\n $iDisqus.on('click', '#thread-submit', _.handle.threadCreate);\r\n $iDisqus.on('click', '.comment-recommend', _.handle.threadVote);\r\n $iDisqus.on('click', '.comment-reaction-btn:not(.selected)', _.handle.reactionVote);\r\n $iDisqus.on('change', '.comment-order-radio', _.handle.selectOrder);\r\n\r\n switch (_.opts.mode) {\r\n case 1:\r\n _.disqus();\r\n break;\r\n case 2:\r\n _.threadInit();\r\n break;\r\n case 3:\r\n _.threadInit();\r\n _.disqus();\r\n break;\r\n default:\r\n _.disqus();\r\n break;\r\n }\r\n }\r\n\r\n // 切换评论框\r\n iDisqus.prototype.toggle = function () {\r\n var _ = this;\r\n if (_.stat.current == 'disqus') {\r\n _.stat.current = 'idisqus';\r\n _.dom.querySelector('#idisqus').style.display = 'block';\r\n _.dom.querySelector('#disqus_thread').style.display = 'none';\r\n } else {\r\n _.disqus();\r\n }\r\n }\r\n\r\n // 加载 Disqus 评论\r\n iDisqus.prototype.disqus = function () {\r\n var _ = this;\r\n var _tips = _.dom.querySelector('.init-container').dataset.tips;\r\n if (_.opts.site != location.origin) {\r\n console.log('本地环境不加载 Disqus 评论框!'+_.opts.site+location.origin);\r\n if (_.opts.mode == 1) {\r\n _.threadInit();\r\n }\r\n \r\n }\r\n if (!_.stat.disqusLoaded) {\r\n _tips = '尝试连接 Disqus……';\r\n\r\n var s = d.createElement('script');\r\n s.src = '//' + _.opts.forum + '.disqus.com/embed.js';\r\n s.dataset.timestamp = Date.now();\r\n s.onload = function () {\r\n _.stat.disqusLoaded = true;\r\n _tips = '连接成功,加载 Disqus 评论框……'\r\n }\r\n s.onerror = function () {\r\n if (_.opts.mode == 1) {\r\n _tips = '连接失败,加载简易评论框……';\r\n _.threadInit();\r\n }\r\n }\r\n\r\n\r\n var img = new Image();\r\n img.onerror = function () {\r\n if (_.opts.mode == 1) {\r\n _tips = '连接超时,加载简易评论框……';\r\n _.threadInit();\r\n }\r\n }\r\n img.onload = function () {\r\n (d.head || d.body).appendChild(s);\r\n clearTimeout(timer)\r\n };\r\n img.src = 'https://disqus.com/favicon.ico?' + Date.now();\r\n var timer = setTimeout(function () {\r\n if ( !img.complete || !img.naturalWidth ) {\r\n if (_.opts.mode == 1) {\r\n _tips = '连接失败,加载简易评论框……';\r\n _.threadInit();\r\n }\r\n }\r\n }, _.opts.timeout);\r\n } else {\r\n _.stat.current = 'disqus';\r\n _.dom.querySelector('#idisqus').style.display = 'none';\r\n _.dom.querySelector('#disqus_thread').style.display = 'block';\r\n }\r\n }\r\n\r\n // 添加事件监听\r\n iDisqus.prototype.addListener = function (els, evt, func) {\r\n var _ = this;\r\n var el = _.dom.getElementsByClassName(els);\r\n [].forEach.call(el, function (item) {\r\n item.addEventListener(evt, func, false);\r\n });\r\n }\r\n\r\n // 评论计数\r\n iDisqus.prototype.count = function () {\r\n var _ = this;\r\n var counts = d.querySelectorAll('[data-disqus-url]');\r\n var qty = counts.length;\r\n if (qty > 0) {\r\n var commentArr = [];\r\n for (var i = 0; i < qty; i++) {\r\n commentArr[i] = counts[i].dataset.disqusUrl.replace(_.opts.site, '');\r\n }\r\n getAjax(\r\n _.opts.api + '/threadsList.php?links=' + commentArr.join(','),\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n var posts = data.response;\r\n posts.forEach(function (item) {\r\n var link = document.createElement('a');\r\n link.href = item.link;\r\n var itemLink = link.href.replace(link.origin, '');\r\n var el = d.querySelector('[data-disqus-url$=\"' + itemLink + '\"]')\r\n if (!!el) {\r\n el.innerHTML = item.posts;\r\n el.dataset.disqusCount = item.posts;\r\n }\r\n });\r\n }, function () {\r\n console.log('获取数据失败!')\r\n }\r\n );\r\n }\r\n };\r\n\r\n // 加载最近评论\r\n iDisqus.prototype.postsList = function (listLimit, containerId) {\r\n var _ = this;\r\n listLimit = listLimit || 5;\r\n var listContainer = d.getElementById(typeof (containerId) == 'string' ? containerId : 'disqusPostsList');\r\n if (listContainer) {\r\n getAjax(\r\n _.opts.api + '/postsList.php?limit=' + listLimit,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n var posts = data.response;\r\n var popHtml = '';\r\n posts.forEach(function (item) {\r\n popHtml += `<li style=\"list-style-type: none;\">${item.name}: ${item.raw_message}</br>评: <a href=\"${item.thread.link}\">${item.thread.title}</a></li>`;\r\n });\r\n popHtml = `<ul>${popHtml}</ul`;\r\n listContainer.innerHTML = popHtml;\r\n }, function () {\r\n console.log('获取数据失败!')\r\n }\r\n );\r\n }\r\n };\r\n\r\n // 加载相关话题\r\n iDisqus.prototype.loadRelated = function () {\r\n var _ = this;\r\n if (_.stat.forum.settings.organicDiscoveryEnabled == false || _.stat.relatedLoaded) {\r\n return;\r\n }\r\n getAjax(\r\n _.opts.api + '/threadsList.php?type=' + _.opts.relatedType.toLowerCase() + '&thread=' + _.stat.thread.id,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n _.stat.relatedLoaded = true;\r\n var threads = data.response;\r\n var popHtml = '';\r\n threads.forEach(function (item) {\r\n var message = item.topPost.message.replace(/<[^>]*>/g, '');\r\n popHtml += `<li class=\"related-item\">\r\n <a class=\"related-item-link\" href=\"${item.link}\" title=\"${item.title}\">\r\n <div class=\"related-item-title\">${item.title}</div>\r\n <div class=\"related-item-desc\">${item.posts}条评论<span class=\"related-item-bullet\"> • </span><time class=\"related-item-time\" datetime=\"${item.createdAt}\"></time></div></a>\r\n <a class=\"related-item-link\" href=\"${item.link}?#comment-${item.topPost.id}\" title=\"${message}\">\r\n <div class=\"related-item-post\">\r\n <div class=\"related-item-avatar\"><img src=\"${item.topPost.avatar}\" /></div>\r\n <div class=\"related-item-main\">\r\n <div class=\"related-item-name\">${ item.topPost.name}</div>\r\n <div class=\"related-item-message\">${ message}</div>\r\n </div>\r\n </div></a>\r\n </li>`;\r\n });\r\n popHtml = `<div class=\"comment-related-title\">在<span class=\"comment-related-forumname\">${_.stat.forum.name}</span>上还有</div><div class=\"comment-related-content\"><ul class=\"related-list\">${popHtml}</ul></div>`;\r\n _.dom.querySelector('.comment-related').innerHTML = popHtml;\r\n _.timeAgo();\r\n }\r\n }, function () {\r\n console.log('获取数据失败!')\r\n }\r\n );\r\n };\r\n\r\n // 加载反应\r\n iDisqus.prototype.loadReactions = function () {\r\n var _ = this;\r\n if (_.stat.forum.settings.threadReactionsEnabled == false) {\r\n return;\r\n }\r\n getAjax(_.opts.api + '/threadReactionsLoadReations.php' + '?thread=' + _.stat.thread.id, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.response.eligible) {\r\n _.dom.querySelector('.comment-reaction-prompt').innerHTML = data.response.prompt;\r\n var reactions = data.response.reactions;\r\n var total = 0;\r\n var reaListHtml = '';\r\n var selectedId = _.user.reactionVote[_.stat.thread.id];\r\n selectedId = selectedId || (!!data.selected ? data.selected.id : 0);\r\n reactions.forEach(function (item) {\r\n total += item.votes;\r\n reaListHtml += `<li class=\"comment-reaction-item\"><a class=\"comment-reaction-btn${(selectedId == item.id ? ' selected' : '')}\" data-id=\"${item.id}\" href=\"javascript:;\"><img class=\"comment-reaction-image\" src=\"${item.imageUrl}\"> ${item.text}</a><div class=\"comment-reaction-count\">${item.votes}</div></li>`;\r\n })\r\n _.dom.querySelector('.comment-reaction-list').innerHTML = reaListHtml;\r\n _.dom.querySelector('.comment-reaction-total').innerHTML = total + ' 人次参与';\r\n }\r\n }, function () { })\r\n\r\n };\r\n\r\n // 反应打分事件\r\n iDisqus.prototype.reactionVote = function (e, target) {\r\n var _ = this;\r\n var $reaction = target.closest('.comment-reaction-item');\r\n var $count = $reaction.querySelector('.comment-reaction-count');\r\n var reactionId = target.dataset.id;\r\n var postData = {\r\n thread: _.stat.thread.id,\r\n unique: _.user.unique,\r\n reaction: reactionId\r\n }\r\n postAjax(_.opts.api + '/threadReactionsVote.php', postData, function (resp) {\r\n _.user.reactionVote[_.stat.thread.id] = reactionId;\r\n l.setItem('reaction_vote', JSON.stringify(_.user.reactionVote));\r\n target.classList.add('selected');\r\n $count.innerHTML++\r\n })\r\n }\r\n\r\n // 排序\r\n iDisqus.prototype.selectOrder = function (e, target) {\r\n var _ = this;\r\n var order = target.value;\r\n sessionStorage.setItem('order', order);\r\n _.stat.order = order;\r\n _.dom.querySelector('.comment-list').innerHTML = '';\r\n _.dom.querySelector('.comment-loadmore').classList.add('hide');\r\n _.stat.next = null;\r\n _.getlist();\r\n }\r\n\r\n // 获取评论列表\r\n iDisqus.prototype.getlist = function () {\r\n var _ = this;\r\n _.stat.loading = true;\r\n _.dom.querySelector('#idisqus').classList.add('loading');\r\n _.dom.querySelector('.comment-list').dataset.tips = '评论加载中……';\r\n getAjax(\r\n _.opts.api + '/getcomments.php?thread=' + _.stat.thread.id + (!!_.stat.next ? '&cursor=' + _.stat.next : '') + '&order=' + _.stat.order,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n _.stat.offsetTop = d.documentElement.scrollTop || d.body.scrollTop;\r\n\r\n _.dom.querySelector('#idisqus').classList.remove('loading')\r\n var loadmore = _.dom.querySelector('.comment-loadmore');\r\n var posts = !!data.response ? data.response : [];\r\n _.stat.root = [];\r\n posts.forEach(function (item) {\r\n _.load(item);\r\n if (!item.parent) {\r\n _.stat.root.unshift(item.id);\r\n }\r\n });\r\n\r\n if (data.cursor.hasPrev) {\r\n _.stat.root.forEach(function (item) {\r\n _.dom.querySelector('.comment-list').appendChild(_.dom.querySelector('#comment-' + item));\r\n })\r\n }\r\n if (data.cursor.hasNext) {\r\n _.stat.next = data.cursor.next;\r\n loadmore.classList.remove('loading');\r\n loadmore.classList.remove('hide');\r\n } else {\r\n _.stat.next = null;\r\n loadmore.classList.add('hide');\r\n }\r\n\r\n if (_.stat.thread.posts == 0) {\r\n _.dom.querySelector('.comment-list').dataset.tips = '来做第一个留言的人吧!';\r\n return;\r\n }\r\n\r\n if (posts.length == 0) {\r\n return;\r\n }\r\n _.timeAgo();\r\n\r\n var iframe = _.dom.querySelectorAll('.comment-item-body iframe');\r\n [].forEach.call(iframe, function (item) {\r\n item.style.width = item.clientWidth + 'px';\r\n item.style.height = item.clientWidth * 9 / 16 + 'px';\r\n setTimeout(function () {\r\n item.src = item.src;\r\n }, 1000)\r\n })\r\n var tweet = _.dom.querySelectorAll('.comment-item-body .twitter-tweet');\r\n if (tweet.length > 0) {\r\n var head = document.getElementsByTagName('head')[0];\r\n var script = document.createElement('script');\r\n script.type = 'text/javascript';\r\n script.src = '//platform.twitter.com/widgets.js';\r\n head.appendChild(script);\r\n }\r\n\r\n window.scrollTo(0, _.stat.offsetTop);\r\n\r\n if (/^#disqus|^#comment-/.test(location.hash) && !data.cursor.hasPrev && !_.stat.disqusLoaded && !_.stat.loaded) {\r\n var el = _.dom.querySelector('#idisqus ' + location.hash)\r\n if (!!el) {\r\n window.scrollBy(0, el.getBoundingClientRect().top);\r\n }\r\n }\r\n _.stat.loading = false;\r\n _.stat.loaded = true;\r\n }\r\n }, function () {\r\n alert('获取数据失败,请检查服务器设置。')\r\n }\r\n );\r\n }\r\n\r\n // 读取评论\r\n iDisqus.prototype.load = function (post) {\r\n\r\n var _ = this;\r\n\r\n _.stat.post[post.id] = post;\r\n\r\n var parentPostDom = _.dom.querySelector('.comment-item[data-id=\"' + post.parent + '\"]');\r\n\r\n var user = {\r\n username: post.username,\r\n name: post.name,\r\n avatar: post.avatar\r\n }\r\n if (!!post.username && _.stat.users.map(function (user) { return user.username; }).indexOf(post.username) == -1) {\r\n _.stat.users.push(user);\r\n }\r\n\r\n var parentPost = !!post.parent ? {\r\n name: `<a class=\"comment-item-pname\" data-parent=\"${post.parent}\" 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>`,\r\n dom: parentPostDom.querySelector('.comment-item-children'),\r\n insert: 'afterbegin'\r\n } : {\r\n name: '',\r\n dom: _.dom.querySelector('.comment-list'),\r\n insert: post.id == 'preview' || !!post.isPost ? 'afterbegin' : 'beforeend'\r\n };\r\n\r\n\r\n var html = `<li class=\"comment-item\" data-id=\"${post.id}\" data-name=\"${post.name}\" id=\"comment-${post.id}\">\r\n <div class=\"comment-item-body\">\r\n <a class=\"comment-item-avatar\" href=\"#comment-${ post.id}\"><img src=\"${post.avatar}\"></a>\r\n <div class=\"comment-item-main\">\r\n <div class=\"comment-item-header\"><a class=\"comment-item-name\" title=\"${ post.name}\" rel=\"nofollow\" target=\"_blank\" href=\"${(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>\r\n <div class=\"comment-item-content\">${ post.message}</div>\r\n <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>\r\n </div></div>\r\n <ul class=\"comment-item-children\">\r\n ${ post.hasMore ? `<li><a class=\"comment-item-loadmore\" href=\"javascript:;\">显示更多回复</a></li>` : `` }\r\n </ul>\r\n </li>`;\r\n\r\n // 已删除评论\r\n if (!!post.isDeleted) {\r\n html = `<li class=\"comment-item\" data-id=\"${post.id}\" id=\"comment-${post.id}\" data-name=\"${post.name}\">\r\n <div class=\"comment-item-body\">\r\n <a class=\"comment-item-avatar\" href=\"#comment-${ post.id}\"><img src=\"${post.avatar}\"></a>\r\n <div class=\"comment-item-main\" data-message=\"此评论已被删除。\"></div></div>\r\n <ul class=\"comment-item-children\">\r\n ${ post.hasMore ? `<li><a class=\"comment-item-loadmore\" href=\"javascript:;\">显示更多回复</a></li>` : `` }\r\n </ul>\r\n </li>`;\r\n }\r\n\r\n\r\n // 更新 or 创建\r\n if (!!_.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"]')) {\r\n _.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"]').outerHTML = html;\r\n } else {\r\n parentPost.dom.insertAdjacentHTML(parentPost.insert, html);\r\n }\r\n\r\n // 发布留言,可编辑删除\r\n if (!!post.isPost && !_.stat.editing) {\r\n var $this = _.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"]');\r\n\r\n var postEdit = setTimeout(function () {\r\n // 十分钟后\r\n if (!!$this.querySelector('.comment-item-manage')) {\r\n $this.querySelector('.comment-item-manage').outerHTML = '';\r\n }\r\n }, 6 * 1e5);\r\n\r\n // 删除\r\n $this.querySelector('.comment-item-delete').addEventListener('click', function (e) {\r\n var postData = {\r\n id: post.id\r\n }\r\n var delDom = e.currentTarget;\r\n delDom.innerHTML = '删除中';\r\n postAjax(_.opts.api + '/removecomment.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n if (data.response.isDeleted == true) {\r\n $this.outerHTML = '';\r\n _.stat.thread.posts = parseInt(_.dom.querySelector('#comment-count').innerHTML) - 1;\r\n _.dom.querySelector('#comment-count').innerHTML = _.stat.thread.posts + ' 条评论';\r\n } else {\r\n alert(data.response.message);\r\n $this.querySelector('.comment-item-manage').outerHTML = '';\r\n }\r\n } else if (data.code === 2) {\r\n alert(data.response);\r\n $this.querySelector('.comment-item-manage').outerHTML = '';\r\n }\r\n }, function () {\r\n alert('删除出错,请稍后重试');\r\n })\r\n clearTimeout(postEdit);\r\n }, false)\r\n\r\n // 编辑\r\n $this.querySelector('.comment-item-edit').addEventListener('click', function () {\r\n _.stat.editing = post;\r\n _.edit(post);\r\n }, false)\r\n }\r\n }\r\n\r\n // 读取更多\r\n iDisqus.prototype.loadMore = function (e, target) {\r\n var _ = this;\r\n _.stat.offsetTop = d.documentElement.scrollTop || d.body.scrollTop;\r\n if (!_.stat.loading) {\r\n target.classList.add('loading');\r\n _.getlist();\r\n }\r\n }\r\n\r\n // 读取更多回复\r\n iDisqus.prototype.loadMoreReply = function (e, target) {\r\n var _ = this;\r\n target.innerHTML = '加载中……';\r\n var $children = target.closest('.comment-item-children');\r\n var $post = target.closest('.comment-item');\r\n getAjax(\r\n _.opts.api + '/descendants.php?post=' + $post.dataset.id,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if( data.code == 0 ){\r\n $children.removeChild(target.parentNode);\r\n var posts = data.response;\r\n posts.forEach(function (item) {\r\n _.load(item);\r\n });\r\n _.timeAgo();\r\n } else {\r\n target.innerHTML = '读取失败';\r\n }\r\n }, function () {\r\n target.innerHTML = '读取出错';\r\n }\r\n );\r\n }\r\n\r\n // 评论框焦点\r\n iDisqus.prototype.focus = function (e, target) {\r\n var wrapper = target.closest('.comment-form-wrapper');\r\n wrapper.classList.add('editing');\r\n if (wrapper.classList.contains('focus')) {\r\n wrapper.classList.remove('focus');\r\n } else {\r\n wrapper.classList.add('focus');\r\n }\r\n }\r\n\r\n // 输入事件\r\n iDisqus.prototype.input = function (e, target) {\r\n var _ = this;\r\n var form = target.closest('.comment-form');\r\n var alertmsg = form.querySelector('.comment-form-alert');\r\n alertmsg.innerHTML = '';\r\n var wrapper = form.querySelector('.comment-form-wrapper');\r\n var filterText = target.value.replace(/<code>.*?<\\/code>/g, '');\r\n var urls = filterText.match(/(^|\\s|\\r|\\n)*(http:\\/\\/|https:\\/\\/)(\\w|-|\\.)*(disqus|sinaimg|giphy|imgur|instagram|twimg|twitter|youtube|youtu\\.be)((\\w|=|\\?|\\.|\\/|&|\\%|-)*)(jpg|png|gif|gallery\\/\\w+|p\\/[a-zA-Z0-9]{11}.*|status\\/\\d{19}|v=[a-zA-Z0-9]{11}|\\/[a-zA-Z0-9]{11})(\\s|$|\\n)/g);\r\n form.querySelector('.comment-image-list').innerHTML = '';\r\n if (!!urls) {\r\n urls.forEach(function (item, i) {\r\n item = item.replace('/\\n|\\r\\n|^\\s|\\s$/g', '');\r\n var image = _.stat.media[item];\r\n if (!!image) {\r\n var imageHtml = `<li class=\"comment-image-item\" data-image-url=\"${image.thumbnailUrl}\"><img class=\"comment-image-object\" src=\"https:${image.thumbnailUrl}\"></li>`;\r\n form.querySelector('.comment-image-list').insertAdjacentHTML('beforeend', imageHtml);\r\n wrapper.classList.add('expanded');\r\n return;\r\n }\r\n postAjax(_.opts.api + '/media.php', { url: item }, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n image = data.response;\r\n var imageHtml = `<li class=\"comment-image-item\" data-image-url=\"${image.thumbnailUrl}\"><img class=\"comment-image-object\" src=\"https:${image.thumbnailUrl}\"></li>`;\r\n form.querySelector('.comment-image-list').insertAdjacentHTML('beforeend', imageHtml);\r\n _.stat.media[item] = image;\r\n wrapper.classList.add('expanded');\r\n }\r\n }, function () {\r\n })\r\n })\r\n } else {\r\n wrapper.classList.remove('expanded');\r\n }\r\n\r\n }\r\n\r\n // 提醒用户 @ mention \r\n iDisqus.prototype.mention = function (e, target) {\r\n var _ = this;\r\n var textarea = target;\r\n var selStart = textarea.selectionStart;\r\n var mentionIndex = textarea.value.slice(0, selStart).lastIndexOf('@');\r\n var mentionText = textarea.value.slice(mentionIndex, selStart);\r\n var mentionDom = _.dom.querySelector('.mention-user');\r\n var showUsers = _.stat.users.filter(function (user) {\r\n var re = new RegExp(mentionText.slice(1), 'i');\r\n return user.username.search(re) > -1;\r\n });\r\n if (mentionText.search(/^@\\w+$|^@$/) == 0 && showUsers.length > 0) {\r\n if (e.keyCode == 38 || e.keyCode == 40) {\r\n return;\r\n }\r\n var coord = _.getCaretCoord(textarea);\r\n var list = '', html = '';\r\n\r\n showUsers.forEach(function (item, i) {\r\n 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>`;\r\n })\r\n if (!!mentionDom) {\r\n mentionDom.innerHTML = '<ul class=\"mention-user-list\">' + list + '</ul>';\r\n mentionDom.style.left = coord.left + 'px';\r\n mentionDom.style.top = coord.top + 'px';\r\n } else {\r\n html = `<div class=\"mention-user\" style=\"left:${coord.left}px;top:${coord.top}px\"><ul class=\"mention-user-list\">${list}</ul></div>`;\r\n _.dom.querySelector('#idisqus').insertAdjacentHTML('beforeend', html);\r\n }\r\n\r\n // 鼠标悬浮\r\n _.addListener('mention-user-item', 'mouseover', function () {\r\n _.dom.querySelector('.mention-user-item.active').classList.remove('active');\r\n this.classList.add('active');\r\n })\r\n\r\n // 鼠标点击\r\n _.addListener('mention-user-item', 'click', function () {\r\n var username = '@' + this.dataset.username + ' ';\r\n textarea.value = textarea.value.slice(0, mentionIndex) + username + textarea.value.slice(selStart);\r\n mentionDom.outerHTML = '';\r\n textarea.focus();\r\n textarea.setSelectionRange(mentionIndex + username.length, mentionIndex + username.length)\r\n })\r\n } else if (!!mentionDom) {\r\n mentionDom.outerHTML = '';\r\n }\r\n }\r\n\r\n // 获取光标坐标 https://medium.com/@_jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a\r\n iDisqus.prototype.getCaretCoord = function (textarea) {\r\n var _ = this;\r\n var carPos = textarea.selectionEnd,\r\n div = d.createElement('div'),\r\n span = d.createElement('span'),\r\n copyStyle = getComputedStyle(textarea);\r\n [].forEach.call(copyStyle, function (prop) {\r\n div.style[prop] = copyStyle[prop];\r\n });\r\n div.style.position = 'absolute';\r\n _.dom.appendChild(div);\r\n div.textContent = textarea.value.substr(0, carPos);\r\n span.textContent = textarea.value.substr(carPos) || '.';\r\n div.appendChild(span);\r\n var coords = {\r\n 'top': textarea.offsetTop - textarea.scrollTop + span.offsetTop + parseFloat(copyStyle.lineHeight),\r\n 'left': textarea.offsetLeft - textarea.scrollLeft + span.offsetLeft\r\n };\r\n _.dom.removeChild(div);\r\n return coords;\r\n }\r\n\r\n // 键盘选择用户\r\n iDisqus.prototype.keySelect = function (e, target) {\r\n var _ = this;\r\n var textarea = target;\r\n var selStart = textarea.selectionStart;\r\n var mentionIndex = textarea.value.slice(0, selStart).lastIndexOf('@');\r\n var mentionText = textarea.value.slice(mentionIndex, selStart);\r\n var mentionDom = _.dom.querySelector('.mention-user');\r\n if (!mentionDom) {\r\n return;\r\n }\r\n var current = _.dom.querySelector('.mention-user-item.active')\r\n switch (e.keyCode) {\r\n case 13:\r\n //回车\r\n var username = '@' + current.dataset.username + ' ';\r\n textarea.value = textarea.value.slice(0, mentionIndex) + username + textarea.value.slice(selStart);\r\n textarea.setSelectionRange(mentionIndex + username.length, mentionIndex + username.length)\r\n _.dom.querySelector('.mention-user').outerHTML = '';\r\n e.preventDefault();\r\n break;\r\n case 38:\r\n //上\r\n if (!!current.previousSibling) {\r\n current.previousSibling.classList.add('active');\r\n current.classList.remove('active');\r\n }\r\n e.preventDefault();\r\n break;\r\n case 40:\r\n //下\r\n if (!!current.nextSibling) {\r\n current.nextSibling.classList.add('active');\r\n current.classList.remove('active');\r\n }\r\n e.preventDefault();\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n // 跳到评论\r\n iDisqus.prototype.jump = function (e, target) {\r\n var _ = this;\r\n var hash = getLocation(target.href).hash;\r\n var el = _.dom.querySelector('#idisqus ' + hash);\r\n history.replaceState(undefined, undefined, hash);\r\n window.scrollBy(0, el.getBoundingClientRect().top);\r\n e.preventDefault();\r\n }\r\n\r\n // 显示父评论\r\n iDisqus.prototype.parentShow = function (e, target) {\r\n var _ = this;\r\n if (!!target.querySelector('.comment-item-parent')) {\r\n return;\r\n }\r\n var comment = _.stat.post[target.dataset.parent];\r\n if (comment.isDeleted) {\r\n return;\r\n }\r\n var message = comment.message.replace(/<[^>]*>/g, '');\r\n var parentHtml = `<div class=\"comment-item-parent\"><a class=\"comment-item-avatar\" href=\"javascript:;\"><img src=\"${comment.avatar}\"></a><div class=\"comment-item-pmain\"><div class=\"comment-item-pheader\">${comment.name}</div><div class=\"comment-item-pcontent\" title=\"${message}\">${message}</div></div></div>`;\r\n target.insertAdjacentHTML('beforeend', parentHtml);\r\n }\r\n\r\n // 点选表情\r\n iDisqus.prototype.field = function (e, target) {\r\n var _ = this;\r\n var item = target;\r\n var form = item.closest('.comment-form');\r\n var textarea = form.querySelector('.comment-form-textarea');\r\n _.appendText(textarea, item.dataset.code);\r\n }\r\n\r\n // 显示回复框 or 取消回复框\r\n iDisqus.prototype.show = function (e, target) {\r\n var _ = this;\r\n\r\n var $this = target;\r\n var item = $this.closest('.comment-item');\r\n\r\n // 无论取消还是回复,移除已显示回复框\r\n var box = _.dom.querySelector('.comment-item .comment-box:not([data-current-id])');\r\n if (box) {\r\n var $show = box.closest('.comment-item');\r\n var cancel = $show.querySelector('.comment-item-cancel')\r\n cancel.outerHTML = cancel.outerHTML.replace('cancel', 'reply');\r\n box.outerHTML = '';\r\n }\r\n\r\n // 回复时,显示评论框\r\n if ($this.className == 'comment-item-reply') {\r\n $this.outerHTML = $this.outerHTML.replace('reply', 'cancel');\r\n var commentBox = _.box.replace(/emoji-input/g, 'emoji-input-' + item.dataset.id).replace(/upload-input/g, 'upload-input-' + item.dataset.id);\r\n item.querySelector('.comment-item-children').insertAdjacentHTML('beforebegin', commentBox);\r\n _.user.init();\r\n\r\n item.querySelector('.comment-form-textarea').focus();\r\n }\r\n\r\n }\r\n\r\n // 验证表单\r\n iDisqus.prototype.verify = function (e, target) {\r\n var _ = this;\r\n var $this = target;\r\n var box = $this.closest('.comment-box');\r\n var $avatar = box.querySelector('.comment-avatar-image');\r\n var $name = box.querySelector('.comment-form-name');\r\n var $email = box.querySelector('.comment-form-email');\r\n var alertmsg = box.querySelector('.comment-form-alert');\r\n if ($email.value == '') {\r\n return;\r\n }\r\n getAjax(\r\n _.opts.api + '/getgravatar.php?email=' + $email.value + '&name=' + $name.value,\r\n function (resp) {\r\n var data = JSON.parse(resp);\r\n if (!data.isEmail && $this == $email) {\r\n _.errorTips('您所填写的邮箱地址有误。', $email);\r\n }\r\n if ($name.value != '') {\r\n $avatar.src = data.gravatar;\r\n }\r\n }, function () {\r\n }\r\n );\r\n }\r\n\r\n // 添加文本\r\n iDisqus.prototype.appendText = function (textarea, text) {\r\n var _ = this;\r\n var selStart = textarea.selectionStart;\r\n var text = selStart == 0 ? text + ' ' : ' ' + text + ' ';\r\n textarea.value = textarea.value.slice(0, selStart) + text + textarea.value.slice(selStart);\r\n textarea.focus();\r\n textarea.setSelectionRange(selStart + text.length, selStart + text.length);\r\n }\r\n\r\n // 上传图片\r\n iDisqus.prototype.upload = function (e, target) {\r\n var _ = this;\r\n var file = target;\r\n var form = file.closest('.comment-form');\r\n var progress = form.querySelector('.comment-image-progress');\r\n var loaded = form.querySelector('.comment-image-loaded');\r\n var wrapper = form.querySelector('.comment-form-wrapper');\r\n var alertmsg = form.querySelector('.comment-form-alert');\r\n alertmsg.innerHTML = '';\r\n if (file.files.length === 0) {\r\n return;\r\n }\r\n\r\n // 以文件大小识别是否为同张图片\r\n var size = file.files[0].size;\r\n\r\n if (size > 5 * 1e6) {\r\n alertmsg.innerHTML = '请选择 5M 以下图片。';\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n return;\r\n }\r\n\r\n if (_.stat.imageSize.indexOf(size) == -1) {\r\n progress.style.width = '80px';\r\n } else {\r\n alertmsg.innerHTML = '请勿选择已存在的图片。';\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n return;\r\n }\r\n\r\n // 展开图片上传界面\r\n wrapper.classList.add('expanded');\r\n\r\n // 图片上传请求\r\n var data = new FormData();\r\n data.append('file', file.files[0]);\r\n var filename = file.files[0].name;\r\n\r\n var $item;\r\n\r\n var xhrUpload = new XMLHttpRequest();\r\n xhrUpload.withCredentials = true;\r\n xhrUpload.onreadystatechange = function () {\r\n if (xhrUpload.readyState == 4 && xhrUpload.status == 200) {\r\n var data = JSON.parse(xhrUpload.responseText);\r\n if (data.code == 0) {\r\n _.stat.imageSize.push(size);\r\n var imageUrl = data.response.thumbnailUrl;\r\n var textarea = form.querySelector('.comment-form-textarea');\r\n _.appendText(textarea, 'https:'+imageUrl);\r\n\r\n var image = new Image();\r\n image.src = imageUrl;\r\n image.onload = function () {\r\n $item.innerHTML = '<img class=\"comment-image-object\" src=\"https:' + imageUrl + '\">';\r\n $item.dataset.imageUrl = imageUrl;\r\n $item.classList.remove('loading');\r\n }\r\n } else {\r\n alertmsg.innerHTML = '图片上传出错。';\r\n $item.innerHTML = '';\r\n if (!!form.getElementsByClassName('comment-image-item').length) {\r\n wrapper.classList.remove('expanded');\r\n }\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n }\r\n }\r\n };\r\n xhrUpload.upload.addEventListener('progress', function (e) {\r\n loaded.style.width = Math.ceil((e.loaded / e.total) * 100) + '%';\r\n }, false);\r\n xhrUpload.upload.addEventListener('load', function (e) {\r\n loaded.style.width = 0;\r\n progress.style.width = 0;\r\n var imageItem = `<li class=\"comment-image-item loading\" data-image-size=\"${size}\">\r\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\" width=\"24px\" height=\"30px\" viewBox=\"0 0 24 30\" style=\"enable-background: new 0 0 50 50;\" xml:space=\"preserve\">\r\n <rect x=\"0\" y=\"10\" width=\"4\" height=\"10\" fill=\"rgba(127,145,158,1)\" opacity=\"0.2\">\r\n <animate attributeName=\"opacity\" attributeType=\"XML\" values=\"0.2; 1; .2\" begin=\"0s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"height\" attributeType=\"XML\" values=\"10; 20; 10\" begin=\"0s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"y\" attributeType=\"XML\" values=\"10; 5; 10\" begin=\"0s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n </rect>\r\n <rect x=\"8\" y=\"10\" width=\"4\" height=\"10\" fill=\"rgba(127,145,158,1)\" opacity=\"0.2\">\r\n <animate attributeName=\"opacity\" attributeType=\"XML\" values=\"0.2; 1; .2\" begin=\"0.15s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"height\" attributeType=\"XML\" values=\"10; 20; 10\" begin=\"0.15s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"y\" attributeType=\"XML\" values=\"10; 5; 10\" begin=\"0.15s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n </rect>\r\n <rect x=\"16\" y=\"10\" width=\"4\" height=\"10\" fill=\"rgba(127,145,158,1)\" opacity=\"0.2\">\r\n <animate attributeName=\"opacity\" attributeType=\"XML\" values=\"0.2; 1; .2\" begin=\"0.3s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"height\" attributeType=\"XML\" values=\"10; 20; 10\" begin=\"0.3s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n <animate attributeName=\"y\" attributeType=\"XML\" values=\"10; 5; 10\" begin=\"0.3s\" dur=\"0.6s\" repeatCount=\"indefinite\" />\r\n </rect>\r\n </svg>\r\n </li>`;\r\n form.querySelector('.comment-image-list').insertAdjacentHTML('beforeend', imageItem);\r\n $item = form.querySelector('[data-image-size=\"' + size + '\"]');\r\n }, false);\r\n xhrUpload.open('POST', _.opts.api + '/media.php', true);\r\n xhrUpload.send(data);\r\n }\r\n\r\n // 移除图片\r\n iDisqus.prototype.remove = function (e) {\r\n var _ = this;\r\n var $item = e.currentTarget.closest('.comment-image-item');\r\n var wrapper = e.currentTarget.closest('.comment-form-wrapper');\r\n $item.outerHTML = '';\r\n _.stat.imageSize = [];\r\n var imageArr = wrapper.getElementsByClassName('comment-image-item');\r\n [].forEach.call(imageArr, function (item, i) {\r\n _.stat.imageSize[i] = item.dataset.imageSize;\r\n });\r\n if (_.stat.imageSize.length == 0) {\r\n wrapper.classList.remove('expanded');\r\n }\r\n wrapper.querySelector('.comment-image-input').value = '';\r\n }\r\n\r\n // 错误提示\r\n iDisqus.prototype.errorTips = function (Text, Dom) {\r\n var _ = this;\r\n if (_.user.logged_in == 'true') {\r\n _.handle.logout();\r\n }\r\n var idisqus = _.dom.querySelector('#idisqus');\r\n var errorDom = _.dom.querySelector('.comment-form-error');\r\n if (!!errorDom) {\r\n errorDom.outerHTML = '';\r\n }\r\n var Top = Dom.offsetTop;\r\n var Left = Dom.offsetLeft;\r\n var errorHtml = '<div class=\"comment-form-error\" style=\"top:' + Top + 'px;left:' + Left + 'px;\">' + Text + '</div>';\r\n idisqus.insertAdjacentHTML('beforeend', errorHtml);\r\n setTimeout(function () {\r\n var errorDom = _.dom.querySelector('.comment-form-error');\r\n if (!!errorDom) {\r\n errorDom.outerHTML = '';\r\n }\r\n }, 3000);\r\n }\r\n\r\n // 发表/回复评论\r\n iDisqus.prototype.post = function (e, target) {\r\n var _ = this;\r\n var item = target.closest('.comment-box[data-current-id]') || target.closest('.comment-item') || target.closest('.comment-box');\r\n var message = item.querySelector('.comment-form-textarea').value;\r\n var parentId = !!item.dataset.id ? item.dataset.id : '';\r\n var imgArr = item.getElementsByClassName('comment-image-item');\r\n\r\n // 不是编辑框需预览\r\n if (!item.dataset.currentId) {\r\n var elName = item.querySelector('.comment-form-name');\r\n var elEmail = item.querySelector('.comment-form-email');\r\n var elUrl = item.querySelector('.comment-form-url');\r\n var alertmsg = item.querySelector('.comment-form-alert');\r\n var alertClear = function () {\r\n setTimeout(function () {\r\n alertmsg.innerHTML = '';\r\n }, 3000);\r\n }\r\n\r\n if (_.user.type != '1') {\r\n var anonName = elName.value;\r\n var anonEmail = elEmail.value;\r\n var anonUrl = elUrl.value.replace(/\\s/g, '');\r\n if (/^\\s*$/i.test(anonName)) {\r\n _.errorTips('名字不能为空或空格。', elName);\r\n return;\r\n }\r\n if (/^\\s*$/i.test(anonEmail)) {\r\n _.errorTips('邮箱不能为空或空格。', elEmail);\r\n return;\r\n }\r\n if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i.test(anonEmail)) {\r\n _.errorTips('请正确填写邮箱。', elEmail);\r\n return;\r\n }\r\n if (!/^([hH][tT]{2}[pP]:\\/\\/|[hH][tT]{2}[pP][sS]:\\/\\/)(([A-Za-z0-9-~]+)\\.)+([A-Za-z0-9-~\\/])+$|^\\s*$/i.test(anonUrl)) {\r\n _.errorTips('请正确填写网址。', elUrl);\r\n return;\r\n }\r\n _.user.unique = _.user.email == anonEmail ? _.user.unique : generateGUID();\r\n _.user.name = anonName;\r\n _.user.email = anonEmail;\r\n _.user.url = anonUrl;\r\n _.user.avatar = item.querySelector('.comment-avatar-image').src;\r\n _.user.submit();\r\n\r\n if (!_.user.name && !_.user.email) {\r\n return;\r\n }\r\n }\r\n\r\n if (!_.stat.message && !_.stat.mediaHtml) {\r\n _.box = _.dom.querySelector('.comment-box').outerHTML.replace('comment-form-wrapper', 'comment-form-wrapper editing').replace(/加入讨论……/, '');\r\n }\r\n\r\n if (/^\\s*$/i.test(message)) {\r\n alertmsg.innerHTML = '评论不能为空或空格。';\r\n item.querySelector('.comment-form-textarea').focus();\r\n return;\r\n };\r\n\r\n var preMessage = message;\r\n\r\n if (!!_.opts.emoji_preview) {\r\n preMessage = preMessage.replace(/:([-+\\w]+):/g, function (match) {\r\n var emojiShort = match.replace(/:/g, '');\r\n var emojiImage = !!_.eac[emojiShort] ? `<img class=\"emojione\" width=\"24\" height=\"24\" alt=\"'+emojiShort+'\" title=\":${emojiShort}:\" src=\"${_.opts.emojiPath + _.eac[emojiShort]}.png\">` : match;\r\n return emojiImage;\r\n });\r\n } else {\r\n _.emojiList.forEach(function (item) {\r\n preMessage = preMessage.replace(`:${item.code}:`, `<img class=\"emojione\" width=\"24\" height=\"24\" src=\"${_.opts.emojiPath + item.unicode}.png\" />`);\r\n });\r\n }\r\n\r\n var post = {\r\n 'url': !!_.user.url ? _.user.url : '',\r\n 'isMod': false,\r\n 'username': null,\r\n 'name': _.user.name,\r\n 'avatar': _.user.avatar,\r\n 'id': 'preview',\r\n 'parent': parentId,\r\n 'createdAt': (new Date()).toJSON(),\r\n 'message': '<p>' + preMessage + '</p>',\r\n };\r\n\r\n _.load(post);\r\n\r\n _.timeAgo();\r\n\r\n // 清空或移除评论框\r\n _.stat.message = message;\r\n _.stat.mediaHtml = item.querySelector('.comment-image-list').innerHTML;\r\n\r\n if (parentId) {\r\n item.querySelector('.comment-item-cancel').click();\r\n } else {\r\n item.querySelector('.comment-form-textarea').value = '';\r\n item.querySelector('.comment-image-list').innerHTML = '';\r\n item.querySelector('.comment-form-wrapper').classList.remove('expanded', 'editing');\r\n }\r\n }\r\n\r\n // @\r\n var mentions = message.match(/@\\w+/g);\r\n if (!!mentions) {\r\n mentions = mentions.filter(function (mention) {\r\n return _.stat.users.map(function (user) { return user.username; }).indexOf(mention.slice(1)) > -1;\r\n });\r\n if (mentions.length > 0) {\r\n var re = new RegExp('(' + mentions.join('|') + ')', 'g');\r\n message = message.replace(re, '$1:disqus');\r\n }\r\n }\r\n\r\n // POST 操作\r\n // 编辑框则更新评论\r\n if (!!item.dataset.currentId) {\r\n var postData = {\r\n id: item.dataset.currentId,\r\n message: message,\r\n unique: _.user.unique\r\n }\r\n postAjax(_.opts.api + '/updatecomment.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n _.stat.message = null;\r\n _.stat.mediaHtml = null;\r\n var post = data.response;\r\n _.load(post);\r\n _.timeAgo();\r\n _.stat.editing = false;\r\n } else {\r\n // 取消编辑\r\n _.load(_.stat.editing)\r\n _.timeAgo();\r\n _.stat.editing = false;\r\n }\r\n }, function () {\r\n // 取消编辑\r\n _.load(_.stat.editing)\r\n _.timeAgo();\r\n _.stat.editing = false;\r\n })\r\n } else {\r\n var postData = {\r\n thread: _.stat.thread.id,\r\n parent: parentId,\r\n message: message,\r\n name: _.user.name,\r\n email: _.user.email,\r\n url: _.user.url,\r\n unique: _.user.unique\r\n }\r\n postAjax(_.opts.api + '/postcomment.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.stat.thread = data.thread;\r\n _.stat.thread.posts = parseInt(_.dom.querySelector('#comment-count').innerHTML) + 1;\r\n _.dom.querySelector('#comment-count').innerHTML = _.stat.thread.posts + ' 条评论';\r\n var post = data.response;\r\n post.isPost = true;\r\n _.load(post);\r\n _.timeAgo();\r\n var postData = {\r\n post: JSON.stringify(post),\r\n thread: JSON.stringify(_.stat.thread),\r\n parent: JSON.stringify(_.stat.post[parentId]),\r\n code: data.verifyCode\r\n }\r\n if (!!data.verifyCode) {\r\n // 异步发送邮件\r\n postAjax(_.opts.api + '/sendemail.php', postData, function (resp) {\r\n console.info('邮件发送成功!');\r\n })\r\n }\r\n } else if (data.code === 2) {\r\n alertmsg.innerHTML = data.response;\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.reEdit(item);\r\n\r\n if (data.response.indexOf('author') > -1) {\r\n _.handle.logout();\r\n }\r\n } else {\r\n alertmsg.innerHTML = '提交失败,请稍后重试,错误代码:' + data.code;\r\n alertClear();\r\n\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.reEdit(item);\r\n }\r\n\r\n }, function () {\r\n alertmsg.innerHTML = '提交出错,请稍后重试。';\r\n alertClear();\r\n\r\n _.dom.querySelector('.comment-item[data-id=\"preview\"]').outerHTML = '';\r\n _.reEdit(item);\r\n })\r\n }\r\n }\r\n\r\n // 重新编辑\r\n iDisqus.prototype.reEdit = function (item) {\r\n var _ = this;\r\n\r\n if (!!item.dataset.id) {\r\n item.querySelector('.comment-item-reply').click();\r\n } else {\r\n item.querySelector('.comment-form-wrapper').classList.add('editing');\r\n }\r\n\r\n // 重新填充文本图片\r\n if (!!_.stat.message) {\r\n item.querySelector('.comment-form-textarea').value = _.stat.message;\r\n }\r\n if (!!_.stat.mediaHtml) {\r\n item.querySelector('.comment-form-wrapper').classList.add('expanded');\r\n item.querySelector('.comment-image-list').innerHTML = _.stat.mediaHtml;\r\n }\r\n }\r\n\r\n // 编辑\r\n iDisqus.prototype.edit = function (post) {\r\n var _ = this;\r\n 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);\r\n var $this = _.dom.querySelector('.comment-item[data-id=\"' + post.id + '\"] .comment-item-body');\r\n $this.outerHTML = commentBox;\r\n _.user.init();\r\n var item = _.dom.querySelector('.comment-box-' + post.id);\r\n item.dataset.currentId = post.id;\r\n item.querySelector('.comment-form-textarea').focus();\r\n\r\n // 取消编辑\r\n item.querySelector('.comment-actions-form').insertAdjacentHTML('afterbegin', '<a class=\"comment-form-cancel\" href=\"javascript:;\">取消</a>')\r\n item.querySelector('.comment-form-cancel').addEventListener('click', function () {\r\n _.stat.editing = false;\r\n _.load(post);\r\n _.timeAgo();\r\n }, false);\r\n\r\n // 重新填充文本图片,连续回复、连续编辑会有 bug\r\n if (!!_.stat.message) {\r\n item.querySelector('.comment-form-textarea').value = _.stat.message;\r\n }\r\n if (!!_.stat.mediaHtml) {\r\n item.querySelector('.comment-form-wrapper').classList.add('expanded');\r\n item.querySelector('.comment-image-list').innerHTML = _.stat.mediaHtml;\r\n }\r\n\r\n }\r\n\r\n // Thread 初始化\r\n iDisqus.prototype.threadInit = function (e, target) {\r\n var _ = this;\r\n _.dom.querySelector('#idisqus').style.display = 'block';\r\n _.dom.querySelector('#disqus_thread').style.display = 'none';\r\n getAjax(_.opts.api + '/threadsDetails.php?ident=' + _.opts.identifier + '&link=' + _.opts.url, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code == 0) {\r\n _.stat.thread = data.response;\r\n _.stat.forum = data.forum;\r\n _.dom.querySelector('#comment-link').href = `https://disqus.com/home/discussion/${_.stat.forum.id}/${_.stat.thread.slug}/?l=zh`;\r\n _.dom.querySelector('.comment-avatar-image').dataset.avatar = _.stat.forum.avatar;\r\n _.dom.querySelector('.comment-recommend-count').innerHTML = _.stat.thread.likes || '';\r\n if (_.stat.forum.settings.mediaembedEnabled == false) {\r\n _.dom.querySelector('.comment-image-input').outerHTML = ''\r\n _.dom.querySelector('[for=\"upload-input\"]').outerHTML = ''\r\n }\r\n if (_.user.logged_in == 'false') {\r\n _.dom.querySelector('.comment-avatar-image').src = _.stat.forum.avatar;\r\n }\r\n _.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(/加入讨论……/, '');\r\n _.opts.badge = _.stat.forum.moderatorBadgeText;\r\n if (!_.stat.order) {\r\n switch (_.stat.forum.order) {\r\n case 1:\r\n _.stat.order = 'asc';\r\n break;\r\n case 2:\r\n _.stat.order = 'desc';\r\n break;\r\n case 4:\r\n _.stat.order = 'popular';\r\n break;\r\n }\r\n }\r\n _.dom.querySelector('.comment-order-radio[value=\"' + _.stat.order + '\"]').checked = true;\r\n\r\n var users = data.votedusers;\r\n var vote = 0;\r\n if (_.user.type == 1) {\r\n // 已登录\r\n vote = users.filter(function (user) {\r\n return user.username == _.user.username;\r\n }).length > 0 ? 1 : 0;\r\n } else {\r\n // 未登录\r\n vote = !!_.user.vote[_.stat.thread.id] ? 1 : 0;;\r\n }\r\n _.user.vote[_.stat.thread.id] = vote;\r\n l.setItem('vote', JSON.stringify(_.user.vote));\r\n if (!!vote) {\r\n _.dom.querySelector('.comment-recommend').classList.add('voted');\r\n _.dom.querySelector('.comment-recommend-text').innerHTML = '已推荐';\r\n }\r\n _.dom.querySelector('#idisqus').classList.remove('init')\r\n _.loadRelated();\r\n _.loadReactions();\r\n _.dom.querySelector('#comment-count').innerHTML = _.stat.thread.posts + ' 条评论';\r\n _.getlist();\r\n } else if (data.code === 2) {\r\n // 自动创建\r\n if (_.opts.autoCreate) {\r\n _.dom.querySelector('.init-container').dataset.tips = '正在创建 Thread……';\r\n var postData = {\r\n url: _.opts.link,\r\n identifier: _.opts.identifier,\r\n title: _.opts.title,\r\n slug: _.opts.slug,\r\n message: _.opts.desc\r\n }\r\n _.threadCreate(postData);\r\n return;\r\n }\r\n _.dom.querySelector('#idisqus').classList.remove('init');\r\n var threadForm = `<div class=\"comment-header\"><span class=\"comment-header-item\">创建 Thread</span></div>\r\n <div class=\"comment-thread-form\">\r\n <p>由于 Disqus 没有本页面的相关 Thread,故需先创建 Thread</p>\r\n <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>\r\n <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>\r\n <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>\r\n <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>\r\n <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>\r\n <button id=\"thread-submit\" class=\"comment-form-submit\">提交</button></div>`;\r\n _.dom.querySelector('#idisqus').innerHTML = threadForm;\r\n }\r\n }, function () { })\r\n }\r\n\r\n // Thread 打分事件\r\n iDisqus.prototype.threadVote = function (e, target) {\r\n var _ = this;\r\n var vote = !!_.user.vote[_.stat.thread.id] ? 0 : 1;\r\n var postData = {\r\n thread: _.stat.thread.id,\r\n unique: _.user.unique,\r\n vote: vote\r\n }\r\n postAjax(_.opts.api + '/threadsVote.php', postData, function (resp) {\r\n _.user.vote[_.stat.thread.id] = vote;\r\n l.setItem('vote', JSON.stringify(_.user.vote));\r\n if (!!vote) {\r\n _.dom.querySelector('.comment-recommend').classList.add('voted');\r\n _.stat.thread.likes++;\r\n } else {\r\n _.dom.querySelector('.comment-recommend').classList.remove('voted');\r\n _.stat.thread.likes = _.stat.thread.likes == 0 ? 0 : _.stat.thread.likes - 1;\r\n }\r\n _.dom.querySelector('.comment-recommend-count').innerHTML = _.stat.thread.likes || '';\r\n })\r\n }\r\n\r\n // Thread Create 事件\r\n iDisqus.prototype.threadCreate = function (e, target) {\r\n var _ = this;\r\n if (!!target) {\r\n var postData = {\r\n url: _.dom.querySelector('#thread-url').value,\r\n identifier: _.dom.querySelector('#thread-identifier').value,\r\n title: _.dom.querySelector('#thread-title').value,\r\n slug: _.dom.querySelector('#thread-slug').value.replace(/[^A-Za-z0-9_-]+/g, ''),\r\n message: _.dom.querySelector('#thread-message').value\r\n }\r\n } else {\r\n var postData = arguments[0];\r\n }\r\n postAjax(_.opts.api + '/createthread.php', postData, function (resp) {\r\n var data = JSON.parse(resp);\r\n if (data.code === 0) {\r\n alert('创建 Thread 成功,刷新后便可愉快地评论了!');\r\n setTimeout(function () { location.reload(); }, 2000);\r\n } else if (data.code === 2) {\r\n if (data.response.indexOf('A thread already exists with link') > -1) {\r\n alert(data.response.replace('A thread already exists with link,', '已存在此链接的相关 Thread,'));\r\n return;\r\n }\r\n if (data.response.indexOf('Invalid URL') > -1) {\r\n alert('参数错误,无效的\\'URL\\'');\r\n return;\r\n }\r\n if (data.response.indexOf('Invalid slug') > -1) {\r\n alert('参数错误,无效的\\'slug\\'');\r\n return;\r\n }\r\n alert(data.response);\r\n return;\r\n } else {\r\n alert(data.response);\r\n return;\r\n }\r\n }, function () {\r\n alert('创建 Thread 出错,请稍后重试!');\r\n })\r\n }\r\n\r\n // 销毁评论框\r\n iDisqus.prototype.destroy = function () {\r\n var _ = this;\r\n _.dom.innerHTML = '';\r\n delete _.dom;\r\n delete _.box;\r\n delete _.emojiList;\r\n delete _.user;\r\n delete _.handle;\r\n delete _.stat;\r\n delete _.opts;\r\n }\r\n\r\n /* CommonJS */\r\n if ( true && module && typeof exports === 'object' && exports)\r\n module.exports = iDisqus;\r\n /* AMD */\r\n else if (true)\r\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {\r\n return iDisqus;\r\n }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n /* Global */\r\n else\r\n {}\r\n\r\n})(window || this);\r\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://%5Bname%5D/./src/iDisqus.js?");
/***/ }),