df-listdirs-patch v2 #41

Closed
df wants to merge 5 commits from df/webif:df-listdirs-patch into master
3 changed files with 122 additions and 19 deletions

View File

@ -58,6 +58,10 @@ proc icon {img {hover ""} {extra ""} {class "va"}} {
puts ">"
}
proc nbsp {str} {
return [string map {" "  } $str]
}
proc directory {file bfile tbfile} {
puts "<div class=\"va relative\">"
set img "/images/711_1_09_Media_Folder.png"
@ -69,7 +73,7 @@ proc directory {file bfile tbfile} {
puts "<a class=dbf
href=\"$::env(SCRIPT_NAME)?dir=[cgi_quote_url $file]\"
file=\"[cgi_quote_html $file]\">"
puts "$bfile</a><span class=filesize id=\"$tbfile\">
puts "[nbsp $bfile]</a><span class=filesize id=\"ID$tbfile\">
</span>"
lassign [dir iconset $file] icons attrs
@ -106,13 +110,12 @@ proc entry {file} {{i 0}} {
global dircount filecount dinuse
set bfile [file tail $file]
regsub -all " +" $bfile "" tbfile
if {[string index $bfile 0] == "\025"} {
set bfile [string range $bfile 1 end]
}
if {[file isdirectory "$file"]} {
incr dircount
directory $file $bfile $tbfile
directory $file $bfile [b64uencode [jsescape $bfile]]
return
}
set ext [string tolower [file extension $file]]
@ -174,7 +177,7 @@ proc entry {file} {{i 0}} {
<input class=\"$fscl\" type=checkbox>
<a class=bf title=\"$synopsis\"
file=\"[cgi_quote_html $file]\" type=$type href=#>
$bfile
[nbsp $bfile]
</a>
"

View File

@ -10,6 +10,18 @@ var plugins = {
dmenu_prepare: {}
};
// pattern matches directory path prefix
var pathre = /.*\/|\.[^.]*$/g;
// IDs of size, img, etc elements for folders use RFC4648 s5 encoding of folder name
function folderID(folder) {
return btoa(escape(folder))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
}
function blockpage(msg)
{
if (!msg)
@ -111,17 +123,14 @@ function epginfo_callback(data, status, xhr)
function insert_folder_size(folder, size)
{
folder = folder.replace(/ /g, '');
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
//console.log("Folder: (%s) = (%s)", folder, size);
if (size.search(/\d$/) == -1)
size += 'iB';
else
size += ' bytes';
if (folder == "")
$('#dirsize').text(' (' + size + ')');
else
$('#' + folder).text(' (' + size + ')');
folder = folderID(folder);
//console.log("Folder: (%s) = (%s)", folder, size);
$(folder == "" ? '#dirsize': '#ID' + folder)
.text(' (' + size + ')');
}
function folder_size_callback(data, status, xhr)
@ -133,11 +142,9 @@ function folder_size_callback(data, status, xhr)
function set_folder_new(folder, cnt)
{
folder = folder.replace(/ /g, '');
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
//console.log("Folder: (%s) = (%s)", folder, cnt);
left = cnt > 99 ? 11 : (cnt > 9 ? 14 : 17);
$('#img' + folder)
$('#img' + folderID(folder))
.attr('src', '/img/Folder_New.png')
.next('span.foldernum')
.css('left', left + 'px')
@ -156,10 +163,8 @@ function new_folder_callback(data, status, xhr)
function set_folder__(folder)
{
folder = folder.replace(/ /g, '');
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
//console.log("Folder: (%s)", folder);
$('#img' + folder + ' ~ span.folderu').show();
$('#img' + folderID(folder) + ' ~ span.folderu').show();
}
function __folder_callback(data, status, xhr)
@ -256,7 +261,7 @@ var $confirm; // Populated after DOM is loaded.
function confirm_action(action, callback, file, type, id)
{
var bfile = file.replace(/.*\/|\.[^.]*$/g, '');
var bfile = file.replace(pathre, '');
$confirm.dialog('option', 'buttons', {
'Yes': function() { $(this).dialog('close');
callback(file, type, id); },
@ -429,7 +434,7 @@ var menuclick = function(action, el, pos)
{
var file = $(el).parent().prevAll('a.bf').last().attr('file');
var efile = encodeURIComponent(file);
var bfile = file.replace(/.*\/|\.[^.]*$/g, '');
var bfile = file.replace(pathre, '');
bfile = bfile.replace(/[\x00-\x1f]+/g, '');
var type = $(el).attr('type');
var id = $(el).attr('did');

View File

@ -20,3 +20,98 @@ proc midnight {} {{today ""}} {
return [clock scan "$today 00:00:00" -format "%Y %m %d %T"]
}
# Base-64 according to RFC 4648
# See https://wiki.tcl-lang.org/page/base64
if {![exists -command binary]} { package require binary }
# RFC 4648 section 4
set ::b64::map {
000000 A 000001 B 000010 C 000011 D 000100 E 000101 F
000110 G 000111 H 001000 I 001001 J 001010 K 001011 L
001100 M 001101 N 001110 O 001111 P 010000 Q 010001 R
010010 S 010011 T 010100 U 010101 V 010110 W 010111 X
011000 Y 011001 Z 011010 a 011011 b 011100 c 011101 d
011110 e 011111 f 100000 g 100001 h 100010 i 100011 j
100100 k 100101 l 100110 m 100111 n 101000 o 101001 p
101010 q 101011 r 101100 s 101101 t 101110 u 101111 v
110000 w 110001 x 110010 y 110011 z 110100 0 110101 1
110110 2 110111 3 111000 4 111001 5 111010 6 111011 7
111100 8 111101 9 111110 + 111111 /
}
set ::b64::unmap [join [lmap {a b} $::b64::map {list $b $a}]]
proc ::b64::encode {str} {
binary scan $str B* bits
switch [expr {[string length $bits]%6}] {
0 {set tail {}}
2 {append bits 0000; set tail ==}
4 {append bits 00; set tail =}
}
return [string cat [string map $::b64::map $bits] $tail]
}
proc ::b64::decode {str} {
set nstr [string trimright $str =]
set dstr [string map $::b64::unmap $nstr]
switch [expr [string length $str]-[string length $nstr]] {
0 {#nothing to do}
1 {set dstr [string range $dstr 0 {end-2}]}
2 {set dstr [string range $dstr 0 {end-4}]}
}
return [binary format B* $dstr]
}
# RFC 4648 section 5
proc ::b64::url_encode {str} {
tailcall string map {+ - / _ = ""} [::b64::encode $str]
}
proc ::b64::url_decode {str} {
tailcall ::b64::decode [string map {- + _ /} $str]
}
alias b64encode ::b64::encode
alias b64decode ::b64::decode
alias b64uencode ::b64::url_encode
alias b64udecode ::b64::url_decode
# ECMA-262 Annex B.2.1
proc ::js::_escape {str} {
return [join [lmap c [split $str ""] {
if {1 != [scan $c "%c" cc]} {
format "%s" $c
} elseif {$cc < 256} {
format "%%%02X" $cc
} else {
format "%%u%04X" $cc
}
}] ""]
}
proc ::js::_unescape {str} {
if {1 == [scan $str "%%%2x" cc] ||
1 == [scan $str "%%u%4x" cc]} {
return [format "%c" $cc]
} else {
return $str
}
}
proc ::js::escape {str} {
return [subst -nobackslashes -novariables \
[regsub -all -- {[^A-Za-z0-9@*_+-./]+} $str \
{[::js::_escape {&}]}]]
}
proc ::js::unescape {str} {
return [subst -nobackslashes -novariables \
[regsub -all -- {%(u[[:xdigit:]]{2})?[[:xdigit:]]{2}} $str \
{[::js::_unescape {&}]}]]
}
alias jsescape ::js::escape
alias jsunescape ::js::unescape