├── LICENSE ├── README.md ├── johnlui_markdown ├── attlib.php ├── images │ └── image.png ├── johnlui_markdown.php ├── johnlui_markdown_callback.php ├── johnlui_markdown_html.php ├── scripts │ └── js │ │ ├── hotkeys.js │ │ ├── module.min.js │ │ ├── simditor-markdown.js │ │ └── simditor.min.js └── styles │ ├── font-awesome.css │ ├── markdown.css │ └── simditor.css └── new_markdown ├── editor.css ├── editor.js ├── icomoon.woff ├── markdown.css ├── markdown_html.php └── new_markdown.php /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 JohnLui 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MarkDown for Emlog 2 | ---- 3 | 4 | 完美的 emlog 博客系统 Markdown 编辑器,已出 2.0 版。 5 | 6 | ## 预览 7 | 8 | ![pic](https://lvwenhan.com/content/uploadfile/201708/ab341502364172.jpg) 9 | 10 | ## 版本记录 11 | 12 | * 2017年08月11日 2.0 版发布,体验更完美,不再修改系统文件,不再手动引入 jQuery,同时更换了文件夹名称 13 | * 2015年04月07日 更新Simditor,增加 gif 支持,增加图片尺寸设置和查看源代码功能 14 | * 2014年10月14日 1.0 发布 15 | 16 | ## 注意事项 17 | 18 | ### 在使用新插件 `New MarkDown` 前,请 *务必* 在 emlog 后台禁用旧的名为 `MarkDown` 的插件,否则可能出现意想不到的问题 19 | 20 | ## 使用方法 21 | 22 | 由于目前(2017-08-11 11:35:22) emlog 开发者中心后台功能异常,所以暂时大家只能手动上传插件进行安装。安装方法: 23 | 24 | 1. 下载本项目,git clone 或者直接 Download ZIP 都可以 25 | 2. 将 `new_markdown` 文件夹压缩为 zip 文件 26 | 3. 在 emlog 后台的“插件”页面手动上传 zip 进行安装 27 | 4. 请务必记得取消旧的名为 `MarkDown` 编辑器的激活 28 | 29 | ## 开源协议 30 | 31 | 本项目遵循 MIT 协议开源,具体请查看根目录下的 LICENSE 文件。 -------------------------------------------------------------------------------- /johnlui_markdown/attlib.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | upload 7 | 8 | 9 | 10 | 26 | 27 |
28 | 上传附件 29 | 批量上传 30 | 附件库( 31 |
32 |
33 | 34 |

该文章没有附件

35 | $value): 37 | $extension = strtolower(substr(strrchr($value['filepath'], "."),1)); 38 | $atturl = BLOG_URL.substr($value['filepath'], 3); 39 | if ($extension == 'zip' || $extension == 'rar'){ 40 | $imgpath = "./views/images/tar.gif"; 41 | $embedlink = "插入 "; 42 | } elseif (in_array($extension, array('gif', 'jpg', 'jpeg', 'png', 'bmp'))) { 43 | $imgpath = $value['filepath']; 44 | $ed_imgpath = BLOG_URL.substr($imgpath,3); 45 | $embedlink = "原图"; 46 | if (isset($value['thum_filepath'])) { 47 | $thum_url = BLOG_URL.substr($value['thum_filepath'], 3); 48 | $embedlink .= " 缩略图"; 49 | } 50 | } else { 51 | $imgpath = "./views/images/fnone.gif"; 52 | $embedlink = "插入 "; 53 | } 54 | ?> 55 |
  • 56 | 57 |
    58 | x 59 | 60 |
    61 | 62 | 63 |
    删除
  • 64 | 65 |
    66 | 67 | 68 | -------------------------------------------------------------------------------- /johnlui_markdown/images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlui/MarkDown-for-Emlog/f106ef7e3f73f9cadb3759d297d94e60f83730c7/johnlui_markdown/images/image.png -------------------------------------------------------------------------------- /johnlui_markdown/johnlui_markdown.php: -------------------------------------------------------------------------------- 1 | '; 23 | } -------------------------------------------------------------------------------- /johnlui_markdown/johnlui_markdown_callback.php: -------------------------------------------------------------------------------- 1 | 文章摘要:', '
    文章摘要:由于编辑器与系统 jQuery 版本冲突,无法显示。
    ', $file_content); 26 | $file_content = str_replace('$("#advset").css(\'display\', $.cookie(\'em_advset\') ? $.cookie(\'em_advset\') : \'\');', '//$("#advset").css(\'display\', $.cookie(\'em_advset\') ? $.cookie(\'em_advset\') : \'\');', $file_content); 27 | fclose($file_1); 28 | 29 | $file_2 = fopen($file_path, 'w+'); 30 | fwrite($file_2, $file_content); 31 | fclose($file_2); 32 | } 33 | 34 | // 更改上传插入页面代码,采用新方式插入 35 | rename(EMLOG_ROOT.'/admin/views/attlib.php', EMLOG_ROOT.'/admin/views/attlib_old.php'); 36 | copy(EMLOG_ROOT.'/content/plugins/johnlui_markdown/attlib.php', EMLOG_ROOT.'/admin/views/attlib.php'); 37 | } 38 | 39 | function callback_rm() { 40 | 41 | // 文件复原 》》 消除 js 错误 42 | $files_path = array(EMLOG_ROOT.'/admin/views/add_log.php', EMLOG_ROOT.'/admin/views/edit_log.php'); 43 | foreach ($files_path as $file_path) { 44 | 45 | $file_1 = fopen($file_path, 'r+'); 46 | $file_content = fread($file_1, filesize($file_path)); 47 | $file_content = str_replace('
    文章摘要:由于编辑器与系统 jQuery 版本冲突,无法显示。
    ', '
    文章摘要:
    ', $file_content); 48 | $file_content = str_replace('//$("#advset").css(\'display\', $.cookie(\'em_advset\') ? $.cookie(\'em_advset\') : \'\');', '$("#advset").css(\'display\', $.cookie(\'em_advset\') ? $.cookie(\'em_advset\') : \'\');', $file_content); 49 | fclose($file_1); 50 | 51 | $file_2 = fopen($file_path, 'w+'); 52 | fwrite($file_2, $file_content); 53 | fclose($file_2); 54 | } 55 | 56 | // 文件复原 》》 更改上传插入页面代码,采用新方式插入 57 | rename(EMLOG_ROOT.'/admin/views/attlib_old.php', EMLOG_ROOT.'/admin/views/attlib.php'); 58 | } -------------------------------------------------------------------------------- /johnlui_markdown/johnlui_markdown_html.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /johnlui_markdown/scripts/js/hotkeys.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | // AMD. Register as an anonymous module. 4 | define('simple-hotkeys', ["jquery", 5 | "simple-module"], function ($, SimpleModule) { 6 | return (root.returnExportsGlobal = factory($, SimpleModule)); 7 | }); 8 | } else if (typeof exports === 'object') { 9 | // Node. Does not work with strict CommonJS, but 10 | // only CommonJS-like enviroments that support module.exports, 11 | // like Node. 12 | module.exports = factory(require("jquery"), 13 | require("simple-module")); 14 | } else { 15 | root.simple = root.simple || {}; 16 | root.simple['hotkeys'] = factory(jQuery, 17 | SimpleModule); 18 | } 19 | }(this, function ($, SimpleModule) { 20 | 21 | var Hotkeys, hotkeys, 22 | __hasProp = {}.hasOwnProperty, 23 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 24 | 25 | Hotkeys = (function(_super) { 26 | __extends(Hotkeys, _super); 27 | 28 | function Hotkeys() { 29 | return Hotkeys.__super__.constructor.apply(this, arguments); 30 | } 31 | 32 | Hotkeys.count = 0; 33 | 34 | Hotkeys.keyNameMap = { 35 | 8: "Backspace", 36 | 9: "Tab", 37 | 13: "Enter", 38 | 16: "Shift", 39 | 17: "Control", 40 | 18: "Alt", 41 | 19: "Pause", 42 | 20: "CapsLock", 43 | 27: "Esc", 44 | 32: "Spacebar", 45 | 33: "PageUp", 46 | 34: "PageDown", 47 | 35: "End", 48 | 36: "Home", 49 | 37: "Left", 50 | 38: "Up", 51 | 39: "Right", 52 | 40: "Down", 53 | 45: "Insert", 54 | 46: "Del", 55 | 91: "Meta", 56 | 93: "Meta", 57 | 48: "0", 58 | 49: "1", 59 | 50: "2", 60 | 51: "3", 61 | 52: "4", 62 | 53: "5", 63 | 54: "6", 64 | 55: "7", 65 | 56: "8", 66 | 57: "9", 67 | 65: "A", 68 | 66: "B", 69 | 67: "C", 70 | 68: "D", 71 | 69: "E", 72 | 70: "F", 73 | 71: "G", 74 | 72: "H", 75 | 73: "I", 76 | 74: "J", 77 | 75: "K", 78 | 76: "L", 79 | 77: "M", 80 | 78: "N", 81 | 79: "O", 82 | 80: "P", 83 | 81: "Q", 84 | 82: "R", 85 | 83: "S", 86 | 84: "T", 87 | 85: "U", 88 | 86: "V", 89 | 87: "W", 90 | 88: "X", 91 | 89: "Y", 92 | 90: "Z", 93 | 96: "0", 94 | 97: "1", 95 | 98: "2", 96 | 99: "3", 97 | 100: "4", 98 | 101: "5", 99 | 102: "6", 100 | 103: "7", 101 | 104: "8", 102 | 105: "9", 103 | 106: "Multiply", 104 | 107: "Add", 105 | 109: "Subtract", 106 | 110: "Decimal", 107 | 111: "Divide", 108 | 112: "F1", 109 | 113: "F2", 110 | 114: "F3", 111 | 115: "F4", 112 | 116: "F5", 113 | 117: "F6", 114 | 118: "F7", 115 | 119: "F8", 116 | 120: "F9", 117 | 121: "F10", 118 | 122: "F11", 119 | 123: "F12", 120 | 124: "F13", 121 | 125: "F14", 122 | 126: "F15", 123 | 127: "F16", 124 | 128: "F17", 125 | 129: "F18", 126 | 130: "F19", 127 | 131: "F20", 128 | 132: "F21", 129 | 133: "F22", 130 | 134: "F23", 131 | 135: "F24", 132 | 59: ";", 133 | 61: "=", 134 | 186: ";", 135 | 187: "=", 136 | 188: ",", 137 | 190: ".", 138 | 191: "/", 139 | 192: "`", 140 | 219: "[", 141 | 220: "\\", 142 | 221: "]", 143 | 222: "'" 144 | }; 145 | 146 | Hotkeys.aliases = { 147 | "escape": "esc", 148 | "delete": "del", 149 | "return": "enter", 150 | "ctrl": "control", 151 | "space": "spacebar", 152 | "ins": "insert", 153 | "cmd": "meta", 154 | "command": "meta", 155 | "wins": "meta", 156 | "windows": "meta" 157 | }; 158 | 159 | Hotkeys.normalize = function(shortcut) { 160 | var i, key, keyname, keys, _i, _len; 161 | keys = shortcut.toLowerCase().replace(/\s+/gi, "").split("+"); 162 | for (i = _i = 0, _len = keys.length; _i < _len; i = ++_i) { 163 | key = keys[i]; 164 | keys[i] = this.aliases[key] || key; 165 | } 166 | keyname = keys.pop(); 167 | keys.sort().push(keyname); 168 | return keys.join("_"); 169 | }; 170 | 171 | Hotkeys.prototype.opts = { 172 | el: document 173 | }; 174 | 175 | Hotkeys.prototype._init = function() { 176 | this.id = ++this.constructor.count; 177 | this._map = {}; 178 | this._delegate = typeof this.opts.el === "string" ? document : this.opts.el; 179 | return $(this._delegate).on("keydown.simple-hotkeys-" + this.id, this.opts.el, (function(_this) { 180 | return function(e) { 181 | var _ref; 182 | return (_ref = _this._getHander(e)) != null ? _ref.call(_this, e) : void 0; 183 | }; 184 | })(this)); 185 | }; 186 | 187 | Hotkeys.prototype._getHander = function(e) { 188 | var keyname, shortcut; 189 | if (!(keyname = this.constructor.keyNameMap[e.which])) { 190 | return; 191 | } 192 | shortcut = ""; 193 | if (e.altKey) { 194 | shortcut += "alt_"; 195 | } 196 | if (e.ctrlKey) { 197 | shortcut += "control_"; 198 | } 199 | if (e.metaKey) { 200 | shortcut += "meta_"; 201 | } 202 | if (e.shiftKey) { 203 | shortcut += "shift_"; 204 | } 205 | shortcut += keyname.toLowerCase(); 206 | return this._map[shortcut]; 207 | }; 208 | 209 | Hotkeys.prototype.respondTo = function(subject) { 210 | if (typeof subject === 'string') { 211 | return this._map[this.constructor.normalize(subject)] != null; 212 | } else { 213 | return this._getHander(subject) != null; 214 | } 215 | }; 216 | 217 | Hotkeys.prototype.add = function(shortcut, handler) { 218 | this._map[this.constructor.normalize(shortcut)] = handler; 219 | return this; 220 | }; 221 | 222 | Hotkeys.prototype.remove = function(shortcut) { 223 | delete this._map[this.constructor.normalize(shortcut)]; 224 | return this; 225 | }; 226 | 227 | Hotkeys.prototype.destroy = function() { 228 | $(this._delegate).off(".simple-hotkeys-" + this.id); 229 | this._map = {}; 230 | return this; 231 | }; 232 | 233 | return Hotkeys; 234 | 235 | })(SimpleModule); 236 | 237 | hotkeys = function(opts) { 238 | return new Hotkeys(opts); 239 | }; 240 | 241 | 242 | return hotkeys; 243 | 244 | 245 | })); 246 | -------------------------------------------------------------------------------- /johnlui_markdown/scripts/js/module.min.js: -------------------------------------------------------------------------------- 1 | !function(a,b){"function"==typeof define&&define.amd?define("simple-module",["jquery"],function(c){return a.returnExportsGlobal=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):a.SimpleModule=b(jQuery)}(this,function(a){var b,c=[].slice;return b=function(){function b(b){var c,d,e,f,g,h,i;if(this.opts=a.extend({},this.opts,b),(g=this.constructor)._connectedClasses||(g._connectedClasses=[]),e=function(){var a,b,d,e;for(d=this.constructor._connectedClasses,e=[],a=0,b=d.length;b>a;a++)c=d[a],f=c.pluginName.charAt(0).toLowerCase()+c.pluginName.slice(1),c.prototype._connected&&(c.prototype._module=this),e.push(this[f]=new c);return e}.call(this),this._connected)this.opts=a.extend({},this.opts,this._module.opts);else for(this._init(),h=0,i=e.length;i>h;h++)d=e[h],"function"==typeof d._init&&d._init();this.trigger("initialized")}return b.extend=function(a){var b,c,d;if(null!=a&&"object"==typeof a){for(b in a)c=a[b],"included"!==b&&"extended"!==b&&(this[b]=c);return null!=(d=a.extended)?d.call(this):void 0}},b.include=function(a){var b,c,d;if(null!=a&&"object"==typeof a){for(b in a)c=a[b],"included"!==b&&"extended"!==b&&(this.prototype[b]=c);return null!=(d=a.included)?d.call(this):void 0}},b.connect=function(a){if("function"==typeof a){if(!a.pluginName)throw new Error("Module.connect: cannot connect plugin without pluginName");return a.prototype._connected=!0,this._connectedClasses||(this._connectedClasses=[]),this._connectedClasses.push(a),a.pluginName?this[a.pluginName]=a:void 0}},b.prototype.opts={},b.prototype._init=function(){},b.prototype.on=function(){var b,d;return b=1<=arguments.length?c.call(arguments,0):[],(d=a(this)).on.apply(d,b),this},b.prototype.one=function(){var b,d;return b=1<=arguments.length?c.call(arguments,0):[],(d=a(this)).one.apply(d,b),this},b.prototype.off=function(){var b,d;return b=1<=arguments.length?c.call(arguments,0):[],(d=a(this)).off.apply(d,b),this},b.prototype.trigger=function(){var b,d;return b=1<=arguments.length?c.call(arguments,0):[],(d=a(this)).trigger.apply(d,b),this},b.prototype.triggerHandler=function(){var b,d;return b=1<=arguments.length?c.call(arguments,0):[],(d=a(this)).triggerHandler.apply(d,b)},b.prototype._t=function(){var a,b;return a=1<=arguments.length?c.call(arguments,0):[],(b=this.constructor)._t.apply(b,a)},b._t=function(){var a,b,d,e;return b=arguments[0],a=2<=arguments.length?c.call(arguments,1):[],d=(null!=(e=this.i18n[this.locale])?e[b]:void 0)||"",a.length>0?(d=d.replace(/([^%]|^)%(?:(\d+)\$)?s/g,function(b,c,d){return d?c+a[parseInt(d)-1]:c+a.shift()}),d.replace(/%%s/g,"%s")):d},b.i18n={"zh-CN":{}},b.locale="zh-CN",b}()}); -------------------------------------------------------------------------------- /johnlui_markdown/scripts/js/simditor-markdown.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | // AMD. Register as an anonymous module unless amdModuleId is set 4 | define('simditor-markdown', ["jquery","simple-module","simditor"], function ($, SimpleModule, Simditor) { 5 | return (root['SimditorMarkdown'] = factory($, SimpleModule, Simditor)); 6 | }); 7 | } else if (typeof exports === 'object') { 8 | // Node. Does not work with strict CommonJS, but 9 | // only CommonJS-like environments that support module.exports, 10 | // like Node. 11 | module.exports = factory(require("jquery"),require("simple-module"),require("simditor")); 12 | } else { 13 | root['SimditorMarkdown'] = factory(jQuery,SimpleModule,Simditor); 14 | } 15 | }(this, function ($, SimpleModule, Simditor) { 16 | 17 | var SimditorMarkdown, 18 | extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 19 | hasProp = {}.hasOwnProperty; 20 | 21 | SimditorMarkdown = (function(superClass) { 22 | extend(SimditorMarkdown, superClass); 23 | 24 | function SimditorMarkdown() { 25 | return SimditorMarkdown.__super__.constructor.apply(this, arguments); 26 | } 27 | 28 | SimditorMarkdown.pluginName = 'Markdown'; 29 | 30 | SimditorMarkdown.prototype.opts = { 31 | markdown: false 32 | }; 33 | 34 | SimditorMarkdown.prototype._init = function() { 35 | var hooks; 36 | if (!this.opts.markdown) { 37 | return; 38 | } 39 | this.editor = this._module; 40 | if (typeof this.opts.markdown === "object") { 41 | hooks = $.extend({}, this.hooks, this.opts.markdown); 42 | } else { 43 | hooks = $.extend({}, this.hooks); 44 | } 45 | return this.editor.on("keypress", (function(_this) { 46 | return function(e) { 47 | var $blockEl, button, cmdEnd, cmdStart, container, content, hook, match, name, range, result, testRange; 48 | if (!(e.which === 32 || e.which === 13)) { 49 | return; 50 | } 51 | range = _this.editor.selection.getRange(); 52 | container = range != null ? range.commonAncestorContainer : void 0; 53 | if (!(range && range.collapsed && container && container.nodeType === 3 && !$(container).parent("pre").length)) { 54 | return; 55 | } 56 | content = container.textContent; 57 | for (name in hooks) { 58 | hook = hooks[name]; 59 | if (e.which === 13 && !hook.enterKey) { 60 | return; 61 | } 62 | if (!(hook && hook.cmd instanceof RegExp)) { 63 | continue; 64 | } 65 | match = content.match(hook.cmd); 66 | if (!match) { 67 | continue; 68 | } 69 | button = _this.editor.toolbar.findButton(name); 70 | if (button === null || button.disabled) { 71 | continue; 72 | } 73 | if (hook.block) { 74 | $blockEl = _this.editor.util.closestBlockEl(container); 75 | testRange = document.createRange(); 76 | testRange.setStart(container, 0); 77 | testRange.collapse(true); 78 | if (!_this.editor.selection.rangeAtStartOf($blockEl, testRange)) { 79 | continue; 80 | } 81 | } 82 | cmdStart = match.index; 83 | cmdEnd = match[0].length + match.index; 84 | range.setStart(container, cmdStart); 85 | range.setEnd(container, cmdEnd); 86 | if (hook.block) { 87 | range.deleteContents(); 88 | if (_this.editor.util.isEmptyNode($blockEl)) { 89 | $blockEl.append(_this.editor.util.phBr); 90 | } 91 | _this.editor.selection.setRangeAtEndOf($blockEl); 92 | } 93 | result = hook.callback.call(_this, button, hook, range, match, $blockEl); 94 | if ((e.which === 32 || name === "code") && result) { 95 | e.preventDefault(); 96 | } 97 | break; 98 | } 99 | }; 100 | })(this)); 101 | }; 102 | 103 | SimditorMarkdown.prototype.hooks = { 104 | title: { 105 | cmd: /^#+/, 106 | block: true, 107 | enterKey: true, 108 | callback: function(button, hook, range, match, $blockEl) { 109 | var level; 110 | level = Math.min(match[0].length, 3); 111 | return button.command("h" + level); 112 | } 113 | }, 114 | blockquote: { 115 | cmd: /^>{1}/, 116 | block: true, 117 | enterKey: true, 118 | callback: function(button, hook, range, match, $blockEl) { 119 | return button.command(); 120 | } 121 | }, 122 | code: { 123 | cmd: /^`{3}/, 124 | block: true, 125 | enterKey: true, 126 | callback: function(button, hook, range, match, $blockEl) { 127 | return button.command(); 128 | } 129 | }, 130 | hr: { 131 | cmd: /^\*{3,}$|^\-{3,}$/, 132 | block: true, 133 | enterKey: true, 134 | callback: function(button, hook, range, match, $blockEl) { 135 | return button.command(); 136 | } 137 | }, 138 | bold: { 139 | cmd: /\*{2}([^\*]+)\*{2}$|_{2}([^_]+)_{2}$/, 140 | block: false, 141 | callback: function(button, hook, range, match) { 142 | var text, textNode; 143 | text = match[1] || match[2]; 144 | textNode = document.createTextNode(text); 145 | this.editor.selection.selectRange(range); 146 | range.deleteContents(); 147 | range.insertNode(textNode); 148 | range.selectNode(textNode); 149 | this.editor.selection.selectRange(range); 150 | document.execCommand("bold"); 151 | this.editor.selection.setRangeAfter(textNode); 152 | document.execCommand("bold"); 153 | this.editor.trigger("valuechanged"); 154 | return this.editor.trigger("selectionchanged"); 155 | } 156 | }, 157 | italic: { 158 | cmd: /\*([^\*]+)\*$/, 159 | block: false, 160 | callback: function(button, hook, range, match) { 161 | var text, textNode; 162 | text = match[1] || match[2]; 163 | textNode = document.createTextNode(text); 164 | this.editor.selection.selectRange(range); 165 | range.deleteContents(); 166 | range.insertNode(textNode); 167 | range.selectNode(textNode); 168 | this.editor.selection.selectRange(range); 169 | document.execCommand("italic"); 170 | this.editor.selection.setRangeAfter(textNode); 171 | document.execCommand("italic"); 172 | this.editor.trigger("valuechanged"); 173 | return this.editor.trigger("selectionchanged"); 174 | } 175 | }, 176 | ul: { 177 | cmd: /^\*{1}$|^\+{1}$|^\-{1}$/, 178 | block: true, 179 | callback: function(button, hook, range, match, $blockEl) { 180 | return button.command(); 181 | } 182 | }, 183 | ol: { 184 | cmd: /^[0-9][\.\u3002]{1}$/, 185 | block: true, 186 | callback: function(button, hook, range, match, $blockEl) { 187 | return button.command(); 188 | } 189 | }, 190 | image: { 191 | cmd: /!\[(.+)\]\((.+)\)$/, 192 | block: true, 193 | callback: function(button, hook, range, match) { 194 | return button.command(match[2]); 195 | } 196 | }, 197 | link: { 198 | cmd: /\[(.+)\]\((.+)\)$|\<((.[^\[\]\(\)]+))\>$/, 199 | block: false, 200 | callback: function(hook, range, match) { 201 | var $link, url; 202 | url = match[2] || match[4]; 203 | if (!/[a-zA-z]+:\/\/[^\s]*/.test(url)) { 204 | return false; 205 | } 206 | $link = $("", { 207 | text: match[1] || match[3], 208 | href: url, 209 | target: "_blank" 210 | }); 211 | this.editor.selection.selectRange(range); 212 | range.deleteContents(); 213 | range.insertNode($link[0]); 214 | this.editor.selection.setRangeAfter($link); 215 | this.editor.trigger("valuechanged"); 216 | return this.editor.trigger("selectionchanged"); 217 | } 218 | } 219 | }; 220 | 221 | return SimditorMarkdown; 222 | 223 | })(SimpleModule); 224 | 225 | Simditor.connect(SimditorMarkdown); 226 | 227 | return SimditorMarkdown; 228 | 229 | })); -------------------------------------------------------------------------------- /johnlui_markdown/scripts/js/simditor.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Simditor v2.1.5 3 | * http://simditor.tower.im/ 4 | * 2015-07-03 5 | */ 6 | !function(a,b){"function"==typeof define&&define.amd?define("simditor",["jquery","simple-module","simple-hotkeys","simple-uploader"],function(c,d,e,f){return a.Simditor=b(c,d,e,f)}):"object"==typeof exports?module.exports=b(require("jquery"),require("simple-module"),require("simple-hotkeys"),require("simple-uploader")):a.Simditor=b(jQuery,SimpleModule,simple.hotkeys,simple.uploader)}(this,function(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J=function(a,b){function c(){this.constructor=a}for(var d in b)K.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},K={}.hasOwnProperty,L=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},M=[].slice;return y=function(b){function c(){return c.__super__.constructor.apply(this,arguments)}return J(c,b),c.pluginName="Selection",c.prototype._init=function(){return this.editor=this._module,this.sel=document.getSelection()},c.prototype.clear=function(){var a;try{return this.sel.removeAllRanges()}catch(b){a=b}},c.prototype.getRange=function(){return this.editor.inputManager.focused&&this.sel.rangeCount?this.sel.getRangeAt(0):null},c.prototype.selectRange=function(a){return this.clear(),this.sel.addRange(a),this.editor.inputManager.focused||!this.editor.util.browser.firefox&&!this.editor.util.browser.msie||this.editor.body.focus(),a},c.prototype.rangeAtEndOf=function(b,c){var d,e,f;return null==c&&(c=this.getRange()),null!=c&&c.collapsed?(b=a(b)[0],d=c.endContainer,e=this.editor.util.getNodeLength(d),c.endOffset===e-1&&a(d).contents().last().is("br")||c.endOffset===e?b===d?!0:a.contains(b,d)?(f=!0,a(d).parentsUntil(b).addBack().each(function(){return function(b,c){var d,e;return e=a(c).parent().contents().filter(function(){return!(this!==c&&3===this.nodeType&&!this.nodeValue)}),d=e.last(),d.get(0)===c||d.is("br")&&d.prev().get(0)===c?void 0:(f=!1,!1)}}(this)),f):!1:!1):void 0},c.prototype.rangeAtStartOf=function(b,c){var d,e;return null==c&&(c=this.getRange()),null!=c&&c.collapsed?(b=a(b)[0],e=c.startContainer,0!==c.startOffset?!1:b===e?!0:a.contains(b,e)?(d=!0,a(e).parentsUntil(b).addBack().each(function(){return function(b,c){var e;return e=a(c).parent().contents().filter(function(){return!(this!==c&&3===this.nodeType&&!this.nodeValue)}),e.first().get(0)!==c?d=!1:void 0}}(this)),d):!1):void 0},c.prototype.insertNode=function(b,c){return null==c&&(c=this.getRange()),null!=c?(b=a(b)[0],c.insertNode(b),this.setRangeAfter(b,c)):void 0},c.prototype.setRangeAfter=function(b,c){return null==c&&(c=this.getRange()),null!=c?(b=a(b)[0],c.setEndAfter(b),c.collapse(!1),this.selectRange(c)):void 0},c.prototype.setRangeBefore=function(b,c){return null==c&&(c=this.getRange()),null!=c?(b=a(b)[0],c.setEndBefore(b),c.collapse(!1),this.selectRange(c)):void 0},c.prototype.setRangeAtStartOf=function(b,c){return null==c&&(c=this.getRange()),b=a(b).get(0),c.setEnd(b,0),c.collapse(!1),this.selectRange(c)},c.prototype.setRangeAtEndOf=function(b,c){var d,e,f,g,h,i;return null==c&&(c=this.getRange()),e=a(b),b=e.get(0),e.is("pre")?(f=e.contents(),f.length>0?(g=f.last(),h=g.text(),"\n"===h.charAt(h.length-1)?c.setEnd(g[0],this.editor.util.getNodeLength(g[0])-1):c.setEnd(g[0],this.editor.util.getNodeLength(g[0]))):c.setEnd(b,0)):(i=this.editor.util.getNodeLength(b),3!==b.nodeType&&i>0&&(d=a(b).contents().last(),d.is("br")?i-=1:3!==d[0].nodeType&&this.editor.util.isEmptyNode(d)&&(d.append(this.editor.util.phBr),b=d[0],i=0)),c.setEnd(b,i)),c.collapse(!1),this.selectRange(c)},c.prototype.deleteRangeContents=function(a){var b,c;return null==a&&(a=this.getRange()),c=a.cloneRange(),b=a.cloneRange(),c.collapse(!0),b.collapse(!1),!a.collapsed&&this.rangeAtStartOf(this.editor.body,c)&&this.rangeAtEndOf(this.editor.body,b)?(this.editor.body.empty(),a.setStart(this.editor.body[0],0),a.collapse(!0),this.selectRange(a)):a.deleteContents(),a},c.prototype.breakBlockEl=function(b,c){var d;return null==c&&(c=this.getRange()),d=a(b),c.collapsed?(c.setStartBefore(d.get(0)),c.collapsed?d:d.before(c.extractContents())):d},c.prototype.save=function(b){var c,d,e;return null==b&&(b=this.getRange()),this._selectionSaved?void 0:(d=b.cloneRange(),d.collapse(!1),e=a("").addClass("simditor-caret-start"),c=a("").addClass("simditor-caret-end"),d.insertNode(c[0]),b.insertNode(e[0]),this.clear(),this._selectionSaved=!0)},c.prototype.restore=function(){var a,b,c,d,e,f,g;return this._selectionSaved?(e=this.editor.body.find(".simditor-caret-start"),a=this.editor.body.find(".simditor-caret-end"),e.length&&a.length?(f=e.parent(),g=f.contents().index(e),b=a.parent(),c=b.contents().index(a),f[0]===b[0]&&(c-=1),d=document.createRange(),d.setStart(f.get(0),g),d.setEnd(b.get(0),c),e.remove(),a.remove(),this.selectRange(d)):(e.remove(),a.remove()),this._selectionSaved=!1,d):!1},c}(b),k=function(b){function c(){return c.__super__.constructor.apply(this,arguments)}return J(c,b),c.pluginName="Formatter",c.prototype.opts={allowedTags:null,allowedAttributes:null},c.prototype._init=function(){return this.editor=this._module,this._allowedTags=this.opts.allowedTags||["br","a","img","b","strong","i","u","font","p","ul","ol","li","blockquote","pre","h1","h2","h3","h4","hr"],this._allowedAttributes=this.opts.allowedAttributes||{img:["src","alt","width","height","data-image-src","data-image-size","data-image-name","data-non-image"],a:["href","target"],font:["color"],pre:["data-lang","class"],p:["data-indent"],h1:["data-indent"],h2:["data-indent"],h3:["data-indent"],h4:["data-indent"]},this.editor.body.on("click","a",function(){return function(){return!1}}(this))},c.prototype.decorate=function(a){return null==a&&(a=this.editor.body),this.editor.trigger("decorate",[a])},c.prototype.undecorate=function(b){return null==b&&(b=this.editor.body.clone()),this.editor.trigger("undecorate",[b]),a.trim(b.html())},c.prototype.autolink=function(b){var c,d,e,f,g,h,i,j,k,l,m;for(null==b&&(b=this.editor.body),h=[],d=function(c){return c.contents().each(function(c,e){var f,g;return f=a(e),f.is("a")||f.closest("a, pre",b).length?void 0:f.contents().length?d(f):(g=f.text())&&/https?:\/\/|www\./gi.test(g)?h.push(f):void 0})},d(b),j=/(https?:\/\/|www\.)[\w\-\.\?&=\/#%:,@\!\+]+/gi,e=0,g=h.length;g>e;e++){for(c=h[e],l=c.text(),k=[],i=null,f=0;null!==(i=j.exec(l));)k.push(document.createTextNode(l.substring(f,i.index))),f=j.lastIndex,m=/^(http(s)?:\/\/|\/)/.test(i[0])?i[0]:"http://"+i[0],k.push(a('').text(i[0])[0]);k.push(document.createTextNode(l.substring(f))),c.replaceWith(a(k))}return b},c.prototype.format=function(b){var c,d,e,f,g,h,i,j,k,l;if(null==b&&(b=this.editor.body),b.is(":empty"))return b.append("

    "+this.editor.util.phBr+"

    "),b;for(k=b.contents(),e=0,g=k.length;g>e;e++)i=k[e],this.cleanNode(i,!0);for(l=b.contents(),f=0,h=l.length;h>f;f++)j=l[f],c=a(j),c.is("br")?("undefined"!=typeof d&&null!==d&&(d=null),c.remove()):this.editor.util.isBlockNode(j)?c.is("li")?d&&d.is("ul, ol")?d.append(j):(d=a("