Index: openacs-4/packages/xowiki/xowiki.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/xowiki.info,v diff -u -N -r1.180.2.92 -r1.180.2.93 --- openacs-4/packages/xowiki/xowiki.info 25 Mar 2022 10:13:47 -0000 1.180.2.92 +++ openacs-4/packages/xowiki/xowiki.info 1 Apr 2022 13:47:51 -0000 1.180.2.93 @@ -10,7 +10,7 @@ t xowiki - + Gustaf Neumann A xotcl-based enterprise wiki system with multiple object types 2021-09-15 @@ -55,7 +55,7 @@ BSD-Style 2 - + @@ -82,7 +82,7 @@ - + 0} { - html::ul -class "nav navbar-nav navbar-right" { + html::ul -class "nav navbar-nav [::xowiki::CSS class navbar-right]" { foreach entry $rightMenuEntries { $entry render } @@ -83,9 +82,9 @@ # get group header set group " " - html::ul -class "nav navbar-nav" { - html::li -class "dropdown" { - set class "dropdown-toggle" + html::ul -class "nav navbar-nav px-3" { + html::li -class "nav-item dropdown" { + set class "nav-link dropdown-toggle" if {[:brand]} {lappend class "navbar-brand"} html::a -href "\#" -class $class -data-toggle "dropdown" { html::t [:text] @@ -119,7 +118,7 @@ } BootstrapNavbarDropdownMenuItem ad_instproc render {} {doku} { - html::li -class [expr {${:href} eq "" ? "disabled": ""}] { + html::li -class [expr {${:href} eq "" ? "nav-item disabled": "nav-item"}] { html::a [:get_attributes target href title id] { html::t ${:text} } @@ -311,6 +310,32 @@ } } + ::xo::tdom::Class create BootstrapCollapseButton \ + -parameter { + {id:required} + {toggle:required} + {direction:required} + {label:required} + } + + BootstrapCollapseButton instproc init {} { + switch [::xowiki::CSS toolkit] { + "bootstrap" { + template::add_script -src urn:ad:js:bootstrap3 + ::html::button -type button -class "btn btn-xs" -data-toggle ${:toggle} -data-target "#${:id}" { + ::html::span -class "glyphicon glyphicon-chevron-${:direction}" {::html::t ${:label}} + } + } + "bootstrap5" { + template::add_script -src urn:ad:js:bootstrap5 + ::html::button -type button -class "btn btn-sm" -data-bs-toggle ${:toggle} -data-bs-target "#${:id}" { + ::html::i -class "bi bi-chevron-${:direction}" {::html::t ${:label}} + } + } + } + } + + # ======================================================= # ::xo::library doc { # ... styling for bootstrap menubar ... @@ -414,8 +439,8 @@ -instproc init_renderer {} { next set :css.table-class "table table-striped" - set :css.tr.even-class even - set :css.tr.odd-class odd + set :css.tr.even-class "align-middle" + set :css.tr.odd-class "align-middle" set :id [::xowiki::Includelet js_name [::xowiki::Includelet html_id [self]]] } @@ -457,7 +482,7 @@ BootstrapTableRenderer instproc render-bulkactions {} { set bulkactions [[self]::__bulkactions children] if {[llength $bulkactions] > 0} { - html::div -class "btn-group" -role group -aria-label "Bulk actions" { + html::div -class "btn-group align-items-center" -role group -aria-label "Bulk actions" { html::t "#xotcl-core.Bulk_actions#:" set bulkaction_container [[lindex $bulkactions 0] set __parent] set name [$bulkaction_container set __identifier] @@ -466,7 +491,7 @@ set id [::xowiki::Includelet html_id $bulk_action] html::ul -class compact { html::li { - html::a -class "btn [::xowiki::CSS class btn-default]" -rule button \ + html::a -class [::xowiki::CSS class bulk-action] -rule button \ -title [$bulk_action tooltip] -href # \ -id $id { html::t [$bulk_action label] @@ -493,7 +518,7 @@ } BootstrapTableRenderer instproc render {} { - ::xo::Page requireCSS urn:ad:css:bootstrap3 + ::xowiki::CSS require_toolkit -css if {![nsf::is object [self]::__actions]} {:actions {}} if {![nsf::is object [self]::__bulkactions]} {:__bulkactions {}} 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 -N -r1.55.2.54 -r1.55.2.55 --- openacs-4/packages/xowiki/tcl/folder-procs.tcl 20 Feb 2022 17:06:17 -0000 1.55.2.54 +++ openacs-4/packages/xowiki/tcl/folder-procs.tcl 1 Apr 2022 13:47:51 -0000 1.55.2.55 @@ -578,6 +578,7 @@ -link $current_folder_pretty_link \ $current_folder bulk-delete $csrf return_url] switch [::$package_id get_parameter PreferredCSSToolkit bootstrap] { + bootstrap5 - bootstrap {set tableWidgetClass ::xowiki::BootstrapTable} default {set tableWidgetClass ::xowiki::YUIDataTable} } Index: openacs-4/packages/xowiki/tcl/form-field-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/form-field-procs.tcl,v diff -u -N -r1.284.2.212 -r1.284.2.213 --- openacs-4/packages/xowiki/tcl/form-field-procs.tcl 31 Mar 2022 14:16:21 -0000 1.284.2.212 +++ openacs-4/packages/xowiki/tcl/form-field-procs.tcl 1 Apr 2022 13:47:51 -0000 1.284.2.213 @@ -1309,20 +1309,14 @@ } FormField instproc render_collapsed {-id:required {-label ""} -inner_method} { - template::add_script -src urn:ad:js:bootstrap3 - set num [clock clicks -microseconds] - ::html::button -type button -class "btn btn-xs" -data-toggle "collapse" -data-target "#$id" { - ::html::span -class "glyphicon glyphicon-chevron-down" {::html::t $label} - } + ::xowiki::BootstrapCollapseButton new -id $id -label $label -toggle "collapse" -direction "down" ::html::div -id "$id" -class "collapse" { :$inner_method } } FormField instproc render_modal {-id:required {-label ""} -inner_method} { - ::html::button -type button -class "btn btn-xs" -data-toggle "modal" -data-target "#$id" { - ::html::span -class "glyphicon glyphicon-chevron-down" {::html::t $label} - } + ::xowiki::BootstrapCollapseButton new -id $id -label $label -toggle "modal" -direction "down" ::html::div -id "$id" -class "modal fade" -tabindex -1 -role dialog aria-hidden "true" { ::html::div -class "modal-dialog" -role document { ::html::div -class "modal-content" { 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 -N -r1.19.2.16 -r1.19.2.17 --- openacs-4/packages/xowiki/tcl/menu-procs.tcl 9 Aug 2021 09:55:57 -0000 1.19.2.16 +++ openacs-4/packages/xowiki/tcl/menu-procs.tcl 1 Apr 2022 13:47:51 -0000 1.19.2.17 @@ -131,7 +131,7 @@ id {dropzone:boolean true} {current_folder:object} - {parent_id ""} + {parent_id:integer,0..1 ""} } ::xowiki::MenuBar instproc get_prop {dict key {default ""}} { @@ -311,11 +311,9 @@ {object_type ::xowiki::File} \ parent_id return_url autoname template_file] - set new_form_link \ - [::$package_id make_link \ - ::$package_id edit-new \ - {object_type ::xowiki::Form} \ - parent_id return_url autoname template_file] + set new_form_link [::$package_id make_form_link -form en:form.form \ + -parent_id ${:parent_id} \ + -nls_language $nls_language -return_url $return_url] } :add_menu_item -name New.Page -item [list url $new_page_link] @@ -608,8 +606,9 @@ -package_key xowiki \ -parameter PreferredCSSToolkit \ -default bootstrap] { - bootstrap {set menuBarRenderer render-bootstrap} - default {set menuBarRenderer render-yui} + bootstrap - + bootstrap5 {set menuBarRenderer render-bootstrap} + default {set menuBarRenderer render-yui} } :$menuBarRenderer } Index: openacs-4/packages/xowiki/tcl/package-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/package-procs.tcl,v diff -u -N -r1.332.2.111 -r1.332.2.112 --- openacs-4/packages/xowiki/tcl/package-procs.tcl 25 Mar 2022 10:13:47 -0000 1.332.2.111 +++ openacs-4/packages/xowiki/tcl/package-procs.tcl 1 Apr 2022 13:47:51 -0000 1.332.2.112 @@ -23,23 +23,74 @@ # return ${:preferredCSSToolkit} } + + :public object method require_toolkit {{-css:switch} {-js:switch}} { + # + # Make sure that the preferred toolkit is loaded. Not that some + # combination won't match nicely, since e.g. the toolbar of a + # theme based on bootstrap5 is messed up, when the preferred + # toolkit is bootstrap3. .... so, we should have some default + # setting or fallbacks to handle such situations. + # + if {${:preferredCSSToolkit} eq "bootstrap5"} { + if {$css} {::xo::Page requireCSS urn:ad:css:bootstrap5} + if {$js} {::xo::Page requireJS urn:ad:js:bootstrap5} + } elseif {${:preferredCSSToolkit} eq "bootstrap"} { + if {$css} {::xo::Page requireCSS urn:ad:css:bootstrap3} + if {$js} {::xo::Page requireJS urn:ad:js:bootstrap3} + } else { + # YUI has many simple files, let the application decide what + # to be loaded. + } + } + :public object method initialize {} { # - # Initialize tailorization for CSS tooklits. The function reads + # Initialize tailorization for CSS toolkits. The function reads # the global apm package parameter and sets/resets accordingly # (a) the default values (actially parameters) for the form # field and (b) defines the toolkit specific CSS class name # mapping. # # + # Loading optional, but universally present header files has do + # be performed per request... not sure this is the best place, + # since packages are as well initialized in the background. + # + if {[ns_conn isconnected] && [apm_package_enabled_p "bootstrap-icons"]} { + template::head::add_css -href urn:ad:css:bootstrap-icons + } + set paramValue [parameter::get_global_value -package_key xowiki \ -parameter PreferredCSSToolkit \ - -default bootstrap] + -default default] + # + # Check, if parameter value is compatible with the theme. In + # particular, a preferred toolkit of "bootstrap3" does not work + # when the theme is based on Bootstrap 5 and vice versa. When necessary, + # align the value. + # + if {$paramValue in {default bootstrap bootstrap5} && [ns_conn isconnected]} { + set theme [subsite::get_theme] + if {$paramValue in {bootstrap default} && [string match *bootstrap5* $theme]} { + set paramValue bootstrap5 + } elseif {$paramValue in {bootstrap5 default} && [string match *bootstrap3* $theme]} { + set paramValue bootstrap + } + if {$paramValue eq "default"} { + # For the time being, Bootstrap 3 is the default. + set paramValue bootstrap + } + } if {[info exists :preferredCSSToolkit] && ${:preferredCSSToolkit} eq $paramValue } { return } + # + # The code below is executed only on first initialization of the + # object or on changes of the preferredCSSToolkit. + # set :preferredCSSToolkit $paramValue if {${:preferredCSSToolkit} eq "bootstrap"} { @@ -53,19 +104,23 @@ } set :cssClasses { btn-default btn-default + bulk-action "btn btn-default" margin-form "" } } elseif {${:preferredCSSToolkit} eq "bootstrap5"} { ::xowiki::formfield::FormField parameter { {CSSclass form-control} {form_item_wrapper_CSSclass form-group} {form_widget_CSSclass ""} - {form_button_CSSclass "btn btn-secondary"} + {form_button_CSSclass "btn btn-outline-secondary btn-sm"} {form_button_wrapper_CSSclass ""} {form_help_text_CSSclass help-block} } set :cssClasses { - btn-default btn-secondary + btn-default btn-outline-secondary + bulk-action "btn btn-outline-secondary btn-sm" + navbar-default navbar-light + navbar-right ms-auto margin-form "" } } else { @@ -97,6 +152,13 @@ return $name } } + + :public object method classes {classNames} { + # + # Map a list of CSS class names + # + return [join [lmap class $classNames {:class $class}] " "] + } } } Index: openacs-4/packages/xowiki/tcl/resource-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/resource-init.tcl,v diff -u -N -r1.3.2.13 -r1.3.2.14 --- openacs-4/packages/xowiki/tcl/resource-init.tcl 22 Jul 2021 19:14:03 -0000 1.3.2.13 +++ openacs-4/packages/xowiki/tcl/resource-init.tcl 1 Apr 2022 13:47:51 -0000 1.3.2.14 @@ -24,7 +24,7 @@ # xowiki.css + xowiki-bootstrap3-specific.css -> xowiki-bootstrap3.css # set resDir $::acs::rootdir/packages/xowiki/www/resources -foreach variant {yui bootstrap3} { +foreach variant {yui bootstrap3 bootstrap5} { if {![ad_file exists $resDir/xowiki-$variant.css] || [ad_file mtime $resDir/xowiki-$variant.css] < [ad_file mtime $resDir/xowiki.css] || [ad_file mtime $resDir/xowiki-$variant.css] < [ad_file mtime $resDir/xowiki-$variant-specific.css] @@ -43,6 +43,7 @@ template::register_urn -urn urn:ad:css:xowiki-yui -resource /resources/xowiki/xowiki-yui.css template::register_urn -urn urn:ad:css:xowiki-bootstrap -resource /resources/xowiki/xowiki-bootstrap3.css +template::register_urn -urn urn:ad:css:xowiki-bootstrap5 -resource /resources/xowiki/xowiki-bootstrap5.css set resource_info [xowiki::bootstrap_treeview::resource_info -version 1.2.0] foreach URN [dict keys [dict get $resource_info urnMap]] { Index: openacs-4/packages/xowiki/tcl/table-widget-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/Attic/table-widget-procs.tcl,v diff -u -N -r1.1.2.17 -r1.1.2.18 --- openacs-4/packages/xowiki/tcl/table-widget-procs.tcl 23 Mar 2022 20:37:16 -0000 1.1.2.17 +++ openacs-4/packages/xowiki/tcl/table-widget-procs.tcl 1 Apr 2022 13:47:51 -0000 1.1.2.18 @@ -108,8 +108,9 @@ -package_key xowiki \ -parameter PreferredCSSToolkit \ -default bootstrap] { - bootstrap {set renderer BootstrapTableRenderer} - default {set renderer YUIDataTableRenderer} + bootstrap - + bootstrap5 {set renderer BootstrapTableRenderer} + default {set renderer YUIDataTableRenderer} } lappend cmd -renderer $renderer } Index: openacs-4/packages/xowiki/tcl/test/includelet-test-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/test/Attic/includelet-test-procs.tcl,v diff -u -N -r1.1.2.4 -r1.1.2.5 --- openacs-4/packages/xowiki/tcl/test/includelet-test-procs.tcl 8 Mar 2022 08:52:10 -0000 1.1.2.4 +++ openacs-4/packages/xowiki/tcl/test/includelet-test-procs.tcl 1 Apr 2022 13:47:51 -0000 1.1.2.5 @@ -33,7 +33,7 @@ "toc-folder" $root_folder_id $package_id] # - # Create pages for toc testing, including page_order comparsions + # Create pages for toc testing, including page_order comparisons # foreach po { 1 Index: openacs-4/packages/xowiki/tcl/test/test-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/test/test-procs.tcl,v diff -u -N -r1.15.2.31 -r1.15.2.32 --- openacs-4/packages/xowiki/tcl/test/test-procs.tcl 14 Mar 2022 11:08:29 -0000 1.15.2.31 +++ openacs-4/packages/xowiki/tcl/test/test-procs.tcl 1 Apr 2022 13:47:51 -0000 1.15.2.32 @@ -514,29 +514,66 @@ # # New form creation happens over the top-level URL # + #set d [acs::test::http \ + # -last_request $last_request -user_id $user_id \ + # $instance/?object_type=::xowiki::Form&edit-new=1&parent_id=$parent_id&return_url=$instance/$path] + set d [acs::test::http \ -last_request $last_request -user_id $user_id \ - $instance/?object_type=::xowiki::Form&edit-new=1&parent_id=$parent_id&return_url=$instance/$path] - acs::test::reply_has_status_code $d 200 + $instance/form.form?m=create-new&parent_id=$parent_id&return_url=$instance/$path] + # + # If we use form.form, we get a redirect; classical + # "object_type=::xowiki::Form&edit-new=1" has no redirect. + # + if {[acs::test::reply_has_status_code $d 302]} { - set response [dict get $d body] - #ns_log notice response=$response - set formCSSClass "margin-form" + set location [::acs::test::get_url_from_location $d] + set d [acs::test::http -last_request $last_request -user_id $user_id $location/] + acs::test::reply_has_status_code $d 200 + set formform 1 - acs::test::dom_html root $response { + set response [::xowiki::test::get_content $d] + #ns_log notice response=$response + set formCSSClass "Form-form" - set selector [subst {string(//form\[contains(@class,'$formCSSClass')\]//input\[@type='submit'\]/@value)}] - set f_submit [$root selectNodes $selector] - aa_true "submit_button '$f_submit' is non empty" {$f_submit ne ""} + acs::test::dom_html root $response { - set f_id [::xowiki::test::get_object_name $root] - aa_true "page_id '$f_id' is empty" {$f_id eq ""} - } + set selector [subst {string(//form\[contains(@class,'$formCSSClass')\]//button\[@type='submit'\])}] + set f_submit [$root selectNodes $selector] + aa_true "submit_button '$f_submit' is non empty" {$f_submit ne ""} - set form [acs::test::get_form $response "//form\[contains(@class,'$formCSSClass')\]"] + set f_id [::xowiki::test::get_object_name $root] + aa_false "page_id '$f_id' is empty" {$f_id eq ""} + } + set form [acs::test::get_form $response "//form\[contains(@class,'$formCSSClass')\]"] + ns_log notice "FORM <$form>" - set f_page_name [dict get $form fields name] - set f_creator [dict get $form fields creator] + set f_page_name [dict get $form fields _name] + set f_creator [dict get $form fields _creator] + } else { + acs::test::reply_has_status_code $d 200 + set formform 0 + + set response [dict get $d body] + #ns_log notice response=$response + set formCSSClass "margin-form" + + acs::test::dom_html root $response { + + set selector [subst {string(//form\[contains(@class,'$formCSSClass')\]//input\[@type='submit'\]/@value)}] + set f_submit [$root selectNodes $selector] + aa_true "submit_button '$f_submit' is non empty" {$f_submit ne ""} + + set f_id [::xowiki::test::get_object_name $root] + aa_true "page_id '$f_id' is empty" {$f_id eq ""} + } + set form [acs::test::get_form $response "//form\[contains(@class,'$formCSSClass')\]"] + ns_log notice "FORM <$form>" + + set f_page_name [dict get $form fields name] + set f_creator [dict get $form fields creator] + } + set f_form_action [dict get $form @action] aa_true "name '$f_page_name' is empty" {$f_page_name eq ""} @@ -550,7 +587,7 @@ aa_true "page has at least 9 fields" { [llength $names] >= 9 } aa_log "empty form_content:\n$[::xowiki::test::pretty_form_content $form_content]" - dict set form_content name $name + dict set form_content [expr {$formform ? "_name" : "name"}] $name set form [acs::test::form_set_fields $form $form_content] set d [::acs::test::form_reply \