/**
* @fileoverview article tool for every theme
*
* @author Liyuan Li
* @version 0.3.0.0, Nov 1, 2018
*/
import $ from 'jquery'
import { Editor } from './lib/b3log/editor/index'
import { LazyLoadCSSImage, LazyLoadImage, ParseMarkdown } from './common'
import config from '../../pipe.json'
/**
* @description 初始化目录
* @param {string} tocId 目录 id
* @param {string} articleId 目录对应正文 id
*/
export const InitToc = (
tocId, articleId, articleOffset = 0, activeClass = 'toc__item--active') => {
const $toc = $(`#${tocId}`)
const $articleTocs = $(`#${articleId} [id^=toc]`)
let tocPositionArray = []
// 目录点击
$toc.find('li').click(function () {
const $it = $(this)
setTimeout(function () {
$toc.find('li').removeClass(activeClass)
$it.addClass(activeClass)
}, 50)
})
$(window).scroll(function (event) {
// 界面各种图片加载会导致帖子目录定位
tocPositionArray = []
$articleTocs.each(function () {
tocPositionArray.push({
id: this.id,
offsetTop: this.offsetTop,
})
})
// 当前目录样式
let scrollTop = $(window).scrollTop()
for (let i = 0, iMax = tocPositionArray.length; i < iMax; i++) {
if (scrollTop < tocPositionArray[i].offsetTop - articleOffset) {
$toc.find('li').removeClass(activeClass)
const index = i > 0 ? i - 1 : 0
$toc.find(`a[href="#${$articleTocs[index].id}"]`).
parent().
addClass(activeClass)
break
}
}
if (scrollTop >= $articleTocs[$articleTocs.length - 1].offsetTop -
articleOffset) {
$toc.find('li').removeClass(activeClass)
$toc.find('li:last').addClass(activeClass)
}
})
$(window).scroll()
}
export const InitHljs = () => {
const $codes = $('pre code')
if ($codes.length === 0) {
return false
}
var parseHljs = function () {
$codes.each(function (i, block) {
var $it = $(this)
if ($it.hasClass('language-flow')) {
return
}
if ($it.parent().find('.pipe-code__copy').length > 0) {
return
}
$it.css({'max-height': $(window).height() - 40}).
parent().
prepend(`
`)
hljs.highlightBlock(block)
})
}
if (typeof hljs === 'undefined') {
$.ajax({
method: 'GET',
url: (config.StaticServer || config.Server) +
'/theme/js/lib/highlight.min.js',
dataType: 'script',
cache: true,
}).done(function () {
parseHljs()
})
} else {
parseHljs()
}
}
/**
* @description 展开编辑器
* @param {String} reply 回复对象的名称
* @param {String} id 文章 id
* @param {String} commentId 回复 id
* @private
*/
export const ShowEditor = (reply, id, commentId) => {
const $editor = $('#pipeEditor')
if ($editor.length === 0) {
location.href = 'https://hacpai.com/login'
return
}
if (commentId) {
$editor.data('commentid', commentId)
} else {
$editor.removeData('commentid')
}
$editor.css({'bottom': '0', 'opacity': 1}).data('id', id)
$('body').css('padding-bottom', $editor.outerHeight() + 'px')
$('#pipeEditorReplyTarget').text(reply)
$('#pipeEditorComment textarea').focus()
}
export const InitComment = () => {
/**
* @description 隐藏编辑器
* @private
*/
const _hideEditor = () => {
const $editor = $('#pipeEditor')
$editor.css({'bottom': `-${$editor.outerHeight()}px`, 'opacity': 0})
$('body').css('padding-bottom', 0)
}
// comment null reply
$('.pipe-comment__null').click(function () {
const $commentNull = $(this)
ShowEditor($commentNull.data('title'), $commentNull.data('id'))
})
// bottom reply
$('#pipeCommentsWrap').on('click', '#pipeCommentBottomComment', function () {
const $bottomComment = $(this)
ShowEditor($bottomComment.data('text'), $bottomComment.data('id'))
})
// comment show reply
$('#pipeCommentsWrap').on('click', '#pipeComments .fn-pointer', function () {
const $it = $(this)
if ($it.hasClass('disabled')) {
return
}
$it.addClass('disabled')
const $svg = $it.find('svg')
if ($svg.hasClass('pipe-comment__chevron-down')) {
$svg.removeClass('pipe-comment__chevron-down')
if ($it.next().find('.pipe-comment__item').length > 0) {
$it.next().slideToggle({
queue: false,
complete: () => {
$it.removeClass('disabled')
},
})
return
}
$.ajax({
url: `${$('#pipeEditorComment').data('blogurl')}/comments/${$it.data(
'id')}/replies`,
type: 'GET',
success: (result) => {
if (result.code === 0) {
let commentHTML = ''
result.data.forEach((item) => {
commentHTML += ``
})
$it.next().html(commentHTML).slideToggle({
queue: false,
complete: () => {
$it.removeClass('disabled')
},
})
LazyLoadImage()
LazyLoadCSSImage()
InitHljs()
ParseMarkdown()
} else {
alert(result.msg)
$it.removeClass('disabled')
}
},
})
} else {
$svg.addClass('pipe-comment__chevron-down')
$it.next().slideToggle({
queue: false,
complete: () => {
$it.removeClass('disabled')
},
})
}
})
// comment remove
$('#pipeCommentsWrap').
on('click', '#pipeComments .pipe-comment__btn--danger', function () {
const $it = $(this)
if (confirm($it.data('label'))) {
$.ajax({
url: `${$('#pipeEditorComment').
data('blogurl')}/comments/${$it.data('id')}`,
type: 'DELETE',
success: (result) => {
if (result.code === 0) {
const $commentsCnt = $('#pipeCommentsCnt')
const $comments = $('#pipeComments')
const $item = $(`#pipeComment${$it.data('id')}`)
if ($('#pipeComments > div > section').length === 1) {
$comments.addClass('pipe-comment__null').html(`
${$it.data('label2')}`).click(function () {
ShowEditor($comments.data('title'), $comments.data('id'))
})
} else {
$item.remove()
$commentsCnt.text(parseInt($commentsCnt.text()) - 1)
}
} else {
alert(result.msg)
}
},
})
}
})
// comment reply
$('#pipeCommentsWrap').
on('click', '#pipeComments .pipe-comment__btn--reply', function () {
const $it = $(this)
ShowEditor($it.data('title'), $it.data('id'), $it.data('commentid'))
})
if ($('#pipeEditorComment').length === 0) {
return
}
// init Editor
const label = $('#pipeEditorComment').data('label').split(',')
const $b3logEditor = Editor({
id: 'pipeEditorComment',
placeholder: $('#pipeEditorComment').data('placeholder'),
tipClass: 'pipe-tooltipped pipe-tooltipped--e',
emojiURL: 'https://www.webpagefx.com/tools/emoji-cheat-sheet/',
label: {
emoji: label[0] + ' ',
bold: label[1] + ' ',
italic: label[2] + ' ',
quote: label[3] + ' ',
link: label[4] + ' ',
upload: label[5],
unorderedList: label[6] + ' ',
orderedList: label[7] + ' ',
view: label[8] + ' ',
question: label[9],
fullscreen: label[10] + ' ',
emojiTip: 'EMOJI CHEAT SHEET',
},
height: 180,
keyup: (event) => {
localStorage.setItem('pipeEditorComment', event.target.value)
},
esc: _hideEditor,
ctrlEnter: () => {
$('#pipeEditorAdd').click()
},
hasView: false,
uploadURL: `${$('#pipeEditorComment').data('blogurl')}/upload`,
fetchUpload: (url, succCB) => {
$.ajax({
url: `${$('#pipeEditorComment').data('blogurl')}/fetch-upload`,
type: 'POST',
data: JSON.stringify({
url,
}),
success: function (result) {
succCB(result.data.originalURL, result.data.url)
},
})
},
previewClass: 'pipe-content__reset',
staticServePath: config.StaticServer || config.Server,
change: (value, $preview) => {
if ($.trim(value) === '' || !$preview) {
$preview && $preview.html('')
return
}
$.ajax({
url: `${config.Server}/api/console/markdown`,
type: 'POST',
data: JSON.stringify({
mdText: value,
}),
success: function (result) {
$preview.html(result.data.html)
LazyLoadImage()
LazyLoadCSSImage()
InitHljs()
ParseMarkdown()
},
})
},
})
$b3logEditor.val(localStorage.getItem('pipeEditorComment'))
// editor cancel
$('#pipeEditorCancel').click(function () {
_hideEditor()
})
// editor add
$('#pipeEditorAdd').click(function () {
const label = $(this).data('label')
const label2 = $(this).data('label2')
const $editor = $('#pipeEditor')
const $editorAdd = $(this)
const $commentContent = $('#pipeEditorComment')
if ($editorAdd.hasClass('disabled')) {
return
}
if ($.trim($b3logEditor.val()).length === 0) {
alert(label2)
return
}
let requestData = {
'articleID': $editor.data('id'),
'content': $b3logEditor.val(),
}
if ($editor.data('commentid')) {
requestData.parentCommentID = $editor.data('commentid')
}
$editorAdd.addClass('pipe-btn--disabled')
$.ajax({
url: `${$commentContent.data('blogurl')}/comments`,
data: JSON.stringify(requestData),
type: 'POST',
success: (result) => {
if (result.code === 0) {
_hideEditor()
const $commentsCnt = $('#pipeCommentsCnt')
const $comments = $('#pipeComments')
if ($commentsCnt.length === 0) {
$comments.removeClass('pipe-comment__null').
unbind('click').
html(
`${result.data}
`)
} else {
$commentsCnt.text(parseInt($commentsCnt.text()) + 1)
$('#pipeComments > div > section').last().after(result.data)
}
if ($(this).data('editable')) {
$('#pipeComments > div > section').
last().
find('.pipe-comment__btn--danger').
removeClass('pipe-comment__btn--none')
}
LazyLoadCSSImage()
LazyLoadImage()
ParseMarkdown()
InitHljs()
$b3logEditor.val('')
localStorage.removeItem('pipeEditorComment')
} else {
alert(result.msg)
}
$editorAdd.removeClass('pipe-btn--disabled')
},
})
})
}