function blog_editor_init(name, editor_config) { if (editor_config === undefined) { editor_config = {}; } editor_config = $.extend({ type: 'blog' }, editor_config); var input_title = $("#input-" + name + "_title"); var input_tags = $("#input-" + name + "_tags"); var input_content_md = $("#input-" + name + "_content_md"); var input_is_hidden = $("#input-" + name + "_is_hidden"); var this_form = input_is_hidden[0].form; var is_saved; var last_save_done = true; // init buttons var save_btn = $(''); var preview_btn = $(''); var bold_btn = $(''); var italic_btn = $(''); if (typeof isBootstrap5Page !== 'undefined' && isBootstrap5Page) { save_btn.get().map(el => new bootstrap.Tooltip(el, { container: 'body', title: '保存 (Ctrl-S)' })); preview_btn.get().map(el => new bootstrap.Tooltip(el, { container: 'body', title: '预览 (Ctrl-D)' })); bold_btn.get().map(el => new bootstrap.Tooltip(el, { container: 'body', title: '粗体 (Ctrl-B)' })); italic_btn.get().map(el => new bootstrap.Tooltip(el, { container: 'body', title: '斜体 (Ctrl-I)' })); } else { save_btn.tooltip({ container: 'body', title: '保存 (Ctrl-S)' }); preview_btn.tooltip({ container: 'body', title: '预览 (Ctrl-D)' }); bold_btn.tooltip({ container: 'body', title: '粗体 (Ctrl-B)' }); italic_btn.tooltip({ container: 'body', title: '斜体 (Ctrl-I)' }); } var all_btn = [save_btn, preview_btn, bold_btn, italic_btn]; // init toolbar var toolbar = $('
'); toolbar.append($('
') .append(save_btn) .append(preview_btn) ); toolbar.append($('
') .append(bold_btn) .append(italic_btn) ); function set_saved(val) { is_saved = val; if (val) { save_btn.removeClass('btn-warning'); save_btn.addClass('btn-success'); save_btn.html(isBootstrap5Page ? '' : ''); before_window_unload_message = null; } else { save_btn.removeClass('btn-success'); save_btn.addClass('btn-warning'); save_btn.html(isBootstrap5Page ? '' : ''); before_window_unload_message = '您所编辑的内容尚未保存'; } } function set_preview_status(status) { // 0: normal // 1: loading // 2: loaded if (status == 0) { preview_btn.removeClass('active'); for (var i = 0; i < all_btn.length; i++) { if (all_btn[i] != preview_btn) { all_btn[i].prop('disabled', false); } } } else if (status == 1) { for (var i = 0; i < all_btn.length; i++) { if (all_btn[i] != preview_btn) { all_btn[i].prop('disabled', true); } } preview_btn.addClass('active'); } } set_saved(true); // init codemirror if (input_content_md[0]) { input_content_md.wrap('
'); var blog_contend_md_editor = input_content_md.parent(); input_content_md.before($('
') .append(toolbar) ); input_content_md.wrap('
'); var codeeditor; if (editor_config.type == 'blog') { codeeditor = CodeMirror.fromTextArea(input_content_md[0], { mode: 'gfm', lineNumbers: true, matchBrackets: true, lineWrapping: true, styleActiveLine: true, theme: 'default' }); } else if (editor_config.type == 'slide') { codeeditor = CodeMirror.fromTextArea(input_content_md[0], { mode: 'plain', lineNumbers: true, matchBrackets: true, lineWrapping: true, styleActiveLine: true, theme: 'default' }); } } function preview(html) { var iframe = $(''); blog_contend_md_editor.append( $('') .append(iframe) ); var iframe_document = iframe[0].contentWindow.document; iframe_document.open(); iframe_document.write(html); iframe_document.close(); $(iframe_document).bind('keydown', 'ctrl+d', function() { preview_btn.click(); return false; }); blog_contend_md_editor.find('.blog-content-md-editor-in').slideUp('fast'); blog_contend_md_editor.find('.blog-content-md-editor-preview').slideDown('fast', function() { set_preview_status(2); iframe.focus(); iframe.find('body').focus(); }); } function save(config) { if (config == undefined) { config = {}; } config = $.extend({ need_preview: false, fail: function() { }, done: function() { } }, config); if (!last_save_done) { config.fail(); config.done(); return; } last_save_done = false; if (config.need_preview) { set_preview_status(1); } var post_data = {}; $($(this_form).serializeArray()).each(function() { post_data[this["name"]] = this["value"]; }); if (config.need_preview) { post_data['need_preview'] = 'on'; } post_data["save-" + name] = ''; $.ajax({ type : 'POST', data : post_data, url : window.location.href, success : function(data) { try { data = JSON.parse(data) } catch (e) { alert(data); if (config.need_preview) { set_preview_status(0); } config.fail(); return; } var ok = true; $(['title', 'content_md', 'tags']).each(function() { ok &= showErrorHelp(name + '_' + this, data[this]); }); if (data.extra !== undefined) { alert(data.extra); ok = false; } if (!ok) { if (config.need_preview) { set_preview_status(0); } config.fail(); return; } set_saved(true); if (config.need_preview) { preview(data.html); } if (data.blog_write_url) { window.history.replaceState({}, document.title, data.blog_write_url); } if (data.blog_url) { $('#a-' + name + '_view_blog').attr('href', data.blog_url).show(); } if (data.blog_id) { $('#div-blog-id').html('博客 ID:' + data.blog_id + '').show(); } } }).fail(function() { if (config.need_preview) { set_preview_status(0); } config.fail(); }).always(function() { last_save_done = true; config.done(); }); } function add_around(sl, sr) { codeeditor.replaceSelection(sl + codeeditor.getSelection() + sr); } // event if (input_content_md[0]) { codeeditor.on('change', function() { codeeditor.save(); set_saved(false); }); } $.merge(input_title, input_tags).on('input', function() { set_saved(false); }); $('#a-' + name + '_save').click(function (e) { e.preventDefault(); save({ done: function () { location.reload(); } }); }); save_btn.click(function() { save(); }); preview_btn.click(function() { if (preview_btn.hasClass('active')) { set_preview_status(0); blog_contend_md_editor.find('.blog-content-md-editor-in').slideDown('fast'); blog_contend_md_editor.find('.blog-content-md-editor-preview').slideUp('fast', function() { $(this).remove(); }); codeeditor.focus(); } else { save({need_preview: true}); } }); bold_btn.click(function() { add_around("**", "**"); codeeditor.focus(); }); italic_btn.click(function() { add_around("*", "*"); codeeditor.focus(); }); input_is_hidden.on('switchChange.bootstrapSwitch', function(e, state) { var ok = true; if (!state && !confirm("你确定要公开吗?")) { ok = false; } if (!ok) { input_is_hidden.bootstrapSwitch('toggleState', true); } else { input_is_hidden.bootstrapSwitch('readonly', true); var succ = true; save({ fail: function() { succ = false; }, done: function() { input_is_hidden.bootstrapSwitch('readonly', false); if (!succ) { input_is_hidden.bootstrapSwitch('toggleState', true); } } }); } }); // init hot keys if (input_content_md[0]) { codeeditor.setOption("extraKeys", { "Ctrl-S": function(cm) { save_btn.click(); }, "Ctrl-B": function(cm) { bold_btn.click(); }, "Ctrl-D": function(cm) { preview_btn.click(); }, "Ctrl-I": function(cm) { italic_btn.click(); } }); } $(document).bind('keydown', 'ctrl+d', function() { preview_btn.click(); return false; }); $.merge(input_title, input_tags).bind('keydown', 'ctrl+s', function() { save_btn.click(); return false; }); if (this_form) { $(this_form).submit(function() { before_window_unload_message = null; }); } }