Merge pull request #277 from NextStepWebs/development

Allow destroying instance, Prompts, README changes, Fix bugs, More
pull/300/head 1.10.1
Wes Cossick 8 years ago
commit 6eae597a69

@ -1,9 +1,9 @@
# SimpleMDE - Markdown Editor
A drop-in JavaScript textarea replacement for writing beautiful and understandable Markdown. The WYSIWYG-esque editor allows users who may be less experienced with Markdown to use familiar toolbar buttons and shortcuts. In addition, the syntax is rendered while editing to clearly show the expected result. Headings are larger, emphasized words are italicized, links are underlined, etc. SimpleMDE is one of the first editors to feature both built-in autosaving and spell checking.
[**Demo**](http://nextstepwebs.github.io/simplemde-markdown-editor)
[**Demo**](https://simplemde.com)
[![Preview](http://i.imgur.com/zqWfJwO.png)](http://nextstepwebs.github.io/simplemde-markdown-editor)
[![Preview](http://i.imgur.com/zqWfJwO.png)](https://simplemde.com)
## Why not a WYSIWYG editor or pure Markdown?
WYSIWYG editors that produce HTML are often complex and buggy. Markdown solves this problem in many ways, plus Markdown can be rendered natively on more platforms than HTML. However, Markdown is not a syntax that an average user will be familiar with, nor is it visually clear while editing. In otherwords, for an unfamiliar user, the syntax they write will make little sense until they click the preview button. SimpleMDE has been designed to bridge this gap for non-technical users who are less familiar with or just learning Markdown syntax.
@ -75,8 +75,10 @@ simplemde.value("This text will appear in the editor");
- **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 `**`.
- **code** 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.
- **forceSync**: If set to `true`, force text changes made in SimpleMDE to be immediately stored in original textarea. Defaults to `false`.
- **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.
@ -92,6 +94,7 @@ simplemde.value("This text will appear in the editor");
- **underscoresBreakWords**: If set to `true`, let underscores be a delimiter for separating words. Defaults to `false`.
- **placeholder**: Custom placeholder that should be displayed
- **previewRender**: Custom function for parsing the plaintext Markdown and returning HTML. Used when user previews.
- **promptURLs**: If set to `true`, a JS alert window appears asking for the link or image URL. Defaults to `false`.
- **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">`
@ -118,6 +121,7 @@ var simplemde = new SimpleMDE({
italic: "_"
},
element: document.getElementById("MyID"),
forceSync: true,
hideIcons: ["guide", "heading"],
indentWithTabs: false,
initialValue: "Hello world!",
@ -144,6 +148,7 @@ var simplemde = new SimpleMDE({
return "Loading...";
},
promptURLs: true,
renderingConfig: {
singleLineBreaks: false,
codeSyntaxHighlighting: true,
@ -200,7 +205,7 @@ horizontal-rule | drawHorizontalRule | Insert Horizontal Line<br>fa fa-minus
preview | togglePreview | Toggle Preview<br>fa fa-eye no-disable
side-by-side | toggleSideBySide | Toggle Side by Side<br>fa fa-columns no-disable no-mobile
fullscreen | toggleFullScreen | Toggle Fullscreen<br>fa fa-arrows-alt no-disable no-mobile
guide | [This link](http://nextstepwebs.github.io/simplemde-markdown-editor/markdown-guide) | Markdown Guide<br>fa fa-question-circle
guide | [This link](https://simplemde.com/markdown-guide) | Markdown Guide<br>fa fa-question-circle
Customize the toolbar using the `toolbar` option like:
@ -297,6 +302,16 @@ simplemde.codemirror.on("change", function(){
});
```
## Removing SimpleMDE from textarea
You can revert to the initial textarea by calling the `toTextArea` method. Note that this clears up the autosave (if enabled) associated with it. The textarea will retain any text from the destroyed SimpleMDE instance.
```JavaScript
var simplemde = new SimpleMDE();
...
simplemde.toTextArea();
simplemde = null;
```
## Useful methods
The following self-explanatory methods may be of use while developing with SimpleMDE.
@ -309,25 +324,6 @@ simplemde.clearAutosavedValue(); // no returned value
```
## How it works
SimpleMDE is an improvement of [lepture's Editor project](https://github.com/lepture/editor) and includes a great many number of changes. It is bundled with [CodeMirror](https://github.com/codemirror/codemirror) and depends on [Font Awesome](http://fortawesome.github.io/Font-Awesome/).
SimpleMDE began as an improvement of [lepture's Editor project](https://github.com/lepture/editor), but has now taken on an identity of its own. It is bundled with [CodeMirror](https://github.com/codemirror/codemirror) and depends on [Font Awesome](http://fortawesome.github.io/Font-Awesome/).
CodeMirror is the backbone of the project and parses much of the Markdown syntax as it's being written. This allows us to add styles to the Markdown that's being written. Additionally, a toolbar and status bar have been added to the top and bottom, respectively. Previews are rendered by [Marked](https://github.com/chjj/marked) using GFM.
## What's changed?
As mentioned earlier, SimpleMDE is an improvement of [lepture's Editor project](https://github.com/lepture/editor). So you might be wondering, what's changed? Quite a bit actually. Here's some notable changes:
- Upgraded from CodeMirror 3 to CodeMirror 5
- Many changes to the style, appearance, and user friendliness
- Interface more closely resembles Bootstrap
- Now mobile friendly
- Option to autosave the text as you type
- Now spell checks what you write
- The text editor now automatically grows as you type more
- Fixed a large amount of bugs
- Switched to Font Awesome icons
- Improved preview rendering in many ways
- Improved as-you-type appearance of headers and code blocks
- Simplified the toolbar
- Many new options during instantiation
- New icons and tooltips
- Additional keyboard shortcuts

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

@ -1,5 +1,5 @@
/**
* simplemde v1.10.0
* simplemde v1.10.1
* Copyright Next Step Webs, Inc.
* @link https://github.com/NextStepWebs/simplemde-markdown-editor
* @license MIT
@ -171,7 +171,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actuall scrolling happens, thus preventing shaking and
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
@ -203,6 +203,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
/* Hack to make IE7 behave */
*zoom:1;
@ -340,332 +341,332 @@ div.CodeMirror-dragcursors {
span.CodeMirror-selectedtext { background: none; }
.CodeMirror {
height: auto;
min-height: 300px;
border: 1px solid #ddd;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
padding: 10px;
font: inherit;
z-index: 1;
height: auto;
min-height: 300px;
border: 1px solid #ddd;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
padding: 10px;
font: inherit;
z-index: 1;
}
.CodeMirror-scroll {
min-height: 300px
min-height: 300px
}
.CodeMirror-fullscreen {
background: #fff;
position: fixed !important;
top: 50px;
left: 0;
right: 0;
bottom: 0;
height: auto;
z-index: 9;
background: #fff;
position: fixed !important;
top: 50px;
left: 0;
right: 0;
bottom: 0;
height: auto;
z-index: 9;
}
.CodeMirror-sided {
width: 50% !important;
width: 50% !important;
}
.editor-toolbar {
position: relative;
opacity: .6;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
padding: 0 10px;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
position: relative;
opacity: .6;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
padding: 0 10px;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.editor-toolbar:after,
.editor-toolbar:before {
display: block;
content: ' ';
height: 1px;
display: block;
content: ' ';
height: 1px;
}
.editor-toolbar:before {
margin-bottom: 8px
margin-bottom: 8px
}
.editor-toolbar:after {
margin-top: 8px
margin-top: 8px
}
.editor-toolbar:hover,
.editor-wrapper input.title:focus,
.editor-wrapper input.title:hover {
opacity: .8
opacity: .8
}
.editor-toolbar.fullscreen {
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding-top: 10px;
padding-bottom: 10px;
box-sizing: border-box;
background: #fff;
border: 0;
position: fixed;
top: 0;
left: 0;
opacity: 1;
z-index: 9;
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding-top: 10px;
padding-bottom: 10px;
box-sizing: border-box;
background: #fff;
border: 0;
position: fixed;
top: 0;
left: 0;
opacity: 1;
z-index: 9;
}
.editor-toolbar.fullscreen::before {
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
position: fixed;
top: 0;
left: 0;
margin: 0;
padding: 0;
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
position: fixed;
top: 0;
left: 0;
margin: 0;
padding: 0;
}
.editor-toolbar.fullscreen::after {
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(255, 255, 255, 1)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
position: fixed;
top: 0;
right: 0;
margin: 0;
padding: 0;
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(255, 255, 255, 1)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
position: fixed;
top: 0;
right: 0;
margin: 0;
padding: 0;
}
.editor-toolbar a {
display: inline-block;
text-align: center;
text-decoration: none!important;
color: #2c3e50!important;
width: 30px;
height: 30px;
margin: 0;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
display: inline-block;
text-align: center;
text-decoration: none!important;
color: #2c3e50!important;
width: 30px;
height: 30px;
margin: 0;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
}
.editor-toolbar a.active,
.editor-toolbar a:hover {
background: #fcfcfc;
border-color: #95a5a6;
background: #fcfcfc;
border-color: #95a5a6;
}
.editor-toolbar a:before {
line-height: 30px
line-height: 30px
}
.editor-toolbar i.separator {
display: inline-block;
width: 0;
border-left: 1px solid #d9d9d9;
border-right: 1px solid #fff;
color: transparent;
text-indent: -10px;
margin: 0 6px;
display: inline-block;
width: 0;
border-left: 1px solid #d9d9d9;
border-right: 1px solid #fff;
color: transparent;
text-indent: -10px;
margin: 0 6px;
}
.editor-toolbar a.fa-header-x:after {
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
font-size: 65%;
vertical-align: text-bottom;
position: relative;
top: 2px;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
font-size: 65%;
vertical-align: text-bottom;
position: relative;
top: 2px;
}
.editor-toolbar a.fa-header-1:after {
content: "1";
content: "1";
}
.editor-toolbar a.fa-header-2:after {
content: "2";
content: "2";
}
.editor-toolbar a.fa-header-3:after {
content: "3";
content: "3";
}
.editor-toolbar a.fa-header-bigger:after {
content: "▲";
content: "▲";
}
.editor-toolbar a.fa-header-smaller:after {
content: "▼";
content: "▼";
}
.editor-toolbar.disabled-for-preview a:not(.no-disable) {
pointer-events: none;
background: #fff;
border-color: transparent;
text-shadow: inherit;
pointer-events: none;
background: #fff;
border-color: transparent;
text-shadow: inherit;
}
@media only screen and (max-width: 700px) {
.editor-toolbar a.no-mobile {
display: none;
}
.editor-toolbar a.no-mobile {
display: none;
}
}
.editor-statusbar {
padding: 8px 10px;
font-size: 12px;
color: #959694;
text-align: right;
padding: 8px 10px;
font-size: 12px;
color: #959694;
text-align: right;
}
.editor-statusbar span {
display: inline-block;
min-width: 4em;
margin-left: 1em;
display: inline-block;
min-width: 4em;
margin-left: 1em;
}
.editor-statusbar .lines:before {
content: 'lines: '
content: 'lines: '
}
.editor-statusbar .words:before {
content: 'words: '
content: 'words: '
}
.editor-statusbar .characters:before {
content: 'characters: '
content: 'characters: '
}
.editor-preview {
padding: 10px;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: #fafafa;
z-index: 7;
overflow: auto;
display: none;
box-sizing: border-box;
padding: 10px;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: #fafafa;
z-index: 7;
overflow: auto;
display: none;
box-sizing: border-box;
}
.editor-preview-side {
padding: 10px;
position: fixed;
bottom: 0;
width: 50%;
top: 50px;
right: 0;
background: #fafafa;
z-index: 9;
overflow: auto;
display: none;
box-sizing: border-box;
border: 1px solid #ddd;
padding: 10px;
position: fixed;
bottom: 0;
width: 50%;
top: 50px;
right: 0;
background: #fafafa;
z-index: 9;
overflow: auto;
display: none;
box-sizing: border-box;
border: 1px solid #ddd;
}
.editor-preview-active-side {
display: block
display: block
}
.editor-preview-active {
display: block
display: block
}
.editor-preview>p,
.editor-preview-side>p {
margin-top: 0
margin-top: 0
}
.editor-preview pre,
.editor-preview-side pre {
background: #eee;
margin-bottom: 10px;
background: #eee;
margin-bottom: 10px;
}
.editor-preview table td,
.editor-preview table th,
.editor-preview-side table td,
.editor-preview-side table th {
border: 1px solid #ddd;
padding: 5px;
border: 1px solid #ddd;
padding: 5px;
}
.CodeMirror .CodeMirror-code .cm-tag {
color: #63a35c;
color: #63a35c;
}
.CodeMirror .CodeMirror-code .cm-attribute {
color: #795da3;
color: #795da3;
}
.CodeMirror .CodeMirror-code .cm-string {
color: #183691;
color: #183691;
}
.CodeMirror .CodeMirror-selected {
background: #d9d9d9;
background: #d9d9d9;
}
.CodeMirror .CodeMirror-code .cm-header-1 {
font-size: 200%;
line-height: 200%;
font-size: 200%;
line-height: 200%;
}
.CodeMirror .CodeMirror-code .cm-header-2 {
font-size: 160%;
line-height: 160%;
font-size: 160%;
line-height: 160%;
}
.CodeMirror .CodeMirror-code .cm-header-3 {
font-size: 125%;
line-height: 125%;
font-size: 125%;
line-height: 125%;
}
.CodeMirror .CodeMirror-code .cm-header-4 {
font-size: 110%;
line-height: 110%;
font-size: 110%;
line-height: 110%;
}
.CodeMirror .CodeMirror-code .cm-comment {
background: rgba(0, 0, 0, .05);
border-radius: 2px;
background: rgba(0, 0, 0, .05);
border-radius: 2px;
}
.CodeMirror .CodeMirror-code .cm-link {
color: #7f8c8d;
color: #7f8c8d;
}
.CodeMirror .CodeMirror-code .cm-url {
color: #aab2b3;
color: #aab2b3;
}
.CodeMirror .CodeMirror-code .cm-strikethrough {
text-decoration: line-through;
text-decoration: line-through;
}
.CodeMirror .CodeMirror-placeholder {
opacity: .5;
opacity: .5;
}
.CodeMirror .cm-spell-error:not(.cm-url):not(.cm-comment):not(.cm-tag):not(.cm-word) {
background: rgba(255, 0, 0, .15);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -24,7 +24,7 @@ var banner = ["/**",
gulp.task("prettify-js", [], function() {
return gulp.src("./src/js/simplemde.js")
.pipe(prettify({js: {braceStyle: "collapse", indentChar: "\t", indentSize: 1, maxPreserveNewlines: 3, spaceBeforeConditional: false}}))
.pipe(prettify({js: {brace_style: "collapse", indent_char: "\t", indent_size: 1, max_preserve_newlines: 3, space_before_conditional: false}}))
.pipe(gulp.dest("./src/js"));
});

@ -1,69 +1,69 @@
{
"name": "simplemde",
"version": "1.10.0",
"version": "1.10.1",
"description": "A simple, beautiful, and embeddable JavaScript Markdown editor. Features autosaving and spell checking.",
"keywords": [
"embeddable",
"markdown",
"editor",
"javascript",
"wysiwyg"
"embeddable",
"markdown",
"editor",
"javascript",
"wysiwyg"
],
"homepage": "https://github.com/NextStepWebs/simplemde-markdown-editor",
"main": "./src/js/simplemde.js",
"license": "MIT",
"company": "Next Step Webs, Inc.",
"author": {
"name": "Wes Cossick",
"url": "http://www.WesCossick.com"
"name": "Wes Cossick",
"url": "http://www.WesCossick.com"
},
"bugs": {
"url": "https://github.com/NextStepWebs/simplemde-markdown-editor/issues"
"url": "https://github.com/NextStepWebs/simplemde-markdown-editor/issues"
},
"dependencies": {
"codemirror": "codemirror/CodeMirror",
"codemirror-spell-checker": "nextstepwebs/codemirror-spell-checker",
"marked": "0.3.5"
"codemirror": "codemirror/CodeMirror",
"codemirror-spell-checker": "nextstepwebs/codemirror-spell-checker",
"marked": "0.3.5"
},
"devDependencies": {
"browserify": "^11.2.0",
"browserify-shim": "^3.8.10",
"debug": "^2.2.0",
"eslint": "^1.6.0",
"gulp": "*",
"gulp-concat": "*",
"gulp-debug": "^2.1.1",
"gulp-eslint": "^1.0.0",
"gulp-header": "*",
"gulp-jsbeautifier": "*",
"gulp-minify-css": "^1.2.1",
"gulp-rename": "^1.2.2",
"gulp-uglify": "*",
"vinyl-source-stream": "^1.1.0",
"vinyl-buffer": "*"
"browserify": "^11.2.0",
"browserify-shim": "^3.8.10",
"debug": "^2.2.0",
"eslint": "*",
"gulp": "*",
"gulp-concat": "*",
"gulp-debug": "^2.1.1",
"gulp-eslint": "*",
"gulp-header": "*",
"gulp-jsbeautifier": "*",
"gulp-minify-css": "^1.2.1",
"gulp-rename": "^1.2.2",
"gulp-uglify": "*",
"vinyl-source-stream": "*",
"vinyl-buffer": "*"
},
"browserify": {
"transform": [
"browserify-shim"
]
"transform": [
"browserify-shim"
]
},
"browser": {
"spell-checker": "./node_modules/codemirror-spell-checker/src/js/spell-checker.js",
"typo": "./node_modules/codemirror-spell-checker/src/js/typo.js"
"spell-checker": "./node_modules/codemirror-spell-checker/src/js/spell-checker.js",
"typo": "./node_modules/codemirror-spell-checker/src/js/typo.js"
},
"browserify-shim": {
"spell-checker": {
"depends": [
"typo:Typo",
"codemirror:CodeMirror"
]
},
"typo": {
"exports": "Typo"
}
"spell-checker": {
"depends": [
"typo:Typo",
"codemirror:CodeMirror"
]
},
"typo": {
"exports": "Typo"
}
},
"repository": {
"type": "git",
"url": "https://github.com/NextStepWebs/simplemde-markdown-editor"
"type": "git",
"url": "https://github.com/NextStepWebs/simplemde-markdown-editor"
}
}

@ -1,328 +1,328 @@
.CodeMirror {
height: auto;
min-height: 300px;
border: 1px solid #ddd;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
padding: 10px;
font: inherit;
z-index: 1;
height: auto;
min-height: 300px;
border: 1px solid #ddd;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
padding: 10px;
font: inherit;
z-index: 1;
}
.CodeMirror-scroll {
min-height: 300px
min-height: 300px
}
.CodeMirror-fullscreen {
background: #fff;
position: fixed !important;
top: 50px;
left: 0;
right: 0;
bottom: 0;
height: auto;
z-index: 9;
background: #fff;
position: fixed !important;
top: 50px;
left: 0;
right: 0;
bottom: 0;
height: auto;
z-index: 9;
}
.CodeMirror-sided {
width: 50% !important;
width: 50% !important;
}
.editor-toolbar {
position: relative;
opacity: .6;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
padding: 0 10px;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
position: relative;
opacity: .6;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
padding: 0 10px;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.editor-toolbar:after,
.editor-toolbar:before {
display: block;
content: ' ';
height: 1px;
display: block;
content: ' ';
height: 1px;
}
.editor-toolbar:before {
margin-bottom: 8px
margin-bottom: 8px
}
.editor-toolbar:after {
margin-top: 8px
margin-top: 8px
}
.editor-toolbar:hover,
.editor-wrapper input.title:focus,
.editor-wrapper input.title:hover {
opacity: .8
opacity: .8
}
.editor-toolbar.fullscreen {
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding-top: 10px;
padding-bottom: 10px;
box-sizing: border-box;
background: #fff;
border: 0;
position: fixed;
top: 0;
left: 0;
opacity: 1;
z-index: 9;
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding-top: 10px;
padding-bottom: 10px;
box-sizing: border-box;
background: #fff;
border: 0;
position: fixed;
top: 0;
left: 0;
opacity: 1;
z-index: 9;
}
.editor-toolbar.fullscreen::before {
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
position: fixed;
top: 0;
left: 0;
margin: 0;
padding: 0;
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
position: fixed;
top: 0;
left: 0;
margin: 0;
padding: 0;
}
.editor-toolbar.fullscreen::after {
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(255, 255, 255, 1)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
position: fixed;
top: 0;
right: 0;
margin: 0;
padding: 0;
width: 20px;
height: 50px;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(255, 255, 255, 1)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
position: fixed;
top: 0;
right: 0;
margin: 0;
padding: 0;
}
.editor-toolbar a {
display: inline-block;
text-align: center;
text-decoration: none!important;
color: #2c3e50!important;
width: 30px;
height: 30px;
margin: 0;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
display: inline-block;
text-align: center;
text-decoration: none!important;
color: #2c3e50!important;
width: 30px;
height: 30px;
margin: 0;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
}
.editor-toolbar a.active,
.editor-toolbar a:hover {
background: #fcfcfc;
border-color: #95a5a6;
background: #fcfcfc;
border-color: #95a5a6;
}
.editor-toolbar a:before {
line-height: 30px
line-height: 30px
}
.editor-toolbar i.separator {
display: inline-block;
width: 0;
border-left: 1px solid #d9d9d9;
border-right: 1px solid #fff;
color: transparent;
text-indent: -10px;
margin: 0 6px;
display: inline-block;
width: 0;
border-left: 1px solid #d9d9d9;
border-right: 1px solid #fff;
color: transparent;
text-indent: -10px;
margin: 0 6px;
}
.editor-toolbar a.fa-header-x:after {
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
font-size: 65%;
vertical-align: text-bottom;
position: relative;
top: 2px;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
font-size: 65%;
vertical-align: text-bottom;
position: relative;
top: 2px;
}
.editor-toolbar a.fa-header-1:after {
content: "1";
content: "1";
}
.editor-toolbar a.fa-header-2:after {
content: "2";
content: "2";
}
.editor-toolbar a.fa-header-3:after {
content: "3";
content: "3";
}
.editor-toolbar a.fa-header-bigger:after {
content: "▲";
content: "▲";
}
.editor-toolbar a.fa-header-smaller:after {
content: "▼";
content: "▼";
}
.editor-toolbar.disabled-for-preview a:not(.no-disable) {
pointer-events: none;
background: #fff;
border-color: transparent;
text-shadow: inherit;
pointer-events: none;
background: #fff;
border-color: transparent;
text-shadow: inherit;
}
@media only screen and (max-width: 700px) {
.editor-toolbar a.no-mobile {
display: none;
}
.editor-toolbar a.no-mobile {
display: none;
}
}
.editor-statusbar {
padding: 8px 10px;
font-size: 12px;
color: #959694;
text-align: right;
padding: 8px 10px;
font-size: 12px;
color: #959694;
text-align: right;
}
.editor-statusbar span {
display: inline-block;
min-width: 4em;
margin-left: 1em;
display: inline-block;
min-width: 4em;
margin-left: 1em;
}
.editor-statusbar .lines:before {
content: 'lines: '
content: 'lines: '
}
.editor-statusbar .words:before {
content: 'words: '
content: 'words: '
}
.editor-statusbar .characters:before {
content: 'characters: '
content: 'characters: '
}
.editor-preview {
padding: 10px;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: #fafafa;
z-index: 7;
overflow: auto;
display: none;
box-sizing: border-box;
padding: 10px;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: #fafafa;
z-index: 7;
overflow: auto;
display: none;
box-sizing: border-box;
}
.editor-preview-side {
padding: 10px;
position: fixed;
bottom: 0;
width: 50%;
top: 50px;
right: 0;
background: #fafafa;
z-index: 9;
overflow: auto;
display: none;
box-sizing: border-box;
border: 1px solid #ddd;
padding: 10px;
position: fixed;
bottom: 0;
width: 50%;
top: 50px;
right: 0;
background: #fafafa;
z-index: 9;
overflow: auto;
display: none;
box-sizing: border-box;
border: 1px solid #ddd;
}
.editor-preview-active-side {
display: block
display: block
}
.editor-preview-active {
display: block
display: block
}
.editor-preview>p,
.editor-preview-side>p {
margin-top: 0
margin-top: 0
}
.editor-preview pre,
.editor-preview-side pre {
background: #eee;
margin-bottom: 10px;
background: #eee;
margin-bottom: 10px;
}
.editor-preview table td,
.editor-preview table th,
.editor-preview-side table td,
.editor-preview-side table th {
border: 1px solid #ddd;
padding: 5px;
border: 1px solid #ddd;
padding: 5px;
}
.CodeMirror .CodeMirror-code .cm-tag {
color: #63a35c;
color: #63a35c;
}
.CodeMirror .CodeMirror-code .cm-attribute {
color: #795da3;
color: #795da3;
}
.CodeMirror .CodeMirror-code .cm-string {
color: #183691;
color: #183691;
}
.CodeMirror .CodeMirror-selected {
background: #d9d9d9;
background: #d9d9d9;
}
.CodeMirror .CodeMirror-code .cm-header-1 {
font-size: 200%;
line-height: 200%;
font-size: 200%;
line-height: 200%;
}
.CodeMirror .CodeMirror-code .cm-header-2 {
font-size: 160%;
line-height: 160%;
font-size: 160%;
line-height: 160%;
}
.CodeMirror .CodeMirror-code .cm-header-3 {
font-size: 125%;
line-height: 125%;
font-size: 125%;
line-height: 125%;
}
.CodeMirror .CodeMirror-code .cm-header-4 {
font-size: 110%;
line-height: 110%;
font-size: 110%;
line-height: 110%;
}
.CodeMirror .CodeMirror-code .cm-comment {
background: rgba(0, 0, 0, .05);
border-radius: 2px;
background: rgba(0, 0, 0, .05);
border-radius: 2px;
}
.CodeMirror .CodeMirror-code .cm-link {
color: #7f8c8d;
color: #7f8c8d;
}
.CodeMirror .CodeMirror-code .cm-url {
color: #aab2b3;
color: #aab2b3;
}
.CodeMirror .CodeMirror-code .cm-strikethrough {
text-decoration: line-through;
text-decoration: line-through;
}
.CodeMirror .CodeMirror-placeholder {
opacity: .5;
opacity: .5;
}

@ -253,7 +253,286 @@ function toggleStrikethrough(editor) {
* Action for toggling code block.
*/
function toggleCodeBlock(editor) {
_toggleBlock(editor, "code", "```\r\n", "\r\n```");
var fenceCharsToInsert = editor.options.blockStyles.code;
function fencing_line(line) {
/* return true, if this is a ``` or ~~~ line */
if(typeof line !== "object") {
throw "fencing_line() takes a 'line' object (not a line number, or line text). Got: " + typeof line + ": " + line;
}
return line.styles && line.styles[2] && line.styles[2].indexOf("formatting-code-block") !== -1;
}
function token_state(token) {
// base goes an extra level deep when mode backdrops are used, e.g. spellchecker on
return token.state.base.base || token.state.base;
}
function code_type(cm, line_num, line, firstTok, lastTok) {
/*
* Return "single", "indented", "fenced" or false
*
* cm and line_num are required. Others are optional for efficiency
* To check in the middle of a line, pass in firstTok yourself.
*/
line = line || cm.getLineHandle(line_num);
firstTok = firstTok || cm.getTokenAt({
line: line_num,
ch: 1
});
lastTok = lastTok || (!!line.text && cm.getTokenAt({
line: line_num,
ch: line.text.length - 1
}));
var types = firstTok.type ? firstTok.type.split(" ") : [];
if(lastTok && token_state(lastTok).indentedCode) {
// have to check last char, since first chars of first line aren"t marked as indented
return "indented";
} else if(types.indexOf("comment") === -1) {
// has to be after "indented" check, since first chars of first indented line aren"t marked as such
return false;
} else if(token_state(firstTok).fencedChars || token_state(lastTok).fencedChars || fencing_line(line)) {
return "fenced";
} else {
return "single";
}
}
function insertFencingAtSelection(cm, cur_start, cur_end, fenceCharsToInsert) {
var start_line_sel = cur_start.line + 1,
end_line_sel = cur_end.line + 1,
sel_multi = cur_start.line !== cur_end.line,
repl_start = fenceCharsToInsert + "\n",
repl_end = "\n" + fenceCharsToInsert;
if(sel_multi) {
end_line_sel++;
}
// handle last char including \n or not
if(sel_multi && cur_end.ch === 0) {
repl_end = fenceCharsToInsert + "\n";
end_line_sel--;
}
_replaceSelection(cm, false, [repl_start, repl_end]);
cm.setSelection({
line: start_line_sel,
ch: 0
}, {
line: end_line_sel,
ch: 0
});
}
var cm = editor.codemirror,
cur_start = cm.getCursor("start"),
cur_end = cm.getCursor("end"),
tok = cm.getTokenAt({
line: cur_start.line,
ch: cur_start.ch || 1
}), // avoid ch 0 which is a cursor pos but not token
line = cm.getLineHandle(cur_start.line),
is_code = code_type(cm, cur_start.line, line, tok);
var block_start, block_end, lineCount;
if(is_code === "single") {
// similar to some SimpleMDE _toggleBlock logic
var start = line.text.slice(0, cur_start.ch).replace("`", ""),
end = line.text.slice(cur_start.ch).replace("`", "");
cm.replaceRange(start + end, {
line: cur_start.line,
ch: 0
}, {
line: cur_start.line,
ch: 99999999999999
});
cur_start.ch--;
if(cur_start !== cur_end) {
cur_end.ch--;
}
cm.setSelection(cur_start, cur_end);
cm.focus();
} else if(is_code === "fenced") {
if(cur_start.line !== cur_end.line || cur_start.ch !== cur_end.ch) {
// use selection
// find the fenced line so we know what type it is (tilde, backticks, number of them)
for(block_start = cur_start.line; block_start >= 0; block_start--) {
line = cm.getLineHandle(block_start);
if(fencing_line(line)) {
break;
}
}
var fencedTok = cm.getTokenAt({
line: block_start,
ch: 1
});
var fence_chars = token_state(fencedTok).fencedChars;
var start_text, start_line;
var end_text, end_line;
// check for selection going up against fenced lines, in which case we don't want to add more fencing
if(fencing_line(cm.getLineHandle(cur_start.line))) {
start_text = "";
start_line = cur_start.line;
} else if(fencing_line(cm.getLineHandle(cur_start.line - 1))) {
start_text = "";
start_line = cur_start.line - 1;
} else {
start_text = fence_chars + "\n";
start_line = cur_start.line;
}
if(fencing_line(cm.getLineHandle(cur_end.line))) {
end_text = "";
end_line = cur_end.line;
if(cur_end.ch === 0) {
end_line += 1;
}
} else if(cur_end.ch !== 0 && fencing_line(cm.getLineHandle(cur_end.line + 1))) {
end_text = "";
end_line = cur_end.line + 1;
} else {
end_text = fence_chars + "\n";
end_line = cur_end.line + 1;
}
if(cur_end.ch === 0) {
// full last line selected, putting cursor at beginning of next
end_line -= 1;
}
cm.operation(function() {
// end line first, so that line numbers don't change
cm.replaceRange(end_text, {
line: end_line,
ch: 0
}, {
line: end_line + (end_text ? 0 : 1),
ch: 0
});
cm.replaceRange(start_text, {
line: start_line,
ch: 0
}, {
line: start_line + (start_text ? 0 : 1),
ch: 0
});
});
cm.setSelection({
line: start_line + (start_text ? 1 : 0),
ch: 0
}, {
line: end_line + (start_text ? 1 : -1),
ch: 0
});
cm.focus();
} else {
// no selection, search for ends of this fenced block
var search_from = cur_start.line;
if(fencing_line(cm.getLineHandle(cur_start.line))) { // gets a little tricky if cursor is right on a fenced line
if(code_type(cm, cur_start.line + 1) === "fenced") {
block_start = cur_start.line;
search_from = cur_start.line + 1; // for searching for "end"
} else {
block_end = cur_start.line;
search_from = cur_start.line - 1; // for searching for "start"
}
}
if(block_start === undefined) {
for(block_start = search_from; block_start >= 0; block_start--) {
line = cm.getLineHandle(block_start);
if(fencing_line(line)) {
break;
}
}
}
if(block_end === undefined) {
lineCount = cm.lineCount();
for(block_end = search_from; block_end < lineCount; block_end++) {
line = cm.getLineHandle(block_end);
if(fencing_line(line)) {
break;
}
}
}
cm.operation(function() {
cm.replaceRange("", {
line: block_start,
ch: 0
}, {
line: block_start + 1,
ch: 0
});
cm.replaceRange("", {
line: block_end - 1,
ch: 0
}, {
line: block_end,
ch: 0
});
});
cm.focus();
}
} else if(is_code === "indented") {
if(cur_start.line !== cur_end.line || cur_start.ch !== cur_end.ch) {
// use selection
block_start = cur_start.line;
block_end = cur_end.line;
if(cur_end.ch === 0) {
block_end--;
}
} else {
// no selection, search for ends of this indented block
for(block_start = cur_start.line; block_start >= 0; block_start--) {
line = cm.getLineHandle(block_start);
if(line.text.match(/^\s*$/)) {
// empty or all whitespace - keep going
continue;
} else {
if(code_type(cm, block_start, line) !== "indented") {
block_start += 1;
break;
}
}
}
lineCount = cm.lineCount();
for(block_end = cur_start.line; block_end < lineCount; block_end++) {
line = cm.getLineHandle(block_end);
if(line.text.match(/^\s*$/)) {
// empty or all whitespace - keep going
continue;
} else {
if(code_type(cm, block_end, line) !== "indented") {
block_end -= 1;
break;
}
}
}
}
// if we are going to un-indent based on a selected set of lines, and the next line is indented too, we need to
// insert a blank line so that the next line(s) continue to be indented code
var next_line = cm.getLineHandle(block_end + 1),
next_line_last_tok = next_line && cm.getTokenAt({
line: block_end + 1,
ch: next_line.text.length - 1
}),
next_line_indented = next_line_last_tok && token_state(next_line_last_tok).indentedCode;
if(next_line_indented) {
cm.replaceRange("\n", {
line: block_end + 1,
ch: 0
});
}
for(var i = block_start; i <= block_end; i++) {
cm.indentLine(i, "subtract"); // TODO: this doesn't get tracked in the history, so can't be undone :(
}
cm.focus();
} else {
// insert code formatting
var no_sel_and_starting_of_line = (cur_start.line === cur_end.line && cur_start.ch === cur_end.ch && cur_start.ch === 0);
var sel_multi = cur_start.line !== cur_end.line;
if(no_sel_and_starting_of_line || sel_multi) {
insertFencingAtSelection(cm, cur_start, cur_end, fenceCharsToInsert);
} else {
_replaceSelection(cm, false, ["`", "`"]);
}
}
}
/**
@ -337,7 +616,14 @@ function drawLink(editor) {
var cm = editor.codemirror;
var stat = getState(cm);
var options = editor.options;
_replaceSelection(cm, stat.link, options.insertTexts.link);
var url = "http://";
if(options.promptURLs) {
url = prompt(options.promptTexts.link);
if(!url) {
return false;
}
}
_replaceSelection(cm, stat.link, options.insertTexts.link, url);
}
/**
@ -347,7 +633,14 @@ function drawImage(editor) {
var cm = editor.codemirror;
var stat = getState(cm);
var options = editor.options;
_replaceSelection(cm, stat.image, options.insertTexts.image);
var url = "http://";
if(options.promptURLs) {
url = prompt(options.promptTexts.image);
if(!url) {
return false;
}
}
_replaceSelection(cm, stat.image, options.insertTexts.image, url);
}
/**
@ -456,7 +749,7 @@ function togglePreview(editor) {
var cm = editor.codemirror;
var wrapper = cm.getWrapperElement();
var toolbar_div = wrapper.previousSibling;
var toolbar = editor.toolbarElements.preview;
var toolbar = editor.options.toolbar ? editor.toolbarElements.preview : false;
var preview = wrapper.lastChild;
if(!preview || !/editor-preview/.test(preview.className)) {
preview = document.createElement("div");
@ -467,8 +760,10 @@ function togglePreview(editor) {
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, "");
if(toolbar) {
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,
@ -476,8 +771,10 @@ function togglePreview(editor) {
setTimeout(function() {
preview.className += " editor-preview-active";
}, 1);
toolbar.className += " active";
toolbar_div.className += " disabled-for-preview";
if(toolbar) {
toolbar.className += " active";
toolbar_div.className += " disabled-for-preview";
}
}
preview.innerHTML = editor.options.previewRender(editor.value(), preview);
@ -487,7 +784,7 @@ function togglePreview(editor) {
toggleSideBySide(editor);
}
function _replaceSelection(cm, active, startEnd) {
function _replaceSelection(cm, active, startEnd, url) {
if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className))
return;
@ -496,6 +793,9 @@ function _replaceSelection(cm, active, startEnd) {
var end = startEnd[1];
var startPoint = cm.getCursor("start");
var endPoint = cm.getCursor("end");
if(url) {
end = end.replace("#url#", url);
}
if(active) {
text = cm.getLine(startPoint.line);
start = text.slice(0, startPoint.ch);
@ -914,7 +1214,7 @@ var toolbarBuiltInButtons = {
},
"guide": {
name: "guide",
action: "http://nextstepwebs.github.io/simplemde-markdown-editor/markdown-guide",
action: "https://simplemde.com/markdown-guide",
className: "fa fa-question-circle",
title: "Markdown Guide",
default: true
@ -937,14 +1237,20 @@ var toolbarBuiltInButtons = {
};
var insertTexts = {
link: ["[", "](http://)"],
image: ["![](http://", ")"],
link: ["[", "](#url#)"],
image: ["![", "](#url#)"],
table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text | Text | Text |\n\n"],
horizontalRule: ["", "\n\n-----\n\n"]
};
var promptTexts = {
link: "URL for the link:",
image: "URL of the image:"
};
var blockStyles = {
"bold": "**",
"code": "```",
"italic": "*"
};
@ -1034,13 +1340,19 @@ function SimpleMDE(options) {
// Set default options for parsing config
options.parsingConfig = options.parsingConfig || {};
options.parsingConfig = extend({
highlightFormatting: true // needed for toggleCodeBlock to detect types of code
}, options.parsingConfig || {});
// Merging the insertTexts, with the given options
options.insertTexts = extend({}, insertTexts, options.insertTexts || {});
// Merging the promptTexts, with the given options
options.promptTexts = promptTexts;
// Merging the blockStyles, with the given options
options.blockStyles = extend({}, blockStyles, options.blockStyles || {});
@ -1080,7 +1392,9 @@ SimpleMDE.prototype.markdown = function(text) {
// Update options
if(this.options && this.options.renderingConfig && this.options.renderingConfig.singleLineBreaks !== false) {
if(this.options && this.options.renderingConfig && this.options.renderingConfig.singleLineBreaks === false) {
markedOptions.breaks = false;
} else {
markedOptions.breaks = true;
}
@ -1172,23 +1486,48 @@ SimpleMDE.prototype.render = function(el) {
placeholder: options.placeholder || el.getAttribute("placeholder") || ""
});
if(options.forceSync === true) {
var cm = this.codemirror;
cm.on("change", function() {
cm.save();
});
}
this.gui = {};
if(options.toolbar !== false) {
this.createToolbar();
this.gui.toolbar = this.createToolbar();
}
if(options.status !== false) {
this.createStatusbar();
this.gui.statusbar = this.createStatusbar();
}
if(options.autosave != undefined && options.autosave.enabled === true) {
this.autosave();
}
this.createSideBySide();
this.gui.sideBySide = this.createSideBySide();
this._rendered = this.element;
};
// Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem throw QuotaExceededError. We're going to detect this and set a variable accordingly.
function isLocalStorageAvailable() {
if(typeof localStorage === "object") {
try {
localStorage.setItem("smde_localStorage", 1);
localStorage.removeItem("smde_localStorage");
} catch(e) {
return false;
}
} else {
return false;
}
return true;
}
SimpleMDE.prototype.autosave = function() {
if(localStorage) {
if(isLocalStorageAvailable()) {
var simplemde = this;
if(this.options.autosave.uniqueId == undefined || this.options.autosave.uniqueId == "") {
@ -1232,7 +1571,7 @@ SimpleMDE.prototype.autosave = function() {
el.innerHTML = "Autosaved: " + h + ":" + m + " " + dd;
}
setTimeout(function() {
this.autosaveTimeoutId = setTimeout(function() {
simplemde.autosave();
}, this.options.autosave.delay || 10000);
} else {
@ -1241,7 +1580,7 @@ SimpleMDE.prototype.autosave = function() {
};
SimpleMDE.prototype.clearAutosavedValue = function() {
if(localStorage) {
if(isLocalStorageAvailable()) {
if(this.options.autosave == undefined || this.options.autosave.uniqueId == undefined || this.options.autosave.uniqueId == "") {
console.log("SimpleMDE: You must set a uniqueId to clear the autosave value");
return;
@ -1291,7 +1630,7 @@ SimpleMDE.prototype.createSideBySide = function() {
var move = (cm.getScrollInfo().height - cm.getScrollInfo().clientHeight) * ratio;
cm.scrollTo(0, move);
};
return true;
return preview;
};
SimpleMDE.prototype.createToolbar = function(items) {
@ -1333,7 +1672,9 @@ SimpleMDE.prototype.createToolbar = function(items) {
var nonSeparatorIconsFollow = false;
for(var x = (i + 1); x < items.length; x++) {
if(items[x] !== "|") {
console.log(x);
if(items[x] !== "|" && (!self.options.hideIcons || self.options.hideIcons.indexOf(items[x].name) == -1)) {
console.log(items[x]);
nonSeparatorIconsFollow = true;
}
}
@ -1644,4 +1985,21 @@ SimpleMDE.prototype.getState = function() {
return getState(cm);
};
module.exports = SimpleMDE;
SimpleMDE.prototype.toTextArea = function() {
var cm = this.codemirror;
var wrapper = cm.getWrapperElement();
wrapper.parentNode.removeChild(this.gui.toolbar);
wrapper.parentNode.removeChild(this.gui.statusbar);
wrapper.parentNode.removeChild(this.gui.sideBySide);
cm.toTextArea();
if(this.autosaveTimeoutId) {
clearTimeout(this.autosaveTimeoutId);
this.autosaveTimeoutId = undefined;
this.clearAutosavedValue();
}
};
module.exports = SimpleMDE;
Loading…
Cancel
Save