Index: openacs-4/packages/xotcl-core/tcl/03-doc-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/03-doc-procs.tcl,v
diff -u -r1.22 -r1.23
--- openacs-4/packages/xotcl-core/tcl/03-doc-procs.tcl 7 Dec 2018 08:43:54 -0000 1.22
+++ openacs-4/packages/xotcl-core/tcl/03-doc-procs.tcl 3 Sep 2024 15:37:54 -0000 1.23
@@ -1,7 +1,7 @@
ad_library {
XOTcl API for the API browser, defines the methods
ad_proc (for object specific methods),
- ad_instproc (for tradional methods) and
+ ad_instproc (for traditional methods) and
ad_doc (for documenting classes). Syntax for the methods
ad_proc and ad_instproc is like oacs ad_proc, ad_doc
receives one argument, similar to ad_library.
@@ -11,17 +11,6 @@
@cvs-id $Id$
}
-# Per default, the content of the ::xotcl:: namespace is not serialized;
-# so we add the specified methods explizitely to the export list
-::Serializer exportMethods {
- ::xotcl::Object instproc ad_proc
- ::xotcl::Object instproc ad_forward
- ::xotcl::Class instproc ad_instproc
- ::xotcl::Class instproc ad_instforward
- ::xotcl::Object instproc ad_doc
- ::nx::Class method init
-}
-
::nx::Object create ::xo::api {
array set :methodLabel {
@@ -121,36 +110,30 @@
# it multiple times).
#
if {$::__form_id eq "1"} {
- #
- # jquery is just needed for the used ajax call
- #
- template::head::add_javascript -src //code.jquery.com/jquery-1.12.4.min.js
- security::csp::require script-src code.jquery.com
template::add_body_script -script {
function ajax_submit(form) {
- //console.log(form);
- $.ajax({
- type: "POST",
- url: "/xotcl/admin/toggle-debug",
- data: $(form).serialize(),
- success: function(msg) {},
- error: function(){alert("failure");}
- });
+ var xhr = new XMLHttpRequest();
+ xhr.open('POST', '/xotcl/admin/toggle-debug', true);
+ xhr.onreadystatechange = function() {
+ if (this.readyState == 4) {
+ if (this.status != 200) {
+ alert('AJAX submit unexpected response: ' + this.status);
+ }
+ }
+ }
+ xhr.send(new FormData(form));
};
}
}
#
- # Add the required js and CSS. We use here bootstrap + titatoggle.
+ # Add the required js and CSS. We use here bootstrap + titatoggle,
+ # and assume, we have bootstrap3 installed
#
- template::head::add_css -href https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css
- template::head::add_javascript -src https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js -order 1
+ #template::head::add_css -href urn:ad:css:bootstrap3
+ #template::head::add_javascript -src urn:ad:js:bootstrap3
- security::csp::require style-src maxcdn.bootstrapcdn.com
- security::csp::require script-src maxcdn.bootstrapcdn.com
- security::csp::require font-src maxcdn.bootstrapcdn.com
-
template::head::add_css -href "/resources/xotcl-core/titatoggle/titatoggle-dist.css"
#
# Return an HTML snippet with a form and the computed form-ID
@@ -209,7 +192,10 @@
:public object method scope {} {
if {[info exists ::xotcl::currentThread]} {
- # we are in an xotcl thread; the body won't be accessible directly
+ #
+ # We are in an XOTcl thread; the body won't be accessible
+ # by default without the explicit scope.
+ #
return $::xotcl::currentThread
}
return ""
@@ -232,7 +218,7 @@
if {$script eq "" && [info exists ::xotcl::currentScript]} {
set script $::xotcl::currentScript
}
- set root_dir [acs_root_dir]
+ set root_dir $::acs::rootdir
set root_length [string length $root_dir]
if { $root_dir eq [string range $script 0 $root_length-1]} {
set script [string range $script $root_length+1 end]
@@ -266,9 +252,9 @@
:public object method proc_index {scope obj instproc proc_name} {
if {$scope eq ""} {
- return "$obj $instproc $proc_name"
+ return [list [string trimleft $obj :] $instproc $proc_name]
} else {
- return "$scope $obj $instproc $proc_name"
+ return [list $scope $obj $instproc $proc_name]
}
}
@@ -302,20 +288,20 @@
}
set string [join $lines \n]
set html [ns_quotehtml $string]
- regsub -all {(\n[\t ]*)(\#[^\n]*)} $html \\1
$html" } :public object method get_doc_block {text {restVar ""}} { # # Get the (first) documentation block of the provided text (which - # might be e.g. the body of a method) + # might be e.g. the body of a method). # set lines [split $text \n] set docBlock "" set i 0 set nrLines [llength $lines] - while {[string trim [lindex $lines $i]] eq "" && $i < $nrLines} {incr i} + while {[string is space [lindex $lines $i]] && $i < $nrLines} {incr i} while {$i < $nrLines} { set line [string trim [lindex $lines $i]] incr i @@ -324,22 +310,21 @@ } if {$restVar ne ""} { upvar $restVar rest - set rest [join [lrange $lines $i end] \n] + set rest [join [lrange $lines $i-1 end] \n] } #ns_log notice "=================== get_doc_block RETURNS <$docBlock>" return $docBlock } :public object method update_object_doc {scope obj doc_string} { - ns_log notice "update_object_doc $scope $obj ..." # # Update the API browser nsvs with information about the provided # object. # - # If no doc string is provided, try to get it from the object # definition. # + if {$doc_string eq ""} { set doc_string [:get_doc_block [:get_init_block $scope $obj]] } @@ -372,11 +357,15 @@ set proc_index [::xo::api object_index $scope $obj] set doc [dict replace $doc \ default_values "" \ - switches $switches \ + switches0 $switches \ + switches1 "" \ positionals "" \ flags $flags \ ] #ns_log notice "proc_index <$proc_index> -> $doc" + if {![nsv_exists api_proc_doc $proc_index]} { + nsv_lappend api_proc_doc_scripts [dict get $doc script] $proc_index + } nsv_set api_proc_doc $proc_index $doc nsv_set api_library_doc $proc_index $doc @@ -403,7 +392,7 @@ # foreach protection {public protected private} { foreach m [::nsf::dispatch $obj ::nsf::methods::class::info::methods \ - -callprotection $protection -type scripted] { + -path -callprotection $protection -type scripted] { set docBlock [:get_doc_block \ [::nsf::dispatch $obj ::nsf::methods::class::info::method body $m]] ::xo::api update_method_doc \ @@ -437,13 +426,13 @@ } :public object method update_method_doc { - {-protection "public"} - {-deprecated:switch false} - {-debug:switch false} - {-warn:switch false} - scope obj inst proc_name - docString - } { + {-protection "public"} + {-deprecated:switch false} + {-debug:switch false} + {-warn:switch false} + scope obj inst proc_name + docString + } { set methodType [::xo::getObjectProperty $obj ${inst}methodtype $proc_name] set varargs_p [expr {$methodType eq "scripted" && "args" in [::xo::getObjectProperty $obj ${inst}args $proc_name]}] @@ -452,12 +441,13 @@ param "" \ protection $protection \ varargs_p $varargs_p \ - deprecated_p false \ + deprecated_p $deprecated \ warn_p false \ script [::xo::api script_name $scope] \ main "" \ flags "" \ - switches "" \ + switches0 "" \ + switches1 "" \ ] if {$docString ne ""} { @@ -488,15 +478,17 @@ set name $flaggedName } if {$isFlag} { - dict lappend doc switches $name + dict lappend doc switches0 $name dict lappend doc flags $name $flags - #my log "default_value $proc_name: $sw -> '[lindex $f 1]' <$pair/$f>" + #:log "default_value $proc_name: $sw -> '[lindex $f 1]' <$pair/$f>" if {$flags eq "switch" && $default eq ""} { set default "false" } } - #my log "default_value $proc_name: $sw -> 'default' <$pair/$f>" - if {[llength $def] > 1} {lappend defaults $name $default} + #:log "default_value $proc_name: $sw -> 'default' <$pair/$f>" + if {[llength $def] > 1} { + lappend defaults $name $default + } } dict set doc default_values $defaults dict set doc positionals [::xo::getObjectProperty $obj ${inst}args $proc_name] @@ -523,6 +515,9 @@ } :public object method get_object_source {scope obj} { + # + # Return the full object definition + # if {![nsf::is object $obj]} { ns_log warning "[self] get_object_source: argument passed as obj is not an object: $obj" return "" @@ -537,17 +532,34 @@ } :public object method get_method_source {scope obj prefix method} { + # + # Return the full method definition. + # :scope_eval $scope ::Serializer methodSerialize $obj $method $prefix } + :public object method get_method_body {scope obj prefix method} { + # + # Return the method body on object (when "prefix" is empty) or + # class (when "prefix" is "inst"). + # + :scope_eval $scope ::nsf::dispatch $obj \ + ::nsf::methods::[expr {$prefix eq "inst" ? "class" : "object"}]::info::method \ + body $method + } + :public object method update_nx_docs {{objects ""}} { + # + # Update for the provided (or all) nx::Object instances the + # internal documentation structures. + # if {[llength $objects] == 0} { set objects [nx::Object info instances -closure] } foreach o $objects { # - # check general per-object documentation + # Check general per-object documentation. # if {[string match ::nx::* $o]} continue ::xo::api update_object_doc "" $o "" @@ -573,10 +585,28 @@ } } -::nx::Class public method init {} { +# --------------------------------------------------------------------- +# +# Per default, the content of the "::xotcl" and "::nx" namespace is +# not serialized; so when extending the base classes of the object +# system, one has to these methods explizitely to the export list for +# the serializer. +# +# The following extensions of the base classes are defined here: +# +::Serializer exportMethods { + ::nx::Class method init + ::xotcl::Object instproc ad_proc + ::xotcl::Object instproc ad_forward + ::xotcl::Class instproc ad_instproc + ::xotcl::Class instproc ad_instforward + ::xotcl::Object instproc ad_doc +} + +::nx::Class method init {} { set r [next] # - # When loading the blueprint, ::xo::api might not be available yet + # When loading the blueprint, ::xo::api might not be available yet. # if {[info commands ::xo::api] ne ""} { ::xo::api update_object_doc "" [self] ""