Index: openacs-4/packages/xowiki/tcl/bootstrap-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/bootstrap-procs.tcl,v diff -u -r1.3.2.10 -r1.3.2.11 --- openacs-4/packages/xowiki/tcl/bootstrap-procs.tcl 12 Sep 2016 11:40:26 -0000 1.3.2.10 +++ openacs-4/packages/xowiki/tcl/bootstrap-procs.tcl 13 Sep 2016 10:50:23 -0000 1.3.2.11 @@ -34,6 +34,14 @@ ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" set css [parameter::get_global_value -package_key xowiki -parameter BootstrapCSS] set js [parameter::get_global_value -package_key xowiki -parameter BootstrapJS] + # + # TODO: We should dynamically be able to determine the + # directives. However, for the time being, the urls below are + # trusted. + # + security::csp::require script-src maxcdn.bootstrapcdn.com + security::csp::require style-src maxcdn.bootstrapcdn.com + foreach url $css {::xo::Page requireCSS $url} foreach url $js {::xo::Page requireJS $url} next @@ -119,10 +127,16 @@ BootstrapNavbarDropdownMenuItem ad_instproc render {} {doku} { html::li -class [expr {[my set href] eq "" ? "disabled": ""}] { - html::a [my get_attributes target href title] { + html::a [my get_attributes target href title id] { html::t [my text] } } + if {[my exists listener] && [my set listener] ne ""} { + lassign [my listener] type body + template::add_body_script -script [subst { + document.getElementById('[my set id]').addEventListener('$type', function (event) {$body}, false); + }] + } } # @@ -137,7 +151,7 @@ } BootstrapNavbarDropzone instproc js {-uploadlink:required} { - html::script -type "text/javascript" { + html::script -type "text/javascript" -nonce $::__csp_nonce { html::t [subst -nocommands { + function($) { 'use strict'; @@ -361,7 +375,9 @@ ::xowiki::BootstrapNavbarDropdownMenuItem \ -text [my get_prop $item label] \ -href [my get_prop $item url] \ - -group [my get_prop $item group] {} + -group [my get_prop $item group] \ + -listener [my get_prop $item listener] \ + {} } } } @@ -435,18 +451,24 @@ set name [$bulkaction_container set __identifier] foreach ba $bulkactions { + set id [::xowiki::Includelet html_id $ba] html::ul -class compact { html::li { # For some reason, btn-secondary seems not to be available # for the "a" tag, so we set the border-color manually. html::a -class "btn btn-secondary" -rule button \ -title [$ba tooltip] -href # \ -style "border-color: #ccc;" \ - -onclick "acs_ListBulkActionClick('$name','[$ba url]'); return false;" { + -id $id { html::t [$ba label] } } } + template::add_body_script -script [subst { + document.getElementById('$id').addEventListener('click', function (event) { + acs_ListBulkActionClick('$name','[$ba url]'); + }, false); + }] } } } Index: openacs-4/packages/xowiki/tcl/folder-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/folder-procs.tcl,v diff -u -r1.33.2.6 -r1.33.2.7 --- openacs-4/packages/xowiki/tcl/folder-procs.tcl 25 May 2016 19:33:46 -0000 1.33.2.6 +++ openacs-4/packages/xowiki/tcl/folder-procs.tcl 13 Sep 2016 10:50:23 -0000 1.33.2.7 @@ -334,7 +334,7 @@ # allowed to do this with certain items.... (the latter in # clipboad-add) $mb add_menu_item -name Clipboard.Add \ - -item [list url javascript:acs_ListBulkActionClick("objects","$folder_link?m=clipboard-add")] + -item [list url \# listener [list click acs_ListBulkActionClick("objects","$folder_link?m=clipboard-add")]] $mb add_menu_item -name Clipboard.Content -item [list url $clipboard_content_link] $mb add_menu_item -name Clipboard.Clear -item [list url $clipboard_clear_link] $mb add_menu_item -name Clipboard.Use.Copy -item [list url $clipboard_copy_link] Index: openacs-4/packages/xowiki/tcl/menu-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/menu-procs.tcl,v diff -u -r1.8.2.4 -r1.8.2.5 --- openacs-4/packages/xowiki/tcl/menu-procs.tcl 25 May 2016 19:33:46 -0000 1.8.2.4 +++ openacs-4/packages/xowiki/tcl/menu-procs.tcl 13 Sep 2016 10:50:23 -0000 1.8.2.5 @@ -57,6 +57,7 @@ linkclass target {group ""} + {listener} } Index: openacs-4/packages/xowiki/tcl/yui-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/yui-procs.tcl,v diff -u -r1.5.2.2 -r1.5.2.3 --- openacs-4/packages/xowiki/tcl/yui-procs.tcl 25 May 2016 19:33:46 -0000 1.5.2.2 +++ openacs-4/packages/xowiki/tcl/yui-procs.tcl 13 Sep 2016 10:50:23 -0000 1.5.2.3 @@ -74,6 +74,7 @@ http://developer.yahoo.com/yui/menu/ } { my append CSSclass " yuimenu" + my set extrajs "" # I want the menu to show up when JS is disabled # This gets overridden by JS, so its only relevant for the non-JS version @@ -109,12 +110,19 @@ # JavaScript # only "root-level" menus need JS # TODO: is this parent-check sufficient / future-safe? - if {![my exists __parent]} { + if {[my exists __parent]} { + # + # propagate extrajs from rendering + # + #ns_log notice "### propagate extrajs <[my set extrajs]> from [my info class] to [[my set __parent] info class]" + [my set __parent] append extrajs [my set extrajs] + } else { html::script -type "text/javascript" { html::t "var [my js_name] = new YAHOO.widget.Menu(\"[my id]\", [my set configuration]);" html::t " [my js_name].render(); [my js_name].show(); + [my set extrajs] " } } @@ -135,6 +143,15 @@ html::li [my get_attributes id {CSSclass class} style] { # if we have no href, mark entry as disabled if {![my exists href] || [my href] eq ""} {my append linkclass " disabled"} + if {[my exists listener] && [my set listener] ne ""} { + #ns_log notice "menuitem has id [my id] listener [my listener] parent [my set __parent] [[my set __parent] info class]" + lassign [my listener] type body + [my set __parent] append extrajs [subst { + document.getElementById('[my id]').addEventListener('$type', function (event) { + $body; + }, false); + }] + } html::a [my get_attributes target href {linkclass class} title] { html::t [my text] if {[my exists helptext]} { @@ -163,6 +180,7 @@ MenuBar looks best without a header and with one MenuItemList only } { my append CSSclass " yuimenubar" + my set extrajs "" if {[my navbar]} {my append CSSclass " yuimenubarnav"} html::div [my get_attributes id {CSSclass class}] { html::div -class "bd" { @@ -177,6 +195,7 @@ ::xo::Page requireJS "YAHOO.util.Event.onDOMReady(function () { var [my js_name] = new YAHOO.widget.MenuBar('[my id]', [my set configuration]); [my js_name].render(); + [my set extrajs] });" } } @@ -197,7 +216,18 @@ } } - + YUIMenuBarItem ad_instproc render {} {} { + my set extrajs "" + set result [next] + if {[my exists __parent]} { + # + # propagate extrajs from rendering + # + #ns_log notice "### propagate extrajs <[my set extrajs]> from [my info class] to [[my set __parent] info class]" + [my set __parent] append extrajs [my set extrajs] + } + } + # # YUIContextMenu # @@ -249,11 +279,11 @@ ::xowiki::YUIMenu { foreach {item_att item} $menu { if {[string match {[a-z]*} $item_att]} continue - set text [my get_prop $item label] - set url [my get_prop $item url] - set group [my get_prop $item group] - #my log "ia=$item_att group '$group' // t=$text item=$item" - ::xowiki::YUIMenuItem -text $text -href $url -group $group {} + ::xowiki::YUIMenuItem \ + -text [my get_prop $item label] \ + -href [my get_prop $item url] \ + -group [my get_prop $item group] \ + -listener [my get_prop $item listener] {} } } } @@ -463,7 +493,7 @@ set datasource ${id}_datasource set datatable ${id}_datatable set coldef ${id}_coldef - + set finaljs "" set js "var $datasource = new YAHOO.util.DataSource(YAHOO.util.Dom.get('$id')); \n" append js "$datasource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE; \n" append js "$datasource.responseSchema = \{ \n" @@ -480,11 +510,17 @@ if {[$field hide]} continue if {[$field istype HiddenField]} continue if {[$field istype BulkAction]} { - set label "" + set subid [::xowiki::Includelet html_id $field] + set label "" if {[info exists ::__csrf_token]} { - append label \n "" + append label "" } set sortable false + append finaljs [subst { + document.getElementById('$subid').addEventListener('click', function (event) { + acs_ListCheckAll('objects', this.checked); + }, false); + }] } else { set label [lang::util::localize [$field label]] set sortable [expr {[$field exists sortable] ? [$field set sortable] : true}] @@ -493,6 +529,7 @@ } append js [join $js_fields ", "] "\];\n" append js "var $datatable = new YAHOO.widget.DataTable('$container', $coldef, $datasource);\n" + append js $finaljs return $js }