add linetracking to easymde

This commit is contained in:
ed 2020-05-01 19:56:52 +02:00
parent 04047f3a72
commit 706f30033e
5 changed files with 162 additions and 4 deletions

View file

@ -45,9 +45,12 @@ html, body {
text-decoration: underline; text-decoration: underline;
} }
/*
*[data-ln]:before { *[data-ln]:before {
content: attr(data-ln); content: attr(data-ln);
font-size: .8em; font-size: .8em;
margin: 0 .4em; margin: 0 .4em;
color: #f0c; color: #f0c;
} }
.cm-header { font-size: .4em !important }
*/

View file

@ -57,5 +57,5 @@
</table> </table>
<p id="u2foot"></p> <p id="u2foot"></p>
<p>( if you don't need resumable uploads and progress bars just use the <a href="#" id="u2nope" onclick="javascript:goto('bup');">basic uploader</a>)</p> <p>( if you don't need lastmod timestamps, resumable uploads or progress bars just use the <a href="#" id="u2nope" onclick="javascript:goto('bup');">basic uploader</a>)</p>
</div> </div>

View file

@ -106,10 +106,16 @@ RUN cd marked-$ver_marked \
# build easymde (TODO man this thing is big) # build easymde (TODO man this thing is big)
COPY easymde.patch /z/
RUN cd easy-markdown-editor-$ver_mde \ RUN cd easy-markdown-editor-$ver_mde \
&& patch -p1 < /z/easymde.patch \
&& sed -ri 's`https://registry.npmjs.org/marked/-/marked-0.8.2.tgz`file:/z/nodepkgs/marked`' package-lock.json \ && sed -ri 's`https://registry.npmjs.org/marked/-/marked-0.8.2.tgz`file:/z/nodepkgs/marked`' package-lock.json \
&& sed -ri 's`("marked": ")[^"]+`\1file:/z/nodepkgs/marked`' ./package.json \ && sed -ri 's`("marked": ")[^"]+`\1file:/z/nodepkgs/marked`' ./package.json \
&& npm install \ && npm install
COPY easymde-ln.patch /z/
RUN cd easy-markdown-editor-$ver_mde \
&& patch -p1 < /z/easymde-ln.patch \
&& gulp \ && gulp \
&& cp -pv dist/easymde.min.css /z/dist/easymde.css \ && cp -pv dist/easymde.min.css /z/dist/easymde.css \
&& cp -pv dist/easymde.min.js /z/dist/easymde.js \ && cp -pv dist/easymde.min.js /z/dist/easymde.js \
@ -202,7 +208,9 @@ RUN cd /z/dist \
# so really not worth it, just drop the patch when that stops working # so really not worth it, just drop the patch when that stops working
# f=../../copyparty/web/deps/marked.js.gz; (cd ~ed/src/ && diff -NarU1 marked-1.0.0-orig/ marked-1.0.0-edit/) >marked.patch; make && printf '%d ' $(wc -c <$f) $(gzip -d <$f | wc -c); echo # easymde:
# 91836 orig
# 88635 no spellcheck
# d=/home/ed/dev/copyparty/scripts/deps-docker/; tar -cf ../x . && ssh root@$bip "cd $d && tar -xv >&2 && make >&2 && tar -cC ../../copyparty/web deps" <../x | (cd ../../copyparty/web/; cat > the.tgz; tar -xvf the.tgz) # d=/home/ed/dev/copyparty/scripts/deps-docker/; tar -cf ../x . && ssh root@$bip "cd $d && tar -xv >&2 && make >&2 && tar -cC ../../copyparty/web deps" <../x | (cd ../../copyparty/web/; cat > the.tgz; tar -xvf the.tgz)

View file

@ -0,0 +1,95 @@
diff -NarU2 easymde-mod1/src/js/easymde.js easymde-edit/src/js/easymde.js
--- easymde-mod1/src/js/easymde.js 2020-05-01 14:34:19.878774400 +0200
+++ easymde-edit/src/js/easymde.js 2020-05-01 19:26:56.843140600 +0200
@@ -2189,4 +2189,5 @@
};
+
EasyMDE.prototype.createSideBySide = function () {
var cm = this.codemirror;
@@ -2223,12 +2224,80 @@
}
pScroll = true;
- var height = v.getScrollInfo().height - v.getScrollInfo().clientHeight;
- var ratio = parseFloat(v.getScrollInfo().top) / height;
- var move = (preview.scrollHeight - preview.clientHeight) * ratio;
- preview.scrollTop = move;
+ var md_vp = v.getScrollInfo();
+ // viewport top: top
+ // viewport size: clientHeight
+ // document size: height
+ var md_scroll_y = md_vp.top + md_vp.clientHeight / 2;
+ var md_center_n = cm.lineAtHeight(md_scroll_y, 'local') + 1;
+ var md_next_n = md_center_n;
+ var md_top = cm.heightAtLine(md_center_n - 1, 'local');
+ while (md_next_n < cm.lineCount())
+ if (cm.getLine(md_next_n++).replace(/\s+/g, '').length > 0)
+ break;
+ var md_end = cm.heightAtLine(md_next_n - 1, 'local');
+ var md_frac = (md_scroll_y - md_top) * 1.0 / (md_end - md_top);
+ var get_pre_line = function(line_n, increase) {
+ var end = 0;
+ var step = -1;
+ if (increase) {
+ step = 1;
+ end = line_n + 1000;
+ }
+ // there might be multiple elements in the marked.js output,
+ // take the element with the biggest height
+ var biggest = -1;
+ var line_dom = null;
+ for (; line_n != end; line_n += step) {
+ var hits = document.querySelectorAll('.editor-preview-side *[data-ln=\'' + line_n + '\']');
+ for (var i = 0; i < hits.length; i++) {
+ var hit_size = hits[i].offsetHeight;
+ if (biggest < hit_size) {
+ biggest = hit_size;
+ line_dom = hits[i];
+ }
+ }
+ if (line_dom) {
+ var ret_y = 0;
+ var el = line_dom;
+ while ((el.getAttribute('class') + '').indexOf('editor-preview-side') < 0) {
+ ret_y += el.offsetTop;
+ el = el.offsetParent;
+ }
+ return [line_n, line_dom, ret_y];
+ }
+ }
+ return null;
+ };
+ var pre1 = get_pre_line(md_center_n, false);
+ var pre2 = get_pre_line(pre1[0] + 1, true) ||
+ [cm.lineCount(), null, preview.scrollHeight];
+
+ console.log('code-center %d, frac %.2f, pre [%d,%d] [%d,%d]',
+ md_center_n, md_frac, pre1[0], pre1[2], pre2[0], pre2[2]);
+
+ // [0] is the markdown line which matches that preview y-pos
+ // and since not all preview lines are tagged with a line-number
+ // take the lineno diff and divide it by the distance
+ var pre_frac = md_frac / ((pre2[0] - pre1[0]) / (md_next_n - md_center_n));
+
+ // then use that fraction for the scroll offset
+ var pre_y = pre1[2] + (pre2[2] - pre1[2]) * pre_frac;
+
+ // unless we couldn't match the markdown line exactly to any preview line
+ if (md_center_n > pre1[0] && md_center_n < pre2[0])
+ pre_y = pre2[2];
+
+ // except jump to the top or bottom if we're close enough
+ if (md_vp.top < 32)
+ pre_y = 0;
+ else if (md_vp.top + 32 >= md_vp.height - md_vp.clientHeight)
+ pre_y = preview.scrollHeight;
+
+ preview.scrollTop = pre_y - preview.clientHeight / 2;
});
// Syncs scroll preview -> editor
- preview.onscroll = function () {
+ // disabled since it should be possible to intentionally unsync
+ preview.onscroll_fgsfds = function () {
if (pScroll) {
pScroll = false;

View file

@ -0,0 +1,52 @@
diff -NarU2 easymde-orig/gulpfile.js easymde-mod1/gulpfile.js
--- easymde-orig/gulpfile.js 2020-04-06 14:09:36.000000000 +0200
+++ easymde-mod1/gulpfile.js 2020-05-01 14:33:52.260175200 +0200
@@ -25,5 +25,4 @@
'./node_modules/codemirror/lib/codemirror.css',
'./src/css/*.css',
- './node_modules/codemirror-spell-checker/src/css/spell-checker.css',
];
diff -NarU2 easymde-orig/package.json easymde-mod1/package.json
--- easymde-orig/package.json 2020-04-06 14:09:36.000000000 +0200
+++ easymde-mod1/package.json 2020-05-01 14:33:57.189975800 +0200
@@ -21,5 +21,4 @@
"dependencies": {
"codemirror": "^5.52.2",
- "codemirror-spell-checker": "1.1.2",
"marked": "^0.8.2"
},
diff -NarU2 easymde-orig/src/js/easymde.js easymde-mod1/src/js/easymde.js
--- easymde-orig/src/js/easymde.js 2020-04-06 14:09:36.000000000 +0200
+++ easymde-mod1/src/js/easymde.js 2020-05-01 14:34:19.878774400 +0200
@@ -11,5 +11,4 @@
require('codemirror/mode/gfm/gfm.js');
require('codemirror/mode/xml/xml.js');
-var CodeMirrorSpellChecker = require('codemirror-spell-checker');
var marked = require('marked/lib/marked');
@@ -1889,18 +1888,7 @@
var mode, backdrop;
- if (options.spellChecker !== false) {
- mode = 'spell-checker';
- backdrop = options.parsingConfig;
- backdrop.name = 'gfm';
- backdrop.gitHubSpice = false;
-
- CodeMirrorSpellChecker({
- codeMirrorInstance: CodeMirror,
- });
- } else {
mode = options.parsingConfig;
mode.name = 'gfm';
mode.gitHubSpice = false;
- }
// eslint-disable-next-line no-unused-vars
@@ -1927,5 +1915,4 @@
configureMouse: configureMouse,
inputStyle: (options.inputStyle != undefined) ? options.inputStyle : isMobile() ? 'contenteditable' : 'textarea',
- spellcheck: (options.nativeSpellcheck != undefined) ? options.nativeSpellcheck : true,
});