Configurable cursor focus

This commit is contained in:
benweet 2014-04-27 13:43:57 +01:00
parent bf778a9945
commit 0a1057d860
11 changed files with 806 additions and 771 deletions

View File

@ -117,6 +117,8 @@ Markdown Extra
> **Tip:** You can disable any **Markdown Extra** feature in the `Extensions` tab of the <i class="icon-cog"></i> `Settings` dialog. > **Tip:** You can disable any **Markdown Extra** feature in the `Extensions` tab of the <i class="icon-cog"></i> `Settings` dialog.
> **Note:** You can find more information about **Markdown** syntax [here][2] and **Markdown Extra** extension [here][3].
### Tables ### Tables
@ -166,6 +168,11 @@ var bar = 0;
> **Tip:** To use **Highlight.js** instead of **Prettify**, just configure the `Markdown Extra` extension in the <i class="icon-cog"></i> `Settings` dialog. > **Tip:** To use **Highlight.js** instead of **Prettify**, just configure the `Markdown Extra` extension in the <i class="icon-cog"></i> `Settings` dialog.
> **Note:** You can find more information:
> - about **Prettify** syntax highlighting [here][5],
> - about **Highlight.js** syntax highlighting [here][6].
### Footnotes ### Footnotes
@ -202,19 +209,42 @@ $$
\Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.
$$ $$
> **Tip:** Make sure you include **MathJax** into your publications to render mathematical expression correctly. Your page/template should include something like: > **Tip:** Make sure you include **MathJax** into your publications to render mathematical expression properly. Your page/template should include something like this:
``` ```
<script type="text/javascript" src="https://stackedit.io/libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script> <script type="text/javascript" src="https://stackedit.io/libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>
``` ```
> **NOTE:** You can find more information: > **Note:** You can find more information about **LaTeX** mathematical expressions [here][4].
> - about **Markdown** syntax [here][2],
> - about **Markdown Extra** extension [here][3], ### UML diagrams
> - about **LaTeX** mathematical expressions [here][4],
> - about **Prettify** syntax highlighting [here][5], You can also render sequence diagrams like this:
> - about **Highlight.js** syntax highlighting [here][6].
```sequence
Alice->Bob: Hello Bob, how are you?
Note right of Bob: Bob thinks
Bob-->Alice: I am good thanks!
```
And flow charts like this:
```flow
st=>start: Start
e=>end
op=>operation: My Operation
cond=>condition: Yes or No?
st->op->cond
cond(yes)->e
cond(no)->op
```
> **Note:** You can find more information:
> - about **Sequence diagrams** syntax [here][7],
> - about **Flow charts** syntax [here][8].
[^stackedit]: [StackEdit](https://stackedit.io/) is a full-featured, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites. [^stackedit]: [StackEdit](https://stackedit.io/) is a full-featured, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.
@ -227,3 +257,5 @@ $$
[4]: http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference [4]: http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference
[5]: https://code.google.com/p/google-code-prettify/ [5]: https://code.google.com/p/google-code-prettify/
[6]: http://highlightjs.org/ [6]: http://highlightjs.org/
[7]: http://bramp.github.io/js-sequence-diagrams/
[8]: http://adrai.github.io/flowchart.js/

View File

@ -119,6 +119,8 @@ define([
utils.setInputValue("#input-settings-font-size", settings.fontSizeRatio); utils.setInputValue("#input-settings-font-size", settings.fontSizeRatio);
// Max width ratio // Max width ratio
utils.setInputValue("#input-settings-max-width", settings.maxWidthRatio); utils.setInputValue("#input-settings-max-width", settings.maxWidthRatio);
// Cursor locking ratio
utils.setInputValue("#input-settings-cursor-focus", settings.cursorFocusRatio);
// Default content // Default content
utils.setInputValue("#textarea-settings-default-content", settings.defaultContent); utils.setInputValue("#textarea-settings-default-content", settings.defaultContent);
// Edit mode // Edit mode
@ -164,6 +166,8 @@ define([
newSettings.fontSizeRatio = utils.getInputFloatValue("#input-settings-font-size", event, 0.1, 10); newSettings.fontSizeRatio = utils.getInputFloatValue("#input-settings-font-size", event, 0.1, 10);
// Max width ratio // Max width ratio
newSettings.maxWidthRatio = utils.getInputFloatValue("#input-settings-max-width", event, 0.1, 10); newSettings.maxWidthRatio = utils.getInputFloatValue("#input-settings-max-width", event, 0.1, 10);
// Cursor locking ratio
newSettings.cursorFocusRatio = utils.getInputFloatValue("#input-settings-cursor-focus", event, 0, 1);
// Default content // Default content
newSettings.defaultContent = utils.getInputValue("#textarea-settings-default-content"); newSettings.defaultContent = utils.getInputValue("#textarea-settings-default-content");
// Edit mode // Edit mode

View File

@ -149,11 +149,8 @@ define([
this.cursorY = coordinates.y; this.cursorY = coordinates.y;
eventMgr.onCursorCoordinates(coordinates.x, coordinates.y); eventMgr.onCursorCoordinates(coordinates.x, coordinates.y);
} }
if(this.adjustScroll) { if(this.adjustScroll && settings.cursorFocusRatio) {
var adjust = inputElt.offsetHeight / 2; var adjust = inputElt.offsetHeight / 2 * settings.cursorFocusRatio;
if(adjust > 130) {
adjust = 130;
}
var cursorMinY = inputElt.scrollTop + adjust; var cursorMinY = inputElt.scrollTop + adjust;
var cursorMaxY = inputElt.scrollTop + inputElt.offsetHeight - adjust; var cursorMaxY = inputElt.scrollTop + inputElt.offsetHeight - adjust;
if(selectionMgr.cursorY < cursorMinY) { if(selectionMgr.cursorY < cursorMinY) {

View File

@ -137,53 +137,6 @@ define([
_.delay(doFlowChart, 0, cb); _.delay(doFlowChart, 0, cb);
} }
function doHighlight(cb) {
if(highlightEltList.length === 0) {
return cb();
}
var highlightElt = highlightEltList.pop();
hljs.highlightBlock(highlightElt);
highlightElt.highlighted = true;
_.delay(doHighlight, 0, cb);
}
function doPrettify(cb) {
if(prettifyEltList.length === 0) {
return cb();
}
var prettifyElt = prettifyEltList.pop();
var html = prettify.prettyPrintOne(prettifyElt.innerHTML);
prettifyElt.innerHTML = html;
prettifyElt.highlighted = true;
_.delay(doPrettify, 0, cb);
}
if(markdownExtra.config.highlighter == "highlight") {
extraOptions.highlighter = "prettify";
var afterHighlight = onAsyncPreview;
onAsyncPreview = function(cb) {
highlightEltList = _.filter(previewContentsElt.querySelectorAll('.prettyprint > code'), function(elt) {
return !elt.highlighted;
});
_.delay(doHighlight, 0, function() {
afterHighlight(cb);
});
};
}
if(markdownExtra.config.highlighter == "prettify") {
extraOptions.highlighter = "prettify";
var afterPrettify = onAsyncPreview;
onAsyncPreview = function(cb) {
prettifyEltList = _.filter(previewContentsElt.querySelectorAll('.prettyprint > code'), function(elt) {
return !elt.highlighted;
});
_.delay(doPrettify, 0, function() {
afterPrettify(cb);
});
};
}
if(markdownExtra.config.diagrams) { if(markdownExtra.config.diagrams) {
extraOptions.highlighter = "prettify"; extraOptions.highlighter = "prettify";
var afterDiagrams = onAsyncPreview; var afterDiagrams = onAsyncPreview;
@ -219,6 +172,20 @@ define([
}); });
}); });
} }
if(markdownExtra.config.highlighter == "highlight") {
extraOptions.highlighter = "prettify";
var previewContentsElt = document.getElementById('preview-contents');
editor.hooks.chain("onPreviewRefresh", function() {
_.each(previewContentsElt.querySelectorAll('.prettyprint > code'), function(elt) {
!elt.highlighted && hljs.highlightBlock(elt);
elt.highlighted = true;
});
});
}
else if(markdownExtra.config.highlighter == "prettify") {
extraOptions.highlighter = "prettify";
editor.hooks.chain("onPreviewRefresh", prettify.prettyPrint);
}
Markdown.Extra.init(converter, extraOptions); Markdown.Extra.init(converter, extraOptions);
}; };

View File

@ -68,6 +68,7 @@ define([
' <li>New contenteditable based editor (credit to Dabblet, Editorially...)</li>', ' <li>New contenteditable based editor (credit to Dabblet, Editorially...)</li>',
' <li>New layout with CSS3 transitions (lighter supposedly)</li>', ' <li>New layout with CSS3 transitions (lighter supposedly)</li>',
' <li>Comments/discussions support (see the new icon in the navigation bar)</li>', ' <li>Comments/discussions support (see the new icon in the navigation bar)</li>',
' <li>UML diagrams support</li>',
' <li>Auto-merge and conflict detection using standard synchronization</li>', ' <li>Auto-merge and conflict detection using standard synchronization</li>',
' <li>Dropped real time sync support :( since you can collaborate simultaneously using standard synchronization</li>', ' <li>Dropped real time sync support :( since you can collaborate simultaneously using standard synchronization</li>',
'</ul>', '</ul>',

View File

@ -110,13 +110,13 @@
<li><a href="#" class="submenu-sync-gdrive action-sync-export-dialog-gdrive"><i <li><a href="#" class="submenu-sync-gdrive action-sync-export-dialog-gdrive"><i
class="icon-provider-gdrive"></i> Save on Google Drive</a></li> class="icon-provider-gdrive"></i> Save on Google Drive</a></li>
<li><a href="#" class="submenu-sync-gdrivesec action-sync-import-gdrivesec"><i <li><a href="#" class="submenu-sync-gdrivesec action-sync-import-gdrivesec"><i
class="icon-provider-gdrive"></i> Open from Google Drive <small>(2nd account)</small></a></li> class="icon-provider-gdrive"></i> Open from Google Drive<br><small>(2nd account)</small></a></li>
<li><a href="#" class="submenu-sync-gdrivesec action-sync-export-dialog-gdrivesec"><i <li><a href="#" class="submenu-sync-gdrivesec action-sync-export-dialog-gdrivesec"><i
class="icon-provider-gdrive"></i> Save on Google Drive <small>(2nd account)</small></a></li> class="icon-provider-gdrive"></i> Save on Google Drive<br><small>(2nd account)</small></a></li>
<li><a href="#" class="submenu-sync-gdriveter action-sync-import-gdriveter"><i <li><a href="#" class="submenu-sync-gdriveter action-sync-import-gdriveter"><i
class="icon-provider-gdrive"></i> Open from Google Drive <small>(3rd account)</small></a></li> class="icon-provider-gdrive"></i> Open from Google Drive<br><small>(3rd account)</small></a></li>
<li><a href="#" class="submenu-sync-gdriveter action-sync-export-dialog-gdriveter"><i <li><a href="#" class="submenu-sync-gdriveter action-sync-export-dialog-gdriveter"><i
class="icon-provider-gdrive"></i> Save on Google Drive <small>(3rd account)</small></a></li> class="icon-provider-gdrive"></i> Save on Google Drive<br><small>(3rd account)</small></a></li>
</ul> </ul>
</div> </div>
<a href="#" data-toggle="collapse" data-target=".collapse-publish-on" <a href="#" data-toggle="collapse" data-target=".collapse-publish-on"
@ -870,6 +870,8 @@
"<span class="file-title"></span>" can be shared using the following link(s): "<span class="file-title"></span>" can be shared using the following link(s):
</p> </p>
<div class="msg-share-list share-list hide"></div> <div class="msg-share-list share-list hide"></div>
<p class="msg-no-share hide"><b>No sharing link yet!</b>
</p>
<p class="msg-no-share hide">To collaborate on this document, use <i class="icon-provider-gdrive"></i> <b>Google Drive</b> <p class="msg-no-share hide">To collaborate on this document, use <i class="icon-provider-gdrive"></i> <b>Google Drive</b>
or <i class="icon-provider-dropbox"></i> <b>Dropbox</b> synchronization from the <i class="icon-provider-stackedit"></i> menu. or <i class="icon-provider-dropbox"></i> <b>Dropbox</b> synchronization from the <i class="icon-provider-stackedit"></i> menu.
</p> </p>
@ -1028,6 +1030,14 @@
class="form-control col-sm-2"> class="form-control col-sm-2">
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-sm-4 control-label"
for="input-settings-cursor-focus">Cursor focus ratio</label>
<div class="col-sm-8 form-inline">
<input type="text" id="input-settings-cursor-focus"
class="form-control col-sm-2">
</div>
</div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label" <label class="col-sm-4 control-label"
for="input-settings-lazy-rendering">Lazy rendering <a for="input-settings-lazy-rendering">Lazy rendering <a

View File

@ -33,10 +33,10 @@
<dl> <dl>
<dt>Developers:</dt> <dt>Developers:</dt>
<dd> <dd>
<a target="_blank" href="http://www.benoitschweblin.com">Benoit <a target="_blank" href="https://twitter.com/benweet">Benoit Schweblin</a><br />
Schweblin</a><br />
Pete Eigel (contributor)<br /> Pete Eigel (contributor)<br />
wiibaa (contributor) wiibaa (contributor)<br />
<a target="_blank" href="http://www.hugwebdesign.com/">Daniel Hug (contributor)</a><br />
</dd> </dd>
</dl> </dl>
<dl> <dl>

View File

@ -7,7 +7,7 @@ define([
'eventMgr', 'eventMgr',
'crel', 'crel',
'mousetrap', 'mousetrap',
'hammerjs', 'hammerjs'
], function($, _, utils, constants, settings, eventMgr, crel, mousetrap, hammer) { ], function($, _, utils, constants, settings, eventMgr, crel, mousetrap, hammer) {
var layout = {}; var layout = {};
@ -36,10 +36,12 @@ define([
var navbar, menuPanel, documentPanel, editor, previewPanel, previewContainer, navbarToggler, previewToggler, previewResizer, previewButtons; var navbar, menuPanel, documentPanel, editor, previewPanel, previewContainer, navbarToggler, previewToggler, previewResizer, previewButtons;
var animate = false; var animate = false;
function startAnimation() { function startAnimation() {
animate = true; animate = true;
wrapperL1.$elt.addClass('layout-animate'); wrapperL1.$elt.addClass('layout-animate');
} }
function endAnimation() { function endAnimation() {
animate = false; animate = false;
wrapperL1.$elt.removeClass('layout-animate'); wrapperL1.$elt.removeClass('layout-animate');
@ -53,6 +55,7 @@ define([
var transitionEndTimeoutId; var transitionEndTimeoutId;
var transitionEndCallbacks = []; var transitionEndCallbacks = [];
function onTransitionEnd(evt) { function onTransitionEnd(evt) {
if(!evt || if(!evt ||
evt.target === wrapperL1.elt || evt.target === wrapperL1.elt ||
@ -67,6 +70,7 @@ define([
transitionEndCallbacks = []; transitionEndCallbacks = [];
} }
} }
DomObject.prototype.applyCss = function() { DomObject.prototype.applyCss = function() {
// Top/left/Bottom/Right // Top/left/Bottom/Right
@ -166,9 +170,10 @@ define([
{ screenWidth: 0, maxWidth: 600 * settings.maxWidthRatio }, { screenWidth: 0, maxWidth: 600 * settings.maxWidthRatio },
{ screenWidth: 1000, maxWidth: 700 * settings.maxWidthRatio }, { screenWidth: 1000, maxWidth: 700 * settings.maxWidthRatio },
{ screenWidth: 1200, maxWidth: 800 * settings.maxWidthRatio }, { screenWidth: 1200, maxWidth: 800 * settings.maxWidthRatio },
{ screenWidth: 1400, maxWidth: 900 * settings.maxWidthRatio }, { screenWidth: 1400, maxWidth: 900 * settings.maxWidthRatio }
]; ];
var maxWidthMapReversed = maxWidthMap.slice(0).reverse(); var maxWidthMapReversed = maxWidthMap.slice(0).reverse();
function getMaxWidth() { function getMaxWidth() {
return _.find(maxWidthMapReversed, function(value) { return _.find(maxWidthMapReversed, function(value) {
return windowSize.width > value.screenWidth; return windowSize.width > value.screenWidth;
@ -184,12 +189,20 @@ define([
var navbarTitleContainerElt; var navbarTitleContainerElt;
var $navbarTitleElt; var $navbarTitleElt;
var navbarBtnGroups = []; var navbarBtnGroups = [];
var navbarBtnGroupsWidth = [80, 80, 160, 160, 80, 40].map(function(width) { var navbarBtnGroupsWidth = [
80,
80,
160,
160,
80,
40
].map(function(width) {
return width + 18; // Add margin return width + 18; // Add margin
}); });
var navbarMarginWidth = 18 * 2 + 25 + 25; var navbarMarginWidth = 18 * 2 + 25 + 25;
var buttonsDropdownWidth = 40; var buttonsDropdownWidth = 40;
var workingIndicatorWidth = 18 + 70; var workingIndicatorWidth = 18 + 70;
function onResize() { function onResize() {
var paddingBottom = wrapperL3.height - 60; var paddingBottom = wrapperL3.height - 60;
@ -232,6 +245,7 @@ define([
} }
var isVertical = settings.layoutOrientation == "vertical"; var isVertical = settings.layoutOrientation == "vertical";
function resizeAll() { function resizeAll() {
windowSize = { windowSize = {
width: window.innerWidth, width: window.innerWidth,
@ -533,7 +547,7 @@ define([
evt.gesture.preventDefault(); evt.gesture.preventDefault();
}).on('dragend', function() { }).on('dragend', function() {
wrapperL2.$elt.removeClass('dragging'); wrapperL2.$elt.removeClass('dragging');
previewButtons.$elt.find('.btn-group').toggleClass('dropup', windowSize.height/2 > -previewButtons.y); previewButtons.$elt.find('.btn-group').toggleClass('dropup', windowSize.height / 2 > -previewButtons.y);
}); });
var isModalShown = false; var isModalShown = false;
@ -551,7 +565,11 @@ define([
return menuPanel.isOpen || documentPanel.isOpen || isModalShown; return menuPanel.isOpen || documentPanel.isOpen || isModalShown;
}; };
$(window).resize(resizeAll); $(window).resize(resizeAll).focus(function() {
if(!menuPanel.isOpen && !documentPanel.isOpen && !isModalShown) {
editor.elt.focus();
}
});
var styleContent = ''; var styleContent = '';
@ -566,16 +584,17 @@ define([
'#preview-contents {', '#preview-contents {',
' font-size: ' + size + 'px;', ' font-size: ' + size + 'px;',
'}', '}',
'}', '}'
].join('\n'); ].join('\n');
} }
applyFont(16 * settings.fontSizeRatio); applyFont(16 * settings.fontSizeRatio);
applyFont(17 * settings.fontSizeRatio, 600); applyFont(17 * settings.fontSizeRatio, 600);
applyFont(18 * settings.fontSizeRatio, 1200); applyFont(18 * settings.fontSizeRatio, 1200);
// Apply dynamic stylesheet // Apply dynamic stylesheet
var style = crel('style', { var style = crel('style', {
type : 'text/css' type: 'text/css'
}); });
style.innerHTML = styleContent; style.innerHTML = styleContent;
document.head.appendChild(style); document.head.appendChild(style);
@ -595,8 +614,10 @@ define([
previewButtons.applyCss(); previewButtons.applyCss();
} }
} }
var closeTimeoutId; var closeTimeoutId;
var dropdownOpen = false; var dropdownOpen = false;
function closePreviewButtons() { function closePreviewButtons() {
clearTimeout(closeTimeoutId); clearTimeout(closeTimeoutId);
closeTimeoutId = setTimeout(function() { closeTimeoutId = setTimeout(function() {
@ -625,7 +646,7 @@ define([
}); });
var maxHeight = -previewButtons.y - previewButtonsDropdownMargin; var maxHeight = -previewButtons.y - previewButtonsDropdownMargin;
// If it's a dropup // If it's a dropup
if(windowSize.height/2 > -previewButtons.y) { if(windowSize.height / 2 > -previewButtons.y) {
maxHeight = windowSize.height + previewButtons.y - previewButtons.elt.offsetHeight - previewButtonsDropdownMargin; maxHeight = windowSize.height + previewButtons.y - previewButtons.elt.offsetHeight - previewButtonsDropdownMargin;
} }
$btnGroupElt.find('.markdown-syntax, .table-of-contents').css({ $btnGroupElt.find('.markdown-syntax, .table-of-contents').css({

View File

@ -1,8 +1,8 @@
define([ define([
"underscore", "underscore",
"constants", "constants",
"storage", "storage"
], function (_, constants, storage) { ], function(_, constants, storage) {
var settings = { var settings = {
layoutOrientation: "horizontal", layoutOrientation: "horizontal",
@ -11,6 +11,7 @@ define([
editorFontClass: 'font-rich', editorFontClass: 'font-rich',
fontSizeRatio: 1, fontSizeRatio: 1,
maxWidthRatio: 1, maxWidthRatio: 1,
cursorFocusRatio: 0.5,
defaultContent: "\n\n\n> Written with [StackEdit](" + constants.MAIN_URL + ").", defaultContent: "\n\n\n> Written with [StackEdit](" + constants.MAIN_URL + ").",
commitMsg: "Published with " + constants.MAIN_URL, commitMsg: "Published with " + constants.MAIN_URL,
conflictMode: 'merge', conflictMode: 'merge',
@ -62,7 +63,7 @@ define([
try { try {
_.extend(settings, JSON.parse(storage.settings)); _.extend(settings, JSON.parse(storage.settings));
} }
catch (e) { catch(e) {
// Ignore parsing error // Ignore parsing error
} }

View File

@ -3,6 +3,7 @@
@import (less) "../libs/highlight/styles/default.css"; @import (less) "../libs/highlight/styles/default.css";
@import (less) "../libs/fontello/css/fontello.css"; @import (less) "../libs/fontello/css/fontello.css";
@body-bg: #fff;
@text-color: #000; @text-color: #000;
@kbd-color: #333; @kbd-color: #333;
@kbd-bg-color: #FFF; @kbd-bg-color: #FFF;
@ -138,7 +139,7 @@ hr {
font-family: @font-family-sans-serif !important; font-family: @font-family-sans-serif !important;
} }
[fill="#ffffff"] { [fill="#ffffff"] {
fill: none; fill: @body-bg;
} }
[stroke="#000000"] { [stroke="#000000"] {
stroke: @text-color; stroke: @text-color;
@ -239,7 +240,7 @@ kbd {
border: 1px solid @kbd-border-color; border: 1px solid @kbd-border-color;
.box-shadow(0 1px 0px @kbd-border-color); .box-shadow(0 1px 0px @kbd-border-color);
font-size: 0.7em; font-size: 0.7em;
font-family: Arial, Helvetica, sans-serif; font-family: sans-serif;
background-color: @kbd-bg-color; background-color: @kbd-bg-color;
color: @kbd-color; color: @kbd-color;
border-radius: 3px; border-radius: 3px;

View File

@ -1092,6 +1092,7 @@ a {
overflow: auto; overflow: auto;
white-space: pre-wrap; white-space: pre-wrap;
word-wrap: break-word; word-wrap: break-word;
word-break: normal;
> .editor-content { > .editor-content {
padding-bottom: 230px; padding-bottom: 230px;
} }