mirror of
https://github.com/9001/copyparty.git
synced 2025-11-05 14:23:17 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68289cfa54 | ||
|
|
42ea30270f | ||
|
|
ebbbbf3d82 | ||
|
|
27516e2d16 | ||
|
|
84bb6f915e | ||
|
|
46752f758a |
21
README.md
21
README.md
@@ -581,27 +581,31 @@ copyparty can invoke external programs to collect additional metadata for files
|
|||||||
`ie` = internet-explorer, `ff` = firefox, `c` = chrome, `iOS` = iPhone/iPad, `Andr` = Android
|
`ie` = internet-explorer, `ff` = firefox, `c` = chrome, `iOS` = iPhone/iPad, `Andr` = Android
|
||||||
|
|
||||||
| feature | ie6 | ie9 | ie10 | ie11 | ff 52 | c 49 | iOS | Andr |
|
| feature | ie6 | ie9 | ie10 | ie11 | ff 52 | c 49 | iOS | Andr |
|
||||||
| --------------- | --- | --- | ---- | ---- | ----- | ---- | --- | ---- |
|
| --------------- | --- | ---- | ---- | ---- | ----- | ---- | --- | ---- |
|
||||||
| browse files | yep | yep | yep | yep | yep | yep | yep | yep |
|
| browse files | yep | yep | yep | yep | yep | yep | yep | yep |
|
||||||
|
| thumbnail view | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| basic uploader | yep | yep | yep | yep | yep | yep | yep | yep |
|
| basic uploader | yep | yep | yep | yep | yep | yep | yep | yep |
|
||||||
|
| up2k | - | - | `*1` | `*1` | yep | yep | yep | yep |
|
||||||
| make directory | yep | yep | yep | yep | yep | yep | yep | yep |
|
| make directory | yep | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| send message | yep | yep | yep | yep | yep | yep | yep | yep |
|
| send message | yep | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| set sort order | - | yep | yep | yep | yep | yep | yep | yep |
|
| set sort order | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| zip selection | - | yep | yep | yep | yep | yep | yep | yep |
|
| zip selection | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| navpane | - | - | `*1` | yep | yep | yep | yep | yep |
|
| file rename | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| up2k | - | - | yep | yep | yep | yep | yep | yep |
|
| file cut/paste | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
|
| navpane | - | `*2` | yep | yep | yep | yep | yep | yep |
|
||||||
|
| image viewer | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
|
| video player | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| markdown editor | - | - | yep | yep | yep | yep | yep | yep |
|
| markdown editor | - | - | yep | yep | yep | yep | yep | yep |
|
||||||
| markdown viewer | - | - | yep | yep | yep | yep | yep | yep |
|
| markdown viewer | - | - | yep | yep | yep | yep | yep | yep |
|
||||||
| play mp3/m4a | - | yep | yep | yep | yep | yep | yep | yep |
|
| play mp3/m4a | - | yep | yep | yep | yep | yep | yep | yep |
|
||||||
| play ogg/opus | - | - | - | - | yep | yep | `*2` | yep |
|
| play ogg/opus | - | - | - | - | yep | yep | `*3` | yep |
|
||||||
| thumbnail view | - | - | - | - | yep | yep | yep | yep |
|
|
||||||
| image viewer | - | - | - | - | yep | yep | yep | yep |
|
|
||||||
| **= feature =** | ie6 | ie9 | ie10 | ie11 | ff 52 | c 49 | iOS | Andr |
|
| **= feature =** | ie6 | ie9 | ie10 | ie11 | ff 52 | c 49 | iOS | Andr |
|
||||||
|
|
||||||
* internet explorer 6 to 8 behave the same
|
* internet explorer 6 to 8 behave the same
|
||||||
* firefox 52 and chrome 49 are the last winxp versions
|
* firefox 52 and chrome 49 are the last winxp versions
|
||||||
* `*1` only public folders (login session is dropped) and no history / back-button
|
* `*1` yes, but extremely slow (ie10: 1 MiB/s, ie11: 270 KiB/s)
|
||||||
* `*2` using a wasm decoder which can sometimes get stuck and consumes a bit more power
|
* `*2` causes a full-page refresh on each navigation
|
||||||
|
* `*3` using a wasm decoder which can sometimes get stuck and consumes a bit more power
|
||||||
|
|
||||||
quick summary of more eccentric web-browsers trying to view a directory index:
|
quick summary of more eccentric web-browsers trying to view a directory index:
|
||||||
|
|
||||||
@@ -613,6 +617,7 @@ quick summary of more eccentric web-browsers trying to view a directory index:
|
|||||||
| **lynx** (2.8.9/macports) | can browse, login, upload/mkdir/msg |
|
| **lynx** (2.8.9/macports) | can browse, login, upload/mkdir/msg |
|
||||||
| **w3m** (0.5.3/macports) | can browse, login, upload at 100kB/s, mkdir/msg |
|
| **w3m** (0.5.3/macports) | can browse, login, upload at 100kB/s, mkdir/msg |
|
||||||
| **netsurf** (3.10/arch) | is basically ie6 with much better css (javascript has almost no effect) |
|
| **netsurf** (3.10/arch) | is basically ie6 with much better css (javascript has almost no effect) |
|
||||||
|
| **opera** (11.60/winxp) | OK: thumbnails, image-viewer, zip-selection, rename/cut/paste. NG: up2k, navpane, markdown, audio |
|
||||||
| **ie4** and **netscape** 4.0 | can browse (text is yellow on white), upload with `?b=u` |
|
| **ie4** and **netscape** 4.0 | can browse (text is yellow on white), upload with `?b=u` |
|
||||||
| **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
|
| **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
VERSION = (0, 13, 3)
|
VERSION = (0, 13, 4)
|
||||||
CODENAME = "future-proof"
|
CODENAME = "future-proof"
|
||||||
BUILD_DT = (2021, 8, 14)
|
BUILD_DT = (2021, 8, 16)
|
||||||
|
|
||||||
S_VERSION = ".".join(map(str, VERSION))
|
S_VERSION = ".".join(map(str, VERSION))
|
||||||
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
|
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
|
||||||
|
|||||||
@@ -956,10 +956,14 @@ class HttpCli(object):
|
|||||||
vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, False, True)
|
vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, False, True)
|
||||||
self._assert_safe_rem(rem)
|
self._assert_safe_rem(rem)
|
||||||
|
|
||||||
|
upload_vpath = self.vpath
|
||||||
lim = vfs.get_dbv(rem)[0].lim
|
lim = vfs.get_dbv(rem)[0].lim
|
||||||
fdir_base = os.path.join(vfs.realpath, rem)
|
fdir_base = os.path.join(vfs.realpath, rem)
|
||||||
if lim:
|
if lim:
|
||||||
fdir_base, rem = lim.all(self.ip, rem, -1, fdir_base)
|
fdir_base, rem = lim.all(self.ip, rem, -1, fdir_base)
|
||||||
|
upload_vpath = "{}/{}".format(vfs.vpath, rem).strip("/")
|
||||||
|
if not nullwrite:
|
||||||
|
bos.makedirs(fdir_base)
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
errmsg = ""
|
errmsg = ""
|
||||||
@@ -986,8 +990,6 @@ class HttpCli(object):
|
|||||||
if lim:
|
if lim:
|
||||||
lim.chk_bup(self.ip)
|
lim.chk_bup(self.ip)
|
||||||
lim.chk_nup(self.ip)
|
lim.chk_nup(self.ip)
|
||||||
if not nullwrite:
|
|
||||||
bos.makedirs(fdir)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with ren_open(fname, "wb", 512 * 1024, **open_args) as f:
|
with ren_open(fname, "wb", 512 * 1024, **open_args) as f:
|
||||||
@@ -1038,7 +1040,9 @@ class HttpCli(object):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
except Pebkac as ex:
|
except Pebkac as ex:
|
||||||
errmsg = volsan(self.asrv.vfs.all_vols.values(), unicode(ex))
|
errmsg = vol_san(
|
||||||
|
self.asrv.vfs.all_vols.values(), unicode(ex).encode("utf-8")
|
||||||
|
).decode("utf-8")
|
||||||
|
|
||||||
td = max(0.1, time.time() - t0)
|
td = max(0.1, time.time() - t0)
|
||||||
sz_total = sum(x[0] for x in files)
|
sz_total = sum(x[0] for x in files)
|
||||||
@@ -1058,7 +1062,7 @@ class HttpCli(object):
|
|||||||
errmsg = "ERROR: " + errmsg
|
errmsg = "ERROR: " + errmsg
|
||||||
|
|
||||||
for sz, sha512, ofn, lfn in files:
|
for sz, sha512, ofn, lfn in files:
|
||||||
vpath = (self.vpath + "/" if self.vpath else "") + lfn
|
vpath = "{}/{}".format(upload_vpath, lfn).strip("/")
|
||||||
msg += 'sha512: {} // {} bytes // <a href="/{}">{}</a>\n'.format(
|
msg += 'sha512: {} // {} bytes // <a href="/{}">{}</a>\n'.format(
|
||||||
sha512[:56], sz, quotep(vpath), html_escape(ofn, crlf=True)
|
sha512[:56], sz, quotep(vpath), html_escape(ofn, crlf=True)
|
||||||
)
|
)
|
||||||
@@ -1695,7 +1699,7 @@ class HttpCli(object):
|
|||||||
|
|
||||||
q = "select sz, rd, fn, at from up where ip=? and at>?"
|
q = "select sz, rd, fn, at from up where ip=? and at>?"
|
||||||
for sz, rd, fn, at in cur.execute(q, (self.ip, lim)):
|
for sz, rd, fn, at in cur.execute(q, (self.ip, lim)):
|
||||||
vp = "/" + "/".join([rd, fn]).strip("/")
|
vp = "/" + "/".join(x for x in [vol.vpath, rd, fn] if x)
|
||||||
if filt and filt not in vp:
|
if filt and filt not in vp:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -346,9 +346,7 @@ def log_thrs(log, ival, name):
|
|||||||
|
|
||||||
def vol_san(vols, txt):
|
def vol_san(vols, txt):
|
||||||
for vol in vols:
|
for vol in vols:
|
||||||
txt = txt.replace(
|
txt = txt.replace(vol.realpath.encode("utf-8"), vol.vpath.encode("utf-8"))
|
||||||
vol.realpath.encode("utf-8"), vol.vpath.encode("utf-8")
|
|
||||||
)
|
|
||||||
|
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|||||||
@@ -742,11 +742,11 @@ window.baguetteBox = (function () {
|
|||||||
if (rot || orot === null)
|
if (rot || orot === null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
el.classList.add('nt');
|
clmod(el, 'nt', 1);
|
||||||
el.removeAttribute('rot');
|
el.removeAttribute('rot');
|
||||||
el.removeAttribute("style");
|
el.removeAttribute("style");
|
||||||
rot = el.offsetHeight;
|
rot = el.offsetHeight;
|
||||||
el.classList.remove('nt');
|
clmod(el, 'nt');
|
||||||
timer.rm(rotn);
|
timer.rm(rotn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,15 +799,21 @@ window.baguetteBox = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateOffset() {
|
function updateOffset() {
|
||||||
var offset = -currentIndex * 100 + '%';
|
var offset = -currentIndex * 100 + '%',
|
||||||
|
xform = slider.style.perspective !== undefined;
|
||||||
|
|
||||||
if (options.animation === 'fadeIn') {
|
if (options.animation === 'fadeIn') {
|
||||||
slider.style.opacity = 0;
|
slider.style.opacity = 0;
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
slider.style.transform = 'translate3d(' + offset + ',0,0)';
|
xform ?
|
||||||
|
slider.style.transform = 'translate3d(' + offset + ',0,0)' :
|
||||||
|
slider.style.left = offset;
|
||||||
slider.style.opacity = 1;
|
slider.style.opacity = 1;
|
||||||
}, 400);
|
}, 400);
|
||||||
} else {
|
} else {
|
||||||
slider.style.transform = 'translate3d(' + offset + ',0,0)';
|
xform ?
|
||||||
|
slider.style.transform = 'translate3d(' + offset + ',0,0)' :
|
||||||
|
slider.style.left = offset;
|
||||||
}
|
}
|
||||||
playvid(false);
|
playvid(false);
|
||||||
var v = vid();
|
var v = vid();
|
||||||
@@ -828,9 +834,9 @@ window.baguetteBox = (function () {
|
|||||||
|
|
||||||
var prev = QS('.full-image.vis');
|
var prev = QS('.full-image.vis');
|
||||||
if (prev)
|
if (prev)
|
||||||
prev.classList.remove('vis');
|
clmod(prev, 'vis');
|
||||||
|
|
||||||
el.closest('div').classList.add('vis');
|
clmod(el.closest('div'), 'vis', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function preloadNext(index) {
|
function preloadNext(index) {
|
||||||
|
|||||||
@@ -417,17 +417,10 @@ html.light #ggrid a.sel {
|
|||||||
html.light #wfm a:not(.en) {
|
html.light #wfm a:not(.en) {
|
||||||
color: #c4a;
|
color: #c4a;
|
||||||
}
|
}
|
||||||
#files tbody tr.c1 td {
|
#files tbody tr.fcut td {
|
||||||
animation: fcut1 .5s ease-out;
|
animation: fcut .5s ease-out;
|
||||||
}
|
}
|
||||||
#files tbody tr.c2 td {
|
@keyframes fcut {
|
||||||
animation: fcut2 .5s ease-out;
|
|
||||||
}
|
|
||||||
@keyframes fcut1 {
|
|
||||||
0% {opacity:0}
|
|
||||||
100% {opacity:1}
|
|
||||||
}
|
|
||||||
@keyframes fcut2 {
|
|
||||||
0% {opacity:0}
|
0% {opacity:0}
|
||||||
100% {opacity:1}
|
100% {opacity:1}
|
||||||
}
|
}
|
||||||
@@ -709,6 +702,10 @@ input.eq_gain {
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
height: 2.2em;
|
||||||
|
line-height: 2.2em;
|
||||||
|
border-bottom: 1px solid #555;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
#thx_ff {
|
#thx_ff {
|
||||||
padding: 5em 0;
|
padding: 5em 0;
|
||||||
@@ -896,6 +893,7 @@ html.light #ghead {
|
|||||||
}
|
}
|
||||||
#ggrid a {
|
#ggrid a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
width: 10em;
|
||||||
width: var(--grid-sz);
|
width: var(--grid-sz);
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
@@ -909,7 +907,9 @@ html.light #ghead {
|
|||||||
}
|
}
|
||||||
#ggrid a img {
|
#ggrid a img {
|
||||||
border-radius: .2em;
|
border-radius: .2em;
|
||||||
|
max-width: 10em;
|
||||||
max-width: var(--grid-sz);
|
max-width: var(--grid-sz);
|
||||||
|
max-height: 8em;
|
||||||
max-height: calc(var(--grid-sz)/1.25);
|
max-height: calc(var(--grid-sz)/1.25);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -1251,6 +1251,7 @@ html.light #files tr.sel a:hover {
|
|||||||
}
|
}
|
||||||
html.light #treeh {
|
html.light #treeh {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
|
border-color: #ddd;
|
||||||
}
|
}
|
||||||
html.light #tree {
|
html.light #tree {
|
||||||
scrollbar-color: #a70 #ddd;
|
scrollbar-color: #a70 #ddd;
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ ebi('tree').innerHTML = (
|
|||||||
' <a href="#" class="btn" step="2" id="twobytwo" tt="Hotkey: A">+</a>\n' +
|
' <a href="#" class="btn" step="2" id="twobytwo" tt="Hotkey: A">+</a>\n' +
|
||||||
' <a href="#" class="btn" step="-2" id="twig" tt="Hotkey: D">–</a>\n' +
|
' <a href="#" class="btn" step="-2" id="twig" tt="Hotkey: D">–</a>\n' +
|
||||||
' <a href="#" class="tgl btn" id="dyntree" tt="autogrow as tree expands">a</a>\n' +
|
' <a href="#" class="tgl btn" id="dyntree" tt="autogrow as tree expands">a</a>\n' +
|
||||||
|
' <a href="#" class="btn" id="visdir" tt="scroll to selected folder">v</a>\n' +
|
||||||
'</div>\n' +
|
'</div>\n' +
|
||||||
'<ul id="treeul"></ul>\n' +
|
'<ul id="treeul"></ul>\n' +
|
||||||
'<div id="thx_ff"> </div>'
|
'<div id="thx_ff"> </div>'
|
||||||
@@ -1657,7 +1658,7 @@ var fileman = (function () {
|
|||||||
r.clip = jread('fman_clip', []);
|
r.clip = jread('fman_clip', []);
|
||||||
|
|
||||||
var nsel = msel.getsel().length;
|
var nsel = msel.getsel().length;
|
||||||
clmod(bren, 'en', nsel == 1);
|
clmod(bren, 'en', nsel);
|
||||||
clmod(bdel, 'en', nsel);
|
clmod(bdel, 'en', nsel);
|
||||||
clmod(bcut, 'en', nsel);
|
clmod(bcut, 'en', nsel);
|
||||||
clmod(bpst, 'en', r.clip && r.clip.length);
|
clmod(bpst, 'en', r.clip && r.clip.length);
|
||||||
@@ -2018,17 +2019,21 @@ var fileman = (function () {
|
|||||||
if (!sel.length)
|
if (!sel.length)
|
||||||
return toast.err(3, 'select at least 1 item to cut');
|
return toast.err(3, 'select at least 1 item to cut');
|
||||||
|
|
||||||
if (sel.length < 100)
|
var els = [];
|
||||||
for (var a = 0; a < sel.length; a++) {
|
for (var a = 0; a < sel.length; a++) {
|
||||||
vps.push(sel[a].vp);
|
vps.push(sel[a].vp);
|
||||||
var cl = ebi(sel[a].id).closest('tr').classList,
|
if (sel.length < 100) {
|
||||||
inv = cl.contains('c1');
|
els.push(ebi(sel[a].id).closest('tr'));
|
||||||
|
clmod(els[a], 'fcut');
|
||||||
cl.remove(inv ? 'c1' : 'c2');
|
}
|
||||||
cl.add(inv ? 'c2' : 'c1');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toast.inf(1, 'cut ' + sel.length + ' items');
|
setTimeout(function () {
|
||||||
|
for (var a = 0; a < els.length; a++)
|
||||||
|
clmod(els[a], 'fcut', 1);
|
||||||
|
}, 1);
|
||||||
|
|
||||||
|
toast.inf(1.5, 'cut ' + sel.length + ' items');
|
||||||
jwrite('fman_clip', vps);
|
jwrite('fman_clip', vps);
|
||||||
r.tx(1);
|
r.tx(1);
|
||||||
};
|
};
|
||||||
@@ -2391,7 +2396,8 @@ var thegrid = (function () {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
function tree_scrollto() {
|
function tree_scrollto(e) {
|
||||||
|
ev(e);
|
||||||
var act = QS('#treeul a.hl'),
|
var act = QS('#treeul a.hl'),
|
||||||
ul = act ? act.offsetParent : null;
|
ul = act ? act.offsetParent : null;
|
||||||
|
|
||||||
@@ -2851,7 +2857,7 @@ var treectl = (function () {
|
|||||||
var treectl = {
|
var treectl = {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"ls_cb": null,
|
"ls_cb": null,
|
||||||
"dir_cb": null
|
"dir_cb": tree_scrollto
|
||||||
},
|
},
|
||||||
entreed = false,
|
entreed = false,
|
||||||
fixedpos = false,
|
fixedpos = false,
|
||||||
@@ -3155,7 +3161,13 @@ var treectl = (function () {
|
|||||||
}
|
}
|
||||||
html.push('</tbody>');
|
html.push('</tbody>');
|
||||||
html = html.join('\n');
|
html = html.join('\n');
|
||||||
|
try {
|
||||||
ebi('files').innerHTML = html;
|
ebi('files').innerHTML = html;
|
||||||
|
}
|
||||||
|
catch (ex) { //ie9
|
||||||
|
window.location.href = this.top;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.hpush)
|
if (this.hpush)
|
||||||
hist_push(this.top);
|
hist_push(this.top);
|
||||||
@@ -3239,6 +3251,7 @@ var treectl = (function () {
|
|||||||
|
|
||||||
ebi('entree').onclick = treectl.entree;
|
ebi('entree').onclick = treectl.entree;
|
||||||
ebi('detree').onclick = treectl.detree;
|
ebi('detree').onclick = treectl.detree;
|
||||||
|
ebi('visdir').onclick = tree_scrollto;
|
||||||
ebi('dotfiles').onclick = tdots;
|
ebi('dotfiles').onclick = tdots;
|
||||||
ebi('dyntree').onclick = dyntree;
|
ebi('dyntree').onclick = dyntree;
|
||||||
ebi('twig').onclick = scaletree;
|
ebi('twig').onclick = scaletree;
|
||||||
@@ -3775,7 +3788,7 @@ var msel = (function () {
|
|||||||
if (r.all && r.all.length) {
|
if (r.all && r.all.length) {
|
||||||
for (var a = 0; a < r.all.length; a++) {
|
for (var a = 0; a < r.all.length; a++) {
|
||||||
var ao = r.all[a];
|
var ao = r.all[a];
|
||||||
ao.sel = ebi(ao.id).closest('tr').classList.contains('sel');
|
ao.sel = clgot(ebi(ao.id).closest('tr'), 'sel');
|
||||||
if (ao.sel)
|
if (ao.sel)
|
||||||
r.sel.push(ao);
|
r.sel.push(ao);
|
||||||
}
|
}
|
||||||
@@ -3791,7 +3804,7 @@ var msel = (function () {
|
|||||||
item = {};
|
item = {};
|
||||||
|
|
||||||
item.id = links[a].getAttribute('id');
|
item.id = links[a].getAttribute('id');
|
||||||
item.sel = links[a].closest('tr').classList.contains('sel');
|
item.sel = clgot(links[a].closest('tr'), 'sel');
|
||||||
item.vp = href.indexOf('/') !== -1 ? href : vbase + href;
|
item.vp = href.indexOf('/') !== -1 ? href : vbase + href;
|
||||||
|
|
||||||
r.all.push(item);
|
r.all.push(item);
|
||||||
|
|||||||
@@ -370,8 +370,8 @@ function save_cb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!r.ok) {
|
if (!r.ok) {
|
||||||
if (!this.btn.classList.contains('force-save')) {
|
if (!clgot(this.btn, 'force-save')) {
|
||||||
this.btn.classList.add('force-save');
|
clmod(this.btn, 'force-save', 1);
|
||||||
var msg = [
|
var msg = [
|
||||||
'This file has been modified since you started editing it!\n',
|
'This file has been modified since you started editing it!\n',
|
||||||
'if you really want to overwrite, press save again.\n',
|
'if you really want to overwrite, press save again.\n',
|
||||||
@@ -387,7 +387,7 @@ function save_cb() {
|
|||||||
return toast.err(0, 'Error! Save failed. Maybe this JSON explains why:\n\n' + this.responseText);
|
return toast.err(0, 'Error! Save failed. Maybe this JSON explains why:\n\n' + this.responseText);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.btn.classList.remove('force-save');
|
clmod(this.btn, 'force-save');
|
||||||
//alert('save OK -- wrote ' + r.size + ' bytes.\n\nsha512: ' + r.sha512);
|
//alert('save OK -- wrote ' + r.size + ' bytes.\n\nsha512: ' + r.sha512);
|
||||||
|
|
||||||
run_savechk(r.lastmod, this.txt, this.btn, 0);
|
run_savechk(r.lastmod, this.txt, this.btn, 0);
|
||||||
|
|||||||
@@ -96,20 +96,16 @@ function md_changed(mde, on_srv) {
|
|||||||
var md_now = mde.value();
|
var md_now = mde.value();
|
||||||
var save_btn = QS('.editor-toolbar button.save');
|
var save_btn = QS('.editor-toolbar button.save');
|
||||||
|
|
||||||
if (md_now == window.md_saved)
|
clmod(save_btn, 'disabled', md_now == window.md_saved);
|
||||||
save_btn.classList.add('disabled');
|
|
||||||
else
|
|
||||||
save_btn.classList.remove('disabled');
|
|
||||||
|
|
||||||
set_jumpto();
|
set_jumpto();
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(mde) {
|
function save(mde) {
|
||||||
var save_btn = QS('.editor-toolbar button.save');
|
var save_btn = QS('.editor-toolbar button.save');
|
||||||
if (save_btn.classList.contains('disabled'))
|
if (clgot(save_btn, 'disabled'))
|
||||||
return toast.inf(2, 'no changes');
|
return toast.inf(2, 'no changes');
|
||||||
|
|
||||||
var force = save_btn.classList.contains('force-save');
|
var force = clgot(save_btn, 'force-save');
|
||||||
function save2() {
|
function save2() {
|
||||||
var txt = mde.value();
|
var txt = mde.value();
|
||||||
|
|
||||||
@@ -153,8 +149,8 @@ function save_cb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!r.ok) {
|
if (!r.ok) {
|
||||||
if (!this.btn.classList.contains('force-save')) {
|
if (!clgot(this.btn, 'force-save')) {
|
||||||
this.btn.classList.add('force-save');
|
clmod(this.btn, 'force-save', 1);
|
||||||
var msg = [
|
var msg = [
|
||||||
'This file has been modified since you started editing it!\n',
|
'This file has been modified since you started editing it!\n',
|
||||||
'if you really want to overwrite, press save again.\n',
|
'if you really want to overwrite, press save again.\n',
|
||||||
@@ -170,7 +166,7 @@ function save_cb() {
|
|||||||
return toast.err(0, 'Error! Save failed. Maybe this JSON explains why:\n\n' + this.responseText);
|
return toast.err(0, 'Error! Save failed. Maybe this JSON explains why:\n\n' + this.responseText);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.btn.classList.remove('force-save');
|
clmod(this.btn, 'force-save');
|
||||||
//alert('save OK -- wrote ' + r.size + ' bytes.\n\nsha512: ' + r.sha512);
|
//alert('save OK -- wrote ' + r.size + ' bytes.\n\nsha512: ' + r.sha512);
|
||||||
|
|
||||||
// download the saved doc from the server and compare
|
// download the saved doc from the server and compare
|
||||||
|
|||||||
@@ -511,7 +511,7 @@ function up2k_init(subtle) {
|
|||||||
import_js('/.cpr/deps/' + fn, unmodal);
|
import_js('/.cpr/deps/' + fn, unmodal);
|
||||||
|
|
||||||
if (is_https)
|
if (is_https)
|
||||||
ebi('u2foot').innerHTML = shame + ' so <em>this</em> uploader will do like 500kB/s at best';
|
ebi('u2foot').innerHTML = shame + ' so <em>this</em> uploader will do like 500 KiB/s at best';
|
||||||
else
|
else
|
||||||
ebi('u2foot').innerHTML = 'seems like ' + shame + ' so do that if you want more performance <span style="color:#' +
|
ebi('u2foot').innerHTML = 'seems like ' + shame + ' so do that if you want more performance <span style="color:#' +
|
||||||
(sha_js == 'ac' ? 'c84">(expecting 20' : '8a5">(but dont worry too much, expect 100') + ' MiB/s)</span>';
|
(sha_js == 'ac' ? 'c84">(expecting 20' : '8a5">(but dont worry too much, expect 100') + ' MiB/s)</span>';
|
||||||
@@ -805,13 +805,13 @@ function up2k_init(subtle) {
|
|||||||
for (var a = 0; a < good_files.length; a++) {
|
for (var a = 0; a < good_files.length; a++) {
|
||||||
var fobj = good_files[a][0],
|
var fobj = good_files[a][0],
|
||||||
name = good_files[a][1],
|
name = good_files[a][1],
|
||||||
fdir = '',
|
fdir = get_evpath(),
|
||||||
now = Date.now(),
|
now = Date.now(),
|
||||||
lmod = fobj.lastModified || now,
|
lmod = fobj.lastModified || now,
|
||||||
ofs = name.lastIndexOf('/') + 1;
|
ofs = name.lastIndexOf('/') + 1;
|
||||||
|
|
||||||
if (ofs) {
|
if (ofs) {
|
||||||
fdir = name.slice(0, ofs);
|
fdir += url_enc(name.slice(0, ofs));
|
||||||
name = name.slice(ofs);
|
name = name.slice(ofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1263,7 +1263,7 @@ function up2k_init(subtle) {
|
|||||||
try { orz(e); } catch (ex) { vis_exh(ex + '', '', '', '', ex); }
|
try { orz(e); } catch (ex) { vis_exh(ex + '', '', '', '', ex); }
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.open('HEAD', t.purl + t.name, true);
|
xhr.open('HEAD', t.purl + uricom_enc(t.name), true);
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1340,12 +1340,13 @@ function up2k_init(subtle) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.purl !== t.purl || response.name !== t.name) {
|
var rsp_purl = url_enc(response.purl);
|
||||||
|
if (rsp_purl !== t.purl || response.name !== t.name) {
|
||||||
// server renamed us (file exists / path restrictions)
|
// server renamed us (file exists / path restrictions)
|
||||||
console.log("server-rename [" + t.purl + "] [" + t.name + "] to [" + response.purl + "] [" + response.name + "]");
|
console.log("server-rename [" + t.purl + "] [" + t.name + "] to [" + rsp_purl + "] [" + response.name + "]");
|
||||||
t.purl = response.purl;
|
t.purl = rsp_purl;
|
||||||
t.name = response.name;
|
t.name = response.name;
|
||||||
pvis.seth(t.n, 0, linksplit(t.purl + t.name).join(' '));
|
pvis.seth(t.n, 0, linksplit(uricom_dec(t.purl)[0] + t.name).join(' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
var chunksize = get_chunksize(t.size),
|
var chunksize = get_chunksize(t.size),
|
||||||
@@ -1703,11 +1704,10 @@ function up2k_init(subtle) {
|
|||||||
catch (ex) { }
|
catch (ex) { }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var fun = fsearch ? 'add' : 'remove',
|
var ico = fsearch ? '🔎' : '🚀',
|
||||||
ico = fsearch ? '🔎' : '🚀',
|
|
||||||
desc = fsearch ? 'Search' : 'Upload';
|
desc = fsearch ? 'Search' : 'Upload';
|
||||||
|
|
||||||
ebi('op_up2k').classList[fun]('srch');
|
clmod(ebi('op_up2k'), 'srch', fsearch);
|
||||||
ebi('u2bm').innerHTML = ico + ' <sup>' + desc + '</sup>';
|
ebi('u2bm').innerHTML = ico + ' <sup>' + desc + '</sup>';
|
||||||
}
|
}
|
||||||
catch (ex) { }
|
catch (ex) { }
|
||||||
|
|||||||
@@ -123,11 +123,18 @@ if (!String.startsWith) {
|
|||||||
return this.substring(i, i + s.length) === s;
|
return this.substring(i, i + s.length) === s;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (!Element.prototype.matches) {
|
||||||
|
Element.prototype.matches =
|
||||||
|
Element.prototype.oMatchesSelector ||
|
||||||
|
Element.prototype.msMatchesSelector ||
|
||||||
|
Element.prototype.mozMatchesSelector ||
|
||||||
|
Element.prototype.webkitMatchesSelector;
|
||||||
|
}
|
||||||
if (!Element.prototype.closest) {
|
if (!Element.prototype.closest) {
|
||||||
Element.prototype.closest = function (s) {
|
Element.prototype.closest = function (s) {
|
||||||
var el = this;
|
var el = this;
|
||||||
do {
|
do {
|
||||||
if (el.msMatchesSelector(s)) return el;
|
if (el.matches(s)) return el;
|
||||||
el = el.parentElement || el.parentNode;
|
el = el.parentElement || el.parentNode;
|
||||||
} while (el !== null && el.nodeType === 1);
|
} while (el !== null && el.nodeType === 1);
|
||||||
}
|
}
|
||||||
@@ -170,12 +177,28 @@ function crc32(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function clmod(obj, cls, add) {
|
function clmod(el, cls, add) {
|
||||||
|
if (el.classList) {
|
||||||
|
if (add == 't')
|
||||||
|
add = el.classList.contains(cls) ? 0 : 1;
|
||||||
|
|
||||||
|
return el.classList[add ? 'add' : 'remove'](cls);
|
||||||
|
}
|
||||||
|
|
||||||
var re = new RegExp('\\s*\\b' + cls + '\\s*\\b', 'g');
|
var re = new RegExp('\\s*\\b' + cls + '\\s*\\b', 'g');
|
||||||
if (add == 't')
|
if (add == 't')
|
||||||
add = !re.test(obj.className);
|
add = !re.test(el.className);
|
||||||
|
|
||||||
obj.className = obj.className.replace(re, ' ') + (add ? ' ' + cls : '');
|
el.className = el.className.replace(re, ' ') + (add ? ' ' + cls : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function clgot(el, cls) {
|
||||||
|
if (el.classList)
|
||||||
|
return el.classList.contains(cls);
|
||||||
|
|
||||||
|
var lst = (el.getAttribute('class') + '').split(/ /g);
|
||||||
|
return has(lst, cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -308,6 +331,16 @@ function uricom_enc(txt, do_fb_enc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function url_enc(txt) {
|
||||||
|
var parts = txt.split('/'),
|
||||||
|
ret = [];
|
||||||
|
|
||||||
|
for (var a = 0; a < parts.length; a++)
|
||||||
|
ret.push(uricom_enc(parts[a]));
|
||||||
|
|
||||||
|
return ret.join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function uricom_dec(txt) {
|
function uricom_dec(txt) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user