You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
13 KiB
336 lines
13 KiB
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
|
<?php $content = !empty($post) ? $post : $page; if ($options->markdown): ?> |
|
<script src="<?php $options->adminStaticUrl('js', 'hyperdown.js?v=' . $suffixVersion); ?>"></script> |
|
<script src="<?php $options->adminStaticUrl('js', 'pagedown.js?v=' . $suffixVersion); ?>"></script> |
|
<script src="<?php $options->adminStaticUrl('js', 'pagedown-extra.js?v=' . $suffixVersion); ?>"></script> |
|
<script src="<?php $options->adminStaticUrl('js', 'diff.js?v=' . $suffixVersion); ?>"></script> |
|
<script> |
|
$(document).ready(function () { |
|
var textarea = $('#text'), |
|
toolbar = $('<div class="editor" id="wmd-button-bar" />').insertBefore(textarea.parent()), |
|
preview = $('<div id="wmd-preview" class="wmd-hidetab" />').insertAfter('.editor'); |
|
|
|
var options = {}, isMarkdown = <?php echo intval($content->isMarkdown || !$content->have()); ?>; |
|
|
|
options.strings = { |
|
bold: '<?php _e('加粗'); ?> <strong> Ctrl+B', |
|
boldexample: '<?php _e('加粗文字'); ?>', |
|
|
|
italic: '<?php _e('斜体'); ?> <em> Ctrl+I', |
|
italicexample: '<?php _e('斜体文字'); ?>', |
|
|
|
link: '<?php _e('链接'); ?> <a> Ctrl+L', |
|
linkdescription: '<?php _e('请输入链接描述'); ?>', |
|
|
|
quote: '<?php _e('引用'); ?> <blockquote> Ctrl+Q', |
|
quoteexample: '<?php _e('引用文字'); ?>', |
|
|
|
code: '<?php _e('代码'); ?> <pre><code> Ctrl+K', |
|
codeexample: '<?php _e('请输入代码'); ?>', |
|
|
|
image: '<?php _e('图片'); ?> <img> Ctrl+G', |
|
imagedescription: '<?php _e('请输入图片描述'); ?>', |
|
|
|
olist: '<?php _e('数字列表'); ?> <ol> Ctrl+O', |
|
ulist: '<?php _e('普通列表'); ?> <ul> Ctrl+U', |
|
litem: '<?php _e('列表项目'); ?>', |
|
|
|
heading: '<?php _e('标题'); ?> <h1>/<h2> Ctrl+H', |
|
headingexample: '<?php _e('标题文字'); ?>', |
|
|
|
hr: '<?php _e('分割线'); ?> <hr> Ctrl+R', |
|
more: '<?php _e('摘要分割线'); ?> <!--more--> Ctrl+M', |
|
|
|
undo: '<?php _e('撤销'); ?> - Ctrl+Z', |
|
redo: '<?php _e('重做'); ?> - Ctrl+Y', |
|
redomac: '<?php _e('重做'); ?> - Ctrl+Shift+Z', |
|
|
|
fullscreen: '<?php _e('全屏'); ?> - Ctrl+J', |
|
exitFullscreen: '<?php _e('退出全屏'); ?> - Ctrl+E', |
|
fullscreenUnsupport: '<?php _e('此浏览器不支持全屏操作'); ?>', |
|
|
|
imagedialog: '<p><b><?php _e('插入图片'); ?></b></p><p><?php _e('请在下方的输入框内输入要插入的远程图片地址'); ?></p><p><?php _e('您也可以使用附件功能插入上传的本地图片'); ?></p>', |
|
linkdialog: '<p><b><?php _e('插入链接'); ?></b></p><p><?php _e('请在下方的输入框内输入要插入的链接地址'); ?></p>', |
|
|
|
ok: '<?php _e('确定'); ?>', |
|
cancel: '<?php _e('取消'); ?>', |
|
|
|
help: '<?php _e('Markdown语法帮助'); ?>' |
|
}; |
|
|
|
var converter = new HyperDown(), |
|
editor = new Markdown.Editor(converter, '', options), |
|
diffMatch = new diff_match_patch(), last = '', preview = $('#wmd-preview'), |
|
mark = '@mark' + Math.ceil(Math.random() * 100000000) + '@', |
|
span = '<span class="diff" />', |
|
cache = {}; |
|
|
|
// 修正白名单 |
|
converter.enableHtml(true); |
|
converter.commonWhiteList += '|img|cite|embed|iframe'; |
|
converter.specialWhiteList = $.extend(converter.specialWhiteList, { |
|
'ol' : 'ol|li', |
|
'ul' : 'ul|li', |
|
'blockquote' : 'blockquote', |
|
'pre' : 'pre|code' |
|
}); |
|
|
|
converter.hook('beforeParseInline', function (html) { |
|
return html.replace(/^\s*<!\-\-\s*more\s*\-\->\s*$/, function () { |
|
return converter.makeHolder('<!--more-->'); |
|
}); |
|
}); |
|
|
|
// 自动跟随 |
|
converter.hook('makeHtml', function (html) { |
|
html = html.replace('<p><!--more--></p>', '<!--more-->'); |
|
|
|
if (html.indexOf('<!--more-->') > 0) { |
|
var parts = html.split(/\s*<\!\-\-more\-\->\s*/), |
|
summary = parts.shift(), |
|
details = parts.join(''); |
|
|
|
html = '<div class="summary">' + summary + '</div>' |
|
+ '<div class="details">' + details + '</div>'; |
|
} |
|
|
|
|
|
var diffs = diffMatch.diff_main(last, html); |
|
last = html; |
|
|
|
if (diffs.length > 0) { |
|
var stack = [], markStr = mark; |
|
|
|
for (var i = 0; i < diffs.length; i ++) { |
|
var diff = diffs[i], op = diff[0], str = diff[1] |
|
sp = str.lastIndexOf('<'), ep = str.lastIndexOf('>'); |
|
|
|
if (op != 0) { |
|
if (sp >=0 && sp > ep) { |
|
if (op > 0) { |
|
stack.push(str.substring(0, sp) + markStr + str.substring(sp)); |
|
} else { |
|
var lastStr = stack[stack.length - 1], lastSp = lastStr.lastIndexOf('<'); |
|
stack[stack.length - 1] = lastStr.substring(0, lastSp) + markStr + lastStr.substring(lastSp); |
|
} |
|
} else { |
|
if (op > 0) { |
|
stack.push(str + markStr); |
|
} else { |
|
stack.push(markStr); |
|
} |
|
} |
|
|
|
markStr = ''; |
|
} else { |
|
stack.push(str); |
|
} |
|
} |
|
|
|
html = stack.join(''); |
|
|
|
if (!markStr) { |
|
var pos = html.indexOf(mark), prev = html.substring(0, pos), |
|
next = html.substr(pos + mark.length), |
|
sp = prev.lastIndexOf('<'), ep = prev.lastIndexOf('>'); |
|
|
|
if (sp >= 0 && sp > ep) { |
|
html = prev.substring(0, sp) + span + prev.substring(sp) + next; |
|
} else { |
|
html = prev + span + next; |
|
} |
|
} |
|
} |
|
|
|
// 替换img |
|
html = html.replace(/<(img)\s+([^>]*)\s*src="([^"]+)"([^>]*)>/ig, function (all, tag, prefix, src, suffix) { |
|
if (!cache[src]) { |
|
cache[src] = false; |
|
} else { |
|
return '<span class="cache" data-width="' + cache[src][0] + '" data-height="' + cache[src][1] + '" ' |
|
+ 'style="background:url(' + src + ') no-repeat left top; width:' |
|
+ cache[src][0] + 'px; height:' + cache[src][1] + 'px; display: inline-block; max-width: 100%;' |
|
+ '-webkit-background-size: contain;-moz-background-size: contain;-o-background-size: contain;background-size: contain;" />'; |
|
} |
|
|
|
return all; |
|
}); |
|
|
|
// 替换block |
|
html = html.replace(/<(iframe|embed)\s+([^>]*)>/ig, function (all, tag, src) { |
|
if (src[src.length - 1] == '/') { |
|
src = src.substring(0, src.length - 1); |
|
} |
|
|
|
return '<div style="background: #ddd; height: 40px; overflow: hidden; line-height: 40px; text-align: center; font-size: 12px; color: #777">' |
|
+ tag + ' : ' + $.trim(src) + '</div>'; |
|
}); |
|
|
|
return html; |
|
}); |
|
|
|
function cacheResize() { |
|
var t = $(this), w = parseInt(t.data('width')), h = parseInt(t.data('height')), |
|
ow = t.width(); |
|
|
|
t.height(h * ow / w); |
|
} |
|
|
|
var to; |
|
editor.hooks.chain('onPreviewRefresh', function () { |
|
var diff = $('.diff', preview), scrolled = false; |
|
|
|
if (to) { |
|
clearTimeout(to); |
|
} |
|
|
|
$('img', preview).load(function () { |
|
var t = $(this), src = t.attr('src'); |
|
|
|
if (scrolled) { |
|
preview.scrollTo(diff, { |
|
offset : - 50 |
|
}); |
|
} |
|
|
|
if (!!src && !cache[src]) { |
|
cache[src] = [this.width, this.height]; |
|
} |
|
}); |
|
|
|
$('.cache', preview).resize(cacheResize).each(cacheResize); |
|
|
|
var changed = $('.diff', preview).parent(); |
|
if (!changed.is(preview)) { |
|
changed.css('background-color', 'rgba(255,230,0,0.5)'); |
|
to = setTimeout(function () { |
|
changed.css('background-color', 'transparent'); |
|
}, 4500); |
|
} |
|
|
|
if (diff.length > 0) { |
|
var p = diff.position(), lh = diff.parent().css('line-height'); |
|
lh = !!lh ? parseInt(lh) : 0; |
|
|
|
if (p.top < 0 || p.top > preview.height() - lh) { |
|
preview.scrollTo(diff, { |
|
offset : - 50 |
|
}); |
|
scrolled = true; |
|
} |
|
} |
|
}); |
|
|
|
<?php Typecho_Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?> |
|
|
|
var input = $('#text'), th = textarea.height(), ph = preview.height(), |
|
uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">' |
|
+ '<i class="i-upload"><?php _e('附件'); ?></i></button>') |
|
.prependTo('.submit .right') |
|
.click(function() { |
|
$('a', $('.typecho-option-tabs li').not('.active')).trigger('click'); |
|
return false; |
|
}); |
|
|
|
$('.typecho-option-tabs li').click(function () { |
|
uploadBtn.find('i').toggleClass('i-upload-active', |
|
$('#tab-files-btn', this).length > 0); |
|
}); |
|
|
|
editor.hooks.chain('enterFakeFullScreen', function () { |
|
th = textarea.height(); |
|
ph = preview.height(); |
|
$(document.body).addClass('fullscreen'); |
|
var h = $(window).height() - toolbar.outerHeight(); |
|
|
|
textarea.css('height', h); |
|
preview.css('height', h); |
|
}); |
|
|
|
editor.hooks.chain('enterFullScreen', function () { |
|
$(document.body).addClass('fullscreen'); |
|
|
|
var h = window.screen.height - toolbar.outerHeight(); |
|
textarea.css('height', h); |
|
preview.css('height', h); |
|
}); |
|
|
|
editor.hooks.chain('exitFullScreen', function () { |
|
$(document.body).removeClass('fullscreen'); |
|
textarea.height(th); |
|
preview.height(ph); |
|
}); |
|
|
|
function initMarkdown() { |
|
editor.run(); |
|
|
|
var imageButton = $('#wmd-image-button'), |
|
linkButton = $('#wmd-link-button'); |
|
|
|
Typecho.insertFileToEditor = function (file, url, isImage) { |
|
var button = isImage ? imageButton : linkButton; |
|
|
|
options.strings[isImage ? 'imagename' : 'linkname'] = file; |
|
button.trigger('click'); |
|
|
|
var checkDialog = setInterval(function () { |
|
if ($('.wmd-prompt-dialog').length > 0) { |
|
$('.wmd-prompt-dialog input').val(url).select(); |
|
clearInterval(checkDialog); |
|
checkDialog = null; |
|
} |
|
}, 10); |
|
}; |
|
|
|
Typecho.uploadComplete = function (file) { |
|
Typecho.insertFileToEditor(file.title, file.url, file.isImage); |
|
}; |
|
|
|
// 编辑预览切换 |
|
var edittab = $('.editor').prepend('<div class="wmd-edittab"><a href="#wmd-editarea" class="active"><?php _e('撰写'); ?></a><a href="#wmd-preview"><?php _e('预览'); ?></a></div>'), |
|
editarea = $(textarea.parent()).attr("id", "wmd-editarea"); |
|
|
|
$(".wmd-edittab a").click(function() { |
|
$(".wmd-edittab a").removeClass('active'); |
|
$(this).addClass("active"); |
|
$("#wmd-editarea, #wmd-preview").addClass("wmd-hidetab"); |
|
|
|
var selected_tab = $(this).attr("href"), |
|
selected_el = $(selected_tab).removeClass("wmd-hidetab"); |
|
|
|
// 预览时隐藏编辑器按钮 |
|
if (selected_tab == "#wmd-preview") { |
|
$("#wmd-button-row").addClass("wmd-visualhide"); |
|
} else { |
|
$("#wmd-button-row").removeClass("wmd-visualhide"); |
|
} |
|
|
|
// 预览和编辑窗口高度一致 |
|
$("#wmd-preview").outerHeight($("#wmd-editarea").innerHeight()); |
|
|
|
return false; |
|
}); |
|
} |
|
|
|
if (isMarkdown) { |
|
initMarkdown(); |
|
} else { |
|
var notice = $('<div class="message notice"><?php _e('这篇文章不是由Markdown语法创建的, 继续使用Markdown编辑它吗?'); ?> ' |
|
+ '<button class="btn btn-xs primary yes"><?php _e('是'); ?></button> ' |
|
+ '<button class="btn btn-xs no"><?php _e('否'); ?></button></div>') |
|
.hide().insertBefore(textarea).slideDown(); |
|
|
|
$('.yes', notice).click(function () { |
|
notice.remove(); |
|
$('<input type="hidden" name="markdown" value="1" />').appendTo('.submit'); |
|
initMarkdown(); |
|
}); |
|
|
|
$('.no', notice).click(function () { |
|
notice.remove(); |
|
}); |
|
} |
|
}); |
|
</script> |
|
<?php endif; ?> |
|
|
|
|