Fixes for new editor

This commit is contained in:
benweet 2014-03-19 00:33:57 +00:00
parent 400d416e3c
commit 8cb7c307ee
9 changed files with 328 additions and 387 deletions

View File

@ -519,6 +519,7 @@ define([
// If the editor is already created // If the editor is already created
$editorElt.val(initDocumentContent); $editorElt.val(initDocumentContent);
aceEditor && aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange); aceEditor && aceEditor.selection.setSelectionRange(fileDesc.editorSelectRange);
aceEditor || pagedownEditor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop);
aceEditor ? aceEditor.focus() : $editorElt.focus(); aceEditor ? aceEditor.focus() : $editorElt.focus();
//pagedownEditor.refreshPreview(); //pagedownEditor.refreshPreview();
return; return;
@ -572,7 +573,7 @@ define([
if(documentContent == newDocumentContent) { if(documentContent == newDocumentContent) {
return false; return false;
} }
if(documentContent !== undefined) { if(documentContent !== undefined) {
fileDesc.content = newDocumentContent; fileDesc.content = newDocumentContent;
eventMgr.onContentChanged(fileDesc); eventMgr.onContentChanged(fileDesc);
@ -589,7 +590,7 @@ define([
}); });
} }
} }
documentContent = newDocumentContent; documentContent = newDocumentContent;
return true; return true;
} }
@ -686,7 +687,7 @@ define([
else { else {
document.body.innerHTML = bodyIndexHTML; document.body.innerHTML = bodyIndexHTML;
} }
var styleContent = ''; var styleContent = '';
// Apply font // Apply font
@ -710,7 +711,7 @@ define([
applyFont(16); applyFont(16);
applyFont(17, 600); applyFont(17, 600);
applyFont(18, 1200); applyFont(18, 1200);
function applyMaxWidth(maxWidth, screenWidth) { function applyMaxWidth(maxWidth, screenWidth) {
styleContent += [ styleContent += [
'@media (min-width: ' + screenWidth + 'px) {', '@media (min-width: ' + screenWidth + 'px) {',
@ -723,7 +724,7 @@ define([
_.each(maxWidthMap, function(entry) { _.each(maxWidthMap, function(entry) {
applyMaxWidth(entry.maxWidth, entry.screenWidth); applyMaxWidth(entry.maxWidth, entry.screenWidth);
}); });
// Apply dynamic stylesheet // Apply dynamic stylesheet
var style = document.createElement("style"); var style = document.createElement("style");
style.innerHTML = styleContent; style.innerHTML = styleContent;
@ -832,10 +833,10 @@ define([
$('#wmd-input').replaceWith(function() { $('#wmd-input').replaceWith(function() {
return $('<pre id="wmd-input">').addClass(this.className).addClass('form-control'); return $('<pre id="wmd-input">').addClass(this.className).addClass('form-control');
}); });
// Create UI layout after textarea // Create UI layout after textarea
createLayout(); createLayout();
editor.init(document.querySelector('#wmd-input'), document.querySelector('.preview-container')); editor.init(document.querySelector('#wmd-input'), document.querySelector('.preview-container'));
} }
else { else {

View File

@ -8,7 +8,7 @@ define([
'crel', 'crel',
'libs/prism-markdown' 'libs/prism-markdown'
], function ($, _, settings, eventMgr, Prism, crel) { ], function ($, _, settings, eventMgr, Prism, crel) {
String.prototype.splice = function (i, remove, add) { String.prototype.splice = function (i, remove, add) {
remove = +remove || 0; remove = +remove || 0;
add = add || ''; add = add || '';
@ -60,23 +60,27 @@ define([
}); });
var previousTextContent; var previousTextContent;
function onInputChange() { function onInputContentChange() {
selectionStart = inputElt.selectionStart; selectionStart = inputElt.selectionStart;
selectionEnd = inputElt.selectionEnd; selectionEnd = inputElt.selectionEnd;
var currentTextContent = inputElt.textContent; var currentTextContent = inputElt.textContent;
if(!/\n$/.test(currentTextContent)) {
currentTextContent += '\n';
}
if(fileChanged === false) { if(fileChanged === false) {
fileDesc.editorStart = selectionStart; fileDesc.editorStart = selectionStart;
fileDesc.editorEnd = selectionEnd; fileDesc.editorEnd = selectionEnd;
if(currentTextContent == previousTextContent) { if(currentTextContent == previousTextContent) {
return; return;
} }
if(!/\n$/.test(currentTextContent)) {
currentTextContent += '\n';
}
fileDesc.content = currentTextContent; fileDesc.content = currentTextContent;
eventMgr.onContentChanged(fileDesc); eventMgr.onContentChanged(fileDesc);
} }
else { else {
if(!/\n$/.test(currentTextContent)) {
currentTextContent += '\n';
fileDesc.content = currentTextContent;
}
eventMgr.onFileOpen(fileDesc); eventMgr.onFileOpen(fileDesc);
previewElt.scrollTop = fileDesc.previewScrollTop; previewElt.scrollTop = fileDesc.previewScrollTop;
selectionStart = fileDesc.editorStart; selectionStart = fileDesc.editorStart;
@ -87,7 +91,59 @@ define([
} }
previousTextContent = currentTextContent; previousTextContent = currentTextContent;
} }
function adjustCursorPosition() {
setTimeout(function() {
selectionStart = inputElt.selectionStart;
selectionEnd = inputElt.selectionEnd;
var backwards = false;
var selection = window.getSelection();
if (!selection.isCollapsed) {
var range = document.createRange();
range.setStart(selection.anchorNode, selection.anchorOffset);
range.setEnd(selection.focusNode, selection.focusOffset);
backwards = range.collapsed;
range.detach();
}
var selectionRange = selection.getRangeAt(0);
var container = backwards ? selectionRange.startContainer : selectionRange.endContainer;
var cursorY;
if(container.textContent == '\n') {
cursorY = container.parentNode.offsetTop + container.parentNode.offsetHeight / 2 - inputElt.scrollTop;
}
else {
if(selectionStart === selectionEnd) {
var selectedChar = inputElt.textContent[selectionStart];
if(selectedChar === undefined || selectedChar == '\n') {
selectionRange = createRange(selectionStart - 1, selectionEnd);
}
else {
selectionRange = createRange(selectionStart, selectionEnd + 1);
}
}
var selectionRect = selectionRange.getBoundingClientRect();
cursorY = selectionRect.top + selectionRect.height / 2 - inputElt.offsetTop;
selectionRange.detach();
}
var adjust = inputElt.offsetHeight / 2;
if(adjust > 130) {
adjust = 130;
}
var cursorMinY = adjust;
var cursorMaxY = inputElt.offsetHeight - adjust;
if(cursorY < cursorMinY) {
inputElt.scrollTop += cursorY - cursorMinY;
}
else if(cursorY > cursorMaxY) {
inputElt.scrollTop += cursorY - cursorMaxY;
}
}, 0);
}
eventMgr.addListener('onLayoutResize', adjustCursorPosition);
editor.init = function(elt1, elt2) { editor.init = function(elt1, elt2) {
inputElt = elt1; inputElt = elt1;
previewElt = elt2; previewElt = elt2;
@ -97,19 +153,19 @@ define([
}); });
editor.$contentElt = $(editor.contentElt); editor.$contentElt = $(editor.contentElt);
inputElt.appendChild(editor.contentElt); inputElt.appendChild(editor.contentElt);
$(inputElt).scroll(function() { $(inputElt).scroll(function() {
scrollTop = this.scrollTop; scrollTop = this.scrollTop;
if(fileChanged === false) { if(fileChanged === false) {
fileDesc.editorScrollTop = scrollTop; fileDesc.editorScrollTop = scrollTop;
} }
}).bind("keyup mouseup", onInputChange); }).bind("keyup mouseup", onInputContentChange);
$(previewElt).scroll(function() { $(previewElt).scroll(function() {
if(fileChanged === false) { if(fileChanged === false) {
fileDesc.previewScrollTop = previewElt.scrollTop; fileDesc.previewScrollTop = previewElt.scrollTop;
} }
}); });
inputElt.focus = function() { inputElt.focus = function() {
editor.$contentElt.focus(); editor.$contentElt.focus();
this.setSelectionRange(selectionStart, selectionEnd); this.setSelectionRange(selectionStart, selectionEnd);
@ -121,7 +177,7 @@ define([
editor.$contentElt.blur(function() { editor.$contentElt.blur(function() {
inputElt.focused = false; inputElt.focused = false;
}); });
Object.defineProperty(inputElt, 'value', { Object.defineProperty(inputElt, 'value', {
get: function () { get: function () {
return this.textContent; return this.textContent;
@ -151,13 +207,13 @@ define([
var replacementText = value.substring(startIndex, value.length - endIndex + 1); var replacementText = value.substring(startIndex, value.length - endIndex + 1);
endIndex = currentValue.length - endIndex + 1; endIndex = currentValue.length - endIndex + 1;
var range = createRange(inputElt, startIndex, endIndex); var range = createRange(startIndex, endIndex);
range.deleteContents(); range.deleteContents();
range.insertNode(document.createTextNode(replacementText)); range.insertNode(document.createTextNode(replacementText));
onInputChange(); onInputContentChange();
} }
}); });
Object.defineProperty(inputElt, 'selectionStart', { Object.defineProperty(inputElt, 'selectionStart', {
get: function () { get: function () {
var selection = window.getSelection(); var selection = window.getSelection();
@ -213,87 +269,10 @@ define([
configurable: true configurable: true
}); });
function findOffset(root, ss) {
if (!root) {
return null;
}
var offset = 0,
element = root,
container;
do {
container = element;
element = element.firstChild;
if (element) {
do {
var len = element.textContent.length;
if (offset <= ss && offset + len > ss) {
break;
}
offset += len;
} while (element = element.nextSibling);
}
if (!element) {
// It's the container's lastChild
break;
}
} while (element && element.hasChildNodes() && element.nodeType != 3);
if (element) {
return {
element: element,
offset: ss - offset
};
} else if (container) {
element = container;
while (element && element.lastChild) {
element = element.lastChild;
}
if (element.nodeType === 3) {
return {
element: element,
offset: element.textContent.length
};
} else {
return {
element: element,
offset: 0
};
}
}
return {
element: root,
offset: 0,
error: true
};
}
function createRange(root, ss, se) {
var range = document.createRange(),
offset = findOffset(root, ss);
range.setStart(offset.element, offset.offset);
if (se && se != ss) {
offset = findOffset(root, se);
}
range.setEnd(offset.element, offset.offset);
return range;
}
inputElt.setSelectionRange = function (ss, se) { inputElt.setSelectionRange = function (ss, se) {
selectionStart = ss; selectionStart = ss;
selectionEnd = se; selectionEnd = se;
var range = createRange(editor.contentElt, ss, se); var range = createRange(ss, se);
var selection = window.getSelection(); var selection = window.getSelection();
selection.removeAllRanges(); selection.removeAllRanges();
@ -303,6 +282,10 @@ define([
editor.$contentElt.on('keydown', function (evt) { editor.$contentElt.on('keydown', function (evt) {
var cmdOrCtrl = evt.metaKey || evt.ctrlKey; var cmdOrCtrl = evt.metaKey || evt.ctrlKey;
if(!cmdOrCtrl && !event.altKey && !event.shiftKey) {
adjustCursorPosition();
}
switch (evt.keyCode) { switch (evt.keyCode) {
case 9: // Tab case 9: // Tab
if (!cmdOrCtrl) { if (!cmdOrCtrl) {
@ -330,17 +313,17 @@ define([
editor.$contentElt.on('paste', function () { editor.$contentElt.on('paste', function () {
pagedownEditor.undoManager.setMode("paste"); pagedownEditor.undoManager.setMode("paste");
setTimeout(function() { setTimeout(function() {
onInputChange(); onInputContentChange();
}, 0); }, 0);
}); });
editor.$contentElt.on('cut', function () { editor.$contentElt.on('cut', function () {
pagedownEditor.undoManager.setMode("cut"); pagedownEditor.undoManager.setMode("cut");
setTimeout(function() { setTimeout(function() {
onInputChange(); onInputContentChange();
}, 0); }, 0);
}); });
var action = function (action, options) { var action = function (action, options) {
options = options || {}; options = options || {};
@ -403,98 +386,17 @@ define([
pagedownEditor.undoManager.setMode("newlines"); pagedownEditor.undoManager.setMode("newlines");
state.before += '\n'// + indent; state.before += '\n' + indent;
state.selection = ''; state.selection = '';
state.ss += indent.length + 1; state.ss += indent.length + 1;
state.se = state.ss; state.se = state.ss;
}, },
comment: function (state) {
var textAction;
var open = '<!--',
close = '-->';
var start = state.before.lastIndexOf(open),
end = state.after.indexOf(close),
closeBefore = state.before.lastIndexOf(close),
openAfter = state.after.indexOf(start);
pagedownEditor.undoManager.setMode("typing");
if (start > -1 && end > -1 && (start > closeBefore || closeBefore === -1) && (end < openAfter || openAfter === -1)) {
// Uncomment
state.before = state.before.splice(start, open.length);
state.after = state.after.splice(end, close.length);
textAction = [{
add: '',
del: open,
start: start
}, {
add: '',
del: close,
start: state.before.length + state.selection.length + end
}];
state.ss -= open.length;
state.se -= open.length;
return textAction;
} else {
// Comment
if (state.selection) {
// Comment selection
state.selection = open + state.selection + close;
textAction = [{
add: open,
del: '',
start: state.ss
}, {
add: close,
del: '',
start: open.length + state.se
}];
} else {
// Comment whole line
start = state.before.lastIndexOf('\n') + 1;
end = state.after.indexOf('\n');
if (end === -1) {
end = state.after.length;
}
while (/\s/.test(state.before.charAt(start))) {
start++;
}
state.before = state.before.splice(start, 0, open);
state.after = state.after.splice(end, 0, close);
textAction = [{
add: open,
del: '',
start: start
}, {
add: close,
del: '',
start: state.before.length + end
}];
}
state.ss += open.length;
state.se += open.length;
return textAction;
}
}
}; };
}; };
var sectionList = []; var sectionList = [];
var sectionsToRemove = []; var sectionsToRemove = [];
var modifiedSections = []; var modifiedSections = [];
@ -516,28 +418,38 @@ define([
// Find modified section starting from top // Find modified section starting from top
var leftIndex = sectionList.length; var leftIndex = sectionList.length;
_.some(sectionList, function(section, index) { _.some(sectionList, function(section, index) {
if(index >= newSectionList.length || section.text != newSectionList[index].text) { var newSection = newSectionList[index];
if(index >= newSectionList.length ||
// Check modified
section.textWithFrontMatter != newSection.textWithFrontMatter ||
// Check that section has not been detached from the DOM with backspace
!section.highlightedContent.parentNode) {
leftIndex = index; leftIndex = index;
return true; return true;
} }
}); });
// Find modified section starting from bottom // Find modified section starting from bottom
var rightIndex = -sectionList.length; var rightIndex = -sectionList.length;
_.some(sectionList.slice().reverse(), function(section, index) { _.some(sectionList.slice().reverse(), function(section, index) {
var newSectionText = newSectionList[newSectionList.length - index - 1].text; var newSection = newSectionList[newSectionList.length - index - 1];
// Check also the content of the node since new lines can be added just at the beggining if(index >= newSectionList.length ||
if(index >= newSectionList.length || section.text != newSectionText || section.highlightedContent.textContent != newSectionText) { // Check modified
section.textWithFrontMatter != newSection.textWithFrontMatter ||
// Check that section has not been detached from the DOM with backspace
!section.highlightedContent.parentNode ||
// Check also the content of the node since new lines can be added just at the beggining
section.highlightedContent.textContent != newSection.textWithFrontMatter) {
rightIndex = -index; rightIndex = -index;
return true; return true;
} }
}); });
if(leftIndex - rightIndex > sectionList.length) { if(leftIndex - rightIndex > sectionList.length) {
// Prevent overlap // Prevent overlap
rightIndex = leftIndex - sectionList.length; rightIndex = leftIndex - sectionList.length;
} }
// Create an array composed of left unmodified, modified, right // Create an array composed of left unmodified, modified, right
// unmodified sections // unmodified sections
var leftSections = sectionList.slice(0, leftIndex); var leftSections = sectionList.slice(0, leftIndex);
@ -547,8 +459,8 @@ define([
sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex); sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex);
sectionList = leftSections.concat(modifiedSections).concat(rightSections); sectionList = leftSections.concat(modifiedSections).concat(rightSections);
} }
function highlightSections() { function highlightSections() {
selectionStart = inputElt.selectionStart; selectionStart = inputElt.selectionStart;
selectionEnd = inputElt.selectionEnd; selectionEnd = inputElt.selectionEnd;
var newSectionEltList = document.createDocumentFragment(); var newSectionEltList = document.createDocumentFragment();
@ -568,7 +480,7 @@ define([
// section can be already removed // section can be already removed
sectionElt && editor.contentElt.removeChild(sectionElt); sectionElt && editor.contentElt.removeChild(sectionElt);
}); });
if(insertBeforeSection !== undefined) { if(insertBeforeSection !== undefined) {
var insertBeforeElt = document.getElementById("wmd-input-section-" + insertBeforeSection.id); var insertBeforeElt = document.getElementById("wmd-input-section-" + insertBeforeSection.id);
editor.contentElt.insertBefore(newSectionEltList, insertBeforeElt); editor.contentElt.insertBefore(newSectionEltList, insertBeforeElt);
@ -576,11 +488,9 @@ define([
else { else {
editor.contentElt.appendChild(newSectionEltList); editor.contentElt.appendChild(newSectionEltList);
} }
//var dummyTextNode = document.createTextNode('\n');
//editor.contentElt.appendChild(dummyTextNode);
inputElt.setSelectionRange(selectionStart, selectionEnd); inputElt.setSelectionRange(selectionStart, selectionEnd);
// Remove textNodes created outside sections // Remove textNodes created outside sections
var childNode = editor.contentElt.firstChild; var childNode = editor.contentElt.firstChild;
while(childNode) { while(childNode) {
@ -592,49 +502,9 @@ define([
} }
} }
} }
/*
function asyncHighlightSections() {
var startTime = Date.now();
var deferredList = [];
modifiedSections.forEach(function(section) {
var deferred = $.Deferred();
setTimeout(function() {
highlight(section);
deferred.resolve();
}, 0);
deferredList.push(deferred);
});
$.when.apply($, deferredList).then(function() {
var text = _.reduce(sectionList, function(text, section) {
return text + section.text;
}, '');
// Check that the editor has the actual value
if(inputElt.textContent == text) {
selectionStart = inputElt.selectionStart;
selectionEnd = inputElt.selectionEnd;
var newSectionEltList = document.createDocumentFragment();
modifiedSections.forEach(function(section) {
newSectionEltList.appendChild(section.highlightedContent);
});
if(insertBeforeSection !== undefined) {
var insertBeforeElt = document.getElementById("wmd-input-section-" + insertBeforeSection.id);
editor.$contentElt[0].insertBefore(newSectionEltList, insertBeforeElt);
}
else {
editor.$contentElt[0].appendChild(newSectionEltList);
}
inputElt.setSelectionRange(selectionStart, selectionEnd);
elapsedTime = Date.now() - startTime;
}
});
}
*/
function highlight(section) { function highlight(section) {
var text = section.text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' '); var text = section.textWithFrontMatter.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
var sectionElt = crel('span', { var sectionElt = crel('span', {
id: 'wmd-input-section-' + section.id, id: 'wmd-input-section-' + section.id,
class: 'wmd-input-section' class: 'wmd-input-section'
@ -643,5 +513,79 @@ define([
section.highlightedContent = sectionElt; section.highlightedContent = sectionElt;
} }
function createRange(ss, se) {
function findOffset(ss) {
var offset = 0,
element = editor.contentElt,
container;
do {
container = element;
element = element.firstChild;
if (element) {
do {
var len = element.textContent.length;
if (offset <= ss && offset + len > ss) {
break;
}
offset += len;
} while (element = element.nextSibling);
}
if (!element) {
// It's the container's lastChild
break;
}
} while (element && element.hasChildNodes() && element.nodeType != 3);
if (element) {
return {
element: element,
offset: ss - offset
};
} else if (container) {
element = container;
while (element && element.lastChild) {
element = element.lastChild;
}
if (element.nodeType === 3) {
return {
element: element,
offset: element.textContent.length
};
} else {
return {
element: element,
offset: 0
};
}
}
return {
element: editor.contentElt,
offset: 0,
error: true
};
}
var range = document.createRange(),
offset = findOffset(ss);
range.setStart(offset.element, offset.offset);
if (se && se != ss) {
offset = findOffset(se);
}
range.setEnd(offset.element, offset.offset);
return range;
}
return editor; return editor;
}); });

View File

@ -43,7 +43,8 @@ define([
var cursorMinY = coef*editorHeight; var cursorMinY = coef*editorHeight;
var cursorMaxY = (1-coef)*editorHeight; var cursorMaxY = (1-coef)*editorHeight;
var cursorY = $editorElt.caret('offset').top - $editorElt.offset().top; var cursorY = $editorElt.caret('offset').top - $editorElt.offset().top;
console.log($editorElt.caret('offset')); //console.log($editorElt.find('.pre-content').caret('offset'));
//console.log(window.getSelection().getRangeAt(0).getBoundingClientRect());
//$positionHelper.detach(); //$positionHelper.detach();
//parentNode.normalize(); //parentNode.normalize();
/* /*

View File

@ -11,9 +11,9 @@ define([
markdownSectionParser.onEventMgrCreated = function(eventMgrParameter) { markdownSectionParser.onEventMgrCreated = function(eventMgrParameter) {
eventMgr = eventMgrParameter; eventMgr = eventMgrParameter;
}; };
var sectionList = []; var sectionList = [];
// Regexp to look for section delimiters // Regexp to look for section delimiters
var regexp = '^.+[ \\t]*\\n=+[ \\t]*\\n+|^.+[ \\t]*\\n-+[ \\t]*\\n+|^\\#{1,6}[ \\t]*.+?[ \\t]*\\#*\\n+'; // Title delimiters var regexp = '^.+[ \\t]*\\n=+[ \\t]*\\n+|^.+[ \\t]*\\n-+[ \\t]*\\n+|^\\#{1,6}[ \\t]*.+?[ \\t]*\\#*\\n+'; // Title delimiters
markdownSectionParser.onPagedownConfigure = function(editor) { markdownSectionParser.onPagedownConfigure = function(editor) {
@ -31,7 +31,7 @@ define([
regexp = '^[ \\t]*\\n\\\\?\\\\begin\\{[a-z]*\\*?\\}[\\s\\S]*?\\\\end\\{[a-z]*\\*?\\}|' + regexp; // \\begin{...} \\end{...} math block delimiters regexp = '^[ \\t]*\\n\\\\?\\\\begin\\{[a-z]*\\*?\\}[\\s\\S]*?\\\\end\\{[a-z]*\\*?\\}|' + regexp; // \\begin{...} \\end{...} math block delimiters
} }
regexp = new RegExp(regexp, 'gm'); regexp = new RegExp(regexp, 'gm');
var converter = editor.getConverter(); var converter = editor.getConverter();
converter.hooks.chain("preConversion", function() { converter.hooks.chain("preConversion", function() {
return _.reduce(sectionList, function(result, section) { return _.reduce(sectionList, function(result, section) {
@ -39,8 +39,8 @@ define([
}, ''); }, '');
}); });
}; };
var trimLen; var trimLen = 0;
markdownSectionParser.onMarkdownTrim = function(len) { markdownSectionParser.onMarkdownTrim = function(len) {
trimLen = len; trimLen = len;
}; };
@ -48,13 +48,16 @@ define([
var sectionCounter = 0; var sectionCounter = 0;
function parseFileContent(fileDesc) { function parseFileContent(fileDesc) {
var text = fileDesc.content.substring(trimLen); var text = fileDesc.content.substring(trimLen);
var frontMatter = fileDesc.content.substring(0, trimLen);
var tmpText = text + "\n\n"; var tmpText = text + "\n\n";
function addSection(startOffset, endOffset) { function addSection(startOffset, endOffset) {
var sectionText = tmpText.substring(offset, endOffset); var sectionText = tmpText.substring(offset, endOffset);
sectionList.push({ sectionList.push({
id: ++sectionCounter, id: ++sectionCounter,
text: sectionText text: sectionText,
textWithFrontMatter: frontMatter + sectionText
}); });
frontMatter = '';
} }
sectionList = []; sectionList = [];
var offset = 0; var offset = 0;
@ -68,9 +71,9 @@ define([
addSection(offset, text.length); addSection(offset, text.length);
eventMgr.onSectionsCreated(sectionList); eventMgr.onSectionsCreated(sectionList);
} }
markdownSectionParser.onFileOpen = parseFileContent; markdownSectionParser.onFileOpen = parseFileContent;
markdownSectionParser.onContentChanged = parseFileContent; markdownSectionParser.onContentChanged = parseFileContent;
return markdownSectionParser; return markdownSectionParser;
}); });

View File

@ -17,7 +17,7 @@ define([
scrollLink.onSectionsCreated = function(sectionListParam) { scrollLink.onSectionsCreated = function(sectionListParam) {
sectionList = sectionListParam; sectionList = sectionListParam;
}; };
var offsetBegin = 0; var offsetBegin = 0;
scrollLink.onMarkdownTrim = function(offsetBeginParam) { scrollLink.onMarkdownTrim = function(offsetBeginParam) {
offsetBegin = offsetBeginParam; offsetBegin = offsetBeginParam;
@ -161,8 +161,8 @@ define([
lastPreviewScrollTop = previewScrollTop; lastPreviewScrollTop = previewScrollTop;
return; return;
} }
$previewElt.stop('scrollLinkFx', true).animate({ scrollingHelper.stop('scrollLinkFx', true).css('value', 0).animate({
scrollTop: destScrollTop value: destScrollTop - previewScrollTop
}, { }, {
easing: 'easeOutSine', easing: 'easeOutSine',
duration: 200, duration: 200,
@ -170,13 +170,15 @@ define([
step: function(now) { step: function(now) {
isPreviewMoving = true; isPreviewMoving = true;
lastPreviewScrollTop = previewScrollTop + now; lastPreviewScrollTop = previewScrollTop + now;
$previewElt.scrollTop(lastPreviewScrollTop);
}, },
done: function() { done: function() {
setTimeout(function() { _.defer(function() {
isPreviewMoving = false; isPreviewMoving = false;
}, 100); });
}, },
}).dequeue('scrollLinkFx'); }).dequeue('scrollLinkFx');
} }
else if(isScrollPreview === true) { else if(isScrollPreview === true) {
if(Math.abs(previewScrollTop - lastPreviewScrollTop) <= 9) { if(Math.abs(previewScrollTop - lastPreviewScrollTop) <= 9) {
@ -205,43 +207,28 @@ define([
lastEditorScrollTop = editorScrollTop; lastEditorScrollTop = editorScrollTop;
return; return;
} }
if(window.lightMode) { scrollingHelper.stop('scrollLinkFx', true).css('value', 0).animate({
$editorElt.stop('scrollLinkFx', true).animate({ value: destScrollTop - editorScrollTop
scrollTop: destScrollTop }, {
}, { easing: 'easeOutSine',
easing: 'easeOutSine', duration: 200,
duration: 200, queue: 'scrollLinkFx',
queue: 'scrollLinkFx', step: function(now) {
step: function(now) { isEditorMoving = true;
isEditorMoving = true; lastEditorScrollTop = editorScrollTop + now;
lastEditorScrollTop = editorScrollTop + now; if(window.lightMode) {
}, $editorElt.scrollTop(lastEditorScrollTop);
done: function() { }
setTimeout(function() { else {
isEditorMoving = false;
}, 100);
},
}).dequeue('scrollLinkFx');
}
else {
scrollingHelper.stop('scrollLinkFx', true).css('value', 0).animate({
value: destScrollTop - editorScrollTop
}, {
easing: 'easeOutSine',
duration: 200,
queue: 'scrollLinkFx',
step: function(now) {
isEditorMoving = true;
lastEditorScrollTop = editorScrollTop + now;
aceEditor.session.setScrollTop(lastEditorScrollTop); aceEditor.session.setScrollTop(lastEditorScrollTop);
}, }
done: function() { },
_.defer(function() { done: function() {
isEditorMoving = false; _.defer(function() {
}); isEditorMoving = false;
}, });
}).dequeue('scrollLinkFx'); },
} }).dequeue('scrollLinkFx');
} }
}, 100); }, 100);
@ -249,7 +236,7 @@ define([
isScrollEditor = true; isScrollEditor = true;
buildSections(); buildSections();
}; };
var isPreviewVisible = true; var isPreviewVisible = true;
function setPreviewHidden() { function setPreviewHidden() {
isPreviewVisible = false; isPreviewVisible = false;
@ -259,7 +246,7 @@ define([
isPreviewVisible = true; isPreviewVisible = true;
console.log(isPreviewVisible); console.log(isPreviewVisible);
} }
scrollLink.onLayoutConfigure = function(layoutGlobalConfig) { scrollLink.onLayoutConfigure = function(layoutGlobalConfig) {
layoutGlobalConfig.east__onclose = setPreviewHidden; layoutGlobalConfig.east__onclose = setPreviewHidden;
layoutGlobalConfig.south__onclose = setPreviewHidden; layoutGlobalConfig.south__onclose = setPreviewHidden;
@ -324,4 +311,4 @@ define([
}; };
return scrollLink; return scrollLink;
}); });

View File

@ -17,7 +17,8 @@ define([
}; };
var regex = /^(\s*-{3}\s*\n([\w\W]+?)\n\s*-{3}\s*\n)?([\w\W]*)$/; var regex = /^(\s*-{3}\s*\n([\w\W]+?)\n\s*-{3}\s*\n)?([\w\W]*)$/;
yamlFrontMatterParser.onContentChanged = function(fileDesc) {
function parseFrontMatter(fileDesc) {
var text = fileDesc.content; var text = fileDesc.content;
var results = regex.exec(text); var results = regex.exec(text);
var yaml = results[2]; var yaml = results[2];
@ -34,11 +35,14 @@ define([
} }
catch (e) { catch (e) {
eventMgr.onMarkdownTrim(0); eventMgr.onMarkdownTrim(0);
return text; return;
} }
} }
eventMgr.onMarkdownTrim((results[1] || '').length); eventMgr.onMarkdownTrim((results[1] || '').length);
}; }
yamlFrontMatterParser.onFileOpen = parseFrontMatter;
yamlFrontMatterParser.onContentChanged = parseFrontMatter;
return yamlFrontMatterParser; return yamlFrontMatterParser;
}); });

View File

@ -123,6 +123,22 @@
</div> </div>
<div class=dropdown-header>IMPORT</div> <div class=dropdown-header>IMPORT</div>
<div class="list-group"> <div class="list-group">
<a class="list-group-item action-sync-import-dropbox" href="#"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-dropbox"></i> Open from
Dropbox</a>
<a href="#" class="list-group-item submenu-sync-gdrive action-sync-import-gdrive"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-gdrive"></i> Open from
Google Drive</a>
<a href="#" class="list-group-item submenu-sync-gdrivesec action-sync-import-gdrivesec"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-gdrive"></i> Open from
Google Drive <small>(2nd account)</small></a>
<a href="#" class="list-group-item submenu-sync-gdriveter action-sync-import-gdriveter"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-gdrive"></i> Open from
Google Drive <small>(3rd account)</small></a>
<a data-toggle="modal" <a data-toggle="modal"
data-target=".modal-import-harddrive-markdown" data-target=".modal-import-harddrive-markdown"
class="list-group-item action-reset-input" href="#"><i class="list-group-item action-reset-input" href="#"><i
@ -134,22 +150,6 @@
data-target=".modal-import-harddrive-html" data-target=".modal-import-harddrive-html"
class="list-group-item action-reset-input" href="#"><i class="list-group-item action-reset-input" href="#"><i
class="icon-code"></i> Convert HTML to Markdown</a> class="icon-code"></i> Convert HTML to Markdown</a>
<a class="list-group-item action-sync-import-dropbox" href="#"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-dropbox"></i> Import from
Dropbox</a>
<a href="#" class="list-group-item submenu-sync-gdrive action-sync-import-gdrive"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-gdrive"></i> Import from
Google Drive</a>
<a href="#" class="list-group-item submenu-sync-gdrivesec action-sync-import-gdrivesec"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-gdrive"></i> Import from
Google Drive <small>(2nd account)</small></a>
<a href="#" class="list-group-item submenu-sync-gdriveter action-sync-import-gdriveter"
data-toggle="collapse" data-target=".menu-panel"><i
class="icon-provider-gdrive"></i> Import from
Google Drive <small>(3rd account)</small></a>
</div> </div>
<ul class="nav"> <ul class="nav">
<li><a href="#" data-toggle="modal" <li><a href="#" data-toggle="modal"

View File

@ -106,6 +106,7 @@ Prism.languages.md = (function() {
'md md-toc': /^\s*\[(toc|TOC)\]\s*$/g 'md md-toc': /^\s*\[(toc|TOC)\]\s*$/g
} }
}; };
md.br = /^\n$/gm;
md.img = { md.img = {
pattern: /!\[[^\]]*\]\([^\)]+\)/g, pattern: /!\[[^\]]*\]\([^\)]+\)/g,
inside: { inside: {

View File

@ -80,7 +80,7 @@
@nav-disabled-link-color: @disabled-color; @nav-disabled-link-color: @disabled-color;
@nav-disabled-link-hover-color: @disabled-color; @nav-disabled-link-hover-color: @disabled-color;
@nav-tabs-border-color: @transparent; @nav-tabs-border-color: @transparent;
@nav-tabs-link-hover-border-color: @transparent; @nav-tabs-link-hover-border-color: @transparent;
@dropdown-bg: @secondary-bg-lighter; @dropdown-bg: @secondary-bg-lighter;
@dropdown-border: @secondary-border-color; @dropdown-border: @secondary-border-color;
@dropdown-link-color: @secondary-color-darkest; @dropdown-link-color: @secondary-color-darkest;
@ -248,11 +248,11 @@ a {
/******************* /*******************
* Buttons * Buttons
*******************/ *******************/
.btn { .btn {
padding: 8px 11px; padding: 8px 11px;
.transition(~"background-color ease-in-out .15s, color ease-in-out .15s, border-color ease-in-out .15s"); .transition(~"background-color ease-in-out .15s, color ease-in-out .15s, border-color ease-in-out .15s");
} }
.btn-default { .btn-default {
&:hover, &:hover,
@ -349,7 +349,7 @@ a {
.form-control-focus(@color: @secondary-desaturated) { .form-control-focus(@color: @secondary-desaturated) {
@color-rgba: rgba(red(@color), green(@color), blue(@color), .6); @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
&:focus { &:focus {
border-color: @input-border; border-color: @input-border;
outline: 0; outline: 0;
.box-shadow(~"@{form-control-inset-shadow}, 0 0 12px -1px @{color-rgba}"); .box-shadow(~"@{form-control-inset-shadow}, 0 0 12px -1px @{color-rgba}");
} }
@ -381,7 +381,7 @@ a {
&:first-child .btn { &:first-child .btn {
margin-right: 6px; margin-right: 6px;
} }
&:last-child .btn { &:last-child .btn {
margin-left: 6px; margin-left: 6px;
} }
@ -391,7 +391,7 @@ a {
/******************* /*******************
* Navbar * Navbar
*******************/ *******************/
.navbar { .navbar {
position: static; position: static;
padding: 0; padding: 0;
@ -437,7 +437,7 @@ a {
} }
} }
} }
.file-title-navbar { .file-title-navbar {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
@ -449,7 +449,7 @@ a {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
} }
.input-file-title-container { .input-file-title-container {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
@ -479,21 +479,21 @@ a {
-webkit-animation: indicator 0.6s ease-out infinite; /* Safari and Chrome */ -webkit-animation: indicator 0.6s ease-out infinite; /* Safari and Chrome */
} }
} }
.offline-status > div { .offline-status > div {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
height: @input-height-slim; height: @input-height-slim;
padding: 9px 10px; padding: 9px 10px;
} }
.buttons-dropdown { .buttons-dropdown {
> .nav { > .nav {
margin-left: 0; margin-left: 0;
margin-right: 0; margin-right: 0;
} }
} }
div.dropdown-menu { div.dropdown-menu {
top: initial; top: initial;
padding: 5px; padding: 5px;
@ -515,7 +515,7 @@ a {
* Menu/Document panels * Menu/Document panels
*********************/ *********************/
// Common style // Common style
.menu-panel, .document-panel { .menu-panel, .document-panel {
display: block; display: block;
position: absolute; position: absolute;
@ -628,7 +628,7 @@ a {
border-left: 1px solid @secondary-border-color-light; border-left: 1px solid @secondary-border-color-light;
.icon-layers { .icon-layers {
font-size: 135%; font-size: 135%;
} }
} }
.search-bar { .search-bar {
position: absolute; position: absolute;
@ -667,8 +667,8 @@ a {
padding-left: 30px; padding-left: 30px;
padding-right: 30px; padding-right: 30px;
} }
} }
} }
} }
// Dropdown document selector // Dropdown document selector
@ -688,7 +688,7 @@ a {
/************************** /**************************
* Document manager * Document manager
**************************/ **************************/
.modal-document-manager { .modal-document-manager {
.nav-pills { .nav-pills {
margin-bottom: 15px; margin-bottom: 15px;
@ -746,8 +746,8 @@ a {
height: @input-height-slim; height: @input-height-slim;
} }
.name, .file-count { .name, .file-count {
padding: 9px 20px 9px 15px; padding: 9px 20px 9px 15px;
} }
} }
@ -792,11 +792,11 @@ a {
margin-top: 4px; margin-top: 4px;
padding-bottom: 20px; padding-bottom: 20px;
} }
hr { hr {
margin: 0; margin: 0;
} }
.markdown-syntax, .table-of-contents { .markdown-syntax, .table-of-contents {
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
@ -804,11 +804,11 @@ a {
margin-right: -20px; margin-right: -20px;
width: 330px; width: 330px;
} }
.markdown-syntax { .markdown-syntax {
white-space: normal; white-space: normal;
} }
.table-of-contents { .table-of-contents {
padding: 20px 0 15px; padding: 20px 0 15px;
margin-left: -10px; margin-left: -10px;
@ -837,7 +837,7 @@ a {
} }
} }
/************************** /**************************
* Settings dialog * Settings dialog
**************************/ **************************/
@ -846,12 +846,12 @@ a {
.modal-header { .modal-header {
padding-bottom: 0; padding-bottom: 0;
} }
textarea { textarea {
max-width: 100%; max-width: 100%;
min-height: 100px; min-height: 100px;
} }
.panel { .panel {
border: 0; border: 0;
border-radius: inherit; border-radius: inherit;
@ -859,7 +859,7 @@ a {
border-bottom: 1px solid @modal-content-separator-color; border-bottom: 1px solid @modal-content-separator-color;
.box-shadow(none); .box-shadow(none);
} }
.accordion-heading { .accordion-heading {
padding: 12px 15px; padding: 12px 15px;
.checkbox { .checkbox {
@ -867,7 +867,7 @@ a {
margin-bottom: 0; margin-bottom: 0;
} }
} }
.accordion-inner { .accordion-inner {
border: 0; border: 0;
padding: 10px 40px 20px; padding: 10px 40px 20px;
@ -877,10 +877,10 @@ a {
} }
.form-inline .label-text { .form-inline .label-text {
margin-left: 15px margin-left: 15px
} }
} }
} }
.tab-pane-button-container { .tab-pane-button-container {
width: 220px; width: 220px;
margin: 10px auto 20px; margin: 10px auto 20px;
@ -889,10 +889,10 @@ a {
padding-left: 15px; padding-left: 15px;
} }
} }
.nav-tabs { .nav-tabs {
margin: 15px 0 0; margin: 15px 0 0;
& > li > a { & > li > a {
&:hover, &:focus { &:hover, &:focus {
color: darken(@secondary, 30%); color: darken(@secondary, 30%);
@ -901,7 +901,7 @@ a {
border-bottom-color: @transparent; border-bottom-color: @transparent;
} }
} }
& > li.active > a { & > li.active > a {
&, &:hover, &:focus { &, &:hover, &:focus {
color: @btn-primary-color; color: @btn-primary-color;
@ -919,7 +919,7 @@ a {
/******************************** /********************************
* Publish/Sync/Share dialogs * Publish/Sync/Share dialogs
********************************/ ********************************/
.modal-manage-sync .sync-list, .modal-manage-sync .sync-list,
.modal-manage-publish .publish-list, .modal-manage-publish .publish-list,
.modal-manage-sharing .share-list { .modal-manage-sharing .share-list {
@ -946,7 +946,7 @@ a {
/********************************* /*********************************
* UI Layout * UI Layout
*********************************/ *********************************/
.ui-layout-resizer { .ui-layout-resizer {
overflow: visible !important; overflow: visible !important;
font-size: 14px !important; font-size: 14px !important;
@ -1017,14 +1017,14 @@ a {
/***************************** /*****************************
* Editor * Editor
*****************************/ *****************************/
.ace_editor { .ace_editor {
color: @tertiary-color-dark; color: @tertiary-color-dark;
} }
.ace-tm { .ace-tm {
background-color: @tertiary-bg; background-color: @tertiary-bg;
.ace_text-input { .ace_text-input {
box-sizing: initial; box-sizing: initial;
} }
@ -1032,107 +1032,107 @@ a {
.ace_cursor { .ace_cursor {
color: darken(@primary-desaturated, 30%); color: darken(@primary-desaturated, 30%);
} }
.ace_print-margin-layer { .ace_print-margin-layer {
display: none; display: none;
} }
.ace_marker-layer .ace_bracket { .ace_marker-layer .ace_bracket {
display: none; display: none;
} }
.ace_markup.ace_heading { .ace_markup.ace_heading {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font-weight: bold; font-weight: bold;
} }
.ace_markup.ace_list { .ace_markup.ace_list {
color: @tertiary-color; color: @tertiary-color;
} }
.ace_constant.ace_language { .ace_constant.ace_language {
color: @tertiary-color-light; color: @tertiary-color-light;
font-weight: normal; font-weight: normal;
} }
.ace_meta.ace_tag { .ace_meta.ace_tag {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font-weight: bold; font-weight: bold;
} }
.ace_keyword.ace_operator { .ace_keyword.ace_operator {
color: @tertiary-color-dark; color: @tertiary-color-dark;
background-color: transparent; background-color: transparent;
} }
.ace_storage, .ace_keyword { .ace_storage, .ace_keyword {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font-weight: bold; font-weight: bold;
} }
.ace_entity.ace_name.ace_function { .ace_entity.ace_name.ace_function {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font-weight: bold; font-weight: bold;
} }
.ace_string { .ace_string {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font-weight: bold; font-weight: bold;
} }
.ace_invalid { .ace_invalid {
color: inherit; color: inherit;
background: inherit; background: inherit;
} }
.ace_strong { .ace_strong {
color: @tertiary-color-dark; color: @tertiary-color-dark;
font-weight: bold; font-weight: bold;
} }
.ace_emphasis { .ace_emphasis {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font-style: italic; font-style: italic;
} }
.ace_blockquote { .ace_blockquote {
color: @tertiary-color; color: @tertiary-color;
} }
.ace_code { .ace_code {
color: @tertiary-color-darker; color: @tertiary-color-darker;
background-color: @code-bg; background-color: @code-bg;
} }
.ace_code_block { .ace_code_block {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font-weight: bold; font-weight: bold;
} }
.ace_link { .ace_link {
color: @tertiary-color; color: @tertiary-color;
background-color: @code-bg; background-color: @code-bg;
} }
.ace_description { .ace_description {
color: @tertiary-color; color: @tertiary-color;
} }
.ace_constant { .ace_constant {
color: @tertiary-color-dark; color: @tertiary-color-dark;
} }
.ace_comment { .ace_comment {
color: @tertiary-color-light; color: @tertiary-color-light;
font-style: italic; font-style: italic;
} }
.ace_doccomment { .ace_doccomment {
color: fade(@state-danger-text, 90%); color: fade(@state-danger-text, 90%);
font-style: italic; font-style: italic;
font-weight: bold; font-weight: bold;
} }
.ace_marker-layer .misspelled { .ace_marker-layer .misspelled {
position: absolute; position: absolute;
z-index: -2; z-index: -2;
@ -1252,16 +1252,16 @@ a {
word-break: break-word; word-break: break-word;
> div { > div {
margin: 0 auto; margin: 0 auto;
padding: 10px 0 230px; padding-bottom: 230px;
} }
} }
.code, .code,
.pre { .pre {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font: normal 0.9em @font-family-monospace font: normal 0.9em @font-family-monospace
} }
.tag { .tag {
color: @tertiary-color-darker; color: @tertiary-color-darker;
font: bold 0.9em @font-family-monospace; font: bold 0.9em @font-family-monospace;
@ -1271,11 +1271,11 @@ a {
font-weight: normal; font-weight: normal;
} }
} }
.latex, .math { .latex, .math {
color: @tertiary-color; color: @tertiary-color;
} }
.entity { .entity {
font: italic 0.9em @font-family-monospace; font: italic 0.9em @font-family-monospace;
color: @tertiary-color; color: @tertiary-color;
@ -1285,23 +1285,23 @@ a {
font-size: 0.9em; font-size: 0.9em;
color: @tertiary-color-light; color: @tertiary-color-light;
} }
.keyword { .keyword {
color: @tertiary-color-dark; color: @tertiary-color-dark;
font-weight: bold; font-weight: bold;
} }
.code, .img, .imgref, .md-toc { .code, .img, .imgref, .md-toc {
background-color: @code-bg; background-color: @code-bg;
border-radius: @border-radius-base; border-radius: @border-radius-base;
padding: 0.15em 0; padding: 0.15em 0;
} }
.md-toc { .md-toc {
font-size: 2.5em; font-size: 2.5em;
padding: 0.2em; padding: 0.2em;
} }
/* /*
.pre { .pre {
line-height: 1.8; line-height: 1.8;
@ -1329,7 +1329,7 @@ a {
color: @tertiary-color-lighter; color: @tertiary-color-lighter;
} }
} }
.h1, .h11 { font-size: 1.4em; } .h1, .h11 { font-size: 1.4em; }
.h2, .h22 { font-size: 1.3em; } .h2, .h22 { font-size: 1.3em; }
.h3 { font-size: 1.2em; } .h3 { font-size: 1.2em; }
@ -1486,7 +1486,7 @@ div.dropdown-menu, {
margin: 1em 0; margin: 1em 0;
} }
} }
.btn-gittip { .btn-gittip {
width: 52px; width: 52px;
height: 25px; height: 25px;
@ -1612,7 +1612,7 @@ div.jGrowl {
/******************* /*******************
* Viewer * Viewer
*******************/ *******************/
.viewer { .viewer {
.document-panel .search-bar { .document-panel .search-bar {
padding: 20px 20px 10px; padding: 20px 20px 10px;
@ -1620,11 +1620,11 @@ div.jGrowl {
display: none; display: none;
} }
} }
.ui-layout-toggler { .ui-layout-toggler {
display: none !important; display: none !important;
} }
.navbar .file-title-navbar { .navbar .file-title-navbar {
cursor: initial; cursor: initial;
.box-shadow(none); .box-shadow(none);