s4
changeset 837:a6462eea48be
Multiple files upload for tablets added and file renaming fixed
author | HIROSE Yuuji <yuuji@gentei.org> |
---|---|
date | Thu, 25 Jun 2020 15:50:16 +0900 |
parents | b3516ee2bb4d |
children | 985ee9a09783 |
files | examples/common/default/default.css s4-blog.sh s4-cgi.sh s4-funcs.sh s4-main.js |
diffstat | 5 files changed, 95 insertions(+), 23 deletions(-) [+] |
line diff
1.1 --- a/examples/common/default/default.css Tue Jun 23 12:58:31 2020 +0900 1.2 +++ b/examples/common/default/default.css Thu Jun 25 15:50:16 2020 +0900 1.3 @@ -55,6 +55,7 @@ 1.4 input[type="radio"][value="replace"]:checked + input.replace[type="file"] { 1.5 visibility: visible; 1.6 } 1.7 +button#morefile {visibility: hidden; background: #fe9;} 1.8 label.admin span {border-bottom: 1px solid blue;} 1.9 label.admin:after {content: "(ADMIN)"; color: red; text-decoration: none;} 1.10
2.1 --- a/s4-blog.sh Tue Jun 23 12:58:31 2020 +0900 2.2 +++ b/s4-blog.sh Thu Jun 25 15:50:16 2020 +0900 2.3 @@ -565,18 +565,21 @@ 2.4 filehelp="《添付の注意》 2.5 $file_accept_help" 2.6 ntmode="通知モード=$blog_notify${blog_team:+ (team=$blog_team)}" 2.7 - textform='<div class="fold"> 2.8 + textform=$(cat<<-EOF 2.9 +<div class="fold"> 2.10 <input type="checkbox" id="cmt" checked><label 2.11 accesskey="c" title="C" for="cmt">コメントする</label><div> 2.12 <table class="b"> 2.13 -<tr><td><textarea id="text" name="text" cols="72" rows="4" title="'"$help"'"> 2.14 -</textarea>'"$touchhelp</td></tr> 2.15 -<tr><td>添付ファイル(${filesize_max_MB}以下):"' 2.16 -<input type="file" name="image"'" $file_accept title=\"$filehelp\" multiple></td></tr>"' 2.17 +<tr><td><textarea id="text" name="text" cols="72" rows="4" title="$help"> 2.18 +</textarea>$touchhelp</td></tr> 2.19 +<tr><td>添付ファイル(${filesize_max_MB}以下): 2.20 +`cgi_file image "" "$file_accept title=\"$filehelp\" multiple"` 2.21 +</td></tr> 2.22 </table> 2.23 -<input type="submit" value="送信"'" class=\"$blog_notify\" title=\"$ntmode\""'> 2.24 +<input type="submit" value="送信" class="$blog_notify" title="$ntmode"> 2.25 <input type="reset" value="リセット"></div></div> 2.26 -' 2.27 +EOF 2.28 + ) 2.29 cat<<-EOF 2.30 </table> <!-- end of s4-blog:blog_showentry() main table --> 2.31 <p class="update_link"><a
3.1 --- a/s4-cgi.sh Tue Jun 23 12:58:31 2020 +0900 3.2 +++ b/s4-cgi.sh Thu Jun 25 15:50:16 2020 +0900 3.3 @@ -57,6 +57,12 @@ 3.4 # $1=name $2=val(as filename) $3=args(if any) 3.5 ## err cgi_file: \$1=$1 \$2=$2 \$3="[$3]" 3.6 # Using global variable $dir 3.7 + case "$3" in 3.8 + *multiple*) 3.9 + onemore='<button type="button" id="morefile" title="More attachment file">添付追加</button>' 3.10 + multiple="$nl$onemore" 3.11 + ;; 3.12 + esac 3.13 if [ -n "$2" -a -s "$dir/$2" ]; then 3.14 file=$dir/$2 3.15 bn=${file##*/} 3.16 @@ -66,13 +72,14 @@ 3.17 fi 3.18 cat<<EOF 3.19 ${icon} 3.20 -<input type="file" name="$1" value="$bn" $3> 3.21 +<input type="file" name="$1" value="$bn" $3>$multiple 3.22 EOF 3.23 ) 3.24 cgi_multi() ( 3.25 # $1=name $2=dir $3=func $4=args... 3.26 # `dir' should contain $name.count and $name.N where N is 1 upto N 3.27 i=1 name=$1 dir=$2 func=$3 3.28 + argnomulti=`echo "$4"|sed 's/multiple//'` # No multiple for Replaced entres 3.29 n=`cat $dir/$name.count` 3.30 case "$func" in 3.31 *file) addrename=yes ;; 3.32 @@ -82,21 +89,26 @@ 3.33 file=$name.$i 3.34 vname=$file.`cat "$dir/$file.rowid"` 3.35 val="`cat $dir/$file`" 3.36 + if [ -n "$addrename" ]; then 3.37 + # ${var:+..} cannot be used for inside-quotes incompatibility of shells 3.38 + ren1="<input class=\"action\" type=\"radio\" name=\"action.$vname\" 3.39 + id=\"mv.$vname\" value=\"mv\"><label for=\"mv.$vname\" 3.40 + title=\"Rename\">名前変更</label>" 3.41 + ren2="<input class=\"mv\" type=\"text\" name=\"mv.$vname\" value=\"$val\">" 3.42 + fi 3.43 cat<<EOF 3.44 <tr><td>($i)</td><td> 3.45 <input class="action" type="radio" name="action.$vname" id="keep.$vname" 3.46 value="keep"><label for="keep.$vname" title="Keep">温存</label> 3.47 <input class="action" type="radio" name="action.$vname" id="edit.$vname" 3.48 value="edit"><label for="edit.$vname" title="Replace">修正</label> 3.49 -${addrename:+<input class="action" type="radio" name="action.$vname" 3.50 - id="mv.$vname" value="mv"><label for="mv.$vname" 3.51 - title="Rename">名前変更</label>} 3.52 +$ren1 3.53 <input class="action" type="radio" name="action.$vname" id="rm.$vname" 3.54 value="rm"><label for="rm.$vname" title="Remove">削除</label> 3.55 <label class="confirm" title="OK?">本当に消します<input class="confirm" type="checkbox" 3.56 name="confirm.$vname" value="yes">はい</label><br> 3.57 -`$func $vname "$val" "$4"`<span>$val</span> 3.58 -${addrename:+<input class="mv" type="text" name="mv.$vname" value="$val">} 3.59 +`$func $vname "$val" "$argnomulti"`<span>$val</span> 3.60 +$ren2 3.61 </td></tr> 3.62 EOF 3.63 i=$((i+1))
4.1 --- a/s4-funcs.sh Tue Jun 23 12:58:31 2020 +0900 4.2 +++ b/s4-funcs.sh Thu Jun 25 15:50:16 2020 +0900 4.3 @@ -63,7 +63,7 @@ 4.4 filesize_max=$((5*1024*1024)) 4.5 filesize_max_MB="$((filesize_max/1024/1024))MB" 4.6 file_accept='accept="image/*,text/*,audio/*,application/vnd.oasis.*,application/pdf,application/x-*"' 4.7 -file_accept='accept=".jpg,.jpeg,.gif,.png,.tiff,.pdf,.odt,.ods,.odp,.odg,.mp3,.mp4,.avi,.ogg,.mov,.webm,.gpx,.json,.geojson,.kml,.html,.css,.rb,.c,.txt,.zip,.xcf,.bz2,.gz,.xz,.7z,.csv,.dat"' 4.8 +file_accept='accept=".jpg,.jpeg,.gif,.png,.tiff,.pdf,.odt,.ods,.odp,.odg,.mp3,.mp4,.avi,.ogg,.mov,.webm,.gpx,.json,.geojson,.kml,.html,.css,.rb,.c,.h,.txt,.tex,.sty,.zip,.xcf,.bz2,.gz,.xz,.7z,.csv,.dat"' 4.9 file_accept_egrep='^(text/|message/|image/|audio/|video/|application/(vnd.oasis|pdf|epub|xml|zip|[xz]-))' 4.10 file_accept_help=" 4.11 添付可能ファイル: テキスト、画像、音声、動画、ODF、PDF、 4.12 @@ -2941,7 +2941,7 @@ 4.13 fi 4.14 subj=`getpar subject` 4.15 afiles="" 4.16 - for fn in `query "SELECT DISTINCT val FROM par WHERE var='files' AND sessid='$session';"` 4.17 + for fn in `query "SELECT DISTINCT val FROM par WHERE var='image' AND sessid='$session';"` 4.18 do 4.19 f=$tmpd/$fn 4.20 if [ -s $f ]; then 4.21 @@ -3144,7 +3144,7 @@ 4.22 <tr><td>Subject: </td><td>`cgi_text subject`</td></tr> 4.23 <tr><td>追加宛先(通常空欄): </td><td>`cgi_text supprcpt ""`</td></tr> 4.24 <tr><td>ファイル添付: </td> 4.25 - <td>`cgi_file files "" "multiple $file_accept title=\"$file_accept_help\""`<br><small>文書ファイルはPDFに変換してから</small></td></tr> 4.26 + <td>`cgi_file image "" "multiple $file_accept title=\"$file_accept_help\""`<br><small>文書ファイルはPDFに変換してから</small></td></tr> 4.27 </table> 4.28 <p>(下記一覧から1人以上選択していない場合は送れません`cgi_submit 確認後送信`)</p> 4.29 </div> 4.30 @@ -3822,6 +3822,16 @@ 4.31 DELETE FROM article WHERE id IN (SELECT id FROM orphanedarticle); 4.32 EOF 4.33 } 4.34 + 4.35 +clearcachedir() ( 4.36 + td=`getcachedir "$1"` 4.37 + err td=$td: ls- `ls $td` 4.38 + if [ -w "$td/image.1" ]; then 4.39 + err Removing td=$td 4.40 + rm -fr $td/ # Clear icon-image cache! 4.41 + fi 4.42 +) 4.43 + 4.44 par2table() ( 4.45 # copy current parameters of par into destination table 4.46 # $1=definition-file 4.47 @@ -3876,6 +3886,7 @@ 4.48 if [ x"$rm" = x"yes" ]; then 4.49 if [ x"$rm$cfm" = x"yesyes" ]; then 4.50 query "delete from $tbl where rowid=$rowid;" 4.51 + clearcachedir "$tbl/$rowid" 4.52 if [ x"$tbl" = x"grp" -o x"$tbl" = x"blog" ]; then 4.53 clean-orphaned 4.54 fi 4.55 @@ -4022,17 +4033,18 @@ 4.56 # regularize filename and strip directory part 4.57 newname=`getpar mv.$v|tr -d '":;#<>?^%$!'|tr -d "'"|tr ' ' _` 4.58 newname=`basename $newname` 4.59 - err "newname($v)=$newname" 4.60 - newext="${newname##*.}" 4.61 - if test x"$newname" != x"$newext" \ 4.62 - && echo "${file_accept#*=}" \ 4.63 - | fgrep -w "$newext" >/dev/null 1>&2 4.64 + oldname=`query "SELECT val FROM $tb2 WHERE rowid=$st_rowid;"` 4.65 + oldext=`expr "$oldname" : '.*\.\(.*\)'` 4.66 + newext=`expr "$newname" : '.*\.\(.*\)'` 4.67 + err "p2t(mv): oldname=$oldname $oldext -> newname($v)=$newname $newext" 4.68 + if [ -n "$newname" -a x"$oldext" = x"$newext" ]; 4.69 then 4.70 newsql="UPDATE $tb2 SET val='$newname'" 4.71 else 4.72 html p<<-EOF 4.73 $newname は取り扱えないファイル名です。 4.74 - 空白を含まない名前で拡張子を正しくつけて下さい。 4.75 + 空白を含まない名前にして下さい。 4.76 + 拡張子の変更もできません。 4.77 EOF 4.78 continue 4.79 fi 4.80 @@ -4043,6 +4055,7 @@ 4.81 esac 4.82 # err newsql=$newsql 4.83 sql=$sql$nl"$newsql where rowid=$st_rowid;" 4.84 + clearcachedir "$tbl/$rowid" 4.85 done 4.86 4.87 if [ x"$bin" = x"NULL" ]; then 4.88 @@ -4082,6 +4095,7 @@ 4.89 ## err $col=$val 4.90 bin=NULL 4.91 ## err partype$col=`getpartype $col "$limit"` 4.92 + ptype=`getpartype $col "$limit"` # partype should be obtained each time 4.93 case $ptype in 4.94 file) file=$tmpd/`getparfilename $col "$limit"` 4.95 ## err parfile-$col=$file
5.1 --- a/s4-main.js Tue Jun 23 12:58:31 2020 +0900 5.2 +++ b/s4-main.js Thu Jun 25 15:50:16 2020 +0900 5.3 @@ -72,8 +72,49 @@ 5.4 u.checked = !u.checked; 5.5 } 5.6 } 5.7 + function addFileInput() { 5.8 + var inpfile = collectElementsByAttr("input", "name", "image"); 5.9 + if (!inpfile) return; 5.10 + var filled = true; 5.11 + var i, ih; 5.12 + for (i of inpfile) { 5.13 + if (! i.value) filled=false; 5.14 + } 5.15 + if (filled) { 5.16 + ih = i.parentNode.innerHTML; 5.17 + if (ih) { 5.18 + var inpf = ih.substring(ih.indexOf("<input")), 5.19 + newi = "<br>"+inpf.substring(0, inpf.indexOf(">")+1); 5.20 + i.insertAdjacentHTML("afterend", newi) 5.21 + // alert(newi); 5.22 + } 5.23 + } 5.24 + } 5.25 + function initFileInput() { // Multiplies "input type=file" 5.26 + var el, morefile = document.getElementById("morefile"); 5.27 + if (morefile) { 5.28 + for (el of collectElementsByAttr("input", "name", "image")) { 5.29 + el.addEventListener("change", function(ev) { 5.30 + if (ev.target.value > "" && ev.target.files.length == 1) 5.31 + morefile.style.visibility = "visible"; 5.32 + // No need to hide again, sure? 5.33 + }); 5.34 + } 5.35 + morefile.addEventListener("click", addFileInput, null); 5.36 + } 5.37 + // When renaming, select basename part 5.38 + for (el of collectElementsByAttr("input", "class", "mv")) { 5.39 + el.addEventListener("focus", function(ev) { 5.40 + var i = ev.target; 5.41 + if (i) { 5.42 + i.setSelectionRange(0, i.value.lastIndexOf(".")); 5.43 + } 5.44 + }); 5.45 + } 5.46 + } 5.47 function initBlogs() { 5.48 - var el, check = collectElementsByAttr("input", "name", "notifyto"); 5.49 + // Auto-complete #xxxx 5.50 + var check = collectElementsByAttr("input", "name", "notifyto"); 5.51 if (check) 5.52 for (let i of check) { 5.53 i.addEventListener("click", insertRedirect, null); 5.54 @@ -138,6 +179,7 @@ 5.55 function init() { 5.56 initGrpAction(); 5.57 initBlogs(); 5.58 + initFileInput(); 5.59 } 5.60 document.addEventListener('DOMContentLoaded', init, null); 5.61 })();