From 12d685fd6eb2efe8b9538b17d50ba326a2a91ea8 Mon Sep 17 00:00:00 2001 From: bohwaz Date: Mon, 21 Nov 2022 18:24:31 +0100 Subject: [PATCH] Update JS dependencies --- www/webdav.css | 4 + www/webdav.js | 332 ++++++++++++++++++++++++++++--------------------- 2 files changed, 197 insertions(+), 139 deletions(-) diff --git a/www/webdav.css b/www/webdav.css index e0b43a8..89450a5 100644 --- a/www/webdav.css +++ b/www/webdav.css @@ -41,6 +41,10 @@ th, td { border: 2px solid var(--g2-color); } +th { + word-break: break-all; +} + td.thumb { width: 5%; } diff --git a/www/webdav.js b/www/webdav.js index d431db6..1b3d6c9 100644 --- a/www/webdav.js +++ b/www/webdav.js @@ -9,8 +9,8 @@ const WebDAVNavigator = (url, options) => { const _ = key => typeof lang_strings != 'undefined' && key in lang_strings ? lang_strings[key] : key; - const common_buttons = ` - `; + const rename_button = ``; + const delete_button = ``; const edit_button = ``; @@ -33,10 +33,6 @@ const WebDAVNavigator = (url, options) => { const body_tpl = `

%title%

- - - - + + + `; + + const dir_row_tpl = `%icon%%name%%modified%
`; + const file_row_tpl = `%icon%%name%%size%%modified%
${_('Download')}
`; const propfind_tpl = ` - + - + `; @@ -355,30 +356,53 @@ const WebDAVNavigator = (url, options) => { var items = [[], []]; var title = null; + var root_permissions = null; xml.querySelectorAll('response').forEach((node) => { var item_uri = normalizeURL(node.querySelector('href').textContent); + var props = null; + + node.querySelectorAll('propstat').forEach((propstat) => { + if (propstat.querySelector('status').textContent.match(/200/)) { + props = propstat; + } + }); + + // This item didn't return any properties, everything is 404? + if (!props) { + console.error('Cannot find properties for: ' + item_uri); + return; + } + var name = item_uri.replace(/\/$/, '').split('/').pop(); name = decodeURIComponent(name); + var permissions = (prop = node.querySelector('permissions')) ? prop.textContent : null; + if (item_uri == uri) { title = name; + root_permissions = permissions; return; } var is_dir = node.querySelector('resourcetype collection') ? true : false; + var index = sort_order == 'name' && is_dir ? 0 : 1; - items[is_dir ? 0 : 1].push({ + items[index].push({ 'uri': item_uri, 'name': name, 'size': !is_dir && (prop = node.querySelector('getcontentlength')) ? parseInt(prop.textContent, 10) : null, 'mime': !is_dir && (prop = node.querySelector('getcontenttype')) ? prop.textContent : null, 'modified': (prop = node.querySelector('getlastmodified')) ? new Date(prop.textContent) : null, 'is_dir': is_dir, + 'permissions': permissions, }); }); - items[0].sort((a, b) => a.name.localeCompare(b.name)); + if (sort_order == 'name') { + items[0].sort((a, b) => a.name.localeCompare(b.name)); + } + items[1].sort((a, b) => { if (sort_order == 'date') { return b.modified - a.modified; @@ -391,8 +415,14 @@ const WebDAVNavigator = (url, options) => { } }); - // Sort with directories first - items = items[0].concat(items[1]); + if (sort_order == 'name') { + // Sort with directories first + items = items[0].concat(items[1]); + } + else { + items = items[1]; + } + var table = ''; var parent = uri.replace(/\/+$/, '').split('/').slice(0, -1).join('/') + '/'; @@ -405,9 +435,15 @@ const WebDAVNavigator = (url, options) => { } items.forEach(item => { + // Don't include files we cannot read + if (item.permissions !== null && item.permissions.indexOf('G') == -1) { + console.error('OC permissions deny read access to this file: ' + item.name, 'Permissions: ', item.permissions); + return; + } + var row = item.is_dir ? dir_row_tpl : file_row_tpl; item.size = item.size !== null ? formatBytes(item.size).replace(/ /g, ' ') : null; - item.icon = item.is_dir ? '📁' : item.uri.replace(/^.*\.(\w+)$/, '$1').toUpperCase(); + item.icon = item.is_dir ? '📁' : (item.uri.indexOf('.') > 0 ? item.uri.replace(/^.*\.(\w+)$/, '$1').toUpperCase() : ''); item.modified = item.modified !== null ? formatDate(item.modified) : null; item.name = html(item.name); table += template(row, item); @@ -416,13 +452,76 @@ const WebDAVNavigator = (url, options) => { document.title = title; document.querySelector('main').innerHTML = template(body_tpl, {'title': html(document.title), 'base_url': base_url, 'table': table}); + var select = $('.sortorder'); + select.value = sort_order; + select.onchange = () => { + sort_order = select.value; + window.localStorage.setItem('sort_order', sort_order); + reloadListing(); + }; + + if (!root_permissions || root_permissions.indexOf('CK') != -1) { + $('.upload').insertAdjacentHTML('afterbegin', create_buttons); + + $('.mkdir').onclick = () => { + openDialog(mkdir_dialog); + document.forms[0].onsubmit = () => { + var name = $('input[name=mkdir]').value; + + if (!name) return false; + + name = encodeURIComponent(name); + + req('MKCOL', current_url + name).then(() => openListing(current_url + name + '/')); + return false; + }; + }; + + $('.mkfile').onclick = () => { + openDialog(mkfile_dialog); + var t = $('input[name=mkfile]'); + t.value = '.md'; + t.focus(); + t.selectionStart = t.selectionEnd = 0; + document.forms[0].onsubmit = () => { + var name = t.value; + + if (!name) return false; + + name = encodeURIComponent(name); + + return reqAndReload('PUT', current_url + name, ''); + }; + }; + + var fi = $('input[type=file]'); + + $('.uploadfile').onclick = () => fi.click(); + + fi.onchange = () => { + if (!fi.files.length) return; + + var body = new Blob(fi.files); + var name = fi.files[0].name; + + name = encodeURIComponent(name); + + return reqAndReload('PUT', current_url + name, body); + }; + } + Array.from($('table').rows).forEach((tr) => { var $$ = (a) => tr.querySelector(a); var file_url = $$('a').href; var file_name = $$('a').innerText; var dir = $$('[colspan]'); var mime = !dir ? tr.getAttribute('data-mime') : 'dir'; - var buttons = $$('td.buttons div') + var buttons = $$('td.buttons div'); + var permissions = tr.getAttribute('data-permissions'); + + if (permissions == 'null') { + permissions = null; + } if (dir) { $$('a').onclick = () => { @@ -435,6 +534,7 @@ const WebDAVNavigator = (url, options) => { if (dir && $$('a').getAttribute('href').length < uri.length) { dir.setAttribute('colspan', 4); tr.querySelector('td:last-child').remove(); + tr.querySelector('td:last-child').remove(); return; } @@ -447,7 +547,43 @@ const WebDAVNavigator = (url, options) => { } // Add rename/delete buttons - buttons.insertAdjacentHTML('afterbegin', common_buttons); + if (!permissions || permissions.indexOf('NV') != -1) { + buttons.insertAdjacentHTML('afterbegin', rename_button); + + $$('.rename').onclick = () => { + openDialog(rename_dialog); + let t = $('input[name=rename]'); + t.value = file_name; + t.focus(); + t.selectionStart = 0; + t.selectionEnd = file_name.lastIndexOf('.'); + document.forms[0].onsubmit = () => { + var name = t.value; + + if (!name) return false; + + name = encodeURIComponent(name); + name = name.replace(/%2F/, '/'); + + var dest = current_url + name; + dest = normalizeURL(dest); + + return reqAndReload('MOVE', file_url, '', {'Destination': dest}); + }; + }; + + } + + if (!permissions || permissions.indexOf('D') != -1) { + buttons.insertAdjacentHTML('afterbegin', delete_button); + + $$('.delete').onclick = (e) => { + openDialog(delete_dialog); + document.forms[0].onsubmit = () => { + return reqAndReload('DELETE', file_url); + }; + }; + } var view_url, edit_url; @@ -485,135 +621,53 @@ const WebDAVNavigator = (url, options) => { $$('a').download = file_name; } - if (mime.match(/^text\/|application\/x-empty/)) { - buttons.insertAdjacentHTML('beforeend', edit_button); + if (!permissions || permissions.indexOf('W') != -1) { + if ( mime.match(/^text\/|application\/x-empty/)) { + buttons.insertAdjacentHTML('beforeend', edit_button); - $$('.edit').onclick = (e) => { - req('GET', file_url).then((r) => r.text().then((t) => { - let md = file_url.match(/\.md$/); - openDialog(md ? markdown_dialog : edit_dialog); - var txt = $('textarea[name=edit]'); - txt.value = t; + $$('.edit').onclick = (e) => { + req('GET', file_url).then((r) => r.text().then((t) => { + let md = file_url.match(/\.md$/); + openDialog(md ? markdown_dialog : edit_dialog); + var txt = $('textarea[name=edit]'); + txt.value = t; - // Markdown editor - if (md) { - let pre = $('#md'); + // Markdown editor + if (md) { + let pre = $('#md'); - txt.oninput = () => { - pre.innerHTML = microdown.parse(html(txt.value)); + txt.oninput = () => { + pre.innerHTML = microdown.parse(html(txt.value)); + }; + + txt.oninput(); + + // Sync scroll, not perfect but better than nothing + txt.onscroll = (e) => { + var p = e.target.scrollTop / (e.target.scrollHeight - e.target.offsetHeight); + var target = e.target == pre ? txt : pre; + target.scrollTop = p * (target.scrollHeight - target.offsetHeight); + e.preventDefault(); + return false; + }; + } + + document.forms[0].onsubmit = () => { + var content = txt.value; + + return reqAndReload('PUT', file_url, content); }; + })); + }; + } + else if (edit_url = wopi_getEditURL(file_url, mime)) { + buttons.insertAdjacentHTML('beforeend', edit_button); - txt.oninput(); - - // Sync scroll, not perfect but better than nothing - txt.onscroll = (e) => { - var p = e.target.scrollTop / (e.target.scrollHeight - e.target.offsetHeight); - var target = e.target == pre ? txt : pre; - target.scrollTop = p * (target.scrollHeight - target.offsetHeight); - e.preventDefault(); - return false; - }; - } - - document.forms[0].onsubmit = () => { - var content = txt.value; - - return reqAndReload('PUT', file_url, content); - }; - })); - }; + $$('.icon').classList.add('document'); + $$('.edit').onclick = () => { wopi_open(file_url, edit_url); return false; }; + } } - else if (edit_url = wopi_getEditURL(file_url, mime)) { - buttons.insertAdjacentHTML('beforeend', edit_button); - - $$('.icon').classList.add('document'); - $$('.edit').onclick = () => { wopi_open(file_url, edit_url); return false; }; - } - - $$('.delete').onclick = (e) => { - openDialog(delete_dialog); - document.forms[0].onsubmit = () => { - return reqAndReload('DELETE', file_url); - }; - }; - - $$('.rename').onclick = () => { - openDialog(rename_dialog); - let t = $('input[name=rename]'); - t.value = file_name; - t.focus(); - t.selectionStart = 0; - t.selectionEnd = file_name.lastIndexOf('.'); - document.forms[0].onsubmit = () => { - var name = t.value; - - if (!name) return false; - - name = encodeURIComponent(name); - name = name.replace(/%2F/, '/'); - - var dest = current_url + name; - dest = normalizeURL(dest); - - return reqAndReload('MOVE', file_url, '', {'Destination': dest}); - }; - }; - }); - - $('.mkdir').onclick = () => { - openDialog(mkdir_dialog); - document.forms[0].onsubmit = () => { - var name = $('input[name=mkdir]').value; - - if (!name) return false; - - name = encodeURIComponent(name); - - req('MKCOL', current_url + name).then(() => openListing(current_url + name + '/')); - return false; - }; - }; - - $('.mkfile').onclick = () => { - openDialog(mkfile_dialog); - var t = $('input[name=mkfile]'); - t.value = '.md'; - t.focus(); - t.selectionStart = t.selectionEnd = 0; - document.forms[0].onsubmit = () => { - var name = t.value; - - if (!name) return false; - - name = encodeURIComponent(name); - - return reqAndReload('PUT', current_url + name, ''); - }; - }; - - var select = $('.sortorder'); - select.value = sort_order; - select.onchange = () => { - sort_order = select.value; - window.localStorage.setItem('sort_order', sort_order); - reloadListing(); - }; - - var fi = $('input[type=file]'); - - $('.uploadfile').onclick = () => fi.click(); - - fi.onchange = () => { - if (!fi.files.length) return; - - var body = new Blob(fi.files); - var name = fi.files[0].name; - - name = encodeURIComponent(name); - - return reqAndReload('PUT', current_url + name, body); - }; }; var current_url = url;