From 8218391cfd49ede10e7d06e79b9372fc351117fe Mon Sep 17 00:00:00 2001 From: Wes Cossick Date: Tue, 1 Sep 2015 20:26:52 -0500 Subject: [PATCH] Gulp now pretty formats JS and CSS --- gulpfile.js | 16 +- package.json | 2 +- src/css/simplemde.css | 33 +- src/js/simplemde.js | 107 ++-- src/js/test/simplemde.js | 1150 -------------------------------------- 5 files changed, 86 insertions(+), 1222 deletions(-) delete mode 100644 src/js/test/simplemde.js diff --git a/gulpfile.js b/gulpfile.js index 7a2455b..1dd6ec5 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -4,7 +4,7 @@ var gulp = require('gulp'), concat = require('gulp-concat'), header = require('gulp-header'), pkg = require('./package.json'), - beautify = require('gulp-beautify'); + prettify = require('gulp-jsbeautifier'); var banner = ['/**', ' * <%= pkg.name %> v<%= pkg.version %>', @@ -46,10 +46,16 @@ gulp.task('styles', function() { .pipe(gulp.dest('dist')); }); -gulp.task('beautify', function() { +gulp.task('prettify-js', function() { gulp.src('./src/js/simplemde.js') - .pipe(beautify({indentSize: 4})) - .pipe(gulp.dest('./src/js/test')) + .pipe(prettify({js: {braceStyle: "collapse", indentChar: "\t", indentSize: 1, maxPreserveNewlines: 3, spaceBeforeConditional: false}})) + .pipe(gulp.dest('./src/js')); +}); + +gulp.task('prettify-css', function() { + gulp.src('./src/css/simplemde.css') + .pipe(prettify({css: {indentChar: "\t", indentSize: 1}})) + .pipe(gulp.dest('./src/css')); }); -gulp.task('default', ['scripts', 'styles', 'beautify']); \ No newline at end of file +gulp.task('default', ['scripts', 'styles', 'prettify-js', 'prettify-css']); \ No newline at end of file diff --git a/package.json b/package.json index 594c50a..702ace1 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "gulp-uglify": "*", "gulp-concat": "*", "gulp-header": "*", - "gulp-beautify": "*" + "gulp-jsbeautifier": "*" }, "repository": { "type": "git", diff --git a/src/css/simplemde.css b/src/css/simplemde.css index b273a41..c51657e 100644 --- a/src/css/simplemde.css +++ b/src/css/simplemde.css @@ -13,7 +13,7 @@ } .CodeMirror-fullscreen { - background:#fff; + background: #fff; position: fixed !important; top: 50px; left: 0; @@ -43,7 +43,8 @@ border-top-right-radius: 4px; } -.editor-toolbar:after, .editor-toolbar:before { +.editor-toolbar:after, +.editor-toolbar:before { display: block; content: ' '; height: 1px; @@ -57,7 +58,9 @@ margin-top: 8px } -.editor-toolbar:hover, .editor-wrapper input.title:focus, .editor-wrapper input.title:hover { +.editor-toolbar:hover, +.editor-wrapper input.title:focus, +.editor-wrapper input.title:hover { opacity: .8 } @@ -89,7 +92,8 @@ cursor: pointer; } -.editor-toolbar a.active, .editor-toolbar a:hover { +.editor-toolbar a.active, +.editor-toolbar a:hover { background: #fcfcfc; border-color: #95a5a6; } @@ -112,8 +116,8 @@ font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 65%; vertical-align: text-bottom; - position:relative; - top:2px; + position: relative; + top: 2px; } .editor-toolbar a.fa-header-1:after { @@ -157,8 +161,8 @@ .editor-preview { padding: 10px; position: absolute; - width:100%; - height:100%; + width: 100%; + height: 100%; top: 0; left: 0; background: #fafafa; @@ -184,23 +188,28 @@ } .editor-preview-active-side { - display: block + display: block } .editor-preview-active { display: block } -.editor-preview>p, .editor-preview-side>p { +.editor-preview>p, +.editor-preview-side>p { margin-top: 0 } -.editor-preview pre, .editor-preview-side pre { +.editor-preview pre, +.editor-preview-side pre { background: #eee; margin-bottom: 10px; } -.editor-preview table td, .editor-preview table th, .editor-preview-side table td, .editor-preview-side table th { +.editor-preview table td, +.editor-preview table th, +.editor-preview-side table td, +.editor-preview-side table th { border: 1px solid #ddd; padding: 5px; } diff --git a/src/js/simplemde.js b/src/js/simplemde.js index b827963..5baa6ca 100644 --- a/src/js/simplemde.js +++ b/src/js/simplemde.js @@ -101,18 +101,18 @@ function toggleFullScreen(editor) { // Set fullscreen var cm = editor.codemirror; cm.setOption("fullScreen", !cm.getOption("fullScreen")); - - + + // Update toolbar class var wrap = cm.getWrapperElement(); - + if(!/fullscreen/.test(wrap.previousSibling.className)) { wrap.previousSibling.className += " fullscreen"; } else { wrap.previousSibling.className = wrap.previousSibling.className.replace(/\s*fullscreen\b/, ""); } - + // Update toolbar button var toolbarButton = editor.toolbarElements.fullscreen; @@ -121,11 +121,11 @@ function toggleFullScreen(editor) { } else { toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); } - - + + // Hide side by side if needed var sidebyside = cm.getWrapperElement().nextSibling; - if (/editor-preview-active-side/.test(sidebyside.className)) + if(/editor-preview-active-side/.test(sidebyside.className)) toggleSideBySide(editor); } @@ -287,7 +287,7 @@ function toggleSideBySide(editor) { var preview = wrapper.nextSibling; var toolbarButton = editor.toolbarElements["side-by-side"]; - if (/editor-preview-active-side/.test(preview.className)) { + if(/editor-preview-active-side/.test(preview.className)) { preview.className = preview.className.replace( /\s*editor-preview-active-side\s*/g, '' ); @@ -295,17 +295,17 @@ function toggleSideBySide(editor) { wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); } else { /* When the preview button is clicked for the first time, - * give some time for the transition from editor.css to fire and the view to slide from right to left, - * instead of just appearing. - */ + * give some time for the transition from editor.css to fire and the view to slide from right to left, + * instead of just appearing. + */ setTimeout(function() { - if (!cm.getOption("fullScreen")) toggleFullScreen(editor); + if(!cm.getOption("fullScreen")) toggleFullScreen(editor); preview.className += ' editor-preview-active-side' }, 1); toolbarButton.className += ' active'; wrapper.className += ' CodeMirror-sided'; } - + // Hide normal preview if active var previewNormal = wrapper.lastChild; if(/editor-preview-active/.test(previewNormal.className)) { @@ -363,10 +363,10 @@ function togglePreview(editor) { } var text = cm.getValue(); preview.innerHTML = parse(text); - + // Turn off side by side if needed var sidebyside = cm.getWrapperElement().nextSibling; - if (/editor-preview-active-side/.test(sidebyside.className)) + if(/editor-preview-active-side/.test(sidebyside.className)) toggleSideBySide(editor); } @@ -407,62 +407,53 @@ function _toggleHeading(cm, direction, size) { (function(i) { var text = cm.getLine(i); var currHeadingLevel = text.search(/[^#]/); - - if(direction !== undefined){ - if (currHeadingLevel <= 0) { - if (direction == 'bigger') { + + if(direction !== undefined) { + if(currHeadingLevel <= 0) { + if(direction == 'bigger') { text = '###### ' + text; } else { text = '# ' + text; } - } else if (currHeadingLevel == 6 && direction == 'smaller') { + } else if(currHeadingLevel == 6 && direction == 'smaller') { text = text.substr(7); - } else if (currHeadingLevel == 1 && direction == 'bigger') { + } else if(currHeadingLevel == 1 && direction == 'bigger') { text = text.substr(2); } else { - if (direction == 'bigger') { + if(direction == 'bigger') { text = text.substr(1); } else { text = '#' + text; } } - } - else{ - if(size == 1){ - if (currHeadingLevel <= 0) { + } else { + if(size == 1) { + if(currHeadingLevel <= 0) { text = '# ' + text; - } - else if(currHeadingLevel == size){ + } else if(currHeadingLevel == size) { text = text.substr(currHeadingLevel + 1); - } - else{ + } else { text = '# ' + text.substr(currHeadingLevel + 1); } - } - else if(size == 2){ - if (currHeadingLevel <= 0) { + } else if(size == 2) { + if(currHeadingLevel <= 0) { text = '## ' + text; - } - else if(currHeadingLevel == size){ + } else if(currHeadingLevel == size) { text = text.substr(currHeadingLevel + 1); - } - else{ + } else { text = '## ' + text.substr(currHeadingLevel + 1); } - } - else{ - if (currHeadingLevel <= 0) { + } else { + if(currHeadingLevel <= 0) { text = '### ' + text; - } - else if(currHeadingLevel == size){ + } else if(currHeadingLevel == size) { text = text.substr(currHeadingLevel + 1); - } - else{ + } else { text = '### ' + text.substr(currHeadingLevel + 1); } } } - + cm.replaceRange(text, { line: i, ch: 0 @@ -719,7 +710,7 @@ var toolbarBuiltInButtons = { } }; -var toolbar = ["bold", "italic", "heading", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "|", "preview", "side-by-side", "fullscreen", "guide"]; +var toolbar = ["bold", "italic", "heading", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "|", "preview", "side-by-side", "fullscreen", "guide"]; /** * Interface of SimpleMDE. @@ -762,12 +753,12 @@ SimpleMDE.toolbar = toolbar; SimpleMDE.markdown = function(text) { if(window.marked) { // Update options - if(this.options.singleLineBreaks !== false){ + if(this.options.singleLineBreaks !== false) { marked.setOptions({ breaks: true }); } - + return marked(text); } }; @@ -842,7 +833,7 @@ SimpleMDE.prototype.render = function(el) { if(options.autosave != undefined && options.autosave.enabled === true) { this.autosave(); } - + this.createSidebyside(); this._rendered = this.element; @@ -903,7 +894,7 @@ SimpleMDE.prototype.createSidebyside = function() { var wrapper = cm.getWrapperElement(); var preview = wrapper.nextSibling; - if (!/editor-preview-side/.test(preview.className)) { + if(!/editor-preview-side/.test(preview.className)) { preview = document.createElement('div'); preview.className = 'editor-preview-side'; wrapper.parentNode.insertBefore(preview, wrapper.nextSibling); @@ -913,7 +904,11 @@ SimpleMDE.prototype.createSidebyside = function() { var cScroll = false; var pScroll = false; cm.on('scroll', function(v) { - if (cScroll){cScroll=false; return;}; pScroll=true; + if(cScroll) { + cScroll = false; + return; + }; + pScroll = true; height = v.getScrollInfo().height - v.getScrollInfo().clientHeight; ratio = parseFloat(v.getScrollInfo().top) / height; move = (preview.scrollHeight - preview.clientHeight) * ratio; @@ -922,7 +917,11 @@ SimpleMDE.prototype.createSidebyside = function() { // Syncs scroll preview -> editor preview.onscroll = function(v) { - if (pScroll){pScroll=false; return;}; cScroll=true; + if(pScroll) { + pScroll = false; + return; + }; + cScroll = true; height = preview.scrollHeight - preview.clientHeight; ratio = parseFloat(preview.scrollTop) / height; move = (cm.getScrollInfo().height - cm.getScrollInfo().clientHeight) * ratio; @@ -937,9 +936,9 @@ SimpleMDE.prototype.createToolbar = function(items) { if(!items || items.length === 0) { return; } - + for(var i = 0; i < items.length; i++) { - if(toolbarBuiltInButtons[items[i]] != undefined){ + if(toolbarBuiltInButtons[items[i]] != undefined) { items[i] = toolbarBuiltInButtons[items[i]]; } } diff --git a/src/js/test/simplemde.js b/src/js/test/simplemde.js deleted file mode 100644 index b827963..0000000 --- a/src/js/test/simplemde.js +++ /dev/null @@ -1,1150 +0,0 @@ -var isMac = /Mac/.test(navigator.platform); - -var shortcuts = { - 'Cmd-B': toggleBold, - 'Cmd-I': toggleItalic, - 'Cmd-K': drawLink, - 'Cmd-H': toggleHeadingSmaller, - 'Shift-Cmd-H': toggleHeadingBigger, - 'Cmd-Alt-I': drawImage, - "Cmd-'": toggleBlockquote, - 'Cmd-Alt-L': toggleOrderedList, - 'Cmd-L': toggleUnorderedList, - 'Cmd-Alt-C': toggleCodeBlock, - 'Cmd-P': togglePreview, -}; - - -/** - * Fix shortcut. Mac use Command, others use Ctrl. - */ -function fixShortcut(name) { - if(isMac) { - name = name.replace('Ctrl', 'Cmd'); - } else { - name = name.replace('Cmd', 'Ctrl'); - } - return name; -} - - -/** - * Create icon element for toolbar. - */ -function createIcon(options, enableTooltips) { - options = options || {}; - var el = document.createElement('a'); - enableTooltips = (enableTooltips == undefined) ? true : enableTooltips; - - if(options.title && enableTooltips) { - el.title = options.title; - - if(isMac) { - el.title = el.title.replace('Ctrl', '⌘'); - el.title = el.title.replace('Alt', '⌥'); - } - } - - el.className = options.className; - return el; -} - -function createSep() { - el = document.createElement('i'); - el.className = 'separator'; - el.innerHTML = '|'; - return el; -} - - -/** - * The state of CodeMirror at the given position. - */ -function getState(cm, pos) { - pos = pos || cm.getCursor('start'); - var stat = cm.getTokenAt(pos); - if(!stat.type) return {}; - - var types = stat.type.split(' '); - - var ret = {}, - data, text; - for(var i = 0; i < types.length; i++) { - data = types[i]; - if(data === 'strong') { - ret.bold = true; - } else if(data === 'variable-2') { - text = cm.getLine(pos.line); - if(/^\s*\d+\.\s/.test(text)) { - ret['ordered-list'] = true; - } else { - ret['unordered-list'] = true; - } - } else if(data === 'atom') { - ret.quote = true; - } else if(data === 'em') { - ret.italic = true; - } else if(data === 'quote') { - ret.quote = true; - } else if(data === 'strikethrough') { - ret.strikethrough = true; - } - } - return ret; -} - - -/** - * Toggle full screen of the editor. - */ -function toggleFullScreen(editor) { - // Set fullscreen - var cm = editor.codemirror; - cm.setOption("fullScreen", !cm.getOption("fullScreen")); - - - // Update toolbar class - var wrap = cm.getWrapperElement(); - - if(!/fullscreen/.test(wrap.previousSibling.className)) { - wrap.previousSibling.className += " fullscreen"; - } else { - wrap.previousSibling.className = wrap.previousSibling.className.replace(/\s*fullscreen\b/, ""); - } - - - // Update toolbar button - var toolbarButton = editor.toolbarElements.fullscreen; - - if(!/active/.test(toolbarButton.className)) { - toolbarButton.className += " active"; - } else { - toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); - } - - - // Hide side by side if needed - var sidebyside = cm.getWrapperElement().nextSibling; - if (/editor-preview-active-side/.test(sidebyside.className)) - toggleSideBySide(editor); -} - - -/** - * Action for toggling bold. - */ -function toggleBold(editor) { - _toggleBlock(editor, 'bold', '**'); -} - - -/** - * Action for toggling italic. - */ -function toggleItalic(editor) { - _toggleBlock(editor, 'italic', '*'); -} - - -/** - * Action for toggling strikethrough. - */ -function toggleStrikethrough(editor) { - _toggleBlock(editor, 'strikethrough', '~~'); -} - -/** - * Action for toggling code block. - */ -function toggleCodeBlock(editor) { - _toggleBlock(editor, 'code', '```\r\n', '\r\n```'); -} - -/** - * Action for toggling blockquote. - */ -function toggleBlockquote(editor) { - var cm = editor.codemirror; - _toggleLine(cm, 'quote'); -} - -/** - * Action for toggling heading size: normal -> h1 -> h2 -> h3 -> h4 -> h5 -> h6 -> normal - */ -function toggleHeadingSmaller(editor) { - var cm = editor.codemirror; - _toggleHeading(cm, 'smaller'); -} - -/** - * Action for toggling heading size: normal -> h6 -> h5 -> h4 -> h3 -> h2 -> h1 -> normal - */ -function toggleHeadingBigger(editor) { - var cm = editor.codemirror; - _toggleHeading(cm, 'bigger'); -} - -/** - * Action for toggling heading size 1 - */ -function toggleHeading1(editor) { - var cm = editor.codemirror; - _toggleHeading(cm, undefined, 1); -} - -/** - * Action for toggling heading size 2 - */ -function toggleHeading2(editor) { - var cm = editor.codemirror; - _toggleHeading(cm, undefined, 2); -} - -/** - * Action for toggling heading size 3 - */ -function toggleHeading3(editor) { - var cm = editor.codemirror; - _toggleHeading(cm, undefined, 3); -} - - -/** - * Action for toggling ul. - */ -function toggleUnorderedList(editor) { - var cm = editor.codemirror; - _toggleLine(cm, 'unordered-list'); -} - - -/** - * Action for toggling ol. - */ -function toggleOrderedList(editor) { - var cm = editor.codemirror; - _toggleLine(cm, 'ordered-list'); -} - - -/** - * Action for drawing a link. - */ -function drawLink(editor) { - var cm = editor.codemirror; - var stat = getState(cm); - _replaceSelection(cm, stat.link, '[', '](http://)'); -} - - -/** - * Action for drawing an img. - */ -function drawImage(editor) { - var cm = editor.codemirror; - var stat = getState(cm); - _replaceSelection(cm, stat.image, '![](http://', ')'); -} - - -/** - * Action for drawing a horizontal rule. - */ -function drawHorizontalRule(editor) { - var cm = editor.codemirror; - var stat = getState(cm); - _replaceSelection(cm, stat.image, '', '\n\n-----\n\n'); -} - - -/** - * Undo action. - */ -function undo(editor) { - var cm = editor.codemirror; - cm.undo(); - cm.focus(); -} - - -/** - * Redo action. - */ -function redo(editor) { - var cm = editor.codemirror; - cm.redo(); - cm.focus(); -} - - -/** - * Toggle side by side preview - */ -function toggleSideBySide(editor) { - var cm = editor.codemirror; - var wrapper = cm.getWrapperElement(); - var code = wrapper.firstChild; - var preview = wrapper.nextSibling; - var toolbarButton = editor.toolbarElements["side-by-side"]; - - if (/editor-preview-active-side/.test(preview.className)) { - preview.className = preview.className.replace( - /\s*editor-preview-active-side\s*/g, '' - ); - toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); - wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); - } else { - /* When the preview button is clicked for the first time, - * give some time for the transition from editor.css to fire and the view to slide from right to left, - * instead of just appearing. - */ - setTimeout(function() { - if (!cm.getOption("fullScreen")) toggleFullScreen(editor); - preview.className += ' editor-preview-active-side' - }, 1); - toolbarButton.className += ' active'; - wrapper.className += ' CodeMirror-sided'; - } - - // Hide normal preview if active - var previewNormal = wrapper.lastChild; - if(/editor-preview-active/.test(previewNormal.className)) { - previewNormal.className = previewNormal.className.replace( - /\s*editor-preview-active\s*/g, '' - ); - var toolbar = editor.toolbarElements.preview; - var toolbar_div = wrapper.previousSibling; - toolbar.className = toolbar.className.replace(/\s*active\s*/g, ''); - toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview*/g, ''); - } - - // Start preview with the current text - var parse = editor.constructor.markdown; - preview.innerHTML = parse(cm.getValue()); - - // Updates preview - cm.on('update', function() { - preview.innerHTML = parse(cm.getValue()); - }); -} - - -/** - * Preview action. - */ -function togglePreview(editor) { - var cm = editor.codemirror; - var wrapper = cm.getWrapperElement(); - var toolbar_div = wrapper.previousSibling; - var toolbar = editor.toolbarElements.preview; - var parse = editor.constructor.markdown; - var preview = wrapper.lastChild; - if(!/editor-preview/.test(preview.className)) { - preview = document.createElement('div'); - preview.className = 'editor-preview'; - wrapper.appendChild(preview); - } - if(/editor-preview-active/.test(preview.className)) { - preview.className = preview.className.replace( - /\s*editor-preview-active\s*/g, '' - ); - toolbar.className = toolbar.className.replace(/\s*active\s*/g, ''); - toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview*/g, ''); - } else { - /* When the preview button is clicked for the first time, - * give some time for the transition from editor.css to fire and the view to slide from right to left, - * instead of just appearing. - */ - setTimeout(function() { - preview.className += ' editor-preview-active' - }, 1); - toolbar.className += ' active'; - toolbar_div.className += ' disabled-for-preview'; - } - var text = cm.getValue(); - preview.innerHTML = parse(text); - - // Turn off side by side if needed - var sidebyside = cm.getWrapperElement().nextSibling; - if (/editor-preview-active-side/.test(sidebyside.className)) - toggleSideBySide(editor); -} - -function _replaceSelection(cm, active, start, end) { - if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className)) - return; - - var text; - var startPoint = cm.getCursor('start'); - var endPoint = cm.getCursor('end'); - if(active) { - text = cm.getLine(startPoint.line); - start = text.slice(0, startPoint.ch); - end = text.slice(startPoint.ch); - cm.replaceRange(start + end, { - line: startPoint.line, - ch: 0 - }); - } else { - text = cm.getSelection(); - cm.replaceSelection(start + text + end); - - startPoint.ch += start.length; - endPoint.ch += start.length; - } - cm.setSelection(startPoint, endPoint); - cm.focus(); -} - - -function _toggleHeading(cm, direction, size) { - if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className)) - return; - - var startPoint = cm.getCursor('start'); - var endPoint = cm.getCursor('end'); - for(var i = startPoint.line; i <= endPoint.line; i++) { - (function(i) { - var text = cm.getLine(i); - var currHeadingLevel = text.search(/[^#]/); - - if(direction !== undefined){ - if (currHeadingLevel <= 0) { - if (direction == 'bigger') { - text = '###### ' + text; - } else { - text = '# ' + text; - } - } else if (currHeadingLevel == 6 && direction == 'smaller') { - text = text.substr(7); - } else if (currHeadingLevel == 1 && direction == 'bigger') { - text = text.substr(2); - } else { - if (direction == 'bigger') { - text = text.substr(1); - } else { - text = '#' + text; - } - } - } - else{ - if(size == 1){ - if (currHeadingLevel <= 0) { - text = '# ' + text; - } - else if(currHeadingLevel == size){ - text = text.substr(currHeadingLevel + 1); - } - else{ - text = '# ' + text.substr(currHeadingLevel + 1); - } - } - else if(size == 2){ - if (currHeadingLevel <= 0) { - text = '## ' + text; - } - else if(currHeadingLevel == size){ - text = text.substr(currHeadingLevel + 1); - } - else{ - text = '## ' + text.substr(currHeadingLevel + 1); - } - } - else{ - if (currHeadingLevel <= 0) { - text = '### ' + text; - } - else if(currHeadingLevel == size){ - text = text.substr(currHeadingLevel + 1); - } - else{ - text = '### ' + text.substr(currHeadingLevel + 1); - } - } - } - - cm.replaceRange(text, { - line: i, - ch: 0 - }, { - line: i, - ch: 99999999999999 - }); - })(i); - } - cm.focus(); -} - - -function _toggleLine(cm, name) { - if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className)) - return; - - var stat = getState(cm); - var startPoint = cm.getCursor('start'); - var endPoint = cm.getCursor('end'); - var repl = { - 'quote': /^(\s*)\>\s+/, - 'unordered-list': /^(\s*)(\*|\-|\+)\s+/, - 'ordered-list': /^(\s*)\d+\.\s+/ - }; - var map = { - 'quote': '> ', - 'unordered-list': '* ', - 'ordered-list': '1. ' - }; - for(var i = startPoint.line; i <= endPoint.line; i++) { - (function(i) { - var text = cm.getLine(i); - if(stat[name]) { - text = text.replace(repl[name], '$1'); - } else { - text = map[name] + text; - } - cm.replaceRange(text, { - line: i, - ch: 0 - }, { - line: i, - ch: 99999999999999 - }); - })(i); - } - cm.focus(); -} - -function _toggleBlock(editor, type, start_chars, end_chars) { - if(/editor-preview-active/.test(editor.codemirror.getWrapperElement().lastChild.className)) - return; - - end_chars = (typeof end_chars === 'undefined') ? start_chars : end_chars; - var cm = editor.codemirror; - var stat = getState(cm); - - var text; - var start = start_chars; - var end = end_chars; - - var startPoint = cm.getCursor('start'); - var endPoint = cm.getCursor('end'); - - if(stat[type]) { - text = cm.getLine(startPoint.line); - start = text.slice(0, startPoint.ch); - end = text.slice(startPoint.ch); - if(type == "bold") { - start = start.replace(/(\*\*|__)(?![\s\S]*(\*\*|__))/, ""); - end = end.replace(/(\*\*|__)/, ""); - } else if(type == "italic") { - start = start.replace(/(\*|_)(?![\s\S]*(\*|_))/, ""); - end = end.replace(/(\*|_)/, ""); - } else if(type == "strikethrough") { - start = start.replace(/(\*\*|~~)(?![\s\S]*(\*\*|~~))/, ""); - end = end.replace(/(\*\*|~~)/, ""); - } - cm.replaceRange(start + end, { - line: startPoint.line, - ch: 0 - }, { - line: startPoint.line, - ch: 99999999999999 - }); - - if(type == "bold" || type == "strikethrough") { - startPoint.ch -= 2; - endPoint.ch -= 2; - } else if(type == "italic") { - startPoint.ch -= 1; - endPoint.ch -= 1; - } - } else { - text = cm.getSelection(); - if(type == "bold") { - text = text.split("**").join(""); - text = text.split("__").join(""); - } else if(type == "italic") { - text = text.split("*").join(""); - text = text.split("_").join(""); - } else if(type == "strikethrough") { - text = text.split("~~").join(""); - } - cm.replaceSelection(start + text + end); - - startPoint.ch += start_chars.length; - endPoint.ch = startPoint.ch + text.length; - } - - cm.setSelection(startPoint, endPoint); - cm.focus(); -} - - -/* The right word count in respect for CJK. */ -function wordCount(data) { - var pattern = /[a-zA-Z0-9_\u0392-\u03c9]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af]+/g; - var m = data.match(pattern); - var count = 0; - if(m === null) return count; - for(var i = 0; i < m.length; i++) { - if(m[i].charCodeAt(0) >= 0x4E00) { - count += m[i].length; - } else { - count += 1; - } - } - return count; -} - - -var toolbarBuiltInButtons = { - "bold": { - name: "bold", - action: toggleBold, - className: "fa fa-bold", - title: "Bold (Ctrl+B)", - }, - "italic": { - name: "italic", - action: toggleItalic, - className: "fa fa-italic", - title: "Italic (Ctrl+I)", - }, - "strikethrough": { - name: "strikethrough", - action: toggleStrikethrough, - className: "fa fa-strikethrough", - title: "Strikethrough", - }, - "heading": { - name: "heading", - action: toggleHeadingSmaller, - className: "fa fa-header", - title: "Heading (Ctrl+H)", - }, - "heading-smaller": { - name: "heading-smaller", - action: toggleHeadingSmaller, - className: "fa fa-header", - title: "Smaller Heading (Ctrl+H)", - }, - "heading-bigger": { - name: "heading-bigger", - action: toggleHeadingBigger, - className: "fa fa-lg fa-header", - title: "Bigger Heading (Shift+Ctrl+H)", - }, - "heading-1": { - name: "heading-1", - action: toggleHeading1, - className: "fa fa-header fa-header-x fa-header-1", - title: "Big Heading", - }, - "heading-2": { - name: "heading-2", - action: toggleHeading2, - className: "fa fa-header fa-header-x fa-header-2", - title: "Medium Heading", - }, - "heading-3": { - name: "heading-3", - action: toggleHeading3, - className: "fa fa-header fa-header-x fa-header-3", - title: "Small Heading", - }, - "code": { - name: "code", - action: toggleCodeBlock, - className: "fa fa-code", - title: "Code (Ctrl+Alt+C)", - }, - "quote": { - name: "quote", - action: toggleBlockquote, - className: "fa fa-quote-left", - title: "Quote (Ctrl+')", - }, - "unordered-list": { - name: "unordered-list", - action: toggleUnorderedList, - className: "fa fa-list-ul", - title: "Generic List (Ctrl+L)", - }, - "ordered-list": { - name: "ordered-list", - action: toggleOrderedList, - className: "fa fa-list-ol", - title: "Numbered List (Ctrl+Alt+L)", - }, - "link": { - name: "link", - action: drawLink, - className: "fa fa-link", - title: "Create Link (Ctrl+K)", - }, - "image": { - name: "image", - action: drawImage, - className: "fa fa-picture-o", - title: "Insert Image (Ctrl+Alt+I)", - }, - "horizontal-rule": { - name: "horizontal-rule", - action: drawHorizontalRule, - className: "fa fa-minus", - title: "Insert Horizontal Line", - }, - "preview": { - name: "preview", - action: togglePreview, - className: "fa fa-eye", - title: "Toggle Preview (Ctrl+P)", - }, - "side-by-side": { - name: "side-by-side", - action: toggleSideBySide, - className: "fa fa-columns", - title: "Toggle Side by Side (F9)", - }, - "fullscreen": { - name: "fullscreen", - action: toggleFullScreen, - className: "fa fa-arrows-alt", - title: "Toggle Fullscreen (F11)", - }, - "guide": { - name: "guide", - action: "http://nextstepwebs.github.io/simplemde-markdown-editor/markdown-guide", - className: "fa fa-question-circle", - title: "Markdown Guide", - } -}; - -var toolbar = ["bold", "italic", "heading", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "|", "preview", "side-by-side", "fullscreen", "guide"]; - -/** - * Interface of SimpleMDE. - */ -function SimpleMDE(options) { - options = options || {}; - - if(options.element) { - this.element = options.element; - } - - if(options.toolbar !== false) - options.toolbar = options.toolbar || SimpleMDE.toolbar; - - if(!options.hasOwnProperty('status')) { - options.status = ['autosave', 'lines', 'words', 'cursor']; - } - - this.options = options; - - // If user has passed an element, it should auto rendered - this.render(); - - // The codemirror component is only available after rendering - // so, the setter for the initialValue can only run after - // the element has been rendered - if(options.initialValue) { - this.value(options.initialValue); - } -} - -/** - * Default toolbar elements. - */ -SimpleMDE.toolbar = toolbar; - -/** - * Default markdown render. - */ -SimpleMDE.markdown = function(text) { - if(window.marked) { - // Update options - if(this.options.singleLineBreaks !== false){ - marked.setOptions({ - breaks: true - }); - } - - return marked(text); - } -}; - -/** - * Render editor to the given element. - */ -SimpleMDE.prototype.render = function(el) { - if(!el) { - el = this.element || document.getElementsByTagName('textarea')[0]; - } - - if(this._rendered && this._rendered === el) { - // Already rendered. - return; - } - - this.element = el; - var options = this.options; - - var self = this; - var keyMaps = {}; - - for(var key in shortcuts) { - (function(key) { - keyMaps[fixShortcut(key)] = function(cm) { - shortcuts[key](self); - }; - })(key); - } - - keyMaps["Enter"] = "newlineAndIndentContinueMarkdownList"; - keyMaps["Tab"] = "tabAndIndentContinueMarkdownList"; - keyMaps["Shift-Tab"] = "shiftTabAndIndentContinueMarkdownList"; - keyMaps["F11"] = function(cm) { - toggleFullScreen(self); - }; - keyMaps["F9"] = function(cm) { - toggleSideBySide(self); - }; - keyMaps["Esc"] = function(cm) { - if(cm.getOption("fullScreen")) cm.setOption("fullScreen", false); - }; - - var mode = "spell-checker"; - var backdrop = "gfm"; - - if(options.spellChecker === false) { - mode = "gfm"; - backdrop = undefined; - } - - this.codemirror = CodeMirror.fromTextArea(el, { - mode: mode, - backdrop: backdrop, - theme: 'paper', - tabSize: (options.tabSize != undefined) ? options.tabSize : 2, - indentUnit: (options.tabSize != undefined) ? options.tabSize : 2, - indentWithTabs: (options.indentWithTabs === false) ? false : true, - lineNumbers: false, - autofocus: (options.autofocus === true) ? true : false, - extraKeys: keyMaps, - lineWrapping: (options.lineWrapping === false) ? false : true - }); - - if(options.toolbar !== false) { - this.createToolbar(); - } - if(options.status !== false) { - this.createStatusbar(); - } - if(options.autosave != undefined && options.autosave.enabled === true) { - this.autosave(); - } - - this.createSidebyside(); - - this._rendered = this.element; -}; - -SimpleMDE.prototype.autosave = function() { - var content = this.value(); - var simplemde = this; - - if(this.options.autosave.unique_id == undefined || this.options.autosave.unique_id == "") { - console.log("SimpleMDE: You must set a unique_id to use the autosave feature"); - return; - } - - if(simplemde.element.form != null && simplemde.element.form != undefined) { - simplemde.element.form.addEventListener("submit", function() { - localStorage.setItem(simplemde.options.autosave.unique_id, ""); - }); - } - - if(this.options.autosave.loaded !== true) { - if(localStorage.getItem(this.options.autosave.unique_id) != null) - this.codemirror.setValue(localStorage.getItem(this.options.autosave.unique_id)); - - this.options.autosave.loaded = true; - } - - if(localStorage) { - localStorage.setItem(this.options.autosave.unique_id, content); - } - - var el = document.getElementById("autosaved"); - if(el != null && el != undefined && el != "") { - var d = new Date(); - var hh = d.getHours(); - var m = d.getMinutes(); - var dd = "am"; - var h = hh; - if(h >= 12) { - h = hh - 12; - dd = "pm"; - } - if(h == 0) { - h = 12; - } - m = m < 10 ? "0" + m : m; - - el.innerHTML = "Autosaved: " + h + ":" + m + " " + dd; - } - - setTimeout(function() { - simplemde.autosave(); - }, this.options.autosave.delay || 10000); -}; - -SimpleMDE.prototype.createSidebyside = function() { - var cm = this.codemirror; - var wrapper = cm.getWrapperElement(); - var preview = wrapper.nextSibling; - - if (!/editor-preview-side/.test(preview.className)) { - preview = document.createElement('div'); - preview.className = 'editor-preview-side'; - wrapper.parentNode.insertBefore(preview, wrapper.nextSibling); - } - - // Syncs scroll editor -> preview - var cScroll = false; - var pScroll = false; - cm.on('scroll', function(v) { - if (cScroll){cScroll=false; return;}; pScroll=true; - height = v.getScrollInfo().height - v.getScrollInfo().clientHeight; - ratio = parseFloat(v.getScrollInfo().top) / height; - move = (preview.scrollHeight - preview.clientHeight) * ratio; - preview.scrollTop = move; - }); - - // Syncs scroll preview -> editor - preview.onscroll = function(v) { - if (pScroll){pScroll=false; return;}; cScroll=true; - height = preview.scrollHeight - preview.clientHeight; - ratio = parseFloat(preview.scrollTop) / height; - move = (cm.getScrollInfo().height - cm.getScrollInfo().clientHeight) * ratio; - cm.scrollTo(0, move); - }; - return true; -} - -SimpleMDE.prototype.createToolbar = function(items) { - items = items || this.options.toolbar; - - if(!items || items.length === 0) { - return; - } - - for(var i = 0; i < items.length; i++) { - if(toolbarBuiltInButtons[items[i]] != undefined){ - items[i] = toolbarBuiltInButtons[items[i]]; - } - } - - var bar = document.createElement('div'); - bar.className = 'editor-toolbar'; - - var self = this; - - var el; - var toolbar_data = {}; - self.toolbar = items; - - for(var i = 0; i < items.length; i++) { - if(items[i].name == "guide" && self.options.toolbarGuideIcon === false) - continue; - - (function(item) { - var el; - if(item === '|') { - el = createSep(); - } else { - el = createIcon(item, self.options.toolbarTips); - } - - // bind events, special for info - if(item.action) { - if(typeof item.action === 'function') { - el.onclick = function(e) { - item.action(self); - }; - } else if(typeof item.action === 'string') { - el.href = item.action; - el.target = '_blank'; - } - } - toolbar_data[item.name || item] = el; - bar.appendChild(el); - })(items[i]); - } - - self.toolbarElements = toolbar_data; - - var cm = this.codemirror; - cm.on('cursorActivity', function() { - var stat = getState(cm); - - for(var key in toolbar_data) { - (function(key) { - var el = toolbar_data[key]; - if(stat[key]) { - el.className += ' active'; - } else if(key != "fullscreen" && key != "side-by-side") { - el.className = el.className.replace(/\s*active\s*/g, ''); - } - })(key); - } - }); - - var cmWrapper = cm.getWrapperElement(); - cmWrapper.parentNode.insertBefore(bar, cmWrapper); - return bar; -}; - -SimpleMDE.prototype.createStatusbar = function(status) { - status = status || this.options.status; - options = this.options; - - if(!status || status.length === 0) return; - - var bar = document.createElement('div'); - bar.className = 'editor-statusbar'; - - var pos, cm = this.codemirror; - for(var i = 0; i < status.length; i++) { - (function(name) { - var el = document.createElement('span'); - el.className = name; - if(name === 'words') { - el.innerHTML = '0'; - cm.on('update', function() { - el.innerHTML = wordCount(cm.getValue()); - }); - } else if(name === 'lines') { - el.innerHTML = '0'; - cm.on('update', function() { - el.innerHTML = cm.lineCount(); - }); - } else if(name === 'cursor') { - el.innerHTML = '0:0'; - cm.on('cursorActivity', function() { - pos = cm.getCursor(); - el.innerHTML = pos.line + ':' + pos.ch; - }); - } else if(name === 'autosave') { - if(options.autosave != undefined && options.autosave.enabled === true) { - el.setAttribute("id", "autosaved"); - } - } - bar.appendChild(el); - })(status[i]); - } - - var cmWrapper = this.codemirror.getWrapperElement(); - cmWrapper.parentNode.insertBefore(bar, cmWrapper.nextSibling); - return bar; -}; - -/** - * Get or set the text content. - */ -SimpleMDE.prototype.value = function(val) { - if(val === undefined) { - return this.codemirror.getValue(); - } else { - this.codemirror.getDoc().setValue(val); - return this; - } -}; - - -/** - * Bind static methods for exports. - */ -SimpleMDE.toggleBold = toggleBold; -SimpleMDE.toggleItalic = toggleItalic; -SimpleMDE.toggleStrikethrough = toggleStrikethrough; -SimpleMDE.toggleBlockquote = toggleBlockquote; -SimpleMDE.toggleHeadingSmaller = toggleHeadingSmaller; -SimpleMDE.toggleHeadingBigger = toggleHeadingBigger; -SimpleMDE.toggleHeading1 = toggleHeading1; -SimpleMDE.toggleHeading2 = toggleHeading2; -SimpleMDE.toggleHeading3 = toggleHeading3; -SimpleMDE.toggleCodeBlock = toggleCodeBlock; -SimpleMDE.toggleUnorderedList = toggleUnorderedList; -SimpleMDE.toggleOrderedList = toggleOrderedList; -SimpleMDE.drawLink = drawLink; -SimpleMDE.drawImage = drawImage; -SimpleMDE.drawHorizontalRule = drawHorizontalRule; -SimpleMDE.undo = undo; -SimpleMDE.redo = redo; -SimpleMDE.togglePreview = togglePreview; -SimpleMDE.toggleSideBySide = toggleSideBySide; -SimpleMDE.toggleFullScreen = toggleFullScreen; - -/** - * Bind instance methods for exports. - */ -SimpleMDE.prototype.toggleBold = function() { - toggleBold(this); -}; -SimpleMDE.prototype.toggleItalic = function() { - toggleItalic(this); -}; -SimpleMDE.prototype.toggleStrikethrough = function() { - toggleStrikethrough(this); -}; -SimpleMDE.prototype.toggleBlockquote = function() { - toggleBlockquote(this); -}; -SimpleMDE.prototype.toggleHeadingSmaller = function() { - toggleHeadingSmaller(this); -}; -SimpleMDE.prototype.toggleHeadingBigger = function() { - toggleHeadingBigger(this); -}; -SimpleMDE.prototype.toggleHeading1 = function() { - toggleHeading1(this); -}; -SimpleMDE.prototype.toggleHeading2 = function() { - toggleHeading2(this); -}; -SimpleMDE.prototype.toggleHeading3 = function() { - toggleHeading3(this); -}; -SimpleMDE.prototype.toggleCodeBlock = function() { - toggleCodeBlock(this); -}; -SimpleMDE.prototype.toggleUnorderedList = function() { - toggleUnorderedList(this); -}; -SimpleMDE.prototype.toggleOrderedList = function() { - toggleOrderedList(this); -}; -SimpleMDE.prototype.drawLink = function() { - drawLink(this); -}; -SimpleMDE.prototype.drawImage = function() { - drawImage(this); -}; -SimpleMDE.prototype.drawHorizontalRule = function() { - drawHorizontalRule(this); -}; -SimpleMDE.prototype.undo = function() { - undo(this); -}; -SimpleMDE.prototype.redo = function() { - redo(this); -}; -SimpleMDE.prototype.togglePreview = function() { - togglePreview(this); -}; -SimpleMDE.prototype.toggleSideBySide = function() { - toggleSideBySide(this); -}; -SimpleMDE.prototype.toggleFullScreen = function() { - toggleFullScreen(this); -};