Typecho原生链接插入方式修改
说明
Typecho原生的链接插入方式不是行内形式,遂修改。
代码
此代码为1.2.1版本代码,别的版本请自行判断。
原始的editor-js.php文件内容:
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php $content = !empty($post) ? $post : $page; if ($options->markdown): ?>
<script src="<?php $options->adminStaticUrl('js', 'hyperdown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'pagedown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'paste.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'purify.js'); ?>"></script>
<script>
$(document).ready(function () {
var textarea = $('#text'),
isFullScreen = false,
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);
// 自动跟随
converter.enableHtml(true);
converter.enableLine(true);
reloadScroll = scrollableEditor(textarea, preview);
// 修正白名单
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>';
}
// 替换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 class="embed"><strong>'
+ tag + '</strong> : ' + $.trim(src) + '</div>';
});
return DOMPurify.sanitize(html, {USE_PROFILES: {html: true}});
});
editor.hooks.chain('onPreviewRefresh', function () {
var images = $('img', preview), count = images.length;
if (count == 0) {
reloadScroll(true);
} else {
images.bind('load error', function () {
count --;
if (count == 0) {
reloadScroll(true);
}
});
}
});
<?php \Typecho\Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?>
var 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);
isFullScreen = true;
});
editor.hooks.chain('enterFullScreen', function () {
$(document.body).addClass('fullscreen');
var h = window.screen.height - toolbar.outerHeight();
textarea.css('height', h);
preview.css('height', h);
isFullScreen = true;
});
editor.hooks.chain('exitFullScreen', function () {
$(document.body).removeClass('fullscreen');
textarea.height(th);
preview.height(ph);
isFullScreen = false;
});
editor.hooks.chain('commandExecuted', function () {
textarea.trigger('input');
});
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;
});
// 剪贴板复制图片
textarea.pastableTextarea().on('pasteImage', function (e, data) {
var name = data.name ? data.name.replace(/[\(\)\[\]\*#!]/g, '') : (new Date()).toISOString().replace(/\..+$/, '');
if (!name.match(/\.[a-z0-9]{2,}$/i)) {
var ext = data.blob.type.split('/').pop();
name += '.' + ext;
}
Typecho.uploadFile(new File([data.blob], name), name);
});
}
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; ?>修改后的代码:
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php $content = !empty($post) ? $post : $page; if ($options->markdown): ?>
<script src="<?php $options->adminStaticUrl('js', 'hyperdown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'pagedown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'paste.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'purify.js'); ?>"></script>
<script>
$(document).ready(function () {
var textarea = $('#text'),
isFullScreen = false,
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);
converter.enableHtml(true);
converter.enableLine(true);
reloadScroll = scrollableEditor(textarea, preview);
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>';
}
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 class="embed"><strong>'
+ tag + '</strong> : ' + $.trim(src) + '</div>';
});
return DOMPurify.sanitize(html, {USE_PROFILES: {html: true}});
});
editor.hooks.chain('onPreviewRefresh', function () {
var images = $('img', preview), count = images.length;
if (count == 0) {
reloadScroll(true);
} else {
images.bind('load error', function () {
count --;
if (count == 0) reloadScroll(true);
});
}
});
<?php \Typecho\Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?>
var 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);
isFullScreen = true;
});
editor.hooks.chain('enterFullScreen', function () {
$(document.body).addClass('fullscreen');
var h = window.screen.height - toolbar.outerHeight();
textarea.css('height', h);
preview.css('height', h);
isFullScreen = true;
});
editor.hooks.chain('exitFullScreen', function () {
$(document.body).removeClass('fullscreen');
textarea.height(th);
preview.height(ph);
isFullScreen = false;
});
editor.hooks.chain('commandExecuted', function () {
textarea.trigger('input');
});
function initMarkdown() {
editor.run();
// --- 核心修改:自定义弹窗逻辑 ---
var linkButton = $('#wmd-link-button');
var newLinkButton = linkButton.clone().off();
linkButton.replaceWith(newLinkButton);
$('#wmd-link-button').click(function() {
var el = textarea[0];
var start = el.selectionStart;
var end = el.selectionEnd;
var text = textarea.val();
var selection = text.substring(start, end);
// 1. 构建仿原生样式的弹窗 HTML
var dialogHtml =
'<div class="wmd-prompt-background" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; opacity: 0.5; background: #000;"></div>' +
'<div class="wmd-prompt-dialog" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1001; background: #fff; border: 1px solid #ccc; padding: 10px 20px 20px; width: 400px; max-width: 90%; box-shadow: 0 5px 15px rgba(0,0,0,0.2);">' +
'<div style="margin-bottom:10px;"><b><?php _e('插入链接'); ?></b></div>' +
'<p><?php _e('请在下方的输入框内输入要插入的链接地址'); ?></p>' +
'<input type="text" class="text" value="http://" style="width: 100%; padding: 5px; margin-bottom: 15px; border: 1px solid #ccc;" />' +
'<button class="btn primary ok"><?php _e('确定'); ?></button> ' +
'<button class="btn cancel"><?php _e('取消'); ?></button>' +
'</div>';
var $dialog = $(dialogHtml);
$('body').append($dialog);
var $input = $dialog.find('input');
$input.focus().select(); // 自动聚焦
// 关闭弹窗函数
var closeDialog = function() {
$dialog.remove();
};
// 确认插入逻辑
var confirmLink = function() {
var url = $input.val();
if (url && url !== '' && url !== 'http://') {
if (selection === '') selection = "<?php _e('请输入链接描述'); ?>";
// 构造行内链接
var result = '[' + selection + '](' + url + ')';
textarea.val(text.substring(0, start) + result + text.substring(end));
el.selectionStart = el.selectionEnd = start + result.length;
textarea.trigger('input');
}
closeDialog();
};
// 绑定事件
$dialog.find('.ok').click(confirmLink);
$dialog.find('.cancel').click(closeDialog);
// 绑定回车和ESC键
$input.keydown(function(e) {
if (e.keyCode == 13) { confirmLink(); return false; } // Enter
if (e.keyCode == 27) { closeDialog(); return false; } // ESC
});
});
// --- 修改结束 ---
// --- 附件上传插入逻辑(保持一致) ---
Typecho.insertFileToEditor = function (file, url, isImage) {
var text = isImage ? '' : '[' + file + '](' + url + ')';
var el = textarea[0], start = el.selectionStart, end = el.selectionEnd, content = textarea.val();
textarea.val(content.substring(0, start) + text + content.substring(end));
el.selectionStart = el.selectionEnd = start + text.length;
textarea.trigger('input');
};
Typecho.uploadComplete = function (file) {
Typecho.insertFileToEditor(file.title, file.url, file.isImage);
};
// ... (后续 UI 切换代码保持不变) ...
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_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;
});
textarea.pastableTextarea().on('pasteImage', function (e, data) {
var name = data.name ? data.name.replace(/[\(\)\[\]\*#!]/g, '') : (new Date()).toISOString().replace(/\..+$/, '');
if (!name.match(/\.[a-z0-9]{2,}$/i)) {
var ext = data.blob.type.split('/').pop();
name += '.' + ext;
}
Typecho.uploadFile(new File([data.blob], name), name);
});
}
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; ?>
评论区(暂无评论)