Merge pull request #189 from NextStepWebs/development

Autosave improvements, Build improvements, New icons, New options, Clearer README
pull/75/head 1.9.0
Wes Cossick 9 years ago
commit 5f3a67dae2

@ -1,5 +1,7 @@
language: node_js
node_js:
- '5'
- '4'
- '0.12'
before_script:
- npm install -g gulp

@ -67,20 +67,24 @@ simplemde.value("This text will appear in the editor");
## Configuration
- **autoDownloadFontAwesome**: If set to `true`, force downloads Font Awesome (used for icons). If set to false, prevents downloading. Defaults to `undefined`, which will intelligently check whether Font Awesome has already been included, then download accordingly.
- **autoDownloadFontAwesome**: If set to `true`, force downloads Font Awesome (used for icons). If set to `false`, prevents downloading. Defaults to `undefined`, which will intelligently check whether Font Awesome has already been included, then download accordingly.
- **autofocus**: If set to `true`, autofocuses the editor. Defaults to `false`.
- **autosave**: *Saves the text that's being written and will load it back in the future. It will forget the text when the form it's contained in is submitted.*
- **enabled**: If set to `true`, autosave the text. Defaults to `false`.
- **delay**: Delay between saves, in milliseconds. Defaults to `10000` (10s).
- **unique_id**: You must set a unique string identifier so that SimpleMDE can autosave. Something that separates this from other instances of SimpleMDE elsewhere on your website.
- **uniqueId**: You must set a unique string identifier so that SimpleMDE can autosave. Something that separates this from other instances of SimpleMDE elsewhere on your website.
- **blockStyles**: Customize how certain buttons that style blocks of text behave.
- **bold** Can be set to `**` or `__`. Defaults to `**`.
- **italic** Can be set to `*` or `_`. Defaults to `*`.
- **element**: The DOM element for the textarea to use. Defaults to the first textarea on the page.
- **hideIcons**: An array of icon names to hide. Can be used to hide specific icons without completely customizing the toolbar.
- **hideIcons**: An array of icon names to hide. Can be used to hide specific icons shown by default without completely customizing the toolbar.
- **indentWithTabs**: If set to `false`, indent using spaces instead of tabs. Defaults to `true`.
- **initialValue**: If set, will customize the initial value of the editor.
- **insertTexts**: Customize how certain buttons that insert text behave. Takes an array with two elements. The first element will be the text inserted before the cursor or highlight, and the second element will be inserted after. For example, this is the default link value: `["[", "](http://)"]`.
- horizontalRule
- image
- link
- table
- **lineWrapping**: If set to `false`, disable line wrapping. Defaults to `true`.
- **parsingConfig**: Adjust settings for parsing the Markdown during editing (not previewing).
- **allowAtxHeaderWithoutSpace**: If set to `true`, will render headers without a space after the `#`. Defaults to `false`.
@ -90,6 +94,7 @@ simplemde.value("This text will appear in the editor");
- **renderingConfig**: Adjust settings for parsing the Markdown during previewing (not editing).
- **singleLineBreaks**: If set to `false`, disable parsing GFM single line breaks. Defaults to `true`.
- **codeSyntaxHighlighting**: If set to `true`, will highlight using [highlight.js](https://github.com/isagalaev/highlight.js). Defaults to `false`. To use this feature you must include highlight.js on your page. For example, include the script and the CSS files like:<br>`<script src="https://cdn.jsdelivr.net/highlight.js/latest/highlight.min.js"></script>`<br>`<link rel="stylesheet" href="https://cdn.jsdelivr.net/highlight.js/latest/styles/github.min.css">`
- **showIcons**: An array of icon names to show. Can be used to show specific icons hidden by default without completely customizing the toolbar.
- **spellChecker**: If set to `false`, disable the spell checker. Defaults to `true`.
- **status**: If set to `false`, hide the status bar. Defaults to `true`.
- Optionally, you can set an array of status bar elements to include, and in what order.
@ -103,9 +108,13 @@ var simplemde = new SimpleMDE({
autofocus: true,
autosave: {
enabled: true,
unique_id: "MyUniqueID",
uniqueId: "MyUniqueID",
delay: 1000,
},
blockStyles: {
bold: "__",
italic: "_"
},
element: document.getElementById("MyID"),
hideIcons: ["guide", "heading"],
indentWithTabs: false,
@ -114,6 +123,7 @@ var simplemde = new SimpleMDE({
horizontalRule: ["", "\n\n-----\n\n"],
image: ["![](http://", ")"],
link: ["[", "](http://)"],
table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text | Text | Text |\n\n"],
},
lineWrapping: false,
parsingConfig: {
@ -135,6 +145,7 @@ var simplemde = new SimpleMDE({
singleLineBreaks: false,
codeSyntaxHighlighting: true,
},
showIcons: ["code", "table"],
spellChecker: false,
status: false,
status: ["autosave", "lines", "words", "cursor"], // Optional usage
@ -165,6 +176,7 @@ unordered-list | toggleUnorderedList | Generic List (Ctrl+L)<br>fa fa-list-ul
ordered-list | toggleOrderedList | Numbered List (Ctrl+Alt+L)<br>fa fa-list-ol
link | drawLink | Create Link (Ctrl+K)<br>fa fa-link
image | drawImage | Insert Image (Ctrl+Alt+I)<br>fa fa-picture-o
table | drawTable | Insert Table<br>fa fa-table
horizontal-rule | drawHorizontalRule | Insert Horizontal Line<br>fa fa-minus
preview | togglePreview | Toggle Preview (Ctrl+P)<br>fa fa-eye no-disable
side-by-side | toggleSideBySide | Toggle Side by Side (F9)<br>fa fa-columns no-disable no-mobile
@ -187,6 +199,14 @@ var simplemde = new SimpleMDE({
className: "fa fa-bold",
title: "Bold (Ctrl+B)",
},
{
name: "custom",
action: customFunction(editor){
// Add your own code
},
className: "fa fa-star",
title: "Custom Button",
},
"|", // Separator
...
],
@ -221,14 +241,15 @@ simplemde.codemirror.on("change", function(){
});
```
## State methods
The following methods will let you check on the state of the editor.
## Useful methods
The following self-explanatory methods may be of use while developing with SimpleMDE.
```js
var simplemde = new SimpleMDE();
simplemde.isPreviewActive();
simplemde.isSideBySideActive();
simplemde.isFullscreenActive();
simplemde.isPreviewActive(); // returns boolean
simplemde.isSideBySideActive(); // returns boolean
simplemde.isFullscreenActive(); // returns boolean
simplemde.clearAutosavedValue(); // no returned value
```
## How it works

@ -1,6 +1,6 @@
{
"name": "simplemde",
"version": "1.8.1",
"version": "1.9.0",
"homepage": "https://github.com/NextStepWebs/simplemde-markdown-editor",
"authors": [
"Wes Cossick"

@ -1,5 +1,5 @@
/**
* simplemde v1.8.1
* simplemde v1.9.0
* Copyright Next Step Webs, Inc.
* @link https://github.com/NextStepWebs/simplemde-markdown-editor
* @license MIT
@ -559,7 +559,7 @@ span.CodeMirror-selectedtext { background: none; }
top: 0;
left: 0;
background: #fafafa;
z-index: 2;
z-index: 7;
overflow: auto;
display: none;
box-sizing: border-box;
@ -573,7 +573,7 @@ span.CodeMirror-selectedtext { background: none; }
top: 50px;
right: 0;
background: #fafafa;
z-index: 9999;
z-index: 9;
overflow: auto;
display: none;
box-sizing: border-box;

File diff suppressed because one or more lines are too long

@ -1,5 +1,5 @@
/**
* simplemde v1.8.1
* simplemde v1.9.0
* Copyright Next Step Webs, Inc.
* @link https://github.com/NextStepWebs/simplemde-markdown-editor
* @license MIT
@ -7,7 +7,7 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SimpleMDE = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (global){
; Typo = global.Typo = require("/Users/wescossick/Documents/Websites/simplemde-markdown-editor/node_modules/codemirror-spell-checker/src/js/typo.js");
; Typo = global.Typo = require("D:\\My Web Sites\\simplemde-markdown-editor\\node_modules\\codemirror-spell-checker\\src\\js\\typo.js");
CodeMirror = global.CodeMirror = require("codemirror");
; var __browserify_shim_require__=require;(function browserifyShim(module, define, require) {
// Initialize data globally to reduce memory consumption
@ -105,7 +105,7 @@ if(!String.prototype.includes) {
}).call(global, module, undefined, undefined);
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"/Users/wescossick/Documents/Websites/simplemde-markdown-editor/node_modules/codemirror-spell-checker/src/js/typo.js":2,"codemirror":6}],2:[function(require,module,exports){
},{"D:\\My Web Sites\\simplemde-markdown-editor\\node_modules\\codemirror-spell-checker\\src\\js\\typo.js":2,"codemirror":6}],2:[function(require,module,exports){
(function (global){
; var __browserify_shim_require__=require;(function browserifyShim(module, exports, require, define, browserify_shim__define__module__export__) {
'use strict';
@ -1888,7 +1888,7 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
// given line.
function updateWidgetHeight(line) {
if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
line.widgets[i].height = line.widgets[i].node.offsetHeight;
line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight;
}
// Do a bulk-read of the DOM positions and sizes needed to draw the
@ -3287,8 +3287,9 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
var out;
for (var i = 0; i < sel.ranges.length; i++) {
var range = sel.ranges[i];
var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
var newHead = skipAtomic(doc, range.head, bias, mayClear);
var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
if (out || newAnchor != range.anchor || newHead != range.head) {
if (!out) out = sel.ranges.slice(0, i);
out[i] = new Range(newAnchor, newHead);
@ -3297,54 +3298,59 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
return out ? normalizeSelection(out, sel.primIndex) : sel;
}
// Ensure a given position is not inside an atomic range.
function skipAtomic(doc, pos, bias, mayClear) {
var flipped = false, curPos = pos;
var dir = bias || 1;
doc.cantEdit = false;
search: for (;;) {
var line = getLine(doc, curPos.line);
if (line.markedSpans) {
for (var i = 0; i < line.markedSpans.length; ++i) {
var sp = line.markedSpans[i], m = sp.marker;
if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
(sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
if (mayClear) {
signal(m, "beforeCursorEnter");
if (m.explicitlyCleared) {
if (!line.markedSpans) break;
else {--i; continue;}
}
}
if (!m.atomic) continue;
var newPos = m.find(dir < 0 ? -1 : 1);
if (cmp(newPos, curPos) == 0) {
newPos.ch += dir;
if (newPos.ch < 0) {
if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
else newPos = null;
} else if (newPos.ch > line.text.length) {
if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
else newPos = null;
}
if (!newPos) {
if (flipped) {
// Driven in a corner -- no valid cursor position found at all
// -- try again *with* clearing, if we didn't already
if (!mayClear) return skipAtomic(doc, pos, bias, true);
// Otherwise, turn off editing until further notice, and return the start of the doc
doc.cantEdit = true;
return Pos(doc.first, 0);
}
flipped = true; newPos = pos; dir = -dir;
}
}
curPos = newPos;
continue search;
function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
var line = getLine(doc, pos.line);
if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
var sp = line.markedSpans[i], m = sp.marker;
if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
(sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
if (mayClear) {
signal(m, "beforeCursorEnter");
if (m.explicitlyCleared) {
if (!line.markedSpans) break;
else {--i; continue;}
}
}
if (!m.atomic) continue;
if (oldPos) {
var near = m.find(dir < 0 ? 1 : -1), diff;
if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) near = movePos(doc, near, -dir, line);
if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
return skipAtomicInner(doc, near, pos, dir, mayClear);
}
var far = m.find(dir < 0 ? -1 : 1);
if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) far = movePos(doc, far, dir, line);
return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null;
}
return curPos;
}
return pos;
}
// Ensure a given position is not inside an atomic range.
function skipAtomic(doc, pos, oldPos, bias, mayClear) {
var dir = bias || 1;
var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
(!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
(!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
if (!found) {
doc.cantEdit = true;
return Pos(doc.first, 0);
}
return found;
}
function movePos(doc, pos, dir, line) {
if (dir < 0 && pos.ch == 0) {
if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1));
else return null;
} else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0);
else return null;
} else {
return new Pos(pos.line, pos.ch + dir);
}
}
@ -5909,7 +5915,7 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
if (dir > 0 && !moveOnce(!first)) break;
}
}
var result = skipAtomic(doc, Pos(line, ch), origDir, true);
var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true);
if (!possible) result.hitSide = true;
return result;
}
@ -7733,7 +7739,7 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;";
removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
}
return widget.height = widget.node.offsetHeight;
return widget.height = widget.node.parentNode.offsetHeight;
}
function addLineWidget(doc, handle, node, options) {
@ -8154,7 +8160,7 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
spanEndStyle = "";
}
if (m.className) spanStyle += " " + m.className;
if (m.css) css = m.css;
if (m.css) css = (css ? css + ";" : "") + m.css;
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
if (m.title && !title) title = m.title;
@ -8423,6 +8429,7 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
this.id = ++nextDocId;
this.modeOption = mode;
this.lineSep = lineSep;
this.extend = false;
if (typeof text == "string") text = this.splitLines(text);
updateDoc(this, {from: start, to: start, text: text});
@ -9930,7 +9937,7 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
// THE END
CodeMirror.version = "5.8.1";
CodeMirror.version = "5.9.1";
return CodeMirror;
});
@ -10782,7 +10789,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
f: s.f,
prevLine: s.prevLine,
thisLine: s.this,
thisLine: s.thisLine,
block: s.block,
htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
@ -12808,6 +12815,7 @@ require("spell-checker");
var marked = require("marked");
// Some variables
var isMac = /Mac/.test(navigator.platform);
var shortcuts = {
@ -12863,6 +12871,7 @@ function createIcon(options, enableTooltips) {
}
}
el.tabIndex = -1;
el.className = options.className;
return el;
}
@ -12966,7 +12975,7 @@ function toggleFullScreen(editor) {
* Action for toggling bold.
*/
function toggleBold(editor) {
_toggleBlock(editor, "bold", "**");
_toggleBlock(editor, "bold", editor.options.blockStyles.bold);
}
@ -12974,7 +12983,7 @@ function toggleBold(editor) {
* Action for toggling italic.
*/
function toggleItalic(editor) {
_toggleBlock(editor, "italic", "*");
_toggleBlock(editor, "italic", editor.options.blockStyles.italic);
}
@ -13078,6 +13087,16 @@ function drawImage(editor) {
_replaceSelection(cm, stat.image, options.insertTexts.image);
}
/**
* Action for drawing a table.
*/
function drawTable(editor) {
var cm = editor.codemirror;
var stat = getState(cm);
var options = editor.options;
_replaceSelection(cm, stat.table, options.insertTexts.table);
}
/**
* Action for drawing a horizontal rule.
*/
@ -13450,19 +13469,20 @@ function wordCount(data) {
return count;
}
var toolbarBuiltInButtons = {
"bold": {
name: "bold",
action: toggleBold,
className: "fa fa-bold",
title: "Bold (Ctrl+B)"
title: "Bold (Ctrl+B)",
default: true
},
"italic": {
name: "italic",
action: toggleItalic,
className: "fa fa-italic",
title: "Italic (Ctrl+I)"
title: "Italic (Ctrl+I)",
default: true
},
"strikethrough": {
name: "strikethrough",
@ -13474,7 +13494,8 @@ var toolbarBuiltInButtons = {
name: "heading",
action: toggleHeadingSmaller,
className: "fa fa-header",
title: "Heading (Ctrl+H)"
title: "Heading (Ctrl+H)",
default: true
},
"heading-smaller": {
name: "heading-smaller",
@ -13506,6 +13527,9 @@ var toolbarBuiltInButtons = {
className: "fa fa-header fa-header-x fa-header-3",
title: "Small Heading"
},
"separator-1": {
name: "separator-1"
},
"code": {
name: "code",
action: toggleCodeBlock,
@ -13516,31 +13540,45 @@ var toolbarBuiltInButtons = {
name: "quote",
action: toggleBlockquote,
className: "fa fa-quote-left",
title: "Quote (Ctrl+')"
title: "Quote (Ctrl+')",
default: true
},
"unordered-list": {
name: "unordered-list",
action: toggleUnorderedList,
className: "fa fa-list-ul",
title: "Generic List (Ctrl+L)"
title: "Generic List (Ctrl+L)",
default: true
},
"ordered-list": {
name: "ordered-list",
action: toggleOrderedList,
className: "fa fa-list-ol",
title: "Numbered List (Ctrl+Alt+L)"
title: "Numbered List (Ctrl+Alt+L)",
default: true
},
"separator-2": {
name: "separator-2"
},
"link": {
name: "link",
action: drawLink,
className: "fa fa-link",
title: "Create Link (Ctrl+K)"
title: "Create Link (Ctrl+K)",
default: true
},
"image": {
name: "image",
action: drawImage,
className: "fa fa-picture-o",
title: "Insert Image (Ctrl+Alt+I)"
title: "Insert Image (Ctrl+Alt+I)",
default: true
},
"table": {
name: "table",
action: drawTable,
className: "fa fa-table",
title: "Insert Table"
},
"horizontal-rule": {
name: "horizontal-rule",
@ -13548,38 +13586,50 @@ var toolbarBuiltInButtons = {
className: "fa fa-minus",
title: "Insert Horizontal Line"
},
"separator-3": {
name: "separator-3"
},
"preview": {
name: "preview",
action: togglePreview,
className: "fa fa-eye no-disable",
title: "Toggle Preview (Ctrl+P)"
title: "Toggle Preview (Ctrl+P)",
default: true
},
"side-by-side": {
name: "side-by-side",
action: toggleSideBySide,
className: "fa fa-columns no-disable no-mobile",
title: "Toggle Side by Side (F9)"
title: "Toggle Side by Side (F9)",
default: true
},
"fullscreen": {
name: "fullscreen",
action: toggleFullScreen,
className: "fa fa-arrows-alt no-disable no-mobile",
title: "Toggle Fullscreen (F11)"
title: "Toggle Fullscreen (F11)",
default: true
},
"guide": {
name: "guide",
action: "http://nextstepwebs.github.io/simplemde-markdown-editor/markdown-guide",
className: "fa fa-question-circle",
title: "Markdown Guide"
title: "Markdown Guide",
default: true
}
};
var insertTexts = {
link: ["[", "](http://)"],
image: ["![](http://", ")"],
table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text | Text | Text |\n\n"],
horizontalRule: ["", "\n\n-----\n\n"]
};
var blockStyles = {
"bold": "**",
"italic": "*"
};
/**
* Interface of SimpleMDE.
@ -13630,10 +13680,28 @@ function SimpleMDE(options) {
}
// Handle toolbar and status bar
if(options.toolbar !== false)
options.toolbar = options.toolbar || SimpleMDE.toolbar;
// Handle toolbar
if(options.toolbar === undefined) {
// Initialize
options.toolbar = [];
// Loop over the built in buttons, to get the preferred order
for(var key in toolbarBuiltInButtons) {
if(toolbarBuiltInButtons.hasOwnProperty(key)) {
if(key.indexOf("separator-") != -1) {
options.toolbar.push("|");
}
if(toolbarBuiltInButtons[key].default === true || (options.showIcons && options.showIcons.constructor === Array && options.showIcons.indexOf(key) != -1)) {
options.toolbar.push(key);
}
}
}
}
// Handle status bar
if(!options.hasOwnProperty("status")) {
options.status = ["autosave", "lines", "words", "cursor"];
}
@ -13656,6 +13724,15 @@ function SimpleMDE(options) {
options.insertTexts = extend({}, insertTexts, options.insertTexts || {});
// Merging the blockStyles, with the given options
options.blockStyles = extend({}, blockStyles, options.blockStyles || {});
// Change unique_id to uniqueId for backwards compatibility
if(options.autosave != undefined && options.autosave.unique_id != undefined && options.autosave.unique_id != "")
options.autosave.uniqueId = options.autosave.unique_id;
// Update this options
this.options = options;
@ -13667,16 +13744,11 @@ function SimpleMDE(options) {
// 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) {
if(options.initialValue && (!this.options.autosave || this.options.autosave.foundSavedValue !== true)) {
this.value(options.initialValue);
}
}
/**
* Default toolbar elements.
*/
SimpleMDE.toolbar = ["bold", "italic", "heading", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "|", "preview", "side-by-side", "fullscreen", "guide"];
/**
* Default markdown render.
*/
@ -13747,6 +13819,14 @@ SimpleMDE.prototype.render = function(el) {
if(cm.getOption("fullScreen")) toggleFullScreen(self);
};
document.addEventListener("keydown", function(e) {
e = e || window.event;
if(e.keyCode == 27) {
if(self.codemirror.getOption("fullScreen")) toggleFullScreen(self);
}
}, false);
var mode, backdrop;
if(options.spellChecker !== false) {
mode = "spell-checker";
@ -13789,53 +13869,69 @@ SimpleMDE.prototype.render = function(el) {
};
SimpleMDE.prototype.autosave = function() {
var content = this.value();
var simplemde = this;
if(localStorage) {
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(this.options.autosave.uniqueId == undefined || this.options.autosave.uniqueId == "") {
console.log("SimpleMDE: You must set a uniqueId 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(simplemde.element.form != null && simplemde.element.form != undefined) {
simplemde.element.form.addEventListener("submit", function() {
localStorage.removeItem("smde_" + simplemde.options.autosave.uniqueId);
});
}
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));
if(this.options.autosave.loaded !== true) {
if(typeof localStorage.getItem("smde_" + this.options.autosave.uniqueId) == "string" && localStorage.getItem("smde_" + this.options.autosave.uniqueId) != "") {
this.codemirror.setValue(localStorage.getItem("smde_" + this.options.autosave.uniqueId));
this.options.autosave.foundSavedValue = true;
}
this.options.autosave.loaded = true;
}
this.options.autosave.loaded = true;
}
if(localStorage) {
localStorage.setItem(this.options.autosave.unique_id, content);
}
localStorage.setItem("smde_" + this.options.autosave.uniqueId, simplemde.value());
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;
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";
el.innerHTML = "Autosaved: " + h + ":" + m + " " + dd;
}
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);
} else {
console.log("SimpleMDE: localStorage not available, cannot autosave");
}
};
setTimeout(function() {
simplemde.autosave();
}, this.options.autosave.delay || 10000);
SimpleMDE.prototype.clearAutosavedValue = function() {
if(localStorage) {
if(this.options.autosave.uniqueId == undefined || this.options.autosave.uniqueId == "") {
console.log("SimpleMDE: You must set a uniqueId to use the autosave feature");
return;
}
localStorage.removeItem("smde_" + this.options.autosave.uniqueId);
} else {
console.log("SimpleMDE: localStorage not available, cannot autosave");
}
};
SimpleMDE.prototype.createSideBySide = function() {
@ -14033,6 +14129,7 @@ SimpleMDE.toggleUnorderedList = toggleUnorderedList;
SimpleMDE.toggleOrderedList = toggleOrderedList;
SimpleMDE.drawLink = drawLink;
SimpleMDE.drawImage = drawImage;
SimpleMDE.drawTable = drawTable;
SimpleMDE.drawHorizontalRule = drawHorizontalRule;
SimpleMDE.undo = undo;
SimpleMDE.redo = redo;
@ -14085,6 +14182,9 @@ SimpleMDE.prototype.drawLink = function() {
SimpleMDE.prototype.drawImage = function() {
drawImage(this);
};
SimpleMDE.prototype.drawTable = function() {
drawTable(this);
};
SimpleMDE.prototype.drawHorizontalRule = function() {
drawHorizontalRule(this);
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -4,6 +4,7 @@ var gulp = require("gulp"),
uglify = require("gulp-uglify"),
concat = require("gulp-concat"),
header = require("gulp-header"),
buffer = require("vinyl-buffer"),
pkg = require("./package.json"),
debug = require("gulp-debug"),
eslint = require("gulp-eslint"),
@ -50,6 +51,7 @@ function taskBrowserify(opts) {
gulp.task("browserify:dev", ["lint"], function() {
return taskBrowserify({debug:true, standalone:"SimpleMDE"})
.pipe(source("simplemde.debug.js"))
.pipe(buffer())
.pipe(header(banner, {pkg: pkg}))
.pipe(gulp.dest("./debug/"));
});
@ -57,6 +59,7 @@ gulp.task("browserify:dev", ["lint"], function() {
gulp.task("browserify:min", ["lint"], function() {
return taskBrowserify({standalone:"SimpleMDE"})
.pipe(source("simplemde.js"))
.pipe(buffer())
.pipe(header(banner, {pkg: pkg}))
.pipe(gulp.dest("./debug/"));
});
@ -67,6 +70,7 @@ gulp.task("scripts", ["browserify:dev", "browserify:min", "lint"], function() {
return gulp.src(js_files)
.pipe(concat("simplemde.min.js"))
.pipe(uglify())
.pipe(buffer())
.pipe(header(banner, {pkg: pkg}))
.pipe(gulp.dest("./dist/"));
});
@ -80,10 +84,12 @@ gulp.task("styles", ["prettify-css"], function() {
return gulp.src(css_files)
.pipe(concat("simplemde.css"))
.pipe(buffer())
.pipe(header(banner, {pkg: pkg}))
.pipe(gulp.dest("./debug/"))
.pipe(minifycss())
.pipe(rename("simplemde.min.css"))
.pipe(buffer())
.pipe(header(banner, {pkg: pkg}))
.pipe(gulp.dest("./dist/"));
});

@ -1,6 +1,6 @@
{
"name": "simplemde",
"version": "1.8.1",
"version": "1.9.0",
"description": "A simple, beautiful, and embeddable JavaScript Markdown editor. Features autosaving and spell checking.",
"keywords": [
"embeddable",
@ -23,7 +23,7 @@
"dependencies": {
"codemirror": "codemirror/CodeMirror",
"codemirror-spell-checker": "nextstepwebs/codemirror-spell-checker",
"marked": "chjj/marked"
"marked": "0.3.5"
},
"devDependencies": {
"browserify": "^11.2.0",
@ -39,7 +39,8 @@
"gulp-minify-css": "^1.2.1",
"gulp-rename": "^1.2.2",
"gulp-uglify": "*",
"vinyl-source-stream": "^1.1.0"
"vinyl-source-stream": "^1.1.0",
"vinyl-buffer": "*"
},
"browserify": {
"transform": [
@ -65,4 +66,4 @@
"type": "git",
"url": "https://github.com/NextStepWebs/simplemde-markdown-editor"
}
}
}

@ -218,7 +218,7 @@
top: 0;
left: 0;
background: #fafafa;
z-index: 2;
z-index: 7;
overflow: auto;
display: none;
box-sizing: border-box;
@ -232,7 +232,7 @@
top: 50px;
right: 0;
background: #fafafa;
z-index: 9999;
z-index: 9;
overflow: auto;
display: none;
box-sizing: border-box;

@ -68,6 +68,7 @@ function createIcon(options, enableTooltips) {
}
}
el.tabIndex = -1;
el.className = options.className;
return el;
}
@ -171,7 +172,7 @@ function toggleFullScreen(editor) {
* Action for toggling bold.
*/
function toggleBold(editor) {
_toggleBlock(editor, "bold", "**");
_toggleBlock(editor, "bold", editor.options.blockStyles.bold);
}
@ -179,7 +180,7 @@ function toggleBold(editor) {
* Action for toggling italic.
*/
function toggleItalic(editor) {
_toggleBlock(editor, "italic", "*");
_toggleBlock(editor, "italic", editor.options.blockStyles.italic);
}
@ -283,6 +284,16 @@ function drawImage(editor) {
_replaceSelection(cm, stat.image, options.insertTexts.image);
}
/**
* Action for drawing a table.
*/
function drawTable(editor) {
var cm = editor.codemirror;
var stat = getState(cm);
var options = editor.options;
_replaceSelection(cm, stat.table, options.insertTexts.table);
}
/**
* Action for drawing a horizontal rule.
*/
@ -655,19 +666,20 @@ function wordCount(data) {
return count;
}
var toolbarBuiltInButtons = {
"bold": {
name: "bold",
action: toggleBold,
className: "fa fa-bold",
title: "Bold (Ctrl+B)"
title: "Bold (Ctrl+B)",
default: true
},
"italic": {
name: "italic",
action: toggleItalic,
className: "fa fa-italic",
title: "Italic (Ctrl+I)"
title: "Italic (Ctrl+I)",
default: true
},
"strikethrough": {
name: "strikethrough",
@ -679,7 +691,8 @@ var toolbarBuiltInButtons = {
name: "heading",
action: toggleHeadingSmaller,
className: "fa fa-header",
title: "Heading (Ctrl+H)"
title: "Heading (Ctrl+H)",
default: true
},
"heading-smaller": {
name: "heading-smaller",
@ -711,6 +724,9 @@ var toolbarBuiltInButtons = {
className: "fa fa-header fa-header-x fa-header-3",
title: "Small Heading"
},
"separator-1": {
name: "separator-1"
},
"code": {
name: "code",
action: toggleCodeBlock,
@ -721,31 +737,45 @@ var toolbarBuiltInButtons = {
name: "quote",
action: toggleBlockquote,
className: "fa fa-quote-left",
title: "Quote (Ctrl+')"
title: "Quote (Ctrl+')",
default: true
},
"unordered-list": {
name: "unordered-list",
action: toggleUnorderedList,
className: "fa fa-list-ul",
title: "Generic List (Ctrl+L)"
title: "Generic List (Ctrl+L)",
default: true
},
"ordered-list": {
name: "ordered-list",
action: toggleOrderedList,
className: "fa fa-list-ol",
title: "Numbered List (Ctrl+Alt+L)"
title: "Numbered List (Ctrl+Alt+L)",
default: true
},
"separator-2": {
name: "separator-2"
},
"link": {
name: "link",
action: drawLink,
className: "fa fa-link",
title: "Create Link (Ctrl+K)"
title: "Create Link (Ctrl+K)",
default: true
},
"image": {
name: "image",
action: drawImage,
className: "fa fa-picture-o",
title: "Insert Image (Ctrl+Alt+I)"
title: "Insert Image (Ctrl+Alt+I)",
default: true
},
"table": {
name: "table",
action: drawTable,
className: "fa fa-table",
title: "Insert Table"
},
"horizontal-rule": {
name: "horizontal-rule",
@ -753,38 +783,50 @@ var toolbarBuiltInButtons = {
className: "fa fa-minus",
title: "Insert Horizontal Line"
},
"separator-3": {
name: "separator-3"
},
"preview": {
name: "preview",
action: togglePreview,
className: "fa fa-eye no-disable",
title: "Toggle Preview (Ctrl+P)"
title: "Toggle Preview (Ctrl+P)",
default: true
},
"side-by-side": {
name: "side-by-side",
action: toggleSideBySide,
className: "fa fa-columns no-disable no-mobile",
title: "Toggle Side by Side (F9)"
title: "Toggle Side by Side (F9)",
default: true
},
"fullscreen": {
name: "fullscreen",
action: toggleFullScreen,
className: "fa fa-arrows-alt no-disable no-mobile",
title: "Toggle Fullscreen (F11)"
title: "Toggle Fullscreen (F11)",
default: true
},
"guide": {
name: "guide",
action: "http://nextstepwebs.github.io/simplemde-markdown-editor/markdown-guide",
className: "fa fa-question-circle",
title: "Markdown Guide"
title: "Markdown Guide",
default: true
}
};
var insertTexts = {
link: ["[", "](http://)"],
image: ["![](http://", ")"],
table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text | Text | Text |\n\n"],
horizontalRule: ["", "\n\n-----\n\n"]
};
var blockStyles = {
"bold": "**",
"italic": "*"
};
/**
* Interface of SimpleMDE.
@ -835,10 +877,28 @@ function SimpleMDE(options) {
}
// Handle toolbar and status bar
if(options.toolbar !== false)
options.toolbar = options.toolbar || SimpleMDE.toolbar;
// Handle toolbar
if(options.toolbar === undefined) {
// Initialize
options.toolbar = [];
// Loop over the built in buttons, to get the preferred order
for(var key in toolbarBuiltInButtons) {
if(toolbarBuiltInButtons.hasOwnProperty(key)) {
if(key.indexOf("separator-") != -1) {
options.toolbar.push("|");
}
if(toolbarBuiltInButtons[key].default === true || (options.showIcons && options.showIcons.constructor === Array && options.showIcons.indexOf(key) != -1)) {
options.toolbar.push(key);
}
}
}
}
// Handle status bar
if(!options.hasOwnProperty("status")) {
options.status = ["autosave", "lines", "words", "cursor"];
}
@ -861,6 +921,15 @@ function SimpleMDE(options) {
options.insertTexts = extend({}, insertTexts, options.insertTexts || {});
// Merging the blockStyles, with the given options
options.blockStyles = extend({}, blockStyles, options.blockStyles || {});
// Change unique_id to uniqueId for backwards compatibility
if(options.autosave != undefined && options.autosave.unique_id != undefined && options.autosave.unique_id != "")
options.autosave.uniqueId = options.autosave.unique_id;
// Update this options
this.options = options;
@ -872,16 +941,11 @@ function SimpleMDE(options) {
// 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) {
if(options.initialValue && (!this.options.autosave || this.options.autosave.foundSavedValue !== true)) {
this.value(options.initialValue);
}
}
/**
* Default toolbar elements.
*/
SimpleMDE.toolbar = ["bold", "italic", "heading", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "|", "preview", "side-by-side", "fullscreen", "guide"];
/**
* Default markdown render.
*/
@ -952,6 +1016,14 @@ SimpleMDE.prototype.render = function(el) {
if(cm.getOption("fullScreen")) toggleFullScreen(self);
};
document.addEventListener("keydown", function(e) {
e = e || window.event;
if(e.keyCode == 27) {
if(self.codemirror.getOption("fullScreen")) toggleFullScreen(self);
}
}, false);
var mode, backdrop;
if(options.spellChecker !== false) {
mode = "spell-checker";
@ -994,53 +1066,69 @@ SimpleMDE.prototype.render = function(el) {
};
SimpleMDE.prototype.autosave = function() {
var content = this.value();
var simplemde = this;
if(localStorage) {
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(this.options.autosave.uniqueId == undefined || this.options.autosave.uniqueId == "") {
console.log("SimpleMDE: You must set a uniqueId 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(simplemde.element.form != null && simplemde.element.form != undefined) {
simplemde.element.form.addEventListener("submit", function() {
localStorage.removeItem("smde_" + simplemde.options.autosave.uniqueId);
});
}
if(this.options.autosave.loaded !== true) {
if(typeof localStorage.getItem(this.options.autosave.unique_id) == "string" && localStorage.getItem(this.options.autosave.unique_id) != "")
this.codemirror.setValue(localStorage.getItem(this.options.autosave.unique_id));
if(this.options.autosave.loaded !== true) {
if(typeof localStorage.getItem("smde_" + this.options.autosave.uniqueId) == "string" && localStorage.getItem("smde_" + this.options.autosave.uniqueId) != "") {
this.codemirror.setValue(localStorage.getItem("smde_" + this.options.autosave.uniqueId));
this.options.autosave.foundSavedValue = true;
}
this.options.autosave.loaded = true;
}
this.options.autosave.loaded = true;
}
if(localStorage) {
localStorage.setItem(this.options.autosave.unique_id, content);
}
localStorage.setItem("smde_" + this.options.autosave.uniqueId, simplemde.value());
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;
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";
el.innerHTML = "Autosaved: " + h + ":" + m + " " + dd;
}
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);
} else {
console.log("SimpleMDE: localStorage not available, cannot autosave");
}
};
setTimeout(function() {
simplemde.autosave();
}, this.options.autosave.delay || 10000);
SimpleMDE.prototype.clearAutosavedValue = function() {
if(localStorage) {
if(this.options.autosave.uniqueId == undefined || this.options.autosave.uniqueId == "") {
console.log("SimpleMDE: You must set a uniqueId to use the autosave feature");
return;
}
localStorage.removeItem("smde_" + this.options.autosave.uniqueId);
} else {
console.log("SimpleMDE: localStorage not available, cannot autosave");
}
};
SimpleMDE.prototype.createSideBySide = function() {
@ -1238,6 +1326,7 @@ SimpleMDE.toggleUnorderedList = toggleUnorderedList;
SimpleMDE.toggleOrderedList = toggleOrderedList;
SimpleMDE.drawLink = drawLink;
SimpleMDE.drawImage = drawImage;
SimpleMDE.drawTable = drawTable;
SimpleMDE.drawHorizontalRule = drawHorizontalRule;
SimpleMDE.undo = undo;
SimpleMDE.redo = redo;
@ -1290,6 +1379,9 @@ SimpleMDE.prototype.drawLink = function() {
SimpleMDE.prototype.drawImage = function() {
drawImage(this);
};
SimpleMDE.prototype.drawTable = function() {
drawTable(this);
};
SimpleMDE.prototype.drawHorizontalRule = function() {
drawHorizontalRule(this);
};

Loading…
Cancel
Save