diff options
author | Dieter Plaetinck <dieter@plaetinck.be> | 2010-04-11 13:34:13 +0200 |
---|---|---|
committer | Dieter Plaetinck <dieter@plaetinck.be> | 2010-04-11 13:34:13 +0200 |
commit | ef94d5c22e84d6a591cf02aa6b787747f40b55ca (patch) | |
tree | 901f472ca668309e90826b083d1e6e2b3082d3fb | |
parent | 6bd1c652d31ae4152479b7b447bde61357fe79a1 (diff) | |
parent | 47c12001920a79d860a67a0235ca43ba0a45dcee (diff) |
merge in formfiller updates
-rw-r--r-- | AUTHORS | 2 | ||||
-rwxr-xr-x | examples/data/scripts/formfiller.sh | 175 |
2 files changed, 128 insertions, 49 deletions
@@ -58,7 +58,7 @@ In alphabetical order: Nicolas Pouillard - refactored scroll command Olivier Schwander - auto file:// prepend Paul Tomak - formfiller.sh script, uzbl vim syntax - Paweł Zuzelski (pawelz) - http auth handler, misc patches + Paweł Zuzelski (pawelz) <pawelz@pld-linux.org> - http auth handler, misc patches Peter Suschlik - backwards searching Přemysl Hrubý (anydot) <email is dfenze AT gmail.com> - several C contributions and cleanups Robert Manea (robm) <email is rob DOT manea AT gmail DOT com> - C code all over the place diff --git a/examples/data/scripts/formfiller.sh b/examples/data/scripts/formfiller.sh index 1408006..69eca17 100755 --- a/examples/data/scripts/formfiller.sh +++ b/examples/data/scripts/formfiller.sh @@ -5,16 +5,37 @@ # uses settings files like: $keydir/<domain> # files contain lines like: !profile=<profile_name> # <fieldname>(fieldtype): <value> -# profile_name should be replaced with a name that will tell sth about that profile -# fieldtype can be text or password - only for information pupropse (auto-generated) - don't change that +# profile_name should be replaced with a name that will tell sth about that +# profile +# fieldtype can be checkbox, text or password, textarea - only for information +# pupropse (auto-generated) - don't change that +# +# Texteares: for textareas edited text can be now splitted into more lines. +# If there will be text, that doesn't match key line: +# <fieldname>(fieldtype):<value> +# then it will be considered as a multiline for the first field above it +# Keep in mind, that if you make more than one line for fileds like input +# text fields, then all lines will be inserted into as one line +# +# Checkboxes/radio-buttons: to uncheck it type on of the following after the +# colon: +# no +# off +# 0 +# unchecked +# false +# or leave it blank, even without spaces +# otherwise it will be considered as checked # # user arg 1: # edit: force editing the file (falls back to new if not found) # new: start with a new file. # load: try to load from file into form # add: try to add another profile to an existing file +# once: edit form using external editor # # something else (or empty): if file not available: new, otherwise load. +# # config dmenu colors and prompt NB="#0f0f0f" @@ -30,15 +51,16 @@ else fi PROMPT="Choose profile" +MODELINE="> vim:ft=formfiller" keydir=${XDG_DATA_HOME:-$HOME/.local/share}/uzbl/dforms [ -d "`dirname $keydir`" ] || exit 1 [ -d "$keydir" ] || mkdir "$keydir" -editor=${VISUAL} -if [ -z ${editor} ]; then - if [ -z ${EDITOR} ]; then +editor="${VISUAL}" +if [ -z "${editor}" ]; then + if [ -z "${EDITOR}" ]; then editor='xterm -e vim' else editor="xterm -e ${EDITOR}" @@ -69,11 +91,67 @@ if [ "$action" != 'edit' -a "$action" != 'new' -a "$action" != 'load' -a "$acti then action="new" [ -e "$keydir/$domain" ] && action="load" -elif [ "$action" == 'edit' ] && [ ! -e "$keydir/$domain" ] +elif [ "$action" = 'edit' ] && [ ! -e "$keydir/$domain" ] then action="new" fi +dumpFunction="function dump() { \ + var rv=''; \ + var allFrames = new Array(window); \ + for(f=0;f<window.frames.length;f=f+1) { \ + allFrames.push(window.frames[f]); \ + } \ + for(j=0;j<allFrames.length;j=j+1) { \ + try { \ + var xp_res=allFrames[j].document.evaluate('//input', allFrames[j].document.documentElement, null, XPathResult.ANY_TYPE,null); \ + var input; \ + while(input=xp_res.iterateNext()) { \ + var type=(input.type?input.type:text); \ + if(type == 'text' || type == 'password' || type == 'search') { \ + rv += input.name + '(' + type + '):' + input.value + '\\\\n'; \ + } \ + else if(type == 'checkbox' || type == 'radio') { \ + rv += input.name + '{' + input.value + '}(' + type + '):' + (input.checked?'ON':'OFF') + '\\\\n'; \ + } \ + } \ + xp_res=allFrames[j].document.evaluate('//textarea', allFrames[j].document.documentElement, null, XPathResult.ANY_TYPE,null); \ + var input; \ + while(input=xp_res.iterateNext()) { \ + rv += input.name + '(textarea):' + input.value + '\\\\n'; \ + } \ + } \ + catch(err) { } \ + } \ + return rv; \ +}; " + +insertFunction="function insert(fname, ftype, fvalue, fchecked) { \ + var allFrames = new Array(window); \ + for(f=0;f<window.frames.length;f=f+1) { \ + allFrames.push(window.frames[f]); \ + } \ + for(j=0;j<allFrames.length;j=j+1) { \ + try { \ + if(ftype == 'text' || ftype == 'password' || ftype == 'search' || ftype == 'textarea') { \ + allFrames[j].document.getElementsByName(fname)[0].value = fvalue; \ + } \ + else if(ftype == 'checkbox') { \ + allFrames[j].document.getElementsByName(fname)[0].checked = fchecked;\ + } \ + else if(ftype == 'radio') { \ + var radios = allFrames[j].document.getElementsByName(fname); \ + for(r=0;r<radios.length;r+=1) { \ + if(radios[r].value == fvalue) { \ + radios[r].checked = fchecked; \ + } \ + } \ + } \ + } \ + catch(err) { } \ + } \ +}; " + if [ "$action" = 'load' ] then [ -e $keydir/$domain ] || exit 2 @@ -84,45 +162,55 @@ then option=`echo -e -n "$menu"| dmenu ${LINES} -nb "${NB}" -nf "${NF}" -sb "${SB}" -sf "${SF}" -p "${PROMPT}"` fi - cat $keydir/$domain | \ - sed -n -e "/^!profile=${option}/,/^!profile=/p" | \ - sed -n -e 's/\([^(]\+\)([^)]\+):[ ]*\(.\+\)$/js if(window.frames.length > 0) { for(i=0;i<window.frames.length;i=i+1) { try { var e = window.frames[i].document.getElementsByName("\1"); if(e.length > 0) { e[0].value="\2"; } } catch(err) { } } }; document.getElementsByName("\1")[0].value="\2"/p' | \ - sed -e 's/@/\\@/g' >> $fifo + # Remove comments + sed '/^>/d' -i $tmpfile + + sed 's/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):\(off\|no\|false\|unchecked\|0\|$\)/\1{\2}(\3):0/I;s/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[^0]\+/\1{\2}(\3):1/I' -i $keydir/$domain + fields=`cat $keydir/$domain | \ + sed -n "/^!profile=${option}/,/^!profile=/p" | \ + sed '/^!profile=/d' | \ + sed 's/^\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):/%{>\1\2):<}%/' | \ + sed 's/^\(.\+\)$/<{br}>\1/' | \ + tr -d '\n' | \ + sed 's/<{br}>%{>\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):<}%/\\n\1\2):/g'` + printf '%s\n' "${fields}" | \ + sed -n -e "s/\([^(]\+\)(\(password\|text\|search\|textarea\)\+):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\2', '\3', 0);/p" | \ + sed -e 's/@/\\@/g;s/<{br}>/\\\\n/g' > $fifo + printf '%s\n' "${fields}" | \ + sed -n -e "s/\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\3', '\2', \4);/p" | \ + sed -e 's/@/\\@/g' > $fifo elif [ "$action" = "once" ] then tmpfile=`mktemp` - html=`echo 'js if(window.frames.length > 0) { for(j=0;j<window.frames.length;j=j+1) { try { window.frames[j].document.documentElement.outerHTML; } catch(err) { } } }' | \ - socat - unix-connect:$socket` - html=${html}" "`echo 'js document.documentElement.outerHTML' | \ - socat - unix-connect:$socket` - html=`echo ${html} | \ - tr -d '\n' | \ - sed 's/>/>\n/g' | \ - sed 's/<input/<input type="text"/g' | \ - sed 's/type="text"\(.*\)type="\([^"]\+\)"/type="\2" \1 /g'` - echo "${html}" | \ - sed -n 's/.*\(<input[^>]\+>\).*/\1/;/type="\(password\|text\)"/Ip' | \ - sed 's/\(.*\)\(type="[^"]\+"\)\(.*\)\(name="[^"]\+"\)\(.*\)/\1\4\3\2\5/I' | \ - sed 's/.*name="\([^"]\+\)".*type="\([^"]\+\)".*/\1(\2):/I' >> $tmpfile - echo "${html}" | \ - sed -n 's/.*<textarea.*name="\([^"]\+\)".*/\1(textarea):/Ip' >> $tmpfile + printf 'js %s dump(); \n' "$dumpFunction" | \ + socat - unix-connect:$socket | \ + sed -n '/^[^(]\+([^)]\+):/p' > $tmpfile + echo "$MODELINE" >> $tmpfile ${editor} $tmpfile [ -e $tmpfile ] || exit 2 - cat $tmpfile | \ - sed -n -e 's/\([^(]\+\)([^)]\+):[ ]*\(.\+\)/js if(window.frames.length > 0) { for(i=0;i<window.frames.length;i=i+1) { try { var e = window.frames[i].document.getElementsByName("\1"); if(e.length > 0) { e[0].value="\2" } } catch(err) { } } }; document.getElementsByName("\1")[0].value="\2"/p' | \ - sed -e 's/@/\\@/g' >> $fifo + # Remove comments + sed '/^>/d' -i $tmpfile + + sed 's/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):\(off\|no\|false\|unchecked\|0\|$\)/\1{\2}(\3):0/I;s/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[^0]\+/\1{\2}(\3):1/I' -i $tmpfile + fields=`cat $tmpfile | \ + sed 's/^\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):/%{>\1\2):<}%/' | \ + sed 's/^\(.\+\)$/<{br}>\1/' | \ + tr -d '\n' | \ + sed 's/<{br}>%{>\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):<}%/\\n\1\2):/g'` + printf '%s\n' "${fields}" | \ + sed -n -e "s/\([^(]\+\)(\(password\|text\|search\|textarea\)\+):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\2', '\3', 0);/p" | \ + sed -e 's/@/\\@/g;s/<{br}>/\\\\n/g' > $fifo + printf '%s\n' "${fields}" | \ + sed -n -e "s/\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\3', '\2', \4);/p" | \ + sed -e 's/@/\\@/g' > $fifo rm -f $tmpfile else - if [ "$action" == 'new' -o "$action" == 'add' ] + if [ "$action" = 'new' -o "$action" = 'add' ] then - if [ "$action" == 'new' ] - then - echo "!profile=NAME_THIS_PROFILE$RANDOM" > $keydir/$domain - else - echo "!profile=NAME_THIS_PROFILE$RANDOM" >> $keydir/$domain - fi + [ "$action" = 'new' ] && echo "$MODELINE" > $keydir/$domain + echo "!profile=NAME_THIS_PROFILE$RANDOM" >> $keydir/$domain # # 2. and 3. line (tr -d and sed) are because, on gmail login for example, # <input > tag is splited into lines @@ -131,7 +219,7 @@ else # type="text" # value=""> # So, tr removes all new lines, and sed inserts new line after each > - # Next sed selects only <input> tags and only with type == "text" or == "password" + # Next sed selects only <input> tags and only with type = "text" or = "password" # If type is first and name is second, then another sed will change their order # so the last sed will make output # text_from_the_name_attr(text or password): @@ -139,18 +227,9 @@ else # login(text): # passwd(password): # - html=`echo 'js if(window.frames.length > 0) { for(i=0;i<window.frames.length;i=i+1) { try { window.frames[i].document.documentElement.outerHTML; } catch(err) { } } }' | \ - socat - unix-connect:$socket` - html=${html}" "`echo 'js document.documentElement.outerHTML' | \ - socat - unix-connect:$socket` - echo ${html} | \ - tr -d '\n' | \ - sed 's/>/>\n/g' | \ - sed 's/<input/<input type="text"/g' | \ - sed 's/type="text"\(.*\)type="\([^"]\+\)"/type="\2" \1 /g' | \ - sed -n 's/.*\(<input[^>]\+>\).*/\1/;/type="\(password\|text\)"/Ip' | \ - sed 's/\(.*\)\(type="[^"]\+"\)\(.*\)\(name="[^"]\+"\)\(.*\)/\1\4\3\2\5/I' | \ - sed 's/.*name="\([^"]\+\)".*type="\([^"]\+\)".*/\1(\2):/I' >> $keydir/$domain + printf 'js %s dump(); \n' "$dumpFunction" | \ + socat - unix-connect:$socket | \ + sed -n '/^[^(]\+([^)]\+):/p' >> $keydir/$domain fi [ -e "$keydir/$domain" ] || exit 3 #this should never happen, but you never know. $editor "$keydir/$domain" #TODO: if user aborts save in editor, the file is already overwritten |