Switch to ACE editor

This commit is contained in:
benweet 2013-09-09 01:08:55 +01:00
parent e9a3d5f97f
commit 24ba484010
19 changed files with 624 additions and 113 deletions

View File

@ -19,6 +19,7 @@
"FileSaver": "*",
"stacktrace": "~0.5.3",
"requirejs-text": "~2.0.10",
"bootstrap-tour": "~0.6.0"
"bootstrap-tour": "~0.6.0",
"ace": "~1.1.1"
}
}

View File

@ -1,5 +1,5 @@
CACHE MANIFEST
#Date Wed Sep 04 2013 00:36:42
#Date Sat Sep 07 2013 23:38:12
CACHE:
index.html

View File

@ -9773,7 +9773,7 @@ if (hljs.LANGUAGES.glsl = function(e) {
});
}, c;
}), define("text!html/mathJaxSettingsBlock.html", [], function() {
return '<p>Allows StackEdit to interpret LaTeX mathematical expressions.</p>\n<div class="form-horizontal">\n <div class="form-group">\n <label class="col-lg-4 control-label"\n for="input-mathjax-config-tex">TeX configuration</label>\n <div class="col-lg-7">\n <input type="text" id="input-mathjax-config-tex" class="form-control">\n </div>\n </div>\n <div class="form-group">\n <label class="col-lg-4 control-label"\n for="input-mathjax-config-tex2jax">tex2jax configuration</label>\n <div class="col-lg-7">\n <input type="text" id="input-mathjax-config-tex2jax" class="form-control">\n </div>\n </div>\n</div>\n<span class="help-block pull-right"><a target="_blank" href="http://docs.mathjax.org/en/latest/options/">More info</a></span>';
return '<p>Allows StackEdit to interpret LaTeX mathematical expressions.</p>\n<div class="form-horizontal">\n <div class="form-group">\n <label class="col-lg-4 control-label"\n for="input-mathjax-config-tex">TeX configuration</label>\n <div class="col-lg-7">\n <input type="text" id="input-mathjax-config-tex" class="form-control">\n </div>\n </div>\n <div class="form-group">\n <label class="col-lg-4 control-label"\n for="input-mathjax-config-tex2jax">tex2jax configuration</label>\n <div class="col-lg-7">\n <input type="text" id="input-mathjax-config-tex2jax" class="form-control">\n </div>\n </div>\n</div>\n<span class="help-block pull-right"><a target="_blank" href="http://docs.mathjax.org/en/latest/options/index.html">More info</a></span>';
}), define("extensions/mathJax", [ "utils", "classes/Extension", "text!html/mathJaxSettingsBlock.html", "mathjax" ], function(utils, Extension, mathJaxSettingsBlockHTML) {
function b(e, t, n) {
var r = k.slice(e, t + 1).join("").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@ -11190,6 +11190,18 @@ function(e) {
t.restart();
});
}, n;
}), define("extensions/richTextarea", [ "jquery", "underscore", "crel", "utils", "classes/Extension" ], function(e, t, n, i, o) {
var r = new o("richTextarea", "Rich Textarea", !1, !0), a = [ "box-sizing", "height", "width", "padding-bottom", "padding-left", "padding-right", "padding-top", "font-family", "font-size", "font-style", "font-variant", "font-weight", "word-spacing", "letter-spacing", "line-height", "text-decoration", "text-indent", "text-transform", "direction" ];
return r.onReady = function() {
var t = n("div", {
style: [ "position : absolute", "overflow : auto", "white-space : pre-wrap", "word-wrap : break-word", "top : 0", "z-index : -1", "overflow : hidden" ].join(";")
});
document.body.appendChild(t);
for (var i, o = e("#wmd-input"), r = {}, s = 0; i = a[s]; s++) r[i] = o.css(i);
e(t).css(r).unbind().offset(o.offset()), o.on("keyup paste cut mouseup", function() {
e(t).text(o.val()).scrollTop(o.scrollTop()).outerWidth(o[0].clientWidth);
});
}, r;
}), function(e) {
var t = "waitForImages";
e.waitForImages = {
@ -11230,7 +11242,7 @@ function(e) {
});
});
};
}(jQuery), define("jquery-waitforimages", function() {}), define("eventMgr", [ "jquery", "underscore", "crel", "utils", "classes/Extension", "settings", "text!html/settingsExtensionsAccordion.html", "extensions/partialRendering", "extensions/userCustom", "extensions/buttonMarkdownSyntax", "extensions/googleAnalytics", "extensions/dialogAbout", "extensions/dialogManagePublication", "extensions/dialogManageSynchronization", "extensions/dialogOpenHarddrive", "extensions/documentTitle", "extensions/documentSelector", "extensions/documentPanel", "extensions/documentManager", "extensions/workingIndicator", "extensions/notifications", "extensions/markdownExtra", "extensions/toc", "extensions/mathJax", "extensions/emailConverter", "extensions/scrollLink", "extensions/buttonSync", "extensions/buttonPublish", "extensions/buttonShare", "extensions/buttonStat", "extensions/buttonHtmlCode", "extensions/buttonViewer", "extensions/welcomeTour", "bootstrap", "jquery-waitforimages" ], function(e, t, n, i, o, r, a) {
}(jQuery), define("jquery-waitforimages", function() {}), define("eventMgr", [ "jquery", "underscore", "crel", "utils", "classes/Extension", "settings", "text!html/settingsExtensionsAccordion.html", "extensions/partialRendering", "extensions/userCustom", "extensions/buttonMarkdownSyntax", "extensions/googleAnalytics", "extensions/dialogAbout", "extensions/dialogManagePublication", "extensions/dialogManageSynchronization", "extensions/dialogOpenHarddrive", "extensions/documentTitle", "extensions/documentSelector", "extensions/documentPanel", "extensions/documentManager", "extensions/workingIndicator", "extensions/notifications", "extensions/markdownExtra", "extensions/toc", "extensions/mathJax", "extensions/emailConverter", "extensions/scrollLink", "extensions/buttonSync", "extensions/buttonPublish", "extensions/buttonShare", "extensions/buttonStat", "extensions/buttonHtmlCode", "extensions/buttonViewer", "extensions/welcomeTour", "extensions/richTextarea", "bootstrap", "jquery-waitforimages" ], function(e, t, n, i, o, r, a) {
function s(e) {
return t.chain(d).map(function(t) {
return t.enabled && t[e];
@ -16214,6 +16226,26 @@ function(e) {
}), p.onError(function(e) {
u(e);
}), p.enqueue();
}, d.rename = function(e, t, n) {
var i = void 0, l = new o();
r(l), a(l), l.onRun(function() {
var n = {
title: t
}, o = gapi.client.drive.files.patch({
fileId: e,
resource: n
});
o.execute(function(t) {
if (t && t.id) return i = t, l.chain(), void 0;
var n = t.error;
void 0 !== n && void 0 !== e && 404 === n.code && (n = 'File ID "' + e + '" not found on Google Drive.|removePublish'),
s(n, l);
});
}), l.onSuccess(function() {
n(void 0, i);
}), l.onError(function(e) {
n(e);
}), l.enqueue();
}, d.createRealtimeFile = function(e, t, n) {
var i = void 0, l = new o();
r(l), a(l), l.onRun(function() {
@ -16518,11 +16550,17 @@ function(e) {
o(void 0, r);
});
}, d.syncUp = function(e, t, n, i, o, r) {
var s = o.contentCRC, l = o.titleCRC;
return t == s && i == l ? (r(void 0, !1), void 0) : (a.upload(o.id, void 0, n, e, o.etag, function(e, n) {
return t == o.contentCRC && i == o.titleCRC ? (r(void 0, !1), void 0) : (a.upload(o.id, void 0, n, e, o.etag, function(e, n) {
return e ? (r(e, !0), void 0) : (o.etag = n.etag, o.contentCRC = t, o.titleCRC = i,
r(void 0, !0), void 0);
}), void 0);
}, d.syncUpRealtime = function(e, t, n, i, o, r) {
var s = !1;
return t != o.contentCRC && (o.contentCRC = t, s = !0), i == o.titleCRC ? (r(void 0, s),
void 0) : (a.rename(o.id, n, function(e, t) {
return e ? (r(e, !0), void 0) : (o.etag = t.etag, o.titleCRC = i, r(void 0, !0),
void 0);
}), void 0);
}, d.syncDown = function(n) {
var i = parseInt(localStorage[u + ".lastChangeId"]);
a.checkChanges(i, function(i, l, c) {
@ -16636,11 +16674,11 @@ function(e) {
}), define("synchronizer", [ "jquery", "underscore", "utils", "eventMgr", "fileSystem", "fileMgr", "classes/Provider", "providers/dropboxProvider", "providers/gdriveProvider" ], function(e, t, n, i, o, r, a) {
function s(e) {
if (0 === b.length) return l(e), void 0;
var t = b.pop();
return t.isRealtime === !0 ? (s(e), void 0) : (t.provider.syncUp(y, x, w, C, t, function(i, o) {
var t = b.pop(), i = t.provider.syncUp;
t.isRealtime === !0 && (i = t.provider.syncUpRealtime), i(y, x, w, C, t, function(i, o) {
return o === !0 && (S = !0), i ? (e(i), void 0) : (o && n.storeAttributes(t), s(e),
void 0);
}), void 0);
});
}
function l(e) {
if (0 === k.length) return c(e), void 0;

View File

@ -1477,7 +1477,7 @@ blockquote{border-left-width:10px}
blockquote p{margin-bottom:15px;font-size:14px;line-height:20px}
blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}
ul,ol{margin-bottom:15px}
#wmd-input{-webkit-box-shadow:none;box-shadow:none}
#wmd-input{-webkit-box-shadow:none;box-shadow:none;background-color:transparent}
#wmd-input,#md-section-helper{resize:none;border:none !important}
#md-section-helper{position:absolute;top:-100px;height:1px;padding:0 6px;overflow-y:scroll;z-index:-1}
.gecko #md-section-helper{height:40px}

View File

@ -1477,7 +1477,7 @@ blockquote{border-left-width:10px}
blockquote p{margin-bottom:15px;font-size:14px;line-height:20px}
blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}
ul,ol{margin-bottom:15px}
#wmd-input{-webkit-box-shadow:none;box-shadow:none}
#wmd-input{-webkit-box-shadow:none;box-shadow:none;background-color:transparent}
#wmd-input,#md-section-helper{resize:none;border:none !important}
#md-section-helper{position:absolute;top:-100px;height:1px;padding:0 6px;overflow-y:scroll;z-index:-1}
.gecko #md-section-helper{height:40px}

View File

@ -1477,7 +1477,7 @@ blockquote{border-left-width:10px}
blockquote p{margin-bottom:15px;font-size:14px;line-height:20px}
blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}
ul,ol{margin-bottom:15px}
#wmd-input{-webkit-box-shadow:none;box-shadow:none}
#wmd-input{-webkit-box-shadow:none;box-shadow:none;background-color:transparent}
#wmd-input,#md-section-helper{resize:none;border:none !important}
#md-section-helper{position:absolute;top:-100px;height:1px;padding:0 6px;overflow-y:scroll;z-index:-1}
.gecko #md-section-helper{height:40px}

View File

@ -1,10 +1,26 @@
define(["underscore", "utils"], function(_, utils) {
define([
"underscore",
"utils",
"ace/range"
], function(_, utils, range) {
var Range = range.Range;
function FileDescriptor(fileIndex, title, syncLocations, publishLocations) {
this.fileIndex = fileIndex;
this._title = title || localStorage[fileIndex + ".title"];
this._editorScrollTop = parseInt(localStorage[fileIndex + ".editorScrollTop"]) || 0;
this._editorStart = parseInt(localStorage[fileIndex + ".editorStart"]) || 0;
this._editorSelectRange = (function() {
try {
var rangeComponents = localStorage[fileIndex + ".editorSelectRange"].split(';');
rangeComponents = _.map(rangeComponents, function(component) {
return parseInt(component);
});
return new Range(rangeComponents[0], rangeComponents[1], rangeComponents[2], rangeComponents[3]);
}
catch(e) {
return new Range();
}
})();
this._editorEnd = parseInt(localStorage[fileIndex + ".editorEnd"]) || 0;
this._previewScrollTop = parseInt(localStorage[fileIndex + ".previewScrollTop"]) || 0;
this._selectTime = parseInt(localStorage[fileIndex + ".selectTime"]) || 0;
@ -36,22 +52,18 @@ define(["underscore", "utils"], function(_, utils) {
localStorage[this.fileIndex + ".editorScrollTop"] = editorScrollTop;
}
});
Object.defineProperty(this, 'editorStart', {
Object.defineProperty(this, 'editorSelectRange', {
get: function() {
return this._editorStart;
return this._editorSelectRange;
},
set: function(editorStart) {
this._editorStart = editorStart;
localStorage[this.fileIndex + ".editorStart"] = editorStart;
}
});
Object.defineProperty(this, 'editorEnd', {
get: function() {
return this._editorEnd;
},
set: function(editorEnd) {
this._editorEnd = editorEnd;
localStorage[this.fileIndex + ".editorEnd"] = editorEnd;
set: function(range) {
this._editorSelectRange = range;
localStorage[this.fileIndex + ".editorSelectRange"] = [
range.start.row,
range.start.column,
range.end.row,
range.end.column
].join(';');
}
});
Object.defineProperty(this, 'previewScrollTop', {
@ -73,31 +85,31 @@ define(["underscore", "utils"], function(_, utils) {
}
});
}
FileDescriptor.prototype.addSyncLocation = function(syncAttributes) {
utils.storeAttributes(syncAttributes);
utils.appendIndexToArray(this.fileIndex + ".sync", syncAttributes.syncIndex);
this.syncLocations[syncAttributes.syncIndex] = syncAttributes;
};
FileDescriptor.prototype.removeSyncLocation = function(syncAttributes) {
utils.removeIndexFromArray(this.fileIndex + ".sync", syncAttributes.syncIndex);
delete this.syncLocations[syncAttributes.syncIndex];
localStorage.removeItem(syncAttributes.syncIndex);
};
FileDescriptor.prototype.addPublishLocation = function(publishAttributes) {
utils.storeAttributes(publishAttributes);
utils.appendIndexToArray(this.fileIndex + ".publish", publishAttributes.publishIndex);
this.publishLocations[publishAttributes.publishIndex] = publishAttributes;
};
FileDescriptor.prototype.removePublishLocation = function(publishAttributes) {
utils.removeIndexFromArray(this.fileIndex + ".publish", publishAttributes.publishIndex);
delete this.publishLocations[publishAttributes.publishIndex];
localStorage.removeItem(publishAttributes.publishIndex);
};
FileDescriptor.prototype.composeTitle = function() {
var result = [];
var syncAttributesList = _.values(this.syncLocations);
@ -116,6 +128,6 @@ define(["underscore", "utils"], function(_, utils) {
result.push(this.title);
return result.join('');
};
return FileDescriptor;
});

View File

@ -2,6 +2,7 @@ define([
"jquery",
"underscore",
"crel",
"ace",
"utils",
"settings",
"eventMgr",
@ -14,7 +15,7 @@ define([
"config",
"uilayout",
"libs/Markdown.Editor"
], function($, _, crel, utils, settings, eventMgr, mousetrap, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML, settingsUserCustomExtensionTooltipHTML) {
], function($, _, crel, ace, utils, settings, eventMgr, mousetrap, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML, settingsUserCustomExtensionTooltipHTML) {
var core = {};
@ -187,7 +188,55 @@ define([
}
// Create the layout
var aceEditor = undefined;
function createLayout() {
aceEditor = ace.edit("wmd-input");
aceEditor.renderer.setShowGutter(false);
aceEditor.renderer.setShowPrintMargin(false);
aceEditor.renderer.setPrintMarginColumn(false);
aceEditor.renderer.setPadding(12);
aceEditor.session.setUseWrapMode(true);
aceEditor.session.setMode("libs/acemode");
// Make bold titles...
(function(bgTokenizer) {
var worker = bgTokenizer.$worker;
bgTokenizer.$worker = function() {
bgTokenizer.currentLine = bgTokenizer.currentLine ? bgTokenizer.currentLine - 1 : 0;
worker();
_.each(bgTokenizer.lines, function(line, i) {
if(i !== 0 && line && line.length !== 0 && line[0].type.indexOf("markup.heading.multi") === 0) {
_.each(bgTokenizer.lines[i-1], function(previousLineObject) {
previousLineObject.type = "markup.heading.prev.multi";
});
}
});
};
})(aceEditor.session.bgTokenizer);
window.wmdInput = {
editor: aceEditor,
focus: function() {
aceEditor.focus();
}
};
Object.defineProperty(window.wmdInput, 'value', {
get: function() {
return aceEditor.getValue();
},
set: function(value) {
aceEditor.setValue(value);
}
});
Object.defineProperty(window.wmdInput, 'scrollTop', {
get: function() {
return aceEditor.renderer.getScrollTop();
},
set: function(value) {
aceEditor.renderer.scrollToY(value);
}
});
var layoutGlobalConfig = {
closable: true,
resizable: false,
@ -216,6 +265,10 @@ define([
setPreviewButtonsVisibility(true);
}
},
onresize: function() {
aceEditor.resize();
eventMgr.onLayoutResize();
},
};
eventMgr.onLayoutConfigure(layoutGlobalConfig);
if(settings.layoutOrientation == "horizontal") {
@ -274,33 +327,39 @@ define([
fileDesc = fileDescParam;
documentContent = undefined;
var initDocumentContent = fileDesc.content;
$editorElt.val(initDocumentContent);
aceEditor.setValue(initDocumentContent, -1);
_.defer(function() {
aceEditor.session.getUndoManager().reset();
});
if(editor !== undefined) {
// If the editor is already created
editor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop);
aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange);
aceEditor.renderer.scrollToY(fileDesc.editorScrollTop);
aceEditor.focus();
eventMgr.onFileOpen(fileDesc);
editor.refreshPreview();
return;
}
var $previewContainerElt = $(".preview-container");
// Store editor scrollTop on scroll event
$editorElt.scroll(function() {
aceEditor.session.on('changeScrollTop', function() {
if(documentContent !== undefined) {
fileDesc.editorScrollTop = $(this).scrollTop();
fileDesc.editorScrollTop = aceEditor.renderer.getScrollTop();
}
});
// Store editor selection on change
$editorElt.bind("keyup mouseup", function() {
aceEditor.session.selection.on('changeSelection', function() {
if(documentContent !== undefined) {
fileDesc.editorStart = this.selectionStart;
fileDesc.editorEnd = this.selectionEnd;
fileDesc.editorSelectRange = aceEditor.getSelectionRange();
}
});
// Store preview scrollTop on scroll event
$previewContainerElt.scroll(function() {
if(documentContent !== undefined) {
fileDesc.previewScrollTop = $(this).scrollTop();
fileDesc.previewScrollTop = $previewContainerElt.scrollTop();
}
});
@ -347,7 +406,7 @@ define([
});
function checkDocumentChanges() {
var newDocumentContent = $editorElt.val();
var newDocumentContent = aceEditor.getValue();
if(documentContent !== undefined && documentContent != newDocumentContent) {
fileDesc.content = newDocumentContent;
eventMgr.onContentChanged(fileDesc);
@ -361,7 +420,7 @@ define([
return function() {
if(documentContent === undefined) {
makePreview();
$editorElt.scrollTop(fileDesc.editorScrollTop);
//$editorElt.scrollTop(fileDesc.editorScrollTop);
$previewContainerElt.scrollTop(fileDesc.previewScrollTop);
}
else {
@ -385,7 +444,11 @@ define([
eventMgr.onEditorConfigure(editor);
editor.hooks.chain("onPreviewRefresh", eventMgr.onAsyncPreview);
editor.run(previewWrapper);
editor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop);
// editor.undoManager.reinit(initDocumentContent, fileDesc.editorStart,
// fileDesc.editorEnd, fileDesc.editorScrollTop);
aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange);
aceEditor.renderer.scrollToY(fileDesc.editorScrollTop);
aceEditor.focus();
// Hide default buttons
$(".wmd-button-row li").addClass("btn btn-success").css("left", 0).find("span").hide();
@ -731,7 +794,7 @@ define([
$("div.dropdown-menu").click(function(e) {
e.stopPropagation();
});
// Load images
_.each(document.querySelectorAll('img'), function(imgElt) {
var $imgElt = $(imgElt);

View File

@ -168,6 +168,7 @@ define([
// Operations on Layout
addEventHook("onLayoutConfigure");
addEventHook("onLayoutCreated");
addEventHook("onLayoutResize");
// Operations on PageDown
addEventHook("onEditorConfigure");

View File

@ -62,7 +62,7 @@ define([
};
mathJax.onEditorConfigure = function(editorObject) {
preview = document.getElementById("preview-contents");
t = document.getElementById("preview-contents");
var converter = editorObject.getConverter();
converter.hooks.chain("preConversion", p);

View File

@ -166,11 +166,9 @@ define([
}
}, 500);
scrollLink.onLayoutConfigure = function(layoutConfig) {
layoutConfig.onresize = function() {
isScrollEditor = true;
buildSections();
};
scrollLink.onLayoutResize = function() {
isScrollEditor = true;
buildSections();
};
scrollLink.onReady = function() {

View File

@ -39,7 +39,7 @@
</ul>
</div>
</div>
<textarea id="wmd-input" class="ui-layout-center form-control"></textarea>
<div id="wmd-input" class="ui-layout-center form-control"></div>
<div class="ui-layout-east preview-container"></div>
<div class="ui-layout-south preview-container"></div>
<div id="wmd-button-bar" class="hide"></div>

View File

@ -2,6 +2,7 @@
(function () {
var util = {},
position = {},
ui = {},
@ -18,41 +19,55 @@
};
var defaultsStrings = {
bold: "Strong <strong> Ctrl+B",
bold: "Strong <strong>",
boldexample: "strong text",
italic: "Emphasis <em> Ctrl+I",
italic: "Emphasis <em>",
italicexample: "emphasized text",
link: "Hyperlink <a> Ctrl+L",
link: "Hyperlink <a>",
linkdescription: "enter link description here",
linkdialog: "<p><b>Insert Hyperlink</b></p><p>http://example.com/ \"optional title\"</p>",
quote: "Blockquote <blockquote> Ctrl+Q",
quote: "Blockquote <blockquote>",
quoteexample: "Blockquote",
code: "Code Sample <pre><code> Ctrl+K",
code: "Code Sample <pre><code>",
codeexample: "enter code here",
image: "Image <img> Ctrl+G",
image: "Image <img>",
imagedescription: "enter image description here",
imagedialog: "<p><b>Insert Image</b></p><p>http://example.com/images/diagram.jpg \"optional title\"<br><br>Need <a href='http://www.google.com/search?q=free+image+hosting' target='_blank'>free image hosting?</a></p>",
olist: "Numbered List <ol> Ctrl+O",
ulist: "Bulleted List <ul> Ctrl+U",
olist: "Numbered List <ol>",
ulist: "Bulleted List <ul>",
litem: "List item",
heading: "Heading <h1>/<h2> Ctrl+H",
heading: "Heading <h1>/<h2>",
headingexample: "Heading",
hr: "Horizontal Rule <hr> Ctrl+R",
undo: "Undo - Ctrl+Z",
redo: "Redo - Ctrl+Y",
redomac: "Redo - Ctrl+Shift+Z",
hr: "Horizontal Rule <hr>",
undo: "Undo -",
redo: "Redo -",
help: "Markdown Editing Help"
};
var keyStrokes = {
bold: "B",
italic: "I",
link: "L",
quote: "Q",
code: "K",
image: "G",
olist: "O",
ulist: "U",
heading: "H",
hr: "R",
undo: "Z",
redo: "Y",
};
// -------------------------------------------------------------------
@ -101,6 +116,7 @@
options.strings.help = options.strings.help || options.helpButton.title;
}
var getString = function (identifier) { return options.strings[identifier] || defaultsStrings[identifier]; }
var getKey = function (identifier) { return (/win/.test(nav.platform.toLowerCase()) ? 'Ctrl+' : 'Command+') + keyStrokes[identifier]; };
idPostfix = idPostfix || "";
@ -128,6 +144,7 @@
var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }, previewWrapper);
var uiManager;
/*benweet
if (!/\?noundo/.test(doc.location.href)) {
undoManager = new UndoManager(function () {
previewManager.refresh();
@ -140,15 +157,14 @@
that.refreshPreview();
}
}
*/
uiManager = new UIManager(idPostfix, panels, undoManager, previewManager, commandManager, options.helpButton, getString);
uiManager = new UIManager(idPostfix, panels, undoManager, previewManager, commandManager, options.helpButton, getString, getKey);
uiManager.setUndoRedoButtonStates();
var forceRefresh = that.refreshPreview = function () { previewManager.refresh(true); };
//Not necessary
//forceRefresh();
that.undoManager = undoManager;
forceRefresh();
that.uiManager = uiManager;
};
@ -305,7 +321,7 @@
function PanelCollection(postfix) {
this.buttonBar = doc.getElementById("wmd-button-bar" + postfix);
this.preview = doc.getElementById("wmd-preview" + postfix);
this.input = doc.getElementById("wmd-input" + postfix);
this.input = window.wmdInput;
};
// Returns true if the DOM element is visible, false if it's hidden.
@ -710,25 +726,44 @@
var stateObj = this;
var inputArea = panels.input;
this.init = function () {
/*benweet
if (!util.isVisible(inputArea)) {
return;
}
if (!isInitialState && doc.activeElement && doc.activeElement !== inputArea) { // this happens when tabbing out of the input box
return;
}
*/
var Range = require('ace/range').Range;
(function(range) {
stateObj.before = inputArea.editor.session.getTextRange(new Range(0,0,range.start.row, range.start.column));
stateObj.selection = inputArea.editor.session.getTextRange();
stateObj.after = inputArea.editor.session.getTextRange(new Range(range.end.row, range.end.column, Number.MAX_VALUE, Number.MAX_VALUE));
})(inputArea.editor.selection.getRange());
this.text = [this.before, this.selection, this.after].join('');
this.length = this.text.length;
this.setInputAreaSelectionStartEnd();
this.scrollTop = inputArea.scrollTop;
/*benweet
if (!this.text && inputArea.selectionStart || inputArea.selectionStart === 0) {
this.text = inputArea.value;
}
*/
}
// Sets the selected text in the input box after we've performed an
// operation.
this.setInputAreaSelection = function () {
var Range = require('ace/range').Range;
inputArea.editor.selection.setSelectionRange((function(posStart, posEnd) {
return new Range(posStart.row, posStart.column, posEnd.row, posEnd.column);
})(inputArea.editor.session.doc.indexToPosition(stateObj.start), inputArea.editor.session.doc.indexToPosition(stateObj.end)));
inputArea.editor.renderer.scrollToY(stateObj.scrollTop);
inputArea.editor.focus();
/*benweet
if (!util.isVisible(inputArea)) {
return;
}
@ -754,10 +789,15 @@
range.moveStart("character", stateObj.start);
range.select();
}
*/
};
this.setInputAreaSelectionStartEnd = function () {
stateObj.start = stateObj.before.length;
stateObj.end = stateObj.after.length;
/*benweet
if (!panels.ieCachedRange && (inputArea.selectionStart || inputArea.selectionStart === 0)) {
stateObj.start = inputArea.selectionStart;
@ -802,27 +842,56 @@
this.setInputAreaSelection();
}
*/
};
// Restore this state into the input area.
this.restore = function () {
// Here we could do editor.setValue but we want to update the less we can for undo management
// Find the first modified char
var startIndex = 0;
var startIndexMax = stateObj.before.length;
while(startIndex < startIndexMax) {
if(stateObj.before.charCodeAt(startIndex) !== stateObj.text.charCodeAt(startIndex))
break;
startIndex++;
}
// Find the last modified char
var endIndex = 0;
var endIndexMax = stateObj.after.length;
var beforeMaxOffset = stateObj.after.length - 1;
var afterMaxOffset = stateObj.text.length - 1;
while(endIndex < endIndexMax) {
if(stateObj.after.charCodeAt(beforeMaxOffset - endIndex) !== stateObj.text.charCodeAt(afterMaxOffset - endIndex))
break;
endIndex++;
}
var Range = require('ace/range').Range;
var range = (function(posStart, posEnd) {
return new Range(posStart.row, posStart.column, posEnd.row, posEnd.column);
})(inputArea.editor.session.doc.indexToPosition(startIndex), inputArea.editor.session.doc.indexToPosition(stateObj.length - endIndex));
inputArea.editor.session.replace(range, stateObj.text.substring(startIndex, afterMaxOffset - endIndex + 1));
this.setInputAreaSelection();
/*benweet
if (stateObj.text != undefined && stateObj.text != inputArea.value) {
inputArea.value = stateObj.text;
}
this.setInputAreaSelection();
inputArea.scrollTop = stateObj.scrollTop;
*/
};
// Gets a collection of HTML chunks from the inptut textarea.
this.getChunks = function () {
var chunk = new Chunks();
chunk.before = util.fixEolChars(stateObj.text.substring(0, stateObj.start));
chunk.before = stateObj.before;
chunk.startTag = "";
chunk.selection = util.fixEolChars(stateObj.text.substring(stateObj.start, stateObj.end));
chunk.selection = stateObj.selection;
chunk.endTag = "";
chunk.after = util.fixEolChars(stateObj.text.substring(stateObj.end));
chunk.after = stateObj.after;
chunk.scrollTop = stateObj.scrollTop;
return chunk;
@ -852,6 +921,7 @@
var startType = "delayed"; // The other legal value is "manual"
// Adds event listeners to elements
/*benweet
var setupEvents = function (inputElem, listener) {
util.addEvent(inputElem, "input", listener);
@ -861,6 +931,7 @@
util.addEvent(inputElem, "keypress", listener);
util.addEvent(inputElem, "keydown", listener);
};
*/
var getDocScrollTop = function () {
@ -1029,7 +1100,10 @@
var init = function () {
/*benweet
setupEvents(panels.input, applyTimeout);
*/
panels.input.editor.session.on('change', applyTimeout);
//Not necessary
//makePreviewHtml();
@ -1238,7 +1312,8 @@
}, 0);
};
function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions, getString) {
function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions, getString, getKey) {
var getStringAndKey = function (identifier) { return getString(identifier) + ' ' + getKey(identifier); };
var inputBox = panels.input,
buttons = {}; // buttons.undo, buttons.link, etc. The actual DOM elements.
@ -1250,6 +1325,23 @@
keyEvent = "keypress";
}
function addKeyCmd(identifierList) {
if(identifierList.length === 0) {
return;
}
var identifier = identifierList.pop();
inputBox.editor.commands.addCommand({
name: getString(identifier),
bindKey: {win: 'Ctrl-' + keyStrokes[identifier], mac: 'Command-' + keyStrokes[identifier]},
exec: function(editor) {
doClick(buttons[identifier]);
},
});
addKeyCmd(identifierList);
}
addKeyCmd(['bold', 'italic', 'link', 'quote', 'code', 'image', 'olist', 'ulist', 'heading', 'hr']);
/*benweet
util.addEvent(inputBox, keyEvent, function (key) {
// Check to see if we have a button key and, if so execute the callback.
@ -1343,6 +1435,7 @@
}
});
}
*/
// Perform the button's action.
@ -1398,9 +1491,11 @@
if (!noCleanup) {
fixupInputArea();
/*benweet
if(!linkOrImage) {
inputBox.dispatchEvent(new Event('input'));
}
*/
}
}
@ -1500,36 +1595,32 @@
xPosition += 25;
}
buttons.bold = makeButton("wmd-bold-button", getString("bold"), "0px", bindCommand("doBold"));
buttons.italic = makeButton("wmd-italic-button", getString("italic"), "-20px", bindCommand("doItalic"));
buttons.bold = makeButton("wmd-bold-button", getStringAndKey("bold"), "0px", bindCommand("doBold"));
buttons.italic = makeButton("wmd-italic-button", getStringAndKey("italic"), "-20px", bindCommand("doItalic"));
makeSpacer(1);
buttons.link = makeButton("wmd-link-button", getString("link"), "-40px", bindCommand(function (chunk, postProcessing) {
buttons.link = makeButton("wmd-link-button", getStringAndKey("link"), "-40px", bindCommand(function (chunk, postProcessing) {
return this.doLinkOrImage(chunk, postProcessing, false);
}));
buttons.quote = makeButton("wmd-quote-button", getString("quote"), "-60px", bindCommand("doBlockquote"));
buttons.code = makeButton("wmd-code-button", getString("code"), "-80px", bindCommand("doCode"));
buttons.image = makeButton("wmd-image-button", getString("image"), "-100px", bindCommand(function (chunk, postProcessing) {
buttons.quote = makeButton("wmd-quote-button", getStringAndKey("quote"), "-60px", bindCommand("doBlockquote"));
buttons.code = makeButton("wmd-code-button", getStringAndKey("code"), "-80px", bindCommand("doCode"));
buttons.image = makeButton("wmd-image-button", getStringAndKey("image"), "-100px", bindCommand(function (chunk, postProcessing) {
return this.doLinkOrImage(chunk, postProcessing, true);
}));
makeSpacer(2);
buttons.olist = makeButton("wmd-olist-button", getString("olist"), "-120px", bindCommand(function (chunk, postProcessing) {
buttons.olist = makeButton("wmd-olist-button", getStringAndKey("olist"), "-120px", bindCommand(function (chunk, postProcessing) {
this.doList(chunk, postProcessing, true);
}));
buttons.ulist = makeButton("wmd-ulist-button", getString("ulist"), "-140px", bindCommand(function (chunk, postProcessing) {
buttons.ulist = makeButton("wmd-ulist-button", getStringAndKey("ulist"), "-140px", bindCommand(function (chunk, postProcessing) {
this.doList(chunk, postProcessing, false);
}));
buttons.heading = makeButton("wmd-heading-button", getString("heading"), "-160px", bindCommand("doHeading"));
buttons.hr = makeButton("wmd-hr-button", getString("hr"), "-180px", bindCommand("doHorizontalRule"));
buttons.heading = makeButton("wmd-heading-button", getStringAndKey("heading"), "-160px", bindCommand("doHeading"));
buttons.hr = makeButton("wmd-hr-button", getStringAndKey("hr"), "-180px", bindCommand("doHorizontalRule"));
makeSpacer(3);
buttons.undo = makeButton("wmd-undo-button", getString("undo"), "-200px", null);
buttons.undo.execute = function (manager) { if (manager) manager.undo(); };
buttons.undo = makeButton("wmd-undo-button", getStringAndKey("undo"), "-200px", null);
buttons.undo.execute = function (manager) { inputBox.editor.session.getUndoManager().undo(); };
var redoTitle = /win/.test(nav.platform.toLowerCase()) ?
getString("redo") :
getString("redomac"); // mac and other non-Windows platforms
buttons.redo = makeButton("wmd-redo-button", redoTitle, "-220px", null);
buttons.redo.execute = function (manager) { if (manager) manager.redo(); };
buttons.redo = makeButton("wmd-redo-button", getStringAndKey("redo"), "-220px", null);
buttons.redo.execute = function (manager) { inputBox.editor.session.getUndoManager().redo(); };
if (helpOptions) {
var helpButton = document.createElement("li");
@ -1549,13 +1640,20 @@
}
setUndoRedoButtonStates();
inputBox.editor.session.on('change', setUndoRedoButtonStates);
}
function setUndoRedoButtonStates() {
/*benweet
if (undoManager) {
setupButton(buttons.undo, undoManager.canUndo());
setupButton(buttons.redo, undoManager.canRedo());
}
*/
setTimeout(function() {
setupButton(buttons.undo, inputBox.editor.session.getUndoManager().hasUndo());
setupButton(buttons.redo, inputBox.editor.session.getUndoManager().hasRedo());
}, 0);
};
this.setUndoRedoButtonStates = setUndoRedoButtonStates;

70
res/libs/acemode.js Normal file
View File

@ -0,0 +1,70 @@
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var oop = require("ace/lib/oop");
var TextMode = require("ace/mode/text").Mode;
var Tokenizer = require("ace/tokenizer").Tokenizer;
var MarkdownHighlightRules = require("./acemode_highlight_rules").MarkdownHighlightRules;
var MarkdownFoldMode = require("ace/mode/folding/markdown").FoldMode;
var Mode = function() {
var highlighter = new MarkdownHighlightRules();
this.$tokenizer = new Tokenizer(highlighter.getRules());
this.$embeds = highlighter.getEmbeds();
this.foldingRules = new MarkdownFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.lineCommentStart = ">";
this.getNextLineIndent = function(state, line, tab) {
if (state == "listblock") {
var match = /^(\s*)(?:([-+*])|(\d+)\.)(\s+)/.exec(line);
if (!match)
return "";
var marker = match[2];
if (!marker)
marker = parseInt(match[3], 10) + 1 + ".";
return match[1] + marker + match[4];
} else {
return this.$getIndent(line);
}
};
}).call(Mode.prototype);
exports.Mode = Mode;
});

View File

@ -0,0 +1,182 @@
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var oop = require("ace/lib/oop");
var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
function github_embed(tag, prefix) {
return { // Github style block
token : "support.function",
regex : "^```" + tag + "\\s*$",
next : prefix + "start"
};
}
var MarkdownHighlightRules = function() {
// regexp must not have capturing parentheses
// regexps are ordered -> the first match is used
this.$rules = {
"basic" : [{
token : "constant.language.escape",
regex : /\\[\\`*_{}\[\]()#+\-.!]/
}, { // code span `
token : "support.function",
regex : "(`+)(.*?[^`])(\\1)"
}, { // reference
token : ["text", "constant", "text", "url", "string", "text"],
regex : "^([ ]{0,3}\\[)([^\\]]+)(\\]:\\s*)([^ ]+)(\\s*(?:[\"][^\"]+[\"])?(\\s*))$"
}, { // link by reference
token : ["text", "string", "text", "constant", "text"],
regex : "(\\[)((?:[[^\\]]*\\]|[^\\[\\]])*)(\\][ ]?(?:\\n[ ]*)?\\[)(.*?)(\\])"
}, { // link by url
token : ["text", "string", "text", "markup.underline", "string", "text"],
regex : "(\\[)"+
"(\\[[^\\]]*\\]|[^\\[\\]]*)"+
"(\\]\\([ \\t]*)"+
"(<?(?:(?:[^\\(]*?\\([^\\)]*?\\)\\S*?)|(?:.*?))>?)"+
"((?:[ \t]*\"(?:.*?)\"[ \\t]*)?)"+
"(\\))"
}, { // strong ** __
token : "strong",
regex : "([*]{2}|[_]{2}(?=\\S))(.*?\\S[*_]*)(\\1)"
}, { // emphasis * _
token : "emphasis",
regex : "([*]|[_](?=\\S))(.*?\\S[*_]*)(\\1)"
}, { //
token : ["text", "url", "text"],
regex : "(<)("+
"(?:https?|ftp|dict):[^'\">\\s]+"+
"|"+
"(?:mailto:)?[-.\\w]+\\@[-a-z0-9]+(?:\\.[-a-z0-9]+)*\\.[a-z]+"+
")(>)"
}],
// code block
"allowBlock": [
{token : "support.function", regex : "^ {4}.+", next : "allowBlock"},
{token : "empty", regex : "", next : "start"}
],
"start" : [{
token : "empty_line",
regex : '^$',
next: "allowBlock"
}, { // h1
token: "markup.heading.multi.1",
regex: "^=+(?=\\s*$)"
}, { // h2
token: "markup.heading.multi.2",
regex: "^\\-+(?=\\s*$)"
}, {
token : function(value) {
return "markup.heading." + value.length;
},
regex : /^#{1,6}(?=\s*[^ #]|\s+#.)/,
next : "header"
},
{ // Github style block
token : "support.function",
regex : "^```\\s*[a-zA-Z]*(?:{.*?\\})?\\s*$",
next : "githubblock"
}, { // block quote
token : "blockquote",
regex : "^>[ ].+$",
next : "blockquote"
}, { // HR * - _
token : "constant",
regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",
next: "allowBlock"
}, { // list
token : "markup.list",
regex : "^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",
next : "listblock-start"
}, {
include : "basic"
}],
"header" : [{
regex: "$",
next : "start"
}, {
include: "basic"
}, {
defaultToken : "markup.heading"
} ],
"listblock-start" : [{
token : "support.variable",
regex : /(?:\[[ x]\])?/,
next : "listblock"
}],
"listblock" : [ { // Lists only escape on completely blank lines.
token : "empty_line",
regex : "^$",
next : "start"
}, { // list
token : "markup.list",
regex : "^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",
next : "listblock-start"
}, {
include : "basic", noEscape: true
}, {
defaultToken : "markup.list"
} ],
"blockquote" : [ { // BLockquotes only escape on blank lines.
token : "empty_line",
regex : "^\\s*$",
next : "start"
}, {
token : "blockquote",
regex : ".+"
} ],
"githubblock" : [ {
token : "support.function",
regex : "^```",
next : "start"
}, {
token : "support.function",
regex : ".+"
} ]
};
this.normalizeRules();
};
oop.inherits(MarkdownHighlightRules, TextHighlightRules);
exports.MarkdownHighlightRules = MarkdownHighlightRules;
});

View File

@ -2,6 +2,11 @@
requirejs.config({
waitSeconds: 0,
packages: [
{
name: 'ace',
location: 'bower-libs/ace/lib/ace',
main: 'ace'
},
{
name: 'css',
location: 'bower-libs/require-css',
@ -146,7 +151,7 @@ require([
// Here, all the modules are loaded and the DOM is ready
core.onReady();
// If browser has detected a new application cache.
if(window.applicationCache) {
window.applicationCache.addEventListener('updateready', function(e) {

View File

@ -6,8 +6,8 @@ define([
var settings = {
layoutOrientation: "horizontal",
lazyRendering: true,
editorFontFamily: "Courier New, Courier, monospace",
editorFontSize: 14,
editorFontFamily: 'Menlo, Consolas, "Courier New", Courier, monospace',
editorFontSize: 12,
defaultContent: "\n\n\n> Written with [StackEdit](" + MAIN_URL + ").",
commitMsg: "Published with " + MAIN_URL,
template: [

View File

@ -120,7 +120,7 @@ define([
});
version = "v6";
}
// Upgrade from v6 to v7
if(version == "v6") {
var currentFileIndex = localStorage["file.current"];
@ -130,7 +130,7 @@ define([
}
version = "v7";
}
// Upgrade from v7 to v8
if(version == "v7") {
_.each(_.keys(localStorage), function(key) {
@ -144,5 +144,16 @@ define([
version = "v8";
}
// Upgrade from v8 to v9
if(version == "v8") {
_.each(_.keys(localStorage), function(key) {
var matchResult = key.match(/file\.\S+\.(editorEnd|editorStart)/);
if(matchResult) {
localStorage.removeItem(key);
}
});
version = "v9";
}
localStorage["version"] = version;
});

View File

@ -16,6 +16,7 @@
@primary-color: #333;
@primary-color-light: lighten(@primary-color, 13%);
@primary-color-lighter: lighten(@primary-color, 20%);
@primary-color-lightest: lighten(@primary-color, 40%);
@primary-color-inv: #fff;
@bg-navbar-hover: @primary-bg-lighter;
@error-border: #ff8661;
@ -102,10 +103,13 @@ body {
tab-size: 4;
}
.ui-layout-east, .ui-layout-south {
background-color: @body-bg;
}
#preview-contents {
padding: 15px;
margin-bottom: 50px;
background-color: @body-bg;
.ui-layout-east & {
padding-left: 5px;
}
@ -904,8 +908,36 @@ ul,ol {
* Editor
*****************************/
.ace-tm .ace_marker-layer .ace_active-line {
background-color: @primary-bg-lighter;
}
.ace-tm .ace_markup.ace_heading {
color: @primary-color-light;
font-weight: 900;
}
.ace-tm .ace_markup.ace_list {
color: @primary-color-lightest;
}
.ace-tm .ace_strong {
font-weight: 600;
}
.ace-tm .ace_emphasis {
font-style: italic;
}
.ace-tm .ace_blockquote {
color: @primary-color-lightest;
font-style: italic;
}
#wmd-input {
.box-shadow(none);
padding: 0;
font-weight: 300;
}
#wmd-input,#md-section-helper {