Switch to ACE editor
This commit is contained in:
parent
e9a3d5f97f
commit
24ba484010
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
@ -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;
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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;
|
||||
});
|
89
res/core.js
89
res/core.js
@ -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);
|
||||
|
@ -168,6 +168,7 @@ define([
|
||||
// Operations on Layout
|
||||
addEventHook("onLayoutConfigure");
|
||||
addEventHook("onLayoutCreated");
|
||||
addEventHook("onLayoutResize");
|
||||
|
||||
// Operations on PageDown
|
||||
addEventHook("onEditorConfigure");
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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>
|
||||
|
@ -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
70
res/libs/acemode.js
Normal 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;
|
||||
});
|
182
res/libs/acemode_highlight_rules.js
Normal file
182
res/libs/acemode_highlight_rules.js
Normal 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;
|
||||
});
|
@ -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) {
|
||||
|
@ -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: [
|
||||
|
@ -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;
|
||||
});
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user