summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
authorCheng-Han, Wu2016-05-26 13:17:00 +0800
committerCheng-Han, Wu2016-05-26 13:17:00 +0800
commitb28750f256d6fbab1406c6c00155ea14eef5c600 (patch)
treed852b4bcf516e532c948566393f4ce0f84c57b9b /public
parentbf1dc237a993f53bbc4d90fd1c81e325d4517fcd (diff)
Update to improve syncscroll performance and add toggle for sync scrolling
Diffstat (limited to 'public')
-rw-r--r--public/css/index.css11
-rw-r--r--public/js/index.js63
-rw-r--r--public/js/syncscroll.js186
3 files changed, 128 insertions, 132 deletions
diff --git a/public/css/index.css b/public/css/index.css
index aaf84a04..1b9fb5d4 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -112,6 +112,17 @@ body {
background-color: white;
box-shadow: 5px 0px 10px #e7e7e7;
}
+.ui-edit-area .ui-sync-toggle {
+ width: 42px;
+ height: 42px;
+ padding: 3px 1px 0 0;
+ border-radius: 50%;
+ border-color: #e7e7e7;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
.ui-view-area {
/*overflow-y: scroll;*/
-webkit-overflow-scrolling: touch;
diff --git a/public/js/index.js b/public/js/index.js
index b4f912bb..29e22979 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -552,7 +552,11 @@ var ui = {
codemirrorScroll: $(".ui-edit-area .CodeMirror .CodeMirror-scroll"),
codemirrorSizer: $(".ui-edit-area .CodeMirror .CodeMirror-sizer"),
codemirrorSizerInner: $(".ui-edit-area .CodeMirror .CodeMirror-sizer > div"),
- markdown: $(".ui-view-area .markdown-body")
+ markdown: $(".ui-view-area .markdown-body"),
+ resize: {
+ handle: $('.ui-resizable-handle'),
+ syncToggle: $('.ui-sync-toggle')
+ }
},
modal: {
snippetImportProjects: $("#snippetImportModalProjects"),
@@ -705,30 +709,6 @@ $(window).error(function () {
//setNeedRefresh();
});
-//when page hash change
-window.onhashchange = locationHashChanged;
-
-function locationHashChanged(e) {
- e.stopPropagation();
- e.preventDefault();
- if (currentMode != modeType.both) {
- return;
- }
- var hashtarget = $("[id$='" + location.hash.substr(1) + "']");
- if (hashtarget.length > 0) {
- var linenumber = hashtarget.attr('data-startline');
- if (linenumber) {
- editor.setOption('viewportMargin', Infinity);
- editor.setOption('viewportMargin', viewportMargin);
- var t = editor.charCoords({
- line: linenumber,
- ch: 0
- }, "local").top;
- editor.scrollTo(null, t - defaultTextHeight * 1.2);
- }
- }
-}
-
var windowResizeDebounce = 200;
var windowResize = _.debounce(windowResizeInner, windowResizeDebounce);
@@ -814,10 +794,38 @@ function checkEditorStyle() {
handles: 'e',
maxWidth: $(window).width() * 0.7,
minWidth: $(window).width() * 0.2,
+ resize: function (e) {
+ ui.area.resize.syncToggle.stop(true, true).show();
+ },
stop: function (e) {
lastEditorWidth = ui.area.edit.width();
}
});
+ if (!ui.area.resize.handle.length) {
+ ui.area.resize.handle = $('.ui-resizable-handle');
+ }
+ if (!ui.area.resize.syncToggle.length) {
+ ui.area.resize.syncToggle = $('<button class="btn btn-lg btn-default ui-sync-toggle" title="Toggle sync scrolling"><i class="fa fa-link fa-fw"></i></button>');
+ ui.area.resize.syncToggle.click(function () {
+ syncscroll = !syncscroll;
+ checkSyncToggle();
+ });
+ ui.area.resize.handle.append(ui.area.resize.syncToggle);
+ ui.area.resize.syncToggle.hide();
+ ui.area.resize.handle.hover(function () {
+ ui.area.resize.syncToggle.stop(true, true).delay(200).fadeIn(100);
+ }, function () {
+ ui.area.resize.syncToggle.stop(true, true).delay(300).fadeOut(300);
+ });
+ }
+}
+
+function checkSyncToggle() {
+ if (syncscroll) {
+ ui.area.resize.syncToggle.find('i').removeClass('fa-unlink').addClass('fa-link');
+ } else {
+ ui.area.resize.syncToggle.find('i').removeClass('fa-link').addClass('fa-unlink');
+ }
}
function checkEditorScrollbar() {
@@ -984,10 +992,10 @@ function changeMode(type) {
ui.area.edit.css('width', lastEditorWidth + 'px');
else
ui.area.edit.css('width', '');
- ui.area.edit.find('.ui-resizable-handle').show();
+ ui.area.resize.handle.show();
} else {
ui.area.edit.css('width', '');
- ui.area.edit.find('.ui-resizable-handle').hide();
+ ui.area.resize.handle.hide();
}
windowResizeInner();
@@ -995,6 +1003,7 @@ function changeMode(type) {
restoreInfo();
if (lastMode == modeType.view && currentMode == modeType.both) {
+ preventSyncScrollToView = true;
syncScrollToEdit();
}
diff --git a/public/js/syncscroll.js b/public/js/syncscroll.js
index b52e2bfa..348af2d1 100644
--- a/public/js/syncscroll.js
+++ b/public/js/syncscroll.js
@@ -105,10 +105,13 @@ md.use(window.markdownitContainer, 'info', { render: renderContainer });
md.use(window.markdownitContainer, 'warning', { render: renderContainer });
md.use(window.markdownitContainer, 'danger', { render: renderContainer });
-var preventSyncScroll = false;
+var syncscroll = true;
+
+var preventSyncScrollToEdit = false;
+var preventSyncScrollToView = false;
var editScrollThrottle = 1;
-var viewScrollThrottle = 20;
+var viewScrollThrottle = 10;
var buildMapThrottle = 100;
var viewScrolling = false;
@@ -126,71 +129,6 @@ if (editor.getOption('scrollbarStyle') === 'native') {
}
ui.area.view.on('scroll', _.throttle(syncScrollToEdit, viewScrollThrottle));
-var preventViewScroll = false;
-
-function syncScrollToEdit(e) {
- if (currentMode != modeType.both) return;
- if (preventViewScroll) {
- if (typeof preventViewScroll === 'number') {
- preventViewScroll--;
- } else {
- preventViewScroll = false;
- }
- return;
- }
- if (!scrollMap || !lineHeightMap) {
- buildMap(true);
- return;
- }
- if (editScrolling) return;
- var scrollTop = ui.area.view[0].scrollTop;
- var lineIndex = 0;
- for (var i = 0, l = scrollMap.length; i < l; i++) {
- if (scrollMap[i] > scrollTop) {
- break;
- } else {
- lineIndex = i;
- }
- }
- var lineNo = 0;
- var lineDiff = 0;
- for (var i = 0, l = lineHeightMap.length; i < l; i++) {
- if (lineHeightMap[i] > lineIndex) {
- break;
- } else {
- lineNo = lineHeightMap[i];
- lineDiff = lineHeightMap[i + 1] - lineNo;
- }
- }
-
- var scrollInfo = editor.getScrollInfo();
- var textHeight = editor.defaultTextHeight();
- var posTo = 0;
- var topDiffPercent = 0;
- var posToNextDiff = 0;
- var preLastLineHeight = scrollInfo.height - scrollInfo.clientHeight - textHeight;
- var preLastLineNo = Math.round(preLastLineHeight / textHeight);
-
- if (scrollInfo.height > scrollInfo.clientHeight && lineNo >= preLastLineNo) {
- posTo = preLastLineHeight;
- topDiffPercent = (scrollTop - scrollMap[preLastLineNo]) / (viewBottom - scrollMap[preLastLineNo]);
- posToNextDiff = Math.ceil(textHeight * topDiffPercent);
- } else {
- posTo = lineNo * textHeight;
- topDiffPercent = (scrollTop - scrollMap[lineNo]) / (scrollMap[lineNo + lineDiff] - scrollMap[lineNo]);
- posToNextDiff = Math.ceil(textHeight * lineDiff * topDiffPercent);
- }
-
- editor.scrollTo(0, posTo + posToNextDiff);
- preventSyncScroll = true;
-
- viewScrolling = true;
- clearTimeout(viewScrollingTimer);
- viewScrollingTimer = setTimeout(function () {
- viewScrolling = false;
- }, viewScrollingDelay);
-}
-
var scrollMap, lineHeightMap, viewTop, viewBottom;
viewAjaxCallback = clearMap;
@@ -279,60 +217,98 @@ function buildMapInner(syncBack) {
scrollMap = _scrollMap;
lineHeightMap = _lineHeightMap;
- if (loaded && syncBack)
+ if (loaded && syncBack) {
syncScrollToView();
+ syncScrollToEdit();
+ }
}
-function getPartByEditorLineNo(lineNo) {
- var part = null;
- ui.area.markdown.find('.part').each(function (n, el) {
- if (part) return;
- var $el = $(el),
- t = $el.data('startline') - 1,
- f = $el.data('endline') - 1;
- if (t === '' || f === '') {
- return;
+
+function syncScrollToEdit(e) {
+ if (currentMode != modeType.both || !syncscroll) return;
+ if (preventSyncScrollToEdit) {
+ if (typeof preventSyncScrollToEdit === 'number') {
+ preventSyncScrollToEdit--;
+ } else {
+ preventSyncScrollToEdit = false;
}
- if (lineNo >= t && lineNo <= f) {
- part = $el;
+ return;
+ }
+ if (!scrollMap || !lineHeightMap) {
+ buildMap(true);
+ return;
+ }
+ if (editScrolling) return;
+
+ var scrollTop = ui.area.view[0].scrollTop;
+ var lineIndex = 0;
+ for (var i = 0, l = scrollMap.length; i < l; i++) {
+ if (scrollMap[i] > scrollTop) {
+ break;
+ } else {
+ lineIndex = i;
}
- });
- if (part)
- return {
- startline: part.data('startline') - 1,
- endline: part.data('endline') - 1,
- linediff: Math.abs(part.data('endline') - part.data('startline')) + 1,
- element: part
- };
- else
- return null;
-}
-
-function getEditorLineNoByTop(top) {
- for (var i = 0; i < lineHeightMap.length; i++)
- if (lineHeightMap[i] * editor.defaultTextHeight() > top)
- return i;
- return null;
+ }
+ var lineNo = 0;
+ var lineDiff = 0;
+ for (var i = 0, l = lineHeightMap.length; i < l; i++) {
+ if (lineHeightMap[i] > lineIndex) {
+ break;
+ } else {
+ lineNo = lineHeightMap[i];
+ lineDiff = lineHeightMap[i + 1] - lineNo;
+ }
+ }
+
+ var posTo = 0;
+ var topDiffPercent = 0;
+ var posToNextDiff = 0;
+ var scrollInfo = editor.getScrollInfo();
+ var textHeight = editor.defaultTextHeight();
+ var preLastLineHeight = scrollInfo.height - scrollInfo.clientHeight - textHeight;
+ var preLastLineNo = Math.round(preLastLineHeight / textHeight);
+ var preLastLinePos = scrollMap[preLastLineNo];
+
+ if (scrollInfo.height > scrollInfo.clientHeight && scrollTop >= preLastLinePos) {
+ posTo = preLastLineHeight;
+ topDiffPercent = (scrollTop - preLastLinePos) / (viewBottom - preLastLinePos);
+ posToNextDiff = Math.ceil(textHeight * topDiffPercent);
+ } else {
+ posTo = lineNo * textHeight;
+ topDiffPercent = (scrollTop - scrollMap[lineNo]) / (scrollMap[lineNo + lineDiff] - scrollMap[lineNo]);
+ posToNextDiff = Math.ceil(textHeight * lineDiff * topDiffPercent);
+ }
+
+ editor.scrollTo(0, posTo + posToNextDiff);
+ preventSyncScrollToView = true;
+
+ viewScrolling = true;
+ clearTimeout(viewScrollingTimer);
+ viewScrollingTimer = setTimeout(function () {
+ viewScrolling = false;
+ }, viewScrollingDelay);
}
function syncScrollToView(event, _lineNo) {
- if (currentMode != modeType.both) return;
- if (preventSyncScroll) {
- if (typeof preventSyncScroll === 'number') {
- preventSyncScroll--;
+ if (currentMode != modeType.both || !syncscroll) return;
+ if (preventSyncScrollToView) {
+ if (typeof preventSyncScrollToView === 'number') {
+ preventSyncScrollToView--;
} else {
- preventSyncScroll = false;
+ preventSyncScrollToView = false;
}
return;
}
- var lineNo, posTo;
- var scrollInfo = editor.getScrollInfo();
if (!scrollMap || !lineHeightMap) {
buildMap(true);
return;
}
+ if (viewScrolling) return;
+
if (!_lineNo) {
+ var lineNo, posTo;
var topDiffPercent, posToNextDiff;
+ var scrollInfo = editor.getScrollInfo();
var textHeight = editor.defaultTextHeight();
lineNo = Math.floor(scrollInfo.top / textHeight);
// if reach the last line, will start lerp to the bottom
@@ -349,11 +325,11 @@ function syncScrollToView(event, _lineNo) {
posTo += Math.floor(posToNextDiff);
}
} else {
- if (viewScrolling) return;
posTo = scrollMap[lineHeightMap[_lineNo]];
}
+
ui.area.view.stop(true, true).scrollTop(posTo);
- preventViewScroll = true;
+ preventSyncScrollToEdit = true;
editScrolling = true;
clearTimeout(editScrollingTimer);