thedesk/app/js/post/bb-md.js

348 lines
9.2 KiB
JavaScript
Raw Permalink Normal View History

2018-01-28 23:22:43 +11:00
//BBCodeとMarkdownの入力・パーサー
2018-02-09 03:43:11 +11:00
//アカウント変えた時にBBとかMDとか
2019-05-19 17:39:30 +10:00
function mdCheck() {
2019-11-09 00:52:54 +11:00
var acct_id = $('#post-acct-sel').val()
2020-07-21 13:44:53 +10:00
/*var profimg = localStorage.getItem('prof_' + acct_id)
2019-05-19 17:39:30 +10:00
if (!profimg) {
2019-11-09 00:52:54 +11:00
profimg = '../../img/missing.svg'
2018-08-21 04:26:14 +10:00
}
2019-11-09 00:52:54 +11:00
$('#acct-sel-prof').attr('src', profimg)
2020-07-21 13:44:53 +10:00
*/
2019-11-09 00:52:54 +11:00
if (localStorage.getItem('post_' + acct_id)) {
$('#toot-post-btn').text(
localStorage.getItem('post_' + acct_id) +
'(' +
localStorage.getItem('domain_' + acct_id) +
')'
)
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#toot-post-btn').text(lang.lang_toot + '(' + localStorage.getItem('domain_' + acct_id) + ')')
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
if (!localStorage.getItem('bb_' + acct_id) && !localStorage.getItem('md_' + acct_id)) {
$('.markdown').addClass('hide')
$('.anti-markdown').addClass('hide')
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('.anti-markdown').removeClass('hide')
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
if ($('.markdown').hasClass('hide')) {
localStorage.setItem('md', 'hide')
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
localStorage.removeItem('md')
2018-02-09 03:43:11 +11:00
}
2019-11-09 00:52:54 +11:00
var domain = localStorage.getItem('domain_' + acct_id)
if (domain == 'itabashi.0j0.jp') {
$('#limited-button').removeClass('hide')
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#limited-button').addClass('hide')
2018-03-20 15:55:25 +11:00
}
2019-11-09 00:52:54 +11:00
if (domain == 'kirishima.cloud') {
$('#faicon-btn').show()
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#faicon-btn').hide()
2018-03-31 13:39:06 +11:00
}
2019-11-09 00:52:54 +11:00
if (domain == 'imastodon.net') {
trendTag()
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#trendtag').html('')
2018-05-20 16:17:10 +10:00
}
2019-11-09 00:52:54 +11:00
if (localStorage.getItem('mode_' + domain) == 'misskey') {
2019-06-07 02:11:04 +10:00
M.toast({ html: lang.lang_bbmd_misskey, displayLength: 5000 })
2018-07-30 21:03:49 +10:00
}
2019-11-09 00:52:54 +11:00
if (idata[domain + '_letters']) {
$('#textarea').attr('data-length', idata[domain + '_letters'])
2019-05-19 17:39:30 +10:00
} else {
2020-07-21 13:44:53 +10:00
var maxletters = localStorage.getItem(domain + 'letters_')
if (maxletters > 0) {
$('#textarea').attr('data-length', maxletters)
} else {
$('#textarea').attr('data-length', 500)
}
2018-04-16 23:58:14 +10:00
}
2019-11-09 00:52:54 +11:00
if (idata[domain + '_glitch'] === 'true') {
$('#local-button').removeClass('hide')
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#local-button').addClass('hide')
2018-09-06 02:47:27 +10:00
}
2019-11-09 00:52:54 +11:00
var multi = localStorage.getItem('multi')
2018-06-18 00:26:45 +10:00
if (multi) {
2019-11-09 00:52:54 +11:00
var obj = JSON.parse(multi)
if (
obj[acct_id].background &&
obj[acct_id].background != 'def' &&
obj[acct_id].text &&
obj[acct_id].text != 'def'
) {
$('#toot-post-btn').removeClass('indigo')
$('#toot-post-btn').css('background-color', '#' + obj[acct_id].background)
$('#toot-post-btn').css('color', obj[acct_id].text)
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#toot-post-btn').css('background-color', '')
$('#toot-post-btn').css('color', '')
$('#toot-post-btn').addClass('indigo')
2018-06-18 00:26:45 +10:00
}
}
2019-11-09 00:52:54 +11:00
loadVis()
2018-02-09 03:43:11 +11:00
}
2018-01-28 23:22:43 +11:00
//BOXのトグルボタン
2019-05-19 17:39:30 +10:00
function mdToggle() {
2019-11-09 00:52:54 +11:00
$('.markdown').toggleClass('hide')
$('.anti-markdown').toggleClass('hide')
if ($('.markdown').hasClass('hide')) {
localStorage.setItem('md', 'hide')
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
localStorage.removeItem('md')
2018-01-28 23:22:43 +11:00
}
}
//最初に読み込みます(MD対応インスタンスかチェック)
2019-11-09 00:52:54 +11:00
if (localStorage.getItem('md') == 'hide') {
$('.markdown').addClass('hide')
$('.anti-markdown').removeClass('hide')
2018-01-28 23:22:43 +11:00
}
//タグを選んだ時に(BB版)
2019-05-19 17:39:30 +10:00
function tagsel(tag) {
2019-11-09 00:52:54 +11:00
var acct_id = $('#post-acct-sel').val()
if (!localStorage.getItem('bb_' + acct_id)) {
return false
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
if (tag == 'large' || tag == 'size' || tag == 'color' || tag == 'colorhex') {
var sub = $('#' + tag).val()
var sub = sub.replace(/#/g, '')
surroundHTML(tag + '=' + sub, tag)
} else if (tag == 'flip=vertical' || tag == 'flip=horizontal') {
surroundHTML(tag, 'flip')
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
surroundHTML(tag, tag)
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
$('#textarea').focus()
2019-05-19 17:39:30 +10:00
}
//HTMLをエスケープしてXSSを防ぐ
function escape_html(string) {
if (typeof string !== 'string') {
2019-11-09 00:52:54 +11:00
return string
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
return string.replace(/[&'`"<>]/g, function(match) {
2019-05-19 17:39:30 +10:00
return {
'&': '&amp;',
"'": '&#x27;',
'`': '&#x60;',
'"': '&quot;',
'<': '&lt;',
2019-11-09 00:52:54 +11:00
'>': '&gt;'
2019-05-19 17:39:30 +10:00
}[match]
2019-11-09 00:52:54 +11:00
})
2018-01-28 23:22:43 +11:00
}
//テキストボックスで選択したやつをタグで囲む(BB版)
2019-05-19 17:39:30 +10:00
function surroundHTML(tagS, tagE) {
2019-11-09 00:52:54 +11:00
var acct_id = $('#post-acct-sel').val()
if (!localStorage.getItem('bb_' + acct_id)) {
return false
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
var target = document.getElementById('textarea')
var pos = getAreaRange(target)
2018-01-28 23:22:43 +11:00
2019-11-09 00:52:54 +11:00
var val = target.value
var range = val.slice(pos.start, pos.end)
var beforeNode = val.slice(0, pos.start)
var afterNode = val.slice(pos.end)
var insertNode
2019-05-19 17:39:30 +10:00
if (range || pos.start != pos.end) {
2019-11-09 00:52:54 +11:00
insertNode = '[' + tagS + ']' + range + '[/' + tagE + ']'
target.value = beforeNode + insertNode + afterNode
} else if (pos.start == pos.end) {
insertNode = '[' + tagS + ']' + '[/' + tagE + ']'
target.value = beforeNode + insertNode + afterNode
2019-05-19 17:39:30 +10:00
}
2018-01-28 23:22:43 +11:00
}
2019-05-19 17:39:30 +10:00
function markdown(tag, ck, br, space) {
2019-11-09 00:52:54 +11:00
if (space == 'before') {
tagE = tag
tag = ' ' + tag
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
tagE = tag
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
surroundMD(tag, tagE, ck, br)
$('#textarea').focus()
2019-05-19 17:39:30 +10:00
}
function surroundMD(tagS, tagE, ck, br) {
2019-11-09 00:52:54 +11:00
var acct_id = $('#post-acct-sel').val()
if (!localStorage.getItem('md_' + acct_id)) {
return false
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
var target = document.getElementById('textarea')
var pos = getAreaRange(target)
2018-01-28 23:22:43 +11:00
2019-11-09 00:52:54 +11:00
var val = target.value
var range = val.slice(pos.start, pos.end)
var beforeNode = val.slice(0, pos.start)
var afterNode = val.slice(pos.end)
var insertNode
if (br == 'yes') {
var br = '\n'
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
var br = ''
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
if ((range || pos.start != pos.end) && ck == 'yes') {
insertNode = tagS + range + tagE
target.value = beforeNode + insertNode + br + afterNode
} else if (pos.start == pos.end || ck == 'no') {
insertNode = tagS + range
target.value = beforeNode + insertNode + br + afterNode
2018-01-28 23:22:43 +11:00
}
}
//テキストボックスの前後チェック
function getAreaRange(obj) {
2019-11-09 00:52:54 +11:00
var pos = new Object()
2019-05-19 17:39:30 +10:00
if (window.getSelection()) {
2019-11-09 00:52:54 +11:00
pos.start = obj.selectionStart
pos.end = obj.selectionEnd
2018-01-28 23:22:43 +11:00
}
2019-11-09 00:52:54 +11:00
return pos
2018-01-28 23:22:43 +11:00
}
//Markdownのリンク挿入
2019-05-19 17:39:30 +10:00
function markdownLink() {
2019-11-09 00:52:54 +11:00
var acct_id = $('#post-acct-sel').val()
if (!localStorage.getItem('md_' + acct_id)) {
return false
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
var linkIns = '[' + $('#linkt').val() + ']' + '(' + $('#link2').val() + ')'
if (linkIns != '[]()') {
$('#textarea').val($('#textarea').val() + linkIns)
$('#linkt').val('')
$('#link2').val('')
$('#textarea').focus()
2018-01-28 23:22:43 +11:00
}
}
//Markdownのimg挿入
2019-05-19 17:39:30 +10:00
function markdownImage() {
2019-11-09 00:52:54 +11:00
var acct_id = $('#post-acct-sel').val()
if (!localStorage.getItem('md_' + acct_id)) {
return false
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
var imgIns = '![' + $('#image').val() + ']' + '(' + $('#image2').val() + ')'
if (imgIns != '![]()') {
$('#textarea').val($('#textarea').val() + imgIns)
$('#image').val('')
$('#image2').val('')
$('#textarea').focus()
2018-01-28 23:22:43 +11:00
}
}
//文字数をチェック(hタグ用)
function str_count(all, part) {
2019-11-09 00:52:54 +11:00
return (all.match(new RegExp(part, 'g')) || []).length
2018-01-28 23:22:43 +11:00
}
//プレビュー
2019-05-19 17:39:30 +10:00
function preview() {
2019-11-09 00:52:54 +11:00
$('#preview-field').show()
$('#toot-field').hide()
$('#preview-btn').hide()
var bb = escape_html($('#textarea').val())
2018-01-28 23:22:43 +11:00
//quote
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/>(.+)$/g, '<blockquote>$1</blockquote>')
2018-01-28 23:22:43 +11:00
//spin
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/\[spin\](.+)\[\/spin\]/g, '<span class="fa fa-spin">$1</span>')
2018-01-28 23:22:43 +11:00
//pulse
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/\[pulse\](.+)\[\/pulse\]/g, '<span class="bbcode-pulse-loading">$1</span>')
2018-01-28 23:22:43 +11:00
//large
2019-11-09 00:52:54 +11:00
var bb = bb.replace(
/\[large=([0-9]{1,2})x\](.+)\[\/large\]/g,
'<span class="fa fa-$1x">$2</span>'
)
2018-01-28 23:22:43 +11:00
//vertical
2019-11-09 00:52:54 +11:00
var bb = bb.replace(
/\[flip=vertical\](.+)\[\/flip\]/g,
'<span class="fa fa-flip-vertical">$1</span>'
)
2018-01-28 23:22:43 +11:00
//horizontal
2019-11-09 00:52:54 +11:00
var bb = bb.replace(
/\[flip=horizontal\](.+)\[\/flip\]/g,
'<span class="fa fa-flip-horizontal">$1</span>'
)
2018-01-28 23:22:43 +11:00
//b
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/\[b\](.+)\[\/b\]/g, '<b>$1</b>')
2018-01-28 23:22:43 +11:00
//i
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/\[i\](.+)\[\/i\]/g, '<i>$1</i>')
2018-01-28 23:22:43 +11:00
//u
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/\[u\](.+)\[\/u\]/g, '<u>$1</u>')
2018-01-28 23:22:43 +11:00
//s
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/\[s\](.+)\[\/s\]/g, '<s>$1</s>')
2018-01-28 23:22:43 +11:00
//size
2019-11-09 00:52:54 +11:00
var bb = bb.replace(
/\[size=([0-9]{1,2})\](.+)\[\/size\]/g,
'<span style="font-size:$1px">$2</span>'
)
2018-01-28 23:22:43 +11:00
//colorhex
2019-11-09 00:52:54 +11:00
var bb = bb.replace(
/\[colorhex=([A-Fa-f0-9]+)\](.+)\[\/colorhex\]/g,
'<span style="color:#$1">$2</span>'
)
2018-01-28 23:22:43 +11:00
//code
2019-11-09 00:52:54 +11:00
var bb = bb.replace(/`(.+)`/g, '<code>$1</code>')
2018-02-13 06:16:46 +11:00
//head
2019-11-09 00:52:54 +11:00
var m
m = bb.match(/^#{1,6}(.+)$/gm)
2019-05-19 17:39:30 +10:00
if (m) {
for (let i = 0; i < m.length; i++) {
2019-11-09 00:52:54 +11:00
var t = m[i].match(/^#{1,6}(.+)$/)
var indexct = '<h' + str_count(m[i], '#') + '>' + t[1] + '</h' + str_count(m[i], '#') + '>'
var bb = bb.replace(new RegExp(m[i], ''), indexct)
2019-05-19 17:39:30 +10:00
}
2018-01-28 23:22:43 +11:00
}
2018-02-13 06:16:46 +11:00
//list(ul)
2019-11-09 00:52:54 +11:00
var li
li = bb.match(/^\- (.+)$/gm)
2019-05-19 17:39:30 +10:00
if (li) {
for (let l = 0; l < li.length; l++) {
2019-11-09 00:52:54 +11:00
var u = li[l].match(/^\- (.+)$/)
var listUl = '<li>' + u[1] + '</li>'
2019-05-19 17:39:30 +10:00
if (l == 0) {
2019-11-09 00:52:54 +11:00
listUl = '<ul>' + listUl
2019-05-19 17:39:30 +10:00
}
if (l == li.length - 1) {
2019-11-09 00:52:54 +11:00
listUl = listUl + '</ul>'
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
var bb = bb.replace(new RegExp(li[l], ''), listUl)
2018-02-13 06:16:46 +11:00
}
}
//list(ol)
2019-11-09 00:52:54 +11:00
var li
li = bb.match(/^1\. (.+)$/gm)
2019-05-19 17:39:30 +10:00
if (li) {
for (let l = 0; l < li.length; l++) {
2019-11-09 00:52:54 +11:00
var u = li[l].match(/^1\. (.+)$/)
var listUl = '<li>' + u[1] + '</li>'
2019-05-19 17:39:30 +10:00
if (l === 0) {
2019-11-09 00:52:54 +11:00
listUl = '<ol>' + listUl
2019-05-19 17:39:30 +10:00
}
if (l === li.length - 1) {
2019-11-09 00:52:54 +11:00
listUl = listUl + '</ol>'
2019-05-19 17:39:30 +10:00
}
2019-11-09 00:52:54 +11:00
var bb = bb.replace(new RegExp(li[l], ''), listUl)
2018-02-13 06:16:46 +11:00
}
}
2018-01-28 23:22:43 +11:00
//img
2019-11-09 00:52:54 +11:00
var bb = bb.replace(
/!\[(.+)\]\((https:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\)/g,
'<img src="$2" text="$1" style="width:100%">'
)
2018-01-28 23:22:43 +11:00
//link
2019-11-09 00:52:54 +11:00
var bb = bb.replace(
/\[(.+)\]\((https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\)/g,
'<a href="$2" target="_blank">$1</a>'
)
bb = nl2br(bb)
bb = bb.replace(new RegExp('</li><br />', 'g'), '')
$('#md-preview').html(bb)
2019-05-19 17:39:30 +10:00
}
//Editで戻る
function previewEdit() {
2019-11-09 00:52:54 +11:00
$('#preview-field').hide()
$('#toot-field').show()
$('#preview-btn').show()
$('#md-preview').html('')
}