From 0f1bbed6b9e31e32a7ef41843afeab6acb146f79 Mon Sep 17 00:00:00 2001 From: hummypkg Date: Fri, 21 Feb 2014 21:25:33 +0000 Subject: [PATCH] migrating git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1789 2a923420-c742-0410-a762-8d5b09965624 --- var/mongoose/cgi-bin/epg/info.jim | 2 +- var/mongoose/cgi-bin/epg/search.jim | 10 +- var/mongoose/cgi-bin/epg/service.jim | 133 -- var/mongoose/cgi-bin/restart.jim | 3 +- var/mongoose/cgi-bin/settings.jim | 32 +- var/mongoose/cgi-bin/xepg.jim | 20 +- var/mongoose/html/browse/audio/audio.jim | 6 +- var/mongoose/html/browse/chunk/chunk.jim | 6 +- var/mongoose/html/browse/crop/crop.jim | 6 +- var/mongoose/html/browse/decrypt/decrypt.jim | 5 +- var/mongoose/html/browse/index.jim | 12 +- var/mongoose/html/browse/join/join.jim | 8 +- var/mongoose/html/browse/mpg/mpg.jim | 5 +- var/mongoose/html/browse/strip/strip.jim | 6 +- var/mongoose/html/browse/thumbnail/index.jim | 4 +- var/mongoose/html/dedup/dedup.jim | 2 +- var/mongoose/html/diag/diag.jim | 9 +- var/mongoose/html/diag/disk.jim | 2 +- var/mongoose/html/diag/dspace/index.jim | 8 +- var/mongoose/html/diag/style.css | 1 + var/mongoose/html/dlna/dlna.jim | 2 +- var/mongoose/html/edit/edit.jim | 8 +- .../{cgi-bin => html}/epg/service.css | 11 + var/mongoose/html/epg/service.jim | 253 +++ var/mongoose/html/epg/service.js | 24 + .../{cgi-bin => html}/epg/xservice.jim | 22 +- var/mongoose/html/img/contb.png | Bin 0 -> 531 bytes var/mongoose/html/img/contt.png | Bin 0 -> 580 bytes var/mongoose/html/js/epg_popup.js | 72 + var/mongoose/html/lib/header.jim | 10 + .../jquery.contextMenu/jquery.contextMenu.css | 142 -- .../jquery.contextMenu/jquery.contextMenu.js | 1686 ----------------- .../jquery.plugin/alerts}/jquery.alerts.css | 0 .../jquery.plugin/alerts}/jquery.alerts.js | 0 .../jquery.plugin/bar}/jquery.bar.css | 0 .../jquery.plugin/bar}/jquery.bar.js | 0 .../confirmAction}/jconfirmaction.jquery.css | 0 .../confirmAction}/jconfirmaction.jquery.js | 0 .../contextMenu}/extra.css | 0 .../contextMenu}/images/cut.png | Bin .../contextMenu}/images/door.png | Bin .../contextMenu}/images/page_white_add.png | Bin .../contextMenu}/images/page_white_copy.png | Bin .../contextMenu}/images/page_white_delete.png | Bin .../contextMenu}/images/page_white_edit.png | Bin .../contextMenu}/images/page_white_paste.png | Bin .../contextMenu}/jquery.contextMenu.css | 0 .../contextMenu}/jquery.contextMenu.js | 0 .../jquery.plugin/easing}/easing.js | 0 .../easy-pie-chart}/jquery.easy-pie-chart.css | 0 .../easy-pie-chart}/jquery.easy-pie-chart.js | 0 .../jquery.plugin/enadis}/enadis.js | 0 .../filetree}/jqueryFileTree.css | 0 .../jquery.plugin/filetree}/jqueryFileTree.js | 0 .../jquery.plugin/flash}/jquery.flash.js | 0 .../jquery.plugin/form}/jquery.form.js | 0 .../freezeheader/jquery.freezeheader.js | 130 ++ .../jquery.plugin/highlight}/highlight.js | 0 .../highlight}/jquery.highlight.js | 0 .../hoverIntent}/jquery.hoverIntent.js | 0 .../{js => lib/jquery.plugin/iajax}/iajax.js | 0 .../iphone-style-checkboxes.css | 0 .../iphone-style-checkboxes.js | 0 .../progressbar}/jquery.progressbar.css | 0 .../progressbar}/jquery.progressbar.js | 0 .../tablesorter}/jquery.tablesorter.js | 0 .../jquery.plugin/tablesorter}/tsort.css | 0 .../jquery.plugin/tabsupport}/tabsupport.js | 0 .../jquery.plugin/touchbridge}/touchbridge.js | 0 .../ui.totop}/jquery.ui.totop.js | 0 .../jquery.plugin/ui.totop}/ui.totop.css | 0 var/mongoose/html/m/lib/header.jim | 6 +- .../html/pkg/{index.shtml => index.jim} | 18 +- var/mongoose/html/play/play.jim | 5 +- var/mongoose/html/sched/sched.jim | 9 +- var/mongoose/html/sched/script.js | 2 +- var/mongoose/html/services.shtml | 6 +- var/mongoose/html/test1 | 1 + var/mongoose/html/test2 | 1 + var/mongoose/include/backup.jim | 2 +- var/mongoose/include/epg.jim | 6 +- var/mongoose/include/menuicons.jim | 2 +- var/mongoose/include/pkg.jim | 46 - var/mongoose/include/toolbar.jim | 2 +- var/mongoose/lib/epg_popup | 75 +- var/mongoose/lib/settings.class | 17 +- var/mongoose/lib/setup | 50 +- var/mongoose/lib/totop | 5 +- 88 files changed, 686 insertions(+), 2207 deletions(-) delete mode 100755 var/mongoose/cgi-bin/epg/service.jim create mode 100644 var/mongoose/html/diag/style.css rename var/mongoose/{cgi-bin => html}/epg/service.css (87%) create mode 100755 var/mongoose/html/epg/service.jim create mode 100644 var/mongoose/html/epg/service.js rename var/mongoose/{cgi-bin => html}/epg/xservice.jim (74%) create mode 100644 var/mongoose/html/img/contb.png create mode 100644 var/mongoose/html/img/contt.png create mode 100644 var/mongoose/html/js/epg_popup.js delete mode 100644 var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.css delete mode 100644 var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.js rename var/mongoose/html/{css => lib/jquery.plugin/alerts}/jquery.alerts.css (100%) rename var/mongoose/html/{js => lib/jquery.plugin/alerts}/jquery.alerts.js (100%) rename var/mongoose/html/{css => lib/jquery.plugin/bar}/jquery.bar.css (100%) rename var/mongoose/html/{js => lib/jquery.plugin/bar}/jquery.bar.js (100%) rename var/mongoose/html/lib/{jquery.confirmAction => jquery.plugin/confirmAction}/jconfirmaction.jquery.css (100%) rename var/mongoose/html/lib/{jquery.confirmAction => jquery.plugin/confirmAction}/jconfirmaction.jquery.js (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/extra.css (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/images/cut.png (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/images/door.png (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/images/page_white_add.png (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/images/page_white_copy.png (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/images/page_white_delete.png (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/images/page_white_edit.png (100%) rename var/mongoose/html/lib/{jquery.contextMenu => jquery.plugin/contextMenu}/images/page_white_paste.png (100%) rename var/mongoose/html/{css => lib/jquery.plugin/contextMenu}/jquery.contextMenu.css (100%) rename var/mongoose/html/{js => lib/jquery.plugin/contextMenu}/jquery.contextMenu.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/easing}/easing.js (100%) rename var/mongoose/html/lib/{jquery.easy-pie-chart => jquery.plugin/easy-pie-chart}/jquery.easy-pie-chart.css (100%) rename var/mongoose/html/lib/{jquery.easy-pie-chart => jquery.plugin/easy-pie-chart}/jquery.easy-pie-chart.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/enadis}/enadis.js (100%) rename var/mongoose/html/{css => lib/jquery.plugin/filetree}/jqueryFileTree.css (100%) rename var/mongoose/html/{js => lib/jquery.plugin/filetree}/jqueryFileTree.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/flash}/jquery.flash.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/form}/jquery.form.js (100%) create mode 100644 var/mongoose/html/lib/jquery.plugin/freezeheader/jquery.freezeheader.js rename var/mongoose/html/{js => lib/jquery.plugin/highlight}/highlight.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/highlight}/jquery.highlight.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/hoverIntent}/jquery.hoverIntent.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/iajax}/iajax.js (100%) rename var/mongoose/html/{css => lib/jquery.plugin/iphone-style-checkboxes}/iphone-style-checkboxes.css (100%) rename var/mongoose/html/{js => lib/jquery.plugin/iphone-style-checkboxes}/iphone-style-checkboxes.js (100%) rename var/mongoose/html/{css => lib/jquery.plugin/progressbar}/jquery.progressbar.css (100%) rename var/mongoose/html/{js => lib/jquery.plugin/progressbar}/jquery.progressbar.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/tablesorter}/jquery.tablesorter.js (100%) rename var/mongoose/html/{css => lib/jquery.plugin/tablesorter}/tsort.css (100%) rename var/mongoose/html/{js => lib/jquery.plugin/tabsupport}/tabsupport.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/touchbridge}/touchbridge.js (100%) rename var/mongoose/html/{js => lib/jquery.plugin/ui.totop}/jquery.ui.totop.js (100%) rename var/mongoose/html/{css => lib/jquery.plugin/ui.totop}/ui.totop.css (100%) rename var/mongoose/html/pkg/{index.shtml => index.jim} (76%) mode change 100644 => 100755 create mode 100644 var/mongoose/html/test1 create mode 100644 var/mongoose/html/test2 delete mode 100755 var/mongoose/include/pkg.jim diff --git a/var/mongoose/cgi-bin/epg/info.jim b/var/mongoose/cgi-bin/epg/info.jim index 3f0bb65..8ae5b9d 100755 --- a/var/mongoose/cgi-bin/epg/info.jim +++ b/var/mongoose/cgi-bin/epg/info.jim @@ -10,7 +10,7 @@ httpheader set service [cgi_get service 0] set event [cgi_get event 0] -if {![cgi_exists bare]} header +if {![cgi_exists bare]} header else noheader set record [lindex [epg fetch dump -service $service -event $event] 0] $record get_channel_info diff --git a/var/mongoose/cgi-bin/epg/search.jim b/var/mongoose/cgi-bin/epg/search.jim index d0d5155..2322784 100755 --- a/var/mongoose/cgi-bin/epg/search.jim +++ b/var/mongoose/cgi-bin/epg/search.jim @@ -4,12 +4,11 @@ package require cgi source /mod/webif/lib/setup require epg.class spinner.class altrow settings.class +jqplugin highlight header require totop -puts "" - set ct [cgi_get ct 0] set crid [cgi_get crid ""] set scrid [cgi_get scrid ""] @@ -56,6 +55,11 @@ if {$ct > 0 } { } set favlist [epg favlist] +if {[$s service_style] eq "standard"} { + set surl xservice +} else { + set surl service +} if {[llength $records] > 0} { puts { @@ -105,7 +109,7 @@ foreach record [lsort -command rsort $records] { puts "[$record get channel_num]" puts "[$record channel_icon 50]" puts " - + [$record get channel_name] " puts [$record cell] diff --git a/var/mongoose/cgi-bin/epg/service.jim b/var/mongoose/cgi-bin/epg/service.jim deleted file mode 100755 index 1e709f2..0000000 --- a/var/mongoose/cgi-bin/epg/service.jim +++ /dev/null @@ -1,133 +0,0 @@ -#!/mod/bin/jimsh - -package require cgi -source /mod/webif/lib/setup -require epg.class spinner.class altrow - -header - -require totop - -[spinner new { - text "Loading EPG Data..." - size "1.2em" - style "margin: 1em;" - }] start - -require epg_popup - -set service [cgi_get service 4170] -set records [epg dbfetch dump \ - -service $service \ - -sort "strftime('%%H%%J', start, 'unixepoch'), strftime('%%M', start, 'unixepoch')" \ - -debug 0 -] - -if {[llength $records] == 0} { - puts "No data for service.." - exit -} - -# Load the channel information from the first entry -set tr [lindex $records 0] -$tr get_channel_info -set channel_num [$tr get channel_num] -set channel_name [$tr get channel_name] - -puts " - -
- [$tr channel_icon 40 {vertical-align:middle}] - - $channel_num - $channel_name - -
-" - -puts " -
- - - - -" -set t [clock seconds] -set firstday [clock format $t -format {%Y%m%d}] -set daymap {} -loop i 0 7 { - puts "" - set daymap([clock format $t -format {%Y%m%d}]) $i - incr t 86400 -} -puts " - - - -" - -set currhour -1 -set currday -1 -foreach e $records { - set start [$e get start] - set day [clock format $start -format "%Y%m%d"] - if {$day ni $daymap} continue - set hour [clock format $start -format "%H"] - if {$hour != $currhour} { - if {$currhour ne "-1"} { - loop i $daymap($currday) 6 { - puts "" - } - puts " - - - - - -
[clock format $t -format {%a}]
" - puts "[clock format $t -format {%e %b}]
" - } - puts -nonewline "
$hour:00 - " - set currhour $hour - set currday $firstday - set newcell 1 - } - if {$day ne $currday} { - loop i $daymap($currday) $daymap($day) { - puts "" - } - set currday $day - set newcell 1 - } - set class "prog" - if {!$newcell} { set class "prog progp" } - if {[$e get series_crid] ne ""} { - set ro 2 - } else { - set ro 1 - } - set st [$e scheduled] - puts " -
-
-[clock format $start -format {%H:%M}]-[clock format [$e end] -format {%H:%M}] -
- -
[$e get text] [join [$e icon_set 14] '']
-
-" - set newcell 0 -} - -puts " -
-
-" - -epg cleanup -footer - diff --git a/var/mongoose/cgi-bin/restart.jim b/var/mongoose/cgi-bin/restart.jim index 9dc01b0..563fb64 100755 --- a/var/mongoose/cgi-bin/restart.jim +++ b/var/mongoose/cgi-bin/restart.jim @@ -19,6 +19,7 @@ if {[cgi_get now] eq "yes"} { } system restartpending 0 +jqplugin progressbar header # Commit pending reservations on older mod versions. @@ -27,8 +28,6 @@ if {![file exists /sbin/rsvsync] && ![file exists /mod/boot/rsvsync]} { } puts { - - - - - +
} @@ -247,6 +247,30 @@ puts " " +puts " + +
+ Default Single-channel style + + + + +
+ +
+ +" + puts "
diff --git a/var/mongoose/cgi-bin/xepg.jim b/var/mongoose/cgi-bin/xepg.jim index 39b678f..74b01d5 100755 --- a/var/mongoose/cgi-bin/xepg.jim +++ b/var/mongoose/cgi-bin/xepg.jim @@ -4,25 +4,29 @@ package require cgi source /mod/webif/lib/setup require settings.class +jqplugin enadis +jscss xepg.js /css/xepg.css header require epg.class spinner.class altrow epg_search totop system.class set irinst [system pkginst ir] -puts { - - - -} +set s [settings] -if {[[settings] chanchangenc]} { +if {[$s chanchangenc]} { puts { } } else { jqplugin confirmAction puts { } } +if {[$s service_style] eq "standard"} { + set surl xservice +} else { + set surl service +} + [spinner new { text "Loading EPG Information..." size "1.2em" @@ -40,7 +44,7 @@ if {$stt <= $now} { set current 0 } -set favgroup [[settings] channel_group] +set favgroup [$s channel_group] set hours [expr 1.0 * [[settings] xepghours]] if {$hours == 0} { set hours 4.0 } @@ -139,7 +143,7 @@ foreach e $records { puts "[$e channel_icon 30] " if {$irinst} { puts "" } puts "$chnum - [$e get channel_name]
" diff --git a/var/mongoose/html/browse/audio/audio.jim b/var/mongoose/html/browse/audio/audio.jim index e010d99..7ee93e5 100755 --- a/var/mongoose/html/browse/audio/audio.jim +++ b/var/mongoose/html/browse/audio/audio.jim @@ -5,6 +5,8 @@ package require cgi source /mod/webif/lib/setup require ts.class system.class +jqplugin progressbar +jscss audio.js header set rfile [cgi_get file] @@ -12,10 +14,8 @@ set ts [ts fetch $rfile] set dir [file dirname $rfile] set len [$ts duration 1] + puts " - - -
Audio Extraction diff --git a/var/mongoose/html/browse/chunk/chunk.jim b/var/mongoose/html/browse/chunk/chunk.jim index 4b856bf..de2d545 100755 --- a/var/mongoose/html/browse/chunk/chunk.jim +++ b/var/mongoose/html/browse/chunk/chunk.jim @@ -4,6 +4,8 @@ package require cgi source /mod/webif/lib/setup require ts.class pretty_size +jqplugin progressbar +jscss chunk.js chunk.css header set rfile [cgi_get file] @@ -19,10 +21,6 @@ set esttime $(int($len * 0.025)) if {[$ts get definition] eq "HD"} { set esttime $($esttime * 4) } puts " - - - -
Split recording into 45 minute segments diff --git a/var/mongoose/html/browse/crop/crop.jim b/var/mongoose/html/browse/crop/crop.jim index 43a0fb9..0859dd1 100755 --- a/var/mongoose/html/browse/crop/crop.jim +++ b/var/mongoose/html/browse/crop/crop.jim @@ -4,6 +4,8 @@ package require cgi source /mod/webif/lib/setup require ts.class pretty_size +jqplugin progressbar +jscss crop.js header set rfile [cgi_get file] @@ -13,10 +15,6 @@ set dir [file dirname $rfile] set len [$ts duration 1] puts " - - - -
Crop recording diff --git a/var/mongoose/html/browse/decrypt/decrypt.jim b/var/mongoose/html/browse/decrypt/decrypt.jim index 756f2bd..4abc414 100755 --- a/var/mongoose/html/browse/decrypt/decrypt.jim +++ b/var/mongoose/html/browse/decrypt/decrypt.jim @@ -5,6 +5,8 @@ package require cgi source /mod/webif/lib/setup require ts.class +jqplugin progressbar +jscss decrypt.js header set rfile [cgi_get file] @@ -14,9 +16,6 @@ set len [$ts duration 1] lassign [$ts dlnaloc "127.0.0.1"] url puts " - - -
Decrypt in-place diff --git a/var/mongoose/html/browse/index.jim b/var/mongoose/html/browse/index.jim index 923a536..7a01444 100755 --- a/var/mongoose/html/browse/index.jim +++ b/var/mongoose/html/browse/index.jim @@ -4,6 +4,8 @@ package require cgi source /mod/webif/lib/setup require ts.class pretty_size system.class settings.class escape browse.class +jqplugin contextMenu bar enadis +jscss script.js style.css header set nicesplice [system pkginst nicesplice] @@ -249,16 +251,6 @@ set dir [cgi_get dir $mroot] ###################################################################### # Render web page -puts { - - - - - - - -} - source assets.jim puts " diff --git a/var/mongoose/html/browse/join/join.jim b/var/mongoose/html/browse/join/join.jim index 0cd41aa..74cd55e 100755 --- a/var/mongoose/html/browse/join/join.jim +++ b/var/mongoose/html/browse/join/join.jim @@ -4,18 +4,14 @@ package require cgi source /mod/webif/lib/setup require ts.class pretty_size +jqplugin progressbar touchbridge +jscss join.js join.css header cgi_input 1 #cgi_dump puts " - - - - - -

Drag the files below into order, enter a name for the resulting file and then click the Join button. diff --git a/var/mongoose/html/browse/mpg/mpg.jim b/var/mongoose/html/browse/mpg/mpg.jim index 81e15dd..ef22c2d 100755 --- a/var/mongoose/html/browse/mpg/mpg.jim +++ b/var/mongoose/html/browse/mpg/mpg.jim @@ -5,6 +5,8 @@ package require cgi source /mod/webif/lib/setup require ts.class system.class +jqplugin progressbar +jscss mpg.js header set rfile [cgi_get file] @@ -13,9 +15,6 @@ set dir [file dirname $rfile] set len [$ts duration 1] puts " - - -

Extract to MPG diff --git a/var/mongoose/html/browse/strip/strip.jim b/var/mongoose/html/browse/strip/strip.jim index 07d5603..54a6723 100755 --- a/var/mongoose/html/browse/strip/strip.jim +++ b/var/mongoose/html/browse/strip/strip.jim @@ -4,6 +4,8 @@ package require cgi source /mod/webif/lib/setup require ts.class pretty_size +jqplugin progressbar +jscss strip.js header set rfile [cgi_get file] @@ -15,10 +17,6 @@ set len [$ts duration 1] set esttime $([$ts size] / 5700000) puts " - - - -
Make recordings smaller by removing unecessary frames diff --git a/var/mongoose/html/browse/thumbnail/index.jim b/var/mongoose/html/browse/thumbnail/index.jim index 720eb6c..cdbb54d 100755 --- a/var/mongoose/html/browse/thumbnail/index.jim +++ b/var/mongoose/html/browse/thumbnail/index.jim @@ -4,6 +4,8 @@ package require cgi source /mod/webif/lib/setup require ts.class pretty_size +jqplugin enadis +jscss script.js header set rfile [cgi_get file] @@ -20,8 +22,6 @@ set pos $($pos + 0) if {$pos < 0} { set pos 0 } puts " - -
Replace Thumbnail diff --git a/var/mongoose/html/dedup/dedup.jim b/var/mongoose/html/dedup/dedup.jim index 71c8580..f61fff1 100755 --- a/var/mongoose/html/dedup/dedup.jim +++ b/var/mongoose/html/dedup/dedup.jim @@ -12,7 +12,7 @@ source process.jim set dir [cgi_get dir "/media/My Video"] set doit [cgi_get doit 0] -puts "" +jscss script.js puts "
De-duplicate $dir diff --git a/var/mongoose/html/diag/diag.jim b/var/mongoose/html/diag/diag.jim index 40f1817..0687670 100755 --- a/var/mongoose/html/diag/diag.jim +++ b/var/mongoose/html/diag/diag.jim @@ -4,19 +4,16 @@ package require cgi source /mod/webif/lib/setup require pretty_size system.class pkg.class +jqplugin enadis +jscss script.js style.css header pkg loaddiagmeta set smv [system modversion 1] -puts { - - - +puts {
Utilities diff --git a/var/mongoose/html/diag/disk.jim b/var/mongoose/html/diag/disk.jim index 88ecc6c..36fcfe2 100755 --- a/var/mongoose/html/diag/disk.jim +++ b/var/mongoose/html/diag/disk.jim @@ -4,6 +4,7 @@ package require cgi source /mod/webif/lib/setup require system.class settings.class +jqplugin enadis header set device [system disk] @@ -20,7 +21,6 @@ if {$line ne ""} { } puts " -

SMART data read from device $device diff --git a/var/mongoose/html/diag/dspace/index.jim b/var/mongoose/html/diag/dspace/index.jim index 45fff77..41e333d 100755 --- a/var/mongoose/html/diag/dspace/index.jim +++ b/var/mongoose/html/diag/dspace/index.jim @@ -4,13 +4,9 @@ package require cgi source /mod/webif/lib/setup require system.class pretty_size -header jqplugin easy-pie-chart - -puts { - - -} +jscss script.js style.css +header set dustbin [system dustbin 1] set root [system mediaroot] diff --git a/var/mongoose/html/diag/style.css b/var/mongoose/html/diag/style.css new file mode 100644 index 0000000..5b29761 --- /dev/null +++ b/var/mongoose/html/diag/style.css @@ -0,0 +1 @@ +button.half { width: 48%; } diff --git a/var/mongoose/html/dlna/dlna.jim b/var/mongoose/html/dlna/dlna.jim index abe125d..5b74465 100755 --- a/var/mongoose/html/dlna/dlna.jim +++ b/var/mongoose/html/dlna/dlna.jim @@ -42,8 +42,8 @@ if {[system is_listening 9000]} { set img "745_1_11_Video_1REC.png" } +jscss script.js puts " -
DLNA Server Information diff --git a/var/mongoose/html/edit/edit.jim b/var/mongoose/html/edit/edit.jim index 28c6091..bbd4530 100755 --- a/var/mongoose/html/edit/edit.jim +++ b/var/mongoose/html/edit/edit.jim @@ -4,17 +4,13 @@ package require cgi source /mod/webif/lib/setup require plugin +jqplugin enadis tabsupport filetree +jscss script.js style.css header set file [cgi_get file "/tmp/hosts"] puts { - - - - - -
File Editor diff --git a/var/mongoose/cgi-bin/epg/service.css b/var/mongoose/html/epg/service.css similarity index 87% rename from var/mongoose/cgi-bin/epg/service.css rename to var/mongoose/html/epg/service.css index 74a1e9c..ec3b787 100644 --- a/var/mongoose/cgi-bin/epg/service.css +++ b/var/mongoose/html/epg/service.css @@ -37,6 +37,12 @@ td.dayhour background: #ffffcc; } +td.sdayhour +{ + vertical-align: middle; + background: #ffffcc; +} + div.prog { margin: 5px; @@ -66,3 +72,8 @@ div.synopsis font-size: 0.9em; } +img.cimg +{ + width: 100%; +} + diff --git a/var/mongoose/html/epg/service.jim b/var/mongoose/html/epg/service.jim new file mode 100755 index 0000000..546168a --- /dev/null +++ b/var/mongoose/html/epg/service.jim @@ -0,0 +1,253 @@ +#!/mod/bin/jimsh + +package require cgi +source /mod/webif/lib/setup +require epg.class spinner.class altrow + +jqplugin iphone-style-checkboxes freezeheader +jscss service.js service.css +header + +require totop + +[spinner new { + text "Loading EPG Data..." + size "1.2em" + style "margin: 1em;" + }] start + +require epg_popup + +set service [cgi_get service 4170] +set records [epg dbfetch dump \ + -service $service \ + -sort "strftime('%%H%%J', start, 'unixepoch'), strftime('%%M', start, 'unixepoch')" \ + -debug 0 +] + +if {[llength $records] == 0} { + puts "No data for service.." + exit +} + +# Load the channel information from the first entry +set tr [lindex $records 0] +$tr get_channel_info +set channel_num [$tr get channel_num] +set channel_name [$tr get channel_name] +puts " + +
+

+ [$tr channel_icon 40 {vertical-align:middle}] + + $channel_num - $channel_name +   + Show synopsis? + + +   + +
+ +" +puts { + +} + +puts " +
+ + + + +" +set t [clock seconds] +set firstday [clock format $t -format {%Y%m%d}] +set daymap {} +loop i 0 8 { + puts "" + set day [clock format $t -format {%Y%m%d}] + set daymap($day) $i + set dayrmap($i) $day + incr t 86400 +} +puts " + + + +" + +set contprog {} + +proc slink {e} { + global service + if {[$e get series_crid] ne ""} { + set ro 2 + } else { + set ro 1 + } + set st [$e scheduled] + return "" +} + +proc prog {e {cont 0} {hour 99}} { + global service day contprog + + set start [$e get start] + set end [$e end] + set class "prog" + if {$cont} { set class "prog progp" } + puts " + +" + + # Programmes which cross the hour boundary + if {[clock format $end -format "%H%M"] > "$($hour + 1)00"} { + puts "
" + set contprog($day) $e + } +} + +proc cprog {} { + global service day contprog hour + + set e $contprog($day) + + set end [$e end] + + if {[clock format $end -format "%H%M"] eq "${hour}00"} { + dict unset contprog $day + return 0 + } + + set start [$e get start] + + puts " +
+
+
+...... -[clock format $end -format {%H:%M}] +
+
+[slink $e] +[$e get name] + +
+
+" + if {[clock format $end -format "%H"] > $hour} { + puts "
" + } else { + dict unset contprog $day + } + return 1 +} + +proc jcprog {day} { + global contprog + + set e $contprog($day) + + set start [$e get start] + set end [$e end] + + puts " +
+
+
+[clock format $start -format {%H:%M}]-[clock format $end -format {%H:%M}] +
+
+[slink $e] +[$e get name] + +
+
+
+" +} + +proc skiptoday {day} { + global daymap dayrmap currday contprog oldcell + if {!$oldcell && [dict exists $contprog $currday]} { + jcprog $currday + } + #puts "Skiptoday: $day ($daymap($currday))
" + if {$daymap($currday) eq $day} return + puts "" + } + puts " + + + + + +
[clock format $t -format {%a}]
" + puts "[clock format $t -format {%e %b}]
" + incr day -1 + loop i $daymap($currday) $day { + set j $($i + 1) + if {[dict exists $contprog $dayrmap($j)]} { + jcprog $dayrmap($j) + } + puts "" + } +} + +set currhour -1 +set currday -1 +set oldcell 0 +foreach e $records { + set start [$e get start] + set day [clock format $start -format "%Y%m%d"] + if {$day ni $daymap} continue + set hour [clock format $start -format "%H"] + if {$hour != $currhour} { + if {$currhour ne "-1"} { + if {$daymap($currday) < 7} { + skiptoday 7 + if {[dict exists $contprog $dayrmap(7)]} { + jcprog $dayrmap(7) + } + } + puts -nonewline "
$hour:00 + " + set currhour $hour + set currday $firstday + set oldcell 0 + } + if {$day ne $currday} { + skiptoday $daymap($day) + set currday $day + set oldcell 0 + } + # Continuations from previous hour... + if {!$oldcell && [dict exists $contprog $day]} { + if {[cprog]} { set oldcell 1 } + } + prog $e $oldcell $hour + set oldcell 1 +} + +puts " +
+
+" + +epg cleanup +footer + diff --git a/var/mongoose/html/epg/service.js b/var/mongoose/html/epg/service.js new file mode 100644 index 0000000..a50f70e --- /dev/null +++ b/var/mongoose/html/epg/service.js @@ -0,0 +1,24 @@ + +$(function() { + +$('button').button(); + +$('#synopsis').iphoneStyle({ + checkedLabel: 'YES', + uncheckedLabel: 'NO' +}).bind('change', function() { + if ($(this).attr('checked')) + $('.synopsis').slideDown(); + else + $('.synopsis').slideUp(); +}); + +$('#listview').bind('click', function() { + var service = $(this).attr('service'); + window.location.href = '/epg/xservice.jim?service=' + service; +}); + +$('table.weekview').freezeHeader(); + +}); + diff --git a/var/mongoose/cgi-bin/epg/xservice.jim b/var/mongoose/html/epg/xservice.jim similarity index 74% rename from var/mongoose/cgi-bin/epg/xservice.jim rename to var/mongoose/html/epg/xservice.jim index 9b3e058..30a0c0b 100755 --- a/var/mongoose/cgi-bin/epg/xservice.jim +++ b/var/mongoose/html/epg/xservice.jim @@ -26,14 +26,28 @@ set channel_name [$tr get channel_name] puts "
- [$tr channel_icon 80 {vertical-align:middle}] - +
+ [$tr channel_icon 40 {vertical-align:middle}] + $channel_num - $channel_name - +   + +
" +puts " + +" puts { +
@@ -61,7 +75,7 @@ foreach record $records { puts "" puts "" } -puts "
[$record get warning]
" +puts "
" epg cleanup footer diff --git a/var/mongoose/html/img/contb.png b/var/mongoose/html/img/contb.png new file mode 100644 index 0000000000000000000000000000000000000000..2827785b8fd48feb0192a71f53857ddbc4165d6c GIT binary patch literal 531 zcmV+u0_^>XP)>dkx1NN2AGg7 zy#@$v^IkIP%VoRSoqPM<=FHs@gx|!LTF@S5Hc=NOD&ap4pW;uDQz`x=Dnaol2y!aL zpF|}n{scizrTCMm1jU~q$f*>664mNsTP={NeiiP%zl5t*X4VvVZD!*+{3!UK1#ir3 zwqVXC@#1=pQTxQ^dD;A#PX0?vbXTFhNsPhNBIY4Dzz z4b$Fx%k--PMnK2iQGFKB0GEl+g4e(}cm*^YvfnPyOZy!L9{@+e$G}ntzdE;3mbuVS)dN2;)?I6-*zP1Rs{H zS+ydfYUu{uIikuU>;aESkdKA?O6K#%_koi%X5;QR>s%}GMcvG*aGtx&b!%BqyaC)d VW$RMfLJj}`002ovPDHLkV1mi_@+SZQ literal 0 HcmV?d00001 diff --git a/var/mongoose/html/img/contt.png b/var/mongoose/html/img/contt.png new file mode 100644 index 0000000000000000000000000000000000000000..34dd7f839e7f262cf55b89c4c2e4840adbc171b4 GIT binary patch literal 580 zcmV-K0=xZ*P)9akXp_7&v!REado_QSrzP{3dCsQ3?Z`>qRaVsl z(9*x`U8O4k+y;IYY`-6@zSxlUW;NBl8@3XC09T3rw|I%?O9?L$qKaZG!yYsC*9mfw z7m1Hs$J-&kQ!{2!Gtas?mjF(~nBUqOY^jJhKG4joYYvh#lGn~BB#)erN$&VhW&myy z{3CSzS@=QYBOXu8FAc^{&L_^<`HAysWo5qhX=7VlhkL3&w1>DNd7w-z`JU>Z;Yle_ zr4m%B*53Yx%7R2C$o>RXD%qbPQ3`zdolKn|kf*|`7))cQRV{1#4 Sf)+IZ0000G< literal 0 HcmV?d00001 diff --git a/var/mongoose/html/js/epg_popup.js b/var/mongoose/html/js/epg_popup.js new file mode 100644 index 0000000..f6dec6f --- /dev/null +++ b/var/mongoose/html/js/epg_popup.js @@ -0,0 +1,72 @@ +$(function() { + function doschedule(type) + { + $('#epginfo_extra').load('/cgi-bin/epg/schedule.jim?' + + 'service=' + + encodeURIComponent($('#dialogue').attr('xs')) + + '&event=' + + encodeURIComponent($('#dialogue').attr('xe')) + + '&type=' + type, function() { + $('#restart_block') + .load('/cgi-bin/restartblock.jim'); + }); + $(":button:contains('Record')").fadeOut('slow'); + $(":button:contains('Reminder')").fadeOut('slow'); + } + + var $buttons1 = { + "Close" : function() {$(this).dialog('close');} + }; + var $buttons2 = $.extend( + {"Record Programme": function() { doschedule(1) }}, + {"Set Reminder": function() { doschedule(3) }}, + $buttons1); + var $buttons3 = $.extend( + {"Record Series": function() { doschedule(2) }}, + $buttons2); + + var $dialog = $('#dialogue').dialog({ + title: "Programme Details", + modal: false, autoOpen: false, + height: 500, width: 700, + show: 'scale', hide: 'fade', + draggable: true, resizable: true, + buttons: $buttons1, + close: function(e,u) { $('#dialogue').empty().html( + 'loading'); } + }); + + function epgpopup(e, o) + { + e.preventDefault(); + var sch = o.attr('sch'); + var rec = o.attr('rec'); + if (sch != 0) + $dialog.dialog("option", "buttons", $buttons1); + else if (rec == 2) + $dialog.dialog("option", "buttons", $buttons3); + else if (rec == 1) + $dialog.dialog("option", "buttons", $buttons2); + else + $dialog.dialog("option", "buttons", $buttons1); + var url = '/cgi-bin/epg/info.jim?service=' + + o.attr('xs') + '&event=' + + o.attr('xe') + '&bare=1'; + $('#dialogue') + .html(' Loading details...' + + ' Please wait...') + .load(url, function() { + $('#dialogue a.event').click(function(e) { + epgpopup(e, $(this)); + }); + }); + $('#dialogue') + .attr('xs', o.attr('xs')) + .attr('xe', o.attr('xe')); + $dialog.dialog('open'); + } + $('a.event').click(function(e) { + e.preventDefault(); + epgpopup(e, $(this)) + }); +}); diff --git a/var/mongoose/html/lib/header.jim b/var/mongoose/html/lib/header.jim index a25d14d..56563e7 100755 --- a/var/mongoose/html/lib/header.jim +++ b/var/mongoose/html/lib/header.jim @@ -24,6 +24,16 @@ puts { +} +if {[info exists _mws_js]} { + foreach js $_mws_js { + puts "" + } + foreach css $_mws_css { + puts "" + } +} +puts { } diff --git a/var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.css b/var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.css deleted file mode 100644 index ee58116..0000000 --- a/var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.css +++ /dev/null @@ -1,142 +0,0 @@ -/*! - * jQuery contextMenu - Plugin for simple contextMenu handling - * - * Version: git-master - * - * Authors: Rodney Rehm, Addy Osmani (patches for FF) - * Web: http://medialize.github.com/jQuery-contextMenu/ - * - * Licensed under - * MIT License http://www.opensource.org/licenses/mit-license - * GPL v3 http://opensource.org/licenses/GPL-3.0 - * - */ - -.context-menu-list { - margin:0; - padding:0; - - min-width: 120px; - max-width: 250px; - display: inline-block; - position: absolute; - list-style-type: none; - - border: 1px solid #DDD; - background: #EEE; - - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); - -ms-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); - - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.context-menu-item { - padding: 2px 2px 2px 24px; - background-color: #EEE; - position: relative; - -webkit-user-select: none; - -moz-user-select: -moz-none; - -ms-user-select: none; - user-select: none; -} - -.context-menu-separator { - padding-bottom:0; - border-bottom: 1px solid #DDD; -} - -.context-menu-item > label > input, -.context-menu-item > label > textarea { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; -} - -.context-menu-item.hover { - cursor: pointer; - background-color: #39F; -} - -.context-menu-item.disabled { - color: #666; -} - -.context-menu-input.hover, -.context-menu-item.disabled.hover { - cursor: default; - background-color: #EEE; -} - -.context-menu-submenu:after { - content: ">"; - color: #666; - position: absolute; - top: 0; - right: 3px; - z-index: 1; -} - -/* icons - #protip: - In case you want to use sprites for icons (which I would suggest you do) have a look at - http://css-tricks.com/13224-pseudo-spriting/ to get an idea of how to implement - .context-menu-item.icon:before {} - */ -.context-menu-item.icon { min-height: 18px; background-repeat: no-repeat; background-position: 4px 2px; } -.context-menu-item.icon-edit { background-image: url(images/page_white_edit.png); } -.context-menu-item.icon-cut { background-image: url(images/cut.png); } -.context-menu-item.icon-copy { background-image: url(images/page_white_copy.png); } -.context-menu-item.icon-paste { background-image: url(images/page_white_paste.png); } -.context-menu-item.icon-delete { background-image: url(images/page_white_delete.png); } -.context-menu-item.icon-add { background-image: url(images/page_white_add.png); } -.context-menu-item.icon-quit { background-image: url(images/door.png); } - -/* vertically align inside labels */ -.context-menu-input > label > * { vertical-align: top; } - -/* position checkboxes and radios as icons */ -.context-menu-input > label > input[type="checkbox"], -.context-menu-input > label > input[type="radio"] { - margin-left: -17px; -} -.context-menu-input > label > span { - margin-left: 5px; -} - -.context-menu-input > label, -.context-menu-input > label > input[type="text"], -.context-menu-input > label > textarea, -.context-menu-input > label > select { - display: block; - width: 100%; - - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - -o-box-sizing: border-box; - box-sizing: border-box; -} - -.context-menu-input > label > textarea { - height: 100px; -} -.context-menu-item > .context-menu-list { - display: none; - /* re-positioned by js */ - right: -5px; - top: 5px; -} - -.context-menu-item.hover > .context-menu-list { - display: block; -} - -.context-menu-accesskey { - text-decoration: underline; -} diff --git a/var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.js b/var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.js deleted file mode 100644 index a903e82..0000000 --- a/var/mongoose/html/lib/jquery.contextMenu/jquery.contextMenu.js +++ /dev/null @@ -1,1686 +0,0 @@ -/*! - * jQuery contextMenu - Plugin for simple contextMenu handling - * - * Version: git-master - * - * Authors: Rodney Rehm, Addy Osmani (patches for FF) - * Web: http://medialize.github.com/jQuery-contextMenu/ - * - * Licensed under - * MIT License http://www.opensource.org/licenses/mit-license - * GPL v3 http://opensource.org/licenses/GPL-3.0 - * - */ - -(function($, undefined){ - - // TODO: - - // ARIA stuff: menuitem, menuitemcheckbox und menuitemradio - // create structure if $.support[htmlCommand || htmlMenuitem] and !opt.disableNative - -// determine html5 compatibility -$.support.htmlMenuitem = ('HTMLMenuItemElement' in window); -$.support.htmlCommand = ('HTMLCommandElement' in window); -$.support.eventSelectstart = ("onselectstart" in document.documentElement); -/* // should the need arise, test for css user-select -$.support.cssUserSelect = (function(){ - var t = false, - e = document.createElement('div'); - - $.each('Moz|Webkit|Khtml|O|ms|Icab|'.split('|'), function(i, prefix) { - var propCC = prefix + (prefix ? 'U' : 'u') + 'serSelect', - prop = (prefix ? ('-' + prefix.toLowerCase() + '-') : '') + 'user-select'; - - e.style.cssText = prop + ': text;'; - if (e.style[propCC] == 'text') { - t = true; - return false; - } - - return true; - }); - - return t; -})(); -*/ - -if (!$.ui || !$.ui.widget) { - // duck punch $.cleanData like jQueryUI does to get that remove event - // https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js#L16-24 - var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); - }; -} - -var // currently active contextMenu trigger - $currentTrigger = null, - // is contextMenu initialized with at least one menu? - initialized = false, - // window handle - $win = $(window), - // number of registered menus - counter = 0, - // mapping selector to namespace - namespaces = {}, - // mapping namespace to options - menus = {}, - // custom command type handlers - types = {}, - // default values - defaults = { - // selector of contextMenu trigger - selector: null, - // where to append the menu to - appendTo: null, - // method to trigger context menu ["right", "left", "hover"] - trigger: "right", - // hide menu when mouse leaves trigger / menu elements - autoHide: false, - // ms to wait before showing a hover-triggered context menu - delay: 200, - // flag denoting if a second trigger should simply move (true) or rebuild (false) an open menu - // as long as the trigger happened on one of the trigger-element's child nodes - reposition: true, - // determine position to show menu at - determinePosition: function($menu) { - // position to the lower middle of the trigger element - if ($.ui && $.ui.position) { - // .position() is provided as a jQuery UI utility - // (...and it won't work on hidden elements) - $menu.css('display', 'block').position({ - my: "center top", - at: "center bottom", - of: this, - offset: "0 5", - collision: "fit" - }).css('display', 'none'); - } else { - // determine contextMenu position - var offset = this.offset(); - offset.top += this.outerHeight(); - offset.left += this.outerWidth() / 2 - $menu.outerWidth() / 2; - $menu.css(offset); - } - }, - // position menu - position: function(opt, x, y) { - var $this = this, - offset; - // determine contextMenu position - if (!x && !y) { - opt.determinePosition.call(this, opt.$menu); - return; - } else if (x === "maintain" && y === "maintain") { - // x and y must not be changed (after re-show on command click) - offset = opt.$menu.position(); - } else { - // x and y are given (by mouse event) - offset = {top: y, left: x}; - } - - // correct offset if viewport demands it - var bottom = $win.scrollTop() + $win.height(), - right = $win.scrollLeft() + $win.width(), - height = opt.$menu.height(), - width = opt.$menu.width(); - - if (offset.top + height > bottom) { - offset.top -= height; - } - - if (offset.left + width > right) { - offset.left -= width; - } - - opt.$menu.css(offset); - }, - // position the sub-menu - positionSubmenu: function($menu) { - if ($.ui && $.ui.position) { - // .position() is provided as a jQuery UI utility - // (...and it won't work on hidden elements) - $menu.css('display', 'block').position({ - my: "left top", - at: "right top", - of: this, - collision: "flipfit fit" - }).css('display', ''); - } else { - // determine contextMenu position - var offset = { - top: 0, - left: this.outerWidth() - }; - $menu.css(offset); - } - }, - // offset to add to zIndex - zIndex: 1, - // show hide animation settings - animation: { - duration: 50, - show: 'slideDown', - hide: 'slideUp' - }, - // events - events: { - show: $.noop, - hide: $.noop - }, - // default callback - callback: null, - // list of contextMenu items - items: {} - }, - // mouse position for hover activation - hoveract = { - timer: null, - pageX: null, - pageY: null - }, - // determine zIndex - zindex = function($t) { - var zin = 0, - $tt = $t; - - while (true) { - zin = Math.max(zin, parseInt($tt.css('z-index'), 10) || 0); - $tt = $tt.parent(); - if (!$tt || !$tt.length || "html body".indexOf($tt.prop('nodeName').toLowerCase()) > -1 ) { - break; - } - } - - return zin; - }, - // event handlers - handle = { - // abort anything - abortevent: function(e){ - e.preventDefault(); - e.stopImmediatePropagation(); - }, - - // contextmenu show dispatcher - contextmenu: function(e) { - var $this = $(this); - - // disable actual context-menu - e.preventDefault(); - e.stopImmediatePropagation(); - - // abort native-triggered events unless we're triggering on right click - if (e.data.trigger != 'right' && e.originalEvent) { - return; - } - - // abort event if menu is visible for this trigger - if ($this.hasClass('context-menu-active')) { - return; - } - - if (!$this.hasClass('context-menu-disabled')) { - // theoretically need to fire a show event at - // http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#context-menus - // var evt = jQuery.Event("show", { data: data, pageX: e.pageX, pageY: e.pageY, relatedTarget: this }); - // e.data.$menu.trigger(evt); - - $currentTrigger = $this; - if (e.data.build) { - var built = e.data.build($currentTrigger, e); - // abort if build() returned false - if (built === false) { - return; - } - - // dynamically build menu on invocation - e.data = $.extend(true, {}, defaults, e.data, built || {}); - - // abort if there are no items to display - if (!e.data.items || $.isEmptyObject(e.data.items)) { - // Note: jQuery captures and ignores errors from event handlers - if (window.console) { - (console.error || console.log)("No items specified to show in contextMenu"); - } - - throw new Error('No Items sepcified'); - } - - // backreference for custom command type creation - e.data.$trigger = $currentTrigger; - - op.create(e.data); - } - // show menu - op.show.call($this, e.data, e.pageX, e.pageY); - } - }, - // contextMenu left-click trigger - click: function(e) { - e.preventDefault(); - e.stopImmediatePropagation(); - $(this).trigger($.Event("contextmenu", { data: e.data, pageX: e.pageX, pageY: e.pageY })); - }, - // contextMenu right-click trigger - mousedown: function(e) { - // register mouse down - var $this = $(this); - - // hide any previous menus - if ($currentTrigger && $currentTrigger.length && !$currentTrigger.is($this)) { - $currentTrigger.data('contextMenu').$menu.trigger('contextmenu:hide'); - } - - // activate on right click - if (e.button == 2) { - $currentTrigger = $this.data('contextMenuActive', true); - } - }, - // contextMenu right-click trigger - mouseup: function(e) { - // show menu - var $this = $(this); - if ($this.data('contextMenuActive') && $currentTrigger && $currentTrigger.length && $currentTrigger.is($this) && !$this.hasClass('context-menu-disabled')) { - e.preventDefault(); - e.stopImmediatePropagation(); - $currentTrigger = $this; - $this.trigger($.Event("contextmenu", { data: e.data, pageX: e.pageX, pageY: e.pageY })); - } - - $this.removeData('contextMenuActive'); - }, - // contextMenu hover trigger - mouseenter: function(e) { - var $this = $(this), - $related = $(e.relatedTarget), - $document = $(document); - - // abort if we're coming from a menu - if ($related.is('.context-menu-list') || $related.closest('.context-menu-list').length) { - return; - } - - // abort if a menu is shown - if ($currentTrigger && $currentTrigger.length) { - return; - } - - hoveract.pageX = e.pageX; - hoveract.pageY = e.pageY; - hoveract.data = e.data; - $document.on('mousemove.contextMenuShow', handle.mousemove); - hoveract.timer = setTimeout(function() { - hoveract.timer = null; - $document.off('mousemove.contextMenuShow'); - $currentTrigger = $this; - $this.trigger($.Event("contextmenu", { data: hoveract.data, pageX: hoveract.pageX, pageY: hoveract.pageY })); - }, e.data.delay ); - }, - // contextMenu hover trigger - mousemove: function(e) { - hoveract.pageX = e.pageX; - hoveract.pageY = e.pageY; - }, - // contextMenu hover trigger - mouseleave: function(e) { - // abort if we're leaving for a menu - var $related = $(e.relatedTarget); - if ($related.is('.context-menu-list') || $related.closest('.context-menu-list').length) { - return; - } - - try { - clearTimeout(hoveract.timer); - } catch(e) {} - - hoveract.timer = null; - }, - - // click on layer to hide contextMenu - layerClick: function(e) { - var $this = $(this), - root = $this.data('contextMenuRoot'), - mouseup = false, - button = e.button, - x = e.pageX, - y = e.pageY, - target, - offset, - selectors; - - e.preventDefault(); - e.stopImmediatePropagation(); - - setTimeout(function() { - var $window, hideshow, possibleTarget; - var triggerAction = ((root.trigger == 'left' && button === 0) || (root.trigger == 'right' && button === 2)); - - // find the element that would've been clicked, wasn't the layer in the way - if (document.elementFromPoint) { - root.$layer.hide(); - target = document.elementFromPoint(x - $win.scrollLeft(), y - $win.scrollTop()); - root.$layer.show(); - } - - if (root.reposition && triggerAction) { - if (document.elementFromPoint) { - if (root.$trigger.is(target) || root.$trigger.has(target).length) { - root.position.call(root.$trigger, root, x, y); - return; - } - } else { - offset = root.$trigger.offset(); - $window = $(window); - // while this looks kinda awful, it's the best way to avoid - // unnecessarily calculating any positions - offset.top += $window.scrollTop(); - if (offset.top <= e.pageY) { - offset.left += $window.scrollLeft(); - if (offset.left <= e.pageX) { - offset.bottom = offset.top + root.$trigger.outerHeight(); - if (offset.bottom >= e.pageY) { - offset.right = offset.left + root.$trigger.outerWidth(); - if (offset.right >= e.pageX) { - // reposition - root.position.call(root.$trigger, root, x, y); - return; - } - } - } - } - } - } - - if (target && triggerAction) { - root.$trigger.one('contextmenu:hidden', function() { - $(target).contextMenu({x: x, y: y}); - }); - } - - root.$menu.trigger('contextmenu:hide'); - }, 50); - }, - // key handled :hover - keyStop: function(e, opt) { - if (!opt.isInput) { - e.preventDefault(); - } - - e.stopPropagation(); - }, - key: function(e) { - var opt = $currentTrigger.data('contextMenu') || {}; - - switch (e.keyCode) { - case 9: - case 38: // up - handle.keyStop(e, opt); - // if keyCode is [38 (up)] or [9 (tab) with shift] - if (opt.isInput) { - if (e.keyCode == 9 && e.shiftKey) { - e.preventDefault(); - opt.$selected && opt.$selected.find('input, textarea, select').blur(); - opt.$menu.trigger('prevcommand'); - return; - } else if (e.keyCode == 38 && opt.$selected.find('input, textarea, select').prop('type') == 'checkbox') { - // checkboxes don't capture this key - e.preventDefault(); - return; - } - } else if (e.keyCode != 9 || e.shiftKey) { - opt.$menu.trigger('prevcommand'); - return; - } - // omitting break; - - // case 9: // tab - reached through omitted break; - case 40: // down - handle.keyStop(e, opt); - if (opt.isInput) { - if (e.keyCode == 9) { - e.preventDefault(); - opt.$selected && opt.$selected.find('input, textarea, select').blur(); - opt.$menu.trigger('nextcommand'); - return; - } else if (e.keyCode == 40 && opt.$selected.find('input, textarea, select').prop('type') == 'checkbox') { - // checkboxes don't capture this key - e.preventDefault(); - return; - } - } else { - opt.$menu.trigger('nextcommand'); - return; - } - break; - - case 37: // left - handle.keyStop(e, opt); - if (opt.isInput || !opt.$selected || !opt.$selected.length) { - break; - } - - if (!opt.$selected.parent().hasClass('context-menu-root')) { - var $parent = opt.$selected.parent().parent(); - opt.$selected.trigger('contextmenu:blur'); - opt.$selected = $parent; - return; - } - break; - - case 39: // right - handle.keyStop(e, opt); - if (opt.isInput || !opt.$selected || !opt.$selected.length) { - break; - } - - var itemdata = opt.$selected.data('contextMenu') || {}; - if (itemdata.$menu && opt.$selected.hasClass('context-menu-submenu')) { - opt.$selected = null; - itemdata.$selected = null; - itemdata.$menu.trigger('nextcommand'); - return; - } - break; - - case 35: // end - case 36: // home - if (opt.$selected && opt.$selected.find('input, textarea, select').length) { - return; - } else { - (opt.$selected && opt.$selected.parent() || opt.$menu) - .children(':not(.disabled, .not-selectable)')[e.keyCode == 36 ? 'first' : 'last']() - .trigger('contextmenu:focus'); - e.preventDefault(); - return; - } - break; - - case 13: // enter - handle.keyStop(e, opt); - if (opt.isInput) { - if (opt.$selected && !opt.$selected.is('textarea, select')) { - e.preventDefault(); - return; - } - break; - } - opt.$selected && opt.$selected.trigger('mouseup'); - return; - - case 32: // space - case 33: // page up - case 34: // page down - // prevent browser from scrolling down while menu is visible - handle.keyStop(e, opt); - return; - - case 27: // esc - handle.keyStop(e, opt); - opt.$menu.trigger('contextmenu:hide'); - return; - - default: // 0-9, a-z - var k = (String.fromCharCode(e.keyCode)).toUpperCase(); - if (opt.accesskeys[k]) { - // according to the specs accesskeys must be invoked immediately - opt.accesskeys[k].$node.trigger(opt.accesskeys[k].$menu - ? 'contextmenu:focus' - : 'mouseup' - ); - return; - } - break; - } - // pass event to selected item, - // stop propagation to avoid endless recursion - e.stopPropagation(); - opt.$selected && opt.$selected.trigger(e); - }, - - // select previous possible command in menu - prevItem: function(e) { - e.stopPropagation(); - var opt = $(this).data('contextMenu') || {}; - - // obtain currently selected menu - if (opt.$selected) { - var $s = opt.$selected; - opt = opt.$selected.parent().data('contextMenu') || {}; - opt.$selected = $s; - } - - var $children = opt.$menu.children(), - $prev = !opt.$selected || !opt.$selected.prev().length ? $children.last() : opt.$selected.prev(), - $round = $prev; - - // skip disabled - while ($prev.hasClass('disabled') || $prev.hasClass('not-selectable')) { - if ($prev.prev().length) { - $prev = $prev.prev(); - } else { - $prev = $children.last(); - } - if ($prev.is($round)) { - // break endless loop - return; - } - } - - // leave current - if (opt.$selected) { - handle.itemMouseleave.call(opt.$selected.get(0), e); - } - - // activate next - handle.itemMouseenter.call($prev.get(0), e); - - // focus input - var $input = $prev.find('input, textarea, select'); - if ($input.length) { - $input.focus(); - } - }, - // select next possible command in menu - nextItem: function(e) { - e.stopPropagation(); - var opt = $(this).data('contextMenu') || {}; - - // obtain currently selected menu - if (opt.$selected) { - var $s = opt.$selected; - opt = opt.$selected.parent().data('contextMenu') || {}; - opt.$selected = $s; - } - - var $children = opt.$menu.children(), - $next = !opt.$selected || !opt.$selected.next().length ? $children.first() : opt.$selected.next(), - $round = $next; - - // skip disabled - while ($next.hasClass('disabled') || $next.hasClass('not-selectable')) { - if ($next.next().length) { - $next = $next.next(); - } else { - $next = $children.first(); - } - if ($next.is($round)) { - // break endless loop - return; - } - } - - // leave current - if (opt.$selected) { - handle.itemMouseleave.call(opt.$selected.get(0), e); - } - - // activate next - handle.itemMouseenter.call($next.get(0), e); - - // focus input - var $input = $next.find('input, textarea, select'); - if ($input.length) { - $input.focus(); - } - }, - - // flag that we're inside an input so the key handler can act accordingly - focusInput: function(e) { - var $this = $(this).closest('.context-menu-item'), - data = $this.data(), - opt = data.contextMenu, - root = data.contextMenuRoot; - - root.$selected = opt.$selected = $this; - root.isInput = opt.isInput = true; - }, - // flag that we're inside an input so the key handler can act accordingly - blurInput: function(e) { - var $this = $(this).closest('.context-menu-item'), - data = $this.data(), - opt = data.contextMenu, - root = data.contextMenuRoot; - - root.isInput = opt.isInput = false; - }, - - // :hover on menu - menuMouseenter: function(e) { - var root = $(this).data().contextMenuRoot; - root.hovering = true; - }, - // :hover on menu - menuMouseleave: function(e) { - var root = $(this).data().contextMenuRoot; - if (root.$layer && root.$layer.is(e.relatedTarget)) { - root.hovering = false; - } - }, - - // :hover done manually so key handling is possible - itemMouseenter: function(e) { - var $this = $(this), - data = $this.data(), - opt = data.contextMenu, - root = data.contextMenuRoot; - - root.hovering = true; - - // abort if we're re-entering - if (e && root.$layer && root.$layer.is(e.relatedTarget)) { - e.preventDefault(); - e.stopImmediatePropagation(); - } - - // make sure only one item is selected - (opt.$menu ? opt : root).$menu - .children('.hover').trigger('contextmenu:blur'); - - if ($this.hasClass('disabled') || $this.hasClass('not-selectable')) { - opt.$selected = null; - return; - } - - $this.trigger('contextmenu:focus'); - }, - // :hover done manually so key handling is possible - itemMouseleave: function(e) { - var $this = $(this), - data = $this.data(), - opt = data.contextMenu, - root = data.contextMenuRoot; - - if (root !== opt && root.$layer && root.$layer.is(e.relatedTarget)) { - root.$selected && root.$selected.trigger('contextmenu:blur'); - e.preventDefault(); - e.stopImmediatePropagation(); - root.$selected = opt.$selected = opt.$node; - return; - } - - $this.trigger('contextmenu:blur'); - }, - // contextMenu item click - itemClick: function(e) { - var $this = $(this), - data = $this.data(), - opt = data.contextMenu, - root = data.contextMenuRoot, - key = data.contextMenuKey, - callback; - - // abort if the key is unknown or disabled or is a menu - if (!opt.items[key] || $this.is('.disabled, .context-menu-submenu, .context-menu-separator, .not-selectable')) { - return; - } - - e.preventDefault(); - e.stopImmediatePropagation(); - - if ($.isFunction(root.callbacks[key]) && Object.prototype.hasOwnProperty.call(root.callbacks, key)) { - // item-specific callback - callback = root.callbacks[key]; - } else if ($.isFunction(root.callback)) { - // default callback - callback = root.callback; - } else { - // no callback, no action - return; - } - - // hide menu if callback doesn't stop that - if (callback.call(root.$trigger, key, root) !== false) { - root.$menu.trigger('contextmenu:hide'); - } else if (root.$menu.parent().length) { - op.update.call(root.$trigger, root); - } - }, - // ignore click events on input elements - inputClick: function(e) { - e.stopImmediatePropagation(); - }, - - // hide - hideMenu: function(e, data) { - var root = $(this).data('contextMenuRoot'); - op.hide.call(root.$trigger, root, data && data.force); - }, - // focus - focusItem: function(e) { - e.stopPropagation(); - var $this = $(this), - data = $this.data(), - opt = data.contextMenu, - root = data.contextMenuRoot; - - $this.addClass('hover') - .siblings('.hover').trigger('contextmenu:blur'); - - // remember selected - opt.$selected = root.$selected = $this; - - // position sub-menu - do after show so dumb $.ui.position can keep up - if (opt.$node) { - root.positionSubmenu.call(opt.$node, opt.$menu); - } - }, - // blur - blurItem: function(e) { - e.stopPropagation(); - var $this = $(this), - data = $this.data(), - opt = data.contextMenu, - root = data.contextMenuRoot; - - $this.removeClass('hover'); - opt.$selected = null; - } - }, - // operations - op = { - show: function(opt, x, y) { - var $trigger = $(this), - offset, - css = {}; - - // hide any open menus - $('#context-menu-layer').trigger('mousedown'); - - // backreference for callbacks - opt.$trigger = $trigger; - - // show event - if (opt.events.show.call($trigger, opt) === false) { - $currentTrigger = null; - return; - } - - // create or update context menu - op.update.call($trigger, opt); - - // position menu - opt.position.call($trigger, opt, x, y); - - // make sure we're in front - if (opt.zIndex) { - css.zIndex = zindex($trigger) + opt.zIndex; - } - - // add layer - op.layer.call(opt.$menu, opt, css.zIndex); - - // adjust sub-menu zIndexes - opt.$menu.find('ul').css('zIndex', css.zIndex + 1); - - // position and show context menu - opt.$menu.css( css )[opt.animation.show](opt.animation.duration, function() { - $trigger.trigger('contextmenu:visible'); - }); - // make options available and set state - $trigger - .data('contextMenu', opt) - .addClass("context-menu-active"); - - // register key handler - $(document).off('keydown.contextMenu').on('keydown.contextMenu', handle.key); - // register autoHide handler - if (opt.autoHide) { - // mouse position handler - $(document).on('mousemove.contextMenuAutoHide', function(e) { - // need to capture the offset on mousemove, - // since the page might've been scrolled since activation - var pos = $trigger.offset(); - pos.right = pos.left + $trigger.outerWidth(); - pos.bottom = pos.top + $trigger.outerHeight(); - - if (opt.$layer && !opt.hovering && (!(e.pageX >= pos.left && e.pageX <= pos.right) || !(e.pageY >= pos.top && e.pageY <= pos.bottom))) { - // if mouse in menu... - opt.$menu.trigger('contextmenu:hide'); - } - }); - } - }, - hide: function(opt, force) { - var $trigger = $(this); - if (!opt) { - opt = $trigger.data('contextMenu') || {}; - } - - // hide event - if (!force && opt.events && opt.events.hide.call($trigger, opt) === false) { - return; - } - - // remove options and revert state - $trigger - .removeData('contextMenu') - .removeClass("context-menu-active"); - - if (opt.$layer) { - // keep layer for a bit so the contextmenu event can be aborted properly by opera - setTimeout((function($layer) { - return function(){ - $layer.remove(); - }; - })(opt.$layer), 10); - - try { - delete opt.$layer; - } catch(e) { - opt.$layer = null; - } - } - - // remove handle - $currentTrigger = null; - // remove selected - opt.$menu.find('.hover').trigger('contextmenu:blur'); - opt.$selected = null; - // unregister key and mouse handlers - //$(document).off('.contextMenuAutoHide keydown.contextMenu'); // http://bugs.jquery.com/ticket/10705 - $(document).off('.contextMenuAutoHide').off('keydown.contextMenu'); - // hide menu - opt.$menu && opt.$menu[opt.animation.hide](opt.animation.duration, function (){ - // tear down dynamically built menu after animation is completed. - if (opt.build) { - opt.$menu.remove(); - $.each(opt, function(key, value) { - switch (key) { - case 'ns': - case 'selector': - case 'build': - case 'trigger': - return true; - - default: - opt[key] = undefined; - try { - delete opt[key]; - } catch (e) {} - return true; - } - }); - } - - setTimeout(function() { - $trigger.trigger('contextmenu:hidden'); - }, 10); - }); - }, - create: function(opt, root) { - if (root === undefined) { - root = opt; - } - // create contextMenu - opt.$menu = $('
    ').addClass(opt.className || "").data({ - 'contextMenu': opt, - 'contextMenuRoot': root - }); - - $.each(['callbacks', 'commands', 'inputs'], function(i,k){ - opt[k] = {}; - if (!root[k]) { - root[k] = {}; - } - }); - - root.accesskeys || (root.accesskeys = {}); - - // create contextMenu items - $.each(opt.items, function(key, item){ - var $t = $('
  • ').addClass(item.className || ""), - $label = null, - $input = null; - - // iOS needs to see a click-event bound to an element to actually - // have the TouchEvents infrastructure trigger the click event - $t.on('click', $.noop); - - item.$node = $t.data({ - 'contextMenu': opt, - 'contextMenuRoot': root, - 'contextMenuKey': key - }); - - // register accesskey - // NOTE: the accesskey attribute should be applicable to any element, but Safari5 and Chrome13 still can't do that - if (item.accesskey) { - var aks = splitAccesskey(item.accesskey); - for (var i=0, ak; ak = aks[i]; i++) { - if (!root.accesskeys[ak]) { - root.accesskeys[ak] = item; - item._name = item.name.replace(new RegExp('(' + ak + ')', 'i'), '$1'); - break; - } - } - } - - if (typeof item == "string") { - $t.addClass('context-menu-separator not-selectable'); - } else if (item.type && types[item.type]) { - // run custom type handler - types[item.type].call($t, item, opt, root); - // register commands - $.each([opt, root], function(i,k){ - k.commands[key] = item; - if ($.isFunction(item.callback)) { - k.callbacks[key] = item.callback; - } - }); - } else { - // add label for input - if (item.type == 'html') { - $t.addClass('context-menu-html not-selectable'); - } else if (item.type) { - $label = $('').appendTo($t); - $('').html(item._name || item.name).appendTo($label); - $t.addClass('context-menu-input'); - opt.hasTypes = true; - $.each([opt, root], function(i,k){ - k.commands[key] = item; - k.inputs[key] = item; - }); - } else if (item.items) { - item.type = 'sub'; - } - - switch (item.type) { - case 'text': - $input = $('') - .attr('name', 'context-menu-input-' + key) - .val(item.value || "") - .appendTo($label); - break; - - case 'textarea': - $input = $('') - .attr('name', 'context-menu-input-' + key) - .val(item.value || "") - .appendTo($label); - - if (item.height) { - $input.height(item.height); - } - break; - - case 'checkbox': - $input = $('') - .attr('name', 'context-menu-input-' + key) - .val(item.value || "") - .prop("checked", !!item.selected) - .prependTo($label); - break; - - case 'radio': - $input = $('') - .attr('name', 'context-menu-input-' + item.radio) - .val(item.value || "") - .prop("checked", !!item.selected) - .prependTo($label); - break; - - case 'select': - $input = $(' - if (item.type && item.type != 'sub' && item.type != 'html') { - $input - .on('focus', handle.focusInput) - .on('blur', handle.blurInput); - - if (item.events) { - $input.on(item.events, opt); - } - } - - // add icons - if (item.icon) { - $t.addClass("icon icon-" + item.icon); - } - } - - // cache contained elements - item.$input = $input; - item.$label = $label; - - // attach item to menu - $t.appendTo(opt.$menu); - - // Disable text selection - if (!opt.hasTypes && $.support.eventSelectstart) { - // browsers support user-select: none, - // IE has a special event for text-selection - // browsers supporting neither will not be preventing text-selection - $t.on('selectstart.disableTextSelect', handle.abortevent); - } - }); - // attach contextMenu to (to bypass any possible overflow:hidden issues on parents of the trigger element) - if (!opt.$node) { - opt.$menu.css('display', 'none').addClass('context-menu-root'); - } - opt.$menu.appendTo(opt.appendTo || document.body); - }, - resize: function($menu, nested) { - // determine widths of submenus, as CSS won't grow them automatically - // position:absolute within position:absolute; min-width:100; max-width:200; results in width: 100; - // kinda sucks hard... - - // determine width of absolutely positioned element - $menu.css({position: 'absolute', display: 'block'}); - // don't apply yet, because that would break nested elements' widths - // add a pixel to circumvent word-break issue in IE9 - #80 - $menu.data('width', Math.ceil($menu.width()) + 1); - // reset styles so they allow nested elements to grow/shrink naturally - $menu.css({ - position: 'static', - minWidth: '0px', - maxWidth: '100000px' - }); - // identify width of nested menus - $menu.find('> li > ul').each(function() { - op.resize($(this), true); - }); - // reset and apply changes in the end because nested - // elements' widths wouldn't be calculatable otherwise - if (!nested) { - $menu.find('ul').andSelf().css({ - position: '', - display: '', - minWidth: '', - maxWidth: '' - }).width(function() { - return $(this).data('width'); - }); - } - }, - update: function(opt, root) { - var $trigger = this; - if (root === undefined) { - root = opt; - op.resize(opt.$menu); - } - // re-check disabled for each item - opt.$menu.children().each(function(){ - var $item = $(this), - key = $item.data('contextMenuKey'), - item = opt.items[key], - disabled = ($.isFunction(item.disabled) && item.disabled.call($trigger, key, root)) || item.disabled === true; - - // dis- / enable item - $item[disabled ? 'addClass' : 'removeClass']('disabled'); - - if (item.type) { - // dis- / enable input elements - $item.find('input, select, textarea').prop('disabled', disabled); - - // update input states - switch (item.type) { - case 'text': - case 'textarea': - item.$input.val(item.value || ""); - break; - - case 'checkbox': - case 'radio': - item.$input.val(item.value || "").prop('checked', !!item.selected); - break; - - case 'select': - item.$input.val(item.selected || ""); - break; - } - } - - if (item.$menu) { - // update sub-menu - op.update.call($trigger, item, root); - } - }); - }, - layer: function(opt, zIndex) { - // add transparent layer for click area - // filter and background for Internet Explorer, Issue #23 - var $layer = opt.$layer = $('
    ') - .css({height: $win.height(), width: $win.width(), display: 'block'}) - .data('contextMenuRoot', opt) - .insertBefore(this) - .on('contextmenu', handle.abortevent) - .on('mousedown', handle.layerClick); - - // IE6 doesn't know position:fixed; - if (!$.support.fixedPosition) { - $layer.css({ - 'position' : 'absolute', - 'height' : $(document).height() - }); - } - - return $layer; - } - }; - -// split accesskey according to http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#assigned-access-key -function splitAccesskey(val) { - var t = val.split(/\s+/), - keys = []; - - for (var i=0, k; k = t[i]; i++) { - k = k[0].toUpperCase(); // first character only - // theoretically non-accessible characters should be ignored, but different systems, different keyboard layouts, ... screw it. - // a map to look up already used access keys would be nice - keys.push(k); - } - - return keys; -} - -// handle contextMenu triggers -$.fn.contextMenu = function(operation) { - if (operation === undefined) { - this.first().trigger('contextmenu'); - } else if (operation.x && operation.y) { - this.first().trigger($.Event("contextmenu", {pageX: operation.x, pageY: operation.y})); - } else if (operation === "hide") { - var $menu = this.data('contextMenu').$menu; - $menu && $menu.trigger('contextmenu:hide'); - } else if (operation === "destroy") { - $.contextMenu("destroy", {context: this}); - } else if ($.isPlainObject(operation)) { - operation.context = this; - $.contextMenu("create", operation); - } else if (operation) { - this.removeClass('context-menu-disabled'); - } else if (!operation) { - this.addClass('context-menu-disabled'); - } - - return this; -}; - -// manage contextMenu instances -$.contextMenu = function(operation, options) { - if (typeof operation != 'string') { - options = operation; - operation = 'create'; - } - - if (typeof options == 'string') { - options = {selector: options}; - } else if (options === undefined) { - options = {}; - } - - // merge with default options - var o = $.extend(true, {}, defaults, options || {}); - var $document = $(document); - var $context = $document; - var _hasContext = false; - - if (!o.context || !o.context.length) { - o.context = document; - } else { - // you never know what they throw at you... - $context = $(o.context).first(); - o.context = $context.get(0); - _hasContext = o.context !== document; - } - - switch (operation) { - case 'create': - // no selector no joy - if (!o.selector) { - throw new Error('No selector specified'); - } - // make sure internal classes are not bound to - if (o.selector.match(/.context-menu-(list|item|input)($|\s)/)) { - throw new Error('Cannot bind to selector "' + o.selector + '" as it contains a reserved className'); - } - if (!o.build && (!o.items || $.isEmptyObject(o.items))) { - throw new Error('No Items sepcified'); - } - counter ++; - o.ns = '.contextMenu' + counter; - if (!_hasContext) { - namespaces[o.selector] = o.ns; - } - menus[o.ns] = o; - - // default to right click - if (!o.trigger) { - o.trigger = 'right'; - } - - if (!initialized) { - // make sure item click is registered first - $document - .on({ - 'contextmenu:hide.contextMenu': handle.hideMenu, - 'prevcommand.contextMenu': handle.prevItem, - 'nextcommand.contextMenu': handle.nextItem, - 'contextmenu.contextMenu': handle.abortevent, - 'mouseenter.contextMenu': handle.menuMouseenter, - 'mouseleave.contextMenu': handle.menuMouseleave - }, '.context-menu-list') - .on('mouseup.contextMenu', '.context-menu-input', handle.inputClick) - .on({ - 'mouseup.contextMenu': handle.itemClick, - 'contextmenu:focus.contextMenu': handle.focusItem, - 'contextmenu:blur.contextMenu': handle.blurItem, - 'contextmenu.contextMenu': handle.abortevent, - 'mouseenter.contextMenu': handle.itemMouseenter, - 'mouseleave.contextMenu': handle.itemMouseleave - }, '.context-menu-item'); - - initialized = true; - } - - // engage native contextmenu event - $context - .on('contextmenu' + o.ns, o.selector, o, handle.contextmenu); - - if (_hasContext) { - // add remove hook, just in case - $context.on('remove' + o.ns, function() { - $(this).contextMenu("destroy"); - }); - } - - switch (o.trigger) { - case 'hover': - $context - .on('mouseenter' + o.ns, o.selector, o, handle.mouseenter) - .on('mouseleave' + o.ns, o.selector, o, handle.mouseleave); - break; - - case 'left': - $context.on('click' + o.ns, o.selector, o, handle.click); - break; - /* - default: - // http://www.quirksmode.org/dom/events/contextmenu.html - $document - .on('mousedown' + o.ns, o.selector, o, handle.mousedown) - .on('mouseup' + o.ns, o.selector, o, handle.mouseup); - break; - */ - } - - // create menu - if (!o.build) { - op.create(o); - } - break; - - case 'destroy': - var $visibleMenu; - if (_hasContext) { - // get proper options - var context = o.context; - $.each(menus, function(ns, o) { - if (o.context !== context) { - return true; - } - - $visibleMenu = $('.context-menu-list').filter(':visible'); - if ($visibleMenu.length && $visibleMenu.data().contextMenuRoot.$trigger.is($(o.context).find(o.selector))) { - $visibleMenu.trigger('contextmenu:hide', {force: true}); - } - - try { - if (menus[o.ns].$menu) { - menus[o.ns].$menu.remove(); - } - - delete menus[o.ns]; - } catch(e) { - menus[o.ns] = null; - } - - $(o.context).off(o.ns); - - return true; - }); - } else if (!o.selector) { - $document.off('.contextMenu .contextMenuAutoHide'); - $.each(menus, function(ns, o) { - $(o.context).off(o.ns); - }); - - namespaces = {}; - menus = {}; - counter = 0; - initialized = false; - - $('#context-menu-layer, .context-menu-list').remove(); - } else if (namespaces[o.selector]) { - $visibleMenu = $('.context-menu-list').filter(':visible'); - if ($visibleMenu.length && $visibleMenu.data().contextMenuRoot.$trigger.is(o.selector)) { - $visibleMenu.trigger('contextmenu:hide', {force: true}); - } - - try { - if (menus[namespaces[o.selector]].$menu) { - menus[namespaces[o.selector]].$menu.remove(); - } - - delete menus[namespaces[o.selector]]; - } catch(e) { - menus[namespaces[o.selector]] = null; - } - - $document.off(namespaces[o.selector]); - } - break; - - case 'html5': - // if or are not handled by the browser, - // or options was a bool true, - // initialize $.contextMenu for them - if ((!$.support.htmlCommand && !$.support.htmlMenuitem) || (typeof options == "boolean" && options)) { - $('menu[type="context"]').each(function() { - if (this.id) { - $.contextMenu({ - selector: '[contextmenu=' + this.id +']', - items: $.contextMenu.fromMenu(this) - }); - } - }).css('display', 'none'); - } - break; - - default: - throw new Error('Unknown operation "' + operation + '"'); - } - - return this; -}; - -// import values into commands -$.contextMenu.setInputValues = function(opt, data) { - if (data === undefined) { - data = {}; - } - - $.each(opt.inputs, function(key, item) { - switch (item.type) { - case 'text': - case 'textarea': - item.value = data[key] || ""; - break; - - case 'checkbox': - item.selected = data[key] ? true : false; - break; - - case 'radio': - item.selected = (data[item.radio] || "") == item.value ? true : false; - break; - - case 'select': - item.selected = data[key] || ""; - break; - } - }); -}; - -// export values from commands -$.contextMenu.getInputValues = function(opt, data) { - if (data === undefined) { - data = {}; - } - - $.each(opt.inputs, function(key, item) { - switch (item.type) { - case 'text': - case 'textarea': - case 'select': - data[key] = item.$input.val(); - break; - - case 'checkbox': - data[key] = item.$input.prop('checked'); - break; - - case 'radio': - if (item.$input.prop('checked')) { - data[item.radio] = item.value; - } - break; - } - }); - - return data; -}; - -// find