mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
(ノ ゚ヮ゚)ノ 彡┻━┻
This commit is contained in:
parent
2a6a3aedd0
commit
e7b99e6fb7
|
@ -16,6 +16,11 @@ var dom_ref = (function () {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// replace it with the real deal in the console
|
||||||
|
var dbg = function () { };
|
||||||
|
// dbg = console.log
|
||||||
|
|
||||||
|
|
||||||
// line->scrollpos maps
|
// line->scrollpos maps
|
||||||
var map_src = [];
|
var map_src = [];
|
||||||
var map_pre = [];
|
var map_pre = [];
|
||||||
|
@ -53,6 +58,7 @@ function genmap(dom) {
|
||||||
|
|
||||||
|
|
||||||
// input handler
|
// input handler
|
||||||
|
var action_stack = null;
|
||||||
var nlines = 0;
|
var nlines = 0;
|
||||||
(function () {
|
(function () {
|
||||||
dom_src.oninput = function (e) {
|
dom_src.oninput = function (e) {
|
||||||
|
@ -75,6 +81,8 @@ var nlines = 0;
|
||||||
cl += ' disabled';
|
cl += ' disabled';
|
||||||
|
|
||||||
sb.setAttribute('class', cl);
|
sb.setAttribute('class', cl);
|
||||||
|
if (action_stack)
|
||||||
|
action_stack.push();
|
||||||
}
|
}
|
||||||
dom_src.oninput();
|
dom_src.oninput();
|
||||||
})();
|
})();
|
||||||
|
@ -89,7 +97,7 @@ redraw = (function () {
|
||||||
dom_ref.style.width = (dom_src.offsetWidth - 4) + 'px';
|
dom_ref.style.width = (dom_src.offsetWidth - 4) + 'px';
|
||||||
map_src = genmap(dom_ref);
|
map_src = genmap(dom_ref);
|
||||||
map_pre = genmap(dom_pre);
|
map_pre = genmap(dom_pre);
|
||||||
console.log(document.body.clientWidth + 'x' + document.body.clientHeight);
|
dbg(document.body.clientWidth + 'x' + document.body.clientHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onresize = onresize;
|
window.onresize = onresize;
|
||||||
|
@ -292,7 +300,7 @@ function linebounds(just_car) {
|
||||||
var car = dom_src.selectionStart,
|
var car = dom_src.selectionStart,
|
||||||
cdr = dom_src.selectionEnd;
|
cdr = dom_src.selectionEnd;
|
||||||
|
|
||||||
console.log(car, cdr);
|
dbg(car, cdr);
|
||||||
|
|
||||||
if (just_car)
|
if (just_car)
|
||||||
cdr = car;
|
cdr = car;
|
||||||
|
@ -439,6 +447,18 @@ function md_newline() {
|
||||||
md_newline();
|
md_newline();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (ctrl && (ev.code == "KeyZ" || kc == 90)) {
|
||||||
|
if (ev.shiftKey)
|
||||||
|
action_stack.redo();
|
||||||
|
else
|
||||||
|
action_stack.undo();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ctrl && (ev.code == "KeyY" || kc == 89)) {
|
||||||
|
action_stack.redo();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.onkeydown = keydown;
|
document.onkeydown = keydown;
|
||||||
|
@ -458,3 +478,113 @@ document.getElementById('help').onclick = function (e) {
|
||||||
dom.style.display = 'none';
|
dom.style.display = 'none';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// blame steen
|
||||||
|
action_stack = (function () {
|
||||||
|
var undos = [];
|
||||||
|
var redos = [];
|
||||||
|
var sched_txt = '';
|
||||||
|
var sched_timer = null;
|
||||||
|
var ignore = false;
|
||||||
|
var ref = dom_src.value;
|
||||||
|
|
||||||
|
function diff(from, to) {
|
||||||
|
if (from === to)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var car = 0,
|
||||||
|
max = Math.max(from.length, to.length);
|
||||||
|
|
||||||
|
for (; car < max; car++)
|
||||||
|
if (from[car] != to[car])
|
||||||
|
break;
|
||||||
|
|
||||||
|
var p1 = from.length,
|
||||||
|
p2 = to.length;
|
||||||
|
|
||||||
|
while (p1 --> 0 && p2 --> 0)
|
||||||
|
if (from[p1] != to[p2])
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (car > ++p1) {
|
||||||
|
car = p1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var txt = from.substring(car, p1)
|
||||||
|
return {
|
||||||
|
car: car,
|
||||||
|
cdr: ++p2,
|
||||||
|
txt: txt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function undiff(from, change) {
|
||||||
|
return {
|
||||||
|
txt: from.substring(0, change.car) + change.txt + from.substring(change.cdr),
|
||||||
|
cursor: change.car + change.txt.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function apply(src, dst) {
|
||||||
|
dbg('undos(%d) redos(%d)', undos.length, redos.length);
|
||||||
|
|
||||||
|
if (src.length === 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var state = undiff(ref, src.pop()),
|
||||||
|
change = diff(ref, state.txt);
|
||||||
|
|
||||||
|
if (change === null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
dst.push(change);
|
||||||
|
ref = state.txt;
|
||||||
|
nodrop = true;
|
||||||
|
dom_src.value = ref;
|
||||||
|
dom_src.setSelectionRange(state.cursor, state.cursor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function schedule_push() {
|
||||||
|
if (ignore) {
|
||||||
|
ignore = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
redos = [];
|
||||||
|
sched_txt = dom_src.value;
|
||||||
|
clearTimeout(sched_timer);
|
||||||
|
sched_timer = setTimeout(push, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
function undo() {
|
||||||
|
return apply(undos, redos);
|
||||||
|
}
|
||||||
|
|
||||||
|
function redo() {
|
||||||
|
return apply(redos, undos);
|
||||||
|
}
|
||||||
|
|
||||||
|
function push() {
|
||||||
|
var change = diff(ref, sched_txt, dom_src.selectionStart);
|
||||||
|
if (change !== null)
|
||||||
|
undos.push(change);
|
||||||
|
|
||||||
|
ref = sched_txt;
|
||||||
|
dbg('undos(%d) redos(%d)', undos.length, redos.length);
|
||||||
|
if (undos.length > 0)
|
||||||
|
dbg(undos.slice(-1)[0]);
|
||||||
|
if (redos.length > 0)
|
||||||
|
dbg(redos.slice(-1)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
push: push,
|
||||||
|
undo: undo,
|
||||||
|
redo: redo,
|
||||||
|
push: schedule_push,
|
||||||
|
_undos: undos,
|
||||||
|
_redos: redos,
|
||||||
|
_ref: ref
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
84
srv/ceditable.html
Normal file
84
srv/ceditable.html
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<!DOCTYPE html><html><head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||||
|
<style>
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
outline: 0;
|
||||||
|
border: none;
|
||||||
|
font-size: 1em;
|
||||||
|
line-height: 1em;
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
html, body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
li, #edit {
|
||||||
|
list-style-type: none;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
word-wrap: break-word; /*ie*/
|
||||||
|
}
|
||||||
|
li:nth-child(even) {
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
#edit, #html, #txt1, #txt2 {
|
||||||
|
background: #eee;
|
||||||
|
position: fixed;
|
||||||
|
width: calc(50% - .8em);
|
||||||
|
height: calc(50% - .8em);
|
||||||
|
}
|
||||||
|
#txt1 { top: .5em; left: .5em }
|
||||||
|
#edit { top: .5em; right: .5em }
|
||||||
|
#html { bottom: .5em; left: .5em }
|
||||||
|
#txt2 { bottom: .5em; right: .5em }
|
||||||
|
|
||||||
|
</style></head><body>
|
||||||
|
<pre id="edit" contenteditable="true"></pre>
|
||||||
|
<textarea id="html"></textarea>
|
||||||
|
<ul id="txt1"></ul>
|
||||||
|
<ul id="txt2"></ul>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var edit = document.getElementById('edit'),
|
||||||
|
html = document.getElementById('html'),
|
||||||
|
txt1 = document.getElementById('txt1'),
|
||||||
|
txt2 = document.getElementById('txt2');
|
||||||
|
|
||||||
|
var oh = null;
|
||||||
|
function fun() {
|
||||||
|
var h = edit.innerHTML;
|
||||||
|
if (oh != h) {
|
||||||
|
oh = h;
|
||||||
|
html.value = h;
|
||||||
|
var t = edit.innerText;
|
||||||
|
if (h.indexOf('<div><br></div>') >= 0)
|
||||||
|
t = t.replace(/\n\n/g, "\n");
|
||||||
|
|
||||||
|
t = '<li>' + t.
|
||||||
|
replace(/&/g, "&").
|
||||||
|
replace(/</g, "<").
|
||||||
|
replace(/>/g, ">").
|
||||||
|
split('\n').join('</li>\n<li>') + '</li>';
|
||||||
|
|
||||||
|
t = t.replace(/<li><\/li>/g, '<li> </li>');
|
||||||
|
txt1.innerHTML = t;
|
||||||
|
txt2.innerHTML = t;
|
||||||
|
}
|
||||||
|
setTimeout(fun, 100);
|
||||||
|
}
|
||||||
|
fun();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue