Switch to ACE editor
This commit is contained in:
parent
ca34415d22
commit
99e5b27fa4
@ -18,6 +18,6 @@
|
||||
"stacktrace": "~0.5.3",
|
||||
"requirejs-text": "~2.0.10",
|
||||
"bootstrap-tour": "~0.6.0",
|
||||
"ace": "~1.1.1"
|
||||
"ace": "#51b7cb67a63998c9c0b7d089a85c60e032a7cc17"
|
||||
}
|
||||
}
|
||||
|
106
res/core.js
106
res/core.js
@ -118,8 +118,8 @@ define([
|
||||
utils.setInputValue("#input-settings-editor-font-family", settings.editorFontFamily);
|
||||
// Editor font size
|
||||
utils.setInputValue("#input-settings-editor-font-size", settings.editorFontSize);
|
||||
// Editor max width
|
||||
utils.setInputValue("#input-settings-editor-max-width", settings.editorMaxWidth);
|
||||
// Max width
|
||||
utils.setInputValue("#input-settings-max-width", settings.maxWidth);
|
||||
// Default content
|
||||
utils.setInputValue("#textarea-settings-default-content", settings.defaultContent);
|
||||
// Commit message
|
||||
@ -147,8 +147,8 @@ define([
|
||||
newSettings.editorFontFamily = utils.getInputTextValue("#input-settings-editor-font-family", event);
|
||||
// Editor font size
|
||||
newSettings.editorFontSize = utils.getInputIntValue("#input-settings-editor-font-size", event, 1, 99);
|
||||
// Editor max width
|
||||
newSettings.editorMaxWidth = utils.getInputIntValue("#input-settings-editor-max-width", event, 1);
|
||||
// Max width
|
||||
newSettings.maxWidth = utils.getInputIntValue("#input-settings-max-width", event, 1);
|
||||
// Default content
|
||||
newSettings.defaultContent = utils.getInputValue("#textarea-settings-default-content");
|
||||
// Commit message
|
||||
@ -212,50 +212,71 @@ define([
|
||||
aceEditor.renderer.setPadding(EDITOR_DEFAULT_PADDING);
|
||||
aceEditor.session.setUseWrapMode(true);
|
||||
aceEditor.session.setMode("libs/ace_mode");
|
||||
// Make titles bold...
|
||||
|
||||
// Make bold titles...
|
||||
(function(self) {
|
||||
function checkLine(currentLine) {
|
||||
var line = self.lines[currentLine];
|
||||
if(line.length !== 0) {
|
||||
if(line[0].type.indexOf("markup.heading.multi") === 0) {
|
||||
_.each(self.lines[currentLine - 1], function(previousLineObject) {
|
||||
previousLineObject.type = "markup.heading.prev.multi";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function customWorker() {
|
||||
if (!self.running) { return; }
|
||||
// Duplicate from background_tokenizer.js
|
||||
if(!self.running) {
|
||||
return;
|
||||
}
|
||||
|
||||
var workerStart = new Date();
|
||||
var startLine = self.currentLine;
|
||||
var currentLine = self.currentLine;
|
||||
var endLine = -1;
|
||||
var doc = self.doc;
|
||||
|
||||
var processedLines = 0;
|
||||
while (self.lines[currentLine]) {
|
||||
currentLine++;
|
||||
}
|
||||
|
||||
var startLine = currentLine;
|
||||
|
||||
var len = doc.getLength();
|
||||
while (self.currentLine < len) {
|
||||
self.$tokenizeRow(self.currentLine);
|
||||
while (self.lines[self.currentLine]) {
|
||||
var line = self.lines[self.currentLine];
|
||||
if(line.length !== 0 && line[0].type.indexOf("markup.heading.multi") === 0) {
|
||||
_.each(self.lines[self.currentLine-1], function(previousLineObject) {
|
||||
previousLineObject.type = "markup.heading.prev.multi";
|
||||
});
|
||||
}
|
||||
self.currentLine++;
|
||||
}
|
||||
var processedLines = 0;
|
||||
self.running = false;
|
||||
while (currentLine < len) {
|
||||
self.$tokenizeRow(currentLine);
|
||||
endLine = currentLine;
|
||||
do {
|
||||
checkLine(currentLine); // benweet
|
||||
currentLine++;
|
||||
} while (self.lines[currentLine]);
|
||||
|
||||
// only check every 5 lines
|
||||
processedLines ++;
|
||||
if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
|
||||
self.fireUpdateEvent(startLine, self.currentLine-1);
|
||||
self.running = setTimeout(customWorker, 20);
|
||||
processedLines++;
|
||||
if((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
|
||||
self.running = setTimeout(customWorker, 20); // benweet
|
||||
self.currentLine = currentLine;
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.currentLine = currentLine;
|
||||
|
||||
self.running = false;
|
||||
|
||||
self.fireUpdateEvent(startLine, len - 1);
|
||||
if(startLine <= endLine)
|
||||
self.fireUpdateEvent(startLine, endLine);
|
||||
}
|
||||
;
|
||||
self.$worker = function() {
|
||||
self.currentLine = self.currentLine ? self.currentLine - 1 : 0;
|
||||
self.lines.splice(0, self.lines.length);
|
||||
self.states.splice(0, self.states.length);
|
||||
self.currentLine = 0;
|
||||
customWorker();
|
||||
};
|
||||
|
||||
})(aceEditor.session.bgTokenizer);
|
||||
|
||||
eventMgr.onAceCreated(aceEditor);
|
||||
window.aceEditor = aceEditor;
|
||||
}
|
||||
|
||||
// Create the layout
|
||||
@ -291,8 +312,11 @@ define([
|
||||
onresize_end: function(paneName) {
|
||||
if(aceEditor !== undefined && paneName == 'center') {
|
||||
aceEditor.resize();
|
||||
var bottomMargin = (aceEditor.renderer.$size.scrollerHeight - aceEditor.renderer.lineHeight) / 2;
|
||||
bottomMargin < 0 && (bottomMargin = 0);
|
||||
aceEditor.renderer.setScrollMargin(0, bottomMargin, 0, 0);
|
||||
setTimeout(function() {
|
||||
var padding = (aceEditor.renderer.$size.scrollerWidth - settings.editorMaxWidth)/2;
|
||||
var padding = (aceEditor.renderer.$size.scrollerWidth - settings.maxWidth) / 2;
|
||||
if(padding < EDITOR_DEFAULT_PADDING) {
|
||||
padding = EDITOR_DEFAULT_PADDING;
|
||||
}
|
||||
@ -324,6 +348,7 @@ define([
|
||||
south__minSize: 200
|
||||
}));
|
||||
}
|
||||
settings.maxWidth && $('#preview-contents').css('max-width', (settings.maxWidth + 30) + 'px');
|
||||
$(".navbar").click(function() {
|
||||
layout.allowOverflow('north');
|
||||
});
|
||||
@ -335,16 +360,16 @@ define([
|
||||
// have fixed position
|
||||
// We also move the north toggler to the east or south resizer as the
|
||||
// north resizer is very small
|
||||
var $previewButtonsContainerElt = $('<div class="preview-button-container">');
|
||||
$previewButtonsElt = $('<div class="extension-preview-buttons">').appendTo($previewButtonsContainerElt);
|
||||
// var $previewButtonsContainerElt = $('<div
|
||||
// class="preview-button-container">');
|
||||
$previewButtonsElt = $('<div class="extension-preview-buttons">');
|
||||
$editorButtonsElt = $('<div class="extension-editor-buttons">');
|
||||
if(settings.layoutOrientation == "horizontal") {
|
||||
$('.ui-layout-resizer-north').append($previewButtonsContainerElt);
|
||||
if(viewerMode || settings.layoutOrientation == "horizontal") {
|
||||
$('.ui-layout-resizer-north').append($previewButtonsElt);
|
||||
$('.ui-layout-resizer-east').append($northTogglerElt).append($editorButtonsElt);
|
||||
}
|
||||
else {
|
||||
$previewButtonsContainerElt.append($editorButtonsElt);
|
||||
$('.ui-layout-resizer-south').append($previewButtonsContainerElt).append($northTogglerElt);
|
||||
$('.ui-layout-resizer-south').append($previewButtonsElt).append($editorButtonsElt).append($northTogglerElt);
|
||||
}
|
||||
|
||||
setPanelVisibility();
|
||||
@ -490,7 +515,9 @@ define([
|
||||
$editorElt.on("input propertychange", previewWrapper);
|
||||
editor = {
|
||||
hooks: hooks,
|
||||
getConverter: function () { return converter; },
|
||||
getConverter: function() {
|
||||
return converter;
|
||||
},
|
||||
run: previewWrapper,
|
||||
refreshPreview: previewWrapper
|
||||
};
|
||||
@ -502,10 +529,10 @@ define([
|
||||
var debouncedMakePreview = _.debounce(makePreview, 500);
|
||||
return function() {
|
||||
if(documentContent === undefined) {
|
||||
aceEditor.renderer.scrollToY(fileDesc.editorScrollTop);
|
||||
makePreview();
|
||||
$previewContainerElt.scrollTop(fileDesc.previewScrollTop);
|
||||
_.defer(function() {
|
||||
aceEditor.renderer.scrollToY(fileDesc.editorScrollTop);
|
||||
eventMgr.onFileOpen(fileDesc);
|
||||
});
|
||||
}
|
||||
@ -667,6 +694,11 @@ define([
|
||||
// Other initialization that are not prioritary
|
||||
eventMgr.addListener("onReady", function() {
|
||||
|
||||
// In vertical mode, we have to offset the editor buttons otherwise they hide the editor buttons
|
||||
if(!viewerMode && settings.layoutOrientation == "vertical") {
|
||||
$previewButtonsElt.css('right', parseInt($previewButtonsElt.css('right')) + $editorButtonsElt.width());
|
||||
}
|
||||
|
||||
var isModalShown = false;
|
||||
$('.modal').on('show.bs.modal', function() {
|
||||
// Close panel if open
|
||||
|
@ -7,7 +7,6 @@ define([
|
||||
"settings",
|
||||
"text!html/settingsExtensionsAccordion.html",
|
||||
"extensions/partialRendering",
|
||||
"extensions/userCustom",
|
||||
"extensions/buttonMarkdownSyntax",
|
||||
"extensions/googleAnalytics",
|
||||
"extensions/dialogAbout",
|
||||
@ -33,6 +32,7 @@ define([
|
||||
"extensions/buttonHtmlCode",
|
||||
"extensions/buttonViewer",
|
||||
"extensions/welcomeTour",
|
||||
"extensions/userCustom",
|
||||
"bootstrap",
|
||||
"jquery-waitforimages"
|
||||
], function($, _, crel, utils, Extension, settings, settingsExtensionsAccordionHTML) {
|
||||
@ -136,8 +136,8 @@ define([
|
||||
addEventHook("onError");
|
||||
addEventHook("onOfflineChanged");
|
||||
addEventHook("onUserActive");
|
||||
addEventHook("onAsyncRunning", true);
|
||||
addEventHook("onPeriodicRun", true);
|
||||
addEventHook("onAsyncRunning");
|
||||
addEventHook("onPeriodicRun");
|
||||
|
||||
// To access modules that are loaded after extensions
|
||||
addEventHook("onFileMgrCreated");
|
||||
@ -184,17 +184,13 @@ define([
|
||||
|
||||
var onPreviewFinished = createEventHook("onPreviewFinished");
|
||||
var onAsyncPreviewListenerList = getExtensionListenerList("onAsyncPreview");
|
||||
// The number of times we expect tryFinished to be called
|
||||
var nbAsyncPreviewListener = onAsyncPreviewListenerList.length + 1;
|
||||
var previewContentsElt = undefined;
|
||||
var $previewContentsElt = undefined;
|
||||
eventMgr["onAsyncPreview"] = function() {
|
||||
logger.log("onAsyncPreview");
|
||||
logger.log("Conversion time: " + (new Date() - eventMgr.previewStartTime));
|
||||
// Call onPreviewFinished listeners when all async preview are finished
|
||||
var counter = 0;
|
||||
function tryFinished() {
|
||||
if(++counter === nbAsyncPreviewListener) {
|
||||
function recursiveCall(callbackList) {
|
||||
var callback = callbackList.length ? callbackList.shift() : function() {
|
||||
logger.log("Preview time: " + (new Date() - eventMgr.previewStartTime));
|
||||
_.defer(function() {
|
||||
var html = "";
|
||||
@ -203,13 +199,15 @@ define([
|
||||
});
|
||||
onPreviewFinished(utils.trim(html));
|
||||
});
|
||||
}
|
||||
};
|
||||
callback(function() {
|
||||
recursiveCall(callbackList);
|
||||
});
|
||||
}
|
||||
// We assume images are loading in the preview
|
||||
$previewContentsElt.waitForImages(tryFinished);
|
||||
_.each(onAsyncPreviewListenerList, function(asyncPreviewListener) {
|
||||
asyncPreviewListener(tryFinished);
|
||||
});
|
||||
recursiveCall(onAsyncPreviewListenerList.concat([function(callback) {
|
||||
// We assume some images are loading asynchronously after the preview
|
||||
$previewContentsElt.waitForImages(callback);
|
||||
}]));
|
||||
};
|
||||
|
||||
var onReady = createEventHook("onReady");
|
||||
@ -255,27 +253,6 @@ define([
|
||||
});
|
||||
document.getElementById('extension-buttons').appendChild(extensionButtonsFragment);
|
||||
|
||||
// Create extension preview buttons
|
||||
logger.log("onCreatePreviewButton");
|
||||
var onCreatePreviewButtonListenerList = getExtensionListenerList("onCreatePreviewButton");
|
||||
var extensionPreviewButtonsFragment = document.createDocumentFragment();
|
||||
_.each(onCreatePreviewButtonListenerList, function(listener) {
|
||||
extensionPreviewButtonsFragment.appendChild(createBtn(listener));
|
||||
});
|
||||
var previewButtonsElt = document.querySelector('.extension-preview-buttons');
|
||||
previewButtonsElt.appendChild(extensionPreviewButtonsFragment);
|
||||
|
||||
// A bit of jQuery...
|
||||
var $previewButtonsElt = $(previewButtonsElt);
|
||||
var previewButtonsWidth = $previewButtonsElt.width();
|
||||
$previewButtonsElt.find('.btn-group').each(function() {
|
||||
var $btnGroupElt = $(this);
|
||||
// Align dropdown to the left of the screen
|
||||
$btnGroupElt.find('.dropdown-menu').css({
|
||||
right: -previewButtonsWidth + $btnGroupElt.width() + $btnGroupElt.position().left
|
||||
});
|
||||
});
|
||||
|
||||
// Create extension editor buttons
|
||||
logger.log("onCreateEditorButton");
|
||||
var onCreateEditorButtonListenerList = getExtensionListenerList("onCreateEditorButton");
|
||||
@ -287,6 +264,27 @@ define([
|
||||
editorButtonsElt.appendChild(extensionEditorButtonsFragment);
|
||||
}
|
||||
|
||||
// Create extension preview buttons
|
||||
logger.log("onCreatePreviewButton");
|
||||
var onCreatePreviewButtonListenerList = getExtensionListenerList("onCreatePreviewButton");
|
||||
var extensionPreviewButtonsFragment = document.createDocumentFragment();
|
||||
_.each(onCreatePreviewButtonListenerList, function(listener) {
|
||||
extensionPreviewButtonsFragment.appendChild(createBtn(listener));
|
||||
});
|
||||
var previewButtonsElt = document.querySelector('.extension-preview-buttons');
|
||||
previewButtonsElt.appendChild(extensionPreviewButtonsFragment);
|
||||
|
||||
// A bit of jQuery...
|
||||
var $previewButtonsElt = $(previewButtonsElt);
|
||||
var previewButtonsWidth = $previewButtonsElt.width();
|
||||
$previewButtonsElt.find('.btn-group').each(function() {
|
||||
var $btnGroupElt = $(this);
|
||||
// Align dropdown to the left of the screen
|
||||
$btnGroupElt.find('.dropdown-menu').css({
|
||||
right: -previewButtonsWidth + $btnGroupElt.width() + $btnGroupElt.position().left
|
||||
});
|
||||
});
|
||||
|
||||
// Call onReady listeners
|
||||
onReady();
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ define([
|
||||
"text!html/buttonMarkdownSyntax.html",
|
||||
], function($, Extension, buttonMarkdownSyntaxHTML) {
|
||||
|
||||
var buttonMarkdownSyntax = new Extension("buttonMarkdownSyntax", 'Button "Markdown syntax', true);
|
||||
var buttonMarkdownSyntax = new Extension("buttonMarkdownSyntax", 'Button "Markdown syntax', true, true);
|
||||
buttonMarkdownSyntax.settingsBlock = '<p>Adds a "Markdown syntax" button over the preview.</p>';
|
||||
|
||||
buttonMarkdownSyntax.onCreatePreviewButton = function() {
|
||||
|
@ -4,7 +4,7 @@ define([
|
||||
"text!html/buttonViewer.html",
|
||||
], function($, Extension, buttonViewerHTML) {
|
||||
|
||||
var buttonViewer = new Extension("buttonViewer", 'Button "Viewer"', true);
|
||||
var buttonViewer = new Extension("buttonViewer", 'Button "Viewer"', true, true);
|
||||
buttonViewer.settingsBlock = '<p>Adds a "Viewer" button over the preview.</p>';
|
||||
|
||||
buttonViewer.onCreatePreviewButton = function() {
|
||||
|
@ -9,6 +9,7 @@ define([
|
||||
var dialogAbout = new Extension("dialogAbout", 'Dialog "About"');
|
||||
|
||||
var libraries = {
|
||||
"ACE": "http://ace.c9.io/",
|
||||
"Bootstrap": "http://getbootstrap.com/",
|
||||
"Bootstrap Tour": "http://bootstraptour.com/",
|
||||
"crel": "https://github.com/KoryNunn/crel",
|
||||
|
@ -65,7 +65,7 @@ define([
|
||||
Markdown.Extra.init(converter, options);
|
||||
|
||||
// Store extensions list in converter for partialRendering
|
||||
converter.extraExtensions = markdownExtra.config.extensions;
|
||||
converter.setExtraExtension && converter.setExtraExtension(markdownExtra.config.extensions);
|
||||
};
|
||||
|
||||
return markdownExtra;
|
||||
|
@ -122,7 +122,7 @@ define([
|
||||
class: 'wmd-preview-section preview-content'
|
||||
});
|
||||
var isFirst = true;
|
||||
while(childNode) {
|
||||
while (childNode) {
|
||||
var nextNode = childNode.nextSibling;
|
||||
if(isFirst === false && /(^| )wmd-title($| )/.test(childNode.className)) {
|
||||
// Stop when encountered the next wmd-title
|
||||
@ -140,7 +140,8 @@ define([
|
||||
sectionElt.appendChild(childNode);
|
||||
}
|
||||
childNode = nextNode;
|
||||
};
|
||||
}
|
||||
;
|
||||
newSectionEltList.appendChild(sectionElt);
|
||||
});
|
||||
wmdPreviewElt.innerHTML = '';
|
||||
@ -184,6 +185,11 @@ define([
|
||||
editor.hooks.chain("onPreviewRefresh", function() {
|
||||
refreshSections();
|
||||
});
|
||||
converter.setExtraExtension = function(extraExtensions) {
|
||||
doFootnotes = _.some(extraExtensions, function(extension) {
|
||||
return extension == "footnotes";
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
partialRendering.onReady = function() {
|
||||
@ -199,13 +205,5 @@ define([
|
||||
fileChanged = true;
|
||||
};
|
||||
|
||||
partialRendering.onFileOpen = function() {
|
||||
if(converter.extraExtensions) {
|
||||
doFootnotes = _.some(converter.extraExtensions, function(extension) {
|
||||
return extension == "footnotes";
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return partialRendering;
|
||||
});
|
@ -946,10 +946,10 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-4 control-label"
|
||||
for="input-settings-editor-max-width">Editor max width</label>
|
||||
for="input-settings-max-width">Max width</label>
|
||||
<div class="col-lg-8 form-inline">
|
||||
<input type="text"
|
||||
id="input-settings-editor-max-width"
|
||||
id="input-settings-max-width"
|
||||
class="form-control col-lg-3"> px
|
||||
</div>
|
||||
</div>
|
||||
|
@ -48,7 +48,7 @@ var Mode = function() {
|
||||
oop.inherits(Mode, TextMode);
|
||||
|
||||
(function() {
|
||||
|
||||
this.type = "text";
|
||||
this.lineCommentStart = ">";
|
||||
|
||||
this.getNextLineIndent = function(state, line, tab) {
|
||||
|
@ -113,7 +113,7 @@ var MarkdownHighlightRules = function() {
|
||||
}, { // list
|
||||
token : "markup.list",
|
||||
regex : "^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",
|
||||
next : "listblock"
|
||||
next : "listblock-start"
|
||||
}, {
|
||||
include : "basic"
|
||||
}],
|
||||
@ -127,13 +127,11 @@ var MarkdownHighlightRules = function() {
|
||||
defaultToken : "markup.heading"
|
||||
} ],
|
||||
|
||||
/* don't need checkbox highlighting...
|
||||
"listblock-start" : [{
|
||||
token : "checkbox",
|
||||
regex : /(?:\[[ x]\])?/,
|
||||
next : "listblock"
|
||||
}],
|
||||
*/
|
||||
|
||||
"listblock" : [ { // Lists only escape on completely blank lines.
|
||||
token : "empty_line",
|
||||
@ -142,7 +140,7 @@ var MarkdownHighlightRules = function() {
|
||||
}, { // list
|
||||
token : "markup.list",
|
||||
regex : "^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",
|
||||
next : "listblock"
|
||||
next : "listblock-start"
|
||||
}, {
|
||||
include : "basic", noEscape: true
|
||||
}, {
|
||||
|
@ -8,7 +8,7 @@ define([
|
||||
lazyRendering: true,
|
||||
editorFontFamily: 'Menlo, Consolas, "Courier New", Courier, monospace',
|
||||
editorFontSize: 12,
|
||||
editorMaxWidth: 960,
|
||||
maxWidth: 960,
|
||||
defaultContent: "\n\n\n> Written with [StackEdit](" + MAIN_URL + ").",
|
||||
commitMsg: "Published with " + MAIN_URL,
|
||||
template: [
|
||||
|
@ -112,7 +112,7 @@ body {
|
||||
|
||||
#preview-contents {
|
||||
padding: 15px;
|
||||
margin-bottom: 50px;
|
||||
margin: 0 auto 50px;
|
||||
.ui-layout-east & {
|
||||
padding-left: 5px;
|
||||
}
|
||||
@ -567,19 +567,11 @@ body {
|
||||
* Preview/Editor extensions buttons
|
||||
********************/
|
||||
|
||||
.preview-button-container {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
.extension-editor-buttons {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.extension-preview-buttons {
|
||||
display: inline-block;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
margin-top: 6px;
|
||||
margin-right: 30px;
|
||||
right: 30px;
|
||||
.ui-layout-resizer-south-closed & {
|
||||
display: none !important;
|
||||
}
|
||||
@ -1231,11 +1223,6 @@ div.jGrowl {
|
||||
line-height: @input-height-base;
|
||||
}
|
||||
|
||||
#preview-contents {
|
||||
max-width: 1024px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.document-panel .search-bar {
|
||||
padding: 20px 20px 10px;
|
||||
.input-group-btn {
|
||||
|
Loading…
Reference in New Issue
Block a user