Index: openacs-4/packages/xotcl-core/xotcl-core.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/xotcl-core.info,v diff -u -N -r1.22 -r1.22.2.1 --- openacs-4/packages/xotcl-core/xotcl-core.info 29 Dec 2006 11:04:16 -0000 1.22 +++ openacs-4/packages/xotcl-core/xotcl-core.info 1 Aug 2007 21:39:31 -0000 1.22.2.1 @@ -8,10 +8,10 @@ t xotcl - + Gustaf Neumann XOTcl library functionality (e.g. thread handling, online documentation, Generic Form and List Classes) - 2006-12-29 + 2007-08-01 This component contains some core functionality for OACS applications using XOTcl. It includes XOTcl thread handling for OACS (supporting persistent and @@ -30,11 +30,16 @@ 0.41: supporting storage_type file, on_submit method and html for forms; 0.43: context and connection context; 0.44: use connection_context, sch regression test works; -0.45: xo:db require operations; +0.45: xo:db require operations; +0.48: policies +0.49: stored procedures object proxies (postgres and Oracle) +0.51: require package +0.52: distinguish between ImageField and ImageAnchorField, start using slots, multivalued form entries, bulk-actions, improved localization, improved sql layer (:.xo::db::sql) + BSD-Style 0 - + Index: openacs-4/packages/xotcl-core/catalog/xotcl-core.de_DE.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/catalog/xotcl-core.de_DE.ISO-8859-1.xml,v diff -u -N -r1.4.2.1 -r1.4.2.2 --- openacs-4/packages/xotcl-core/catalog/xotcl-core.de_DE.ISO-8859-1.xml 23 Apr 2007 05:55:08 -0000 1.4.2.1 +++ openacs-4/packages/xotcl-core/catalog/xotcl-core.de_DE.ISO-8859-1.xml 1 Aug 2007 21:39:31 -0000 1.4.2.2 @@ -1,5 +1,5 @@ - + Neu: %type% Neue Seite vom Type %type% erzeugen Index: openacs-4/packages/xotcl-core/catalog/xotcl-core.en_US.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/catalog/xotcl-core.en_US.ISO-8859-1.xml,v diff -u -N -r1.4.2.1 -r1.4.2.2 --- openacs-4/packages/xotcl-core/catalog/xotcl-core.en_US.ISO-8859-1.xml 23 Apr 2007 05:55:08 -0000 1.4.2.1 +++ openacs-4/packages/xotcl-core/catalog/xotcl-core.en_US.ISO-8859-1.xml 1 Aug 2007 21:39:31 -0000 1.4.2.2 @@ -1,5 +1,5 @@ - + Add %type% Add new item of type %type% @@ -8,6 +8,9 @@ Edit %type% has entered the room Live Revision + <blockquote> +You don't have sufficient permissions for performing method %method% on object %object%. +</blockquote> Revisions of Entry Revisions Index: openacs-4/packages/xotcl-core/catalog/xotcl-core.es_ES.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/catalog/xotcl-core.es_ES.ISO-8859-1.xml,v diff -u -N -r1.1.4.2 -r1.1.4.3 --- openacs-4/packages/xotcl-core/catalog/xotcl-core.es_ES.ISO-8859-1.xml 22 Mar 2007 10:14:02 -0000 1.1.4.2 +++ openacs-4/packages/xotcl-core/catalog/xotcl-core.es_ES.ISO-8859-1.xml 1 Aug 2007 21:39:31 -0000 1.1.4.3 @@ -1,13 +1,13 @@ - + A�adir %type% - A�adir un nuevo item del tipo %type% - Crear nuevo %type% - Editar item + A�adir un nuevo �tem del tipo %type% + Crear Nuevo %type% + Editar �tem Editar %type% ha entrado en la sala - Revisi�n Actual - Revisiones para la entrada + Revisi�n Viva + Revisiones de la Entrada Revisiones Index: openacs-4/packages/xotcl-core/catalog/xotcl-core.pt_BR.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/catalog/xotcl-core.pt_BR.ISO-8859-1.xml,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xotcl-core/catalog/xotcl-core.pt_BR.ISO-8859-1.xml 1 Aug 2007 21:39:31 -0000 1.1.4.2 @@ -0,0 +1,11 @@ + + + + Adicionar %type% + Adicionar novo item tipo %type% + Editar Item + Entrou na sala + Revis�o Ativa + Revis�es da Entrada + Revis�es + Index: openacs-4/packages/xotcl-core/tcl/01-debug-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/01-debug-procs.tcl,v diff -u -N -r1.8 -r1.8.2.1 --- openacs-4/packages/xotcl-core/tcl/01-debug-procs.tcl 17 Nov 2006 21:29:17 -0000 1.8 +++ openacs-4/packages/xotcl-core/tcl/01-debug-procs.tcl 1 Aug 2007 21:39:31 -0000 1.8.2.1 @@ -1,10 +1,14 @@ ## tell serializer to export methods, although these are methods of # ::xotcl::Object +package require xotcl::serializer + ::Serializer exportMethods { ::xotcl::Object instproc log + ::xotcl::Object instproc msg + ::xotcl::Object instproc __timediff ::xotcl::Object instproc debug - ::xotcl::Object instproc contains + ::xotcl::Object instproc qn ::xotcl::Object instproc serialize ::xotcl::Object instforward db_1row ::xotcl::Object instproc destroy_on_cleanup @@ -23,6 +27,44 @@ my requireNamespace namespace eval [self] $cmds } + namespace eval ::xo { + Class create ::xo::Attribute \ + -parameter { + {name "[namespace tail [::xotcl::self]]"} + {domain "[lindex [regexp -inline {^(.*)::slot::[^:]+$} [::xotcl::self]] 1]"} + {multivalued false} + {required false} + default + type + spec + pretty_name + {pretty_plural ""} + {datatype "text"} + {sqltype "text"} + {min_n_values 1} + {max_n_values 1} + help_text + validator + } + + } +} else { + namespace eval ::xo { + Class create ::xo::Attribute \ + -superclass ::xotcl::Attribute \ + -parameter { + spec + {required false} + pretty_name + {pretty_plural ""} + {datatype "text"} + {sqltype "text"} + {min_n_values 1} + {max_n_values 1} + help_text + validator + } + } } ::xotcl::Object instforward db_1row -objscope @@ -31,25 +73,28 @@ ::Serializer deepSerialize [self] } +namespace eval ::xo { + ::xotcl::Class create ::xo::InstanceManager \ + -instproc alloc args { + set r [next] + set key blueprint($r) + if {![ns_conn isconnected]} { + [self class] set $key 1 + } elseif {![[self class] exists $key]} { + [self class] set connectionobject($r) 1 + } + return $r + } \ + -instproc destroy args { + next + ns_log notice "--unset -nocomplain [self class]::blueprint([self])" + [self class] unset -nocomplain blueprint([self]) + [self class] unset -nocomplain connectionobject([self]) + } -# Currently, xotcl's serializer does not export ::xotcl::* commands, -# except methods for ::xotcl::Object and ::xotcl::Core, so we use the -# mixin instead of te direct defintion... should be changed in the future -# namespace eval ::xo { -# Class create ::xo::NonPosArgs \ -# -instproc integer args { -# if {[llength $args] < 2} return -# foreach {name value} $args break -# if {![string is integer $value]} { -# error "value '$value' of $name not an integer" -# } -# } \ -# -instproc optional {name args} { -# ; -# } -# } -# ::xotcl::nonposArgs proc integer -# ::xotcl::nonposArgs proc optional + # deactivate for now + #::xotcl::Object instmixin add ::xo::InstanceManager +} ::xotcl::nonposArgs proc integer args { if {[llength $args] < 2} return @@ -60,7 +105,7 @@ ; } -::xotcl::Object instproc log msg { +::xotcl::Object instproc __timediff {} { set now [ns_time get] if {[ns_conn isconnected]} { set start_time [ns_conn start] @@ -77,14 +122,26 @@ } else { set diff "" } - ns_log notice "$msg, [self] [self callingclass]->[self callingproc] (${ms}ms$diff)" set ::__last_timestamp $now + return "${ms}ms$diff" } +::xotcl::Object instproc log msg { + ns_log notice "$msg, [self] [self callingclass]->[self callingproc] ([my __timediff])" +} + ::xotcl::Object instproc debug msg { ns_log debug "[self] [self callingclass]->[self callingproc]: $msg" } - +::xotcl::Object instproc msg msg { + if {[ns_conn isconnected]} { + util_user_message -message "$msg ([self] [self callingclass]->[self callingproc])" + } +} +::xotcl::Object instproc qn query_name { + set qn "dbqd.[my uplevel self class]-[my uplevel self proc].$query_name" + return $qn +} namespace eval ::xo { Class Timestamp Timestamp instproc init {} {my set time [clock clicks -milliseconds]} @@ -125,26 +182,9 @@ } } - # - # a simple calback for cleanup of per connection objects - # ns_atclose is a little to early for us... - # - ::xotcl::Object instproc destroy_on_cleanup {} { - set ::xotcl_cleanup([self]) 1 - #my log "--A cleanup for [lsort [array names ::xotcl_cleanup]]" - ::trace add variable ::xotcl_cleanup([self]) unset ::xo::cleanup_callback - } - proc ::xo::cleanup_callback {var object op} { - if {![::xotcl::Object isobject $object]} { - #ns_log notice "--D $object already destroyed, nothing to do" - $object destroy - } else { - #ns_log notice "--D $object destroy" - $object destroy - } - } } + # ::xotcl::Class instproc import {class pattern} { # namespace eval [self] [list \ # namespace import [list import [$class self]]::$pattern; @@ -168,3 +208,113 @@ # ns_log notice "--T [ns_ictl get]" #} +namespace eval ::xo { + # + # In earlier versions of xotcl-core, we used variable traces + # to trigger deletion of objects. This had two kind of problems: + # 1) there was no way to control the order of the deletions + # 2) the global variables used for managing db handles might + # be deleted already + # 3) the traces are executed at a time when the connection + # is already closed + # Aolserver 4.5 supports a trace for freeconn. We can register + # a callback to be executed before the connection is freed, + # therefore, we have still information from ns_conn available. + # For aolserver 4.5 we use oncleanup, which is at least before + # the cleanup of variables. + # + # In contrary, in 4.0.10, on cleanup is called after the global + # variables of a connection thread are deleted. Therefore + # the triggered calls should not use database handles, + # since these are as well managed via global variables, + # the will be deleted as well at this time,. + # + # To come up with an approach working for 4.5 and 4.0.10, we + # distinguish between a at_cleanup and at_close, so connection + # related info can still be obtained. + # + if {[catch {set registered [ns_ictl gettraces freeconn]}]} { + ns_log notice "*** you should really upgrade to Aolserver 4.5" + # "ns_ictl oncleanup" is called after variables are deleted + if {[ns_ictl epoch] == 0} { + ns_ictl oncleanup ::xo::at_cleanup + ns_ictl oninit [list ns_atclose ::xo::at_close] + } + +# proc trace_cleanup {args} { +# set name [lindex $args 1] +# #ns_log notice "*** cleanup <$args> '$name'" +# if {[::xotcl::Object isobject $name]} { +# ns_log notice "*** cleanup $name destroy" +# $name destroy +# } +# } + } else { + + # register only once + if {[lsearch $registered ::xo::cleanup] == -1} { + ns_ictl trace freeconn ::xo::freeconn + } + + proc ::xo::freeconn {} { + catch {::xo::at_close} + catch {::xo::at_cleanup} + } + } + + #proc ::xo::at_create {} { + # ns_log notice "--at_create *********" + # foreach i [::xo::InstanceManager array names blueprint] { + # if {![::xotcl::Object isobject $i]} { + # ::xo::InstanceManager unset blueprint($i) + # ns_log notice "--at_create no such object: $i" + # } + # } + #} + + ::xotcl::Object instproc destroy_on_cleanup {} { + #my log "--cleanup adding ::xo::cleanup([self]) [list [self] destroy]" + set ::xo::cleanup([self]) [list [self] destroy] + } + + proc at_close {args} { + } + + proc at_cleanup {args} { + #ns_log notice "*** start of cleanup <$args> ([array get ::xo::cleanup])" + set at_end "" + foreach {name cmd} [array get ::xo::cleanup] { + #::trace remove variable ::xotcl_cleanup($name) unset ::xo::cleanup + if {![::xotcl::Object isobject $name]} { + #ns_log notice "--D $name already destroyed, nothing to do" + continue + } + if {$name eq "::xo::cc"} { + append at_end $cmd\n + continue + } + #ns_log notice "*** cleanup $cmd" + if {[catch {eval $cmd} errorMsg]} { + set obj [lindex $cmd 0] + ns_log notice "Error during ::xo::cleanup: $errorMsg $::errorInfo" + catch { + ns_log notice "... analyze: cmd = $cmd" + ns_log notice "... analyze: $obj is_object? [::xotcl::Object isobject $obj]" + ns_log notice "... analyze: class [$obj info class]" + ns_log notice "... analyze: precedence [$obj info precedence]" + ns_log notice "... analyze: methods [lsort [$obj info methods]]" + } + } + } + #ns_log notice "*** at_end $at_end" + if {[catch {eval $at_end} errorMsg]} { + ns_log notice "Error during ::xo::cleanup: $errorMsg $::errorInfo" + } + array unset ::xo::cleanup + #ns_log notice "*** end of cleanup" + } +} + +#ns_log notice "*** FREECONN? [ns_ictl gettraces freeconn]" +#ns_ictl trace freeconn {ns_log notice "*** FREECONN isconnected=[ns_conn isconnected]"} +#ns_ictl oncleanup {ns_log notice "*** ONCLEANUP isconnected=[ns_conn isconnected]"} 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 -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xotcl-core/tcl/03-doc-procs.tcl 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1,335 @@ +ad_library { + XOTcl API for api browser, defines the methods + ad_proc (for object specific methods), + ad_instproc (for tradional methods) and + ad_odc (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. + + @author Gustaf Neumann + @creation-date 2005-05-13 + @cvs-id $Id: 03-doc-procs.tcl,v 1.1.2.2 2007/08/01 21:39:31 gustafn Exp $ +} + +# 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 + ::xotcl::Object instproc __api_make_doc + ::xotcl::Object instproc __api_make_forward_doc +} +::Serializer exportObjects { + ::xotcl::api +} + +::xotcl::Object create ::xotcl::api \ + -proc isclass {scope obj} { + expr {$scope eq "" ? + [::xotcl::Object isclass $obj] : + [$scope do ::xotcl::Object isclass $obj]} + } -proc isobject {scope obj} { + expr {$scope eq "" ? + [::xotcl::Object isobject $obj] : + [$scope do ::xotcl::Object isobject $obj]} + } -proc scope {} { + if {[info exists ::xotcl::currentThread]} { + # we are in an xotcl thread; the body won't be accessible directly + return $::xotcl::currentThread + } + return "" + + } -proc scope_from_object_reference {scope_var object_var} { + upvar $scope_var scope $object_var object + set scope "" + regexp {^(.+) do (.+)$} $object match scope object + + } -proc scope_from_proc_index {proc_index} { + set scope "" + regexp {^(.+) .+ (inst)?proc (.+)$} $proc_index match scope + return $scope + + } -proc inscope {scope args} { + expr {$scope eq "" ? [eval $args] : [eval $scope do $args]} + + } -proc script_name {scope} { + #set kind [expr {[my istype ::xotcl::Class] ? "Class" : "Object"}] + #return "$scope$kind [self]" + set script [info script] + if {$script eq "" && [info exists ::xotcl::currentScript]} { + set script $::xotcl::currentScript + } + set root_dir [nsv_get acs_properties root_directory] + set root_length [string length $root_dir] + if { $root_dir eq [string range $script 0 [expr {$root_length - 1}]]} { + set script [string range $script [expr {$root_length + 1}] end] + } + return $script + + } -proc object_link {{-noimg:boolean off} scope obj} { + set link "" + if {$noimg} { + return "$link$obj" + } else { + return "$obj$link\[i\]" + } + + } -proc object_url {{-show_source 0} {-show_methods 1} scope obj} { + set object [expr {$scope eq "" ? $obj : "$scope do $obj"}] + return [export_vars -base /xotcl/show-object {object show_source show_methods}] + } -proc object_index {scope obj} { + set kind [expr {[my isclass $scope $obj] ? "Class" : "Object"}] + return "$scope$kind $obj" + + } -proc proc_index {scope obj instproc proc_name} { + if {$scope eq ""} { + return "$obj $instproc $proc_name" + } else { + return "$scope $obj $instproc $proc_name" + } + + } -proc source_to_html {{-width 100} string} { + set lines [list] + foreach l [split $string \n] { + while {[string length $l] > $width} { + set pos [string last " \{" $l $width] + if {$pos>10} { + lappend lines "[string range $l 0 [expr {$pos-1}]] \\" + set l " [string range $l $pos end]" + } else { + # search for a match right of the target + set pos [string first " \{" $l $width] + if {$pos>10} { + lappend lines "[string range $l 0 [expr {$pos-1}]] \\" + set l " [string range $l $pos end]" + } else { + # last resort try to split around spaces + set pos [string last " " $l $width] + if {$pos>10} { + lappend lines "[string range $l 0 [expr {$pos-1}]] \\" + set l " [string range $l $pos end]" + } else { + break + } + } + } + } + lappend lines $l + } + set string [join $lines \n] + set html [ad_quotehtml $string] + regsub -all {(\n[\t ]*)(\#[^\n]*)} $html \\1\\2 html + return "
$html
" + } + + + + +::xotcl::Object instproc __api_make_doc {inst proc_name} { + upvar doc doc private private public public deprecated deprecated + if {$doc eq ""} { + set doc_elements(main) "" + } else { + ad_parse_documentation_string $doc doc_elements + } + set defaults [list] + foreach a [my info ${inst}args $proc_name] { + if {[my info ${inst}default $proc_name $a d]} {lappend defaults $a $d} + } + set public [expr {$private ? false : true}] + set doc_elements(public_p) $public + set doc_elements(private_p) $private + set doc_elements(deprecated_p) $deprecated + set doc_elements(varargs_p) [expr {[lsearch args [my info ${inst}args $proc_name]]>-1}] + set doc_elements(flags) [list] + set doc_elements(switches) [list] + foreach f [my info ${inst}nonposargs $proc_name] { + set pair [split [lindex $f 0 0] :] + set sw [string range [lindex $pair 0] 1 end] + lappend doc_elements(switches) $sw + lappend doc_elements(flags) $sw [lindex $pair 1] + #my log "default_value $proc_name: $sw -> '[lindex $f 1]' <$pair/$f>" + if {[lindex $pair 1] eq "switch" && [lindex $f 1] eq ""} { + set default "false" + } else { + set default [lindex $f 1] + } + #my log "default_value $proc_name: $sw -> 'default' <$pair/$f>" + lappend defaults $sw $default + } + set doc_elements(default_values) $defaults + set doc_elements(positionals) [my info ${inst}args $proc_name] + # argument documentation finished + set scope [::xotcl::api scope] + set doc_elements(script) [::xotcl::api script_name $scope] + set proc_index [::xotcl::api proc_index $scope [self] ${inst}proc $proc_name] + if {![nsv_exists api_proc_doc $proc_index]} { + nsv_lappend api_proc_doc_scripts $doc_elements(script) $proc_index + } + #my log "doc_elements=[array get doc_elements]" + #my log "SETTING api_proc_doc '$proc_index'" + nsv_set api_proc_doc $proc_index [array get doc_elements] +} + +::xotcl::Object instproc __api_make_forward_doc {inst method_name} { + upvar doc doc private private public public deprecated deprecated + if {$doc eq ""} { + set doc_elements(main) "" + } else { + ad_parse_documentation_string $doc doc_elements + #my log "doc_elements=[array get doc_elements]" + } + set defaults [list] + set public [expr {$private ? false : true}] + set doc_elements(public_p) $public + set doc_elements(private_p) $private + set doc_elements(deprecated_p) $deprecated + set doc_elements(varargs_p) false + set doc_elements(flags) [list] + set doc_elements(switches) [list] + set doc_elements(default_values) [list] + set doc_elements(positionals) [list] + # argument documentation finished + set scope [::xotcl::api scope] + set doc_elements(script) [::xotcl::api script_name $scope] + set proc_index [::xotcl::api proc_index $scope [self] ${inst}forward $method_name] + if {![nsv_exists api_proc_doc $proc_index]} { + nsv_lappend api_proc_doc_scripts $doc_elements(script) $proc_index + } + #my log "doc_elements=[array get doc_elements]" + #my log "SETTING api_proc_doc '$proc_index'" + nsv_set api_proc_doc $proc_index [array get doc_elements] +} + +::xotcl::Object instproc ad_proc { + {-private:switch false} + {-deprecated:switch false} + {-warn:switch false} + {-debug:switch false} + proc_name arguments doc body} { + uplevel [list [self] proc $proc_name $arguments $body] + my __api_make_doc "" $proc_name + } + +::xotcl::Object instproc ad_forward { + {-private:switch false} + {-deprecated:switch false} + {-warn:switch false} + {-debug:switch false} + method_name doc args} { + uplevel [self] forward $method_name $args + my __api_make_forward_doc "" $method_name + } + +::xotcl::Class instproc ad_instproc { + {-private:switch false} + {-deprecated:switch false} + {-warn:switch false} + {-debug:switch false} + proc_name arguments doc body} { + uplevel [list [self] instproc $proc_name $arguments $body] + my __api_make_doc inst $proc_name + } + +::xotcl::Object instproc ad_instforward { + {-private:switch false} + {-deprecated:switch false} + {-warn:switch false} + {-debug:switch false} + method_name doc args} { + uplevel [self] instforward $method_name $args + my __api_make_forward_doc inst $method_name + } + + + +::xotcl::Object instproc ad_doc {doc_string} { + ad_parse_documentation_string $doc_string doc_elements + set scope [::xotcl::api scope] + set doc_elements(script) [::xotcl::api script_name $scope] + set proc_index [::xotcl::api object_index $scope [self]] + + #if {![nsv_exists api_proc_doc $proc_index]} { + # nsv_lappend api_proc_doc_scripts $doc_elements(script) $proc_index + #} + set doc_elements(public_p) true + set doc_elements(private_p) false + set doc_elements(varargs_p) false + set doc_elements(deprecated_p) false + set doc_elements(default_values) "" + set doc_elements(switches) "" + set doc_elements(positionals) "" + set doc_elements(flags) "" + nsv_set api_proc_doc $proc_index [array get doc_elements] + nsv_set api_library_doc \ + $proc_index \ + [array get doc_elements] + + set file_index $doc_elements(script) + + if {[nsv_exists api_library_doc $file_index]} { + array set elements [nsv_get api_library_doc $file_index] + } + set oldDoc [expr {[info exists elements(main)] ? \ + [lindex $elements(main) 0] : ""}] + set prefix "This file defines the following Objects and Classes" + set entry [::xotcl::api object_link $scope [self]] + if {![string match *$prefix* $oldDoc]} { + append oldDoc "

$prefix: $entry" + } else { + append oldDoc ", $entry" + } + set elements(main) [list $oldDoc] + #my log "elements = [array get elements]" + nsv_set api_library_doc $file_index [array get elements] +} + + +Class ::Test -ad_doc { + Test Class for the documentation of + Classes, + Objects, + instprocs, and + procs. + @author Gustaf Neumann + @cvs-id $Id: 03-doc-procs.tcl,v 1.1.2.2 2007/08/01 21:39:31 gustafn Exp $ +} +::Test ad_proc my-class-specific-proc {x y} { + This is a proc of Class Test merely for testing purposes... + @param x First Operand + @param y Second Operand +} { + ns_log notice "hello world $x $y" +} + +::Test ad_instproc my-method {-id:required} { + This is an instproc of Class Test merely for testing purposes... + @param id Some Id +} { + ns_log notice "hello world $id" +} +::Test ad_instproc my-method2 {-id:required {-flag:boolean true}} { + This is an instproc of Class Test merely for testing purposes... + @param id Some Id + @param flag Some flag +} { + ns_log notice "hello world $id" +} +::Test ad_instproc -private my-method3 {-id:required {-flag:boolean true} -switch:switch x {y 1}} { + This is an instproc of Class Test merely for testing purposes... + @param id Some Id + @param flag Some flag + @param switch Switch to turn on or off depending on default + @param x First Operand + @param y Second Operand +} { + ns_log notice "hello world $id" +} + +Class ::SpecializedTest -superclass ::Test -ad_doc { + A Class defined as a subclass of ::Test for testing the + documentation stuff... +} Index: openacs-4/packages/xotcl-core/tcl/05-db-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/05-db-procs.tcl,v diff -u -N -r1.2.2.1 -r1.2.2.2 --- openacs-4/packages/xotcl-core/tcl/05-db-procs.tcl 15 Jan 2007 08:49:58 -0000 1.2.2.1 +++ openacs-4/packages/xotcl-core/tcl/05-db-procs.tcl 1 Aug 2007 21:39:32 -0000 1.2.2.2 @@ -6,45 +6,392 @@ @cvs-id $Id$ } + namespace eval ::xo::db { + ::xotcl::Object create require - ::xotcl::Object require + require set postgresql_table_exists {select 1 from pg_tables where tablename = '$name'} + require set postgresql_view_exists {select 1 from pg_views where viewname = '$name'} + require set postgresql_index_exists {select 1 from pg_indexes where indexname = '$name'} + require set oracle_table_exists {select 1 from all_tables where table_name = '$name'} + require set oracle_view_exists {select 1 from all_views where view_name = '$name'} + require set oracle_index_exists {select 1 from all_indexes where index_name = '$name'} + require proc table {name definition} { - if {![db_0or1row check-$name \ - "select 1 from pg_tables where tablename = '$name'"]} { - db_dml create-$name "create table $name ($definition)" + if {[db_driverkey ""] eq "oracle"} {set name [string toupper $name]} + if {![db_0or1row [my qn ""] [subst [my set [db_driverkey ""]_table_exists]]]} { + #my log "--table $name does not exist, creating with $definition" + db_dml [my qn create-table-$name] "create table $name ($definition)" } } require proc view {name definition} { - if {![db_0or1row check-$name \ - "select 1 from pg_views where viewname = '$name'"]} { - db_dml create-$name "create view $name AS $definition" + if {[db_driverkey ""] eq "oracle"} {set name [string toupper $name]} + if {![db_0or1row [my qn ""] [subst [my set [db_driverkey ""]_view_exists]]]} { + db_dml [my qn create-view-$name] "create view $name AS $definition" } } + if {[db_driverkey ""] eq "oracle"} { + proc mk_sql_constraint_name {table att suffix} { + set name ${table}_${att}_$suffix + if {[string length $name]>30} { + set sl [string length $suffix] + set name [string range ${table}_${att} 0 [expr {28 - $sl}]]_$suffix + } + return [string toupper $name] + } + } else { + proc mk_sql_constraint_name {table att suffix} { + set name ${table}_${att}_$suffix + return $name + } + } + require proc index {-table -col {-using ""} {-unique false}} { set colpart $col regsub -all ", *" $colpart _ colpart set suffix [expr {$unique ? "un_idx" : "idx"}] set uniquepart [expr {$unique ? "UNIQUE" : ""}] - set name ${table}_${colpart}_$suffix - if {![db_0or1row check_${name} \ - "select 1 from pg_indexes where indexname = '$name'"]} { + set name [::xo::db::mk_sql_constraint_name $table $colpart $suffix] + if {![db_0or1row [my qn ""] [subst [my set [db_driverkey ""]_index_exists]]]} { set using [expr {$using ne "" ? "using $using" : ""}] - db_dml create-$name \ + db_dml [my qn create-index-$name] \ "create $uniquepart index $name ON $table $using ($col)" } } - proc has_ltree {} { + require proc package name { + if {[info command ::${name}::*] eq ""} { + set dir [ns_info tcllib]/../packages/$name + foreach file [glob $dir/tcl/*-procs.tcl] { + uplevel #1 source $file + } + } + } + + proc function_name {sql} { + if {[db_driverkey ""] eq "oracle"} {return [string map [list "__" .] $sql]} + return $sql + } + + ad_proc has_ltree {} { + Check, whether ltree is available (postgres only) + } { ns_cache eval xotcl_object_cache ::xo::has_ltree { - if {[db_string check_ltree "select count(*) from pg_proc where proname = 'ltree_in'"] == 0} { - return 0 + if {[db_driverkey ""] eq "postgresql" && + [db_string check_ltree "select count(*) from pg_proc where proname = 'ltree_in'"]} { + return 1 } - return 1 + return 0 } } + # we create the sql object + ::xotcl::Object create sql + + + if {[db_driverkey ""] eq "postgresql"} { + + # during load, we do not have "package_plsql_args" available yet, so we do it by hand + sql set all_package_functions { + select distinct + substring(function from 0 for position('__' in function)) as package_name, + substring(function from position('__' in function)+2) as object_name + from acs_function_args + } + + sql proc map_datatype {type} { + switch -- $type { + long_text { set type text } + } + return $type + } + sql proc datatype_constraint {type table att} {return ""} + + sql proc select { + -vars:required + -from:required + -where:required + {-groupby ""} + {-limit ""} + {-offset ""} + {-start ""} + {-orderby ""} + {-map_function_names false} + } { + set offset_clause [expr {$offset ne "" ? "OFFSET $offset" : ""}] + set limit_clause [expr {$limit ne "" ? "LIMIT $limit" : ""}] + set order_clause [expr {$orderby ne "" ? "ORDER BY $orderby" : ""}] + set group_clause [expr {$groupby ne "" ? "GROUP BY $groupby" : ""}] + return "SELECT $vars FROM $from WHERE $where $group_clause $order_clause $limit_clause" + } + + sql proc date_trunc {field date} { + return "date_trunc('$field',$date)" + } + sql proc date_trunc_expression {field date date_string} { + return "date_trunc('$field',$date) = '$date_string'" + } + + } else { ;# Oracle + + sql set all_package_functions { + select distinct package_name, object_name + from user_arguments args + where args.position > 0 and package_name is not null + } + + sql proc map_datatype {type} { + switch -- $type { + text { set type varchar2(4000) } + long_text { set type clob } + boolean { set type char(1) } + } + return $type + } + sql proc datatype_constraint {type table att} { + set constraint "" + switch $type { + boolean { + set cname [::xo::db::mk_sql_constraint_name $table $att _ck] + set constraint "constraint $cname check ($att in ('t','f'))"} + } + return $constraint + } + + sql proc select { + -vars:required + -from:required + -where:required + {-groupby ""} + {-limit ""} + {-offset ""} + {-start ""} + {-orderby ""} + {-map_function_names false} + } { + # "-start" not used so far + set order_clause [expr {$orderby ne "" ? "ORDER BY $orderby" : ""}] + set group_clause [expr {$groupby ne "" ? "GROUP BY $groupby" : ""}] + if {$map_function_names} {set vars [::xo::db::function_name $vars]} + set sql "SELECT $vars FROM $from WHERE $where $group_clause" + if {$limit ne "" || $offset ne ""} { + if {$offset eq ""} { + set limit_clause "ROWNUM <= $limit" + } elseif {$limit eq ""} { + set limit_clause "ROWNUM >= $offset" + } else { + set limit_clause "ROWNUM BETWEEN $offset and [expr {$offset+$limit}]" + } + # for pagination, we will need an "inner" sort, such as + # SELECT * FROM (SELECT ...., ROW_NUMBER() OVER (ORDER BY ...) R FROM table) WHERE R BETWEEN 0 and 100 + set sql "SELECT * FROM ($sql $order_clause) WHERE $limit_clause" + } else { + append sql " " $order_clause + } + my log "--returned sql = $sql" + return $sql + } + sql proc date_trunc {field date} { + return "to_char(trunc($date,'$field'), 'YYYY-MM-DD HH24:MI:SS')" + } + sql proc date_trunc_expression {field date date_string} { + return "trunc($date,'$field') = trunc(to_date('$date_string','YYYY-MM-DD'),'$field')" + } + } + sql proc since_interval_condition {var interval} { + set since [clock format [clock scan "-$interval"] -format "%Y-%m-%d %T"] + return "$var > TO_TIMESTAMP('$since','YYYY-MM-DD HH24:MI:SS')" + } } +namespace eval ::xo::db { + Class create DbPackage + + # Some stored procs like content_item__new do currently not define null default values. + # Therefore, we need - temporary - this ugly redundancy to keep + # :required passing and to allow the xowiki regression test to run. + # The correct fix is to define the correct default values in the + # database with define_function_args() + DbPackage array set defaults { + "content_item__new" {RELATION_TAG null DESCRIPTION null TEXT null + CREATION_IP null NLS_LANGUAGE null LOCALE null CONTEXT_ID null + DATA null TITLE null ITEM_ID null + } + "content_type__create_attribute" { + DEFAULT_VALUE null SORT_ORDER null PRETTY_PLURAL null + } + "content_type__drop_type" { + DROP_CHILDREN_P f DROP_TABLE_P f DROP_OBJECTS_P f + } + } + + DbPackage instproc sql-arguments {sql package_name object_name} { + my array unset defined + my set function_args [db_list_of_lists [my qn get_function_params] $sql] + set psql_args [list] + my set arg_order [list] + foreach arg [my set function_args] { + foreach {arg_name default_value} $arg break + lappend psql_args \$_$arg_name + my lappend arg_order $arg_name + my set defined($arg_name) $default_value + } + if {[[self class] exists defaults(${package_name}__$object_name)]} { + set prototype_args [[self class] set defaults(${package_name}__$object_name)] + foreach {arg_name default_value} $prototype_args { + if {![my exists defined($arg_name)]} { + lappend psql_args \$_$arg_name + my lappend arg_order $arg_name + } + } + my array set defined $prototype_args + } + return [join $psql_args ", "] + } + + DbPackage instproc psql-postgresql {package_name object_name full_statement_name} { + set psql_args [my sql-arguments { + select args.arg_name, args.arg_default + from acs_function_args args + where args.function = upper(:package_name) || '__' || upper(:object_name) + order by function, arg_seq + } $package_name $object_name] + my set sql [subst { + select ${package_name}__${object_name}($psql_args) + }] + #return {ns_pg_bind 0or1row $db $sql} + return {ns_set value [ns_pg_bind 0or1row $db $sql] 0} + } + + DbPackage instproc psql-oracle {package_name object_name full_statement_name} { + # + # in Oracle, we have to distinguish between functions and procs + # + set is_function [db_0or1row [my qn is_function] { + select 1 from dual + where exists (select 1 from user_arguments where + package_name = upper(:package_name) + and object_name = upper(:object_name) + and position = 0) + }] + # In Oracle, args.default_value appears to be defunct and useless. + # for now, we simply return "null" as a constant, otherwise the + # argument would be required + set psql_args [my sql-arguments { + select args.argument_name, 'unknown' + from user_arguments args + where args.position > 0 + and args.object_name = upper(:object_name) + and args.package_name = upper(:package_name) + order by args.position + } $package_name $object_name] + if {$is_function} { + my set sql [subst {BEGIN :1 := ${package_name}.${object_name}(\$sql_args); END;}] + return {ns_ora exec_plsql_bind $db $sql 1 ""} + } else { + my set sql [subst {BEGIN ${package_name}.${object_name}(\$sql_args); END;}] + #return {ns_set value [ns_ora select $db $sql] 0} + return {ns_ora dml $db $sql} + } + } + + DbPackage instproc proc_body-postgresql {} { + return { + #defined: [my array get defined] + foreach var \[list [my set arg_order]\] { + set varname \[string tolower $var\] + if {\[info exists $varname\]} { + set $var \[set $varname\] + set _$var :$var + } else { + set _$var null + } + } + set sql "[my set sql]" + db_with_handle -dbn $dbn db { + #my log "sql=$sql, sql_command=[set sql_command]" + return \[ [set sql_command] \] + } + } + } + + DbPackage instproc proc_body-oracle {} { + return { + #defined: [my array get defined] + set sql_args \[list\] + foreach var \[list [my set arg_order]\] { + set varname \[string tolower $var\] + if {\[info exists $varname\]} { + lappend sql_args "$varname => :$varname" + } + } + set sql_args \[join $sql_args ,\] + set sql "[my set sql]" + db_with_handle -dbn $dbn db { + #my log "sql=$sql, sql_command=[set sql_command]" + return \[ [set sql_command] \] + } + } + } + + DbPackage instproc dbproc_nonposargs {object_name} { + # + # This method compiles a stored procedure into a xotcl method + # using a classic nonpositional argument style interface. + # + # The current implementation should work on postgres and oracle (not tested) + # but will not work, when a single openacs instance want to talk to + # postgres and oracle simultaneously. Not sure, how important this is... + # + if {$object_name eq "set"} { + my log "We cannot handle object_name = '$object_name' in this version" + return + } + set package_name [namespace tail [self]] + set statement_name [my qn $package_name-$object_name] + set sql_command [my psql-[db_driverkey ""] $package_name $object_name $statement_name] + set proc_body [my proc_body-[db_driverkey ""]] + + set nonposarg_list [list [list -dbn ""]] + foreach arg_name [my set arg_order] { + set default_value [my set defined($arg_name)] + set required [expr {$default_value eq "" ? ":required" : ""}] + # special rule for DBN ... todo: proc has to handle this as well + set nonposarg_name [expr {$arg_name eq "DBN" ? "DBN" : [string tolower $arg_name]}] + lappend nonposarg_list -$nonposarg_name$required + } + #my log "-- define $object_name $nonposarg_list" + + my ad_proc $object_name $nonposarg_list {} [subst -novariables $proc_body] + } + + DbPackage instproc unknown {m args} { + error "Error: unknown database method $m for dbpackage [self]" + } + + DbPackage proc create_all_functions {} { + db_foreach [my qn ""] [::xo::db::sql set all_package_functions] { + #if {![my isobject $package_name]} { DbPackage create $package_name } + #$package_name dbproc_exportvars $object_name + set class_name ::xo::db::sql::[string tolower $package_name] + if {![my isobject $class_name]} { DbPackage create $class_name } + $class_name dbproc_nonposargs [string tolower $object_name] + } + } + + DbPackage create_all_functions + + ad_proc tcl_date {timestamp tz_var} { + Convert the time stamp (coming from the database) into a format, which + can be passed to Tcl's "clock scan". + } { + upvar $tz_var tz + set tz 00 + regexp {^([^.]+)[.][0-9]+(.*)$} $timestamp _ timestamp tz + return $timestamp + } +} + + Index: openacs-4/packages/xotcl-core/tcl/05-doc-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/Attic/05-doc-procs.tcl,v diff -u -N --- openacs-4/packages/xotcl-core/tcl/05-doc-procs.tcl 29 Dec 2006 11:04:16 -0000 1.10 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,335 +0,0 @@ -ad_library { - XOTcl API for api browser, defines the methods - ad_proc (for object specific methods), - ad_instproc (for tradional methods) and - ad_odc (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. - - @author Gustaf Neumann - @creation-date 2005-05-13 - @cvs-id $Id: 05-doc-procs.tcl,v 1.10 2006/12/29 11:04:16 gustafn Exp $ -} - -# 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 - ::xotcl::Object instproc __api_make_doc - ::xotcl::Object instproc __api_make_forward_doc -} -::Serializer exportObjects { - ::xotcl::api -} - -::xotcl::Object create ::xotcl::api \ - -proc isclass {scope obj} { - expr {$scope eq "" ? - [::xotcl::Object isclass $obj] : - [$scope do ::xotcl::Object isclass $obj]} - } -proc isobject {scope obj} { - expr {$scope eq "" ? - [::xotcl::Object isobject $obj] : - [$scope do ::xotcl::Object isobject $obj]} - } -proc scope {} { - if {[info exists ::xotcl::currentThread]} { - # we are in an xotcl thread; the body won't be accessible directly - return $::xotcl::currentThread - } - return "" - - } -proc scope_from_object_reference {scope_var object_var} { - upvar $scope_var scope $object_var object - set scope "" - regexp {^(.+) do (.+)$} $object match scope object - - } -proc scope_from_proc_index {proc_index} { - set scope "" - regexp {^(.+) .+ (inst)?proc (.+)$} $proc_index match scope - return $scope - - } -proc inscope {scope args} { - expr {$scope eq "" ? [eval $args] : [eval $scope do $args]} - - } -proc script_name {scope} { - #set kind [expr {[my istype ::xotcl::Class] ? "Class" : "Object"}] - #return "$scope$kind [self]" - set script [info script] - if {$script eq "" && [info exists ::xotcl::currentScript]} { - set script $::xotcl::currentScript - } - set root_dir [nsv_get acs_properties root_directory] - set root_length [string length $root_dir] - if { $root_dir eq [string range $script 0 [expr {$root_length - 1}]]} { - set script [string range $script [expr {$root_length + 1}] end] - } - return $script - - } -proc object_link {{-noimg:boolean off} scope obj} { - set link "" - if {$noimg} { - return "$link$obj" - } else { - return "$obj$link\[i\]" - } - - } -proc object_url {{-show_source 0} {-show_methods 1} scope obj} { - set object [expr {$scope eq "" ? $obj : "$scope do $obj"}] - return [export_vars -base /xotcl/show-object {object show_source show_methods}] - } -proc object_index {scope obj} { - set kind [expr {[my isclass $scope $obj] ? "Class" : "Object"}] - return "$scope$kind $obj" - - } -proc proc_index {scope obj instproc proc_name} { - if {$scope eq ""} { - return "$obj $instproc $proc_name" - } else { - return "$scope $obj $instproc $proc_name" - } - - } -proc source_to_html {{-width 100} string} { - set lines [list] - foreach l [split $string \n] { - while {[string length $l] > $width} { - set pos [string last " \{" $l $width] - if {$pos>10} { - lappend lines "[string range $l 0 [expr {$pos-1}]] \\" - set l " [string range $l $pos end]" - } else { - # search for a match right of the target - set pos [string first " \{" $l $width] - if {$pos>10} { - lappend lines "[string range $l 0 [expr {$pos-1}]] \\" - set l " [string range $l $pos end]" - } else { - # last resort try to split around spaces - set pos [string last " " $l $width] - if {$pos>10} { - lappend lines "[string range $l 0 [expr {$pos-1}]] \\" - set l " [string range $l $pos end]" - } else { - break - } - } - } - } - lappend lines $l - } - set string [join $lines \n] - set html [ad_quotehtml $string] - regsub -all {(\n[\t ]*)(\#[^\n]*)} $html \\1\\2 html - return "

$html
" - } - - - - -::xotcl::Object instproc __api_make_doc {inst proc_name} { - upvar doc doc private private public public deprecated deprecated - if {$doc eq ""} { - set doc_elements(main) "" - } else { - ad_parse_documentation_string $doc doc_elements - } - set defaults [list] - foreach a [my info ${inst}args $proc_name] { - if {[my info ${inst}default $proc_name $a d]} {lappend defaults $a $d} - } - set public [expr {$private ? false : true}] - set doc_elements(public_p) $public - set doc_elements(private_p) $private - set doc_elements(deprecated_p) $deprecated - set doc_elements(varargs_p) [expr {[lsearch args [my info ${inst}args $proc_name]]>-1}] - set doc_elements(flags) [list] - set doc_elements(switches) [list] - foreach f [my info ${inst}nonposargs $proc_name] { - set pair [split [lindex $f 0 0] :] - set sw [string range [lindex $pair 0] 1 end] - lappend doc_elements(switches) $sw - lappend doc_elements(flags) $sw [lindex $pair 1] - #my log "default_value $proc_name: $sw -> '[lindex $f 1]' <$pair/$f>" - if {[lindex $pair 1] eq "switch" && [lindex $f 1] eq ""} { - set default "false" - } else { - set default [lindex $f 1] - } - #my log "default_value $proc_name: $sw -> 'default' <$pair/$f>" - lappend defaults $sw $default - } - set doc_elements(default_values) $defaults - set doc_elements(positionals) [my info ${inst}args $proc_name] - # argument documentation finished - set scope [::xotcl::api scope] - set doc_elements(script) [::xotcl::api script_name $scope] - set proc_index [::xotcl::api proc_index $scope [self] ${inst}proc $proc_name] - if {![nsv_exists api_proc_doc $proc_index]} { - nsv_lappend api_proc_doc_scripts $doc_elements(script) $proc_index - } - #my log "doc_elements=[array get doc_elements]" - #my log "SETTING api_proc_doc '$proc_index'" - nsv_set api_proc_doc $proc_index [array get doc_elements] -} - -::xotcl::Object instproc __api_make_forward_doc {inst method_name} { - upvar doc doc private private public public deprecated deprecated - if {$doc eq ""} { - set doc_elements(main) "" - } else { - ad_parse_documentation_string $doc doc_elements - #my log "doc_elements=[array get doc_elements]" - } - set defaults [list] - set public [expr {$private ? false : true}] - set doc_elements(public_p) $public - set doc_elements(private_p) $private - set doc_elements(deprecated_p) $deprecated - set doc_elements(varargs_p) false - set doc_elements(flags) [list] - set doc_elements(switches) [list] - set doc_elements(default_values) [list] - set doc_elements(positionals) [list] - # argument documentation finished - set scope [::xotcl::api scope] - set doc_elements(script) [::xotcl::api script_name $scope] - set proc_index [::xotcl::api proc_index $scope [self] ${inst}forward $method_name] - if {![nsv_exists api_proc_doc $proc_index]} { - nsv_lappend api_proc_doc_scripts $doc_elements(script) $proc_index - } - #my log "doc_elements=[array get doc_elements]" - #my log "SETTING api_proc_doc '$proc_index'" - nsv_set api_proc_doc $proc_index [array get doc_elements] -} - -::xotcl::Object instproc ad_proc { - {-private:switch false} - {-deprecated:switch false} - {-warn:switch false} - {-debug:switch false} - proc_name arguments doc body} { - uplevel [list [self] proc $proc_name $arguments $body] - my __api_make_doc "" $proc_name - } - -::xotcl::Object instproc ad_forward { - {-private:switch false} - {-deprecated:switch false} - {-warn:switch false} - {-debug:switch false} - method_name doc args} { - uplevel [self] forward $method_name $args - my __api_make_forward_doc "" $method_name - } - -::xotcl::Class instproc ad_instproc { - {-private:switch false} - {-deprecated:switch false} - {-warn:switch false} - {-debug:switch false} - proc_name arguments doc body} { - uplevel [list [self] instproc $proc_name $arguments $body] - my __api_make_doc inst $proc_name - } - -::xotcl::Object instproc ad_instforward { - {-private:switch false} - {-deprecated:switch false} - {-warn:switch false} - {-debug:switch false} - method_name doc args} { - uplevel [self] instforward $method_name $args - my __api_make_forward_doc inst $method_name - } - - - -::xotcl::Object instproc ad_doc {doc_string} { - ad_parse_documentation_string $doc_string doc_elements - set scope [::xotcl::api scope] - set doc_elements(script) [::xotcl::api script_name $scope] - set proc_index [::xotcl::api object_index $scope [self]] - - #if {![nsv_exists api_proc_doc $proc_index]} { - # nsv_lappend api_proc_doc_scripts $doc_elements(script) $proc_index - #} - set doc_elements(public_p) true - set doc_elements(private_p) false - set doc_elements(varargs_p) false - set doc_elements(deprecated_p) false - set doc_elements(default_values) "" - set doc_elements(switches) "" - set doc_elements(positionals) "" - set doc_elements(flags) "" - nsv_set api_proc_doc $proc_index [array get doc_elements] - nsv_set api_library_doc \ - $proc_index \ - [array get doc_elements] - - set file_index $doc_elements(script) - - if {[nsv_exists api_library_doc $file_index]} { - array set elements [nsv_get api_library_doc $file_index] - } - set oldDoc [expr {[info exists elements(main)] ? \ - [lindex $elements(main) 0] : ""}] - set prefix "This file defines the following Objects and Classes" - set entry [::xotcl::api object_link $scope [self]] - if {![string match *$prefix* $oldDoc]} { - append oldDoc "

$prefix: $entry" - } else { - append oldDoc ", $entry" - } - set elements(main) [list $oldDoc] - #my log "elements = [array get elements]" - nsv_set api_library_doc $file_index [array get elements] -} - - -Class ::Test -ad_doc { - Test Class for the documentation of - Classes, - Objects, - instprocs, and - procs. - @author Gustaf Neumann - @cvs-id $Id: 05-doc-procs.tcl,v 1.10 2006/12/29 11:04:16 gustafn Exp $ -} -::Test ad_proc my-class-specific-proc {x y} { - This is a proc of Class Test merely for testing purposes... - @param x First Operand - @param y Second Operand -} { - ns_log notice "hello world $x $y" -} - -::Test ad_instproc my-method {-id:required} { - This is an instproc of Class Test merely for testing purposes... - @param id Some Id -} { - ns_log notice "hello world $id" -} -::Test ad_instproc my-method2 {-id:required {-flag:boolean true}} { - This is an instproc of Class Test merely for testing purposes... - @param id Some Id - @param flag Some flag -} { - ns_log notice "hello world $id" -} -::Test ad_instproc -private my-method3 {-id:required {-flag:boolean true} -switch:switch x {y 1}} { - This is an instproc of Class Test merely for testing purposes... - @param id Some Id - @param flag Some flag - @param switch Switch to turn on or off depending on default - @param x First Operand - @param y Second Operand -} { - ns_log notice "hello world $id" -} - -Class ::SpecializedTest -superclass ::Test -ad_doc { - A Class defined as a subclass of ::Test for testing the - documentation stuff... -} Index: openacs-4/packages/xotcl-core/tcl/10-recreation-procs.tcl-old =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/Attic/10-recreation-procs.tcl-old,v diff -u -N --- openacs-4/packages/xotcl-core/tcl/10-recreation-procs.tcl-old 30 Dec 2005 00:04:44 -0000 1.4 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,161 +0,0 @@ -ad_library { - Support for the recreation of classes objects without - destroying foreign references. Normally, when a class - definition is reloaded, the class is destroyed and created - again with the same name. During the destruction of a class - several references to this class are removed (e.g. in a - class hierarchy, the relation from instances to this class, etc.). - XOTcl provides support for altering this behavior through - the recreate method. - - @author Gustaf Neumann - @creation-date 2005-05-13 - @cvs-id $Id: 10-recreation-procs.tcl-old,v 1.4 2005/12/30 00:04:44 gustafn Exp $ -} - -if {![::xotcl::Object isclass ::xotcl::RecreationClass]} { - ::xotcl::Class create ::xotcl::RecreationClass -ad_doc { -

This meta-class controlls the behavior of classes (and optionally - their instances), when the classes (or their instances) are - overwritten by same named new objects; we call this situation - a recreate of an object.

- -

Normally, when files with e.g. class definitions are sourced, - the classes and objects are newly defined. When e.g. class - definitions exists already in this file, these classes are - deleted first before they are newly created. When a class is - deleted, the instances of this class are changed into - instances of class ::xotcl::Object.

- -

This can be a problem when the class instances are not - reloaded and when they should survife the redefintion with the - same class relationships. Therefore we define a - meta class RecreationClass, which can be used to parameterize - the behavior on redefinitions. Alternatively, Classes or objects - could provide their own recreate methods.

- -

Per default, this meta-class handles only the class redefintion - case and does only a reconfigure on the class object (in order - to get e.g. ad_doc updated).

- The following parameters are defined: -
    -
  • reconfigure: reconfigure class (default 1) -
  • reinit: run init after configure for this class (default unset) -
  • instrecreate: handle recreate of class instances (default unset) - When this flag is set to 0, instreconfigure and instreinit are ignored. -
  • instreconfigure: reconfigure instances of this class (default 1) -
  • instreinit: re-init instances of this class (default unset) -
- } -parameter { - {reconfigure 1} - {reinit} - {instrecreate} - {instreconfigure 1} - {instreinit} - } -superclass ::xotcl::Class \ - -instproc recreate {obj args} { - my log "### recreateclass instproc $obj <$args>" - # the minimal reconfiguration is to set the class and remove methods - $obj class [self] - foreach p [$obj info procs] {$obj proc $p {} {}} - if {![my exists instrecreate]} { - #my log "### no instrecreate for $obj <$args>" - next - return - } - if {[my exists instreconfigure]} { - # before we set defaults, we must unset vars - foreach var [$obj info vars] {$obj unset $var} - set pcl [my info parameterclass] - # set defaults and run configure - $pcl searchDefaults $obj - eval $obj configure $args - #my log "### instproc recreate $obj + configure $args ..." - } - if {[my exists instreinit]} { - #my log "### instreinit for $obj <$args>" - eval $obj init - #my log "### instproc recreate $obj + init ..." - } - } -proc recreate {obj args} { - my log "### recreateclass proc $obj <$args>" - # the minimal reconfiguration is to set the class and remove methods - $obj class [self] - foreach p [$obj info instprocs] {$obj instproc $p {} {}} - if {[my exists reconfigure]} { - # before we set defaults, we must unset vars - foreach var [$obj info vars] {$obj unset $var} - set pcl [my info parameterclass] - $pcl searchDefaults $obj - # set defaults and run configure - eval $obj configure $args - } - if {[my exists reinit]} { - eval $obj init - } - } - - ::Serializer exportObjects { - ::xotcl::RecreationClass - } -} - -Class ad_proc recreate {obj args} { - The re-definition of recreate makes reloading of class definitions via - apm possible, since the foreign keys of the class relations - to these classes survive these calls. One can define specialized - versions of this for certain classes or use ::xotcl::RecreationClass. - - Class proc recreate is called on the class level, while - Class instproc recreate is called on the instance level. - - @param obj name of the object to be recreated - @param args arguments passed to recreate (might contain parameters) -} { - # clean on the class level - #my log "proc recreate $obj $args" - foreach p [$obj info instprocs] {$obj instproc $p {} {}} - $obj instmixin set {} - $obj instfilter set {} - next ; # clean next on object level -} -Class ad_instproc recreate {obj args} { - The re-definition of recreate makes reloading of class definitions via - apm possible, since the foreign keys of the class relations - to these classes survive these calls. One can define specialized - versions of this for certain classes or use ::xotcl::RecreationClass. - - Class proc recreate is called on the class level, while - Class instproc recreate is called on the instance level. - - @param obj name of the object to be recreated - @param args arguments passed to recreate (might contain parameters) -} { - # clean on the object level - my log "+++ instproc recreate $obj <$args> old class = [$obj info class], new class = [self]" - set cl [self] - $obj class $cl - foreach p [$obj info procs] {$obj proc $p {} {}} - foreach c [$obj info children] { - my log "recreate destroy <$c destroy" - $c destroy - } - foreach var [$obj info vars] {$obj unset $var} - $obj mixin set {} - $obj filter set {} - set pcl [$cl info parameterclass] - $pcl searchDefaults $obj - #my log "+++ recreate calling $obj configure $args" - set pos [eval $obj configure $args] - #my log "+++ recreate instproc configure returns $pos" - if {[lsearch -exact $args -init] == -1} { - incr pos -1 - #my log "+++ $obj init [lrange $args 0 $pos]" - eval $obj init [lrange $args 0 $pos] - } -} - -::Serializer exportMethods { - ::xotcl::Class instproc recreate - ::xotcl::Class proc recreate -} \ No newline at end of file Index: openacs-4/packages/xotcl-core/tcl/20-Ordered-Composite-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/20-Ordered-Composite-procs.tcl,v diff -u -N -r1.7.2.1 -r1.7.2.2 --- openacs-4/packages/xotcl-core/tcl/20-Ordered-Composite-procs.tcl 15 Jan 2007 08:49:58 -0000 1.7.2.1 +++ openacs-4/packages/xotcl-core/tcl/20-Ordered-Composite-procs.tcl 1 Aug 2007 21:39:32 -0000 1.7.2.2 @@ -61,7 +61,9 @@ # destroy all children of the ordered composite if {[my exists __children]} { #my log "--W destroying children [my set __children]" - foreach c [my set __children] { $c destroy } + foreach c [my set __children] { + if {[my isobject $c]} {$c destroy} + } } #show_stack;my log "--W children murdered, now next, chlds=[my info children]" namespace eval [self] {namespace forget *} ;# for pre 1.4.0 versions @@ -135,5 +137,19 @@ } } } + + Class OrderedComposite::MethodCompare + OrderedComposite::MethodCompare instproc __compare {a b} { + set by [my set __orderby] + set x [$a $by] + set y [$b $by] + if {$x < $y} { + return -1 + } elseif {$x > $y} { + return 1 + } else { + return 0 + } + } } Index: openacs-4/packages/xotcl-core/tcl/30-widget-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/30-widget-procs.tcl,v diff -u -N -r1.10 -r1.10.2.1 --- openacs-4/packages/xotcl-core/tcl/30-widget-procs.tcl 15 Sep 2006 16:33:06 -0000 1.10 +++ openacs-4/packages/xotcl-core/tcl/30-widget-procs.tcl 1 Aug 2007 21:39:32 -0000 1.10.2.1 @@ -39,16 +39,27 @@ set ::xo::acs_lang_url [apm_package_url_from_key acs-lang]admin - proc localize text { + proc localize {text {inline 0}} { + #ns_log notice "--local $text $inline" if {![my exists __localizer]} { my set __localizer [list] } if {[string first \x002 $text] == -1} { return $text } else { set return_text "" + if {$inline} { + # Attempt to move all message keys outside of tags + while { [regsub -all {(<[^>]*)(\x002\(\x001[^\x001]*\x001\)\x002)([^>]*>)} $text {\2\1\3} text] } {} + + # Attempt to move all message keys outside of statements + regsub -all -nocase {(]*>[^<]*)(\x002\(\x001[^\x001]*\x001\)\x002)([^<]*]*>)} $text {\2\1\3} text + + while { [regsub -all -nocase {(]*>[^<]*)(\x002\(\x001[^\x001]*\x001\)\x002)} $text {\2\1} text] } {} + } + while {[regexp {^([^\x002]*)\x002\(\x001([^\x001]*)\x001\)\x002(.*)$} $text _ \ - before key text]} { + before key text]} { append return_text $before foreach {package_key message_key} [split $key .] break set url [export_vars -base $::xo::acs_lang_url/edit-localized-message { @@ -67,7 +78,12 @@ }] set type missing } - my lappend __localizer [::xo::Localizer new -type $type -key $key -url $url] + if {!$inline} { + my lappend __localizer [::xo::Localizer new -type $type -key $key -url $url] + } else { + set l [::xo::Localizer new -type $type -key $key -url $url] + append return_text [$l asHTML] + } } append return_text $text return $return_text @@ -134,7 +150,11 @@ # proc get_user_name {uid} { if {$uid ne "" && $uid != 0} { - acs_user::get -user_id $uid -array user + if {[catch {acs_user::get -user_id $uid -array user}]} { + # we saw some strange cases, where after a regression, + # a user_id was present, which was already deleted... + return nobody + } return "$user(first_names) $user(last_name)" } else { return nobody @@ -144,13 +164,15 @@ # # define an abstract table # - Class Table -superclass OrderedComposite \ - -parameter {{no_data "No Data"} {renderer TABLE2}} + -parameter [expr {[apm_version_names_compare [ad_acs_version] 5.3.0] == 1 ? + {{no_data "No Data"} {renderer TABLE3}} : + {{no_data "No Data"} {renderer TABLE2}} + }] Table instproc destroy {} { #my log "-- " - foreach c {__actions __columns} { + foreach c {:__bulkactions __actions __columns} { #my log "-- namespace eval [self]::$c {namespace forget *}" namespace eval [self]::$c {namespace forget *} } @@ -161,6 +183,11 @@ namespace eval $M {namespace import -force [self class]::*} $M contains $cmd } + Table instproc __bulkactions {cmd} { + set M [OrderedComposite create [self]::__bulkactions] + namespace eval $M {namespace import -force [self class]::*} + $M contains $cmd + } Table instproc columns {cmd} { set M [OrderedComposite create [self]::__columns] namespace eval $M {namespace import -force [self class]::*} @@ -177,7 +204,7 @@ } Table instproc render_with {renderer trn_mixin} { - #my log "--" + #my log "-- renderer=$renderer" set cl [self class] [self] mixin ${cl}::$renderer foreach child [$cl info classchildren] { @@ -199,19 +226,25 @@ Table instproc write_csv {} { set output "" set line [list] + my msg columns=[[self]::__columns children] foreach column [[self]::__columns children] { - set value [string map {\" \\\"} [$column name]] + set label [$column label] + if {[regexp {^#(.*)#$} $label _ message_key]} { + set label [_ $message_key] + } + set value [string map {\" \\\"} $label] lappend line \"$value\" } append output [join $line ,] \n foreach row [my children] { set line [list] foreach column [[self]::__columns children] { - set value [string map {\" \\\"} [$row set [$column name]]] + set value [string map {\" \\\"} [$row set [$column set name]]] lappend line \"$value\" } append output [join $line ,] \n } + #ns_return 200 text/plain $output ns_return 200 text/csv $output } @@ -253,6 +286,23 @@ return -[my name] } + Class BulkAction \ + -superclass ::xo::OrderedComposite::Child \ + -parameter {name id {html {}}} \ + -instproc actions {cmd} { + my init + set grandParent [[my info parent] info parent] + if {![my exists name]} {my set name [namespace tail [self]]} + set M [::xo::OrderedComposite create ${grandParent}::__bulkactions] + namespace eval $M {namespace import -force ::xo::Table::*} + $M contains $cmd + $M set __belongs_to [self] + $M set __identifier [my set name] + } \ + -instproc get-slots {} { + ; + } + Class AnchorField \ -superclass ::xo::Table::Field \ -instproc get-slots {} { @@ -269,7 +319,6 @@ -instproc get-slots {} { set slots [list -[my name]] lappend slots [list -[my name].src [my src]] - lappend slots [list -[my name].href ""] foreach att {width height border title alt} { if {[my exists $att]} { lappend slots [list -[my name].$att [my $att]] @@ -280,33 +329,40 @@ return $slots } + Class ImageAnchorField \ + -superclass ::xo::Table::ImageField \ + -instproc get-slots {} { + return [concat [next] -[my name].href ""] + } + Class ImageField_EditIcon \ - -superclass ImageField -parameter { + -superclass ImageAnchorField -parameter { {src /resources/acs-subsite/Edit16.gif} {width 16} {height 16} {border 0} {title "[_ xotcl-core.edit_item]"} {alt "edit"} } # for xotcl 1.4.0: {title [_ xotcl-core.edit_item]} {alt "edit"} Class ImageField_AddIcon \ - -superclass ImageField -parameter { + -superclass ImageAnchorField -parameter { {src /resources/acs-subsite/Add16.gif} {width 16} {height 16} {border 0} {title "Add Item"} {alt "add"} } Class ImageField_ViewIcon \ - -superclass ImageField -parameter { + -superclass ImageAnchorField -parameter { {src /resources/acs-subsite/Zoom16.gif} {width 16} {height 16} {border 0} {title "View Item"} {alt "view"} } Class ImageField_DeleteIcon \ - -superclass ImageField -parameter { + -superclass ImageAnchorField -parameter { {src /resources/acs-subsite/Delete16.gif} {width 16} {height 16} {border 0} {title "Delete Item"} {alt "delete"} } # export table elements - namespace export Field AnchorField Action ImageField \ - ImageField_EditIcon ImageField_ViewIcon ImageField_DeleteIcon ImageField_AddIcon + namespace export Field AnchorField Action ImageField ImageAnchorField \ + ImageField_EditIcon ImageField_ViewIcon ImageField_DeleteIcon ImageField_AddIcon \ + BulkAction } } @@ -321,6 +377,9 @@ -instproc init_renderer {} { #my log "--" my set __rowcount 0 + my set css.table-class list + my set css.tr.even-class list-even + my set css.tr.odd-class list-odd } TABLE instproc render-actions {} { @@ -339,6 +398,27 @@ } } + TABLE instproc render-bulkactions {} { + set bulkactions [[self]::__bulkactions children] + html::div -class "list-button-bar-bottom" { + html::t "Bulk-Actions:" + set bulkaction_container [[lindex $bulkactions 0] set __parent] + set name [$bulkaction_container set __identifier] + + html::ul -class compact { + foreach ba $bulkactions { + html::li { + html::a -title [$ba tooltip] -class button -href # \ + -onclick "acs_ListBulkActionClick('$name','[$ba url]'); return false;" \ + { + html::t [$ba label] + } + } + } + } + } + } + TABLE instproc render-body {} { html::tr -class list-header { foreach o [[self]::__columns children] { @@ -350,7 +430,10 @@ html::tr {html::td { html::t [my set no_data]}} } else { foreach line [my children] { - html::tr -class [expr {[my incr __rowcount]%2 ? "list-odd" : "list-even" }] { + #my log "--LINE vars=[my info vars] cL: [[self class] info vars] r=[my renderer]" + html::tr -class [expr {[my incr __rowcount]%2 ? + [my set css.tr.odd-class] : + [my set css.tr.even-class] }] { foreach field [[self]::__columns children] { html::td [concat [list class list] [$field html]] { $field render-data $line @@ -363,9 +446,22 @@ TABLE instproc render {} { if {![my isobject [self]::__actions]} {my actions {}} - html::table -class list { - my render-actions - my render-body + if {![my isobject [self]::__bulkactions]} {my bulkactions {}} + set bulkactions [[self]::__bulkactions children] + if {$bulkactions eq ""} { + html::table -class [my set css.table-class] { + my render-actions + my render-body + } + } else { + set name [[self]::__bulkactions set __identifier] + html::form -name $name { + html::table -class [my set css.table-class] { + my render-actions + my render-body + } + my render-bulkactions + } } } @@ -391,7 +487,11 @@ Class create TABLE::Field -superclass ::xo::Drawable TABLE::Field instproc render-data {line} { - html::t [$line set [my name]] + if {[$line exists [my name].richtext]} { + html::t -disableOutputEscaping [$line set [my name]] + } else { + html::t [$line set [my name]] + } } TABLE::Field instproc render {} { @@ -432,7 +532,7 @@ set href [export_vars -base [ad_conn url] $query] html::a -href $href -title $title { html::t [my _ label] - html::img -src $img -alt "" + html::img -src $img -alt "" -border 0 } } @@ -453,12 +553,43 @@ Class create TABLE::ImageField \ -superclass TABLE::Field \ -instproc render-data {line} { - html::a -href [$line set [my name].href] -style "border-bottom: none;" { - html::img [$line attlist [my name] {src width height border title alt}] {} - } - $line render_localizer + html::a -style "border-bottom: none;" { + html::img [$line attlist [my name] {src width height border title alt}] {} + } + $line render_localizer } + Class create TABLE::ImageAnchorField \ + -superclass TABLE::Field \ + -instproc render-data {line} { + set href [$line set [my name].href] + if {$href ne ""} { + html::a -href $href -style "border-bottom: none;" { + html::img [$line attlist [my name] {src width height border title alt}] {} + } + $line render_localizer + } + } + + Class create TABLE::BulkAction -superclass ::xo::Drawable + TABLE::BulkAction instproc render {} { + set name [my name] + #my msg [my serialize] + html::th -class list { + html::input -type checkbox -name __bulkaction \ + -onclick "acs_ListCheckAll('$name', this.checked)" \ + -title "Mark/Unmark all rows" + } + } + TABLE::BulkAction instproc render-data {line} { + #my msg [my serialize] + set name [my name] + set value [$line set [my id]] + html::input -type checkbox -name $name -value $value \ + -id "$name,$value" \ + -title "Mark/Unmark this row" + } + Class TABLE2 \ -superclass TABLE \ -instproc render-actions {} { @@ -472,19 +603,49 @@ } \ -instproc render {} { if {![my isobject [self]::__actions]} {my actions {}} + if {![my isobject [self]::__bulkactions]} {my __bulkactions {}} + set bulkactions [[self]::__bulkactions children] html::div { my render-actions - html::div -class table { - html::table -class list {my render-body} - } + if {$bulkactions eq ""} { + html::div -class table { + html::table -class [my set css.table-class] {my render-body} + } + } else { + set name [[self]::__bulkactions set __identifier] + html::form -name $name { + html::div -class table { + html::table -class [my set css.table-class] {my render-body} + my render-bulkactions + } + } + } } } + Class create TABLE2::Action -superclass TABLE::Action Class create TABLE2::Field -superclass TABLE::Field Class create TABLE2::AnchorField -superclass TABLE::AnchorField Class create TABLE2::ImageField -superclass TABLE::ImageField - + Class create TABLE2::ImageAnchorField -superclass TABLE::ImageAnchorField + Class create TABLE2::BulkAction -superclass TABLE::BulkAction + + Class TABLE3 \ + -superclass TABLE2 \ + -instproc init_renderer {} { + next + my set css.table-class list-table + my set css.tr.even-class even + my set css.tr.odd-class odd + } + + Class create TABLE3::Action -superclass TABLE::Action + Class create TABLE3::Field -superclass TABLE::Field + Class create TABLE3::AnchorField -superclass TABLE::AnchorField + Class create TABLE3::ImageField -superclass TABLE::ImageField + Class create TABLE3::ImageAnchorField -superclass TABLE::ImageAnchorField + Class create TABLE3::BulkAction -superclass TABLE::BulkAction } Class TableWidget \ Index: openacs-4/packages/xotcl-core/tcl/40-thread-mod-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/40-thread-mod-procs.tcl,v diff -u -N -r1.3 -r1.3.2.1 --- openacs-4/packages/xotcl-core/tcl/40-thread-mod-procs.tcl 14 Jul 2006 01:22:11 -0000 1.3 +++ openacs-4/packages/xotcl-core/tcl/40-thread-mod-procs.tcl 1 Aug 2007 21:39:32 -0000 1.3.2.1 @@ -12,7 +12,7 @@ When an instance of THREAD is created (e.g. t1), an init-command is provided. e.g.:
-    THREAD create t1 {
+    ::xotcl::THREAD create t1 {
       Class Counter -parameter {{value 1}}
       Counter instproc ++ {} {my incr value}
       Counter c1
@@ -52,7 +52,7 @@
    creates a Proxy for an object c1 in thread t1.
    After this, c1 can be used like an local object.
   
-    THREAD::Proxy c1 -attach t1
+    ::xotcl::THREAD::Proxy c1 -attach t1
     set x [c1 ++]
   
The Proxy forwards all commands to the @@ -85,9 +85,9 @@ ::xotcl::Object setExitHandler { #my log "EXITHANDLER of request thread [pid]" - if {[catch {Proxy detachAll} m]} { - #my log "EXITHANDLER error in detachAll $m" - } + #if {[catch {::xotcl::THREAD::Proxy detachAll} m]} { + # #my log "EXITHANDLER error in detachAll $m" + #} } ::Serializer exportObjects { @@ -102,7 +102,7 @@ # -parameter {{persistent 0}} Class create ::xotcl::THREAD \ - -parameter {{persistent 0}} + -parameter {{persistent 0} {lightweight 0}} #Class create ::xotcl::THREAD \ # -parameter {{persistent 0}} @@ -117,8 +117,20 @@ } ::xotcl::THREAD instproc init cmd { - my instvar initcmd - set initcmd { + my instvar initcmd + if {![ns_ictl epoch]} { + #ns_log notice "--THREAD init [self] no epoch" + + # We are during initialization. For some unknown reasons, XOTcl + # is not available in newly created threads, so we have to care for it. + # We need only a partial initialization, to allow the exit handler + # to be defined. + set initcmd { + package req XOTcl + namespace import -force ::xotcl::* + } + } + append initcmd { ::xotcl::Object setExitHandler { #my log "EXITHANDLER of slave thread SELF [pid]" } @@ -161,7 +173,7 @@ my log "thread terminated" nsv_unset [self class] [self] thread::mutex destroy [my set mutex] - ns_log notice "mutex [my set mutex] destroyed" + my log "+++ mutex [my set mutex] destroyed" } } next @@ -186,14 +198,31 @@ #my check_blueprint #my log "after lock" if {![nsv_exists [self class] [self]]} { - set tid [::thread::create] + if {[my lightweight]} { + my log "CREATE lightweight thread" + set tid [::thread::create -thin] + } else { + set tid [::thread::create] + } nsv_set [self class] [self] $tid if {[my persistent]} { - my log "created new persistent [self class] as $tid pid=[pid]" + my log "--created new persistent [self class] as $tid pid=[pid]" } else { - my log "created new [self class] as $tid pid=[pid]" + my log "--created new [self class] as $tid pid=[pid]" } - ::thread::send $tid [my set initcmd] + #my log "--THREAD DO send [self] epoch = [ns_ictl epoch]" + if {[my lightweight]} { + } elseif {![ns_ictl epoch]} { + #ns_log notice "--THREAD send [self] no epoch" + # We are during initialization. For some unknown reasons, XOTcl + # is not available in newly created threads, so we have to care + # for full initialization, including xotcl blueprint. + _ns_savenamespaces + set initcmd [ns_ictl get] + } + append initcmd [my set initcmd] + #ns_log notice "INIT $initcmd" + ::thread::send $tid $initcmd } else { set tid [nsv_get [self class] [self]] } @@ -223,7 +252,7 @@ # create a sample persistent thread that can be acessed # via request threads -#THREAD create t0 { +#::xotcl::THREAD create t0 { # Class Counter -parameter {{value 1}} # Counter instproc ++ {} {my incr value} # Index: openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl,v diff -u -N -r1.7 -r1.7.2.1 --- openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl 12 Dec 2006 19:09:26 -0000 1.7 +++ openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl 1 Aug 2007 21:39:32 -0000 1.7.2.1 @@ -11,6 +11,7 @@ ns_log notice "libthread does not appear to be available, NOT loading bgdelivery" return } +#return ;# DONT COMMIT # catch {ns_conn contentsentlength} alone does not work, since we do not have # a connection yet, and the bgdelivery won't be activated @@ -108,7 +109,79 @@ fconfigure [my channel] -translation binary incr ::subscription_count } -} -persistent 1 + + Class ::HttpSpooler -parameter {channel {timeout 10000} {counter 0}} + ::HttpSpooler instproc init {} { + my set running 0 + my set release 0 + my set spooling 0 + my set queue [list] + } + ::HttpSpooler instproc all_done {} { + catch {close [my channel]} + my log "" + my destroy + } + ::HttpSpooler instproc release {} { + # release indicates the when running becomes 0, the spooler is finished + my set release 1 + if {[my set running] == 0} {my all_done} + } + ::HttpSpooler instproc done {reason request} { + my instvar running release + incr running -1 + my log "--running $running" + $request destroy + if {$running == 0 && $release} {my all_done} + } + ::HttpSpooler instproc deliver {data request} { + my instvar spooling + my log "-- spooling $spooling" + if {$spooling} { + my log "--enqueue" + my lappend queue $data $request + } else { + #my log "--send" + set spooling 1 + # puts -nonewline [my channel] $data + # my done + set filename [ns_tmpnam] + set fd [open $filename w] + fconfigure $fd -translation binary + puts -nonewline $fd $data + close $fd + set fd [open $filename] + fconfigure $fd -translation binary + fconfigure [my channel] -translation binary + fcopy $fd [my channel] -command \ + [list [self] end-delivery $filename $fd [my channel] $request] + } + } + ::HttpSpooler instproc end-delivery {filename fd ch request bytes args} { + my instvar queue + my log "--- end of delivery of $filename, $bytes bytes written $args" + if {[catch {close $fd} e]} {ns_log notice "httpspool, closing file $filename, error: $e"} + my set spooling 0 + if {[llength $queue]>0} { + my log "--dequeue" + set data [lindex $queue 0] + set req [lindex $queue 1] + set queue [lreplace $queue 0 1] + my deliver $data $req + } + my done delivered $request + } + ::HttpSpooler instproc add {-request {-post_data ""}} { + if {[regexp {http://([^/]*)(/.*)} $request _ host path]} { + set port 80 + regexp {^([^:]+):(.*)$} $host _ host port + my incr running + xo::AsyncHttpRequest [self]::[my incr counter] \ + -host $host -port $port -path $path \ + -timeout [my timeout] -post_data $post_data -request_manager [self] + } + } +} -persistent 1 ;# -lightweight 1 bgdelivery ad_forward running { Interface to the background delivery thread to query the currently running deliveries. @@ -170,4 +243,19 @@ bgdelivery proc send_to_subscriber {key msg} { my do -async ::Subscriber broadcast $key $msg -} \ No newline at end of file +} +##################################### +bgdelivery proc create_spooler {{-content_type text/plain} {-timeout 10000}} { + ns_write "HTTP/1.0 200 OK\r\nContent-type: $content_type\r\n\r\n" + set ch [ns_conn channel] + thread::transfer [my get_tid] $ch + my do ::HttpSpooler new -channel $ch -timeout $timeout +} + +bgdelivery proc spooler_add_request {spooler request {post_data ""}} { + my log "-- do -async $spooler add -request $request" + my do -async $spooler add -request $request -post_data $post_data +} +bgdelivery proc spooler_release {spooler} { + my do -async $spooler release +} Index: openacs-4/packages/xotcl-core/tcl/chat-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/Attic/chat-procs.tcl,v diff -u -N -r1.11 -r1.11.2.1 --- openacs-4/packages/xotcl-core/tcl/chat-procs.tcl 2 Dec 2006 19:07:01 -0000 1.11 +++ openacs-4/packages/xotcl-core/tcl/chat-procs.tcl 1 Aug 2007 21:39:32 -0000 1.11.2.1 @@ -39,7 +39,9 @@ set msg [ad_quotehtml $msg] my log "-- msg=$msg" - if {$get_new && [info command ::thread::mutex] ne ""} { + if {$get_new + && [info command ::thread::mutex] ne "" + && [info command ::bgdelivery] ne ""} { # we could use the streaming interface my broadcast_msg [Message new -volatile -time [clock seconds] \ -user_id $user_id -msg $msg -color $color] Index: openacs-4/packages/xotcl-core/tcl/context-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/context-procs.tcl,v diff -u -N -r1.6.2.1 -r1.6.2.2 --- openacs-4/packages/xotcl-core/tcl/context-procs.tcl 15 Jan 2007 08:49:58 -0000 1.6.2.1 +++ openacs-4/packages/xotcl-core/tcl/context-procs.tcl 1 Aug 2007 21:39:32 -0000 1.6.2.2 @@ -50,13 +50,17 @@ } # get the query parameters (from the url) + #my log "--P processing actual query $actual_query" foreach querypart [split $actual_query &] { set name_value_pair [split $querypart =] set att_name [ns_urldecode [lindex $name_value_pair 0]] - set att_value [expr {[llength $name_value_pair] == 1 ? 1 : - [ns_urldecode [lindex $name_value_pair 1]] }] + if {[llength $name_value_pair] == 1} { + set att_value 1 + } else { + set att_value [ns_urldecode [lindex $name_value_pair 1]] + } if {[info exists (-$att_name)]} { - set passed_args(-$att_name) $att_value + lappend passed_args(-$att_name) $att_value } elseif {$all_from_query} { set queryparm($att_name) $att_value } @@ -99,6 +103,17 @@ #my log "--cc qp [array names queryparm] // $actual_query" } + Context instproc query_parameter {name {default ""}} { + my instvar queryparm + return [expr {[info exists queryparm($name)] ? $queryparm($name) : $default}] + } + Context instproc exists_query_parameter {name} { + #my log "--qp my exists $name => [my exists queryparm($name)]" + my exists queryparm($name) + } + Context instproc get_all_query_parameter {} { + return [my array get queryparm] + } Context ad_instproc export_vars {{-level 1}} { Export the query variables @@ -150,7 +165,6 @@ url } - # TODO code (in xinha, + css) # TODO edit revision loop ConnectionContext proc require { @@ -161,7 +175,7 @@ {-actual_query " "} } { if {![info exists url]} { - my log "--CONN ns_conn url" + #my log "--CONN ns_conn url" set url [ns_conn url] } #my log "--i [self args]" @@ -174,19 +188,19 @@ if {![my isobject ::xo::cc]} { my create ::xo::cc \ -package_id $package_id \ - -parameter_declaration $parameter \ + [list -parameter_declaration $parameter] \ -user_id $user_id \ -actual_query $actual_query \ -url $url - #my log "--cc ::xo::cc created $url" - ::xo::cc destroy_on_cleanup + #my msg "--cc ::xo::cc created $url [::xo::cc serialize]" + ::xo::cc destroy_on_cleanup } else { #my log "--cc ::xo::cc reused $url" ::xo::cc configure \ -package_id $package_id \ -url $url \ -actual_query $actual_query \ - -parameter_declaration $parameter + [list -parameter_declaration $parameter] ::xo::cc set_user_id $user_id ::xo::cc process_query_parameter } @@ -200,7 +214,7 @@ } ConnectionContext instproc returnredirect {url} { - my log "--rp" + #my log "--rp" my set __continuation [list ad_returnredirect $url] return "" } @@ -246,12 +260,21 @@ call ::permission::permission_p but avoid multiple calls in the same session through caching in the connection context } { - #my log "--p [self args] [info exists party_id] " if {![info exists party_id]} { set party_id [my user_id] #my log "--p party_id $party_id" - #::xo::show_stack if {$party_id == 0} { + set key permission($object_id,$privilege,$party_id) + if {[my exists $key]} {return [my set $key]} + set granted [permission::permission_p -party_id $party_id \ + -object_id $object_id \ + -privilege $privilege] + if {$granted} { + my set $key $granted + return $granted + } + # The permission is not granted for the public. + # We force the user to login auth::require_login return 0 } @@ -270,27 +293,36 @@ # next # } - ConnectionContext instproc query_parameter {name {default ""}} { - my instvar queryparm - return [expr {[info exists queryparm($name)] ? $queryparm($name) : $default}] - } - ConnectionContext instproc exists_query_parameter {name} { - #my log "--qp my exists $name => [my exists queryparm($name)]" - my exists queryparm($name) - } - ConnectionContext instproc form_parameter {name {default ""}} { + ConnectionContext instproc get_all_form_parameter {} { my instvar form_parameter + #array set form_parameter [ns_set array [ns_getform]] + foreach {att value} [ns_set array [ns_getform]] { + if {[info exists form_parameter($att)]} { + my set form_parameter_multiple($att) 1 + } + lappend form_parameter($att) $value + } + } + ConnectionContext instproc form_parameter {name {default ""}} { + my instvar form_parameter form_parameter_multiple if {![info exists form_parameter]} { - array set form_parameter [ns_set array [ns_getform]] + my get_all_form_parameter } - return [expr {[info exists form_parameter($name)] ? - $form_parameter($name) : $default}] + if {[info exists form_parameter($name)]} { + if {[info exists form_parameter_multiple($name)]} { + return $form_parameter($name) + } else { + return [lindex $form_parameter($name) 0] + } + } else { + return $default + } } ConnectionContext instproc exists_form_parameter {name} { my instvar form_parameter if {![info exists form_parameter]} { - array set form_parameter [ns_set array [ns_getform]] + my get_all_form_parameter } my exists form_parameter($name) } @@ -335,8 +367,8 @@ init_url false requires the package_id to be specified and a call to Package instproc set_url to complete initialization } { + #my log "--i [self args], URL=$url, init_url=$init_url" - #my log "--i [self args]" if {$url eq "" && $init_url} { #set url [ns_conn url] #my log "--CONN ns_conn url" @@ -363,7 +395,7 @@ } { #my log "--R $package_id exists? [my isobject ::$package_id]" if {![my isobject ::$package_id]} { - #my log "--R we have to create ::$package_id" + #my log "--R we have to create ::$package_id //url='$url'" if {$url ne ""} { my create ::$package_id -url $url } else { @@ -384,14 +416,16 @@ PackageMgr create Package -parameter { id url + {context ::xo::cc} package_url + package_key instance_name } - Package instforward query_parameter ::xo::cc %proc - Package instforward exists_query_parameter ::xo::cc %proc - Package instforward form_parameter ::xo::cc %proc - Package instforward exists_form_parameter ::xo::cc %proc - Package instforward returnredirect ::xo::cc %proc + Package instforward query_parameter {%my set context} %proc + Package instforward exists_query_parameter {%my set context} %proc + Package instforward form_parameter {%my set context} %proc + Package instforward exists_form_parameter {%my set context} %proc + Package instforward returnredirect {%my set context} %proc Package instproc get_parameter {attribute {default ""}} { @@ -404,18 +438,31 @@ my instvar id url set id [namespace tail [self]] array set info [site_node::get_from_object_id -object_id $id] - my package_url $info(url) + set package_url $info(url) + if {[ns_conn isconnected]} { + # in case of of host-node map, simplify the url to avoid redirects + # .... but ad_host works only, when we are connected.... TODO: solution for syndication + set root [root_of_host [ad_host]] + regexp "^${root}(.*)$" $package_url _ package_url + } + #my log "--R package_url= $package_url (was $info(url))" + my package_url $package_url + my package_key $info(package_key) my instance_name $info(instance_name) - if {![my exists url]} { + if {[my exists url] && [info exists root]} { + regexp "^${root}(.*)$" $url _ url + } else { + my log "--R we have no url, use package_url" # if we have no more information, we use the package_url as actual url - set url [my package_url] - } + set url $package_url + } my set_url -url $url } Package instproc set_url {-url} { my url $url my set object [string range [my url] [string length [my package_url]] end] + #my log "--R object set to [my set object], [my serialize]" } # Package instproc destroy {} { Index: openacs-4/packages/xotcl-core/tcl/generic-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/generic-procs.tcl,v diff -u -N -r1.40.2.1 -r1.40.2.2 --- openacs-4/packages/xotcl-core/tcl/generic-procs.tcl 15 Jan 2007 08:49:58 -0000 1.40.2.1 +++ openacs-4/packages/xotcl-core/tcl/generic-procs.tcl 1 Aug 2007 21:39:32 -0000 1.40.2.2 @@ -53,69 +53,221 @@ } proc package_id_from_package_key { key } { - set id [apm_version_id_from_package_key $key] - set mount_url [site_node::get_children -all -package_key $key -node_id $id] - array set site_node [site_node::get -url $mount_url] - return $site_node(package_id) + return [db_string dbqd.null.get_package_id_from_key \ + {select package_id from apm_packages where package_key = :key}] } CrClass instproc unknown { obj args } { my log "unknown called with $obj $args" } + # + # The following methods are used oracle, postgres specific code (locking, + # for the type hierarchies, ... + # + CrClass instproc lock {tablename mode} { + # no locking by default + } + if {[db_driverkey ""] eq "postgresql"} { + # + # Postgres + # + CrClass instproc object_types_query { + {-subtypes_first:boolean false} + } { + my instvar object_type_key + set order_clause [expr {$subtypes_first ? "order by tree_sortkey desc":""}] + return "select object_type from acs_object_types where + tree_sortkey between '$object_type_key' and tree_right('$object_type_key') + $order_clause" + } + CrClass instproc init_type_hierarchy {} { + my instvar object_type + my set object_type_key [db_list [my qn get_tree_sortkey] { + select tree_sortkey from acs_object_types + where object_type = :object_type + }] + } + CrClass instproc type_selection {-with_subtypes:boolean} { + my instvar object_type_key object_type + if {$with_subtypes} { + #return "acs_object_types.tree_sortkey between '$object_type_key' and tree_right('$object_type_key')" + #return "ci.content_type in ('[join [my object_types] ',']')" + return "ci.content_type in ([my object_types_query])" + } else { + return "ci.content_type = '$object_type'" + #return "acs_object_types.tree_sortkey = '$object_type_key'" + } + } + set pg_version [db_string dbqd.null.get_version { + select substring(version() from 'PostgreSQL #"[0-9]+.[0-9+]#".%' for '#') }] + ns_log notice "--Postgres Version $pg_version" + if {$pg_version < 8.2} { + ns_log notice "--Postgres Version $pg_version older than 8.2, use locks" + CrClass instproc lock {tablename mode} { + db_dml [my qn lock_objects] "LOCK TABLE $tablename IN $mode MODE" + } + } + } else { + # + # Oracle + # + CrClass instproc object_types_query { + {-subtypes_first:boolean false} + } { + my instvar object_type + set order_clause [expr {$subtypes_first ? "order by LEVEL desc":""}] + return "select object_type from acs_object_types + start with object_type = '$object_type' + connect by prior object_type = supertype $order_clause" + } + CrClass instproc init_type_hierarchy {} { + my set object_type_key {} + } + CrClass instproc type_selection {-with_subtypes:boolean} { + my instvar object_type + if {$with_subtypes} { + return "acs_objects.object_type in ([my object_types_query])" + } else { + return "acs_objects.object_type = '$object_type'" + } + } + } + CrClass set common_query_atts { - item_id revision_id creation_user creation_date last_modified object_type - creation_user last_modified publish_status + object_type item_id revision_id + creation_user creation_date creation_user + publish_status last_modified } if {[apm_version_names_compare [ad_acs_version] 5.2] > -1} { CrClass lappend common_query_atts package_id } CrClass set common_insert_atts {name title description mime_type nls_language text} - CrClass instproc object_types { - {-subtypes_first:boolean false} - } { - my instvar object_type_key - set order_clause [expr {$subtypes_first ? "order by tree_sortkey desc":""}] - return [db_list get_object_types " - select object_type from acs_object_types where - tree_sortkey between :object_type_key and tree_right(:object_type_key) - $order_clause - "] - } - - CrClass instproc edit_atts {} { + CrClass instproc edit_atts {} { concat [[self class] set common_insert_atts] [my sql_attribute_names] } CrClass instproc object_type_exists {} { my instvar object_type - expr {$object_type eq [db_list select_type { + expr {$object_type eq [db_list [my qn select_type] { select object_type from acs_object_types where object_type = :object_type }]} } + CrClass ad_instproc folder_type_unregister_all { + {-include_subtypes t} + } { + Unregister the object type from all folders on the system + + @param include_subtypes Boolean value (t/f) to flag whether the + operation should be applied on subtypes as well + } { + my instvar object_type + db_foreach [my qn all_folders] { + select folder_id from cr_folder_type_map + where content_type = :object_type + } { + ::xo::db::sql::content_folder unregister_content_type \ + -folder_id $folder_id \ + -content_type $object_type \ + -include_subtypes $include_subtypes + } + } + CrClass ad_instproc folder_type { + {-include_subtypes t} -folder_id operation } { register the current object type for folder_id. If folder_id is not specified, use the instvar of the class instead. + + @param include_subtypes Boolean value (t/f) to flag whether the + operation should be applied on subtypes as well } { if {$operation ne "register" && $operation ne "unregister"} { - error "[self] operation for folder_type must be '\ - register' or 'unregister'" + error "[self] operation for folder_type must be 'register' or 'unregister'" } my instvar object_type if {![info exists folder_id]} { my instvar folder_id } - db_1row register_type "select content_folder__${operation}_content_type(\ - $folder_id,:object_type,'t')" + ::xo::db::sql::content_folder ${operation}_content_type \ + -folder_id $folder_id \ + -content_type $object_type \ + -include_subtypes $include_subtypes } + CrClass instproc create_attributes {} { + if {[my cr_attributes] ne ""} { + my instvar object_type + set slot [self]::slot + if {[info command $slot] eq ""} { + ::xotcl::Object create $slot + } + set o [::xo::OrderedComposite new -contains [my cr_attributes]] + $o destroy_on_cleanup + + foreach att [$o children] { + $att instvar attribute_name datatype pretty_name sqltype references default + # provide a default pretty name for the attribute based on message keys + if {![info exists pretty_name]} { + set pretty_name "#xowiki.[namespace tail [self]]-$attribute_name#" + } + + set column_spec [::xo::db::sql map_datatype $sqltype] + #my log "--SQL $attribute_name datatype=$datatype, sqltype=$sqltype, column_spec=$column_spec" + if {[info exists references]} {append column_spec " references $references" } + if {[info exists default]} {append column_spec " default '$default'" } + append column_spec " " \ + [::xo::db::sql datatype_constraint $sqltype [my table_name] $attribute_name] + + if {![attribute::exists_p $object_type $attribute_name]} { + ::xo::db::sql::content_type create_attribute \ + -content_type $object_type \ + -attribute_name $attribute_name \ + -datatype $datatype \ + -pretty_name $pretty_name \ + -column_spec [string trim $column_spec] + } + #if {![info exists default]} { + # set default "" + #} + #lappend parameters [list $attribute_name $default] + #unset default + } + #my log "--parameter [self] parameter [list $parameters]" + #my parameter $parameters + + # TODO the following will not be needed, when we enforce xotcl 1.5.0+ + set parameters [list] + foreach att [$o children] { + $att instvar attribute_name datatype pretty_name sqltype default help_text spec validator + set slot_obj [self]::slot::$attribute_name + #my log "--cr ::xo::Attribute create $slot_obj" + ::xo::Attribute create $slot_obj + if {![info exists default]} { + set default "" + } + if {[info exists help_text]} {$slot_obj help_text $help_text} + if {[info exists validator]} {$slot_obj validator $validator} + if {[info exists spec]} {$slot_obj spec $spec} + $slot_obj datatype $datatype + $slot_obj pretty_name $pretty_name + $slot_obj default $default + $slot_obj sqltype $sqltype + lappend parameters [list $attribute_name $default] + unset default + } + if {$::xotcl::version < 1.5} { + my parameter [concat [my info parameter] $parameters] + } + } + } + CrClass ad_instproc create_object_type {} { Create an oacs object_type and a table for keeping the additional attributes. @@ -130,29 +282,22 @@ } db_transaction { - db_1row create_type { - select content_type__create_type( - :object_type,:supertype,:pretty_name, :pretty_plural, - :table_name, :id_column, :name_method - ) - } - if {[my cr_attributes] ne ""} { - set o [::xo::OrderedComposite new -contains [my cr_attributes]] - $o destroy_on_cleanup - foreach att [$o children] { - $att instvar attribute_name datatype pretty_name sqltype - db_1row create_att { - select content_type__create_attribute( - :object_type,:attribute_name,:datatype, - :pretty_name,null,null,null,:sqltype - ) - } - } - } + ::xo::db::sql::content_type create_type \ + -content_type $object_type \ + -supertype $supertype \ + -pretty_name $pretty_name \ + -pretty_plural $pretty_plural \ + -table_name $table_name \ + -id_column $id_column \ + -name_method $name_method + + my create_attributes my folder_type register } } + + CrClass ad_instproc drop_object_type {} { Delete the object type and remove the table for the attributes. This method should be called when all instances are deleted. It @@ -161,14 +306,16 @@ my instvar object_type table_name db_transaction { my folder_type unregister - db_1row drop_type { - select content_type__drop_type(:object_type,'t','t') - } + ::xo::db::sql::content_type drop_type \ + -content_type $object_type \ + -drop_children_p t \ + -drop_table_p t } } CrClass ad_instproc require_folder { {-parent_id -100} + {-content_types content_revision} -package_id -name } { @@ -201,12 +348,12 @@ error "Could not determine package id or community id" } } - set folder_id [ns_cache eval xotcl_object_type_cache cid-$cid { + set folder_id [ns_cache eval xotcl_object_type_cache root_folder-$cid { set folder_name "$name: $cid" if {[info command content::item::get_id_by_name] eq ""} { set folder_id "" - db_0or1row get_id_by_name "select item_id as folder_id from cr_items \ + db_0or1row [my qn get_id_by_name] "select item_id as folder_id from cr_items \ where name = :folder_name and parent_id = :parent_id" } else { set folder_id [content::item::get_id_by_name \ @@ -218,6 +365,15 @@ -parent_id $parent_id \ -package_id $package_id -context_id $cid] } + # register all specified content types + foreach content_type $content_types { + # if a content_type ends with a *, include subtypes + set with_subtypes [expr {[regexp {^(.*)[*]$} $content_type _ content_type] ? "t" : "f"}] + ::xo::db::sql::content_folder register_content_type \ + -folder_id $folder_id \ + -content_type $content_type \ + -include_subtypes $with_subtypes + } return $folder_id }] @@ -232,32 +388,21 @@ } { } - CrClass instproc getFormClass {-data} { - if {[info exists data]} { - # new style. does not depend on form variables - if {[$data exists item_id] && [$data set item_id] != 0 && [my exists edit_form]} { - return [my edit_form] - } else { - return [my form] - } + CrClass instproc getFormClass {-data:required} { + if {[$data exists item_id] && [$data set item_id] != 0 && [my exists edit_form]} { + return [my edit_form] } else { - set item_id [::xo::cc form_parameter item_id ""] ;# item_id should be be hardcoded - set new_p [::xo::cc form_parameter __new_p ""] - #my log "--F item_id '$item_id', confirmed_p new_p '$new_p' [my set item_id]" - if {$item_id ne "" && $new_p ne "1" && [my exists edit_form]} { - #my log "--F use edit_form [my edit_form]" - return [my edit_form] - } else { - return [my form] - } + return [my form] } } + CrClass instproc init {} { my instvar object_type sql_attribute_names if {[my info superclass] ne "::Generic::CrItem"} { my set superclass [[my info superclass] set object_type] } + my init_type_hierarchy set sql_attribute_names [list] set o [::xo::OrderedComposite new -contains [my cr_attributes]] $o destroy_on_cleanup @@ -273,11 +418,12 @@ if {![my object_type_exists]} { my create_object_type + } else { + db_transaction { + my create_attributes + } } - my set object_type_key [db_list get_tree_sortkey { - select tree_sortkey from acs_object_types - where object_type = :object_type - }] + next } @@ -290,7 +436,7 @@ @return item_id } { - if {[db_0or1row entry_exists_select "\ + if {[db_0or1row [my qn entry_exists_select] "\ select item_id from cr_items where name = :name and parent_id = :parent_id"]} { return $item_id } @@ -309,7 +455,7 @@ @return cr item object } { - my log "-- [self args]" + #my log "-- [self args]" if {![::xotcl::Object isobject $object]} { # if the object does not yet exist, we have to create it my create $object @@ -328,14 +474,19 @@ lappend atts $fq } if {$revision_id} { - $object db_1row fetch_from_view_revision_id "\ + $object db_1row [my qn fetch_from_view_revision_id] "\ select [join $atts ,], i.parent_id \ from [my set table_name]i n, cr_items i,acs_objects o \ where n.revision_id = $revision_id \ and i.item_id = n.item_id \ and o.object_id = $revision_id" } else { - $object db_1row fetch_from_view_item_id "\ +my log "select [join $atts ,], i.parent_id \ + from [my set table_name]i n, cr_items i, acs_objects o \ + where i.item_id = $item_id \ + and n.[my id_column] = coalesce(i.live_revision, i.latest_revision) \ + and o.object_id = i.item_id" + $object db_1row [my qn fetch_from_view_item_id] "\ select [join $atts ,], i.parent_id \ from [my set table_name]i n, cr_items i, acs_objects o \ where i.item_id = $item_id \ @@ -344,7 +495,8 @@ } if {[apm_version_names_compare [ad_acs_version] 5.2] <= -1} { - $object set package_id [db_string get_pid "select package_id from cr_folders where folder_id = [$object set parent_id]"] + $object set package_id [db_string [my qn get_pid] \ + "select package_id from cr_folders where folder_id = [$object set parent_id]"] } #my log "--AFTER FETCH\n[$object serialize]" @@ -365,8 +517,12 @@ @param item_id id of the item to be retrieved. @param revision_id revision-id of the item to be retrieved. } { - my fetch_object -object ::[expr {$revision_id ? $revision_id : $item_id}] \ - -item_id $item_id -revision_id $revision_id + set object ::[expr {$revision_id ? $revision_id : $item_id}] + if {![my isobject $object]} { + my fetch_object -object $object \ + -item_id $item_id -revision_id $revision_id + } + return $object } CrClass ad_instproc delete { @@ -375,14 +531,19 @@ Delete a content item from the content repository. @param item_id id of the item to be deleted } { - db_exec_plsql content_item_delete { - select content_item__delete(:item_id) - } + ::xo::db::sql::content_item del -item_id $item_id } + CrClass instproc object_types { + {-subtypes_first:boolean false} + } { + return [db_list [my qn get_object_types] \ + [my object_types_query -subtypes_first $subtypes_first]] + } + CrClass ad_instproc instance_select_query { {-select_attributes ""} - {-order_clause ""} + {-orderby ""} {-where_clause ""} {-from_clause ""} {-with_subtypes:boolean true} @@ -395,56 +556,60 @@ returns the SQL-query to select the CrItems of the specified object_type @select_attributes attributes for the sql query to be retrieved, in addion to ci.item_id acs_objects.object_type, which are always returned - @param order_clause clause for ordering the solution set + @param orderby for ordering the solution set @param where_clause clause for restricting the answer set @param with_subtypes return subtypes as well @param count return the query for counting the solutions @param folder_id parent_id @param publish_status one of 'live', 'ready' or 'production' @return sql query } { - my instvar object_type_key if {![info exists folder_id]} {my instvar folder_id} set attributes [list ci.item_id ci.name ci.publish_status acs_objects.object_type] foreach a $select_attributes { if {$a eq "title"} {set a cr.title} lappend attributes $a } - set type_selection [expr {$with_subtypes ? - "acs_object_types.tree_sortkey between \ - '$object_type_key' and tree_right('$object_type_key')" : - "acs_object_types.tree_sortkey = '$object_type_key'"}] + set type_selection [my type_selection -with_subtypes $with_subtypes] + #my log "type_selection -with_subtypes $with_subtypes returns $type_selection" if {$count} { set attribute_selection "count(*)" - set order_clause "" ;# no need to order when we count + set orderby "" ;# no need to order when we count set page_number "" ;# no pagination when count is used } else { set attribute_selection [join $attributes ,] } + + set cond [list] + if {$type_selection ne ""} {lappend cond $type_selection} + if {$where_clause ne ""} {lappend cond $where_clause} + if {[info exists publish_status]} {lappend cond "ci.publish_status eq '$publish_status'"} + lappend cond "coalesce(ci.live_revision,ci.latest_revision) = cr.revision_id + and ci.parent_id = $folder_id and acs_objects.object_id = cr.revision_id" - if {$where_clause ne ""} { - set where_clause "and $where_clause" - } if {$page_number ne ""} { - set pagination "offset [expr {$page_size*($page_number-1)}] limit $page_size" + set limit $page_size + set offset [expr {$page_size*($page_number-1)}] } else { - set pagination "" + set limit "" + set offset "" } - set publish_clause \ - [expr {[info exists publish_status] ? " and ci.publish_status eq '$publish_status'" : ""}] - return "select $attribute_selection - from acs_object_types, acs_objects, cr_items ci, cr_revisions cr $from_clause - where $type_selection - and acs_object_types.object_type = ci.content_type - and coalesce(ci.live_revision,ci.latest_revision) = cr.revision_id - and parent_id = $folder_id and acs_objects.object_id = cr.revision_id \ - $where_clause $order_clause $publish_clause $pagination" + + set sql [::xo::db::sql select \ + -vars $attribute_selection \ + -from "acs_objects, cr_items ci, cr_revisions cr $from_clause" \ + -where [join $cond " and "] \ + -orderby $orderby \ + -limit $limit -offset $offset] + my log "--sql=$sql" + return $sql } CrClass ad_instproc instantiate_all { {-select_attributes ""} - {-order_clause ""} + {-orderby ""} + {-from_clause ""} {-where_clause ""} {-with_subtypes:boolean true} {-folder_id} @@ -469,8 +634,9 @@ -folder_id $folder_id \ -select_attributes $select_attributes \ -with_subtypes $with_subtypes \ + -from_clause $from_clause \ -where_clause $where_clause \ - -order_clause $order_clause \ + -orderby $orderby \ -page_size $page_size -page_number $page_number] { set __o [$object_type create ${__result}::$item_id] $__result add $__o @@ -485,7 +651,10 @@ {-sql ""} {-full_statement_name ""} } { - Return a set of instances of folder objects. + Return a set of instances of objects. It creates plain objects + of type ::xotcl::Object just containing the variables that + the sql query returns. + The container and contained objects are automatically destroyed on cleanup of the connection thread } { @@ -497,7 +666,7 @@ while {1} { set continue [ns_db getrow $db $selection] if {!$continue} break - set o [Object new] + set o [::xotcl::Object new] foreach {att val} [ns_set array $selection] {$o set $att $val} if {[$o exists object_type]} { @@ -513,7 +682,10 @@ return $__result } - Class create Attribute -parameter {attribute_name datatype pretty_name {sqltype "text"}} + Class create Attribute -parameter { + attribute_name datatype pretty_name {sqltype "text"} references + default help_text spec validator + } Class create CrItem -parameter { package_id @@ -522,27 +694,39 @@ {nls_language en_US} {publish_status ready} } + CrItem instproc initialize_loaded_object {} { # dummy action, to be refined } - CrItem ad_proc instantiate { + CrItem ad_proc get_object_type { -item_id {-revision_id 0} } { - Instantiate the live revision or the specified revision of an - CrItem. - @return object containing the attributes of the CrItem - } { + Return the object type for an item_id or revision_id. + + @retun object_type typically an XOTcl class + } { set object_type [ns_cache eval xotcl_object_type_cache \ [expr {$item_id ? $item_id : $revision_id}] { if {$item_id} { - db_1row get_class "select content_type as object_type from cr_items where item_id=$item_id" + db_1row [my qn get_class] "select content_type as object_type from cr_items where item_id=$item_id" } else { - db_1row get_class "select object_type from acs_objects where object_id=$revision_id" + db_1row [my qn get_class] "select object_type from acs_objects where object_id=$revision_id" } return $object_type }] + } + + CrItem ad_proc instantiate { + -item_id + {-revision_id 0} + } { + Instantiate the live revision or the specified revision of an + CrItem. + @return object containing the attributes of the CrItem + } { + set object_type [my get_object_type -item_id $item_id -revision_id $revision_id] #if {![string match "::*" $object_type]} {set object_type ::$object_type} return [$object_type instantiate -item_id $item_id -revision_id $revision_id] } @@ -553,8 +737,7 @@ } { Delete a CrItem in the database } { - db_1row get_class_and_folder \ - "select content_type as object_type from cr_items where item_id = $item_id" + set object_type [my get_object_type -item_id $item_id] $object_type delete -item_id $item_id } @@ -565,7 +748,7 @@ Lookup CR item from title and folder (parent_id) @return item_id or 0 if not successful } { - if {[db_0or1row entry_exists_select "\ + if {[db_0or1row [my qn entry_exists_select] "\ select item_id from cr_items where name = :name and parent_id = :parent_id" ]} { #my log "-- found $item_id for $name in folder '$parent_id'" return $item_id @@ -574,17 +757,22 @@ return 0 } - # provide the appropriate db_* call for the view update. Earlier - # versions up to 5.3.0d1 used db_dml, newer versions (around july - # 2006) have to use db_0or1row, when the patch for deadlocks and - # duplicate items is applied... + if {[db_driverkey ""] eq "postgresql"} { - apm_version_get -package_key acs-content-repository -array info - array get info - CrItem set insert_view_operation \ - [expr {[apm_version_names_compare $info(version_name) 5.3.0d1] < 1 ? "db_dml" : "db_0or1row"}] - array unset info - + # provide the appropriate db_* call for the view update. Earlier + # versions up to 5.3.0d1 used db_dml, newer versions (around july + # 2006) have to use db_0or1row, when the patch for deadlocks and + # duplicate items is applied... + + apm_version_get -package_key acs-content-repository -array info + array get info + CrItem set insert_view_operation \ + [expr {[apm_version_names_compare $info(version_name) 5.3.0d1] < 1 ? "db_dml" : "db_0or1row"}] + array unset info + } else { ;# Oracle + CrItem set insert_view_operation db_dml + } + # uncomment the following line, if you want to force db_0or1row for # update operations (e.g. when using the provided patch for the # content repository in a 5.2 installation) @@ -593,11 +781,20 @@ CrItem instproc update_content_length {storage_type revision_id} { if {$storage_type eq "file"} { - db_dml update_content_length "update cr_revisions \ + db_dml [my qn update_content_length] "update cr_revisions \ set content_length = [file size [my set import_file]] \ where revision_id = $revision_id" } } + CrItem instproc update_content {revision_id content} { + [my info class] instvar storage_type + if {$storage_type eq "file"} { + my log "--update_content not implemented for type file" + } else { + db_dml [my qn update_content] "update cr_revisions \ + set content = :content where revision_id = $revision_id" + } + } CrItem instproc current_user_id {} { if {[my isobject ::xo::cc]} {return [::xo::cc user_id]} @@ -632,14 +829,14 @@ my instvar import_file set text [cr_create_content_file $item_id $revision_id $import_file] } - $insert_view_operation revision_add \ + $insert_view_operation [my qn revision_add] \ "insert into [[my info class] set table_name]i ([join $__atts ,]) \ values (:[join $__atts ,:])" my update_content_length $storage_type $revision_id if {$live_p} { - set publish_status [my set publish_status] - db_0or1row make_live \ - {select content_item__set_live_revision(:revision_id, :publish_status)} + ::xo::db::sql::content_item set_live_revision \ + -revision_id $revision_id \ + -publish_status [my set publish_status] } else { # if we do not make the revision live, use the old revision_id, # and let CrCache save it @@ -650,29 +847,38 @@ } if {[apm_version_names_compare [ad_acs_version] 5.2] > -1} { - ns_log notice "--Version 5.2 or newer [ad_acs_version]" - CrItem set content_item__new { - select content_item__new(:name,$parent_id,null,null,null,\ - :creation_user,null,null,\ - 'content_item',:object_type,null,:description,:mime_type,\ - :nls_language,null,null,null,'f',:storage_type, :package_id) + ns_log notice "--OpenACS Version 5.2 or newer [ad_acs_version]" +# CrItem set content_item__new_args { +# name parent_id creation_user {item_subtype "content_item"} {content_type $object_type} +# description mime_type nls_language {is_live f} storage_type package_id +# } + CrItem set content_item__new_args { + -name $name -parent_id $parent_id -creation_user $creation_user \ + -item_subtype "content_item" -content_type $object_type \ + -description $description -mime_type $mime_type -nls_language $nls_language \ + -is_live f -storage_type $storage_type -package_id $package_id } } else { - ns_log notice "--Version 5.1 or older [ad_acs_version]" - CrItem set content_item__new { - select content_item__new(:name,$parent_id,null,null,null,\ - :creation_user,null,null,\ - 'content_item',:object_type,null,\ - :description,:mime_type,\ - :nls_language,null,:storage_type) + ns_log notice "--OpenACS Version 5.1 or older [ad_acs_version]" +# CrItem set content_item__new_args { +# name parent_id creation_user {item_subtype "content_item"} {content_type $object_type} +# description mime_type nls_language {is_live f} storage_type +# } + CrItem set content_item__new_args { + -name $name -parent_id $parent_id -creation_user $creation_user \ + -item_subtype "content_item" -content_type $object_type \ + -description $description -mime_type $mime_type -nls_language $nls_language \ + -is_live f -storage_type $storage_type } } CrItem ad_instproc set_live_revision {-revision_id:required {-publish_status "ready"}} { @param revision_id @param publish_status one of 'live', 'ready' or 'production' } { - db_0or1row set_live_revision {select content_item__set_live_revision(:revision_id,:publish_status)} + ::xo::db::sql::content_item set_live_revision \ + -revision_id $revision_id \ + -publish_status $publish_status } CrItem ad_instproc save_new {-package_id -creation_user_id {-live_p:boolean true}} { @@ -707,29 +913,39 @@ db_transaction { $__class instvar storage_type object_type - $__class folder_type -folder_id $parent_id register - db_dml lock_objects "LOCK TABLE acs_objects IN SHARE ROW EXCLUSIVE MODE" - - set item_id [db_string insert_item \ - [subst [[self class] set content_item__new]]] + #$__class folder_type -folder_id $parent_id register + [self class] lock acs_objects "SHARE ROW EXCLUSIVE" set revision_id [db_nextval acs_object_id_seq] + + if {$name eq ""} { + # we have an autonamed item, use a unique value for the name + set name [expr {[my exists __autoname_prefix] ? + "[my set __autoname_prefix]$revision_id" : $revision_id}] + if {$title eq ""} { + set title [expr {[my exists __title_prefix] ? + "[my set __title_prefix] ($name)" : $name}] + } + } + set item_id [eval ::xo::db::sql::content_item new [[self class] set content_item__new_args]] if {$storage_type eq "file"} { set text [cr_create_content_file $item_id $revision_id $import_file] } #my log "--V atts=([join $__atts ,])\nvalues=(:[join $__atts ,:])" - $insert_view_operation revision_add \ + $insert_view_operation [my qn revision_add] \ "insert into [$__class set table_name]i ([join $__atts ,]) \ values (:[join $__atts ,:])" my update_content_length $storage_type $revision_id if {$live_p} { - set publish_status [my set publish_status] - db_0or1row make_live \ - "select content_item__set_live_revision(:revision_id,:publish_status)" + ::xo::db::sql::content_item set_live_revision \ + -revision_id $revision_id \ + -publish_status [my set publish_status] } } my set revision_id $revision_id - my db_1row get_dates {select creation_date, last_modified \ - from acs_objects where object_id = :revision_id} + my db_1row [my qn get_dates] { + select creation_date, last_modified + from acs_objects where object_id = :revision_id + } return $item_id } @@ -738,89 +954,90 @@ instance variable. } { # delegate deletion to the class - [my info class] delete [my set item_id] + [my info class] delete -item_id [my set item_id] } ::Generic::CrItem instproc revisions {} { TableWidget t1 -volatile \ -columns { Field version_number -label "" -html {align right} - ImageField edit -label "" -src /resources/acs-subsite/Zoom16.gif \ + ImageAnchorField edit -label "" -src /resources/acs-subsite/Zoom16.gif \ -title "View Item" -alt "view" \ -width 16 -height 16 -border 0 AnchorField diff -label "" AnchorField author -label [_ file-storage.Author] Field content_size -label [_ file-storage.Size] -html {align right} Field last_modified_ansi -label [_ file-storage.Last_Modified] Field description -label [_ file-storage.Version_Notes] - ImageField live_revision -label [_ xotcl-core.live_revision] \ + ImageAnchorField live_revision -label [_ xotcl-core.live_revision] \ -src /resources/acs-subsite/radio.gif \ -width 16 -height 16 -border 0 -html {align center} ImageField_DeleteIcon version_delete -label "" -html {align center} } set user_id [my current_user_id] set page_id [my set item_id] - set live_revision_id [content::item::get_live_revision -item_id $page_id] + set live_revision_id [::xo::db::sql::content_item get_live_revision -item_id $page_id] my instvar package_id set base [$package_id url] - - db_foreach revisions_select \ - "select ci.name, n.revision_id as version_id, - person__name(n.creation_user) as author, - n.creation_user as author_id, - to_char(n.last_modified,'YYYY-MM-DD HH24:MI:SS') as last_modified_ansi, - n.description, - acs_permission__permission_p(n.revision_id,:user_id,'admin') as admin_p, - acs_permission__permission_p(n.revision_id,:user_id,'delete') as delete_p, - r.content_length, - content_revision__get_number(n.revision_id) as version_number - from cr_revisionsi n, cr_items ci, cr_revisions r - where ci.item_id = n.item_id and ci.item_id = :page_id + set sql [::xo::db::sql select \ + -map_function_names true \ + -vars "ci.name, n.revision_id as version_id,\ + person__name(n.creation_user) as author, \ + n.creation_user as author_id, \ + to_char(n.last_modified,'YYYY-MM-DD HH24:MI:SS') as last_modified_ansi,\ + n.description,\ + acs_permission__permission_p(n.revision_id,:user_id,'admin') as admin_p,\ + acs_permission__permission_p(n.revision_id,:user_id,'delete') as delete_p,\ + r.content_length,\ + content_revision__get_number(n.revision_id) as version_number " \ + -from "cr_revisionsi n, cr_items ci, cr_revisions r" \ + -where "ci.item_id = n.item_id and ci.item_id = :page_id and r.revision_id = n.revision_id and exists (select 1 from acs_object_party_privilege_map m where m.object_id = n.revision_id and m.party_id = :user_id - and m.privilege = 'read') - order by n.revision_id desc" { - - if {$content_length < 1024} { - if {$content_length eq ""} {set content_length 0} - set content_size_pretty "[lc_numeric $content_length] [_ file-storage.bytes]" - } else { - set content_size_pretty "[lc_numeric [format %.2f [expr {$content_length/1024.0}]]] [_ file-storage.kb]" - } - - set last_modified_ansi [lc_time_system_to_conn $last_modified_ansi] - - if {$version_id != $live_revision_id} { - set live_revision "Make this Revision Current" - set live_revision_icon /resources/acs-subsite/radio.gif - } else { - set live_revision "Current Live Revision" - set live_revision_icon /resources/acs-subsite/radiochecked.gif - } - - set live_revision_link [export_vars -base $base \ - {{m make-live-revision} {revision_id $version_id}}] - t1 add \ - -version_number $version_number: \ - -edit.href [export_vars -base $base {{revision_id $version_id}}] \ - -author $author \ - -content_size $content_size_pretty \ - -last_modified_ansi [lc_time_fmt $last_modified_ansi "%x %X"] \ - -description $description \ - -live_revision.src $live_revision_icon \ - -live_revision.title $live_revision \ - -live_revision.href $live_revision_link \ - -version_delete.href [export_vars -base $base \ - {{m delete-revision} {revision_id $version_id}}] \ - -version_delete.title [_ file-storage.Delete_Version] - - [t1 last_child] set payload(revision_id) $version_id - } - + and m.privilege = 'read')" \ + -orderby "n.revision_id desc"] + + db_foreach [my qn revisions_select] $sql { + if {$content_length < 1024} { + if {$content_length eq ""} {set content_length 0} + set content_size_pretty "[lc_numeric $content_length] [_ file-storage.bytes]" + } else { + set content_size_pretty "[lc_numeric [format %.2f [expr {$content_length/1024.0}]]] [_ file-storage.kb]" + } + + set last_modified_ansi [lc_time_system_to_conn $last_modified_ansi] + + if {$version_id != $live_revision_id} { + set live_revision "Make this Revision Current" + set live_revision_icon /resources/acs-subsite/radio.gif + } else { + set live_revision "Current Live Revision" + set live_revision_icon /resources/acs-subsite/radiochecked.gif + } + + set live_revision_link [export_vars -base $base \ + {{m make-live-revision} {revision_id $version_id}}] + t1 add \ + -version_number $version_number: \ + -edit.href [export_vars -base $base {{revision_id $version_id}}] \ + -author $author \ + -content_size $content_size_pretty \ + -last_modified_ansi [lc_time_fmt $last_modified_ansi "%x %X"] \ + -description $description \ + -live_revision.src $live_revision_icon \ + -live_revision.title $live_revision \ + -live_revision.href $live_revision_link \ + -version_delete.href [export_vars -base $base \ + {{m delete-revision} {revision_id $version_id}}] \ + -version_delete.title [_ file-storage.Delete_Version] + + [t1 last_child] set payload(revision_id) $version_id + } + # providing diff links to the prevision versions. This can't be done in # the first loop, since we have not yet the revision id of entry in the next line. set lines [t1 children] @@ -841,7 +1058,39 @@ return [t1 asHTML] } + # + # Object specific privilege to be used with policies + # + + CrItem ad_instproc privilege=creator { + {-login true} user_id package_id method + } { + + Define an object specific privilege to be used in the policies. + Grant access to a content item for the creator (creation_user) + of the item, and for the package admin. + + } { + set allowed 0 + #my log "--checking privilege [self args]" + if {[my exists creation_user]} { + if {$user_id == 0 && $login} { + auth::require_login + } elseif {[my set creation_user] == $user_id} { + set allowed 1 + } else { + # allow the package admin always access + set allowed [::xo::cc permission \ + -object_id $package_id \ + -party_id $user_id \ + -privilege admin] + } + } + return $allowed + } + + # # Form template class # @@ -870,6 +1119,7 @@ CrCache instproc delete {-item_id} { next ns_cache flush xotcl_object_cache ::$item_id + # we should probably flush as well cached revisions } Class CrCache::Item @@ -969,7 +1219,7 @@ } Form instproc new_data {} { my instvar data - my log "--- new_data ---" + #my log "--- new_data ---" foreach __var [my form_vars] { $data set $__var [my var $__var] } @@ -978,7 +1228,7 @@ return [$data set item_id] } Form instproc edit_data {} { - my log "--- edit_data ---" + #my log "--- edit_data --- setting form vars=[my form_vars]" my instvar data foreach __var [my form_vars] { $data set $__var [my var $__var] @@ -989,7 +1239,7 @@ set old_name [::xo::cc form_parameter __object_name ""] set new_name [$data set name] if {$old_name ne $new_name} { - db_dml update_rename "update cr_items set name = :new_name \ + db_dml [my qn update_rename] "update cr_items set name = :new_name \ where item_id = [$data set item_id]" } } @@ -1014,9 +1264,10 @@ } Form instproc new_request {} { - my log "--- new_request ---" + #my log "--- new_request ---" my request create my instvar data + #my log "--VAR [my var item_id]" foreach var [[$data info class] edit_atts] { if {[$data exists $var]} { my var $var [list [$data set $var]] @@ -1025,7 +1276,7 @@ } Form instproc edit_request {item_id} { my instvar data - my log "--- edit_request ---" + #my log "--- edit_request ---" my request write foreach var [[$data info class] edit_atts] { if {[$data exists $var]} { @@ -1035,12 +1286,15 @@ } Form instproc on_submit {item_id} { - # dummy proc + # The content of this proc is strictly speaking not necessary. + # However, on redirects after a submit to the same page, it + # ensures the setting of edit_form_page_title and context + my request write } Form instproc on_validation_error {} { my instvar edit_form_page_title context - my log "-- " + #my log "-- " set edit_form_page_title [my edit_page_title] set context [list $edit_form_page_title] } @@ -1097,14 +1351,14 @@ append new_data { category::map_object -remove_old -object_id $item_id $category_ids #ns_log notice "-- new data category::map_object -remove_old -object_id $item_id $category_ids" - db_dml insert_asc_named_object \ - "insert into acs_named_objects (object_id,object_name,package_id) \ - values (:item_id, :name, :package_id)" + #db_dml [my qn insert_asc_named_object] \ + # "insert into acs_named_objects (object_id,object_name,package_id) \ + # values (:item_id, :name, :package_id)" } append edit_data { - db_dml update_asc_named_object \ - "update acs_named_objects set object_name = :name, \ - package_id = :package_id where object_id = :item_id" + #db_dml [my qn update_asc_named_object] \ + # "update acs_named_objects set object_name = :name, \ + # package_id = :package_id where object_id = :item_id" #ns_log notice "-- edit data category::map_object -remove_old -object_id $item_id $category_ids" category::map_object -remove_old -object_id $item_id $category_ids } @@ -1230,7 +1484,7 @@ List ad_instproc generate { - -order_by + {-orderby ""} -template } { the method generate is used to actually generate the list template @@ -1241,7 +1495,6 @@ } { my instvar object_type with_subtypes - set order_clause [expr {[info exists order_by] ? "order by $order_by":""}] if {![info exists template]} { set template [my name] } @@ -1268,7 +1521,7 @@ -folder_id [my folder_id] \ -select_attributes $select_attributes \ -with_subtypes $with_subtypes \ - -order_clause $order_clause] { + -orderby $orderby] { set view_url [export_vars -base [my view_link] {item_id}] set edit_url [export_vars -base [my edit_link] {item_id}] set delete_url [export_vars -base [my delete_link] {item_id}] Index: openacs-4/packages/xotcl-core/tcl/http-client-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/http-client-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xotcl-core/tcl/http-client-procs.tcl 1 Aug 2007 21:39:32 -0000 1.2.2.2 @@ -0,0 +1,256 @@ +namespace eval ::xo { + # + # + # + Class create HttpRequest \ + -parameter { + {host} + {port 80} + {path /} + {url} + {post_data ""} + {content_type text/plain} + {request_manager} + {request_header_fields {}} + {user_agent xohttp/0.1} + } + + HttpRequest instproc parse_url {} { + my instvar url host port path + if {[regexp {http://([^/]*)(/.*)} $url _ host path]} { + set port 80 + regexp {^([^:]+):(.*)$} $host _ host port + } else { + error "unsupported or invalid url '$url'" + } + } + + HttpRequest instproc init {} { + my instvar S post_data host port + my set meta [list] + my set data "" + if {[my exists url]} {my parse_url} + + if {[catch {set S [socket $host $port]} err]} { + my cancel "error socket $host $port: $err" + return + } + if {[catch { + set method [expr {$post_data eq "" ? "GET" : "POST"}] + puts $S "$method [my path] HTTP/1.0" + puts $S "Accept: */*" + puts $S "Host: $host" + puts $S "User-Agent: [my user_agent]" + foreach {tag value} [my request_header_fields] { + #regsub -all \[\n\r\] $value {} value + #set tag [string trim $tag] + puts $S "$tag: $value" + } + my $method + } err]} { + my cancel "error send $host $port: $err" + return + } + } + + HttpRequest instproc GET {} { + my instvar S + puts $S "" + my query_done + } + + HttpRequest instproc POST {} { + my instvar S post_data + puts $S "Content-Length: [string length $post_data]" + puts $S "Content-Type: [my content_type]" + puts $S "" + fconfigure $S -translation {auto binary} + if {[regexp {; *charset=([^ ]+)$} [my content_type] _ encoding]} { + fconfigure $S -encoding $encoding + } + #my log "--post data blocking=[fconfigure $S -blocking]" + puts -nonewline $S $post_data + my query_done + } + + HttpRequest instproc query_done {} { + my instvar S + flush $S + my received_first_line + } + HttpRequest instproc notify {method arg} { + if {[my exists request_manager]} { + [my request_manager] $method $arg [self] + } + } + HttpRequest instproc cancel {reason} { + my log "--- $reason" + catch {close [my set S]} + my notify done $reason + } + + HttpRequest instproc finish {} { + catch {close [my set S]} + #my log "--- [my host] [my port] [my path] has finished" + my notify deliver [my set data] + } + HttpRequest instproc getLine {var} { + my upvar $var response + my instvar S + set n [gets $S response] + if {[eof $S]} { + my log "--premature eof" + return -2 + } + if {$n == -1} {my log "--input pending, no full line"; return -1} + #my log "got $response" + return $n + } + HttpRequest instproc received_first_line {} { + my instvar S statusCode + fconfigure $S -translation crlf + set n [my getLine response] + switch -exact -- $n { + -2 {my cancel premature-eof; return} + -1 {return} + } + if {[regexp {^HTTP/([0-9.]+) +([0-9]+) *} $response _ \ + responseHttpVersion statusCode]} { + my received_first_line_done + } else { + my log "--unexpected response '$response'" + my cancel unexpected-response + } + } + HttpRequest instproc received_first_line_done {} { + my header + } + HttpRequest instproc header {} { + while {1} { + set n [my getLine response] + switch -exact -- $n { + -2 {my cancel premature-eof; return} + -1 {continue} + 0 {break} + default { + #my log "--header $response" + if {[regexp -nocase {^content-length:(.+)$} $response _ length]} { + my set content_length [string trim $length] + } + if {[regexp -nocase {^([^:]+): *(.+)$} $response _ key value]} { + my lappend meta [string tolower $key] $value + } + } + } + } + my received_header_done + } + HttpRequest instproc received_header_done {} { + fconfigure [my set S] -translation binary + if {[my exists content_length]} { + my set data [read [my set S] [my set content_length]] + } else { + my set data [read [my set S]] + } + } + + + Class AsyncHttpRequest -superclass HttpRequest -parameter { + {timeout 10000} + } + AsyncHttpRequest instproc init {} { + my set to_identifier [after [my set timeout] [self] cancel timeout] + next + } + AsyncHttpRequest instproc POST {} { + if {[my exists S]} {fconfigure [my set S] -blocking false} + next + } + AsyncHttpRequest instproc cancel {reason} { + if {$reason ne "timeout"} { + after cancel [my set to_identifier] + } + next + } + AsyncHttpRequest instproc finish {} { + after cancel [my set to_identifier] + next + } + AsyncHttpRequest instproc query_done {} { + my instvar S + flush $S + fconfigure $S -blocking false + fileevent $S readable [list [self] received_first_line] + } + AsyncHttpRequest instproc received_first_line_done {} { + fileevent [my set S] readable [list [self] header] + } + AsyncHttpRequest instproc received_header_done {} { + fconfigure [my set S] -translation binary + fileevent [my set S] readable [list [self] received_data] + } + AsyncHttpRequest instproc received_data {} { + my instvar S + if {[eof $S]} { + my finish + } else { + set block [read $S] + my append data $block + #my log "reveived [string length $block] bytes" + } + } + + Class HttpRequestTrace + nsv_set HttpRequestTrace count 0 + + HttpRequestTrace instproc init {} { + + #TODO remove me +# my instvar host path +# if {[my exists endpoint]} { +# # soap specificities +# my url [my set endpoint] +# my post_data [my payload] +# my content_type "text/xml" +# if {[my action] eq ""} { +# my headers [list SOAPAction [my set endpoint]] +# } else { +# my headers [list SOAPAction [my action]] +# } +# } + + my instvar F post_data + my set meta [list] + my set requestCount [nsv_incr HttpRequestTrace count] ;# make it an instvar to find it in the log file + set F [open /tmp/req-[format %.4d [my set requestCount]] w] + + set method [expr {$post_data eq "" ? "GET" : "POST"}] + puts $F "$method [my path] HTTP/1.0" + puts $F "Accept: */*" + puts $F "Host: [my host]" + puts $F "User-Agent: [my user_agent]" + foreach {tag value} [my request_header_fields] { puts $F "$tag: $value" } + next + } + + HttpRequestTrace instproc POST {} { + my instvar F post_data + puts $F "Content-Length: [string length $post_data]" + puts $F "Content-Type: [my content_type]" + puts $F "" + fconfigure $F -translation {auto binary} + puts -nonewline $F $post_data + next + } + + HttpRequestTrace instproc cancel {reason} { + catch {close [my set F]} + next + } + HttpRequestTrace instproc finish {} { + catch {close [my set F]} + next + } + + #HttpRequest instmixin add HttpRequestTrace +} Index: openacs-4/packages/xotcl-core/tcl/policy-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/policy-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xotcl-core/tcl/policy-procs.tcl 1 Aug 2007 21:39:32 -0000 1.10.2.2 @@ -0,0 +1,191 @@ +ad_library { + XOTcl API for policies + + @author Gustaf Neumann + @creation-date 2007-03-09 + @cvs-id $Id: policy-procs.tcl,v 1.10.2.2 2007/08/01 21:39:32 gustafn Exp $ +} + +namespace eval ::xo { + + Class Policy + + Policy instproc defined_methods {class} { + set c [self]::$class + expr {[my isclass $c] ? [$c array names require_permission] : [list]} + } + + Policy instproc check_privilege {{-login true} -user_id -package_id privilege object method} { + set allowed -1 ;# undecided + if {[acs_user::site_wide_admin_p -user_id $user_id]} { + return 1 + } + switch $privilege { + none {return 1} + login { + if {$login} { + auth::require_login; return 1 + } else { + return [expr {$user_id != 0}] + } + } + swa { + set allowed 0 + #if {!$allowed} { + # ad_return_warning "Insufficient Permissions" \ + # "Only side wide admins are allowed for this operation! ($object $method)" + # ad_script_abort + #} + } + default { + # try object specific privileges. These have the signature: + # + # instproc privilege= {{-login true} user_id package_id method} + # + if {[$object info methods privilege=$privilege] ne ""} { + if {![info exists package_id]} {set package_id [::xo::cc package_id]} + set allowed [$object privilege=$privilege -login $login $user_id $package_id $method] + } + } + } + #my log "--check_privilege {$privilege $object $method} ==> $allowed" + return $allowed + } + + Policy instproc get_privilege {{-query_context "::xo::cc"} permission object method} { + # the privilege might by primitive (one word privilege) + # or it might be complex (attribute + privilege) + # or it might be conditional (primitive or complex) in a list of privilges + + foreach p $permission { + + set condition [lindex $p 0] + if {[llength $condition]>1} { + # we have a condition + foreach {cond value} $condition break + if {[$object condition=$cond $query_context $value]} { + return [my get_privilege [lrange $p 1 end] $object $method] + } + } else { + # we have no condition + return [list [expr {[llength $p] == 1 ? "primitive" : "complex"}] $p] + } + } + } + + Policy instproc get_permission {{-check_classes true} object method} { + set permission "" + set o [self]::[namespace tail $object] + set key require_permission($method) + if {[my isobject $o] && [$o exists $key]} { + set permission [$o set $key] + } elseif {[my isobject $o] && [$o exists default_permission]} { + set permission [$o set default_permission] + } elseif {$check_classes} { + # we have no object specific policy information, check the classes + set c [$object info class] + foreach class [concat $c [$c info heritage]] { + set c [self]::[namespace tail $class] + if {![my isclass $c]} continue + set permission [my get_permission -check_classes false $class $method] + if {$permission ne ""} break + } + } + return $permission + } + + Policy ad_instproc check_permissions {-user_id -package_id {-link ""} object method} { + + This method checks whether the current user is allowed + or not to invoke a method based on the given policy. + This method is purely checking and does not force logins + or other side effects. It can be safely used for example + to check whether links should be shown or not. + + @see enforce_permissions + @return 0 or 1 + + } { + if {![info exists user_id]} {set user_id [::xo::cc user_id]} + if {![info exists package_id]} {set package_id [::xo::cc package_id]} + + set ctx "" + if {$link ne ""} { + set query [lindex [split $link ?] 1] + set ctx [::xo::Context new -destroy_on_cleanup -actual_query $query] + $ctx process_query_parameter + } + + set permission [my get_permission $object $method] + #my log "--permission for o=$object, m=$method => $permission" + if {$permission ne ""} { + foreach {kind p} [my get_privilege -query_context $ctx $permission $object $method] break + #my log "--privilege = $p kind = $kind" + switch $kind { + primitive {return [my check_privilege -login false \ + -package_id $package_id -user_id $user_id \ + $p $object $method]} + complex { + foreach {attribute privilege} $p break + set id [$object set $attribute] + #my log "--p checking permission::permission_p -object_id $id -privilege $privilege" + return [::xo::cc permission -object_id $id -privilege $privilege -party_id $user_id] + } + } + } + return 0 + } + + Policy ad_instproc enforce_permissions {-user_id -package_id object method} { + + This method checks whether the current user is allowed + or not to invoke a method based on the given policy and + forces logins if required. + + @see check_permissions + @return 0 or 1 + + } { + if {![info exists user_id]} {set user_id [::xo::cc user_id]} + if {![info exists package_id]} {set package_id [::xo::cc package_id]} + + #my log "--p enforce_permissions {$object $method}" + set allowed 0 + set permission [my get_permission $object $method] + if {$permission ne ""} { + foreach {kind p} [my get_privilege $permission $object $method] break + switch $kind { + primitive { + set allowed [my check_privilege \ + -user_id $user_id -package_id $package_id \ + $p $object $method] + set privilege $p + } + complex { + foreach {attribute privilege} $p break + set id [$object set $attribute] + set allowed [::xo::cc permission -object_id $id \ + -privilege $privilege \ + -party_id $user_id] + } + } + } + + #my log "--p enforce_permissions {$object $method} : $permission ==> $allowed" + + if {!$allowed} { + if {$permission eq ""} { + ns_log notice "permission::require_permission: no permission for " \ + "$object->$method defined" + } else { + ns_log notice "permission::require_permission: $user_id doesn't \ + have $privilege on $object" + } + ad_return_forbidden "Permission Denied" [_ xotcl-core.policy-error-insufficient_permissions] + ad_script_abort + } + + return $allowed + } + +} \ No newline at end of file Index: openacs-4/packages/xotcl-core/tcl/test/xotcl-avail-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/test/xotcl-avail-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xotcl-core/tcl/test/xotcl-avail-procs.tcl 1 Aug 2007 21:39:32 -0000 1.1.2.2 @@ -0,0 +1,27 @@ +ad_library { + Test the availability of xotcl +} + + +aa_register_case -cats {api smoke} check_xotcl { + Basic test of the availability of xotcl +} { + proc ? {cmd expected {msg ""}} { + set r [uplevel $cmd] + if {$msg eq ""} {set msg $cmd} + aa_true $msg [expr {$r eq $expected}] + #if {$r ne $expected} { + # test errmsg "$msg returned '$r' ne '$expected'" + #} else { + # test okmsg "$msg - passed ([t1 diff] ms)" + #} + } + ? {expr {$::xotcl::version < 1.4}} 0 "XOTcl Version $::xotcl::version >= 1.4" + set ns_cache_version_old [catch {ns_cache names xowiki_cache xxx}] + if {$ns_cache_version_old} { + ? {set x old} new "upgrade ns_cache: cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nscache" + } else { + ? {set x new} new "ns_cache version seems up to date" + } + +} \ No newline at end of file Index: openacs-4/packages/xotcl-core/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/www/index.tcl,v diff -u -N -r1.3.2.1 -r1.3.2.2 --- openacs-4/packages/xotcl-core/www/index.tcl 15 Jan 2007 08:49:59 -0000 1.3.2.1 +++ openacs-4/packages/xotcl-core/www/index.tcl 1 Aug 2007 21:39:32 -0000 1.3.2.2 @@ -64,7 +64,7 @@ append output "
  • [::xotcl::api object_link {} $cl]
      " - foreach kind {class superclass mixin instmixin} { + foreach kind {class superclass subclass mixin instmixin} { append output [info_classes $cl $kind] } Index: openacs-4/packages/xowiki/COPYRIGHT =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/COPYRIGHT,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/COPYRIGHT 1 Aug 2007 21:39:23 -0000 1.1.2.2 @@ -0,0 +1,23 @@ + * xowiki + * + * Copyright (C) 2005 Gustaf Neumann, neumann@wu-wien.ac.at + * + * Vienna University of Economics and Business Administration + * Institute of Information Systems and New Media + * A-1090, Augasse 2-6 + * Vienna, Austria + * + * This is a BSD-Style license applicable for the files in this + * directory and below, except when stated explicitly different. + * + * Permission to use, copy, modify, distribute, and sell this + * software and its documentation for any purpose is hereby granted + * without fee, provided that the above copyright notice appear in + * all copies and that both that copyright notice and this permission + * notice appear in supporting documentation. We make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + + Index: openacs-4/packages/xowiki/xowiki.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/xowiki.info,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/xowiki.info 1 Aug 2007 21:39:23 -0000 1.60.2.2 @@ -0,0 +1,94 @@ + + + + + xowiki + xowikis + f + f + xowiki + + + Gustaf Neumann + A more generic xotcl-based wikis example with object types +and subtypes based on the content repository (with category support) + 2007-08-01 + <pre> +XoWiki is a Wiki implementation for OpenACS in XOTcl. Instead of +trying to implement the full set of Wiki markup commands of systems +like MediaWiki, XoWiki is based on a rich text editor and focuses more +on integration with OpenACS (e.g categories, general comments, +ADP-includes). XoWiki combines aspects of wicks (ease of +page-creation) with aspects of a content management system (revisions, +re-usable items, multiple languages). Furthermore, XoWiki allows to +define different types of links such one could define book-structures +(where a navigation structure could be built on the fly) or glossaries +with different kind of word relationships (like synonyms, +etc.). XoWiki supports pages in multiple languages and is localized. + +Some features: + - cross language links + - inclusion of ADP pages + - nesting of Wiki-pages + - large set of includeable content (includelets) + - search + - tags + - categories + - RSS + - weblog + - podcasts + - notifications + - web 2.0 gadgets (digg, delicious, my yahoo) + - audio embedding + - different appearances (template_file) + - book-structures + - prototype pages + - import/export + - virtual presence + - analysis of collaboration networks + - forms + - named/unnamed pages + - various security policies +</pre> + BSD-Style + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/xowiki/catalog/xowiki.de_DE.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/catalog/xowiki.de_DE.ISO-8859-1.xml,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/catalog/xowiki.de_DE.ISO-8859-1.xml 1 Aug 2007 21:39:24 -0000 1.21.2.2 @@ -0,0 +1,47 @@ + + + + Verwalten + Zur�ck + Neuen Eintrag vom Typ %type% erstellen + Erzeuge diese Seite in der folgenden Sprache: + L�schen + Bearbeiten + bearbeiten + Eintr�ge f�r as Formular %form%: + Dieses Formular wird noch von %count% Eintr�gen verwendet. Bitte verwenden Sie diese, bevor Sie das Formular l�schen. + Formular + Einschr�nkungen + Eintr�ge f�r dieses Formular + Formular ausf�llen + Index + Verst�ndigungen + Creator + Kurzbeschreibung + Name + Eindeutige Kurzbezeichnung f�r einen Eintrag im Ordner; enth�lt meist nur Kleinbuchstaben + Sprache + Abschnitt + Inhalt + Titel der Seite + Another item with the name '%value%' exists already in this folder + Typ der Seite + Instanzattribute + Seitenvorlage + Unbenamte Instanzen + Dauer + Schl�sselworte + Publikationsdatum + Untertitel + H�ufig verwendete Schlagworte + h�ufige Schlagworte + �ndern Sie entweder den Namen des existierenden Portlets oder den Titel der Xowiki-Seite, die Sie zum Portal hinzuf�gen wollen. + Es gibt bereits ein Portlet mit dem Titel '%page_title%' in diesem Portal. + Freigegeben + Verweise auf diese Seite: + Verlauf + Suche + Ansehen + mehr... + Pers�nliche Schlagworte + Index: openacs-4/packages/xowiki/catalog/xowiki.en_US.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/catalog/xowiki.en_US.ISO-8859-1.xml,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/catalog/xowiki.en_US.ISO-8859-1.xml 1 Aug 2007 21:39:24 -0000 1.29.2.2 @@ -0,0 +1,74 @@ + + + + Admin + Back + Create new entry of type %type% + Create this page in a different language + Delete + Edit + edit tags + Entries for form %form% + This form is still used by %count% entries. Please delete these first before deleting this page. + Form constraint contains invalid characters + From field '%name%' has unknown attribute '%entry%' + Unknown editor %editor%. Possible values are: %editors% + From field '%name%' has unknown specification '%entry%' + Syntax: adp &lt;name of adp-file&gt; {&lt;argument list&gt;}<br/> + +Invalid argument list: '%adp%'; must be of form: attribute value pairs (even number of elements) + <pre>%errMsg%</pre> + +Argument list must contain attribute value pairs (attributes with dashes) + evaluation of adp file returned error message: %errorMsg% + Error in includelet '%page_name%': +<pre>%::errorInfo%</pre> + Nesting of includelets is to deep + Error: includelet '%page_name%' unknown + Error in includelet '{{%arg%}}' of page %name%: + Can be obtained from the name of the uploaded file + Form + Form Constraints + Entries for this form + Fill out + OK + Template + %errorMsg% + Index + New Page + Notifications + Invalid numeric value + Creator + Description + Last Modified + Name + Shortname to identify an entry within a folder, typically lowercase characters + Language + Section + Content + Page Title + Another item with the name '%value%' exists already in this folder + Page Type + Instance Attributes + Page Instance + Unnamed Entries + Duration + E.g. 9:16 means 9 minutes 16 seconds (if ffmpeg is installed and configured, it will get the value automatically) + Keywords + comma separated itunes keywords, e.g. salt, pepper, shaker, exciting + Can be obtained from the name of the uploaded file + Publication Date + Subtitle + Popular tags + popular tags + Please either change the existing portlets' name or the title of the xowiki page you want to add to the portal. + A portlet with the title '%page_title%' already exists in this portal. + Published + References to this Page: + Revisions + %errorMsg% + Search + View + more... + Your Tags + Index: openacs-4/packages/xowiki/catalog/xowiki.es_ES.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/catalog/xowiki.es_ES.ISO-8859-1.xml,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/catalog/xowiki.es_ES.ISO-8859-1.xml 1 Aug 2007 21:39:24 -0000 1.7.2.2 @@ -0,0 +1,40 @@ + + + + Administrar + Volver + Crear esta p�gina en un lenguaje diferente + Borrar + Editar + editar tags + Forme + �ndice + Nueva P�gina + Notificaciones + Autor + Descripci�n + Nombre + Idioma + Secci�n + Contenido + T�tulo de la P�gina + Tipo de P�gina + Cualidad + Plantilla de la p�gina + Entradas innomadas + Duraci�n + Palabras claves + Fecha de la publicaci�n + Subt�tulo + Tags populares + tags populares + Por favor, cambie el nombre de los portlets existentes � el t�tulo de la p�gina del xowiki que se quiere a�adir al portal. + Un portlet cuyo t�tulo es '%page_title%' ya existe en este portal. + Publicado + Referencias a esta P�gina: + Revisiones + Buscar + Vista + m�s... + Tus tags + Index: openacs-4/packages/xowiki/lib/view.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/lib/view.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/lib/view.adp 1 Aug 2007 21:39:24 -0000 1.2.2.2 @@ -0,0 +1 @@ +@html;noquote@ Index: openacs-4/packages/xowiki/lib/view.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/lib/view.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/lib/view.tcl 1 Aug 2007 21:39:24 -0000 1.8.2.2 @@ -0,0 +1,29 @@ +set parameter [subst { + {-m view} + {-return_url "[ns_conn url]"} + {-template_file "view-links"} + {-folder_id 0} +}] + +# TODO the following should be done more elegantly +set actual_query [expr {[info exists template_file] ? "template_file=$template_file" : " "}] + +if {[info exists url]} { + # new style, the url is sufficient + ::xowiki::Package initialize -parameter $parameter -url $url -actual_query $actual_query +} else { + # old style, use item_id + set page [::xowiki::Package instantiate_page_from_id \ + -item_id $item_id -parameter $parameter] + ::xo::cc export_vars +} + +set html [::$package_id invoke -method $m] + +if {![info exists css]} { + set fn [get_server_root]/packages/xowiki/www/resources/xowiki.css + set F [open $fn]; set css [read $F]; close $F + set css "" + set html $css$html +} + Index: openacs-4/packages/xowiki/tcl/adp-generator-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/adp-generator-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/adp-generator-procs.tcl 1 Aug 2007 21:39:24 -0000 1.9.2.2 @@ -0,0 +1,270 @@ +ad_library { + XoWiki - adp generator procs: remove redundancy in adp files by generating it + + @creation-date 2007-03-13 + @author Gustaf Neumann + @cvs-id $Id: adp-generator-procs.tcl,v 1.9.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + + +namespace eval ::xowiki { + + Class ADP_Generator -parameter { + {master 1} + {wikicmds 1} + {footer 1} + {recreate 0} + {extra_header_stuff ""} + } + + ADP_Generator instproc before_render {obj} { + # just a hook, might be removed later + } + + ADP_Generator instproc ajax_tag_definition {} { + # if we have no footer, we have no tag form + if {![my footer]} {return ""} + + return {} + } + + + + ADP_Generator instproc master_part {} { + return [subst -novariables -nobackslashes \ +{ + @title;noquote@ + @context;noquote@ + @header_stuff;noquote@[my extra_header_stuff] + + [my ajax_tag_definition] + + @header_stuff;noquote@[my extra_header_stuff] + + [my ajax_tag_definition] + }]\n + } + + ADP_Generator instproc wikicmds_part {} { + if {![my wikicmds]} {return ""} + return {} + } + + ADP_Generator instproc footer_part {} { + if {![my footer]} {return ""} + return "@footer;noquote@" + } + + ADP_Generator instproc content_part {} { + return "@top_portlets;noquote@\n@content;noquote@" + } + + + ADP_Generator instproc generate {} { + my instvar master wikicmds footer + set _ "\n" + + # if we include the master, we include the primitive js function + if {$master} { + append _ [my master_part] + } + + append _ \ +{ + +
      } \n + + append _ [my wikicmds_part] \n + append _ [my content_part] \n + append _ [my footer_part] \n + append _ "
      \n" + } + + ADP_Generator instproc init {} { + set name [namespace tail [self]] + set filename [file dirname [info script]]/../www/$name.adp + # generate the adp file, if it does not exist + if {[catch {set f [open $filename w]} errorMsg]} { + my log "Error: cannot overwrite $filename, ignoring possible changes" + } else { + puts -nonewline $f [my generate] + close $f + } + } + + ADP_Generator create view-plain -master 0 -wikicmds 0 -footer 0 + ADP_Generator create view-links -master 0 -footer 0 + ADP_Generator create view-default -master 1 -footer 1 + + ADP_Generator create oacs-view -master 1 -footer 1 \ + -extra_header_stuff { + + + } \ + -proc content_part {} { + return [subst -novariables -nobackslashes \ +{
      +
      + +
      +
      +[next] +
      +}] + } + + # + # similar to oacs view (categories left), but having as well a right bar + # + ADP_Generator create oacs-view2 -master 1 -footer 1 \ + -extra_header_stuff { + + + + } \ + -proc before_render {page} { + ::xo::cc set_parameter weblog_page weblog-portlet + } \ + -proc content_part {} { + return [subst -novariables -nobackslashes \ +{
      +
      + +
      +
      + +
      +[next] +
      + + +
      +}] + } + + # + # similar to oacs view2 (categories left), but everything left + # + ADP_Generator create oacs-view3 -master 1 -footer 1 \ + -extra_header_stuff { + + + + } \ + -proc before_render {page} { + ::xo::cc set_parameter weblog_page weblog-portlet + } \ + -proc content_part {} { + return [subst -novariables -nobackslashes \ +{
      + + +
      +
      + + + +
      + +
      +Contributors +
      +
      + +
      +
      + + +
      +
      +
      +[next] +
      +}] + } + + +} Index: openacs-4/packages/xowiki/tcl/category-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/category-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/category-procs.tcl 1 Aug 2007 21:39:24 -0000 1.12.2.2 @@ -0,0 +1,125 @@ +namespace eval ::xowiki { + # + # ::xowiki::CatTree (category tree) + # + + Class CatTree -superclass ::xo::OrderedComposite -parameter {{name ""}} + + CatTree instproc add_to_category { + -category + -orderby + -itemobj + {-increasing:boolean true} + {-open_item:boolean false} + } { + set items ${category}::items + if {![my isobject $items]} { + ::xo::OrderedComposite create $items + if {[info exists orderby]} { + if {$orderby eq "page_order"} { + $items mixin add ::xo::OrderedComposite::IndexCompare + } + set direction [expr {$increasing ? "increasing" : "decreasing"}] + $items orderby -order $direction $orderby + } + } + $items add $itemobj + if {$open_item} { + $category open_tree + $itemobj set open_item 1 + } + } + CatTree instproc open_tree {} {;} + + CatTree instproc render {{-tree_style:boolean false}} { + if {$tree_style} { + #::xowiki::Page requireCSS "/resources/acs-templating/mktree.css" + ::xowiki::Page requireCSS "/resources/xowiki/cattree.css" + ::xowiki::Page requireJS "/resources/acs-templating/mktree.js" + + foreach c [my children] {append content [$c render] \n} + return "
        $content
      " + } else { + Category instmixin Category::section_style + foreach c [my children] {append content [$c render] \n} + Category instmixin "" + return $content + } + } + + # + # ::xowiki::Category + # + + Class Category -superclass ::xo::OrderedComposite -parameter { + package_id level label pos category_id {open_requests 0} count {href ""} + } + #Category instproc destroy {} {my log --; next} + Category instproc open_tree {} { + my set open_requests 1 + if {[my exists __parent]} {[my set __parent] open_tree} + } + + Category instproc some_child_has_items {} { + foreach i [my children] { + if {[my isobject ${i}::items]} {return 1} + if {[$i some_child_has_items]} {return 1} + } + return 0 + } + + Category instproc render {} { + set content "" + if {[my isobject [self]::items]} { + foreach i [[self]::items children] { + $i instvar name title prefix suffix + set entry "$prefix$title$suffix" + append cat_content [my render_item -highlight [$i exists open_item] $entry] + } + foreach c [my children] {append cat_content [$c render] \n} + append content [my render_category -open [expr {[my set open_requests]>0}] $cat_content] + } elseif {[my open_requests]>0 || [my some_child_has_items]} { + set cat_content "" + foreach c [my children] {append cat_content [$c render] \n} + append content [my render_category -open true $cat_content] + + } + return $content + } + + # + # These are the list-specific rendering functions + # + + Category instproc render_item {{-highlight:boolean false} item} { + if {$highlight} { + return "
    • $item
    • \n" + } else { + return "
    • $item
    • \n" + } + } + Category instproc render_category {{-open:boolean false} cat_content} { + set open_state [expr {[my set open_requests]>0?"class='liOpen'" : "class='liClosed'"}] + set c [expr {[my exists count] ? "([my count])" : ""}] + return "
    • [my label] $c\n
        $cat_content
      \n" + } + + # + # These are the section-specific rendering functions + # + + Class Category::section_style + Category::section_style instproc render_item {{-highlight:boolean false} item} { + if {$highlight} { + return "$item
      \n" + } else { + return "$item
      \n" + } + } + Category::section_style instproc render_category {{-open:boolean false} cat_content} { + set section [expr {[my level] + 2}] + return "[my label]\n

      \ +

      $cat_content
      \n" + } + +} Index: openacs-4/packages/xowiki/tcl/chat-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/chat-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/chat-procs.tcl 1 Aug 2007 21:39:24 -0000 1.9.2.2 @@ -0,0 +1,150 @@ +ad_library { + XoWiki - chat procs + + @creation-date 2006-02-02 + @author Gustaf Neumann + @cvs-id $Id: chat-procs.tcl,v 1.9.2.2 2007/08/01 21:39:24 gustafn Exp $ +} +namespace eval ::xowiki { + ::xo::ChatClass Chat -superclass ::xo::Chat + + Chat instproc render {} { + my orderby time + set result "" + foreach child [my children] { + set msg [$child msg] + set user_id [$child user_id] + set timelong [clock format [$child time]] + set timeshort [clock format [$child time] -format {[%H:%M:%S]}] + if {$user_id > 0} { + acs_user::get -user_id $user_id -array user + set name [expr {$user(screen_name) ne "" ? $user(screen_name) : $user(name)}] + set url "/shared/community-member?user%5fid=$user_id" + set creator "$name" + } else { + set creator "Nobody" + } + append result "$timeshort\ + [my encode $creator]\ + [my encode $msg]\n" + } + return $result + } + + Chat proc initialize_nsvs {} {;} ;# noop + + Chat proc login {-chat_id -package_id -mode} { + my log "--" + auth::require_login + if {![info exists package_id]} {set package_id [ad_conn package_id] } + if {![info exists chat_id]} {set chat_id $package_id } + set context id=$chat_id&s=[ad_conn session_id].[clock seconds] + set path [site_node::get_url_from_object_id -object_id $package_id] + + if {![info exists mode]} { + set mode polling + if {[info command ::thread::mutex] ne "" && + ![catch {ns_conn contentsentlength}]} { + # we seem to have libthread installed, and the patch for obtaining the tcl-stream + # from a connection thread, so we can use the background delivery thread; + # scripted streaming should work everywhere + set mode scripted-streaming + if {[regexp (firefox) [string tolower [ns_set get [ns_conn headers] User-Agent]]]} { + # for firefox, we could use the nice mode without the spinning load indicator + # currently, streaming mode seems broken with current firefox... + #set mode streaming + } + } + my log "--mode $mode" + } + + switch $mode { + polling { + ::xowiki::Page requireJS "/resources/xowiki/get-http-object.js" + set jspath packages/xowiki/www/ajax/chat.js + set login_url ${path}ajax/chat?m=login&$context + set get_update "chatSendCmd(\"$path/ajax/chat?m=get_new&$context\",chatReceiver)" + set get_all "chatSendCmd(\"$path/ajax/chat?m=get_all&$context\",chatReceiver)" + } + streaming { + set jspath packages/xowiki/www/ajax/streaming-chat.js + set subscribe_url ${path}ajax/chat?m=subscribe&$context + } + scripted-streaming { + append context &mode=scripted + set jspath packages/xowiki/www/ajax/scripted-streaming-chat.js + set subscribe_url ${path}ajax/chat?m=subscribe&$context + } + } + set send_url ${path}ajax/chat?m=add_msg&$context&msg= + + if { ![file exists [acs_root_dir]/$jspath] } { + return -code error "File [acs_root_dir]/$jspath does not exist" + } + set file [open [acs_root_dir]/$jspath]; set js [read $file]; close $file + + my log "--CHAT mode=$mode" + + switch $mode { + polling {return "\ + +
      + + +
      " + } + + + streaming {return "\ + +
      +
      + " + } + + + scripted-streaming {return "\ + +
      + + + +
      " + } + } + } +} + 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 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/form-field-procs.tcl 1 Aug 2007 21:39:24 -0000 1.32.2.2 @@ -0,0 +1,1017 @@ +ad_library { + XoWiki - form fields + + @creation-date 2007-06-22 + @author Gustaf Neumann + @cvs-id $Id: form-field-procs.tcl,v 1.32.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki { + + # Second approximation for form fields. + # FormFields are objects, which can be outputed as well in ad_forms + # or asHTML included in wiki pages. FormFields support + # + # - validation + # - help_text + # - error messages + # - internationlized pretty_values + # + # and inherit properties of the original datatypes via slots + # (e.g. for boolean entries). FormFields can be subclassed + # to ensure tailorability and high reuse. + # + # todo: at some later time, this should go into xotcl-core + + ########################################################### + # + # ::xowiki::FormField (Base Class) + # + ########################################################### + Class FormField -parameter { + {required false} + {display_field true} + {inline false} + CSSclass + {type text} + {label} + {name} + {id} + {value ""} + {spec ""} + {help_text ""} + {error_msg ""} + {validator ""} + locale + default + object + } + FormField instproc init {} { + if {![my exists label]} {my label [string totitle [my name]]} + if {![my exists id]} {my id [my name]} + if {[my exists id]} {my set html(id) [my id]} + if {[my exists default]} {my set value [my default]} + my config_from_spec [my spec] + } + + FormField instproc validate {obj} { + my instvar name required value + + if {$required && $value eq ""} { + my instvar label + return [_ acs-templating.Element_is_required] + } + # + #my msg "[my name] [my info class] validator=[my validator]" + if {[my validator] ne ""} { + set errorMsg "" + # + # The validator might set the variable errorMsg in this scope. + # + set success 1 + set validator_method check=[my validator] + set proc_info [my procsearch $validator_method] + if {$proc_info ne ""} { + # we have a slot checker, call it + #my msg "call field specific validator $validator_method '$value'" + set success [my $validator_method $value] + } + if {$success == 1} { + # the previous check was ok, check now for a validator on the + # object level + set validator_method validate=[my validator] + set proc_info [$obj procsearch $validator_method] + if {$proc_info ne ""} { + #my msg "call object level validator $validator_method '$value'" + set success [$obj $validator_method $value] + } + } + if {$success == 0} { + # + # We have an error message. Get the class name from procsearch and construct + # a message key based on the class and the name of the validator. + # + set cl [namespace tail [lindex $proc_info 0]] + return [_ xowiki.$cl-validate_[my validator] [list value $value errorMsg $errorMsg]] + } + } + return "" + } + + FormField instproc reset_parameter {} { + # reset application specific parameters (defined below ::xowiki::FormField) + # such that searchDefaults will pick up the new defaults, when a form field + # is reclassed. + for {set c [my info class]} {$c ne "::xowiki::FormField"} {set c [$c info superclass]} { + #my msg "[my name] parameters ($c) = [$c info parameter]" + foreach p [$c info parameter] { + set l [split $p] + if {[llength $l] != 2} continue + set var [lindex $l 0] + if {[my exists $var]} { + #my msg "[my name] unset '$var'" + my unset $var + } + } + } + } + + FormField instproc config_from_spec {spec} { + my instvar type options widget_type + if {[my info class] eq [self class]} { + # Check, wether the actual class of the formfield differs from the + # generic FromField class. If yes, the object was already + # reclassed to a concrete form field type. Since config_from_spec + # can be called multiple times, we want to do the reclassing only + # once. + my class [self class]::$type + ::xotcl::Class::Parameter searchDefaults [self]; # TODO: will be different in xotcl 1.6.* + } + + foreach s [split $spec ,] { + switch -glob $s { + optional {my set required false} + required {my set required true} + label=* {my label [lindex [split $s =] 1]} + help_text=* {my help_text [lindex [split $s =] 1]} + *=* { + set l [split $s =] + foreach {attribute value} $l break + set definition_class [lindex [my procsearch $attribute] 0] + if {[string match "::xotcl::*" $definition_class] || $definition_class eq ""} { + error [_ xowiki.error-form_constraint-unknown_attribute [list name [my name] entry $attribute]] + } + if {[catch { + # + # We want to allow a programmer to use e.g. options=[xowiki::locales] + # + # Note: do not allow users to use [] via forms, since they might + # execute arbitrary commands. The validator for the form fields + # makes sure, that the input specs are free from square brackets. + # + if {[string match {\[*\]} $value]} { + set value [subst $value] + } + my [lindex $l 0] $value + } errMsg]} { + error "Error during setting attribute '[lindex $l 0]' to value '[lindex $l 1]': $errMsg" + } + } + default { + if {[my isclass [self class]::$s]} { + my class [self class]::$s + my reset_parameter + #my msg "[my name] searchDefaults" + ::xotcl::Class::Parameter searchDefaults [self]; # TODO: will be different in xotcl 1.6.* + } else { + if {$s ne ""} { + error [_ xowiki.error-form_constraint-unknown_spec_entry \ + [list name [my name] entry $s x "Unknown spec entry for entry '$s'"]] + } + } + } + } + } + + # + # It is possible, that a default value of a form field is changed through a spec. + # Since only the configuration might set values, checking value for "" seems safe here. + # + if {[my value] eq "" && [my exists default] && [my default] ne ""} { + #my msg "reset value to [my default]" + my value [my default] + } + + if {[lang::util::translator_mode_p]} { + my mixin "::xo::TRN-Mode" + } + my initialize + } + + FormField instproc asWidgetSpec {} { + my instvar widget_type options label help_text format html display_html + set spec $widget_type + if {[my exists spell]} {append spec ",[expr {[my spell] ? {} : {no}}]spell"} + + if {![my required]} {append spec ",optional"} + append spec " {label " [list $label] "} " + + if {[my exists html]} { + append spec " {html {" + foreach {key value} [array get html] { + append spec $key " " [list $value] " " + } + append spec "}} " + } + + if {[my exists options]} { + append spec " {options " [list $options] "} " + } + if {[my exists format]} { + append spec " {format " [list $format] "} " + } + if {$help_text ne ""} { + if {[string match "#*#" $help_text]} { + set internationalized [_ [string trim $help_text #]] + append spec " {help_text {$internationalized}}" + } else { + append spec " {help_text {$help_text}}" + } + } + return $spec + } + + FormField ad_instproc get_attributes { + args + } { + Get a list of attribute value pairs + of instance attributes. It returns only those + pairs for which a value exists. + + @return flattened list of attribute value pairs + } { + set pairs [list] + foreach attribute $args { + set l [split $attribute] + if {[llength $l] > 1} { + foreach {attribute HTMLattribute} $l break + } else { + set HTMLattribute $attribute + } + #my msg "[my name] check for $attribute => [my exists $attribute]" + if {[my exists $attribute]} { + lappend pairs $HTMLattribute [my set $attribute] + } + } + return $pairs + } + + FormField instproc render {} { + # In case, we use an asHTML of a FormField, we use this + # render definition + if {[my inline]} { + # with label, error message, help text + my render_form_widget + } else { + # without label, error message, help text + my render_item + } + } + + FormField instproc render_form_widget {} { + # This method provides the form-widget wrapper + ::html::div -class form-widget { my render_content } + } + + FormField instproc render_content {} { + # This is the most general widget content renderer. + # If no special renderer is defined, we fall back to this one, + # which is in most cases a simple input fied of type string. + ::html::input [my get_attributes type size maxlength id name value] {} + } + + FormField instproc render_error_msg {} { + if {[my error_msg] ne ""} { + ::html::div -class form-error { + my instvar label + ::html::t [::xo::localize [my error_msg]] + my render_localizer + my set error_reported 1 + } + } + } + + FormField instproc render_help_text {} { + set text [my help_text] + if {$text ne ""} { + html::div -class form-help-text { + html::img -src "/shared/images/info.gif" -alt {[i]} -title {Help text} \ + -width "12" -height 9 -border 0 -style "margin-right: 5px" {} + html::t $text + } + } + } + + FormField instproc render_localizer {} { + # Just an empty fall-back method. + # This method will be overloaded in trn mode by a mixin. + } + + FormField instproc render_item {} { + ::html::div -class form-item-wrapper { + ::html::div -class form-label { + ::html::label -for [my id] { + ::html::t [my label] + } + if {[my required]} { + ::html::div -class form-required-mark { + ::html::t " (#acs-templating.required#)" + } + } + } + my render_form_widget + my render_help_text + my render_error_msg + html::t \n + } + } + + FormField instproc localize {v} { + # We localize in pretty_value the message keys in the + # language of the item (not the connection item). + if {[regexp "^#(.*)#$" $v _ key]} { + return [lang::message::lookup [my locale] $key] + } + return $v + } + + FormField instproc pretty_value {v} { + if {[my exists options]} { + foreach o [my set options] { + foreach {label value} $o break + if {$value eq $v} {return [my localize $label]} + } + } + return [string map [list & "&" < "<" > ">" \" """ ' "'" @ "@"] $v] + } + + ########################################################### + # + # ::xowiki::FormField::submit_button + # + ########################################################### + + Class FormField::submit_button -superclass FormField + FormField::submit_button instproc initialize {} { + my set type submit + } + FormField::submit_button instproc render_content {} { + my set value [::xo::localize [_ xowiki.Form-submit_button]] + ::html::div -class form-button { + #::html::br + ::html::input [my get_attributes type {CSSclass class} value] {} + my render_localizer + } + } + + ########################################################### + # + # ::xowiki::FormField::hidden + # + ########################################################### + + Class FormField::hidden -superclass FormField + FormField::hidden instproc initialize {} { + my type hidden + my set widget_type text(hidden) + } + FormField::hidden instproc render_item {} { + # don't render the labels + my render_form_widget + } + FormField::hidden instproc render_help_text {} { + } + + ########################################################### + # + # ::xowiki::FormField::inform + # + ########################################################### + + Class FormField::inform -superclass FormField + FormField::inform instproc initialize {} { + my type hidden + my set widget_type text(inform) + } + FormField::inform instproc render_content {} { + ::html::t [my value] + ::html::input [my get_attributes type id name value] {} + } + FormField::inform instproc render_help_text {} { + } + + ########################################################### + # + # ::xowiki::FormField::text + # + ########################################################### + + Class FormField::text -superclass FormField -parameter { + {size 80} + maxlength + } + FormField::text instproc initialize {} { + my set widget_type text + foreach p [list size maxlength] {if {[my exists $p]} {my set html($p) [my $p]}} + } + + ########################################################### + # + # ::xowiki::FormField::numeric + # + ########################################################### + + Class FormField::numeric -superclass FormField::text -parameter { + {validator numeric} + } + FormField::numeric instproc initialize {} { + my validator numeric + next + my set widget_type numeric + } + FormField::numeric instproc check=numeric {value} { + return [string is double $value] + } + + ########################################################### + # + # ::xowiki::FormField::user_id + # + ########################################################### + + Class FormField::user_id -superclass FormField::numeric -parameter { + } + FormField::user_id instproc pretty_value {v} { + return [::xo::get_user_name $v] + } + + ########################################################### + # + # ::xowiki::FormField::url + # + ########################################################### + + Class FormField::url -superclass FormField::text -parameter { + {link_label} + } + FormField::url instproc pretty_value {v} { + if {$v ne ""} { + if {[my exists link_label]} { + set link_label [my localize [my link_label]] + } else { + set link_label $v + } + return "$link_label" + } + } + + ########################################################### + # + # ::xowiki::FormField::detail_link + # + ########################################################### + + Class FormField::detail_link -superclass FormField::url -parameter { + {link_label "#xowiki.weblog-more#"} + } + FormField::detail_link instproc pretty_value {v} { + if {$v eq ""} { + return "" + } + if {$v ne ""} { + set link_label [my localize [my link_label]] + return " \[ $link_label \]" + } + } + + ########################################################### + # + # ::xowiki::FormField::textarea + # + ########################################################### + + Class FormField::textarea -superclass FormField -parameter { + {rows 2} + {cols 80} + {spell false} + style + } + FormField::textarea instproc initialize {} { + my set widget_type text(textarea) + foreach p [list rows cols style] {if {[my exists $p]} {my set html($p) [my $p]}} + next + } + + FormField::textarea instproc render_content {} { + ::html::textarea [my get_attributes id name cols rows style {CSSclass class}] { + ::html::t [my value] + } + } + + ########################################################### + # + # ::xowiki::FormField::richtext + # + ########################################################### + + Class FormField::richtext -superclass FormField::textarea -parameter { + {editor xinha} + plugins + folder_id + width + {validator safe_html} + } + FormField::richtext instproc initialize {} { + # Reclass the editor based on the attribute 'editor' if necessary + # and call initialize again in this case... + my display_field false + + if {[my editor] ne "" && [my info class] ne "[self class]::[my editor]"} { + set editor_class [self class]::[my editor] + if {![my isclass $editor_class]} { + set editors [list] + foreach c [::xowiki::FormField::richtext info subclass] { + lappend editors [namespace tail $c] + } + error [_ xowiki.error-form_constraint-unknown_editor \ + [list name [my name] editor [my editor] editors $editors]] + } + my class $editor_class + my reset_parameter + ::xotcl::Class::Parameter searchDefaults [self]; # TODO: will be different in xotcl 1.6.* + my initialize + } else { + next + } + } + FormField::richtext instproc check=safe_html {value} { + # don't check if the user has admin permissions on the package + if {[::xo::cc permission \ + -object_id [::xo::cc package_id] \ + -privilege admin \ + -party_id [::xo::cc user_id]]} { + set msg "" + } else { + set msg [ad_html_security_check $value] + } + if {$msg ne ""} { + my uplevel [list set errorMsg $msg] + return 0 + } + return 1 + } + FormField::richtext instproc pretty_value {v} { + # for richtext, perform minimal output escaping + return [string map [list @ "@"] $v] + } + + ########################################################### + # + # ::xowiki::FormField::richtext::wym + # + ########################################################### + Class FormField::richtext::wym -superclass FormField::richtext -parameter { + {editor wym} + {CSSclass wymeditor} + } + FormField::richtext::wym instproc initialize {} { + next + my set widget_type richtext + ::xowiki::Page requireCSS "/resources/xowiki/wymeditor/skins/default/screen.css" + ::xowiki::Page requireJS "/resources/xowiki/wymeditor/jquery.js" + ::xowiki::Page requireJS "/resources/xowiki/wymeditor/jquery.wymeditor.js" + ::xowiki::Page requireJS { + var $j = jQuery.noConflict(); + $j(function() { + $j(".wymeditor").wymeditor(); + }); + } + } + + ########################################################### + # + # ::xowiki::FormField::richtext::xinha + # + ########################################################### + + Class FormField::richtext::xinha -superclass FormField::richtext -parameter { + javascript + {height 350px} + {style "width: 100%"} + } + FormField::richtext::xinha instproc initialize {} { + next + my set widget_type richtext + if {![my exists plugins]} { + my plugins \ + [parameter::get -parameter "XowikiXinhaDefaultPlugins" \ + -default [parameter::get_from_package_key \ + -package_key "acs-templating" -parameter "XinhaDefaultPlugins"]] + } + my set options [my get_attributes editor plugins width height folder_id javascript] + } + FormField::richtext::xinha instproc render_content {} { + # we use for the time being the initialization of xinha based on + # the site master + set ::acs_blank_master(xinha) 1 + set quoted [list] + foreach e [my plugins] {lappend quoted '$e'} + set ::acs_blank_master(xinha.plugins) [join $quoted ", "] + + array set o [my set options] + set xinha_options "" + foreach e {width height folder_id fs_package_id file_types attach_parent_id} { + if {[info exists o($e)]} { + append xinha_options "xinha_config.$e = '$o($e)';\n" + } + } + append xinha_options "xinha_config.package_id = '[::xo::cc package_id]';\n" + if {[info exists o(javascript)]} { + append xinha_options $o(javascript) \n + } + set ::acs_blank_master(xinha.options) $xinha_options + lappend ::acs_blank_master__htmlareas [my id] + next + } + + + ########################################################### + # + # ::xowiki::FormField::radio + # + ########################################################### + + Class FormField::radio -superclass FormField -parameter { + {options ""} + {horizontal false} + } + FormField::radio instproc initialize {} { + my set widget_type text(radio) + } + FormField::radio instproc render_content {} { + set value [my value] + foreach o [my options] { + foreach {label rep} $o break + set atts [list id [my id]:$rep name [my name] type radio value $rep] + if {$value eq $rep} {lappend atts checked checked} + ::html::input $atts {} + html::t "$label " + if {![my horizontal]} {html::br} + } + } + + ########################################################### + # + # ::xowiki::FormField::select + # + ########################################################### + + Class FormField::select -superclass FormField -parameter { + {options ""} + {multiple "false"} + } + FormField::select instproc initialize {} { + my set widget_type text(select) + } + FormField::select instproc render_content {} { + set atts [my get_attributes id name] + if {[my multiple]} {lappend atts multiple [my multiple]} + set options [my options] + if {![my required]} { + set options [linsert $options 0 [list "--" ""]] + } + ::html::select $atts { + foreach o $options { + foreach {label rep} $o break + set atts [list value $rep] + #my msg "lsearch {[my value]} $value ==> [lsearch [my value] $value]" + if {[lsearch [my value] $rep] > -1} { + lappend atts selected on + } + ::html::option $atts {::html::t $label} + }} + } + + + ########################################################### + # + # ::xowiki::FormField::DD + # + ########################################################### + + Class FormField::DD -superclass FormField -superclass FormField::select + FormField::DD instproc initialize {} { + my options { + {01 1} {02 2} {03 3} {04 4} {05 5} {06 6} {07 7} {08 8} {09 9} {10 10} + {11 11} {12 12} {13 13} {14 14} {15 15} {16 16} {17 17} {18 18} {19 19} {20 20} + {21 21} {22 22} {23 23} {24 24} {25 25} {26 26} {27 27} {28 28} {29 29} {30 30} + {31 31} + } + next + } + + ########################################################### + # + # ::xowiki::FormField::HH24 + # + ########################################################### + + Class FormField::HH24 -superclass FormField -superclass FormField::select + FormField::HH24 instproc initialize {} { + my options { + {00 0} {01 1} {02 2} {03 3} {04 4} {05 5} {06 6} {07 7} {08 8} {09 9} + {10 10} {11 11} {12 12} {13 13} {14 14} {15 15} {16 16} {17 17} {18 18} {19 19} + {20 20} {21 21} {22 22} {23 23} + } + next + } + + ########################################################### + # + # ::xowiki::FormField::MI + # + ########################################################### + + Class FormField::MI -superclass FormField -superclass FormField::select + FormField::MI instproc value args { + if {[llength $args] == 0} {return [my set value]} else { + set v [lindex $args 0] + if {$v eq ""} {return [my set value ""]} else { + # round to 5 minutes + my set value [lindex [my options] [expr {($v + 2) / 5}] 1] + } + } + } + FormField::MI instproc initialize {} { + my options { + {00 0} {05 5} {10 10} {15 15} {20 20} {25 25} + {30 30} {35 35} {40 40} {45 45} {50 50} {55 55} + } + next + } + + ########################################################### + # + # ::xowiki::FormField::MM + # + ########################################################### + + Class FormField::MM -superclass FormField -superclass FormField::select + FormField::MM instproc initialize {} { + my options { + {01 1} {02 2} {03 3} {04 4} {05 5} {06 6} {07 7} {08 8} {09 9} {10 10} + {11 11} {12 12} + } + next + } + ########################################################### + # + # ::xowiki::FormField::mon + # + ########################################################### + + Class FormField::mon -superclass FormField::select + FormField::mon instproc initialize {} { + set values [lang::message::lookup [my locale] acs-lang.localization-abmon] + if {[lang::util::translator_mode_p]} {set values [::xo::localize $values]} + set last 0 + foreach m {1 2 3 4 6 7 8 9 10 11 12} { + lappend options [list [lindex $values $last] $m] + set last $m + } + my options $options + next + } + ########################################################### + # + # ::xowiki::FormField::month + # + ########################################################### + + Class FormField::month -superclass FormField::select + FormField::month instproc initialize {} { + set values [lang::message::lookup [my locale] acs-lang.localization-mon] + if {[lang::util::translator_mode_p]} {set values [::xo::localize $values]} + set last 0 + foreach m {1 2 3 4 6 7 8 9 10 11 12} { + lappend options [list [lindex $values $last] $m] + set last $m + } + my options $options + next + } + + ########################################################### + # + # ::xowiki::FormField::YYYY + # + ########################################################### + + Class FormField::YYYY -superclass FormField::numeric -parameter { + {size 4} + {maxlength 4} + } + + ########################################################### + # + # ::xowiki::FormField::date + # + ########################################################### + + Class FormField::date -superclass FormField -parameter { + {format "DD MONTH YYYY"} + {display_format "%Y-%m-%d %T"} + } + # The default of a date might be all relative dates + # supported by clock scan. These include "now", "tomorrow", + # "yesterday", "next week", .... use _ for blanks + + FormField::date instproc initialize {} { + my set widget_type date + my set format [string map [list _ " "] [my format]] + my array set format_map { + SS {SS %S 1} + MI {MI %M 1} + HH24 {HH24 %H 1} + DD {DD %e 0} + MM {MM %m 1} + MON {mon %m 1} + MONTH {month %m 1} + YYYY {YYYY %Y 0} + } + foreach {class code trim_zeros} [my components] { + # + # create for each component of the format a subobject named by the class + # + ::xowiki::FormField::$class create [self]::$class \ + -name [my name].$class -id [my id].$class -locale [my locale] + } + } + + FormField::date instproc components {} { + set components [list] + foreach c [split [my format]] { + if {![my exists format_map($c)]} { + error "Unknown format component: $c. \ + Valid compontents are [my array names format_map]" + } + eval lappend components [my set format_map($c)] + } + return $components + } + + FormField::date instproc set_compound_value {} { + set value [my value] + #my msg "date: value set to '$value'" + if {$value ne ""} { + set ticks [clock scan [string map [list _ " "] $value]] + } else { + set ticks "" + } + # set the value parts for each components + foreach {class code trim_zeros} [my components] { + if {$ticks ne ""} { + set value_part [clock format $ticks -format $code] + if {$trim_zeros} { + set value_part [string trimleft $value_part 0] + if {$value_part eq ""} {set value_part 0} + } + } else { + set value_part "" + } + [self]::$class value $value_part + } + } + + FormField::date instproc get_compound_value {} { + # Set the internal representation of the date based on the components values. + # Internally, the ansi date format is used. + set year ""; set month ""; set day ""; set hour ""; set min ""; set sec "" + if {[my isobject [self]::YYYY]} {set year [[self]::YYYY value]} + if {[my isobject [self]::month]} {set month [[self]::month value]} + if {[my isobject [self]::mon]} {set month [[self]::mon value]} + if {[my isobject [self]::MM]} {set month [[self]::MM value]} + if {[my isobject [self]::DD]} {set day [[self]::DD value]} + if {[my isobject [self]::HH24]} {set hour [[self]::HH24 value]} + if {[my isobject [self]::MI]} {set min [[self]::MI value]} + if {[my isobject [self]::SS]} {set sec [[self]::SS value]} + if {"$year$month$day$hour$min$sec" eq ""} { + return "" + } + if {$year eq ""} {set year 2000} + if {$month eq ""} {set month 1} + if {$day eq ""} {set day 1} + if {$hour eq ""} {set hour 0} + if {$min eq ""} {set min 0} + if {$sec eq ""} {set sec 0} + #my msg "$year-$month-$day ${hour}:${min}:${sec}" + set ticks [clock scan "$year-$month-$day ${hour}:${min}:${sec}"] + # TODO: TZ??? + return [clock format $ticks -format "%Y-%m-%d %T"] + } + + FormField::date instproc pretty_value {v} { + # internally, we have ansi format. For displaying the date, use the display format + # drop of the value after the "." we assume to have a date in the local zone + regexp {^([^.]+)[.]} $v _ v + return [clock format [clock scan $v] -format [string map [list _ " "] [my display_format]]] + } + + FormField::date instproc render_content {} { + my set_compound_value + my set style "margin: 0px; padding: 0px;" + html::fieldset [my get_attributes id style] { + foreach {class code trim_zeros} [my components] { + [self]::$class render_content + } + } + } + + ########################################################### + # + # ::xowiki::FormField::boolean + # + ########################################################### + + Class FormField::boolean -superclass FormField::radio -parameter { + {default t} + } + FormField::boolean instproc initialize {} { + # should be with cvs head message catalogs: + # my options {{#acs-kernel.common_No# f} {#acs-kernel.common_Yes# t}} + my options {{No f} {#acs-kernel.common_Yes# t}} + next + } + + ########################################################### + # + # ::xowiki::FormField::scale + # + ########################################################### + + Class FormField::scale -superclass FormField::radio -parameter {{n 5} {horizontal true}} + FormField::scale instproc initialize {} { + my instvar n + set options [list] + for {set i 1} {$i <= $n} {incr i} { + lappend options [list $i $i] + } + my options $options + next + } + + ########################################################### + # + # a few test cases + # + ########################################################### + + proc ? {cmd expected {msg ""}} { + ::xo::Timestamp t1 + set r [uplevel $cmd] + if {$msg eq ""} {set msg $cmd} + if {$r ne $expected} { + regsub -all \# $r "" r + append ::_ "Error: $msg returned \n'$r' ne \n'$expected'\n" + } else { + append ::_ "$msg - passed ([t1 diff] ms)\n" + } + } + # + proc test_form_fields {} { + set ::_ "" + set o [Object new -destroy_on_cleanup] + # mixin methods for create_form_field + $o mixin ::xowiki::Page + + set f0 [$o create_form_field -name test \ + -slot ::xowiki::Page::slot::name] + ? {$f0 asWidgetSpec} \ + {text {label #xowiki.Page-name#} {html {size 80 }} {help_text {Shortname to identify an entry within a folder, typically lowercase characters}}} \ + "name with help_text" + + set f0 [$o create_form_field -name test \ + -slot ::xowiki::Page::slot::name -spec inform] + ? {$f0 asWidgetSpec} \ + {text(inform) {label #xowiki.Page-name#} {help_text {Shortname to identify an entry within a folder, typically lowercase characters}}} \ + "name with help_text + inform" + + set f0 [$o create_form_field -name test \ + -slot ::xowiki::Page::slot::name -spec optional] + ? {$f0 asWidgetSpec} \ + {text,optional {label #xowiki.Page-name#} {html {size 80 }} {help_text {Shortname to identify an entry within a folder, typically lowercase characters}}} \ + "name with help_text + optional" + + set f1 [$o create_form_field -name test \ + -slot ::xowiki::Page::slot::description \ + -spec "textarea,cols=80,rows=2"] + ? {$f1 asWidgetSpec} \ + {text(textarea),nospell,optional {label #xowiki.Page-description#} {html {cols 80 rows 2 }} } \ + "textarea,cols=80,rows=2" + + set f2 [$o create_form_field -name test \ + -slot ::xowiki::Page::slot::nls_language \ + -spec {select,options=[xowiki::locales]}] + ? {$f2 asWidgetSpec} \ + {text(select),optional {label #xowiki.Page-nls_language#} {options {[xowiki::locales]}} } \ + {select,options=[xowiki::locales]} + + + $o mixin ::xowiki::PodcastItem + set f3 [$o create_form_field -name test \ + -slot ::xowiki::PodcastItem::slot::pub_date] + ? {$f3 asWidgetSpec} \ + {date,optional {label #xowiki.PodcastItem-pub_date#} {format {YYYY MM DD HH24 MI}} } \ + {date with format} + } +} Index: openacs-4/packages/xowiki/tcl/lcs-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/lcs-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/lcs-procs.tcl 1 Aug 2007 21:39:24 -0000 1.2.2.2 @@ -0,0 +1,150 @@ +# Copyright (c) 2003 by Kevin B. Kenny. All rights reserved. +# See the file, +# 'http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/tcllib/tcllib/license.terms' +# for terms and conditions of redistribution. + + namespace eval list { namespace export longestCommonSubsequence } + + # Do a compatibility version of [lset] for pre-8.4 versions of Tcl. + # This version does not do multi-arg [lset]! + + if { [package vcompare [package provide Tcl] 8.4] < 0 } { + proc list::K { x y } { set x } + proc list::lset { var index arg } { + upvar 1 $var list + set list [lreplace [K $list [set list {}]] $index $index $arg] + } + } + + # list::longestCommonSubsequence -- + # + # Computes the longest common subsequence of two lists. + # + # Parameters: + # sequence1, sequence2 -- Two lists to compare. + # + # Results: + # Returns a list of two lists of equal length. + # The first sublist is of indices into sequence1, and the + # second sublist is of indices into sequence2. Each corresponding + # pair of indices corresponds to equal elements in the sequences; + # the sequence returned is the longest possible. + # + # Side effects: + # None. + + proc list::longestCommonSubsequence { sequence1 sequence2 } { + + set seta [list] + set setb [list] + + # Construct a set of equivalence classes of lines in file 2 + + set index 0 + foreach string $sequence2 { + lappend eqv($string) $index + incr index + } + + # K holds descriptions of the common subsequences. + # Initially, there is one common subsequence of length 0, + # with a fence saying that it includes line -1 of both files. + # The maximum subsequence length is 0; position 0 of + # K holds a fence carrying the line following the end + # of both files. + + lappend K [list -1 -1 {}] + lappend K [list [llength $sequence1] [llength $sequence2] {}] + set k 0 + + # Walk through the first file, letting i be the index of the line and + # string be the line itself. + + set i 0 + foreach string $sequence1 { + + # Consider each possible corresponding index j in the second file. + + if { [info exists eqv($string)] } { + + # c is the candidate match most recently found, and r is the + # length of the corresponding subsequence. + + set c [lindex $K 0] + set r 0 + + foreach j $eqv($string) { + + # Perform a binary search to find a candidate common + # subsequence to which may be appended this match. + + set max $k + set min $r + set s [expr { $k + 1 }] + while { $max >= $min } { + set mid [expr { ( $max + $min ) / 2 }] + set bmid [lindex [lindex $K $mid] 1] + if { $j == $bmid } { + break + } elseif { $j < $bmid } { + set max [expr {$mid - 1}] + } else { + set s $mid + set min [expr { $mid + 1 }] + } + } + + # Go to the next match point if there is no suitable + # candidate. + + if { $j == [lindex [lindex $K $mid] 1] || $s > $k} { + continue + } + + # s is the sequence length of the longest sequence + # to which this match point may be appended. Make + # a new candidate match and store the old one in K + # Set r to the length of the new candidate match. + + set newc [list $i $j [lindex $K $s]] + lset K $r $c + set c $newc + set r [expr {$s + 1}] + + # If we've extended the length of the longest match, + # we're done; move the fence. + + if { $s >= $k } { + lappend K [lindex $K end] + incr k + break + } + + } + + # Put the last candidate into the array + + lset K $r $c + + } + + incr i + + } + + set q [lindex $K $k] + + for { set i 0 } { $i < $k } {incr i } { + lappend seta {} + lappend setb {} + } + while { [lindex $q 0] >= 0 } { + incr k -1 + lset seta $k [lindex $q 0] + lset setb $k [lindex $q 1] + set q [lindex $q 2] + } + + return [list $seta $setb] + + } Index: openacs-4/packages/xowiki/tcl/link-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/link-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/link-procs.tcl 1 Aug 2007 21:39:24 -0000 1.30.2.2 @@ -0,0 +1,303 @@ +ad_library { + XoWiki - definition of link types and their renderers + + @creation-date 2006-04-15 + @author Gustaf Neumann + @cvs-id $Id: link-procs.tcl,v 1.30.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki { + + # + # generic links + # + Class create ExternalLink -parameter { + href label title target + } + ExternalLink instproc render {} { + my instvar href label title target + set title_att "" + if {[info exists title]} {append title_att " title='$title'"} + if {[info exists target]} {append title_att " target='$target'"} + return "$label" + } + + Class create Link -parameter { + type name lang stripped_name label page + folder_id package_id + title target + } + Link instproc atts {} { + set atts "" + if {[my exists title]} {append atts " title='[my title]'"} + if {[my exists target]} {append atts " target='[my target]'"} + } + Link instproc init {} { + set class [self class]::[my type] + if {[my isclass $class]} {my class $class} + #my log "--L link has class [my info class] // $class" + } + Link instproc resolve {} { + #my log "--lookup of [my name] -page [my page]" + if {![regexp {(.*?)(\#|%23)+(.*)$} [my name] full_name name anchor_tag anchor]} { + set name [my name] + } + ::Generic::CrItem lookup -name $name -parent_id [my folder_id] + } + Link instproc render_found {href label} { + return "$label" + } + Link instproc render_not_found {href label} { + return " \[ $label \] " + } + Link instproc render {} { + my instvar package_id + set page [my page] + set item_id [my resolve] + my log "--u resolve returns $item_id" + if {$item_id} { + $page lappend references [list $item_id [my type]] + ::xowiki::Package require $package_id + if {![regexp {(.*?)(\#|%23)+(.*)$} [my stripped_name] full_name name anchor_tag anchor]} { + set name [my stripped_name] + set anchor "" + } + set href [::$package_id pretty_link -lang [my lang] -anchor $anchor $name] + + my render_found $href [my label] + } else { + $page incr unresolved_references + set object_type [[$page info class] set object_type] + set name [my name] + set title [my label] + set href [export_vars -base [$package_id package_url] \ + {{edit-new 1} object_type name title}] + my render_not_found $href [my label] + } + } + + Link instproc lookup_xowiki_package_by_name {name start_package_id} { + set ancestors [site_node::get_ancestors \ + -node_id $start_package_id \ + -element node_id] + foreach a $ancestors { + set package_id [site_node::get_children -node_id $a -package_key xowiki \ + -filters [list name $name] -element package_id] + if {$package_id ne ""} { + #my log "--LINK found package_id=$package_id [my isobject ::$package_id]" + ::xowiki::Package require $package_id + return $package_id + } + } + return 0 + } + + + # + # language links + # + + Class create ::xowiki::Link::language -superclass ::xowiki::Link -parameter { + return_only + } + ::xowiki::Link::language instproc render {} { + set page [my page] + my instvar lang name package_id + set item_id [my resolve] + if {$item_id} { + set css_class "found" + set link [$package_id pretty_link -lang $lang [my stripped_name]] + } else { + set css_class "undefined" + set last_page_id [$page set item_id] + set object_type [[$page info class] set object_type] + set link [$package_id make_link $package_id \ + edit-new object_type name last_page_id] + } + # my log "--lang_link=$link" + if {[my exists return_only] && [my return_only] ne $css_class} { + set link "" + } + if {$link ne ""} { + $page lappend lang_links($css_class) \ + "$lang" + } + return "" + } + + # + # image links + # + + Class create ::xowiki::Link::image -superclass ::xowiki::Link \ + -parameter { + href cssclass + float width height + padding padding-right padding-left padding-top padding-bottom + margin margin-left margin-right margin-top margin-bottom + border border-width position top botton left right + } + ::xowiki::Link::image instproc render {} { + my instvar name package_id label + set page [my page] + set item_id [my resolve] + #my log "-- image resolve for $page returned $item_id (name=$name, label=$label) " + if {$item_id} { + set link [[my package_id] pretty_link -download true \ + -absolute [$page absolute_links] $name] + #my log "--l fully quali [$page absolute_links], base=$base" + #set link [export_vars -base $base {{m download}} ] + $page lappend references [list $item_id [my type]] + my render_found $link $label + } else { + $page incr unresolved_references + set last_page_id [$page set item_id] + set title $label + set link [export_vars -base [$package_id package_url] \ + {{edit-new 1} {object_type ::xowiki::File} + {return_url "[$package_id url]"} + name title last_page_id}] + my render_not_found $link $label + } + } + ::xowiki::Link::image instproc render_found {link label} { + set style "" + foreach a { + float width height + padding padding-right padding-left padding-top padding-bottom + margin margin-left margin-right margin-top margin-bottom + border border-width position top botton left right + } { + if {[my exists $a]} {append style "$a: [my set $a];"} + } + if {$style ne ""} {set style "style='$style'"} + set label [string map [list ' "'"] $label] + set cls [expr {[my exists cssclass] ? [my cssclass] : "xowikiimage"}] + if {[my exists href]} { + set href [my set href] + if {[string match "java*" $href]} {set href .} + return "$label" + } else { + return "$label" + } + } + + Class create ::xowiki::Link::file -superclass ::xowiki::Link::image -parameter { + width height align pluginspage pluginurl hidden href target + autostart loop volume controls controller mastersound starttime endtime + } + ::xowiki::Link::file instproc resolve {} { + set item_id [next] + # my log "-- file, lookup of [my name] returned $item_id" + if {$item_id == 0 && [regsub {^file:} [my name] image: name]} { + set item_id [::Generic::CrItem lookup -name $name -parent_id [my folder_id]] + } + return $item_id + } + ::xowiki::Link::file instproc render_found {internal_href label} { + foreach f { + width height align pluginspage pluginurl hidden href target + autostart loop volume controls controller mastersound starttime endtime + } { + if {[my exists $f]} { + append embed_options "$f = '[my set $f]' " + } + } + if {![info exists embed_options]} { + return "$label" + } else { + set internal_href [string map [list %2e .] $internal_href] + return "" + } + } + + Class create ::xowiki::Link::swf -superclass ::xowiki::Link::file -parameter { + width height bgcolor version + quality wmode align salign play loop menu scale + } + ::xowiki::Link::swf instproc resolve {} { + set item_id [next] + my log "--file, lookup of [my name] returned $item_id" + if {$item_id == 0 && [regsub {^swf:} [my name] file: name]} { + set item_id [::Generic::CrItem lookup -name $name -parent_id [my folder_id]] + my log "--file, 2nd lookup of $name returned $item_id" + } + return $item_id + } + ::xowiki::Link::swf instproc render_found {href label} { + ::xowiki::Page requireJS /resources/xowiki/swfobject.js + my instvar package_id name + #set link [$package_id pretty_link -absolute true -siteurl http://localhost:8003 $name]/download.swf + foreach {width height bgcolor version} {320 240 #999999 7} break + foreach a {width height bgcolor version} {if {[my exists $a]} {set $a [my set $a]}} + set id [::xowiki::Portlet self_id] + set addParams "" + foreach a {quality wmode align salign play loop menu scale} { + if {[my exists $a]} {append addParams "so.addParam('$a', '[my set $a]');\n"} + } + + return "
      $label
      + + " + } + + + # + # glossary links + # + + Class create ::xowiki::Link::glossary -superclass ::xowiki::Link + ::xowiki::Link::glossary instproc resolve {} { + # look for a package instance of xowiki, named "glossary" (the type) + set id [my lookup_xowiki_package_by_name [my type] \ + [site_node::get_node_id_from_object_id -object_id [my package_id]]] + #my log "--LINK glossary lookup returned package_id $id" + if {$id} { + # set correct package id for rendering the link + my set package_id $id + #my log "-- INITIALIZE $id" + #::xowiki::Package initialize -package_id $id + my log "--u setting package_id to $id" + # lookup the item from the found folder + return [::Generic::CrItem lookup -name [my name] -parent_id [$id set folder_id]] + } + #my log "--LINK no page found [my name], [my lang], type=[my type]." + return 0 + } + ::xowiki::Link::glossary instproc render_found {href label} { + ::xowiki::Page requireJS "/resources/xowiki/get-http-object.js" + ::xowiki::Page requireJS "/resources/xowiki/popup-handler.js" + ::xowiki::Page requireJS "/resources/xowiki/overlib/overlib.js" + return "$label" + } + + # + # link cache + # + + Class LinkCache + LinkCache instproc resolve {} { + set key link-[my type]-[my name]-[my folder_id] + while {1} { + array set r [ns_cache eval xowiki_cache $key { + set id [next] + if {$id == 0 || $id eq ""} break ;# don't cache + return [list item_id $id package_id [my package_id]] + }] + break + } + if {![info exists r(item_id)]} {return 0} + # we have a valid item. Set the the package_id and return the item_id + my package_id $r(package_id) + return $r(item_id) + } + + Link instmixin add LinkCache +} Index: openacs-4/packages/xowiki/tcl/notification-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/notification-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/notification-procs.tcl 1 Aug 2007 21:39:24 -0000 1.8.2.2 @@ -0,0 +1,154 @@ +ad_library { + XoWiki - Notification procs + + @creation-date 2006-08-08 + @author Gustaf Neumann + @cvs-id $Id: notification-procs.tcl,v 1.8.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki { + + ad_proc -private ::xowiki::notifications-install {} { + + set impl_id [acs_sc::impl::new_from_spec -spec { + name xowiki_notif_type + contract_name NotificationType + owner xowiki + aliases { + GetURL xowiki::notification::get_url + ProcessReply xowiki::notification::process_reply + } + }] + + set type_id [notification::type::new \ + -sc_impl_id $impl_id \ + -short_name xowiki_notif \ + -pretty_name "XoWiki Notification" \ + -description "Notification of a new XoWiki page"] + + foreach delivery {email} { + notification::type::delivery_method_enable -type_id $type_id \ + -delivery_method_id [notification::delivery::get_id -short_name $delivery] + } + + foreach interval {instant hourly daily} { + notification::type::interval_enable -type_id $type_id \ + -interval_id [notification::interval::get_id_from_name -name $interval] + } + } + + + ad_proc -private ::xowiki::notifications-uninstall {} { + + set type_id [notification::type::get_type_id -short_name xowiki_notif] + + foreach delivery {email} { + notification::type::delivery_method_disable -type_id $type_id \ + -delivery_method_id [notification::delivery::get_id -short_name $delivery] + } + foreach interval {instant hourly daily} { + notification::type::interval_disable -type_id $type_id \ + -interval_id [notification::interval::get_id_from_name -name $interval] + } + + notification::type::delete -short_name xowiki_notif + + acs_sc::impl::delete \ + -contract_name "NotificationType" \ + -impl_name xowiki_notif_type + } +} + +namespace eval ::xowiki::notification { + + ad_proc -private get_url {revision_id} { + return [::xowiki::url $revision_id] + } + + + ad_proc -public do_notifications { + {-revision_id} + {-page} + {-html} + {-text} + {-new:boolean true} + } { + generate a notification + @param revision_id + @param new new or modified item + } { + + if {![info exists page]} { + set page [::xowiki::Package instantiate_page_from_id -revision_id $revision_id] + $page volatile + } + + if {[$page set publish_status] eq "production"} { + # don't do notification for pages under construction + #ns_log notice "--n xowiki::notification NO NOTIFCATION due to production state" + return + } + + $page absolute_links 1 + if {![info exists html]} {set html [$page render]} + if {![info exists text]} {set text [ad_html_text_convert -from text/html -to text/plain -- $html]} + + #ns_log notice "--n xowiki::notification::do_notifications called for item_id [$page set revision_id] publish_status=[$page set publish_status] XXX" + $page instvar package_id + set link [::$package_id pretty_link -absolute 1 [$page name]] + append html "

      For more details, see [$page set title]

      " + append text "\nFor more details, see $link ...
      \n" + + set state [expr {[$page set last_modified] eq [$page set creation_date] ? "New" : "Updated"}] + set instance_name [::$package_id instance_name] + + #ns_log notice "--n per directory [$page set title] ($state)" + notification::new \ + -type_id [notification::type::get_type_id -short_name xowiki_notif] \ + -object_id [$page set package_id] \ + -response_id [$page set revision_id] \ + -notif_subject "\[$instance_name\] [$page set title] ($state)" \ + -notif_text $text \ + -notif_html $html \ + -notif_user [$page set creation_user] + + #ns_log notice "--n find categories [$page set title] ($state)" + + foreach cat_id [category::get_mapped_categories [$page set item_id] ] { + set tree_id [category::get_tree $cat_id] + array unset cat + array unset label + foreach category_info [category_tree::get_tree $tree_id] { + foreach {category_id category_label deprecated_p level} $category_info {break} + set cat($level) $category_id + set label($level) $category_label + if {$category_id == $cat_id} break + } + foreach level [array names cat] { + #ns_log notice "--n category $cat($level) $label($level): [$page set title] ($state)" + notification::new \ + -type_id [notification::type::get_type_id -short_name xowiki_notif] \ + -object_id $cat($level) \ + -response_id [$page set revision_id] \ + -notif_subject "\[$instance_name\] $label($level): [$page set title] ($state)" \ + -notif_text $text \ + -notif_html $html \ + -notif_user [$page set creation_user] + } + } + } + + + ad_proc -private process_reply { reply_id} { + handles a reply to an xowiki notif + + @author Deds Castillo (deds@i-manila.com.ph) + @creation-date 2006-06-08 + + } { + # DEDS: need to decide on what to do with this + # do we publish it as comment? + # for now, drop it + return "f" + } +} 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 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/package-procs.tcl 1 Aug 2007 21:39:24 -0000 1.77.2.2 @@ -0,0 +1,1027 @@ +ad_library { + XoWiki - package specific methods + + @creation-date 2006-10-10 + @author Gustaf Neumann + @cvs-id $Id: package-procs.tcl,v 1.77.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki { + + ::xo::PackageMgr create Package \ + -superclass ::xo::Package \ + -parameter {{folder_id "[::xo::cc query_parameter folder_id 0]"}} + + Package ad_proc instantiate_page_from_id { + {-revision_id 0} + {-item_id 0} + {-user_id -1} + {-parameter ""} + } { + Instantiate a page in situations, where the context is not set up + (e.g. we have no package object or folder obect). This call is convenient + when testing e.g. from the developer shell + } { + #TODO can most probably further simplified + set page [::Generic::CrItem instantiate -item_id $item_id -revision_id $revision_id] + + #my log "--I instantiate i=$item_id revision_id=$revision_id page=$page" + + $page folder_id [$page set parent_id] + if {[apm_version_names_compare [ad_acs_version] 5.2] <= -1} { + set package_id [db_string [my qn get_pid] \ + "select package_id from cr_folders where folder_id = [$page $folder_id]"] + $page package_id $package_id + } else { + set package_id [$page set package_id] + } + ::xowiki::Package initialize \ + -package_id $package_id -user_id $user_id \ + -parameter $parameter -init_url false -actual_query "" + ::$package_id set_url -url [::$package_id pretty_link [$page name]] + return $page + } + + Package ad_proc instances {{-include_unmounted false}} { + @return list of package_ids of xowiki instances + } { + if {$include_unmounted} { + return [db_list [my qn get_xowiki_packages] {select package_id \ + from apm_packages where package_key = 'xowiki'}] + } else { + return [db_list [my qn get_mounted_packages] {select package_id \ + from apm_packages p, site_nodes s \ + where package_key = 'xowiki' and s.object_id = p.package_id}] + } + } + + Package ad_proc get_url_from_id {{-item_id 0} {-revision_id 0}} { + Get the full URL from a page in situations, where the context is not set up. + @see instantiate_page_from_id + } { + set page [::xowiki::Package instantiate_page_from_id \ + -item_id $item_id -revision_id $revision_id] + $page volatile + return [::[$page package_id] url] + } + + # + # URL and naming management + # + + Package instproc normalize_name {string} { + set string [string trim $string] + # if subst_blank_in_name is turned on, turn spaces into _ + if {[my get_parameter subst_blank_in_name 1] != 0} { + regsub -all { +} $string "_" string + } + return [ns_urldecode $string] + } + + Package instproc default_locale {} { + # TODO: this might be called quite often. we can optimize this my caching into xo::cc + if {[ns_conn isconnected] && [my get_parameter use_connection_locale 0]} { + # we are connected, return the connection locale + set locale [lang::conn::locale] + } else { + # return either the package locale or the site-wide locale + set locale [lang::system::locale -package_id [my id]] + } + return $locale + } + + Package instproc default_language {} { + return [string range [my default_locale] 0 1] + } + Package array set www-file { + admin 1 + diff 1 + doc 1 + edit 1 + error-template 1 + portlet 1 portlet-ajax 1 portlets 1 + prototypes 1 + ressources 1 + revisions 1 + view-default 1 view-links 1 view-plain 1 oacs-view 1 oacs-view2 1 oacs-view3 1 + download 1 + } + + Package ad_instproc pretty_link { + {-anchor ""} + {-absolute:boolean false} + {-siteurl ""} + {-lang ""} + {-download false} + name + } { + Generate a (minimal) link to a wiki page with the specified name. + Pratically all links in the xowiki systems are generated through this + function. + + @param anchor anchor to be added to the link + @param absolute make an absolute link (including protocol and host) + @param lang use the specified 2 character language code (rather than computing the value) + @param download create download link (without m=download) + @param name name of the wiki page + } { + #my msg "input name=$name, lang=$lang" + set default_lang [my default_language] + if {$lang eq ""} { + if {![regexp {^(..):(.*)$} $name _ lang name]} { + if {![regexp {^(file|image|swf):(.*)$} $name _ lang name]} { + set lang $default_lang + } + } + } + set host [expr {$absolute ? ($siteurl ne "" ? $siteurl : [ad_url]) : ""}] + if {$anchor ne ""} {set anchor \#$anchor} + #my log "--LINK $lang == $default_lang [expr {$lang ne $default_lang}] $name" + set package_prefix [my get_parameter package_prefix [my package_url]] + if {$package_prefix eq "/" && [string length $lang]>2} { + # don't compact the the path for images etc. to avoid conflicts with e.g. //../image/* + set package_prefix [my package_url] + } + #my msg "lang=$lang name=$name" + set encoded_name [string map [list %2d - %5f _ %2e .] [ns_urlencode $name]] + if {$download} { + set url ${host}${package_prefix}download/${lang}/$encoded_name$anchor + } elseif {$lang ne $default_lang || [[self class] exists www-file($name)]} { + set url ${host}${package_prefix}${lang}/$encoded_name$anchor + } else { + set url ${host}${package_prefix}$encoded_name$anchor + } + return $url + } + + Package instproc init {} { + #my log "--R creating + folder_object" + next + my require_folder_object + my set policy [my get_parameter security_policy ::xowiki::policy1] + #my proc destroy {} {my log "--P "; next} + } + + Package ad_instproc get_parameter {attribute {default ""}} { + resolves configurable parameters according to the following precedence: + (1) values specifically set per page {{set-parameter ...}} + (2) query parameter + (3) per instance parameters from the folder object (computable) + (4) standard OpenACS package parameter + } { + set value [::xo::cc get_parameter $attribute] + if {$value eq ""} {set value [my query_parameter $attribute]} + if {$value eq ""} {set value [::[my folder_id] get_payload $attribute]} + if {$value eq ""} {set value [next]} + return $value + } + + Package instproc show_page_order {} { + return [expr {[::xo::db::has_ltree] && [my get_parameter display_page_order 1]}] + } + + # + # conditional links + # + Package ad_instproc make_link {-privilege -link object method args} { + Creates conditionally a link for use in xowiki. When the generated link + will be activated, the specified method of the object will be invoked. + make_link checks in advance, wether the actual user has enough + rights to invoke the method. If not, this method returns empty. + + @param Object The object to which the link refers to. If it is a package_id it will base \ + to the root_url of the package_id. If it is a page, it will base to the page_url + @param method Which method to use. This will be appended as "m=method" to the url. + + Examples for methods: +
        +
      • view: To view and existing page
      • +
      • edit: To edit an existing page
      • +
      • revisions: To view the revisions of an existing page
      • +
      + + @param args List of attributes to be append to the link. Every element + can be an attribute name, or a "name value" pair. Behaves like export_vars. + + @return The link or empty + @see export_vars + } { + my instvar id + + set computed_link "" + if {[$object istype ::xowiki::Package]} { + set base [my package_url] + if {[info exists link]} { + set computed_link [uplevel export_vars -base [list $base$link] [list $args]] + } else { + lappend args [list $method 1] + set computed_link [uplevel export_vars -base [list $base] [list $args]] + } + } elseif {[$object istype ::xowiki::Page]} { + if {[info exists link]} { + set base $link + } else { + set base [my url] + } + lappend args [list m $method] + set computed_link [uplevel export_vars -base [list $base] [list $args]] + } + + if {[info exists privilege]} { + set granted [expr {$privilege eq "public" ? 1 : + [permission::permission_p \ + -object_id $id -privilege $privilege \ + -party_id [::xo::cc user_id]] }] + } else { + # determine privilege from policy + set granted [my check_permissions -link $computed_link $object $method] + #my log "--p $id check_permissions $object $method ==> $granted" + } + + if {$granted} { + return $computed_link + } + return "" + } + + + Package instproc invoke {-method} { + my set mime_type text/html + my set delivery ns_return + set page [my resolve_page [my set object] method] + if {$page ne ""} { + if {[$page procsearch $method] eq ""} { + return [my error_msg "Method '$method' is not defined for this object"] + } else { + #my msg "--invoke [my set object] id=$page method=$method" + return [my call $page $method] + } + } else { + # the requested page was not found, provide an error message and + # an optional link for creating the page + my instvar id + my get_name_and_lang_from_path [my set object] lang local_name + set name ${lang}:$local_name + set object_type ::xowiki::Page ;# for the time being; maybe a parameter? + set new_link [my make_link $id edit-new object_type return_url name] + if {$new_link ne ""} { + set edit_snippet "

      Do you want to create page $name new?" + } else { + set edit_snippet "" + } + return [my error_msg "Page '[my set object]' is not available. $edit_snippet"] + } + } + Package instproc reply_to_user {text} { + if {[::xo::cc exists __continuation]} { + eval [::xo::cc set __continuation] + } else { + if {[string length $text] > 1} { + [my set delivery] 200 [my set mime_type] $text + } + } + } + + Package instproc error_msg {error_msg} { + my instvar id + set template_file error-template + if {![regexp {^[./]} $template_file]} { + set template_file /packages/xowiki/www/$template_file + } + set context [list [$id instance_name]] + set title Error + set header_stuff [::xowiki::Page header_stuff] + set index_link [my make_link -privilege public -link "" $id {} {}] + set link [my query_parameter "return_url" ""] + if {$link ne ""} {set back_link $link} + $id return_page -adp $template_file -variables { + context title index_link back_link header_stuff error_msg + } + } + + Package instproc resolve_page {object method_var} { + upvar $method_var method + my instvar folder_id id policy + # + # first, resolve package level methods + # + if {$object eq ""} { + set exported [$policy defined_methods Package] + foreach m $exported { + #my log "--QP my exists_query_parameter $m = [my exists_query_parameter $m]" + if {[my exists_query_parameter $m]} { + set method $m ;# determining the method, similar file extensions + return [self] + } + } + } + if {[string match //* $object]} { + + # we have a reference to another instance, we cant resolve this from this package. + # Report back not found + return "" + } + + #my log "--o object is '$object'" + if {$object eq ""} { + # we have no object, but as well no method callable on the package + set object [$id get_parameter index_page "index"] + } + # + # second, resolve object level methods + # + #my log "--o try index '$object'" + set page [my resolve_request -path $object method] + #my log "--o page is '$page'" + if {$page ne ""} { + return $page + } + + # stripped object is the object without a language prefix + set stripped_object $object + regexp {^..:(.*)$} $object _ stripped_object + + # try standard page + set standard_page [$id get_parameter ${object}_page] + #my log "--o standard_page '$standard_page'" + if {$standard_page ne ""} { + set page [my resolve_request -path $standard_page method] + if {$page ne ""} { + return $page + } + } else { + regexp {../([^/]+)$} $object _ object + set standard_page "en:$stripped_object" + # maybe we are calling from a different language, but the + # standard page with en: was already instantiated + set page [my resolve_request -path $standard_page method] + if {$page ne ""} { + return $page + } + } + set page [my import_prototype_page $stripped_object] + if {$page eq ""} { + my log "no prototype for '$object' found" + } + return $page + } + + Package instproc import_prototype_page {{prototype_name ""}} { + set page "" + if {$prototype_name eq ""} { + set prototype_name [my query_parameter import_prototype_page ""] + set via_url 1 + } + if {$prototype_name eq ""} { + error "No name for prototype given" + } + set fn [get_server_root]/packages/[my package_key]/www/prototypes/$prototype_name.page + #my log "--W check $fn" + if {[file readable $fn]} { + my instvar folder_id id + # We have the file. We try to create an item or revision from + # definition in the file system. + if {[regexp {^(..):(.*)$} $prototype_name _ lang local_name]} { + set name $prototype_name + } else { + set name en:$prototype_name + } + #my log "--sourcing page definition $fn, using name '$name'" + set page [source $fn] + $page configure -name $name \ + -parent_id $folder_id -package_id $id + if {![$page exists title]} { + $page set title $object + } + $page destroy_on_cleanup + $page set_content [string trim [$page text] " \n"] + $page initialize_loaded_object + set item_id [::Generic::CrItem lookup -name $name -parent_id $folder_id] + if {$item_id == 0} { + $page save_new + } else { + # get the page from the CR with all variables + set p [::Generic::CrItem instantiate -item_id $item_id] + $p destroy_on_cleanup + # copy all variables from the prototype page + # into the instantiated page + foreach v [$page info vars] {$p set $v [$page set $v]} + $p save + set page $p + } + } + if {[info exists via_url] && [my exists_query_parameter "return_url"]} { + my returnredirect [my query_parameter "return_url" [my package_url]] + } + return $page + } + + Package instproc call {object method} { + my instvar policy + #my log "--call enforce_permissions $object $method -> [$policy enforce_permissions $object $method]" + if {[$policy enforce_permissions $object $method]} { + #my log "--p calling $object ([$object info class]) '$method'" + $object $method + } else { + my log "not allowed to call $object $method" + } + } + Package instforward check_permissions {%my set policy} %proc + + Package instproc get_name_and_lang_from_path {path vlang vlocal_name} { + my upvar $vlang lang $vlocal_name local_name + if {[regexp {^pages/(..)/(.*)$} $path _ lang local_name]} { + } elseif {[regexp {^(..)/(.*)$} $path _ lang local_name]} { + } elseif {[regexp {^(..):(.*)$} $path _ lang local_name]} { + } elseif {[regexp {^(file|image|download)/(.*)$} $path _ lang local_name]} { + } else { + set key queryparm(lang) + if {[info exists $key]} { + set lang [set $key] + } else { + # we can't determine lang from name, or query parameter, so take default + set lang [my default_language] + } + set local_name $path + } + } + + Package instproc resolve_request {-path method_var} { + my instvar folder_id + #my log "--u [self args]" + [self class] instvar queryparm + set item_id 0 + + if {$path ne ""} { + + set item_id [::Generic::CrItem lookup -name $path -parent_id $folder_id] + my log "--try $path -> $item_id" + + if {$item_id == 0} { + my get_name_and_lang_from_path $path lang local_name + set name ${lang}:$local_name + set item_id [::Generic::CrItem lookup -name $name -parent_id $folder_id] + #my log "--try $name -> $item_id // ::Generic::CrItem lookup -name $name -parent_id $folder_id" + if {$item_id == 0 && $lang eq "download" + && [regexp {^([^/]+)/(.*)$} $local_name _ prefix base_name]} { + set item_id [::Generic::CrItem lookup -name ${prefix}:$base_name -parent_id $folder_id] + if {$item_id != 0} { + upvar $method_var method + set method download + } + } + if {$item_id == 0 && $lang eq "file"} { + set item_id [::Generic::CrItem lookup -name swf:$local_name -parent_id $folder_id] + if {$item_id == 0} { + set item_id [::Generic::CrItem lookup -name image:$local_name -parent_id $folder_id] + } + my log "--try image:$local_name -> $item_id" + } + if {$item_id == 0} { + set nname [my normalize_name $name] + set item_id [::Generic::CrItem lookup -name $nname -parent_id $folder_id] + my log "--try $nname -> $item_id" + } + } + } + if {$item_id != 0} { + set revision_id [my query_parameter revision_id 0] + set [expr {$revision_id ? "item_id" : "revision_id"}] 0 + #my log "--instantiate item_id $item_id revision_id $revision_id" + set r [::Generic::CrItem instantiate -item_id $item_id -revision_id $revision_id] + $r destroy_on_cleanup + #my log "--instantiate done CONTENT\n[$r serialize]" + $r set package_id [namespace tail [self]] + return $r + } else { + return "" + } + } + + Package instproc require_folder_object { } { + my instvar id folder_id + #my log "--f [my isobject ::$folder_id] folder_id=$folder_id" + + if {$folder_id == 0} { + # TODO: we should make a parameter allowed_page_types (see content_types), + # but the package admin should not have necessarily the rights to change it + set folder_id [::xowiki::Page require_folder \ + -name xowiki -package_id $id \ + -content_types ::xowiki::Page* ] + } + + if {![::xotcl::Object isobject ::$folder_id]} { + # if we can't get the folder from the cache, create it + if {[catch {eval [nsv_get xotcl_object_cache ::$folder_id]}]} { + while {1} { + set item_id [ns_cache eval xotcl_object_type_cache item_id-of-$folder_id { + set myid [CrItem lookup -name ::$folder_id -parent_id $folder_id] + if {$myid == 0} break; # don't cache ID if invalid + return $myid + }] + break + } + if {[info exists item_id]} { + # we have a valid item_id and get the folder object + #my log "--f fetch folder object -object ::$folder_id -item_id $item_id" + ::xowiki::Object fetch_object -object ::$folder_id -item_id $item_id + } else { + # we have no folder object yet. so we create one... + ::xowiki::Object create ::$folder_id + ::$folder_id set text "# this is the payload of the folder object\n\n\ + #set index_page \"index\"\n" + ::$folder_id set parent_id $folder_id + ::$folder_id set name ::$folder_id + ::$folder_id set title ::$folder_id + ::$folder_id set package_id $id + ::$folder_id set publish_status "production" + ::$folder_id save_new + ::$folder_id initialize_loaded_object + } + } + #my log "--f new folder object = ::$folder_id" + #::$folder_id proc destroy {} {my log "--f "; next} + ::$folder_id set package_id $id + ::$folder_id destroy_on_cleanup + } else { + #my log "--f reuse folder object $folder_id [::Serializer deepSerialize ::$folder_id]" + } + + my set folder_id $folder_id + } + + Package instproc return_page {-adp:required -variables -form} { + #my log "--vars=[self args]" + set __vars [list] + foreach _var $variables { + if {[llength $_var] == 2} { + lappend __vars [lindex $_var 0] [uplevel subst [lindex $_var 1]] + } else { + set localvar local.$_var + upvar $_var $localvar + if {[array exists $localvar]} { + lappend __vars &$_var $localvar + } elseif {[info exists $localvar]} { + # ignore undefined variables + lappend __vars $_var [set $localvar] + } + } + } + + if {[info exists form]} { + set level [template::adp_level] + foreach f [uplevel #$level info vars ${form}:*] { + lappend __vars &$f $f + upvar #$level $f $f + } + } + #my log "--before adp" ; # $__vars + set text [template::adp_include $adp $__vars] + + if { [lang::util::translator_mode_p] } { + set text [::xo::localize $text 1] + } + #my log "--after adp" + return $text + } + + + + ############################################################### + # + # user callable methods on package level + # + + Package ad_instproc reindex {} { + reindex all items of this package + } { + my instvar folder_id + set pages [db_list [my qn get_pages] "select page_id from xowiki_page, cr_revisions r, cr_items ci \ + where page_id = r.revision_id and ci.item_id = r.item_id and ci.parent_id = $folder_id \ + and ci.live_revision = page_id"] + #my log "--reindex returns <$pages>" + foreach page_id $pages { + #search::queue -object_id $page_id -event DELETE + search::queue -object_id $page_id -event INSERT + } + } + + # + # Package import + # + + Package ad_instproc import {-user_id -folder_id {-replace 0} -objects} { + import the specified pages into the xowiki instance + } { + set package_id [my id] + if {![info exists folder_id]} {set folder_id [my folder_id]} + if {![info exists user_id]} {set user_id [::xo::cc user_id]} + if {![info exists objects]} {set objects [::xowiki::Page allinstances]} + + set msg "processing objects: $objects

      " + set added 0 + set replaced 0 + set updated 0 + + foreach o $objects { + $o demarshall -parent_id $folder_id -package_id $package_id -creation_user $user_id + + # page instances have references to page templates, add these first + if {[$o istype ::xowiki::PageInstance]} continue + + set item_id [CrItem lookup -name [$o set name] -parent_id $folder_id] + if {$item_id != 0} { + if {$replace} { ;# we delete the original + ::Generic::CrItem delete -item_id $item_id + set item_id 0 + incr replaced + } else { + ::Generic::CrItem instantiate -item_id $item_id + $item_id copy_content_vars -from_object $o + $item_id save + incr updated + } + } + if {$item_id == 0} { + set n [$o save_new] + incr added + } + } + + foreach o $objects { + if {[$o istype ::xowiki::PageInstance]} { + set old_template_id [$o set page_template] + set template_id [CrItem lookup \ + -name [::$old_template_id set name] \ + -parent_id $folder_id] + db_transaction { + set item_id [CrItem lookup -name [$o set name] -parent_id $folder_id] + if {$item_id != 0} { + if {$replace} { ;# we delete the original + ::Generic::CrItem delete -item_id $item_id + set item_id 0 + incr replaced + } else { + ::Generic::CrItem instantiate -item_id $item_id + $item_id copy_content_vars -from_object $o + $item_id set page_template $template_id + $item_id save + incr updated + } + } + if {$item_id == 0} { ;# the item does not exist -> update reference and save + $o set page_template $template_id + $o save_new + incr added + } + } + } + } + foreach o $objects {$o destroy} + append msg "$added objects newly inserted, $updated objects updated, $replaced objects replaced

      " + } + + # + # RSS 2.0 support + # + Package ad_instproc rss { + -maxentries + -name_filter + -entries_of + -title + -days + } { + Report content of xowiki folder in rss 2.0 format. The + reporting order is descending by date. The title of the feed + is taken from the title, the description + is taken from the description field of the folder object. + + @param maxentries maximum number of entries retrieved + @param days report entries changed in speficied last days + + } { + set package_id [my id] + set folder_id [$package_id folder_id] + if {![info exists namefilter]} { + set name_filter [my get_parameter name_filter ""] + } + if {![info exists entries_of]} { + set entries_of [my get_parameter entries_of ""] + } + if {![info exists title]} { + set title [my get_parameter title ""] + if {$title eq ""} { + set title [::$folder_id set title] + } + } + + if {![info exists days] && + [regexp {[^0-9]*([0-9]+)d} [my query_parameter rss] _ days]} { + # setting the variable days + } else { + set days 10 + } + + set r [RSS new -destroy_on_cleanup \ + -package_id [my id] \ + -name_filter $name_filter \ + -entries_of $entries_of \ + -title $title \ + -days $days] + + #set t text/plain + set t text/xml + ns_return 200 $t [$r render] + } + + # + # Google sitemap support + # + + Package ad_instproc google-sitemap { + {-max_entries ""} + {-changefreq "daily"} + {-priority "0.5"} + } { + Report content of xowiki folder in google site map format + https://www.google.com/webmasters/sitemaps/docs/en/protocol.html + + @param maxentries maximum number of entries retrieved + @param package_id to determine the xowiki instance + @param changefreq changefreq as defined by google + @param priority priority as defined by google + + } { + set package_id [my id] + set folder_id [::$package_id folder_id] + + set timerange_clause "" + + set content { + +} + + set sql [::xo::db::sql select \ + -vars "s.body, p.name, p.creator, p.title, p.page_id,\ + p.object_type as content_type, p.last_modified, p.description" \ + -from "xowiki_pagex p, syndication s, cr_items ci" \ + -where "ci.parent_id = $folder_id and ci.live_revision = s.object_id \ + and s.object_id = p.page_id $timerange_clause" \ + -orderby "p.last_modified desc" \ + -limit $max_entries] + my log $sql + db_foreach [my qn get_pages] $sql { + #my log "--found $name" + if {[string match "::*" $name]} continue + if {$content_type eq "::xowiki::PageTemplate::"} continue + + set time [::xo::db::tcl_date $last_modified tz] + set time "[clock format [clock scan $time] -format {%Y-%m-%dT%T}]${tz}:00" + + append content \n\ + [::$package_id pretty_link -absolute true $name] \n\ + $time \n\ + $changefreq \n\ + $priority \n\ + \n + } + + append content \n + #set t text/plain + set t text/xml + ns_return 200 $t $content + } + + Package ad_proc google-sitemapindex { + {-changefreq "daily"} + {-priority "priority"} + } { + Provide a sitemap index of all xowiki instances in google site map format + https://www.google.com/webmasters/sitemaps/docs/en/protocol.html + + @param maxentries maximum number of entries retrieved + @param package_id to determine the xowiki instance + @param changefreq changefreq as defined by google + @param priority priority as defined by google + + } { + + set content { + +} + foreach package_id [::xowiki::Package instances] { + set last_modified [db_string [my qn get_newest_modification_date] \ + "select last_modified from acs_objects where package_id = $package_id \ + order by last_modified desc limit 1"] + + set time [::xo::db::tcl_date $last_modified tz] + set time "[clock format [clock scan $time] -format {%Y-%m-%dT%T}]${tz}:00" + + #my log "--site_node::get_from_object_id -object_id $package_id" + array set info [site_node::get_from_object_id -object_id $package_id] + + append content \n\ + [ad_url]$info(url)?google-sitemap \n\ + $time \n\ + + } + append content \n + #set t text/plain + set t text/xml + ns_return 200 $t $content + } + + Package instproc google-sitemapindex {} { + [self class] [self proc] + } + + Package instproc edit-new {} { + my instvar folder_id id + set object_type [my query_parameter object_type "::xowiki::Page"] + set autoname [my get_parameter autoname 0] + set page [$object_type new -volatile -parent_id $folder_id -package_id $id] + $page set name "" + return [$page edit -new true -autoname $autoname] + } + + Package instproc flush_references {-item_id:integer,required -name} { + my instvar folder_id id + if {$name eq "::$folder_id"} { + #my log "--D deleting folder object ::$folder_id" + ns_cache flush xotcl_object_cache ::$folder_id + ns_cache flush xotcl_object_type_cache item_id-of-$folder_id + ns_cache flush xotcl_object_type_cache root_folder-$id + ::$folder_id destroy + } + set key link-*-$name-$folder_id + foreach n [ns_cache names xowiki_cache $key] {ns_cache flush xowiki_cache $n} + } + + Package instproc delete {-item_id -name} { + # + # This delete method does not require an instanantiated object, + # while the class-specific delete methods in xowiki-procs need these. + # If a (broken) object can't be instantiated, it cannot be deleted. + # Therefore we need this package level delete method. + # While the class specific methods are used from the + # application pages, the package_level method is used from the admin pages. + # + my instvar folder_id id + if {![info exists item_id]} { + set item_id [my query_parameter item_id] + #my log "--D item_id from query parameter $item_id" + set name [my query_parameter name] + } + if {$item_id ne ""} { + #my log "--D trying to delete $item_id $name" + set object_type [::Generic::CrItem get_object_type -item_id $item_id] + # in case of PageTemplate and subtypes, we need to check + # for pages using this template + set classes [concat $object_type [$object_type info heritage]] + if {[lsearch $classes "::xowiki::PageTemplate"] > -1} { + set count [::xowiki::PageTemplate count_usages -item_id $item_id] + if {$count > 0} { + return [$id error_msg \ + [_ xowiki.error-delete_entries_first [list count $count]]] + } + } + $object_type delete -item_id $item_id + my flush_references -item_id $item_id -name $name + } else { + my log "--D nothing to delete!" + } + my returnredirect [my query_parameter "return_url" [$id package_url]] + } + + # + # policy management + # + + Package instproc condition=has_class {query_context value} { + return [expr {[$query_context query_parameter object_type ""] eq $value}] + } + + + Class create Policy -superclass ::xo::Policy + + Policy policy1 -contains { + + Class Package -array set require_permission { + reindex swa + import_prototype_page swa + rss none + google-sitemap none + google-sitemapindex none + delete {{id admin}} + edit-new {{{has_class ::xowiki::Object} id admin} {id create}} + } + + Class Page -array set require_permission { + view none + revisions {{package_id write}} + diff {{package_id write}} + edit {{package_id write}} + save-form-data {{package_id write}} + make-live-revision {{package_id write}} + delete-revision {{package_id admin}} + delete {{package_id admin}} + save-tags login + popular-tags login + create-new {{item_id write}} + } -set default_permission {{package_id write}} + + Class Object -array set require_permission { + edit {{package_id admin}} + } + Class File -array set require_permission { + download none + } + Class Form -array set require_permission { + create-new {{item_id write}} + list {{package_id read}} + } + } + + Policy policy2 -contains { + # + # we require side wide admin rights for deletions and code + # + + Class Package -array set require_permission { + reindex {{id admin}} + rss none + google-sitemap none + google-sitemapindex none + delete swa + edit-new {{{has_class ::xowiki::Object} swa} {id create}} + } + + Class Page -array set require_permission { + view {{package_id read}} + revisions {{package_id write}} + diff {{package_id write}} + edit {{package_id write}} + make-live-revision {{package_id write}} + delete-revision swa + delete swa + save-tags login + popular-tags login + } + + Class Object -array set require_permission { + edit swa + } + Class File -array set require_permission { + download {{package_id read}} + } + } + + Policy policy3 -contains { + # + # we require side wide admin rights for deletions + # we perform checking on item_ids for pages. + # + + Class Package -array set require_permission { + reindex {{id admin}} + rss none + google-sitemap none + google-sitemapindex none + delete swa + edit-new {{{has_class ::xowiki::Object} swa} {id create}} + } + + Class Page -array set require_permission { + view {{item_id read}} + revisions {{item_id write}} + diff {{item_id write}} + edit {{item_id write}} + make-live-revision {{item_id write}} + delete-revision swa + delete swa + save-tags login + popular-tags login + } + + Class Object -array set require_permission { + edit swa + } + Class File -array set require_permission { + download {{package_id read}} + } + } + + Policy policy4 -contains { + ::xotcl::Object function -array set require_permission { + f none + } -set default_permission login + } + + #my log "--set granted [policy4 check_permissions -user_id 0 -package_id 0 function f]" +} + + + Index: openacs-4/packages/xowiki/tcl/syndicate-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/syndicate-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/syndicate-procs.tcl 1 Aug 2007 21:39:24 -0000 1.19.2.2 @@ -0,0 +1,375 @@ +namespace eval ::xowiki { + # + # RSS 2.0 support + # + Class XMLSyndication -parameter {package_id} + + XMLSyndication instproc init {} { + my set xmlMap [list & "&" < "<" > ">" \" """ ' "'"] + } + + XMLSyndication instproc tag {{-atts } name value} { + my instvar xmlMap + set attsXML "" + if {[info exists atts]} { + foreach {attName attValue} $atts { + append attsXML " $attName='[string map [list ' {'} { } { }] $attValue]'" + } + } + return <$name$attsXML>[string map $xmlMap $value] + } + + Class RSS -superclass XMLSyndication -parameter { + maxentries + {name_filter ""} + {entries_of ""} + {days ""} + {css ""} + {siteurl "[ad_url]"} + {description ""} + {language en-us} + {title ""} + } \ + -ad_doc { + Report content of xowiki folder in rss 2.0 format. The + reporting order is descending by date. The title of the feed + is taken from the title, the description + is taken from the description field of the folder object. + + @param maxentries maximum number of entries retrieved + @param days report entries changed in speficied last days + @param name_filter include only pages matching the provided regular expression (postgres) + } + + RSS instproc css_link {} { + my instvar css + if {$css ne ""} { + # + # firefox 2.0 appears to overwrite the style info, so one has to use such ugly tricks: + # http://www.blingblog.info/2006/10/30/firefox-big-browser/ + # when we want to use custom style sheets + # + set user_agent [string tolower [ns_set get [ns_conn headers] User-Agent]] + set filler [expr {[string first firefox $user_agent] >- 1 ? + "" : "" + }] + set css_link [expr {[string match /* $css] ? $css : "/resources/xowiki/$css"}] + return "\n\n$filler" + } + return "" + } + + RSS instproc head {} { + my instvar title link description language + return "[my css_link] + + + [my tag title $title] + [my tag link $link] + [my tag description $description] + [my tag language $language] + [my tag generator xowiki]" + } + + RSS instproc item {-creator -title -link -guid -description -pubdate } { + append result \n\ + [my tag dc:creator $creator ] \n\ + [my tag title $title ] \n\ + [my tag link $link ] \n\ + [my tag -atts {isPermaLink false} guid $guid] \n\ + [my tag description $description ] \n\ + [my tag pubDate $pubdate ] \n\ + \n + } + + RSS instproc tail {} { + return "\n\n\n" + } + + + RSS instproc limit {} { + my instvar maxentries + if {[info exists maxentries] && $maxentries ne ""} { + return $maxentries + } + return "" + } + + RSS instproc extra_where_clause {} { + my instvar name_filter days entries_of package_id + set extra_where_clause "" + if {$name_filter ne ""} { + append extra_where_clause " and ci.name ~ E'$name_filter' " + } + if {$days ne ""} { + append extra_where_clause "and " \ + [::xo::db::sql since_interval_condition p.last_modified "$days days"] + } + if {$entries_of ne ""} { + set form_items [list] + set folder_id [$package_id folder_id] + foreach t [split $entries_of |] { + set form_item_id [::xowiki::Form lookup -name $t -parent_id $folder_id] + if {$form_item_id == 0} {error "Cannot lookup page $t"} + lappend form_items $form_item_id + } + append extra_where_clause " and p.page_template in ('[join $form_items ',']') and p.page_instance_id = p.revision_id " + + my set base_table xowiki_form_pagex + } + return $extra_where_clause + } + + RSS instproc render {} { + my instvar package_id max_entries name_filter title days description siteurl base_table + set folder_id [::$package_id folder_id] + + if {$description eq ""} {set description [::$folder_id set description]} + my set link $siteurl[site_node::get_url_from_object_id -object_id $package_id] + + set base_table xowiki_pagex + set extra_where_clause [my extra_where_clause] + + if {$base_table ne "xowiki_pagex"} { + # we assume, we retrieve the entries for a form + set extra_from "" + } else { + # return always instance_attributes + set extra_from "left join \ + xowiki_page_instance on (p.revision_id = page_instance_id)" + } + + set sql [::xo::db::sql select \ + -vars "s.body, p.name, p.creator, p.title, p.page_id, instance_attributes, \ + p.object_type as content_type, p.last_modified, p.description" \ + -from "syndication s, cr_items ci, $base_table p $extra_from" \ + -where "ci.parent_id = $folder_id and ci.live_revision = s.object_id \ + and ci.publish_status <> 'production' \ + $extra_where_clause \ + and s.object_id = p.page_id" \ + -orderby "p.last_modified desc" \ + -limit [my limit]] + + set content [my head] + db_foreach get_pages $sql { + if {[string match "::*" $name]} continue + if {$content_type eq "::xowiki::PageTemplate"} continue + + set description [string trim $description] + if {$description eq ""} {set description $body} + if {$title eq ""} {set title $name} + set time [::xo::db::tcl_date $last_modified tz] + set link [::xowiki::Portlet detail_link \ + -package_id $package_id -name $name \ + -absolute true \ + -instance_attributes $instance_attributes] + + #append title " ($content_type)" + set time "[clock format [clock scan $time] -format {%a, %d %b %Y %T}] ${tz}00" + append content [my item \ + -creator $creator \ + -title $title \ + -link $link \ + -guid $siteurl/$page_id \ + -description $description \ + -pubdate $time \ + ] + } + + append content [my tail] + return $content + } + + Class Podcast -superclass RSS -parameter { + {subtitle ""} + {description ""} + {summary ""} + {author ""} + {explicit "no"} + } + + + Podcast instproc head {} { + my instvar title link description language subtitle summary author explicit + + return "[my css_link] + + + [my tag title $title] + [my tag link $link] + [my tag description $description] + [my tag language $language] + [my tag generator xowiki] + [my tag itunes:subtitle $subtitle] + [my tag itunes:summary $summary] + [my tag itunes:author $author] + [my tag itunes:explicit $explicit] +" + } + + Podcast instproc item { + -author -title -subtitle -description + -link -guid -pubdate + -mime_type -duration -keywords} { + append result \n \ + [my tag title $title] \n\ + [my tag link $link ] \n\ + [my tag -atts {isPermaLink true} guid $guid] \n\ + [my tag pubDate $pubdate] \n\ + [my tag itunes:duration $duration] \n\ + [my tag author $author ] \n\ + [my tag description $description ] \n\ + [my tag itunes:subtitle $subtitle ] \n\ + [my tag itunes:author $author ] \n\ + [my tag itunes:keywords $keywords ] \n\ + " " \ + \n \n + } + + + Podcast instproc render {} { + my instvar package_id max_entries name_filter title days \ + summary subtitle description author siteurl + + set folder_id [::$package_id folder_id] + if {$description eq ""} {set description [::$folder_id set description]} + if {$summary eq ""} {set summary $description} + if {$subtitle eq ""} {set subtitle $title} + + my set link $siteurl[site_node::get_url_from_object_id -object_id $package_id] + + set content [my head] + set sql [::xo::db::sql select \ + -vars * \ + -from "xowiki_podcast_itemi p, cr_items ci, cr_mime_types m" \ + -where "ci.parent_id = $folder_id and ci.item_id = p.item_id \ + and ci.live_revision = p.object_id \ + and p.mime_type = m.mime_type \ + and ci.publish_status <> 'production' [my extra_where_clause]" \ + -orderby "p.pub_date asc" \ + -limit [my limit]] + + db_foreach get_pages $sql { + if {$content_type ne "::xowiki::PodcastItem"} continue + if {$title eq ""} {set title $name} + set link [::$package_id pretty_link -download true -absolute true -siteurl $siteurl $name] + append content [my item \ + -author $creator -title $title -subtitle $subtitle \ + -description $description \ + -link $link -mime_type $mime_type \ + -guid $link -pubdate $pub_date -duration $duration \ + -keywords $keywords] + } + + append content [my tail] + return $content + } + + Class Timeline -superclass XMLSyndication \ + -parameter {user_id {limit 1000}} + + Timeline instproc reverse list { + set result [list] + for {set i [expr {[llength $list] - 1}]} {$i >= 0} {incr i -1} { + lappend result [lindex $list $i] + } + return $result + } + + Timeline instproc render {} { + my instvar package_id + set folder_id [::$package_id folder_id] + set where_clause "" + set limit "" + + set last_user "" + set last_item "" + set last_clock "" + if {[my exists user_id]} { append where_clause " and o.creation_user = [my user_id] " } + if {[my exists limit]} { set limit [my limit] } + + ::xo::OrderedComposite items -destroy_on_cleanup + set sql [::xo::db::sql select \ + -vars "ci.name, o.creation_user, cr.publish_date, o2.creation_date, \ + cr.item_id, ci.parent_id, cr.title" \ + -from "cr_items ci, cr_revisions cr, acs_objects o, acs_objects o2" \ + -where "cr.item_id = ci.item_id and o.object_id = cr.revision_id + and o2.object_id = cr.item_id + and ci.parent_id = :folder_id and o.creation_user is not null + $where_clause" \ + -orderby "revision_id desc" \ + -limit $limit] + db_foreach get_pages $sql { + set publish_date [::xo::db::tcl_date $publish_date tz] + set creation_date [::xo::db::tcl_date $creation_date tz] + set clock [clock scan $publish_date] + + if {$last_user == $creation_user && $last_item == $item_id && $last_clock ne ""} { + #my log "--clockdiff = [expr {$last_clock - $clock }] $name [clock format $clock -format {%b %d %Y %X %Z} -gmt true]" + if {($last_clock - $clock) < 7500 } { + #my log "--clock ignore change due to cockdiff" + continue + } + } + set o [Object new] + foreach att {item_id creation_user item_id clock name publish_date parent_id title} { + $o set $att [set $att] + } + $o set operation [expr {$creation_date eq $publish_date ? "created" : "modified"}] + + items add $o + foreach {last_user last_item last_clock} [list $creation_user $item_id $clock] break + } + + # The following loop tries to distinguis between create and modify by age. + # This does not work in cases, where we get just a limited amount + # or restricted entries +# if {$limit eq ""} { +# foreach i [my reverse [items children]] { +# set key seen([$i set item_id]) +# if {[info exists $key]} { +# $i set operation modified +# } else { +# $i set operation created +# set $key 1 +# } +# } +# } + + foreach i [items children] { + set key contrib([clock format [$i set clock] -format "%Y-%m-%d" -gmt true],[$i set creation_user],[$i set item_id]) + lappend $key $i + } + + set result \n + + foreach c [lsort -decreasing [array names contrib]] { + if {[llength $contrib($c)] == 1} { + set i $contrib($c) + set title [$i set title] + set user [::xo::get_user_name [$i set creation_user]] + set event "$user [$i set operation] [$i set title] [$i set name]" + } else { + set i [lindex $contrib($c) 0] + set event "Contributions by [::xo::get_user_name [$i set creation_user]] on [clock format [$i set clock] -format {%b %d %Y} -gmt true]\n

        " + set title "[$i set title] ([llength $contrib($c)])" + foreach j $contrib($c) { + set stamp [clock format [$j set clock] -format "%X %Z" -gmt true] + append event "
      • $stamp: [$j set operation]
      • " \n + } + append event "
      " \n + } + set stamp [clock format [$i set clock] -format "%b %d %Y %X %Z" -gmt true] + set user [::xo::get_user_name [$i set creation_user]] + append result [my tag -atts [list \ + start $stamp \ + title $title \ + link [$package_id pretty_link [$i set name]]] \ + event $event] \n + } + append result \n + return $result + } +} Index: openacs-4/packages/xowiki/tcl/template-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/template-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/template-procs.tcl 1 Aug 2007 21:39:24 -0000 1.1.2.2 @@ -0,0 +1,53 @@ +### +### just for backward compatibility for oacs 5.1 -gustaf neumann +### + +if {[apm_version_names_compare [ad_acs_version] 5.2] <= -1} { + + +ad_proc -public ::template::adp_include { + {-uplevel 1} + src + varlist +} { + return a the output of a tcl/adp pair as a string. adp_level is + set to the calling procedure so that pass by reference works. + and example of using this is in the search indexer for various content + types: +
      +    bookshelf::book::get -book_id $book_id -array bookdata
      +    set body [template::adp_include /packages/bookshelf/lib/one-book \ 
      +                  [list &book "bookdata" base $base style feed]]
      +  
      + + The [list &book "bookdata" ...] tells adp_include to pass the book array by reference to the adp in +clude, where it is + refered to via @book.field@. + + @param uplevel how far up the stack should the adp_level be set to + (default is the calling procedures level) + @param src should be the path to the tcl/adp pair relative to the server root, as + with the src attribute to the include tag. + @param varlist a list of {key value key value ... } varlist can also be &var foo + for things passed by reference (arrays and multirows) + + @return the string generated by the tcl/adp pair. + + @author Jeff Davis davis@xarg.net + @creation-date 2004-06-02 + + @see template::adp_parse +} { + # set the stack frame at which the template is being parsed so that + # other procedures can reference variables cleanly + variable parse_level + lappend parse_level [expr [info level] - $uplevel] + + set __adp_out [template::adp_parse [template::util::url_to_file $src] $varlist] + + # pop off parse level + template::util::lpop parse_level + + return $__adp_out +} +} \ No newline at end of file Index: openacs-4/packages/xowiki/tcl/weblog-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/weblog-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/weblog-procs.tcl 1 Aug 2007 21:39:24 -0000 1.19.2.2 @@ -0,0 +1,276 @@ +namespace eval ::xowiki { + # + # ::xowiki::Weblog + # + + Class create ::xowiki::Weblog -parameter { + package_id + {page_size 20} + {page_number ""} + date + tag + ptag + category_id + {entries_of ""} + filter_msg + {sort_composite ""} + {no_footer false} + {name_filter ""} + {entry_label "Postings"} + {exclude_item_ids 0} + {summary false} + {summary_chars 150} + {entry_renderer ::xowiki::Weblog::Entry} + {entry_flag} + } + + ::xowiki::Weblog instproc init {} { + my instvar filter_msg package_id nr_items next_page_link prev_page_link + my instvar date category_id tag ptag page_number page_size summary items + my instvar name_filter entry_label entries_of sort_composite summary_chars + + my log "--W starting" + set folder_id [::$package_id set folder_id] + set filter_msg "" + set query_parm "" + + # set up filters + set extra_from_clause "" + set extra_where_clause "" + + if {$date ne ""} { + #set date_clause "and date_trunc('day',p.publish_date) = '$date'" + set date_clause "and [::xo::db::sql date_trunc_expression day p.publish_date $date]" + set filter_msg "Filtered by date $date" + set query_parm "&date=$date" + } else { + set date_clause "" + } + if {$category_id ne ""} { + set cnames [list] + #append extra_where_clause "and c.object_id = ci.item_id and c.category_id = $category_id " + #append extra_from_clause ",category_object_map c " + foreach cid [split $category_id ,] { + append extra_where_clause "and exists (select * from category_object_map \ + where object_id = ci.item_id and category_id = $cid)" + lappend cnames [::category::get_name $cid] + } + append extra_from_clause "" + set filter_msg "Filtered by category [join $cnames {, }]" + set query_parm "&category_id=$category_id" + } + if {$tag ne ""} { + set filter_msg "Filtered by your tag $tag" + append extra_from_clause ",xowiki_tags tags " + append extra_where_clause "and tags.item_id = ci.item_id and tags.tag = :tag and \ + tags.user_id = [::xo::cc user_id]" + set query_parm "&tag=[ad_urlencode $tag]" + } + if {$ptag ne ""} { + set filter_msg "Filtered by popular tag $ptag" + append extra_from_clause ",xowiki_tags tags " + append extra_where_clause "and tags.item_id = ci.item_id and tags.tag = :ptag " + set query_parm "&ptag=[ad_urlencode $ptag]" + } + if {$name_filter ne ""} { + append extra_where_clause "and ci.name ~ E'$name_filter' " + } + set base_type ::xowiki::Page + set base_table xowiki_pagei + set attributes [list cr.revision_id p.publish_date p.title p.creator p.creation_user \ + p.description s.body pi.instance_attributes] + if {$entries_of ne ""} { + set form_items [list] + foreach t [split $entries_of |] { + set form_item_id [::xowiki::Form lookup -name $t -parent_id $folder_id] + if {$form_item_id == 0} {error "Cannot lookup page $t"} + lappend form_items $form_item_id + } + append extra_where_clause " and p.page_template in ('[join $form_items ',']') and p.page_instance_id = cr.revision_id " + set base_type ::xowiki::FormPage + set base_table xowiki_form_pagei + } + + # create an item container, which delegates rendering to its children + set items [::xo::OrderedComposite new -proc render {} { + set content "" + foreach c [my children] { append content [$c render] } + return $content + }] + + foreach i [split [my exclude_item_ids] ,] {lappend ::xowiki_page_item_id_rendered $i} + $items set weblog_obj [self] + + set sql \ + [list -folder_id $folder_id \ + -select_attributes $attributes \ + -orderby "publish_date desc" \ + -from_clause "$extra_from_clause, $base_table p \ + left outer join syndication s on s.object_id = p.revision_id \ + left join xowiki_page_instance pi on (p.revision_id = pi.page_instance_id)" \ + -where_clause "ci.item_id not in ([my exclude_item_ids]) \ + and ci.name != '::$folder_id' and ci.name not like '%weblog%' $date_clause \ + [::xowiki::Page container_already_rendered ci.item_id] \ + and ci.content_type not in ('::xowiki::PageTemplate','::xowiki::Object') \ + and ci.publish_status <> 'production' \ + and p.revision_id = cr.revision_id \ + $extra_where_clause" ] + + if {$page_number ne ""} { + lappend sql -page_number $page_number -page_size $page_size + } + + set nr_items [db_string count [eval $base_type instance_select_query $sql -count true]] + #my msg count=$nr_items + #my msg sql=$sql + set s [$base_type instantiate_objects -sql [eval $base_type instance_select_query $sql]] + + foreach c [$s children] { + $c instvar revision_id publish_date title name item_id creator creation_user \ + description body instance_attributes + + set time [::xo::db::tcl_date $publish_date tz] + set pretty_date [util::age_pretty -timestamp_ansi $time \ + -sysdate_ansi [clock_to_ansi [clock seconds]] \ + -mode_3_fmt "%d %b %Y, at %X"] + + if {$summary} { + # we need always: package_id item_id name title creator creation_user pretty_date + set p [Page new -package_id $package_id -item_id $item_id \ + -name $name -title $title -creator $creator] + $p set creation_user $creation_user + $p set description [expr {$description eq "" && $body ne ""? \ + "[string range $body 0 $summary_chars]..." : $description}] + $p set instance_attributes $instance_attributes + } else { + # do full instantiation and rendering + # ns_log notice "--Render object revision_id = $revision_id $name $title ::$revision_id?[my isobject ::$revision_id]" + set p [::Generic::CrItem instantiate -item_id 0 -revision_id $revision_id] + # in cases, the revision was created already earlier, drop the mixins + if {[$p info mixin] ne ""} {$p mixin {}} + if {[my exists entry_flag]} {$p set [my entry_flag] 1} + if {[my no_footer]} {$p set __no_footer 1} + if {[catch {$p set description [$p render]} errorMsg]} { + set description "Render Error ($errorMsg) $revision_id $name $title" + } + if {[my exists entry_flag]} {$p unset [my entry_flag]} + #my log "--W $p render (mixins=[$p info mixin]) => $description" + } + $p set pretty_date $pretty_date + $p set publish_date $publish_date + #my log "--W setting $p set publish_date $publish_date" + #$p proc destroy {} {my log "--Render temporal object destroyed"; next} + #ns_log notice "--W Render object $p DONE $revision_id $name $title " + $p mixin add [my set entry_renderer] + #my log "--W items=$items, added mixin [my set entry_renderer] to $p, has now <[$p info mixin]>" + $items add $p + } + + array set smsg {1 full 0 summary} + set flink "$smsg($summary)" + + if {$page_number ne ""} { + set nr [llength [$items children]] + set from [expr {($page_number-1)*$page_size+1}] + set to [expr {($page_number-1)*$page_size+$nr}] + set range [expr {$nr > 1 ? "$from - $to" : $from}] + + if {$filter_msg ne ""} { + append filter_msg ", $range of $nr_items $entry_label (all, $flink)" + } else { + append filter_msg "Showing $range of $nr_items $entry_label ($flink)" + } + + set next_p [expr {$nr_items > $page_number*$page_size}] + set prev_p [expr {$page_number > 1}] + + if {$next_p} { + set query [::xo::update_query_variable [ns_conn query] page_number [expr {$page_number+1}]] + set next_page_link [export_vars -base [::xo::cc url] $query] + } + if {$prev_p} { + set query [::xo::update_query_variable [ns_conn query] page_number [expr {$page_number-1}]] + set prev_page_link [export_vars -base [::xo::cc url] $query] + } + } + #my proc destroy {} {my log "--W"; next} + + if {$sort_composite ne ""} { + foreach {kind att direction} [split $sort_composite ,] break + if {$kind eq "method"} {$items mixin add ::xo::OrderedComposite::MethodCompare} + $items orderby -order [expr {$direction eq "asc" ? "increasing" : "decreasing"}] $att + } + my log "--W done" + } + + ::xowiki::Weblog instproc render {} { + #my log "--W begin" + my instvar items + # + # We need the following CSS file for rendering + # + ::xowiki::Page requireCSS "/resources/xowiki/weblog.css" + + $items set entry_renderer [my entry_renderer] + set content [$items render] + $items destroy_on_cleanup + #my log "--W end" + return $content + } + + proc ::xo::update_query_variable {old_query var value} { + set query [list [list $var $value]] + foreach pair [split $old_query &] { + foreach {key value} [split $pair =] break + if {$key eq $var} continue + lappend query [list [ns_urldecode $key] [ns_urldecode $value]] + } + return $query + } + + # default layout for weblog entries + Class create ::xowiki::Weblog::EntryRenderer -instproc render {} { + my instvar package_id name title creator creation_user pretty_date description + [my set __parent] instvar weblog_obj + + set link [::$package_id pretty_link $name] + set more [expr {[$weblog_obj summary] ? + " \[#xowiki.weblog-more#\]" : ""}] + append more "

      " + + append content "
      " \ + "

      $title

      " \ + "

      Created by $creator, " \ + "last modfied by [::xo::get_user_name $creation_user] " \ + "$pretty_date

      " \ + $description $more \n\ + "
      " + } + + + # Default layout for weblog + Class create ::xowiki::Weblog::WeblogRenderer -instproc render {} { + my instvar filter_msg link name prev_page_link next_page_link + + set filter "" + set prev "" + set next "" + + if {[info exists filter_msg]} { + set filter "
      $filter_msg
      " + } + if {[info exists prev_page_link]} { + set prev "\ + Previous Page" + } + if {[info exists next_page_link]} { + set next "\ + Next Page" + } + return "
      $filter [next] $prev $next
      " + } + + +} Index: openacs-4/packages/xowiki/tcl/xowiki-cache-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-cache-init.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/xowiki-cache-init.tcl 1 Aug 2007 21:39:24 -0000 1.1.2.2 @@ -0,0 +1,3 @@ + +ns_cache create xowiki_cache -size 200000 +# [ad_parameter -package_id [ad_acs_kernel_id] MaxSize memoize 200000] Index: openacs-4/packages/xowiki/tcl/xowiki-callback-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-callback-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/xowiki-callback-procs.tcl 1 Aug 2007 21:39:24 -0000 1.30.2.2 @@ -0,0 +1,390 @@ +ad_library { + XoWiki - Notification procs + + @creation-date 2006-08-08 + @author Gustaf Neumann + @cvs-id $Id: xowiki-callback-procs.tcl,v 1.30.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki { + + ad_proc -private ::xowiki::after-install {} { + ::xowiki::sc::register_implementations + ::xowiki::notifications-install + } + + ad_proc -private ::xowiki::before-uninstall {} { + ::xowiki::sc::unregister_implementations + ::xowiki::notifications-uninstall + + # Unregister all types from all folders + ::xowiki::Page folder_type_unregister_all + + # Delete object types + foreach type [::xowiki::Page object_types -subtypes_first true] { + ::xo::db::sql::content_type drop_type -content_type $type \ + -drop_children_p t -drop_table_p t -drop_objects_p t + } + } + + + # + # upgrade logic + # + + ad_proc ::xowiki::upgrade_callback { + {-from_version_name:required} + {-to_version_name:required} + } { + + Callback for upgrading + + @author Gustaf Neumann (neumann@wu-wien.ac.at) + } { + ns_log notice "-- UPGRADE $from_version_name -> $to_version_name" + + if {$to_version_name eq "0.13"} { + ns_log notice "-- upgrading to 0.13" + set package_id [::Generic::package_id_from_package_key xowiki] + set folder_id [::xowiki::Page require_folder \ + -package_id $package_id \ + -content_types ::xowki::Page* \ + -name xowiki] + set r [::CrWikiPage instantiate_all -folder_id $folder_id] + db_transaction { + array set map { + ::CrWikiPage ::xowiki::Page + ::CrWikiPlainPage ::xowiki::PlainPage + ::PageTemplate ::xowiki::PageTemplate + ::PageInstance ::xowiki::PageInstance + } + foreach e [$r children] { + set oldClass [$e info class] + if {[info exists map($oldClass)]} { + set newClass $map($oldClass) + #ns_log notice "-- old class [$e info class] -> $newClass, fetching [$e set item_id] " + [$e info class] fetch_object -object $e -item_id [$e set item_id] + set oldtitle [$e set title] + $e append title " (old)" + $e save + $e class $newClass + $e set title $oldtitle + $e set name $oldtitle + $e save_new + } else { + ns_log notice "-- no new class for $oldClass" + } + } + } + } + + if {[apm_version_names_compare $from_version_name "0.19"] == -1 && + [apm_version_names_compare $to_version_name "0.19"] > -1} { + ns_log notice "-- upgrading to 0.19" + ::xowiki::sc::register_implementations + } + + if {[apm_version_names_compare $from_version_name "0.21"] == -1 && + [apm_version_names_compare $to_version_name "0.21"] > -1} { + ns_log notice "-- upgrading to 0.21" + if {![attribute::exists_p ::xowiki::Page page_title]} { + ::xo::db::sql::content_type create_attribute \ + -content_type ::xowiki::Page \ + -attribute_name page_title \ + -datatype text \ + -pretty_name "Page Title" \ + -column_spec text + } + if {![attribute::exists_p ::xowiki::Page creator]} { + ::xo::db::sql::content_type create_attribute \ + -content_type ::xowiki::Page \ + -attribute_name creator \ + -datatype text \ + -pretty_name "Creator" \ + -column_spec text + } + ::xowiki::update_views + } + + if {[apm_version_names_compare $from_version_name "0.22"] == -1 && + [apm_version_names_compare $to_version_name "0.22"] > -1} { + ns_log notice "-- upgrading to 0.22" + set folder_ids [list] + set package_ids [list] + foreach package_id [::xowiki::Package instances] { + set folder_id [db_list get_folder_id "select f.folder_id from cr_items c, cr_folders f \ + where c.name = 'xowiki: $package_id' and c.item_id = f.folder_id"] + if {$folder_id ne ""} { + db_dml update_package_id {update cr_folders set package_id = :package_id + where folder_id = :folder_id} + lappend folder_ids $folder_id + lappend package_ids $package_id + } + } + foreach f $folder_ids p $package_ids { + db_dml update_context_ids "update acs_objects set context_id = $p where object_id = $f" + } + } + + if {[apm_version_names_compare $from_version_name "0.25"] == -1 && + [apm_version_names_compare $to_version_name "0.25"] > -1} { + ns_log notice "-- upgrading to 0.25" + # Only run this if the PageInstance does not exist + if {[catch {acs_sc::impl::get_id -owner xowiki -name ::xowiki::PageInstance}]} { + acs_sc::impl::new_from_spec -spec { + name "::xowiki::PageInstance" + aliases { + datasource ::xowiki::datasource + url ::xowiki::url + } + contract_name FtsContentProvider + owner xowiki + } + } + } + + if {[apm_version_names_compare $from_version_name "0.27"] == -1 && + [apm_version_names_compare $to_version_name "0.27"] > -1} { + ns_log notice "-- upgrading to 0.27" + db_dml copy_page_title_into_title \ + "update cr_revisions set title = p.page_title from xowiki_page p \ + where page_title != '' and revision_id = p.page_id" + + db_list delete_deprecated_types_from_ancient_versions \ + "select [::xo::db::function_name content_item__delete(i.item_id)] from cr_items i \ + where content_type in ('CrWikiPage', 'CrWikiPlainPage', \ + 'PageInstance', 'PageTemplate','CrNote', 'CrSubNote')" + } + + if {[apm_version_names_compare $from_version_name "0.30"] == -1 && + [apm_version_names_compare $to_version_name "0.30"] > -1} { + ns_log notice "-- upgrading to 0.30" + # delete orphan cr revisions, created automatically by content_item + # new, when e.g. a title is specified.... + foreach class {::xowiki::Page ::xowiki::PlainPage ::xowiki::Object + ::xowiki::PageTemplate ::xowiki::PageInstance} { + db_dml delete_orphan_revisions " + delete from cr_revisions where revision_id in ( + select r.revision_id from cr_items i,cr_revisions r + where i.content_type = '$class' and r.item_id = i.item_id + and not r.revision_id in (select [$class id_column] from [$class table_name])) + " + db_dml delete_orphan_items " + delete from acs_objects where object_type = '$class' + and not object_id in (select item_id from cr_items where content_type = '$class') + and not object_id in (select [$class id_column] from [$class table_name]) + " + } + } + + if {[apm_version_names_compare $from_version_name "0.31"] == -1 && + [apm_version_names_compare $to_version_name "0.31"] > -1} { + ns_log notice "-- upgrading to 0.31" + set folder_ids [list] + set package_ids [list] + foreach package_id [::xowiki::Package instances] { + set folder_id [db_string get_folder_id "select f.folder_id from cr_items c, cr_folders f \ + where c.name = 'xowiki: $package_id' and c.item_id = f.folder_id"] + if {$folder_id ne ""} { + db_dml update_package_id {update acs_objects set package_id = :package_id where object_id in + (select item_id as object_id from cr_items where parent_id = :folder_id)} + db_dml update_package_id {update acs_objects set package_id = :package_id where object_id in + (select r.revision_id as object_id from cr_revisions r, cr_items i where + i.item_id = r.item_id and i.parent_id = :folder_id)} + ::xowiki::Package initialize -package_id $package_id -init_url false + ::$package_id reindex + } + } + } + + if {[apm_version_names_compare $from_version_name "0.34"] == -1 && + [apm_version_names_compare $to_version_name "0.34"] > -1} { + ns_log notice "-- upgrading to 0.34" + ::xowiki::notifications-install + } + + if {[apm_version_names_compare $from_version_name "0.39"] == -1 && + [apm_version_names_compare $to_version_name "0.39"] > -1} { + ns_log notice "-- upgrading to 0.39" + catch {db_dml create-xowiki-last-visited-time-idx \ + "create index xowiki_last_visited_time_idx on xowiki_last_visited(time)" + } + } + + if {[apm_version_names_compare $from_version_name "0.42"] == -1 && + [apm_version_names_compare $to_version_name "0.42"] > -1} { + ns_log notice "-- upgrading to 0.42" + ::xowiki::add_ltree_order_column + # get rid of obsolete column + catch { + ::xo::db::sql::content_type delete_attribute \ + -content_type ::xowiki::Page \ + -attribute_name page_title \ + -drop_column t + } + # drop old non-conformant indices + foreach index { xowiki_ref_index + xowiki_last_visited_index_unique xowiki_last_visited_index + xowiki_tags_index_tag xowiki_tags_index_user + } { + catch {db_dml drop_index "drop index $index"} + } + ::xowiki::update_views + } + if {[apm_version_names_compare $from_version_name "0.56"] == -1 && + [apm_version_names_compare $to_version_name "0.56"] > -1} { + ns_log notice "-- upgrading to 0.56" + db_dml add_integer_column \ + "alter table xowiki_page_instance add npage_template \ + integer references cr_items(item_id)" + db_dml copy_old_values \ + "update xowiki_page_instance set npage_template = cast(page_template as integer)" + db_dml rename_old_column \ + "alter table xowiki_page_instance rename column page_template to old_page_template" + db_dml rename_new_column \ + "alter table xowiki_page_instance rename column npage_template to page_template" + # a few releases later, drop old column + if {[db_0or1row in_between_version \ + "select 1 from acs_object_types where \ + object_type = '::xowiki::Form' and supertype = '::xowiki::Page'"]} { + # we have a version with a type hierarchy not compatible with the new one. + # this comes by updating often from head. + # The likelyhood to have such as version is rather low. + ns_log notice "Deleting incompatible version of ::xowiki::Form" + ::xo::db::sql::content_type drop_type -content_type ::xowiki::FormInstance \ + -drop_children_p t -drop_table_p t -drop_objects_p t + ::xo::db::sql::content_type drop_type -content_type ::xowiki::Form \ + -drop_children_p t -drop_table_p t -drop_objects_p t + } + ::xowiki::update_views + } + + if {[apm_version_names_compare $from_version_name "0.58"] == -1 && + [apm_version_names_compare $to_version_name "0.58"] > -1} { + ns_log notice "-- upgrading to 0.58" + + if {[catch {acs_sc::impl::get_id -owner xowiki -name ::xowiki::FormPage}]} { + acs_sc::impl::new_from_spec -spec { + name "::xowiki::FormPage" + aliases { + datasource ::xowiki::datasource + url ::xowiki::url + } + contract_name FtsContentProvider + owner xowiki + } + } + } + + if {[apm_version_names_compare $from_version_name "0.59"] == -1 && + [apm_version_names_compare $to_version_name "0.59"] > -1} { + ns_log notice "-- upgrading to 0.59" + # Remove all old objects of tyoe ::xowiki::FormInstance and the type + # from the database. + if {[catch { + ::xo::db::sql::content_type drop_type -content_type ::xowiki::FormInstance \ + -drop_children_p t -drop_table_p t -drop_objects_p t + } errorMsg]} { + ns_log notice "--upgrade produced error: $errorMsg" + } + } + + if {[apm_version_names_compare $from_version_name "0.60"] == -1 && + [apm_version_names_compare $to_version_name "0.60"] > -1} { + ns_log notice "-- upgrading to 0.60" + # load for all xowiki package instances te weblog-portlet prototype page + foreach package_id [::xowiki::Package instances] { + ::xowiki::Package initialize -package_id $package_id -init_url false + $package_id import_prototype_page weblog-portlet + } + } + + if {[apm_version_names_compare $from_version_name "0.65"] == -1 && + [apm_version_names_compare $to_version_name "0.65"] > -1} { + ns_log notice "-- upgrading to 0.65" + catch { + # for new installs, the old column might not exist + db_dml drop_old_column \ + "alter table xowiki_page_instance drop column old_page_template" + } + ::xowiki::update_views + } + } + + ad_proc fix_all_package_ids {} { + earlier versions of openacs did not have the package_id set correctly + in acs_objects; this proc updates the package_ids of all items + and revisions in acs_objects + } { + set folder_ids [list] + set package_ids [list] + foreach package_id [::xowiki::Package instances] { + ns_log notice "checking package_id $package_id" + set folder_id [db_list get_folder_id "select f.folder_id from cr_items c, cr_folders f \ + where c.name = 'xowiki: $package_id' and c.item_id = f.folder_id"] + if {$folder_id ne ""} { + db_dml update_package_id {update acs_objects set package_id = :package_id + where object_id in + (select item_id as object_id from cr_items where parent_id = :folder_id) + and package_id is NULL} + db_dml update_package_id {update acs_objects set package_id = :package_id + where object_id in + (select r.revision_id as object_id from cr_revisions r, cr_items i where + i.item_id = r.item_id and i.parent_id = :folder_id) + and package_id is NULL} + } + } + } + + ad_proc update_views {} { + update all automatic views of xowiki + } { + foreach object_type [::xowiki::Page object_types] { + ::xo::db::sql::content_type refresh_view -content_type $object_type + } + + catch {db_dml drop_live_revision_view "drop view xowiki_page_live_revision"} + if {[db_driverkey ""] eq "postgresql"} { + set sortkeys ", ci.tree_sortkey, ci.max_child_sortkey " + } else { + set sortkeys "" + } + ::xo::db::require view xowiki_page_live_revision \ + "select p.*, cr.*,ci.parent_id, ci.name, ci.locale, ci.live_revision, \ + ci.latest_revision, ci.publish_status, ci.content_type, ci.storage_type, \ + ci.storage_area_key $sortkeys \ + from xowiki_page p, cr_items ci, cr_revisions cr \ + where p.page_id = ci.live_revision \ + and p.page_id = cr.revision_id \ + and ci.publish_status <> 'production'" + } + + ad_proc add_ltree_order_column {} { + add ltree order column, if ltree is configured + } { + if {[::xo::db::has_ltree]} { + # catch sql statement to allow multiple runs + catch {::xo::db::sql::content_type create_attribute \ + -content_type ::xowiki::Page \ + -attribute_name page_order \ + -datatype text \ + -pretty_name Order \ + -column_spec ltree} + + ::xo::db::require index -table xowiki_page -col page_order -using gist + set result 1 + } else { + set result 0 + } + ::xowiki::update_views + return $result + } + + proc form_upgrade {} { + db_dml from_upgrade { + update xowiki_form f set form = xowiki_formi.data from xowiki_formi + where f.xowiki_form_id = xowiki_formi.revision_id + } + } + +} \ No newline at end of file Index: openacs-4/packages/xowiki/tcl/xowiki-form-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-form-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/xowiki-form-procs.tcl 1 Aug 2007 21:39:24 -0000 1.84.2.2 @@ -0,0 +1,742 @@ +ad_library { + XoWiki - form classes + + @creation-date 2006-04-10 + @author Gustaf Neumann + @cvs-id $Id: xowiki-form-procs.tcl,v 1.84.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki { + + # + # Application specific forms + # + + Class create WikiForm -superclass ::Generic::Form \ + -parameter { + {field_list {item_id name page_order title creator text description nls_language}} + {f.item_id {item_id:key}} + {f.name "="} + {f.page_order "="} + {f.title "="} + {f.creator "="} + {f.text "= richtext,editor=xinha"} + {f.description "="} + {f.nls_language "="} + {validate + {{name {\[::xowiki::validate_name\]} {Another item with this name exists \ + already in this folder}}}} + {with_categories true} + {submit_link "view"} + {folderspec ""} + {autoname 0} + } -ad_doc { + Form Class for XoWiki Pages. + + You can manipulate the form elements shown by editing the field_list. + The following elements are mandatory in field_list + and should never be left out: +
        +
      • name +
      • item_id +
      + + } + + WikiForm instproc mkFields {} { + my instvar data autoname + set __fields "" + set field_list [my field_list] + + set show_page_order [[$data package_id] show_page_order] + if {!$show_page_order} { my f.page_order "= hidden" } + if {$autoname} { my f.name "= hidden,optional"} + set form_fields [list] + + foreach __field $field_list { + + # if there is no field spec, use the default from the slot definitions + set __spec [expr {[my exists f.$__field] ? [my set f.$__field] : "="}] + set __wspec [lindex $__spec 0] + #my msg "$__field wspec=$__wspec, spec=$__spec" + + # check first if we have widget_specs. + # TODO: this part is likely to be removed in the future. + set s [$data get_rich_text_spec $__field ""] + if {$s ne ""} { + set __spec $s + set __wspec [lindex $__spec 0] + # old style folder spec substituion. ugly. + if {[my folderspec] ne ""} { + # append the folder spec to its options + set __newspec [list $__wspec] + foreach __e [lrange $__spec 1 end] { + foreach {__name __value} $__e break + if {$__name eq "options"} {eval lappend __value [my folderspec]} + lappend __newspec [list $__name $__value] + } + #my log "--F rewritten spec is '$__newspec'" + set __spec $__newspec + } + } elseif {[lindex $__wspec 0] eq "="} { + # + # get the information from the attribute definitions & given specs + # + set f [$data create_form_field \ + -name $__field \ + -slot [$data find_slot $__field] \ + -spec [lindex $__spec 1] \ + ] + + if {[$f istype ::xowiki::FormField::richtext] && + [my folderspec] ne ""} { + # insert the folder id into the spec for the + # oacsfs plugin to access the correct filestore instance + foreach {key value} [my folderspec] break + $f $key $value + } + + set __spec ${__field}:[$f asWidgetSpec] + set __wspec [lindex $__spec 0] + lappend form_fields $f + } + + if {[string first "richtext" $__wspec] > -1} { + # ad_form does a subst, therefore escape esp. the javascript stuff + set __spec [string map {\[ \\[ \] \\] \$ \\$ \\ \\\\} $__spec] + } + + #my msg "--F field <$__field> = $__spec" + append __fields [list $__spec] \n + } + + # setting form fields for later use in validator + # $data show_fields $form_fields + my set form_fields $form_fields + + my set fields $__fields + + } + + proc ::xowiki::locales {} { + set locales [lang::system::get_locales] + set defpos [lsearch $locales [lang::conn::locale]] + set locales [linsert [lreplace $locales $defpos $defpos] 0 \ + [lang::conn::locale]] + foreach l $locales {lappend lpairs [list $l $l]} + return $lpairs + } + + proc ::xowiki::page_templates {} { + ::xowiki::f1 instvar data folder_id ;# form has to be named ::xowiki::f1 + set q [::xowiki::PageTemplate instance_select_query \ + -folder_id $folder_id \ + -with_subtypes false \ + -select_attributes {name}] + db_foreach [my qn get_page_templates] $q { + lappend lpairs [list $name $item_id] + } if_no_rows { + lappend lpairs [list "(No Page Template available)" ""] + } + return $lpairs + } + + # + # todo: this should be OO-ified -gustaf + proc ::xowiki::validate_file {} { + my instvar data + my get_uploaded_file + upvar title title + if {$title eq ""} {set title [$data set upload_file]} + # my log "--F validate_file returns [$data exists import_file]" + return [$data exists import_file] + } + + proc ::xowiki::guesstype {fn} { + set mime [ns_guesstype $fn] + if {$mime eq "*/*"} { + # ns_guesstype was failing + switch [file extension $fn] { + .mp3 {set mime audio/mpeg} + .cdf {set mime application/x-netcdf} + .flv {set mime video/x-flv} + } + } + return $mime + } + + proc ::xowiki::validate_duration {} { + upvar duration duration + my instvar data + $data instvar package_id + if {[$data istype ::xowiki::PodcastItem] && $duration eq "" && [$data exists import_file]} { + set filename [expr {[$data exists full_file_name] ? [$data full_file_name] : [$data set import_file]}] + set ffmpeg [$package_id get_parameter "ffmpeg" "/usr/bin/ffmpeg"] + if {[file exists $ffmpeg]} { + catch {exec $ffmpeg -i $filename} output + if {[info exists output]} { + regexp {Duration: +([0-9:.]+)[ ,]} $output _ duration + } + } + } + return 1 + } + + + proc ::xowiki::validate_name {} { + upvar name name nls_language nls_language + my instvar data + + set old_name [::xo::cc form_parameter __object_name ""] + if {$name eq $old_name && $name ne ""} { + # do not change names, which are already validated; + # otherwise, autonamed entries might get an unwanted en:prefix + return 1 + } + # my log "--F validate_name data=[my exists data]" + $data instvar package_id + if {[$data istype ::xowiki::File] && [$data exists mime_type]} { + #my log "--mime validate_name data=[my exists data] MIME [$data set mime_type]" + set name [$data complete_name $name [$data set upload_file]] + } else { + if {![regexp {^..:} $name]} { + if {![info exists nls_language]} { + set nls_language [lang::conn::locale] + } + set name [$data complete_name $name $nls_language] + } + } + set name [::$package_id normalize_name $name] + + # check, if we try to create a new item with an existing name + if {[$data form_parameter __new_p 0] + || [$data form_parameter __object_name] ne $name + } { + set folder_id [$data parent_id] + return [expr {[CrItem lookup -name $name -parent_id $folder_id] == 0}] + } + return 1 + } + + + proc ::xowiki::validate_form_constraints {} { + upvar form_constraints form_constraints + my instvar data + set f [$data lookup_form_field -name form_constraints [my set form_fields]] + $f value $form_constraints + set validation_error [$f validate $data] + if {$validation_error ne ""} { + util_user_message -message "Error in form constraints: $validation_error" + set success 0 + } else { + set success 1 + } + return $success + } + + + + + WikiForm instproc data_from_form {{-new 0}} { + my instvar data + if {[$data exists_form_parameter text.format]} { + $data set mime_type [$data form_parameter text.format] + } + if {$new && [[$data set package_id] get_parameter production_mode 0]} { + $data set publish_status production + } + upvar #[template::adp_level] page_order page_order + if {[info exists page_order] && $page_order ne ""} { + set page_order [string trim $page_order " ."] + } + } + WikiForm instproc update_references {} { + my instvar data folder_id + if {![my istype PageInstanceForm]} { + ### danger: update references does an ad_eval, which breaks the [template::adp_level] + ### ad_form! don't do it in pageinstanceforms. + $data render_adp false + $data render -update_references + } + # Delete the link cache entries for this entry. + # The logic could be made more intelligent to delete entries is more rare cases, like + # in case the file was renamed, but this is more bullet-proove. + # + # In case "ns_cache names xowiki_cache *pattern*" is not working on your installation; + # upgrade ns_cache from cvs or use + # foreach entry [lsearch -inline -all [ns_cache names xowiki_cache] link-*-$folder_id] + foreach entry [ns_cache names xowiki_cache link-*-$folder_id] { + array set tmp [ns_cache get xowiki_cache $entry] + if {$tmp(item_id) == [$data set item_id]} { + ns_cache flush xowiki_cache $entry + } + } + if {![$data istype ::xowiki::Object] && + ![$data istype ::xowiki::PageTemplate] } { + if {[$data istype ::xowiki::PageInstance]} { + if {[$data set instance_attributes] ne ""} { + # fieldless page instances are not notified. problem? + # my log "--i instance_attributes = <[$data set instance_attributes]>" + ::xowiki::notification::do_notifications -page $data + } + } else { + ::xowiki::notification::do_notifications -page $data + } + } + + #my log "v=[ad_acs_version] 5.2] compare: [apm_version_names_compare [ad_acs_version] 5.2]" + if {[apm_version_names_compare [ad_acs_version] 5.3.0d4] == 1} { + application_data_link::update_links_from \ + -object_id [$data set item_id] \ + -text [$data set text] + } + } + + + WikiForm instproc new_request {} { + my instvar data + # + # get the defaults from the slots and set it in the data. + # This should not be necessary with xotocl 1.6.* + # + foreach f [my field_list] { + set s [$data find_slot $f] + if {$s ne "" && [$s exists default] && [$s default] ne ""} { + #my msg "new_request $f default = '[$s default]'" + $data set $f [$s default] + } + } + # + # set the following defaults manually + # + $data set creator [::xo::get_user_name [::xo::cc user_id]] + $data set nls_language [ad_conn locale] + next + } + + WikiForm instproc edit_request args { + my instvar data + if {[$data set creator] eq ""} { + $data set creator [::xo::get_user_name [::xo::cc user_id]] + } + next + } + + WikiForm instproc new_data {} { + my instvar data + my data_from_form -new 1 + $data set __autoname_prefix [string range [$data set nls_language] 0 1]: + set item_id [next] + $data set creation_user [::xo::cc user_id] + my update_references + return $item_id + } + + WikiForm instproc edit_data {} { + my data_from_form -new 0 + set item_id [next] + my update_references + return $item_id + } + + WikiForm instproc after_submit {item_id} { + set link [my submit_link] + if {$link eq "."} { + my instvar data + # we can determine submit link only after nls_langauge + # is returned from the user + my submit_link [[$data package_id] pretty_link [$data name]] + } + next + } + # + # PlainWiki Form + # + + Class create PlainWikiForm -superclass WikiForm \ + -parameter { + {f.text "= textarea,cols=80,rows=10"} + } + + # + # File Form + # + + Class create FileForm -superclass WikiForm \ + -parameter { + {html { enctype multipart/form-data }} \ + {field_list {item_id name page_order text title creator description}} + {f.name "= optional,help_text=#xowiki.File-name-help_text#"} + {f.title "= optional"} + {f.text + {upload_file:file(file) + {label #xowiki.content#} + {html {size 30}} }} + {validate { + {upload_file {\[::xowiki::validate_file\]} {For new entries, \ + a upload file must be provided}} + {name {\[::xowiki::validate_name\]} {Another item with this name exists \ + already in this folder}} + }} + } + + + FileForm instproc get_uploaded_file {} { + my instvar data + #my log "--F... [ns_conn url] [ns_conn query] form vars = [ns_set array [ns_getform]]" + set upload_file [$data form_parameter upload_file] + # my log "--F... upload_file = $upload_file" + if {$upload_file ne "" && $upload_file ne "{}"} { + $data set upload_file $upload_file + $data set import_file [$data form_parameter upload_file.tmpfile] + set mime_type [$data form_parameter upload_file.content-type] + if {$mime_type eq "application/octet-stream"} { + set guessed_mime_type [::xowiki::guesstype $upload_file] + my msg guess=$guessed_mime_type + if {$guessed_mime_type ne "*/*"} { + set mime_type $guessed_mime_type + } + } + $data set mime_type $mime_type + } elseif {[$data exists name]} { + # my log "--F no upload_file provided [lsort [$data info vars]]" + if {[$data exists mime_type]} { + my log "--mime_type=[$data set mime_type]" + #my log " text=[$data set text]" + regexp {^[^:]+:(.*)$} [$data set name] _ upload_file + $data set upload_file $upload_file + $data set import_file [$data full_file_name] + # my log "--F upload_file $upload_file import_file [$data full_file_name]" + #my log " import_type=[$data set import_file]" + } + } else { + # my log "--F no name and no upload file" + $data set upload_file "" + } + } + FileForm instproc new_data {} { + #my get_uploaded_file + return [next] + } + FileForm instproc edit_data {} { + #my get_uploaded_file + return [next] + } + +# {f.pub_date +# {pub_date:date,optional {format "YYYY MM DD HH24 MI"} {html {id date}} +# {after_html { Y-M-D} +# }} +# } + + Class create PodcastForm -superclass FileForm \ + -parameter { + {html { enctype multipart/form-data }} \ + {field_list {item_id name page_order text title subtitle creator pub_date duration keywords + description}} + {validate { + {upload_file {\[::xowiki::validate_file\]} {For new entries, \ + a upload file must be provided}} + {name {\[::xowiki::validate_name\]} {Another item with this name exists \ + already in this folder}} + {duration {\[::xowiki::validate_duration\]} {Check duration and provide default}} + }} + } + +# {help_text {E.g. 9:16 means 9 minutes 16 seconds (if ffmpeg is installed and configured, it will get the value automatically)}} + + PodcastForm instproc to_timestamp {widgetinfo} { + if {$widgetinfo ne ""} { + foreach {y m day hour min} $widgetinfo break + set t [clock scan "${hour}:$min $m/$day/$y"] + return [clock format $t] + } + return "" + } + PodcastForm instproc to_timeinfo {timestamp} { + set t [clock scan $timestamp] + return "[clock format $t -format {%Y %m %d %H %M}] {} {YY MM DD HH24 MI}" + } + + PodcastForm instproc new_data {} { + set pub_date [my var pub_date] + my var pub_date [list [my to_timestamp $pub_date]] + return [next] + } + PodcastForm instproc edit_data {} { + set pub_date [my var pub_date] + my var pub_date [list [my to_timestamp $pub_date]] + return [next] + } + + PodcastForm instproc new_request {} { + my instvar data + $data set pub_date [my to_timeinfo [clock format [clock seconds] -format "%y-%m-%d %T"]] + next + } + PodcastForm instproc edit_request {item_id} { + my instvar data + $data set pub_date [my to_timeinfo [$data set pub_date]] + next + } + + + # + # Object Form + # + + Class create ObjectForm -superclass PlainWikiForm \ + -parameter { + {f.text "= textarea,cols=80,rows=15"} + {with_categories false} + } + + ObjectForm instproc init {} { + my instvar data + if {[$data exists name]} { + # don't call validate on the folder object, don't let people change its name + set name [$data set name] + if {$name eq "::[$data set parent_id]"} { + my f.name "= inform,help_text=" + my validate {{name {1} {dummy}} } + #my log "--e don't validate folder id - parent_id = [$data set parent_id]" + } + } + next + } + + ObjectForm instproc new_request {} { + my instvar data + permission::require_permission \ + -party_id [ad_conn user_id] -object_id [$data set parent_id] \ + -privilege "admin" + next + } + + ObjectForm instproc edit_request {item_id} { + my instvar data + #my f.name {{name:text {label #xowiki.Page-name#}}} + permission::require_permission \ + -party_id [ad_conn user_id] -object_id [$data set parent_id] \ + -privilege "admin" + next + } + + ObjectForm instproc edit_data {} { + [my data] initialize_loaded_object + next + } + + # + # PageTemplateForm + # + Class create PageTemplateForm -superclass WikiForm \ + -parameter { + {field_list { + item_id name page_order title creator text anon_instances + description nls_language + }} + } + + # + # PageInstance Forms + # + + Class create PageInstanceForm -superclass WikiForm \ + -parameter { + {field_list {item_id name page_order page_template description nls_language}} + {f.page_template + {page_template:text(select) + {label "Page Template"} + {options \[xowiki::page_templates\]}} + } + {with_categories false} + } + PageInstanceForm instproc set_submit_link_edit {} { + my instvar folder_id data + set object_type [[$data info class] object_type] + #my log "-- data=$data cl=[$data info class] ot=$object_type" + set item_id [$data set item_id] + set page_template [$data form_parameter page_template] + if {[$data exists_query_parameter return_url]} { + set return_url [$data query_parameter return_url] + } + set link [::[$data set package_id] pretty_link [$data set name]] + my submit_link [export_vars -base $link {{m edit} page_template return_url item_id}] + # my log "-- submit_link = [my submit_link]" + } + + PageInstanceForm instproc new_data {} { + my instvar data + set item_id [next] + my set_submit_link_edit + return $item_id + } + + PageInstanceForm instproc edit_data {} { + return [next] + } + + Class create PageInstanceEditForm -superclass WikiForm \ + -parameter { + {field_list_top {item_id name page_order title creator}} + {field_list_bottom {page_template description nls_language}} + {f.name "= inform"} + {f.page_template {page_template:text(hidden)}} + {f.nls_language {nls_language:text(hidden)}} + {with_categories true} + {textfieldspec {text(textarea),nospell {html {cols 60 rows 5}}}} + } + + PageInstanceEditForm instproc new_data {} { + my instvar data + set __vars {folder_id item_id page_template return_url} + set object_type [[$data info class] object_type] + #my log "-- cl=[[my set data] info class] ot=$object_type $__vars" + foreach __v $__vars {set $__v [$data from_parameter $__v] ""} + set item_id [next] + + set link [::[$data set package_id] pretty_link [$data set name]] + my submit_link [export_vars -base $link {{m edit} $__vars}] + # my log "-- submit_link = [my submit_link]" + return $item_id + } + + PageInstanceEditForm instproc edit_request {item_id} { + my log "-- " + my instvar page_instance_form_atts data + next + array set __ia [$data set instance_attributes] + foreach var $page_instance_form_atts { + if {[info exists __ia($var)]} {my var $var [list $__ia($var)]} + } + } + + + PageInstanceEditForm instproc edit_data {} { + my log "-- " + my instvar page_instance_form_atts data + array set __ia [$data set instance_attributes] + foreach var $page_instance_form_atts { + set __ia($var) [my var $var] + } + $data set instance_attributes [array get __ia] + set item_id [next] + my log "-- edit_data item_id=$item_id" + return $item_id + } + + PageInstanceEditForm instproc init {} { + my instvar data page_instance_form_atts + set item_id [$data form_parameter item_id] + # + # make sure to have page template object loaded + # + set page_template_id [$data form_parameter page_template ""] + if {$page_template_id eq ""} { + set page_template_id [$data set page_template] + } + set template [::Generic::CrItem instantiate -item_id $page_template_id] + $template destroy_on_cleanup + set dont_edit [concat [[$data info class] edit_atts] [list title] \ + [::Generic::CrClass set common_query_atts]] + + set category_spec [$data get_short_spec @categories] + foreach f [split $category_spec ,] { + if {$f eq "off"} {my set with_categories false} + } + + # + # compute list of form instance attributes + # + set page_instance_form_atts [list] + foreach {var _} [$data template_vars [$template set text]] { + if {[lsearch $dont_edit $var] == -1} {lappend page_instance_form_atts $var} + } + my set field_list [concat [my field_list_top] $page_instance_form_atts [my field_list_bottom]] + + # + # get widget specs from folder. + # All other specs are taken form attributes or form constraints. + # The widget_spec functionality might be deprecated in the future. + # + foreach __var $page_instance_form_atts { + set spec [$data widget_spec_from_folder_object $__var [$template set name]] + if {$spec ne ""} { + my set f.$__var "$__var:$spec" + } + } + + my edit_page_title [$data get_from_template title] + next + #my log "--fields = [my fields]" + } + + proc ::xowiki::validate_form_text {} { + upvar text text + if {$text eq ""} { return 1 } + if {[llength $text] != 2} { return 0 } + foreach {content mime} $text break + if {$content eq ""} {return 1} + set clean_content $content + regsub -all "
      " $clean_content "" clean_content + regsub -all "" $clean_content "" clean_content + #ns_log notice "--validate_form_content '$content' clean='$clean_content', \ + # stripped='[string trim $clean_content]'" + if {[string trim $clean_content] eq ""} { set text [list "" $mime]} + #my msg "final text='$text'" + return 1 + } + + proc ::xowiki::validate_form_form {} { + upvar form form + if {$form eq ""} {return 1} + dom parse -simple -html [lindex $form 0] doc + $doc documentElement root + return [expr {[$root nodeName] eq "form"}] + } + + Class create FormForm -superclass ::xowiki::PageTemplateForm \ + -parameter { + {field_list {item_id name page_order title creator text form form_constraints + anon_instances description nls_language}} + {f.text "= richtext,height=150px,label=#xowiki.Form-template#"} + {f.form "= richtext,height=150px"} + {f.form_constraints "="} + {validate { + {name {\[::xowiki::validate_name\]} {Another item with this name exists \ + already in this folder}} + {text {\[::xowiki::validate_form_text\]} {Form must contain a valid template}} + {form {\[::xowiki::validate_form_form\]} {Form must contain an HTML form}} + {form_constraints {\[::xowiki::validate_form_constraints\]} {Invalid form constraints}} + }} + } + + FormForm instproc new_data {} { + my instvar data + set item_id [next] + + # provide unique ids and names, if form is provided +# set form [$data set form] +# if {$form ne ""} { +# dom parse -simple -html [lindex $form 0] doc +# $doc documentElement root +# set id ID$item_id +# $root setAttribute id $id +# set fields [$root selectNodes "//*\[@name != ''\]"] +# foreach field $fields { +# $field setAttribute name $id.[$field getAttribute name] +# } +# # updating is rather crude. we need the item_id in advance to fill it +# # into the items, but it is returned from saving the file. +# my log "item_id=$item_id form=[$root asHTML] [$data serialize]" +# $data update_content [$data revision_id] [list [$root asHTML] [lindex $form 1] ] +# } + return $item_id + } + + + +} Index: openacs-4/packages/xowiki/tcl/xowiki-portlet-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/Attic/xowiki-portlet-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/xowiki-portlet-procs.tcl 1 Aug 2007 21:39:24 -0000 1.83.2.2 @@ -0,0 +1,2321 @@ +ad_library { + XoWiki - define various kind of includelets + + @creation-date 2006-10-10 + @author Gustaf Neumann + @cvs-id $Id: xowiki-portlet-procs.tcl,v 1.83.2.2 2007/08/01 21:39:24 gustafn Exp $ +} +namespace eval ::xowiki::portlet { + Class create ::xowiki::Portlet \ + -superclass ::xo::Context \ + -parameter { + {name ""} + {title ""} + {__decoration "portlet"} + {parameter_declaration {}} + {id} + } + + ::xowiki::Portlet proc describe_includelets {portlet_classes} { + my log "--plc=$portlet_classes " + foreach cl $portlet_classes { + set result "" + append result "{{[namespace tail $cl]" + foreach p [$cl info parameter] { + if {[llength $p] != 2} continue + foreach {name value} $p break + if {$name eq "parameter_declaration"} { + foreach pp $value { + #append result "" + switch [llength $pp] { + 1 {append result " $pp"} + 2 { + set v [lindex $pp 1] + if {$v eq ""} {set v {""}} + append result " [lindex $pp 0] $v" + } + } + #append result "\n" + } + } + } + append result "}}\n" + my set html([namespace tail $cl]) $result + my describe_includelets [$cl info subclass] + } + } + ::xowiki::Portlet proc available_includelets {} { + if {[my array exists html]} {my array unset html} + my describe_includelets [::xowiki::Portlet info subclass] + set result "
        " + foreach d [lsort [my array names html]] { + append result "
      • " [my set html($d)] "
      • " \n + } + append result "
      " + return $result + } + + ::xowiki::Portlet instproc js_name {} { + return [string map [list : _ # _] [self]] + } + + ::xowiki::Portlet proc self_id {} { + return [string map [list : _ # _] [self]] + } + ::xowiki::Portlet proc html_id {name} { + # Construct a valid HTML id or name. + # For details, see http://www.w3.org/TR/html4/types.html + regsub -all {[^A-Za-z0-9_:.-]} $name _ name + return $name + } + + ::xowiki::Portlet proc detail_link { + {-absolute:boolean false} + -package_id + -name + -instance_attributes + } { + array set ia $instance_attributes + if {[info exists ia(detail_link)] && $ia(detail_link) ne ""} { + set link $ia(detail_link) + } else { + set link [::$package_id pretty_link $name] + } + return $link + } + + ::xowiki::Portlet instproc screen_name {user_id} { + acs_user::get -user_id $user_id -array user + return [expr {$user(screen_name) ne "" ? $user(screen_name) : $user(name)}] + } + + + ::xowiki::Portlet proc incr_page_order {p} { + regexp {^(.*[.]?)([^.])$} $p _ prefix suffix + if {[string is integer -strict $suffix]} { + incr suffix + } elseif {[string is lower -strict $suffix]} { + regexp {^(.*)(.)$} $suffix _ before last + if {$last eq "z"} { + set last "aa" + } else { + set last [format %c [expr {[scan $last %c] + 1}]] + } + set suffix $before$last + } elseif {[string is upper -strict $suffix]} { + regexp {^(.*)(.)$} $suffix _ before last + if {$last eq "Z"} { + set last "AA" + } else { + set last [format %c [expr {[scan $last %c] + 1}]] + } + set suffix $before$last + } + return $prefix$suffix + } + + ::xowiki::Portlet instproc locale_clause {package_id locale} { + set default_locale [$package_id default_locale] + set system_locale "" + + set with_system_locale [regexp {(.*)[+]system} $locale _ locale] + if {$locale eq "default"} { + set locale $default_locale + set include_system_locale 0 + } + + set locale_clause "" + if {$locale ne ""} { + set locale_clause " and r.nls_language = '$locale'" + if {$with_system_locale} { + set system_locale [lang::system::locale -package_id $package_id] + if {$system_locale ne $default_locale} { + set locale_clause " and (r.nls_language = '$locale' + or r.nls_language = '$system_locale' and not exists + (select 1 from cr_items i where i.name = '[string range $locale 0 1]:' || + substring(ci.name,4) and i.parent_id = ci.parent_id))" + } + } + } + + #my log "--locale $locale, def=$default_locale sys=$system_locale, cl=$locale_clause" + return [list $locale $locale_clause] + } + + ::xowiki::Portlet instproc category_clause {category_spec {item_ref p.item_id}} { + # the category_spec has the syntax "a,b,c|d,e", where the values are category_ids + # pipe symbols are or-operations, commas are and-operations; + # no parenthesis are permitted + set extra_where_clause "" + set or_names [list] + set ors [list] + foreach cid_or [split $category_spec |] { + set ands [list] + set and_names [list] + foreach cid_and [split $cid_or ,] { + lappend and_names [::category::get_name $cid_and] + lappend ands "exists (select 1 from category_object_map \ + where object_id = p.item_id and category_id = $cid_and)" + } + lappend or_names "[join $and_names { and }]" + lappend ors "([join $ands { and }])" + } + set cnames "[join $or_names { or }]" + set extra_where_clause "and ([join $ors { or }])" + #my log "--cnames $category_spec -> $cnames" + return [list $cnames $extra_where_clause] + } + ::xowiki::Portlet instproc get_source {source} { + if {$source ne ""} { + my instvar package_id + set page [$package_id resolve_page $source __m] + if {$page eq ""} { + error "Cannot find page '$source'" + } + $page destroy_on_cleanup + } else { + set page [my set __including_page] + } + return $page + } +} + +namespace eval ::xowiki::portlet { + ############################################################################# + Class create available-includelets \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "The following includelets can be used in a page"} + } + + available-includelets instproc render {} { + my get_parameters + return [::xowiki::Portlet available_includelets] + } +} + +namespace eval ::xowiki::portlet { + ############################################################################# + # dotlrn style portlet decoration for includelets + # + Class ::xowiki::portlet::decoration=portlet -instproc render {} { + my instvar package_id name title + set class [namespace tail [my info class]] + set id [expr {[my exists id] ? "id='[my id]'" : ""}] + set html [next] + set link [expr {[string match "*:*" $name] ? + "$title" : + $title}] + return [subst [[self class] set template]] + } -set template [expr {[apm_version_names_compare [ad_acs_version] 5.3.0] == 1 ? + {
      +
      $link
      +
      $html
      + } : {
      $link
      +
      [next]
      } + }] + Class ::xowiki::portlet::decoration=plain -instproc render {} { + set class [namespace tail [my info class]] + set id [expr {[my exists id] ? "id='[my id]'" : ""}] + return "
      [next]
      " + } + + Class ::xowiki::portlet::decoration=rightbox -instproc render {} { + set class [namespace tail [my info class]] + set id [expr {[my exists id] ? "id='[my id]'" : ""}] + return "
      [next]
      " + } +} + +namespace eval ::xowiki::portlet { + + Class create get \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-variable:required } + {-source ""} + }} + } -instproc render {} { + my get_parameters + set page [my get_source $source] + if {[$page exists $variable]} { + return [$page set $variable] + } else { + return "no such variable $variable in page [$page set name]" + } + } + + Class create creation-date \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-source ""} + {-format "%m-%d-%Y"} + }} + } -instproc render {} { + my get_parameters + set page [my get_source $source] + set time [$page set creation_date] + regexp {^([^.]+)[.]} $time _ time + return [clock format [clock scan $time] -format $format] + } + + ############################################################################# + # rss button + # + Class create rss-button \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-span "10d"} + {-name_filter} + {-entries_of} + {-title} + }} + } + + rss-button instproc render {} { + my get_parameters + set href [export_vars -base [$package_id package_url] {{rss $span} name_filter title entries_of}] + return "RSS" + } + + ############################################################################# + # set-parameter "includelet" + # + Class create set-parameter \ + -superclass ::xowiki::Portlet \ + -parameter {{__decoration plain}} + + set-parameter instproc render {} { + my get_parameters + set pl [my set __caller_parameters] + if {[llength $pl] % 2 == 1} { + error "no even number of parameters '$pl'" + } + foreach {att value} $pl { + ::xo::cc set_parameter $att $value + } + return "" + } +} + +namespace eval ::xowiki::portlet { + ############################################################################# + # valid parameters for he categories portlet are + # tree_name: match pattern, if specified displays only the trees + # with matching names + # no_tree_name: if specified, tree names are not displayed + # open_page: name (e.g. en:iMacs) of the page to be opened initially + # tree_style: boolean, default: true, display based on mktree + + Class create categories \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "Categories"} + {parameter_declaration { + {-tree_name ""} + {-tree_style:boolean 1} + {-no_tree_name:boolean 0} + {-count:boolean 0} + {-summary:boolean 0} + {-locale ""} + {-open_page ""} + {-order_items_by "title,asc"} + {-category_ids ""} + {-except_category_ids ""} + }} + } + + categories instproc render {} { + my get_parameters + + set content "" + set folder_id [$package_id folder_id] + set open_item_id [expr {$open_page ne "" ? + [CrItem lookup -name $open_page -parent_id $folder_id] : 0}] + + foreach {locale locale_clause} [my locale_clause $package_id $locale] break + + set have_locale [expr {[lsearch [info args category_tree::get_mapped_trees] locale] > -1}] + set trees [expr {$have_locale ? + [category_tree::get_mapped_trees $package_id $locale] : + [category_tree::get_mapped_trees $package_id]}] + foreach tree $trees { + foreach {tree_id my_tree_name ...} $tree {break} + if {$tree_name ne "" && ![string match $tree_name $my_tree_name]} continue + if {!$no_tree_name} { + append content "

      $my_tree_name

      " + } + set categories [list] + set pos 0 + set cattree(0) [::xowiki::CatTree new -volatile -orderby pos -name $my_tree_name] + set category_infos [expr {$have_locale ? + [category_tree::get_tree $tree_id $locale] : + [category_tree::get_tree $tree_id]}] + + foreach category_info $category_infos { + foreach {cid category_label deprecated_p level} $category_info {break} + + set c [::xowiki::Category new -orderby pos -category_id $cid -package_id $package_id \ + -level $level -label $category_label -pos [incr pos]] + set cattree($level) $c + set plevel [expr {$level -1}] + $cattree($plevel) add $c + set category($cid) $c + lappend categories $cid + } + + set sql "category_object_map c, cr_items ci, cr_revisions r, xowiki_page p \ + where c.object_id = ci.item_id and ci.parent_id = $folder_id \ + and ci.content_type not in ('::xowiki::PageTemplate') \ + and category_id in ([join $categories ,]) \ + and r.revision_id = ci.live_revision \ + and p.page_id = r.revision_id \ + and ci.publish_status <> 'production'" + + if {$except_category_ids ne ""} { + append sql \ + " and not exists (select * from category_object_map c2 \ + where ci.item_id = c2.object_id \ + and c2.category_id in ($except_category_ids))" + } + #ns_log notice "--c category_ids=$category_ids" + if {$category_ids ne ""} { + foreach cid [split $category_ids ,] { + append sql " and exists (select * from category_object_map \ + where object_id = ci.item_id and category_id = $cid)" + } + } + append sql $locale_clause + + if {$count} { + db_foreach [my qn get_counts] \ + "select count(*) as nr,category_id from $sql group by category_id" { + $category($category_id) set count $nr + set s [expr {$summary ? "&summary=$summary" : ""}] + $category($category_id) href [ad_conn url]?category_id=$category_id$s + $category($category_id) open_tree + } + append content [$cattree(0) render -tree_style $tree_style] + } else { + foreach {orderby direction} [split $order_items_by ,] break ;# e.g. "title,asc" + set increasing [expr {$direction ne "desc"}] + + # + # If we have ltree, we query the order_column from the database, + # otherwise we don't retrieve it, but set the Tcl variable page_order empty. + # + if {[::xo::db::has_ltree]} { + set order_column ", p.page_order" + } else { + set order_column "" + set page_order "" + } + + db_foreach [my qn get_pages] \ + "select ci.item_id, ci.name, ci.content_type, r.title, category_id $order_column from $sql" { + if {$title eq ""} {set title $name} + set itemobj [Object new] + set prefix "" + set suffix "" + foreach var {name title prefix suffix page_order} {$itemobj set $var [set $var]} + + $cattree(0) add_to_category \ + -category $category($category_id) \ + -itemobj $itemobj \ + -orderby $orderby \ + -increasing $increasing \ + -open_item [expr {$item_id == $open_item_id}] + } + append content [$cattree(0) render -tree_style $tree_style] + } + } + return $content + } +} + + +namespace eval ::xowiki::portlet { + ############################################################################# + # + # display recent entries by categories + # -gustaf neumann + # + # valid parameters from the include are + # tree_name: match pattern, if specified displays only the trees with matching names + # max_entries: show given number of new entries + + Class create categories-recent \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "Recently Changed Pages by Categories"} + {parameter_declaration { + {-max_entries:integer 10} + {-tree_name ""} + {-locale ""} + }} + } + + categories-recent instproc render {} { + my get_parameters + + set cattree [::xowiki::CatTree new -volatile -name "categories-recent"] + + foreach {locale locale_clause} [my locale_clause $package_id $locale] break + + set have_locale [expr {[lsearch [info args category_tree::get_mapped_trees] locale] > -1}] + set trees [expr {$have_locale ? + [category_tree::get_mapped_trees $package_id $locale] : + [category_tree::get_mapped_trees $package_id]}] + + foreach tree $trees { + foreach {tree_id my_tree_name ...} $tree {break} + if {$tree_name ne "" && ![string match $tree_name $my_tree_name]} continue + lappend tree_ids $tree_id + } + if {[info exists tree_ids]} { + set tree_select_clause "and c.tree_id in ([join $tree_ids ,])" + } else { + set tree_select_clause "" + } + set sql [::xo::db::sql select \ + -vars "c.category_id, ci.name, r.title, r.publish_date, \ + to_char(r.publish_date,'YYYY-MM-DD HH24:MI:SS') as formatted_date" \ + -from "category_object_map_tree c, cr_items ci, cr_revisions r, xowiki_page p" \ + -where "c.object_id = ci.item_id and ci.parent_id = [$package_id folder_id] \ + and r.revision_id = ci.live_revision \ + and p.page_id = r.revision_id $tree_select_clause $locale_clause \ + and ci.publish_status <> 'production'" \ + -orderby "publish_date desc" \ + -limit $max_entries] + db_foreach [my qn get_pages] $sql { + if {$title eq ""} {set title $name} + set itemobj [Object new] + set prefix "$formatted_date " + set suffix "" + foreach var {name title prefix suffix} {$itemobj set $var [set $var]} + if {![info exists categories($category_id)]} { + set categories($category_id) [::xowiki::Category new \ + -package_id $package_id \ + -label [category::get_name $category_id $locale]\ + -level 1] + $cattree add $categories($category_id) + } + $cattree add_to_category -category $categories($category_id) -itemobj $itemobj + } + return [$cattree render] + } +} + + +namespace eval ::xowiki::portlet { + ############################################################################# + # + # display recent entries + # + + Class create recent \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "Recently Changed Pages"} + {parameter_declaration { + {-max_entries:integer 10} + {-allow_edit:boolean false} + {-allow_delete:boolean false} + }} + } + + recent instproc render {} { + my get_parameters + ::xowiki::Page requireCSS "/resources/acs-templating/lists.css" + TableWidget t1 -volatile \ + -set allow_edit $allow_edit \ + -set allow_delete $allow_delete \ + -columns { + Field date -label "Modification Date" + if {[[my info parent] set allow_edit]} { + ImageField_EditIcon edit -label "" -html {style "padding-right: 2px;"} + } + AnchorField title -label [::xowiki::Page::slot::title set pretty_name] + if {[[my info parent] set allow_delete]} { + ImageField_DeleteIcon delete -label "" + } + } + + db_foreach [my qn get_pages] \ + [::xo::db::sql select \ + -vars "i.name, r.title, p.page_id, r.publish_date, \ + to_char(r.publish_date,'YYYY-MM-DD HH24:MI:SS') as formatted_date" \ + -from "cr_items i, cr_revisions r, xowiki_page p" \ + -where "i.parent_id = [$package_id folder_id] \ + and r.revision_id = i.live_revision \ + and p.page_id = r.revision_id \ + and i.publish_status <> 'production'" \ + -orderby "publish_date desc" \ + -limit $max_entries ] { + + t1 add \ + -title $title \ + -title.href [$package_id pretty_link $name] \ + -date $formatted_date + + if {$allow_edit} { + #set page_link [$package_id pretty_link $name] + #set edit_link [$package_id make_link $page_link edit return_url] + set p [::Generic::CrItem instantiate -item_id 0 -revision_id $page_id] + $p destroy_on_cleanup + set page_link [$package_id pretty_link $name] + set edit_link [$package_id make_link -link $page_link $p edit return_url] + my log "page_link=$page_link, edit=$edit_link" + [t1 last_child] set edit.href $edit_link + } + if {$allow_delete} { + if {![info exists p]} { + set p [::Generic::CrItem instantiate -item_id 0 -revision_id $page_id] + $p destroy_on_cleanup + } + set page_link [$package_id pretty_link $name] + set delete_link [$package_id make_link -link $page_link $p delete return_url] + [t1 last_child] set delete.href $delete_link + } + } + return [t1 asHTML] + } +} + +namespace eval ::xowiki::portlet { + ############################################################################# + # + # display last visited entries + # + + Class create last-visited \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "Last Visited Pages"} + {parameter_declaration { + {-max_entries:integer 20} + }} + } + + last-visited instproc render {} { + my get_parameters + ::xowiki::Page requireCSS "/resources/acs-templating/lists.css" + + TableWidget t1 -volatile \ + -columns { + AnchorField title -label [::xowiki::Page::slot::title set pretty_name] + } + + db_foreach [my qn get_pages] \ + [::xo::db::sql select \ + -vars "r.title,i.name, to_char(time,'YYYY-MM-DD HH24:MI:SS') as visited_date" \ + -from "xowiki_last_visited x, xowiki_page p, cr_items i, cr_revisions r" \ + -where "x.page_id = i.item_id and i.live_revision = p.page_id \ + and r.revision_id = p.page_id and x.user_id = [::xo::cc user_id] \ + and x.package_id = $package_id and i.publish_status <> 'production'" \ + -orderby "visited_date desc" \ + -limit $max_entries] \ + { + t1 add \ + -title $title \ + -title.href [$package_id pretty_link $name] + } + return [t1 asHTML] + } +} + + +namespace eval ::xowiki::portlet { + ############################################################################# + # + # list the most popular pages + # + + Class create most-popular \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "Most Popular Pages"} + {parameter_declaration { + {-max_entries:integer "10"} + {-interval} + }} + } + + most-popular instproc render {} { + my get_parameters + ::xowiki::Page requireCSS "/resources/acs-templating/lists.css" + + if {[info exists interval]} { + # + # If we have and interval, we cannot get report the number of visits + # for that interval, since we have only the aggregated values in + # the database. + # + my append title " in last $interval" + + TableWidget t1 -volatile \ + -columns { + AnchorField title -label [::xowiki::Page::slot::title set pretty_name] + Field users -label Visitors -html { align right } + } + set since_condition "and [::xo::db::sql since_interval_condition time $interval]" + db_foreach [my qn get_pages] \ + [::xo::db::sql select \ + -vars "count(x.user_id) as nr_different_users, x.page_id, r.title,i.name" \ + -from "xowiki_last_visited x, xowiki_page p, cr_items i, cr_revisions r" \ + -where "x.page_id = i.item_id and i.live_revision = p.page_id and r.revision_id = p.page_id \ + and x.package_id = $package_id and i.publish_status <> 'production' \ + $since_condition" \ + -groupby "x.page_id, r.title, i.name" \ + -orderby "nr_different_users desc" \ + -limit $max_entries ] { + t1 add \ + -title $title \ + -title.href [$package_id pretty_link $name] \ + -users $nr_different_users + } + } else { + + TableWidget t1 -volatile \ + -columns { + AnchorField title -label [::xowiki::Page::slot::title set pretty_name] + Field count -label Visits -html { align right } + Field users -label Visitors -html { align right } + } + db_foreach [my qn get_pages] \ + [::xo::db::sql select \ + -vars "sum(x.count) as sum, count(x.user_id) as nr_different_users, x.page_id, r.title,i.name" \ + -from "xowiki_last_visited x, xowiki_page p, cr_items i, cr_revisions r" \ + -where "x.page_id = i.item_id and i.live_revision = p.page_id and r.revision_id = p.page_id \ + and x.package_id = $package_id and i.publish_status <> 'production'" \ + -groupby "x.page_id, r.title, i.name" \ + -orderby "sum desc" \ + -limit $max_entries] { + t1 add \ + -title $title \ + -title.href [$package_id pretty_link $name] \ + -users $nr_different_users \ + -count $sum + } + } + return [t1 asHTML] + } +} + +namespace eval ::xowiki::portlet { + ############################################################################# + # + # Display unread items + # + # Currently moderately useful + # + # TODO: display of unread *revisions* should be included optionally, one has to + # consider what to do with auto-created stuff (put it into 'production' state?) + # + + Class create unread-items \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "Unread Items"} + {parameter_declaration { + {-max_entries:integer 20} + }} + } + + unread-items instproc render {} { + my get_parameters + ::xowiki::Page requireCSS "/resources/acs-templating/lists.css" + + TableWidget t1 -volatile \ + -columns { + AnchorField title -label [::xowiki::Page::slot::title set pretty_name] + } + + set or_clause "or i.item_id in (select x.page_id from xowiki_last_visited x, acs_objects o \ + where x.time < o.last_modified and x.page_id = o.object_id and x.package_id = $package_id) +" + + db_foreach [my qn get_pages] \ + [::xo::db::sql select \ + -vars "a.title, i.name" \ + -from "xowiki_page p, cr_items i, acs_objects a " \ + -where "(i.item_id not in (select x.page_id from xowiki_last_visited x + where x.user_id = [::xo::cc user_id] and x.package_id = $package_id) + $or_clause + ) + and i.live_revision = p.page_id + and i.parent_id = [$package_id folder_id] + and i.publish_status <> 'production' + and a.object_id = i.item_id" \ + -orderby "a.creation_date desc" \ + -limit $max_entries] \ + { + t1 add \ + -title $title \ + -title.href [$package_id pretty_link $name] + } + return [t1 asHTML] + } +} + + + + +namespace eval ::xowiki::portlet { + ############################################################################# + # + # Show the tags + # + + Class create tags \ + -superclass ::xowiki::Portlet \ + -parameter { + {title "Tags"} + {parameter_declaration { + {-limit:integer 20} + {-summary:boolean 0} + {-popular:boolean 0} + {-page} + }} + } + + tags instproc render {} { + my get_parameters + ::xowiki::Page requireCSS "/resources/acs-templating/lists.css" + + if {$popular} { + set label [_ xowiki.popular_tags_label] + set tag_type ptag + set sql [::xo::db::sql select \ + -vars "count(*) as nr,tag" \ + -from xowiki_tags \ + -where "package_id=$package_id" \ + -groupby tag \ + -orderby tag \ + -limit $limit] + } else { + set label [_ xowiki.your_tags_label] + set tag_type tag + set sql "select count(*) as nr,tag from xowiki_tags where \ + user_id=[::xo::cc user_id] and package_id=$package_id group by tag order by tag" + } + set entries [list] + + if {![info exists page]} {set page [$package_id get_parameter weblog_page]} + set base_url [$package_id pretty_link $page] + + db_foreach [my qn get_counts] $sql { + set s [expr {$summary ? "&summary=$summary" : ""}] + set href $base_url?$tag_type=[ad_urlencode $tag]$s + lappend entries "$tag ($nr)" + } + return [expr {[llength $entries] > 0 ? + "

      $label

      [join $entries {, }]
      \n" : + ""}] + } + + Class create my-tags \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-summary 1} + }} + } + + my-tags instproc render {} { + my get_parameters + my instvar __including_page tags + ::xowiki::Page requireJS "/resources/xowiki/get-http-object.js" + + set p_link [$package_id pretty_link [$__including_page name]] + set return_url "[::xo::cc url]?[::xo::cc actual_query]" + set weblog_page [$package_id get_parameter weblog_page weblog] + set save_tag_link [$package_id make_link -link $p_link $__including_page \ + save-tags return_url] + set popular_tags_link [$package_id make_link -link $p_link $__including_page \ + popular-tags return_url weblog_page] + + set tags [lsort [::xowiki::Page get_tags -user_id [::xo::cc user_id] \ + -item_id [$__including_page item_id] -package_id $package_id]] + set href [$package_id package_url]$weblog_page?summary=$summary + + set entries [list] + foreach tag $tags {lappend entries "$tag"} + set tags_with_links [join [lsort $entries] {, }] + + set content [subst -nobackslashes { + #xowiki.your_tags_label#: $tags_with_links + (#xowiki.edit_link#, + #xowiki.popular_tags_link#) + +
      + }] + return $content + } + + + Class create my-categories \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-summary 1} + }} + } + + my-categories instproc render {} { + my get_parameters + my instvar __including_page + set content "" + + set weblog_page [$package_id get_parameter weblog_page weblog] + set entries [list] + set href [$package_id package_url]$weblog_page?summary=$summary + set notification_type "" + if {[$package_id get_parameter "with_notifications" 1] && + [::xo::cc user_id] != 0} { ;# notifications require login + set notification_type [notification::type::get_type_id -short_name xowiki_notif] + } + if {[$package_id exists_query_parameter return_url]} { + set return_url [$package_id query_parameter return_url] + } + foreach cat_id [category::get_mapped_categories [$__including_page set item_id]] { + foreach {category_id category_name tree_id tree_name} [category::get_data $cat_id] break + #my log "--cat $cat_id $category_id $category_name $tree_id $tree_name" + set entry "$category_name ($tree_name)" + if {$notification_type ne ""} { + set notification_text "Subscribe category $category_name in tree $tree_name" + set notifications_return_url [expr {[info exists return_url] ? $return_url : [ad_return_url]}] + set notification_image \ + "$notification_text" + + set cat_notif_link [export_vars -base /notifications/request-new \ + {{return_url $notifications_return_url} \ + {pretty_name $notification_text} \ + {type_id $notification_type} \ + {object_id $category_id}}] + append entry " " \ + "" + + } + lappend entries $entry + } + if {[llength $entries]>0} { + set content "Categories: [join $entries {, }]" + } + return $content + } + + Class create my-general-comments \ + -superclass ::xowiki::Portlet \ + -parameter {{__decoration none}} + + my-general-comments instproc render {} { + my get_parameters + my instvar __including_page + set item_id [$__including_page item_id] + set gc_return_url [$package_id url] + set gc_link [general_comments_create_link \ + -object_name [$__including_page title] \ + $item_id $gc_return_url] + set gc_comments [general_comments_get_comments $item_id $gc_return_url] + + return "

      #general-comments.Comments#

        $gc_comments

      $gc_link

      " + } + + Class create digg \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-description ""} + {-url} + }} + } + + digg instproc render {} { + my get_parameters + my instvar __including_page + set digg_link [export_vars -base "http://digg.com/submit" { + {phase 2} + {url $url} + {title "[string range [$__including_page title] 0 74]"} + {body_text "[string range $description 0 349]"} + }] + return "Digg!" + } + + Class create delicious \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-description ""} + {-tags ""} + {-url} + }} + } + + delicious instproc render {} { + my get_parameters + my instvar __including_page + + # the following opens a window, where a user can edit the posted info. + # however, it seems not possible to add tags this way automatically. + # Alternatively, one could use the api as descibed below; this allows + # tags, but no editing... + # http://farm.tucows.com/blog/_archives/2005/3/24/462869.html#adding + + set delicious_link [export_vars -base "http://del.icio.us/post" { + {v 4} + {url $url} + {title "[string range [$__including_page title] 0 79]"} + {notes "[string range $description 0 199]"} + tags + }] + return "Add to your del.icio.usdel.icio.us" + } + + + Class create my-yahoo-publisher \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-publisher ""} + {-rssurl} + }} + } + + my-yahoo-publisher instproc render {} { + my get_parameters + my instvar __including_page + + set publisher [ad_urlencode $publisher] + set feedname [ad_urlencode [[$package_id folder_id] title]] + set rssurl [ad_urlencode $rssurl] + set my_yahoo_link "http://us.rd.yahoo.com/my/atm/$publisher/$feedname/*http://add.my.yahoo.com/rss?url=$rssurl" + + return "Add to My Yahoo!" + } + + Class create my-references \ + -superclass ::xowiki::Portlet \ + -parameter {{__decoration none}} + + my-references instproc render {} { + my get_parameters + my instvar __including_page + + set item_id [$__including_page item_id] + set refs [list] + db_foreach [my qn get_references] "SELECT page,ci.name,f.package_id \ + from xowiki_references,cr_items ci,cr_folders f \ + where reference=$item_id and ci.item_id = page and ci.parent_id = f.folder_id" { + ::xowiki::Package require $package_id + lappend refs "$name" + } + set references [join $refs ", "] + + array set lang {found "" undefined ""} + foreach i [$__including_page array names lang_links] { + set lang($i) [join [$__including_page set lang_links($i)] ", "] + } + append references " " $lang(found) + set result "" + if {$references ne " "} { + append result "#xowiki.references_label# $references" + } + if {$lang(undefined) ne ""} { + append result "#xowiki.create_this_page_in_language# $lang(undefined)" + } + return $result + } + +} + +namespace eval ::xowiki::portlet { + ############################################################################# + # presence + # + Class create presence \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration rightbox} + {parameter_declaration { + {-interval "10 minutes"} + {-max_users:integer 40} + {-show_anonymous "summary"} + {-page} + }} + } + + # TODO make display style -decoration + + presence instproc render {} { + my get_parameters + + set summary 0 + if {[::xo::cc user_id] == 0} { + switch -- $show_anonymous { + nothing {return ""} + all {set summary 0} + default {set summary 1} + } + } + + if {[info exists page] && $page eq "this"} { + my instvar __including_page + set extra_where_clause "and page_id = [$__including_page item_id] " + set what " on page [$__including_page title]" + } else { + set extra_where_clause "" + set what " in community [$package_id instance_name]" + } + + if {!$summary} { + set select_users "user_id, to_char(max(time),'YYYY-MM-DD HH24:MI:SS') as max_time from xowiki_last_visited " + } + set since_condition [::xo::db::sql since_interval_condition time $interval] + set where_clause "package_id=$package_id and $since_condition $extra_where_clause" + set when "
      in last $interval" + + set output "" + + if {$summary} { + set count [db_string [my qn presence_count_users] \ + "select count(distinct user_id) from xowiki_last_visited WHERE $where_clause"] + } else { + set values [db_list_of_lists [my qn get_users] \ + [::xo::db::sql select \ + -vars "user_id, to_char(max(time),'YYYY-MM-DD HH24:MI:SS') as max_time" \ + -from xowiki_last_visited \ + -where $where_clause \ + -groupby user_id \ + -orderby "max_time desc" \ + -limit $max_users ]] + set count [llength $values] + if {$count == $max_users} { + # we have to check, whether there were more users... + set count [db_string [my qn presence_count_users] "$select_count $where_clause"] + } + foreach value $values { + foreach {user_id time} $value break + set seen($user_id) $time + + regexp {^([^.]+)[.]} $time _ time + set pretty_time [util::age_pretty -timestamp_ansi $time \ + -sysdate_ansi [clock_to_ansi [clock seconds]] \ + -mode_3_fmt "%d %b %Y, at %X"] + set name [::xo::get_user_name $user_id] + + append output "$name$pretty_time\n" + } + if {$output ne ""} {set output "$output
      \n"} + } + set users [expr {$count == 0 ? "No registered users" : + $count == 1 ? "1 registered user" : + "$count registered users"}] + return "

      $users$what$when

      $output" + } +} + + +namespace eval ::xowiki::portlet { + ############################################################################# + # portlets based on order + # + Class create toc \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-style ""} + {-open_page ""} + {-book_mode false} + {-ajax true} + {-expand_all false} + {-remove_levels 0} + {-category_id} + }} + } + +#"select page_id, page_order, name, title, \ +# (select count(*)-1 from xowiki_page_live_revision where page_order <@ p.page_order) as count \ +# from xowiki_page_live_revision p where not page_order is NULL order by page_order asc" + + toc instproc count {} {return [my set navigation(count)]} + toc instproc current {} {return [my set navigation(current)]} + toc instproc position {} {return [my set navigation(position)]} + toc instproc page_name {p} {return [my set page_name($p)]} + + toc proc anchor {name} { + # try to strip the language prefix from the name + regexp {^.*:([^:]+)$} $name _ name + # anchor is used between single quotes + regsub -all ' $name {\'} anchor + return $anchor + } + + toc instproc get_nodes {open_page package_id expand_all remove_levels} { + my instvar navigation page_name book_mode + array set navigation {parent "" position 0 current ""} + + set js "" + set node() root + set node_cnt 0 + + set extra_where_clause "" + if {[my exists category_id]} { + foreach {cnames extra_where_clause} [my category_clause [my set category_id]] break + } + set sql [::xo::db::sql select \ + -vars "page_id, page_order, name, title" \ + -from "xowiki_page_live_revision p" \ + -where "parent_id=[$package_id folder_id] and not page_order is NULL $extra_where_clause"] + set pages [::xowiki::Page instantiate_objects -sql $sql] + $pages mixin add ::xo::OrderedComposite::IndexCompare + $pages orderby page_order + + my set jsobjs "" + #my log "--book read [llength [$pages children]] pages" + + foreach o [$pages children] { + $o instvar page_order title page_id name title + + #my log "o: $page_order" + set displayed_page_order $page_order + for {set i 0} {$i < $remove_levels} {incr i} { + regsub {^[^.]+[.]} $displayed_page_order "" displayed_page_order + } + set label "$displayed_page_order $title" + set id tmpNode[incr node_cnt] + set node($page_order) $id + set jsobj [my js_name].objs\[$node_cnt\] + + set page_name($node_cnt) $name + if {![regexp {^(.*)[.]([^.]+)} $page_order _ parent]} {set parent ""} + + if {$book_mode} { + set href [$package_id url]#[toc anchor $name] + } else { + set href [$package_id pretty_link $name] + } + + if {$expand_all} { + set expand "true" + } else { + set expand [expr {$open_page eq $name} ? "true" : "false"] + if {$expand} { + set navigation(parent) $parent + set navigation(position) $node_cnt + set navigation(current) $page_order + for {set p $parent} {$p ne ""} {} { + if {![info exists node($p)]} break + append js "$node($p).expand();\n" + if {![regexp {^(.*)[.]([^.]+)} $p _ p]} {set p ""} + } + } + } + set parent_node [expr {[info exists node($parent)] ? $node($parent) : "root"}] + set refvar [expr {[my set ajax] ? "ref" : "href"}] + regsub -all {\"} $label {\"} label + #my log "$jsobj = {label: \"$label\", id: \"$id\", $refvar: \"$href\", c: $node_cnt};" + append js \ + "$jsobj = {label: \"$label\", id: \"$id\", $refvar: \"$href\", c: $node_cnt};" \ + "var $node($page_order) = new YAHOO.widget.TextNode($jsobj, $parent_node, $expand);\n" \ + "" + my lappend jsobjs $jsobj + + } + set navigation(count) $node_cnt + #my log "--COUNT=$node_cnt" + return $js + } + + toc instproc ajax_tree {js_tree_cmds} { + return "
      + +
      " + } + + toc instproc tree {js_tree_cmds} { + return "
      + +
      " + } + + + toc instproc render {} { + my get_parameters + + switch -- $style { + "menu" {set s "menu/"} + "folders" {set s "folders/"} + "default" {set s ""} + } + ::xowiki::Page requireCSS "/resources/ajaxhelper/yui/treeview/assets/${s}tree.css" + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/yahoo/yahoo.js" + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/event/event.js" + if {$ajax} { + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/dom/dom.js" ;# ANIM + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/connection/connection.js" + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/animation/animation.js" ;# ANIM + } + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/treeview/treeview.js" + + my set book_mode $book_mode + if {!$book_mode} { + ###### my set book_mode [[my set __including_page] exists __is_book_page] + } elseif $ajax { + #my log "--warn: cannot use bookmode with ajax, resetting ajax" + set ajax 0 + } + my set ajax $ajax + if {[info exists category_id]} {my set category_id $category_id} + + set js_tree_cmds [my get_nodes $open_page $package_id $expand_all $remove_levels] + + return [expr {$ajax ? [my ajax_tree $js_tree_cmds ] : [my tree $js_tree_cmds ]}] + } + + ############################################################################# + # Selection + # + # TODO: base book (and toc) on selection + Class create selection \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-edit_links:boolean true} + {-pages ""} + {-ordered_pages} + }} + } + + selection instproc render {} { + my instvar page_order + my get_parameters + my set package_id $package_id + my set edit_links $edit_links + + # compute a list of ordered_pages from pages, if necessary + if {[info exists ordered_pages]} { + foreach {order page} $ordered_pages {set page_order($page) $order} + } else { + set i 0 + foreach page $pages { set page_order($page) [incr i]} + } + + # should check for quotes in names + set page_names ('[join [array names page_order] ',']') + set pages [::xowiki::Page instantiate_objects -sql \ + "select page_id, name, title, item_id \ + from xowiki_page_live_revision p \ + where parent_id = [$package_id folder_id] \ + and name in $page_names \ + [::xowiki::Page container_already_rendered item_id]" ] + foreach p [$pages children] { + $p set page_order $page_order([$p set name]) + } + + $pages mixin add ::xo::OrderedComposite::IndexCompare + $pages orderby page_order + return [my render_children $pages] + } + + selection instproc render_children {pages} { + my instvar package_id edit_links + foreach o [$pages children] { + $o instvar page_order title page_id name title + set level [expr {[regsub {[.]} $page_order . page_order] + 1}] + set edit_markup "" + set p [::Generic::CrItem instantiate -item_id 0 -revision_id $page_id] + $p destroy_on_cleanup + if {$edit_links} { + set p_link [$package_id pretty_link $name] + set edit_link [$package_id make_link -link $p_link $p edit return_url] + if {$edit_link ne ""} { + set edit_markup "
      " + } + } + $p set unresolved_references 0 + switch [$p info class] { + ::xowiki::Form { + set content [$p render] + } + default { + set content [$p get_content] + set content [string map [list "\{\{" "\\\{\{"] $content] + } + } + append output "" \ + $edit_markup \ + "$page_order $title" \ + $content + } + return $output + } + + Class create composite-form \ + -superclass ::xowiki::portlet::selection \ + -parameter { + {parameter_declaration { + {-edit_links:boolean false} + {-pages ""} + {-ordered_pages} + }} + } + + composite-form instproc render {} { + my get_parameters + my instvar __including_page + set inner_html [next] + #my log "innerhtml=$inner_html" + regsub -nocase -all "
      " $inner_html "
      " inner_html + regsub -nocase -all "" $inner_html "
      " inner_html + dom parse -simple -html
      $inner_html
      doc + $doc documentElement root + + set fields [$root selectNodes "//div\[@class = 'wiki-menu'\]"] + foreach field $fields {$field delete} + + set inner_html [$root asHTML] + set id ID[$__including_page item_id] + set base [$package_id pretty_link [$__including_page name]] + #set id ID$item_id + #$root setAttribute id $id + set as_att_value [string map [list & "&" < "<" > ">" \" """ ' "'"] $inner_html] + + set save_form [subst { +

      + Create Form from Content +

      + + }] + + return $inner_html$save_form + } + + ############################################################################# + # book style + # + Class create book \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-category_id} + {-menu_buttons edit-item-button} + }} + } + + book instproc render {} { + my get_parameters + + my instvar __including_page + lappend ::xowiki_page_item_id_rendered [$__including_page item_id] + $__including_page set __is_book_page 1 + + set extra_where_clause "" + set cnames "" + if {[info exists category_id]} { + foreach {cnames extra_where_clause} [my category_clause $category_id] break + } + + set pages [::xowiki::Page instantiate_objects -sql \ + "select page_id, page_order, name, title, item_id \ + from xowiki_page_live_revision p \ + where parent_id = [$package_id folder_id] \ + and not page_order is NULL $extra_where_clause \ + [::xowiki::Page container_already_rendered item_id]" ] + $pages mixin add ::xo::OrderedComposite::IndexCompare + $pages orderby page_order + + set output "" + if {$cnames ne ""} { + append output "
      Filtered by categories: $cnames
      " + } + set return_url [::xo::cc url] + + foreach o [$pages children] { + $o instvar page_order title page_id name title + set level [expr {[regsub {[.]} $page_order . page_order] + 1}] + set p [::Generic::CrItem instantiate -item_id 0 -revision_id $page_id] + $p destroy_on_cleanup + + $p set unresolved_references 0 + #$p set render_adp 0 + switch [$p info class] { + ::xowiki::Form { + set content [$p render] + } + default { + set content [$p get_content] + set content [string map [list "\{\{" "\\\{\{"] $content] + } + } + set menu [list] + foreach b $menu_buttons { + set html [$p include_portlet [list $b -book_mode true]] + if {$html ne ""} {lappend menu $html} + } + append output "" \ + "
      " [join $menu " "] "
      " \ + "$page_order $title
      " \ + $content + } + return $output + } +} + +namespace eval ::xowiki::portlet { + Class create item-button \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + } + + item-button instproc render_button { + -page + -package_id + -method + -src + -alt + -title + -return_url + -page_order + -object_type + } { + set html "" + if {![info exists return_url]} {set return_url $p_link} + if {![info exists alt]} {set alt $method} + if {[$page istype ::xowiki::Package]} { + set edit_link [$package_id make_link $package_id \ + edit-new page_order object_type return_url autoname] + } else { + set p_link [$package_id pretty_link [$page name]] + set edit_link [$package_id make_link -link $p_link $page $method return_url page_order] + } + + if {$edit_link ne ""} { + set html "\"$alt\"" + } + return $html + } + + Class create edit-item-button -superclass ::xowiki::portlet::item-button \ + -parameter { + {parameter_declaration { + {-page_id} + {-title "#xowiki.edit#"} + {-alt "edit"} + {-book_mode false} + }} + } + + edit-item-button instproc render {} { + my get_parameters + my instvar __including_page + set page [expr {[info exists page_id] ? $page_id : $__including_page}] + if {[$page istype ::xowiki::FormPage]} { + set template [$page page_template] + set title "$title [$template title] [$page name]" + } + set return_url [::xo::cc url] + if {$book_mode} { + append return_url #[toc anchor [$page name]] + } + return [my render_button \ + -page $page -method edit -package_id $package_id \ + -title $title -alt $alt -return_url $return_url \ + -src /resources/acs-subsite/Edit16.gif] + } + + Class create delete-item-button -superclass ::xowiki::portlet::item-button \ + -parameter { + {__decoration none} + {parameter_declaration { + {-page_id} + {-title "#xowiki.delete#"} + {-alt "delete"} + {-book_mode false} + }} + } + + delete-item-button instproc render {} { + my get_parameters + my instvar __including_page + set page [expr {[info exists page_id] ? $page_id : $__including_page}] + return [my render_button \ + -page $page -method delete -package_id $package_id \ + -title $title -alt $alt \ + -return_url [::xo::cc url] \ + -src /resources/acs-subsite/Delete16.gif] + } + + Class create create-item-button -superclass ::xowiki::portlet::item-button \ + -parameter { + {__decoration none} + {parameter_declaration { + {-page_id} + {-alt "new"} + {-book_mode false} + }} + } + + create-item-button instproc render {} { + my get_parameters + my instvar __including_page + set page [expr {[info exists page_id] ? $page_id : $__including_page}] + set page_order [::xowiki::Portlet incr_page_order [$page page_order]] + if {[$page istype ::xowiki::FormPage]} { + set template [$page page_template] + return [my render_button \ + -page $template -method create-new -package_id $package_id \ + -title [_ xowiki.create_new_entry_of_type [list type [$template title]]] \ + -alt $alt -page_order $page_order \ + -return_url [::xo::cc url] \ + -src /resources/acs-subsite/Add16.gif] + } else { + set object_type [$__including_page info class] + return [my render_button \ + -page $package_id -method edit_new -package_id $package_id \ + -title [_ xowiki.create_new_entry_of_type [list type $object_type]] \ + -alt $alt -page_order $page_order \ + -return_url [::xo::cc url] \ + -object_type $object_type \ + -src /resources/acs-subsite/Add16.gif] + } + } + +} + + +namespace eval ::xowiki::portlet { + + Class create graph \ + -superclass ::xowiki::Portlet \ + -parameter {{__decoration plain}} + + graph instproc graphHTML {-edges -nodes -max_edges -cutoff -base {-attrib node_id}} { + + ::xowiki::Page requireJS "/resources/ajaxhelper/prototype/prototype.js" + set user_agent [string tolower [ns_set get [ns_conn headers] User-Agent]] + if {[string match "*msie *" $user_agent]} { + # canvas support for MSIE + ::xowiki::Page requireJS "/resources/xowiki/excanvas.js" + } + ::xowiki::Page requireJS "/resources/xowiki/collab-graph.js" + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/yahoo/yahoo.js" + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/event/event.js" + + set nodesHTML "" + array set n $nodes + + foreach {node label} $nodes { + set link "$label" + append nodesHTML "
          $link
      \n" + } + + set edgesHTML ""; set c 0 + foreach p [lsort -index 1 -decreasing -integer $edges] { + foreach {edge weight width} $p break + foreach {a b} [split $edge ,] break + #my log "--G $a -> $b check $c > $max_edges, $weight < $cutoff" + if {[incr c]>$max_edges} break + if {$weight < $cutoff} continue + append edgesHTML "g.addEdge(\$('$a'), \$('$b'), $weight, 0, $width);\n" + } + # [lsort -index 1 -decreasing -integer $edges]
      [set cutoff] - [set c]
      + + return [subst -novariables { +
      + + +[set nodesHTML] + +
      +}] + } +} + +namespace eval ::xowiki::portlet { + Class create collab-graph \ + -superclass ::xowiki::portlet::graph \ + -parameter { + {parameter_declaration { + {-max_edges 70} + {-cutoff 0.1} + {-show_anonymous "message"} + -user_id + }} + } + + collab-graph instproc render {} { + my get_parameters + + if {$show_anonymous ne "all" && [::xo::cc user_id] eq 0} { + return "You must login to see the [namespace tail [self class]]" + } + if {![info exists user_id]} {set user_id [::xo::cc user_id]} + + set folder_id [$package_id folder_id] + db_foreach [my qn get_collaborators] { + select count(revision_id), item_id, creation_user + from cr_revisions r, acs_objects o + where item_id in + (select distinct i.item_id from + acs_objects o, acs_objects o2, cr_revisions cr, cr_items i + where o.object_id = i.item_id and o2.object_id = cr.revision_id + and o2.creation_user = :user_id and i.item_id = cr.item_id + and i.parent_id = :folder_id order by item_id + ) + and o.object_id = revision_id + and creation_user is not null + group by item_id, creation_user} { + + lappend i($item_id) $creation_user $count + set count_var user_count($creation_user) + if {![info exists $count_var]} {set $count_var 0} + incr $count_var $count + set user($creation_user) "[::xo::get_user_name $creation_user] ([set $count_var])" + if {![info exists activities($creation_user)]} {set activities($creation_user) 0} + incr activities($creation_user) $count + } + + set result "

      Collaboration Graph for [::xo::get_user_name $user_id] in this wiki" + if {[array size i] < 1} { + append result "

      No collaborations found

      " + } else { + + foreach x [array names i] { + foreach {u1 c1} $i($x) { + foreach {u2 c2} $i($x) { + if {$u1 < $u2} { + set var collab($u1,$u2) + if {![info exists $var]} {set $var 0} + incr $var $c1 + incr $var $c2 + } + } + } + } + + set max 50 + foreach x [array names collab] { + if {$collab($x) > $max} {set max $collab($x)} + } + + set edges [list] + foreach x [array names collab] { + lappend edges [list $x $collab($x) [expr {$collab($x)*5.0/$max}]] + } + + append result "($activities($user_id) contributions)

      \n" + append result [my graphHTML \ + -nodes [array get user] -edges $edges \ + -max_edges $max_edges -cutoff $cutoff \ + -base collab -attrib user_id] + } + + return $result + } + + + Class create activity-graph \ + -superclass ::xowiki::portlet::graph \ + -parameter { + {parameter_declaration { + {-max_edges 70} + {-cutoff 0.1} + {-max_activities:integer 100} + {-show_anonymous "message"} + }} + } + + activity-graph instproc render {} { + my get_parameters + + if {$show_anonymous ne "all" && [::xo::cc user_id] eq 0} { + return "You must login to see the [namespace tail [self class]]" + } + + set folder_id [$package_id folder_id] + + # there must be a better way to handle temporaray tables safely.... + catch {db_dml [my qn drop_temp_table] {drop table XOWIKI_TEMP_TABLE}} + + set sql "create global temporary table XOWIKI_TEMP_TABLE on commit preserve rows as " + set subquery [::xo::db::sql select \ + -vars "i.item_id, revision_id, creation_user" \ + -from "cr_revisions cr, cr_items i, acs_objects o" \ + -where "cr.item_id = i.item_id and i.parent_id = $folder_id \ + and o.object_id = revision_id" \ + -orderby "revision_id desc" \ + -limit $max_activities] + + # this is currently a rather ugly hack to get the suff quicky working in oracle. + # TODO: cleanup, different methods for oracle and postgres for handling temporary tables + if {[catch {db_dml [my qn get_n_most_recent_contributions] $sql$subquery}]} { + db_dml . "insert into XOWIKI_TEMP_TABLE (item_id,revision_id,creation_user) ($subquery)" + } + + set total 0 + db_foreach [my qn get_activities] { + select count(revision_id),item_id, creation_user + from XOWIKI_TEMP_TABLE + where creation_user is not null + group by item_id, creation_user + } { + lappend i($item_id) $creation_user $count + incr total $count + set count_var user_count($creation_user) + if {![info exists $count_var]} {set $count_var 0} + incr $count_var $count + set user($creation_user) "[::xo::get_user_name $creation_user] ([set $count_var])" + } + + if {[catch {db_dml [my qn drop_temp_table] {drop table XOWIKI_TEMP_TABLE}} ]} { + db_dml [my qn trunc_temp_table] {truncate table XOWIKI_TEMP_TABLE } + } + + if {[array size i] == 0} { + append result "

      No activities found

      " + } elseif {[array size user] == 1} { + set user_id [lindex [array names user] 0] + append result "

      Last $total activities were done by user " \ + "[::xo::get_user_name $user_id]." + } else { + append result "

      Collaborations in last $total activities by [array size user] Users in this wiki

      " + + foreach x [array names i] { + foreach {u1 c1} $i($x) { + foreach {u2 c2} $i($x) { + if {$u1 < $u2} { + set var collab($u1,$u2) + if {![info exists $var]} {set $var 0} + incr $var $c1 + incr $var $c2 + } + } + } + } + + set max 0 + foreach x [array names collab] { + if {$collab($x) > $max} {set max $collab($x)} + } + + set edges [list] + foreach x [array names collab] { + lappend edges [list $x $collab($x) [expr {$collab($x)*5.0/$max}]] + } + + append result [my graphHTML \ + -nodes [array get user] -edges $edges \ + -max_edges $max_edges -cutoff $cutoff \ + -base collab -attrib user_id] + } + + return $result + } + + Class create timeline \ + -superclass ::xowiki::Portlet \ + -parameter { + {parameter_declaration { + -user_id + {-data timeline-data} + {-interval1 DAY} + {-interval2 MONTH} + }} + } + + timeline instproc render {} { + my get_parameters + + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/yahoo/yahoo.js" + ::xowiki::Page requireJS "/resources/ajaxhelper/yui/event/event.js" + ::xowiki::Page requireJS "/resources/xowiki/timeline/api/timeline-api.js" + + set stamp [clock format [clock seconds] -format "%b %d %Y %X %Z" -gmt true] + if {[info exists user_id]} {append data "?user_id=$user_id"} + + return [subst -nocommands -nobackslashes { +
      + + + }] + } + + Class create user-timeline \ + -superclass timeline \ + -parameter { + {parameter_declaration { + -user_id + {-data timeline-data} + {-interval1 DAY} + {-interval2 MONTH} + }} + } + + user-timeline instproc render {} { + my get_parameters + if {![info exists user_id]} {set user_id [::xo::cc user_id]]} + ::xo::cc set_parameter user_id $user_id + next + } + +} + + +namespace eval ::xowiki::portlet { + ############################################################################# + Class create form-menu \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-form_item_id:integer,required} + }} + } + + form-menu instproc render {} { + my get_parameters + # todo return_url + my instvar __including_page + set base [$package_id pretty_link [$__including_page name]] + set new_link [$package_id make_link -link $base $__including_page create-new return_url] + set answer_link [$package_id make_link -link $base $__including_page list return_url] + set template [::Generic::CrItem instantiate -item_id $form_item_id] + set count [$template count_usages] + set links [list] + foreach l [list new_link answer_link] { + if {[set $l] ne ""} { + set label #xowiki.form-menu-$l# + if {$l eq "answer_link"} {append label " ($count) "} + lappend links "$label" + } + } + return "
      [join $links { · }]
      \n" + } + + ############################################################################# + Class create form-entry-menu \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + }} + } + + form-entry-menu instproc render {} { + my get_parameters + my instvar __including_page + set form [$__including_page page_template] + set base [$package_id pretty_link [$form name]] + return "\n" + } + + ############################################################################# + Class create form-usages \ + -superclass ::xowiki::Portlet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-form_item_id:integer} + {-form} + {-orderby "_last_modified,desc"} + {-all:boolean false} + {-field_names} + {-csv false} + }} + } + + form-usages instproc render {} { + my get_parameters + my instvar __including_page + + ::xowiki::Page requireCSS "/resources/acs-templating/lists.css" + set return_url [::xo::cc url]?[::xo::cc actual_query] + + if {![info exists form_item_id]} { + set form_item_id [::xowiki::Form lookup -name $form -parent_id $folder_id] + if {$form_item_id == 0} {error "Cannot lookup page $form"} + } + + set form_item [::xowiki::Form instantiate -item_id $form_item_id] + $form_item destroy_on_cleanup + + if {![info exists field_names]} { + set fn [::xowiki::PageInstance get_short_spec_from_form_constraints \ + -name @table \ + -form_constraints [$form_item form_constraints]] + set field_names [split $fn ,] + } + if {$field_names eq ""} { + set field_names {_name _last_modified _creation_user} + } + + set sql_atts [list instance_attributes] + foreach att [::xowiki::FormPage edit_atts] {set __att($att) 1} + set common_atts [list last_modified creation_user name] + foreach att $common_atts { + lappend sql_atts p.$att + set __att($att) 1 + } + + set form_constraints [$form_item form_constraints] + # set cr_field_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ + # -name @cr_fields \ + # -form_constraints $form_constraints] + # if some fields are hidden in the form, there might still be values (creation_user, etc) + # maybe filter hidden? ignore for the time being. + set cr_field_spec "" + # + set field_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ + -name @fields \ + -form_constraints $form_constraints] + + foreach spec_name $field_names { + set short_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ + -name $spec_name \ + -form_constraints $form_constraints] + + switch -glob -- $spec_name { + __* {error not_allowed} + _* { + set varname [string range $spec_name 1 end] + if {![info exists __att($varname)]} { + error "unknown attribute $spec_name" + } + set f [$form_item create_form_field \ + -name $spec_name \ + -slot [$form_item find_slot $varname] \ + -spec $cr_field_spec,$short_spec] + lappend sql_atts p.$varname + } + default { + set f [$form_item create_form_field \ + -name $spec_name \ + -slot "" \ + -spec $field_spec,$short_spec] + } + } + lappend form_fields $f + set __ff($spec_name) $f + } + #my msg ff=[array names __ff] + #$form_item show_fields $form_fields + + if {[info exists __ff(_creation_user)]} {$__ff(_creation_user) label "By User"} + + set cols "" + append cols {ImageField_EditIcon edit -label "" -html {style "padding: 2px;"}} \n + foreach fn $field_names { + append cols [list AnchorField $fn -label [$__ff($fn) label] -orderby $fn] \n + } + append cols [list ImageField_DeleteIcon delete -label "" ] \n + + TableWidget t1 -volatile -columns $cols + + # + # Sorting is done for the time being in tcl. This has the advantage + # that page_orders can be sorted with the special mixin and that + # instance attributes can be used for sorting as well. + # + foreach {att order} [split $orderby ,] break + if {$att eq "_page_order"} { + t1 mixin add ::xo::OrderedComposite::IndexCompare + } + t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] $att + + # + # build SQL query and iterate over the results + # maybe this could be slightly faster by using instantiate_objects + # + set publish_status_clause [expr {$all ? "" : " and ci.publish_status <> 'production' "}] + set items [::xowiki::FormPage instantiate_all \ + -select_attributes $sql_atts \ + -from_clause ", xowiki_form_pagex p" \ + -with_subtypes false \ + -where_clause " p.page_template = $form_item_id \ + and p.xowiki_form_page_id = cr.revision_id \ + $publish_status_clause" \ + -folder_id [$package_id folder_id]] + $items destroy_on_cleanup + + foreach p [$items children] { + $p set package_id $package_id + + array set __ia [$p set instance_attributes] + set page_link [$package_id pretty_link [$p name]] + + t1 add \ + -delete delete \ + -delete.href [$package_id make_link -link $page_link $p delete return_url] \ + -edit edit \ + -edit.href [$package_id make_link -link $page_link $p edit return_url] + + set __c [t1 last_child] + $__c set _name.href $page_link + foreach __fn $field_names { + switch -glob -- $__fn { + __* {error not_allowed} + _* {set __value [$p set [string range $__fn 1 end]]} + default { + if {[info exists __ia($__fn)]} { + set __value $__ia($__fn) + } else { + # the field was added after the current entry was created + set __value "" + } + } + } + if {[$__ff($__fn) istype ::xowiki::FormField::richtext]} { + $__c set $__fn.richtext 1 + } + $__c set $__fn [$__ff($__fn) pretty_value $__value] + } + } + + if {$csv} { + return [t1 write_csv] + } + + set base [$package_id pretty_link [$__including_page name]] + set label [$__including_page name] + append html [_ xowiki.entries_using_form [list form "$label

      "]] + append html [t1 asHTML] + append html "csv" + return $html + } +} + \ No newline at end of file Index: openacs-4/packages/xowiki/tcl/xowiki-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/xowiki-procs.tcl 1 Aug 2007 21:39:24 -0000 1.162.2.2 @@ -0,0 +1,1386 @@ +ad_library { + XoWiki - main libraray classes and objects + + @creation-date 2006-01-10 + @author Gustaf Neumann + @cvs-id $Id: xowiki-procs.tcl,v 1.162.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki { + # + # create classes for different kind of pages + # + ::Generic::CrClass create Page -superclass ::Generic::CrItem \ + -pretty_name "XoWiki Page" -pretty_plural "XoWiki Pages" \ + -table_name "xowiki_page" -id_column "page_id" \ + -mime_type text/html \ + -cr_attributes { + if {[::xo::db::has_ltree]} { + ::Generic::Attribute new -attribute_name page_order -datatype text \ + -sqltype ltree -validator page_order + } + ::Generic::Attribute new -attribute_name creator -datatype text + } \ + -parameter { + page_id + {revision_id 0} + item_id + object_type + parent_id + package_id + name + title + text + description + nls_language + {folder_id -100} + {lang en} + {render_adp 1} + {absolute_links 0} + last_modified + creation_user + } \ + -form ::xowiki::WikiForm + + # TODO: the following slot definitions are not meant to stay this way. + # when we change to the xotcl 1.5.0+ slots, this will go away + if {$::xotcl::version < 1.5} { + if {![::xotcl::Object isobject ::xowiki::Page::slot]} { + ::xotcl::Object create ::xowiki::Page::slot + } + foreach parameter {name title description text nls_language publish_date creation_user last_modified} { + if {![::xotcl::Object isobject ::xowiki::Page::slot::$parameter]} { + ::xo::Attribute create ::xowiki::Page::slot::$parameter + } + } + } + + ::xowiki::Page::slot::name set pretty_name #xowiki.Page-name# + ::xowiki::Page::slot::name set required true + ::xowiki::Page::slot::name set help_text #xowiki.Page-name-help_text# + ::xowiki::Page::slot::name set datatype text + ::xowiki::Page::slot::name set validator name + + ::xowiki::Page::slot::title set pretty_name #xowiki.Page-title# + ::xowiki::Page::slot::title set required true + ::xowiki::Page::slot::title set datatype text + + ::xowiki::Page::slot::description set pretty_name #xowiki.Page-description# + ::xowiki::Page::slot::description set spec "textarea,cols=80,rows=2" + ::xowiki::Page::slot::description set datatype text + + ::xowiki::Page::slot::text set pretty_name #xowiki.Page-text# + ::xowiki::Page::slot::text set spec "richtext" + ::xowiki::Page::slot::text set datatype text + + ::xowiki::Page::slot::nls_language set pretty_name #xowiki.Page-nls_language# + ::xowiki::Page::slot::nls_language set datatype text + ::xowiki::Page::slot::nls_language set spec {select,options=[xowiki::locales]} + + ::xowiki::Page::slot::last_modified set pretty_name #xowiki.Page-last_modified# + ::xowiki::Page::slot::last_modified set spec date + + ::xowiki::Page::slot::creation_user set spec user_id + + ::Generic::CrClass create PlainPage -superclass Page \ + -pretty_name "XoWiki Plain Page" -pretty_plural "XoWiki Plain Pages" \ + -table_name "xowiki_plain_page" -id_column "ppage_id" \ + -mime_type text/plain \ + -form ::xowiki::PlainWikiForm + + ::Generic::CrClass create File -superclass Page \ + -pretty_name "XoWiki File" -pretty_plural "XoWiki Files" \ + -table_name "xowiki_file" -id_column "file_id" \ + -storage_type file \ + -form ::xowiki::FileForm + + ::Generic::CrClass create PodcastItem -superclass File \ + -pretty_name "Podcast Item" -pretty_plural "Podcast Items" \ + -table_name "xowiki_podcast_item" -id_column "podcast_item_id" \ + -cr_attributes { + ::Generic::Attribute new -attribute_name pub_date -datatype date \ + -sqltype timestamp -spec "date,format=YYYY_MM_DD_HH24_MI" + ::Generic::Attribute new -attribute_name duration -datatype text \ + -help_text "#xowiki.PodcastItem-duration-help_text#" + ::Generic::Attribute new -attribute_name subtitle -datatype text + ::Generic::Attribute new -attribute_name keywords -datatype text \ + -help_text "#xowiki.PodcastItem-keywords-help_text#" + } \ + -storage_type file \ + -form ::xowiki::PodcastForm + + ::Generic::CrClass create PageTemplate -superclass Page \ + -pretty_name "XoWiki Page Template" -pretty_plural "XoWiki Page Templates" \ + -table_name "xowiki_page_template" -id_column "page_template_id" \ + -cr_attributes { + ::Generic::Attribute new -attribute_name anon_instances -datatype boolean \ + -sqltype boolean -default "f" + } \ + -form ::xowiki::PageTemplateForm + + ::Generic::CrClass create PageInstance -superclass Page \ + -pretty_name "XoWiki Page Instance" -pretty_plural "XoWiki Page Instances" \ + -table_name "xowiki_page_instance" -id_column "page_instance_id" \ + -cr_attributes { + ::Generic::Attribute new -attribute_name page_template \ + -datatype integer -sqltype integer -references cr_items(item_id) + ::Generic::Attribute new -attribute_name instance_attributes \ + -datatype text -sqltype long_text -default "" + } \ + -form ::xowiki::PageInstanceForm \ + -edit_form ::xowiki::PageInstanceEditForm + + ::Generic::CrClass create Object -superclass PlainPage \ + -pretty_name "XoWiki Object" -pretty_plural "XoWiki Objects" \ + -table_name "xowiki_object" -id_column "xowiki_object_id" \ + -mime_type text/xotcl \ + -form ::xowiki::ObjectForm + + ::Generic::CrClass create Form -superclass PageTemplate \ + -pretty_name "XoWiki Form" -pretty_plural "XoWiki Forms" \ + -table_name "xowiki_form" -id_column "xowiki_form_id" \ + -cr_attributes { + ::Generic::Attribute new -attribute_name form \ + -datatype text -sqltype long_text -default "" + ::Generic::Attribute new -attribute_name form_constraints \ + -datatype text -sqltype long_text -default "" \ + -validator form_constraints -spec "textarea,cols=100,rows=2" + } \ + -form ::xowiki::FormForm + + ::Generic::CrClass create FormPage -superclass PageInstance \ + -pretty_name "XoWiki FormPage" -pretty_plural "XoWiki FormPages" \ + -table_name "xowiki_form_page" -id_column "xowiki_form_page_id" + + #::Generic::CrClass create FormInstance -superclass PageInstance \ + # -pretty_name "XoWiki FormInstance" -pretty_plural "XoWiki FormInstances" \ + # -table_name "xowiki_form_instance" -id_column "xowiki_form_instance_id" + + # + # create various extra tables, indices and views + # + ::xo::db::require table xowiki_references \ + "reference integer references cr_items(item_id) on delete cascade, + link_type [::xo::db::sql map_datatype text], + page integer references cr_items(item_id) on delete cascade" + ::xo::db::require index -table xowiki_references -col reference + + + ::xo::db::require table xowiki_last_visited \ + "page_id integer references cr_items(item_id) on delete cascade, + package_id integer, + user_id integer, + count integer, + time timestamp" + ::xo::db::require index -table xowiki_last_visited -col user_id,page_id -unique true + ::xo::db::require index -table xowiki_last_visited -col user_id,package_id + ::xo::db::require index -table xowiki_last_visited -col time + + # Oracle has a limit of 3118 characters for keys, therefore no text as type for "tag" + ::xo::db::require table xowiki_tags \ + "item_id integer references cr_items(item_id) on delete cascade, + package_id integer, + user_id integer references users(user_id), + tag varchar(3000), + time timestamp" + ::xo::db::require index -table xowiki_tags -col user_id,item_id + ::xo::db::require index -table xowiki_tags -col tag,package_id + + + if {[::xo::db::has_ltree]} { + ::xo::db::require index -table xowiki_page -col page_order -using gist + } + + set sortkeys [expr {[db_driverkey ""] eq "oracle" ? "" : ", ci.tree_sortkey, ci.max_child_sortkey"}] + ::xo::db::require view xowiki_page_live_revision \ + "select p.*, cr.*,ci.parent_id, ci.name, ci.locale, ci.live_revision, \ + ci.latest_revision, ci.publish_status, ci.content_type, ci.storage_type, \ + ci.storage_area_key $sortkeys \ + from xowiki_page p, cr_items ci, cr_revisions cr \ + where p.page_id = ci.live_revision \ + and p.page_id = cr.revision_id \ + and ci.publish_status <> 'production'" + + # + # Page definitions + # + + + Page set recursion_count 0 + Page array set RE { + include {([^\\]){{([^<]+?)}}(\s|<|$)?} + anchor {([^\\])\\\[\\\[([^\]]+?)\\\]\\\]} + div {()([^\\])>>([^&<]*?)<<()([ \n]*)?} + clean {[\\](\{\{|>>|\[\[)} + clean2 {
      *(\n" + } + if {[info exists ::js_order]} { + foreach file $::js_order { + if {[string match "*;*" $file]} { + # it is not a file, but some javascipt statements + append result "\n" + } else { + append result "\n" + } + } + } + return $result + } + Page proc quoted_html_content text { + list [ad_text_to_html $text] text/html + } + + # + # Operations on the whole instance + # + + # + # Page marshall/demarshall + # + + + Page instproc marshall {} { + my instvar name + if {[regexp {^..:[0-9]+$} $name] || + [regexp {^[0-9]+$} $name]} { + # + # for anonymous entries, names might clash in the target + # instance. If we create on the target site for anonymous + # entries always new instances, we end up with duplicates. + # Therefore, we rename anonymous entries during export to + # ip_address:port/item_id + # + set old_name $name + set server [ns_info server] + set port [ns_config ns/server/${server}/module/nssock port] + set name [ns_info address]:${port}/[my item_id] + set content [my serialize] + set name $old_name + } else { + set content [my serialize] + } + return $content + } + + File instproc marshall {} { + set fn [my full_file_name] + set F [open $fn] + fconfigure $F -translation binary + set C [read $F] + close $F + my set __file_content [::base64::encode $C] + next + } + + Page instproc demarshall {-parent_id -package_id -creation_user} { + # this method is the counterpart of marshall + my set parent_id $parent_id + my set package_id $package_id + my set creation_user $creation_user + # + # if we import from an instance without page_orders into an instance + # with page_orders, we need default values + if {[::xo::db::has_ltree] && ![my exists page_order]} { + my set page_order "" + } + # in the general case, no more actions required + } + + File instproc demarshall {args} { + next + # we have to care about recoding the file content + my instvar import_file __file_content + set import_file [ns_tmpnam] + set F [open $import_file w] + fconfigure $F -translation binary + puts -nonewline $F [::base64::decode $__file_content] + close $F + } + + # set default values. + # todo: with slots, it should be easier to set default values + # for non existing variables + PageInstance instproc demarshall {args} { + # some older versions do not have anon_instances + if {![my exists anon_instances]} { + my set anon_instances "f" + } + next + } + Form instproc demarshall {args} { + # some older versions do not have anon_instances + if {![my exists anon_instances]} { + my set anon_instances "t" + } + next + } + + Page instproc copy_content_vars {-from_object:required} { + array set excluded_var { + folder_id 1 package_id 1 absolute_links 1 lang_links 1 + publish_status 1 item_id 1 revision_id 1 last_modified 1 parent_id 1 + } + foreach var [$from_object info vars] { + if {![info exists excluded_var($var)]} { + my set $var [$from_object set $var] + } + } + } + + Page proc import {-user_id -package_id -folder_id {-replace 0} -objects} { + my log "DEPRECATED" + if {![info exists package_id]} {set package_id [::xo::cc package_id]} + set cmd [list $package_id import -replace $replace] + + if {[info exists user_id]} {lappend cmd -user_id $user_id} + if {[info exists objects]} {lappend cmd -objects $objects} + eval $cmd + } + + # + # tag management, get_tags works on instance or gobally + # + + Page proc save_tags {-package_id:required -item_id:required -user_id:required tags} { + db_dml [my qn delete_tags] \ + "delete from xowiki_tags where item_id = $item_id and user_id = $user_id" + foreach tag $tags { + db_dml [my qn insert_tag] \ + "insert into xowiki_tags (item_id,package_id, user_id, tag, time) \ + values ($item_id, $package_id, $user_id, :tag, current_timestamp)" + } + } + Page proc get_tags {-package_id:required -item_id -user_id} { + if {[info exists item_id]} { + if {[info exists user_id]} { + # tags for item and user + set tags [db_list [my qn get_tags] \ + "SELECT distinct tag from xowiki_tags \ + where user_id=$user_id and item_id=$item_id and package_id=$package_id"] + } else { + # all tags for this item + set tags [db_list [my qn get_tags] \ + "SELECT distinct tag from xowiki_tags \ + where item_id=$item_id and package_id=$package_id"] + } + } else { + if {[info exists user_id]} { + # all tags for this user + set tags [db_list [my qn get_tags] \ + "SELECT distinct tag from xowiki_tags \ + where user_id=$user_id and package_id=$package_id"] + } else { + # all tags for the package + set tags [db_list [my qn get_tags] \ + "SELECT distinct tag from xowiki_tags \ + where package_id=$package_id"] + } + } + join $tags " " + } + + + # + # Methods of ::xowiki::Page + # + + Page instforward query_parameter {%my set package_id} %proc + Page instforward exists_query_parameter {%my set package_id} %proc + Page instforward form_parameter {%my set package_id} %proc + Page instforward exists_form_parameter {%my set package_id} %proc + + Page instproc complete_name {name {nls_language ""}} { + if {![regexp {^..:} $name]} { + if {$name ne ""} { + # prepend the language prefix only, if the entry is not empty + if {$nls_language eq ""} {set nls_language [my set nls_language]} + set name [string range $nls_language 0 1]:$name + } + } + } + +# Page instproc init {} { +# my log "--W " +# ::xo::show_stack +# next +# } + +# Page instproc destroy {} { +# my log "--W " +# ::xo::show_stack +# next +# } + + Page instproc initialize_loaded_object {} { + my instvar title + if {[info exists title] && $title eq ""} {set title [my set name]} + next + } + + Page instproc regsub_eval {{-noquote:boolean false} re string cmd} { + if {$noquote} { + set map { \[ \\[ \] \\] \$ \\$ \\ \\\\} + } else { + set map { \" \\\" \[ \\[ \] \\] \$ \\$ \\ \\\\} + } +# my msg "re=$re, string=$string cmd=$cmd" +# set c [regsub -all $re [string map { \[ \\[ \] \\] \ +# \$ \\$ \\ \\\\} $string] \ +# "\[$cmd\]"] +# my msg c=$c +# set s [subst $c] +# my msg s=$s +# return $s + uplevel [list subst [regsub -all $re [string map $map $string] "\[$cmd\]"]] + } + + Page instproc error_during_render {msg} { + return "
      $msg
      " + } + + Page instproc error_in_includelet {arg msg} { + my instvar name + return [my error_during_render "[_ xowiki.error_in_includelet]
      \n$msg"] + } + + Page instproc include_portlet {arg} { + # we want to use package_id as proc-local variable, since the + # cross package reference might alter it locally + set package_id [my package_id] + + # do we have a wellformed list? + if {[catch {set page_name [lindex $arg 0]} errMsg]} { + #my log "--S arg='$arg'" + # there is something syntactically wrong + return [my error_in_includelet $arg [_ xowiki.error-includelet-dash_syntax_invalid]] + } + + # the include is either a portlet class, or a wiki page + if {[my isclass ::xowiki::portlet::$page_name]} { + # direct call, without page, not tailorable + set page [::xowiki::portlet::$page_name new \ + -package_id $package_id \ + -name $page_name \ + -actual_query [::xo::cc actual_query]] + } else { + # + # Include a wiki page, tailorable. + # + # For the resolver, we create a fresh context to avoid recursive loops, when + # e.g. revision_id is set through a query parameter... + # + set last_context [expr {[my exists context] ? $context : "::xo::cc"}] + + if {[regexp {^/(/[^?]*)[?]?(.*)$} $page_name _ url query]} { + # + # Handle cross package xowiki includes. + # Note, that package::initialize might change the package id. + # + ::xowiki::Package initialize -parameter {{-m view}} -url $url \ + -actual_query $query + if {$package_id != 0} { + $package_id context [::xo::Context new -volatile] + set object_name [$package_id set object] + # A user might force the language by preceding the + # name with a language prefix. + if {![regexp {^..:} $object_name]} { + set object_name [my lang]:$object_name + } + set page [$package_id resolve_page $object_name __m] + #my msg "cross package reference $page_name ==> $page, package_id=$package_id" + } + #my log "--resolve --> $page" + } else { + $package_id context [::xo::Context new -volatile] + set page [$package_id resolve_page $page_name __m] + } + $package_id context $last_context + + if {$page ne "" && ![$page exists __decoration]} { + $page set __decoration portlet + } + } + + if {$page ne ""} { + my set __last_includelet $page + $page destroy_on_cleanup + $page set __including_page [self] + $page set __caller_parameters [lrange $arg 1 end] + #$page set __decoration portlet + foreach {att value} [$page set __caller_parameters] { + switch -- $att { + -decoration {$page set __decoration $value} + -title {$page set title $value} + } + } + if {[$page exists __decoration] && [$page set __decoration] ne "none"} { + $page mixin add ::xowiki::portlet::decoration=[$page set __decoration] + } + + if {[catch {set html [$page render]} errorMsg]} { + set html [my error_during_render [_ xowiki.error-includelet-error_during_render]] + } + #my log "--include portlet returns $html" + return $html + } else { + return [my error_during_render [_ xowiki.error-includelet-unknown]] + } + } + + Page instproc include {ch arg ch2} { + # make recursion depth a global variable to ease the deletion etc. + if {[catch {incr ::xowiki_inclusion_depth}]} { + set ::xowiki_inclusion_depth 1 + } + if {$::xowiki_inclusion_depth > 10} { + return ${ch}[my error_in_includelet $arg [_ xowiki.error-includelet-nesting_to_deep]] + } + if {[regexp {^adp (.*)$} $arg _ adp]} { + if {[catch {lindex $adp 0} errMsg]} { + # there is something syntactically wrong + incr ::xowiki_inclusion_depth -1 + return ${ch}[my error_in_includelet $arg [_ xowiki.error-includelet-adp_syntax_invalid]] + } + set adp [string map {  " "} $adp] + set adp_fn [lindex $adp 0] + if {![string match "/*" $adp_fn]} {set adp_fn /packages/xowiki/www/$adp_fn} + set adp_args [lindex $adp 1] + if {[llength $adp_args] % 2 == 1} { + incr ::xowiki_inclusion_depth -1 + set adp $adp_args + return ${ch}[my error_in_includelet $arg [_ xowiki.error-includelet-adp_syntax_invalid]] + } + lappend adp_args __including_page [self] + set including_page_level [template::adp_level] + if {[catch {set page [template::adp_include $adp_fn $adp_args]} errorMsg]} { + # in case of error, reset the adp_level to the previous value + set ::template::parse_level $including_page_level + incr ::xowiki_inclusion_depth -1 + return ${ch}[my error_in_includelet $arg \ + [_ xowiki.error-includelet-error_during_adp_evaluation]] + } + + return $ch$page$ch2 + } else { + # we have a direct (adp-less include) + # Some browsers change {{cmd -flag "..."}} into {{cmd -flag "..."}} + # We have to change this back + regsub -all {([^\\])"} $arg "\\1\"" arg + set html [my include_portlet $arg] + #my log "--include portlet returns $html" + incr ::xowiki_inclusion_depth -1 + return $ch$html$ch2 + } + } + + Page instproc div {ch arg} { + if {$arg eq "content"} { + return "$ch
      " + } elseif {[string match left-col* $arg] \ + || [string match right-col* $arg] \ + || $arg eq "sidebar"} { + return "$ch
      " + } elseif {$arg eq "box"} { + return "$ch
      " + } elseif {$arg eq ""} { + return "$ch
      " + } else { + return $ch + } + } + Page instproc anchor {ch arg} { + set label $arg + set link $arg + set options "" + regexp {^([^|]+)[|](.*)$} $arg _ link label + regexp {^([^|]+)[|](.*)$} $label _ label options + if {[string match "http*//*" $link] || [string match "//*" $link]} { + regsub {^//} $link / link + set l [ExternalLink new -label $label -href $link] + eval $l configure $options + set html [$l render] + $l destroy + return "$ch$html" + } + + set name "" + my instvar parent_id package_id + # do we have a language link (it starts with a ':') + if {[regexp {^:(..):(.*)$} $link _ lang stripped_name]} { + set link_type language + } elseif {[regexp {^(file|image|swf):(.*)$} $link _ link_type stripped_name]} { + set lang "" + set name $link + } else { + # do we have a typed link? + if {![regexp {^([^:][^:][^:]+):((..):)?(.+)$} $link _ link_type _ lang stripped_name]} { + # must be an untyped link; defaults, in case the second regexp does not match either + set lang "" + set link_type link + set stripped_name $link + regexp {^(..):(.+)$} $link _ lang stripped_name + } + } + set normalized_name [::$package_id normalize_name $stripped_name] + if {$lang eq ""} {set lang [my lang]} + if {$name eq ""} {set name $lang:$normalized_name} + if {$label eq $arg} {set label $stripped_name} + + Link create [self]::link \ + -page [self] \ + -type $link_type -name $name -lang $lang \ + -stripped_name $normalized_name -label $label \ + -folder_id $parent_id -package_id $package_id + + if {[catch {eval [self]::link configure $options} error]} { + return "${ch}
      Error during processing of options: $error
      " + } else { + return $ch[[self]::link render] + } + } + + + Page instproc substitute_markup {source} { + set baseclass [expr {[[my info class] exists RE] ? [my info class] : [self class]}] + $baseclass instvar RE + #my log "-- baseclass for RE = $baseclass" + if {[my set mime_type] eq "text/enhanced"} { + set source [ad_enhanced_text_to_html $source] + } + set content "" + set l " "; #use one byte trailer for regexps for escaped content + foreach l0 [split [lindex $source 0] \n] { + append l $l0 + if {[string first \{\{ $l] > -1 && [string first \}\} $l] == -1} continue + set l [my regsub_eval $RE(anchor) $l {my anchor "\1" "\2"}] + set l [my regsub_eval $RE(div) $l {my div "\2" "\3"}] + set l [my regsub_eval $RE(include) $l {my include "\\\1" "\2" "\3"}] + regsub -all $RE(clean) $l {\1} l + regsub -all $RE(clean2) $l { \1} l + append content [string range $l 1 end] \n + set l " " + } + #my log "--substitute_markup returns $content" + return $content + } + + Page instproc adp_subst {content} { + #my log "--adp_subst in [my name]" + set __ignorelist [list RE __defaults name_method object_type_key] + foreach __v [my info vars] { + if {[info exists $__v]} continue + my instvar $__v + } + foreach __v [[my info class] info vars] { + if {[lsearch -exact $__ignorelist $__v]>-1} continue + if {[info exists $__v]} continue + [my info class] instvar $__v + } + set __ignorelist [list __v __ignorelist __varlist __template_variables__ \ + text item_id content lang_links] + set __varlist [list] + set __template_variables__ "
        \n" + foreach __v [lsort [info vars]] { + if {[lsearch -exact $__ignorelist $__v]>-1} continue + lappend __varlist $__v + append __template_variables__ "
      • $__v: '[set $__v]'\n" + } + append __template_variables__ "
      \n" + regsub -all [template::adp_variable_regexp] $content {\1@\2;noquote@} content + #my log "--adp before adp_eval '[template::adp_level]'" + # + # The adp buffer has limited size. For large pages, it might happen + # that the buffer overflows. In Aolserver 4.5, we can increase the + # buffer size. In 4.0.10, we are out of luck. + # + set l [string length $content] + if {[catch {set bufsize [ns_adp_ctl bufsize]}]} { + set bufsize 0 + } + if {$bufsize > 0 && $l > $bufsize} { + # we have aolserver 4.5, we can increase the bufsize + ns_adp_ctl bufsize [expr {$l + 1024}] + } + set template_code [template::adp_compile -string $content] + set my_parse_level [template::adp_level] + if {[catch {set template_value [template::adp_eval template_code]} errMsg]} { + set ::template::parse_level $my_parse_level + #my log "--adp after adp_eval '[template::adp_level]' mpl=$my_parse_level" + return "
      Error in Page $name: $errMsg
      $content

      Possible values are$__template_variables__" + } + return $template_value + } + + Page instproc get_description {content} { + my instvar revision_id + set description [my set description] + if {$description eq "" && $content ne ""} { + set description [ad_html_text_convert -from text/html -to text/plain -- $content] + } + if {$description eq "" && $revision_id > 0} { + set description [db_string [my qn get_description_from_syndication] \ + "select body from syndication where object_id = $revision_id" \ + -default ""] + } + return $description + } + + Page instproc get_content {} { + #my log "--" + return [my substitute_markup [my set text]] + } + Page instproc set_content {text} { + my text [list [string map [list >> "\n
      >>" << "<<\n"] \ + [string trim $text " \n"]] text/html] + } + + Page instproc get_rich_text_spec {field_name default} { + my instvar package_id + set spec "" + foreach {s widget_spec} [$package_id get_parameter widget_specs] { + foreach {page_name var_name} [split $s ,] break + # in case we have no name (edit new page) we use the first value or the default. + set name [expr {[my exists name] ? [my set name] : $page_name}] + #my msg "--w T.name = '$name' var=$page_name, $var_name $field_name " + if {[string match $page_name $name] && + [string match $var_name $field_name]} { + set spec $widget_spec + #my msg "setting spec to $spec" + break + } + } + if {$spec eq ""} {return $default} + return $field_name:$spec + } + + Page instproc validate=name {name} { + upvar nls_language nls_language + my set data [self] ;# for the time being; change clobbering when validate_name becomes a method + set success [::xowiki::validate_name] + if {$success} { + # set the instance variable with a potentially prefixed name + # the classical validators do just an upvar + my set name $name + } + return $success + } + Page instproc validate=page_order {value} { + if {[my exists page_order]} { + set page_order [string trim $value " ."] + my page_order $page_order + } + return 1 + } + + Page instproc update_references {page_id references} { + db_dml [my qn delete_references] \ + "delete from xowiki_references where page = $page_id" + foreach ref $references { + foreach {r link_type} $ref break + db_dml [my qn insert_reference] \ + "insert into xowiki_references (reference, link_type, page) \ + values ($r,:link_type,$page_id)" + } + } + + Page proc container_already_rendered {field} { + if {![info exists ::xowiki_page_item_id_rendered]} { + return "" + } + #my log "--OMIT and not $field in ([join $::xowiki_page_item_id_rendered ,])" + return "and not $field in ([join $::xowiki_page_item_id_rendered ,])" + } + + Page instproc footer {} { + return "" + } + + Page instproc render {-update_references:switch} { + my instvar item_id revision_id references lang render_adp unresolved_references parent_id + my array set lang_links {found "" undefined ""} + #my log "-- my class=[my info class]" + set name [my set name] + regexp {^(..):(.*)$} $name _ lang name + set references [list] + set unresolved_references 0 + #my log "--W setting unresolved_references to 0 [info exists unresolved_references]" + set content [my get_content] + #my log "--W after content [info exists unresolved_references] [my exists unresolved_references] ?? [info vars]" + if {$update_references || $unresolved_references > 0} { + my update_references $item_id [lsort -unique $references] + } + set html [expr {$render_adp ? [my adp_subst $content] : $content}] + if {![my exists __no_footer]} {append html [my footer]} + return $html + } + + Page instproc record_last_visited {-user_id} { + my instvar item_id package_id + if {![info exists user_id]} {set user_id [ad_conn user_id]} + if {$user_id > 0} { + # only record information for authenticated users + db_dml [my qn update_last_visisted] \ + "update xowiki_last_visited set time = current_timestamp, count = count + 1 \ + where page_id = $item_id and user_id = $user_id" + if {[db_resultrows] < 1} { + db_dml [my qn insert_last_visisted] \ + "insert into xowiki_last_visited (page_id, package_id, user_id, count, time) \ + values ($item_id, $package_id, $user_id, 1, current_timestamp)" + } + } + } + + # + # Some utility functions, called on different kind of pages + # + + Page instproc lookup_form_field { + -name + form_fields + } { + set found 0 + foreach f $form_fields { + if {[$f name] eq $name} {set found 1; break} + } + if {!$found && [regexp {^([^.]+)[.](.*)$} $name _ container component]} { + # components of a field + set f [my lookup_form_field -name $container $form_fields]::$component + set found 1 + } + if {!$found} { + error "No form field with name $name found" + } + return $f + } + + Page instproc show_fields {form_fields} { + # this method is for debugging only + set msg "" + foreach f $form_fields { append msg "[$f name] [$f info class], " } + my msg $msg + } + + + # + # Methods of ::xowiki::PlainPage + # + + PlainPage parameter { + {render_adp 0} + } + PlainPage array set RE { + include {([^\\]){{(.+?)}}[ \n\r]} + anchor {([^\\])\\\[\\\[([^\]]+?)\\\]\\\]} + div {()([^\\])>>([^<]*?)<<} + clean {[\\](\{\{|>>|\[\[)} + clean2 {(--DUMMY NOT USED--)} + } + + PlainPage instproc get_content {} { + #my log "-- my class=[my info class]" + return [my substitute_markup [my set text]] + } + PlainPage instproc set_content {text} { + my text $text + } + + PlainPage instproc substitute_markup {source} { + [self class] instvar RE + set content "" + foreach l [split $source \n] { + set l " $l" + set l [my regsub_eval $RE(anchor) $l {my anchor "\1" "\2"}] + set l [my regsub_eval $RE(div) $l {my div "\2" "\3"}] + set l [my regsub_eval $RE(include) $l {my include "\1" "\2" ""}] + regsub -all $RE(clean) $l {\1} l + append content [string range $l 1 end] \n + } + return $content + } + + # + # Methods of ::xowiki::File + # + + File parameter { + {render_adp 0} + } + File instproc complete_name {name {fn ""}} { + my instvar mime_type package_id + switch -glob -- $mime_type { + image/* {set type image} + default {set type file} + } + if {$name ne ""} { + set stripped_name $name + regexp {^(.*):(.*)$} $name _ _t stripped_name + } else { + set stripped_name $fn + } + return ${type}:[::$package_id normalize_name $stripped_name] + } + File instproc full_file_name {} { + if {![my exists full_file_name]} { + if {[my exists item_id]} { + my instvar text mime_type package_id item_id revision_id + set storage_area_key [db_string [my qn get_storage_key] \ + "select storage_area_key from cr_items where item_id=$item_id"] + my set full_file_name [cr_fs_path $storage_area_key]/$text + #my log "--F setting FILE=[my set full_file_name]" + } + } + return [my set full_file_name] + } + + File instproc get_content {} { + my instvar name mime_type description parent_id package_id creation_user + # don't require permissions here, such that rss can present the link + set page_link [$package_id make_link -privilege public [self] download ""] + #my log "--F page_link=$page_link ---- " + set t [TableWidget new -volatile \ + -columns { + AnchorField name -label [_ xowiki.Page-name] + Field mime_type -label "Content Type" + Field last_modified -label "Last Modified" + Field mod_user -label "By User" + Field size -label "Size" + }] + + regsub {[.][0-9]+([^0-9])} [my set last_modified] {\1} last_modified + regexp {^([^:]+):(.*)$} $name _ link_type stripped_name + set label $stripped_name + + $t add \ + -name $stripped_name \ + -mime_type $mime_type \ + -name.href $page_link \ + -last_modified $last_modified \ + -mod_user [::xo::get_user_name $creation_user] \ + -size [file size [my full_file_name]] + + if {$link_type eq "image"} { + set l [Link new -volatile \ + -page [self] \ + -type $link_type -name $name -lang "" \ + -stripped_name $stripped_name -label $label \ + -folder_id $parent_id -package_id $package_id] + set image "

      [$l render]
      " + } else { + set image "" + } + return "$image

      [$t asHTML]

      \n

      $description

      " + } + + PodcastItem instproc get_content {} { + set content [next] + append content
        + foreach i {title subtitle creator pub_date duration keywords} { + append content "
      • $i: [my set $i]\n" + } + append content
      + return $content + } + + # + # PageTemplate specifics + # + PageTemplate parameter { + {render_adp 0} + } + PageTemplate instproc count_usages {{-all false}} { + return [::xowiki::PageTemplate count_usages -item_id [my item_id] -all $all] + } + + PageTemplate proc count_usages {-item_id:required {-all:boolean false}} { + set publish_status_clause [expr {$all ? "" : " and i.publish_status <> 'production' "}] + set count [db_string [my qn count_usages] \ + "select count(page_instance_id) from xowiki_page_instance, cr_items i \ + where page_template = $item_id \ + $publish_status_clause \ + and page_instance_id = coalesce(i.live_revision,i.latest_revision)"] + return $count + } + + # + # PageInstance methods + # + + PageInstance proc get_short_spec_from_form_constraints {-name -form_constraints} { + foreach name_and_spec $form_constraints { + foreach {spec_name short_spec} [split $name_and_spec :] break + if {$spec_name eq $name} { + #my msg "get_short_spec $name returns 1 $short_spec" + return $short_spec + } + } + return "" + } + + PageInstance instproc get_short_spec {name} { + #my msg "get_short_spec $name" + my instvar page_template + # in the old-fashioned 2-form page-instance create, page_template + # might be non-existant or empty. + if {[info exists page_template] && $page_template ne "" && + [$page_template exists form_constraints]} { + set short_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ + -name $name -form_constraints [$page_template form_constraints]] + if {$short_spec ne ""} { + return $short_spec + } + } + return "" + } + + PageInstance instproc get_field_label {name value} { + set short_spec [my get_short_spec $name] + if {$short_spec ne ""} { + set f [FormField new -volatile -name $name -spec $short_spec] + return [$f pretty_value $value] + } + return $value + } + PageInstance instproc widget_spec_from_folder_object {name given_template_name} { + # get the widget field specifications from the payload of the folder object + # for a field with a specified name in a specified page template + my instvar page_template + foreach {s widget_spec} [[my set parent_id] get_payload widget_specs] { + foreach {template_name var_name} [split $s ,] break + #ns_log notice "--w T.title = '$given_template_name' var=$name" + if {([string match $template_name $given_template_name] || $given_template_name eq "") && + [string match $var_name $name]} { + return $widget_spec + #ns_log notice "--w using $widget for $name" + } + } + return "" + } + PageInstance instproc get_field_type {name default_spec} { + my instvar page_template + # get widget spec from folder (highest priority) + set spec [my widget_spec_from_folder_object $name [$page_template set name]] + if {$spec ne ""} { + return $spec + } + # get widget spec from attribute definition + set f [my create_form_field -name $name -slot [my find_slot $name]] + if {$f ne ""} { + return [$f asWidgetSpec] + } + # use default widget spec + return $default_spec + } + + PageInstance instproc get_from_template {var} { + my instvar page_template + #my log "-- fetching page_template = $page_template" + ::Generic::CrItem instantiate -item_id $page_template + $page_template destroy_on_cleanup + return [$page_template set $var] + } + + PageInstance instproc get_content {} { + set raw_template [my get_from_template text] + set T [my adp_subst [lindex $raw_template 0]] + return [my substitute_markup [list $T [lindex $raw_template 1]]] + } + PageInstance instproc template_vars {content} { + set result [list] + foreach {_ _ v} [regexp -inline -all [template::adp_variable_regexp] $content] { + lappend result $v "" + } + return $result + } + PageInstance instproc adp_subst {content} { + # initialize template variables (in case, new variables are added to template) + array set __ia [my template_vars $content] + # add extra variables as instance attributes + array set __ia [my set instance_attributes] + foreach var [array names __ia] { + #my log "-- set $var [list $__ia($var)]" + # TODO: just for the lookup, whether a field is a richt text field, + # there should be a more efficient and easier way... + if {[string match "richtext*" [my get_field_type $var text]]} { + # ignore the text/html info from htmlarea + set value [lindex $__ia($var) 0] + } else { + set value $__ia($var) + } + # the value might not be from the form attributes (e.g. title), don't clear it. + if {$value eq "" && [my exists $var]} continue + my set $var [my get_field_label $var $value] + } + next + } + + # + # Methods of ::xowiki::Object + # + + Object instproc get_content {} { + if {[[self]::payload info methods content] ne ""} { + return [my substitute_markup [[self]::payload content]] + } else { + return "
      [string map {> > < <} [my set text]]
      " + } + } + + Object instproc initialize_loaded_object {} { + my set_payload [my set text] + next + } + Object instproc set_payload {cmd} { + set payload [self]::payload + if {[my isobject $payload]} {$payload destroy} + ::xo::Context create $payload -requireNamespace \ + -actual_query [::xo::cc actual_query] + $payload set package_id [my set package_id] + if {[catch {$payload contains $cmd} error ]} { + ns_log error "content $cmd lead to error: $error" + } + #my log "call init mixins=[my info mixin]//[$payload info mixin]" + $payload init + } + Object instproc get_payload {var {default ""}} { + set payload [self]::payload + if {![my isobject $payload]} { + ::xo::Context create $payload -requireNamespace + } + expr {[$payload exists $var] ? [$payload set $var] : $default} + } + + # + # Methods of ::xowiki::Form + # + Form instproc footer {} { + return [my include_portlet [list form-menu -form_item_id [my item_id]]] + } + + Form proc disable_input_fields {form} { + dom parse -simple -html $form doc + $doc documentElement root + set fields [$root selectNodes "//button | //input | //optgroup | //option | //select | //textarea "] + foreach field $fields { + $field setAttribute disabled "disabled" + } + return [$root asHTML] + } + + Form instproc get_content {} { + my instvar text form + ::xowiki::Form requireFormCSS + + # we assume, that the richtext is stored as 2-elem list with mime-type + #my log "-- text='$text'" + if {[lindex $text 0] ne ""} { + set content [my substitute_markup [my set text]] + } elseif {[lindex $form 0] ne ""} { + set content [[self class] disable_input_fields [lindex $form 0]] + } else { + set content "" + } + return $content + } + + Form instproc list {} { + my view [my include_portlet [list form-usages -form_item_id [my item_id]]] + } + + + Form instproc validate=form_constraints {form_constraints} { + # + # First check for invalid meta characters for security reasons. + # + if {[regexp {[\[\]]} $form_constraints]} { + my uplevel [list set errorMsg [_ xowiki.error-form_constraint-invalid_characters]] + return 0 + } + # + # Create from fields from all specs and report, if there are any errors + # + foreach name_and_spec $form_constraints { + foreach {spec_name short_spec} [split $name_and_spec :] break + if {$spec_name eq "@table" || $spec_name eq "@categories"} continue + + #my msg "checking spec '$short_spec' for form field '$spec_name'" + if {[catch { + set f [my create_form_field \ + -name $spec_name \ + -slot [my find_slot $spec_name] \ + -spec $short_spec] + $f destroy + } errorMsg]} { + my uplevel [list set errorMsg $errorMsg] + #my msg "ERROR: invalid spec '$short_spec' for form field '$spec_name' -- $errorMsg" + return 0 + } + } + return 1 + } + + + # + # Methods of ::xowiki::FormPage + # + FormPage instproc footer {} { + if {[my exists __no_form_page_footer]} { + next + } else { + return [my include_portlet [list form-entry-menu]] + } + } + + FormPage instproc form_attributes {} { + # + # this method returns the form attributes (including _*) + # + my instvar page_template + set dont_edit [concat [[my info class] edit_atts] [list title] \ + [::Generic::CrClass set common_query_atts]] + + set template [lindex [my get_from_template text] 0] + #set field_names [list _name _title _description _creator _nls_language _page_order] + set field_names [list] + set form [lindex [my get_from_template form] 0] + if {$form eq ""} { + foreach {var _} [my template_vars $template] { + #if {[string match _* $var]} continue + if {[lsearch $dont_edit $var] == -1} {lappend field_names $var} + } + set form_vars 0 + } else { + foreach {match 1 att} [regexp -all -inline [template::adp_variable_regexp] $form] { + #if {[string match _* $att]} continue + lappend field_names $att + } + dom parse -simple -html $form doc + $doc documentElement root + set fields [$root selectNodes "//*\[@name != ''\]"] + foreach field $fields { + set node_name [$field nodeName] + if {$node_name ne "input" + && $node_name ne "textarea" + && $node_name ne "select" + } continue + set att [$field getAttribute name] + #if {[string match _* $att]} continue + if {[lsearch $field_names $att] == -1} { + lappend field_names $att + } + } + set form_vars 1 + } + return [list $form_vars $field_names] + } + + + FormPage instproc get_content {} { + my instvar doc root package_id page_template + set text [lindex [my get_from_template text] 0] + if {$text ne ""} { + #my msg "we have a template text='$text'" + # we have a template + return [next] + } else { + ::xowiki::Form requireFormCSS + set form [lindex [my get_from_template form] 0] + foreach {form_vars field_names} [my form_attributes] break + set form_fields [my create_form_fields $field_names] + set form [my regsub_eval \ + [template::adp_variable_regexp] $form \ + {my form_field_as_html -mode display "\\\1" "\2" $form_fields}] + + dom parse -simple -html $form doc + $doc documentElement root + my set_form_data + return [Form disable_input_fields [$root asHTML]] + } + } + + FormPage instproc get_value {before varname} { + #my msg "varname=$varname" + array set __ia [my set instance_attributes] + switch -glob $varname { + _* {set value [my set [string range $varname 1 end]]} + default { + if {[info exists __ia($varname)]} { + set value [set __ia($varname)] + } elseif {[my exists $varname]} { + set value [my $varname] + } else { + my msg "**** unknown variable '$varname' ****" + #set value **** unknown variable '$varname' ****" + set value "" + } + } + } + + set f [my create_form_field -name $varname \ + -slot [my find_slot [string trimleft $varname _]] \ + -configuration [list -value $value]] + set v $value + set value [$f pretty_value $value] + #my msg "$varname [$f info class] before=$v after pretty_value=$value" + #my msg [$f serialize] + + return $before$value + } + + FormPage instproc adp_subst {content} { + set content [my regsub_eval -noquote true \ + [template::adp_variable_regexp] " $content" {my get_value "\\\1" "\2"}] + #regsub -all $content {\1@\2;noquote@} content + return [string range $content 1 end] + } + + FormPage instproc is_new_entry {old_name} { + return [expr {[my publish_status] eq "production" && $old_name eq [my revision_id]}] + } + + FormPage instproc save_data {old_name category_ids} { + #my log "-- [self args]" + my instvar package_id name + db_transaction { + # + # if the newly created item was in production mode, but ordinary entries + # are not, change on the first save the status to ready + # + if {[my is_new_entry $old_name]} { + if {![$package_id get_parameter production_mode 0]} { + my set publish_status "ready" + } + } + # could be optimized, if we do not want to have categories (form constraints?) + category::map_object -remove_old -object_id [my item_id] $category_ids + + my save + my log "-- old_name $old_name, name $name" + if {$old_name ne $name} { + my log "--formpage renaming" + db_dml [my qn update_rename] "update cr_items set name = :name \ + where item_id = [my item_id]" + } + } + return [my item_id] + } + +} + +source [file dirname [info script]]/xowiki-www-procs.tcl + Index: openacs-4/packages/xowiki/tcl/xowiki-sc-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-sc-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/xowiki-sc-procs.tcl 1 Aug 2007 21:39:24 -0000 1.21.2.2 @@ -0,0 +1,144 @@ +ad_library { + XoWiki - Search Service Contracts + + @creation-date 2006-01-10 + @author Gustaf Neumann + @cvs-id $Id: xowiki-sc-procs.tcl,v 1.21.2.2 2007/08/01 21:39:24 gustafn Exp $ +} + +namespace eval ::xowiki {} + +ad_proc -private ::xowiki::datasource { revision_id } { + @param revision_id + + returns a datasource for the search package +} { + #ns_log notice "--sc datasource called with revision_id = $revision_id" + + set page [::xowiki::Package instantiate_page_from_id -revision_id $revision_id -user_id 0] + $page volatile + + #ns_log notice "--sc package=[[$page package_id] serialize]" + ns_log notice "--sc $page [$page set publish_status]" + + if {[$page set publish_status] eq "production"} { + # no data source for for pages under construction + #ns_log notice "--sc page under construction, no datasource" + return [list object_id $revision_id title "" \ + content "" keywords "" \ + storage_type text mime text/html] + } + + $page absolute_links 1 + #ns_log notice "--sc setting absolute links for page = $page [$page set name]" + + set html [$page render] + set text [ad_html_text_convert -from text/html -to text/plain -- $html] + #set text [ad_text_to_html $html]; #this could be used for entity encoded html text in rss entries + + #::xowiki::notification::do_notifications -page $page -html $html -text $text + + #ns_log notice "--sc INDEXING $revision_id -> $text" + #$page set unresolved_references 0 + $page instvar item_id + # cleanup old stuff. This might run into an error, when search is not + # configured, and therefore txt does not exist. TODO: we should look for a better + # solution, where syndication does not depend on search.... + catch { + db_dml delete_old_revisions { + delete from txt where object_id in \ + (select revision_id from cr_revisions + where item_id = :item_id and revision_id != :revision_id) + } + } + foreach tag {h1 h2 h3 h4 h5 b strong} { + foreach {match words} [regexp -all -inline "<$tag>(\[^<\]+)" $html] { + foreach w [split $words] { + if {$w eq ""} continue + set word($w) 1 + } + } + } + #ns_log notice "--sc keywords $revision_id -> [array names word]" + + return [list object_id $revision_id title [$page title] \ + content $text keywords [array names word] \ + storage_type text mime text/html \ + syndication [list \ + link [::[$page package_id] pretty_link -absolute 1 [$page set name]] \ + description $text \ + author [$page set creator] \ + category "" \ + guid "$item_id" \ + pubDate [$page set last_modified]] \ + ] +} + +ad_proc -private ::xowiki::url { revision_id} { + returns a url for a message to the search package +} { + return [::xowiki::Package get_url_from_id -revision_id $revision_id] +} + + +namespace eval ::xowiki::sc { + + ad_proc -private ::xowiki::sc::register_implementations {} { + Register the content type fts contract + } { + acs_sc::impl::new_from_spec -spec { + name "::xowiki::Page" + aliases { + datasource ::xowiki::datasource + url ::xowiki::url + } + contract_name FtsContentProvider + owner xowiki + } + acs_sc::impl::new_from_spec -spec { + name "::xowiki::PlainPage" + aliases { + datasource ::xowiki::datasource + url ::xowiki::url + } + contract_name FtsContentProvider + owner xowiki + } + acs_sc::impl::new_from_spec -spec { + name "::xowiki::PageInstance" + aliases { + datasource ::xowiki::datasource + url ::xowiki::url + } + contract_name FtsContentProvider + owner xowiki + } + acs_sc::impl::new_from_spec -spec { + name "::xowiki::FormPage" + aliases { + datasource ::xowiki::datasource + url ::xowiki::url + } + contract_name FtsContentProvider + owner xowiki + } + acs_sc::impl::new_from_spec -spec { + name "::xowiki::File" + aliases { + datasource ::xowiki::datasource + url ::xowiki::url + } + contract_name FtsContentProvider + owner xowiki + } +} + + ad_proc -private ::xowiki::sc::unregister_implementations {} { + acs_sc::impl::delete -contract_name FtsContentProvider -impl_name ::xowiki::Page + acs_sc::impl::delete -contract_name FtsContentProvider -impl_name ::xowiki::PlainPage + acs_sc::impl::delete -contract_name FtsContentProvider -impl_name ::xowiki::PageInstance + acs_sc::impl::delete -contract_name FtsContentProvider -impl_name ::xowiki::FormPage + acs_sc::impl::delete -contract_name FtsContentProvider -impl_name ::xowiki::File + } +} + Index: openacs-4/packages/xowiki/tcl/xowiki-www-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-www-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/xowiki-www-procs.tcl 1 Aug 2007 21:39:25 -0000 1.95.2.2 @@ -0,0 +1,1082 @@ +ad_library { + XoWiki - www procs. These procs are the methods called on xowiki pages via + the web interface. + + @creation-date 2006-04-10 + @author Gustaf Neumann + @cvs-id $Id: xowiki-www-procs.tcl,v 1.95.2.2 2007/08/01 21:39:25 gustafn Exp $ +} + + +namespace eval ::xowiki { + + Page instproc htmlFooter {{-content ""}} { + my instvar package_id description + if {[my exists __no_footer]} {return ""} + + set footer "
      " + + if {$description eq ""} { + set description [my get_description $content] + } + + #set ::META(description) $description + + if {[ns_conn isconnected]} { + set url "[ns_conn location][::xo::cc url]" + set package_url "[ns_conn location][$package_id package_url]" + } + + if {[$package_id get_parameter "with_tags" 1] && + ![my exists_query_parameter no_tags] && + [::xo::cc user_id] != 0 + } { + set tag_content "[my include_portlet my-tags]
      " + set tag_includelet [my set __last_includelet] + set tags [$tag_includelet set tags] + } else { + set tag_content "" + set tags "" + } + + if {[$package_id get_parameter "with_digg" 0] && [info exists url]} { + append footer "
      " \ + [my include_portlet [list digg -description $description -url $url]] "
      \n" + } + + if {[$package_id get_parameter "with_delicious" 0] && [info exists url]} { + append footer "
      " \ + [my include_portlet [list delicious -description $description -url $url -tags $tags]] \ + "
      \n" + } + + if {[$package_id get_parameter "with_yahoo_publisher" 0] && [info exists package_url]} { + append footer "
      " \ + [my include_portlet [list my-yahoo-publisher \ + -publisher [::xo::get_user_name [::xo::cc user_id]] \ + -rssurl "$package_url?rss"]] \ + "
      \n" + } + + append footer [my include_portlet my-references]
      + + if {[$package_id get_parameter "show_per_object_categories" 1]} { + append footer [my include_portlet my-categories]
      + set categories_includelet [my set __last_includelet] + } + + append footer $tag_content + + if {[$package_id get_parameter "with_general_comments" 0] && + ![my exists_query_parameter no_gc]} { + append footer [my include_portlet my-general-comments]
      + } + + return "
      $footer
      \n" + } + +} + +namespace eval ::xowiki { + + Page instproc view {{content ""}} { + # view is used only for the toplevel call, when the xowiki page is viewed + # this is not inteded for embedded wiki pages + my instvar package_id item_id + $package_id instvar folder_id ;# this is the root folder + ::xowiki::Page set recursion_count 0 + + set template_file [my query_parameter "template_file" \ + [::$package_id get_parameter template_file view-default]] + + if {[my isobject ::xowiki::$template_file]} { + $template_file before_render [self] + } + + if {$content eq ""} { + set content [my render] + } + #my log "--after render" + set footer [my htmlFooter -content $content] + + set top_portlets "" + set vp [$package_id get_parameter "top_portlet" ""] + if {$vp ne ""} { + set top_portlets [my include_portlet $vp] + } + + if {[$package_id get_parameter "with_user_tracking" 1]} { + my record_last_visited + } + + # Deal with the views package (many thanks to Malte for this snippet!) + if {[$package_id get_parameter with_views_package_if_available 1] + && [apm_package_installed_p "views"]} { + views::record_view -object_id $item_id -viewer_id [::xo::cc user_id] + array set views_data [views::get -object_id $item_id] + } + + # import title, name and text into current scope + my instvar title name text + + if {[my exists_query_parameter return_url]} { + set return_url [my query_parameter return_url] + } + + if {[$package_id get_parameter "with_notifications" 1]} { + if {[::xo::cc user_id] != 0} { ;# notifications require login + set notifications_return_url [expr {[info exists return_url] ? $return_url : [ad_return_url]}] + set notification_type [notification::type::get_type_id -short_name xowiki_notif] + set notification_text "Subscribe the XoWiki instance" + set notification_subscribe_link \ + [export_vars -base /notifications/request-new \ + {{return_url $notifications_return_url} + {pretty_name $notification_text} + {type_id $notification_type} + {object_id $package_id}}] + set notification_image \ + "$notification_text" + } + } + #my log "--after notifications [info exists notification_image]" + + set master [$package_id get_parameter "master" 1] + #if {[my exists_query_parameter "edit_return_url"]} { + # set return_url [my query_parameter "edit_return_url"] + #} + my log "--after options" + + if {$master} { + set context [list $title] + set autoname [$package_id get_parameter autoname 0] + set object_type [$package_id get_parameter object_type [my info class]] + set rev_link [$package_id make_link [self] revisions] + set edit_link [$package_id make_link [self] edit return_url] + set delete_link [$package_id make_link [self] delete return_url] + if {[my istype ::xowiki::FormPage]} { + set template_id [my page_template] + set form [$package_id pretty_link [$template_id name]] + set new_link [$package_id make_link -link $form $template_id create-new return_url] + } else { + set new_link [$package_id make_link $package_id edit-new object_type return_url autoname] + } + set admin_link [$package_id make_link -privilege admin -link admin/ $package_id {} {}] + set index_link [$package_id make_link -privilege public -link "" $package_id {} {}] + set create_in_req_locale_link "" + + if {[$package_id get_parameter use_connection_locale 0]} { + $package_id get_name_and_lang_from_path \ + [$package_id set object] req_lang req_local_name + set default_lang [$package_id default_language] + if {$req_lang ne $default_lang} { + set l [Link create new -destroy_on_cleanup \ + -page [self] -type language -stripped_name $req_local_name \ + -name ${default_lang}:$req_local_name -lang $default_lang \ + -label $req_local_name -folder_id $folder_id \ + -package_id $package_id -init \ + -return_only undefined] + $l render + } + } + + #my log "--after context delete_link=$delete_link " + set template [$folder_id get_payload template] + set page [self] + + if {$template ne ""} { + set __including_page $page + set __adp_stub [acs_root_dir]/packages/xowiki/www/view-default + set template_code [template::adp_compile -string $template] + if {[catch {set content [template::adp_eval template_code]} errmsg]} { + ns_return 200 text/html "Error in Page $name: $errmsg
      $template" + } else { + ns_return 200 text/html $content + } + } else { + + # use adp file + foreach css [$package_id get_parameter extra_css ""] {::xowiki::Page requireCSS $css} + # refetch it, since it might have been changed via set-parameter + set template_file [my query_parameter "template_file" \ + [::$package_id get_parameter template_file view-default]] + + if {![regexp {^[./]} $template_file]} { + set template_file /packages/xowiki/www/$template_file + } + set header_stuff [::xowiki::Page header_stuff] + $package_id return_page -adp $template_file -variables { + name title item_id context header_stuff return_url + content footer package_id + rev_link edit_link delete_link new_link admin_link index_link + notification_subscribe_link notification_image + top_portlets page + views_data + } + } + } else { + ns_return 200 [::xo::cc get_parameter content-type text/html] $content + } + } +} + + +namespace eval ::xowiki { + + Page instproc edit { + {-new:boolean false} + {-autoname:boolean false} + {-validaton_errors ""} + } { + my instvar package_id item_id revision_id + $package_id instvar folder_id ;# this is the root folder + + # set some default values if they are provided + foreach key {name title page_order last_page_id} { + if {[$package_id exists_query_parameter $key]} { + my set $key [$package_id query_parameter $key] + } + } + if {$new} { + my set creator [::xo::get_user_name [::xo::cc user_id]] + my set nls_language [ad_conn locale] + } + + set object_type [my info class] + if {!$new && $object_type eq "::xowiki::Object" && [my set name] eq "::$folder_id"} { + # if we edit the folder object, we have to do some extra magic here, + # since the folder object has slightly different naming conventions. + # ns_log notice "--editing folder object ::$folder_id, FLUSH $page" + ns_cache flush xotcl_object_cache [self] + ns_cache flush xotcl_object_cache ::$folder_id + my move ::$folder_id + set page ::$folder_id + #ns_log notice "--move page=$page" + } + + # + # setting up folder id for file selector (use community folder if available) + # + set fs_folder_id "" + if {[info commands ::dotlrn_fs::get_community_shared_folder] ne ""} { + set fs_folder_id [::dotlrn_fs::get_community_shared_folder \ + -community_id [::dotlrn_community::get_community_id]] + } + + # the following line is like [$package_id url], but works as well with renamed objects + # set myurl [$package_id pretty_link [my form_parameter name]] + + if {[my exists_query_parameter "return_url"]} { + set submit_link [my query_parameter "return_url" "."] + set return_url $submit_link + } else { + set submit_link "." + } + #my log "--u submit_link=$submit_link qp=[my query_parameter return_url]" + + # we have to do template mangling here; ad_form_template writes form + # variables into the actual parselevel, so we have to be in our + # own level in order to access an pass these + variable ::template::parse_level + lappend parse_level [info level] + set action_vars [expr {$new ? "{edit-new 1} object_type return_url" : "{m edit} return_url"}] + #my log "--formclass=[$object_type getFormClass -data [self]] ot=$object_type" + [$object_type getFormClass -data [self]] create ::xowiki::f1 -volatile \ + -action [export_vars -base [$package_id url] $action_vars] \ + -data [self] \ + -folderspec [expr {$fs_folder_id ne "" ?"folder_id $fs_folder_id":""}] \ + -submit_link $submit_link \ + -autoname $autoname + + if {[info exists return_url]} { + ::xowiki::f1 generate -export [list [list return_url $return_url]] + } else { + ::xowiki::f1 generate + } + + ::xowiki::f1 instvar edit_form_page_title context formTemplate + + if {[info exists item_id]} { + set rev_link [$package_id make_link [self] revisions] + set view_link [$package_id make_link [self] view] + } + if {[info exists last_page_id]} { + set back_link [$package_id url] + } + + set index_link [$package_id make_link -privilege public -link "" $package_id {} {}] + set html [$package_id return_page -adp /packages/xowiki/www/edit \ + -form f1 \ + -variables {item_id edit_form_page_title context formTemplate + view_link back_link rev_link index_link}] + template::util::lpop parse_level + #my log "--e html length [string length $html]" + return $html + } + + Page instproc find_slot {-start_class name} { + if {![info exists start_class]} { + set start_class [my info class] + } + foreach cl [concat $start_class [$start_class info heritage]] { + set slotobj ${cl}::slot::$name + if {[my isobject $slotobj]} { + #my msg $slotobj + return $slotobj + } + } + return "" + } + + Page instproc create_form_field { + -name + {-slot ""} + {-spec ""} + {-configuration ""} + } { + if {$slot eq ""} { + # We have no slot, so create a minimal slot. This should only happen for instance attributes + set slot [::xo::Attribute new -pretty_name $name -datatype text -volatile -noinit] + } + + set spec_list [list] + if {[$slot exists spec]} {lappend spec_list [$slot set spec]} + if {$spec ne ""} {lappend spec_list $spec} + #my msg "[self args] spec_list $spec_list" + #my msg "$name, spec_list = '[join $spec_list ,]'" + + if {[$slot exists pretty_name]} { + set label [$slot set pretty_name] + } else { + set label $name + my log "no pretty_name for variable $name in slot $slot" + } + + if {[$slot exists default]} { + #my msg "setting ff $name default = [$slot default]" + set default [$slot default] + } else { + set default "" + } + set f [FormField new -name $name \ + -id [::xowiki::Portlet html_id F.[my name].$name] \ + -locale [my nls_language] \ + -label $label \ + -type [expr {[$slot exists datatype] ? [$slot set datatype] : "text"}] \ + -help_text [expr {[$slot exists help_text] ? [$slot set help_text] : ""}] \ + -validator [expr {[$slot exists validator] ? [$slot set validator] : ""}] \ + -required [expr {[$slot exists required] ? [$slot set required] : "false"}] \ + -default $default \ + -spec [join $spec_list ,] \ + -object [self] \ + ] + + $f destroy_on_cleanup + eval $f configure $configuration + return $f + } + + PageInstance instproc create_form_field { + -name + {-slot ""} + {-spec ""} + {-configuration ""} + } { + set short_spec [my get_short_spec $name] + #my msg "create form field '$name', short_spec = '$short_spec', slot=$slot" + set spec_list [list] + if {$spec ne ""} {lappend spec_list $spec} + if {$short_spec ne ""} {lappend spec_list $short_spec} + #my msg "$name: short_spec '$short_spec', spec_list 1 = '[join $spec_list ,]'" + set f [next -name $name -slot $slot -spec [join $spec_list ,] -configuration $configuration] + return $f + } + +} + +namespace eval ::xowiki { + + FormPage instproc create_category_fields {} { + set category_spec [my get_short_spec @categories] + foreach f [split $category_spec ,] { + if {$f eq "off"} {return [list]} + } + + set category_fields [list] + set container_object_id [my package_id] + set category_trees [category_tree::get_mapped_trees $container_object_id] + set category_ids [category::get_mapped_categories [my item_id]] + #my msg "mapped category ids=$category_ids" + + foreach category_tree $category_trees { + foreach {tree_id tree_name subtree_id assign_single_p require_category_p} $category_tree break + + set options [list] + #if {!$require_category_p} {lappend options [list "--" ""]} + set value [list] + foreach category [category_tree::get_tree -subtree_id $subtree_id $tree_id] { + foreach {category_id category_name deprecated_p level} $category break + if {[lsearch $category_ids $category_id] > -1} {lappend value $category_id} + set category_name [ad_quotehtml [lang::util::localize $category_name]] + if { $level>1 } { + set category_name "[string repeat { } [expr {2*$level -4}]]..$category_name" + } + lappend options [list $category_name $category_id] + } + set f [FormField new \ + -name "__category_${tree_name}_$tree_id" \ + -locale [my nls_language] \ + -label $tree_name \ + -type select \ + -value $value \ + -required $require_category_p] + #my msg "category field [my name] created, value '$value'" + $f destroy_on_cleanup + $f options $options + $f multiple [expr {!$assign_single_p}] + lappend category_fields $f + } + return $category_fields + } + + FormPage instproc set_form_value {att value} { + my instvar root item_id + set fields [$root selectNodes "//*\[@name='$att'\]"] + #my msg "found field = $fields xp=//*\[@name='$att'\]" + foreach field $fields { + # TODO missing: textarea + if {[$field nodeName] ne "input"} continue + set type [expr {[$field hasAttribute type] ? [$field getAttribute type] : "text"}] + # the switch should be really different objects ad classes...., but thats HTML, anyhow. + switch $type { + checkbox {$field setAttribute checked true} + radio { + set inputvalue [$field getAttribute value] + if {$inputvalue eq $value} { + $field setAttribute checked true + } + } + hidden - + text { $field setAttribute value $value} + default {my msg "can't handle $type so far $att=$value"} + } + } + } +} + + +namespace eval ::xowiki { + + FormPage ad_instproc set_form_data {} { + Store the instance attributes in the form. + } { + #my msg "set_form_value instance attributes = [my instance_attributes]" + foreach {att value} [my instance_attributes] { + #my msg "set_form_value $att '$value'" + my set_form_value $att $value + } + } +} + + +namespace eval ::xowiki { + + FormPage ad_instproc get_form_data {form_fields} { + Get the values from the form and store it as + instance attributes. + } { + set validation_errors 0 + set category_ids [list] + array set containers [list] + array set __ia [my set instance_attributes] + + # we have a form and get all form variables + + foreach att [::xo::cc array names form_parameter] { + #my msg "getting att=$att" + switch -glob -- $att { + __category_* { + set f [my lookup_form_field -name $att $form_fields] + set value [$f value [::xo::cc form_parameter $att]] + foreach v $value {lappend category_ids $v} + } + __* { + # other internal variables (like __object_name) are ignored + } + _* { + # instance attribute fields + set f [my lookup_form_field -name $att $form_fields] + set value [$f value [::xo::cc form_parameter $att]] + set varname [string range $att 1 end] + if {![string match *.* $att]} {my set $varname $value} + } + default { + # user form content fields + set f [my lookup_form_field -name $att $form_fields] + set value [$f value [::xo::cc form_parameter $att]] + # my msg "value of $att is $value" + if {![string match *.* $att]} {set __ia($att) $value} + } + } + if {[string match *.* $att]} { + foreach {container component} [split $att .] break + lappend containers($container) $component + } + } + + # + # In a second iteration, combine the values from the components + # of a container to the value of the container. + # + foreach c [array names containers] { + switch -glob -- $c { + __* {} + _* { + set f [my lookup_form_field -name $c $form_fields] + my set [string range $c 1 end] [$f get_compound_value] + } + default { + set f [my lookup_form_field -name $c $form_fields] + set __ia($c) [$f get_compound_value] + } + } + } + + # + # Run validators + # + foreach f $form_fields { + set validation_error [$f validate [self]] + #my msg "validation of [$f name] with value '[$f value]' returns $validation_error" + if {$validation_error ne ""} { + $f error_msg $validation_error + incr validation_errors + } + } + #my log "--set instance attributes to [array get __ia]" + my set instance_attributes [array get __ia] + return [list $validation_errors $category_ids] + } + + FormPage instproc form_field_as_html {{-mode edit} before name form_fields} { + set found 0 + foreach f $form_fields { + if {[$f name] eq $name} {set found 1; break} + } + if {!$found} { + set f [my create_form_field -name $name -slot [my find_slot $name]] + } + #my msg "$name mode=$mode type=[$f set type]" + if {$mode eq "edit" || [$f display_field]} { + set html [$f asHTML] + } else { + set html @$name@ + } + #my msg "$name $html" + return ${before}$html + } +} + +namespace eval ::xowiki { + + FormPage instproc create_form_fields {field_names} { + + set form_fields [my create_category_fields] + set cr_field_spec [my get_short_spec @cr_fields] + set field_spec [my get_short_spec @fields] + + foreach att $field_names { + switch -glob -- $att { + __* {} + _* { + set varname [string range $att 1 end] + lappend form_fields [my create_form_field -name $att \ + -spec $cr_field_spec \ + -slot [my find_slot $varname]] + } + default { + lappend form_fields [my create_form_field -name $att \ + -spec $field_spec \ + -slot [my find_slot $att]] + } + } + } + return $form_fields + } + + FormPage instproc edit { + {-validation_errors ""} + } { + my instvar page_template doc root package_id + + ::xowiki::Form requireFormCSS + + set form [lindex [my get_from_template form] 0] + set anon_instances [my get_from_template anon_instances] + + if {$form eq ""} { + # + # Since we have no form, we create it on the fly + # from the template variables and the form field specifications. + # + set form "
      " + set formgiven 0 + } else { + set formgiven 1 + } + + foreach {form_vars needed_attributes} [my form_attributes] break + #my msg "form_vars=$form_vars needed_attributes=$needed_attributes" + if {$form_vars} {foreach v $needed_attributes {set field_in_form($v) 1}} + + # + # Remove the fields already included in auto_fields form the needed_attributes. + # The final list field_names determines the order of the fields in the form. + # + set auto_fields [list _name _page_order _creator _title _text _description _nls_language] + set reduced_attributes $needed_attributes + + foreach f $auto_fields { + set p [lsearch $reduced_attributes $f] + if {$p > -1} { + #if {$form_vars} { + #set auto_field_in_form($f) 1 + #} + set reduced_attributes [lreplace $reduced_attributes $p $p] + } + } + #my msg reduced_attributes=$reduced_attributes + #my msg fields_from_from=[array names field_in_form] + + set field_names [list _name] + if {[$package_id show_page_order]} { lappend field_names _page_order } + lappend field_names _title _creator + foreach fn $reduced_attributes { lappend field_names $fn } + foreach fn [list _text _description _nls_language] { lappend field_names $fn } + #my msg field_names=$field_names + + set form_fields [my create_form_fields $field_names] + if {$anon_instances} { + set f [my lookup_form_field -name _name $form_fields] + $f config_from_spec hidden + } + # include _text only, if explicitely needed (in form or template) + if {[lsearch $needed_attributes _text] == -1} { + #my msg "setting text hidden" + set f [my lookup_form_field -name _text $form_fields] + $f config_from_spec hidden + } + #my show_fields $form_fields + + if {[my form_parameter __form_action ""] eq "save-form-data"} { + #my msg "we have to validate" + # + # we have to valiate and save the form data + # + foreach {validation_errors category_ids} [my get_form_data $form_fields] break + if {$validation_errors != 0} { + #my msg "$validation_errors errors in $form_fields" + #foreach f $form_fields { my msg "$f: [$f name] '[$f set value]' err: [$f error_msg] " } + # reset the name in error cases to the original one + my set name [my form_parameter __object_name] + } else { + # + # we have no validation erros, so we can save the content + # + my save_data [::xo::cc form_parameter __object_name ""] $category_ids + #my log "--forminstance redirect to [$package_id pretty_link [my name]]" + $package_id returnredirect \ + [my query_parameter "return_url" [$package_id pretty_link [my name]]] + return + } + } else { + # + # display the current values + # + + if {[my is_new_entry [my name]]} { + my set creator [::xo::get_user_name [::xo::cc user_id]] + my set nls_language [ad_conn locale] + } + + array set __ia [my set instance_attributes] + foreach att $field_names { + switch -glob $att { + __* {} + _* { + set f [my lookup_form_field -name $att $form_fields] + set varname [string range $att 1 end] + $f value [my set $varname] + } + default { + set f [my lookup_form_field -name $att $form_fields] + if {[info exists __ia($att)]} { + $f value $__ia($att) + } + } + } + set ff($att) $f + } + + # for named entries, just set the entry fields to empty, + # without changing the instance variables + if {[my is_new_entry [my name]]} { + if {![$ff(_title) istype ::xowiki::FormField::hidden]} {$ff(_title) value ""} + if {!$anon_instances} {$ff(_name) value ""} + } + } + + # the following command wout be correct, but does not work due to a bug in + # tdom. + #set form [my regsub_eval \ + # [template::adp_variable_regexp] $form \ + # {my form_field_as_html "\\\1" "\2" $form_fields}] + # due to this bug, we replace the at-character by \x003 to avoid conflict withe the + # input and we insert the fields in the result from tdom. + + set form [string map [list @ \x003] $form] + #my msg form=$form + + dom parse -simple -html $form doc + $doc documentElement root + + ::require_html_procs + $root firstChild fcn + # + # prepend some fields above the HTML contents of the form + # + $root insertBeforeFromScript { + ::html::input -type hidden -name __object_name -value [my name] + ::html::input -type hidden -name __form_action -value save-form-data + + # insert automatic form fields on top + foreach att $field_names { + #if {$formgiven && ![string match _* $att]} continue + if {[info exists field_in_form($att)]} continue + set f [my lookup_form_field -name $att $form_fields] + #my msg "insert auto_field $att" + $f render_item + } + } $fcn + # + # append some fields after the HTML contents of the form + # + set submit_button_class "" + $root appendFromScript { + # append category fields + foreach f $form_fields { + if {[string match "__category_*" [$f name]]} { + $f render_item + } elseif {[$f info class] eq "::xowiki::FormField::richtext::wym"} { + set submit_button_class "wymupdate" + } + } + + # insert unreported errors and add a submit field at bottom + foreach f $form_fields { + if {[$f set error_msg] ne "" && ![$f exists error_reported]} { + $f render_error_msg + } + } + set f [::xowiki::FormField::submit_button new -destroy_on_cleanup \ + -name __form_button_ok \ + -CSSclass $submit_button_class] + $f render_content + } + set form [lindex [$root selectNodes //form] 0] + if {$form eq ""} { + my msg "no form found in page [$page_template name]" + } else { + if {[my exists_query_parameter "return_url"]} { + set return_url [my query_parameter "return_url"] + } + set url [export_vars -base [$package_id pretty_link [my name]] {{m "edit"} return_url}] + $form setAttribute action $url method POST + set oldCSSClass [expr {[$form hasAttribute class] ? [$form getAttribute class] : ""}] + $form setAttribute class [string trim "$oldCSSClass margin-form"] + } + my set_form_data + set html [$root asHTML] + + set html [my regsub_eval \ + {(^|[^\\])\x003([a-zA-Z0-9_:]+)\x003} $html \ + {my form_field_as_html "\\\1" "\2" $form_fields}] + + #my msg result=$html + my view $html + } + + + + File instproc download {} { + my instvar text mime_type package_id item_id revision_id + $package_id set mime_type $mime_type + set use_bg_delivery [expr {![catch {ns_conn contentsentlength}] && + [info command ::bgdelivery] ne ""}] + $package_id set delivery \ + [expr {$use_bg_delivery ? "ad_returnfile_background" : "ns_returnfile"}] + #my log "--F FILE=[my full_file_name]" + return [my full_file_name] + } + + Page instproc revisions {} { + my instvar package_id name item_id + set context [list [list [$package_id url] $name ] [_ xotcl-core.revisions]] + set title "[_ xotcl-core.revision_title] '$name'" + set content [next] + $package_id return_page -adp /packages/xowiki/www/revisions -variables { + content context {page_id $item_id} title + } + } + + Page instproc make-live-revision {} { + my instvar revision_id item_id package_id + #my log "--M set_live_revision($revision_id)" + ::xo::db::sql::content_item set_live_revision -revision_id $revision_id + set page_id [my query_parameter "page_id"] + ns_cache flush xotcl_object_cache ::$item_id + ::$package_id returnredirect [my query_parameter "return_url" \ + [export_vars -base [$package_id url] {{m revisions}}]] + } + + + Page instproc delete-revision {} { + my instvar revision_id package_id item_id + db_1row [my qn get_revision] "select latest_revision,live_revision from cr_items where item_id = $item_id" + ns_cache flush xotcl_object_cache ::$item_id + ns_cache flush xotcl_object_cache ::$revision_id + ::xo::db::sql::content_revision del -revision_id $revision_id + set redirect [my query_parameter "return_url" \ + [export_vars -base [$package_id url] {{m revisions}}]] + if {$live_revision == $revision_id} { + # latest revision might have changed by delete_revision, so we have to fetch here + db_1row [my qn get_revision] "select latest_revision from cr_items where item_id = $item_id" + if {$latest_revision eq ""} { + # we are out of luck, this was the final revision, delete the item + my instvar package_id name + $package_id delete -name $name -item_id $item_id + } else { + ::xo::db::sql::content_item set_live_revision -revision_id $latest_revision + } + } + if {$latest_revision ne ""} { + # otherwise, "delete" did already the redirect + ::$package_id returnredirect [my query_parameter "return_url" \ + [export_vars -base [$package_id url] {{m revisions}}]] + } + } + + Page instproc delete {} { + my instvar package_id item_id name + [my info class] delete -item_id $item_id + ::$package_id flush_references -item_id $item_id -name $name + ::$package_id returnredirect \ + [my query_parameter "return_url" [$package_id package_url]] + } + + Page instproc save-tags {} { + my instvar package_id item_id + ::xowiki::Page save_tags -user_id [::xo::cc user_id] -item_id $item_id \ + -package_id $package_id [my form_parameter new_tags] + + ::$package_id returnredirect \ + [my query_parameter "return_url" [$package_id url]] + } + + Page instproc popular-tags {} { + my instvar package_id item_id parent_id + set limit [my query_parameter "limit" 20] + set weblog_page [$package_id get_parameter weblog_page weblog] + set href [$package_id pretty_link $weblog_page]?summary=1 + + set entries [list] + db_foreach [my qn get_popular_tags] \ + [::xo::db::sql \ + -vars "count(*) as nr, tag" \ + -from "xowiki_tags" \ + -where "item_id=$item_id" \ + -groupby "tag" \ + -orderby "nr" \ + -limit $limit] { + lappend entries "$tag ($nr)" + } + ns_return 200 text/html "[_ xowiki.popular_tags_label]: [join $entries {, }]" + } + + Page instproc diff {} { + my instvar package_id + set compare_id [my query_parameter "compare_revision_id" 0] + if {$compare_id == 0} { + return "" + } + set my_page [::xowiki::Package instantiate_page_from_id -revision_id [my set revision_id]] + $my_page volatile + + set html1 [$my_page render] + set text1 [ad_html_text_convert -from text/html -to text/plain -- $html1] + set user1 [::xo::get_user_name [$my_page set creation_user]] + set time1 [$my_page set creation_date] + set revision_id1 [$my_page set revision_id] + regexp {^([^.]+)[.]} $time1 _ time1 + + set other_page [::xowiki::Package instantiate_page_from_id -revision_id $compare_id] + $other_page volatile + #$other_page absolute_links 1 + + set html2 [$other_page render] + set text2 [ad_html_text_convert -from text/html -to text/plain -- $html2] + set user2 [::xo::get_user_name [$other_page set creation_user]] + set time2 [$other_page set creation_date] + set revision_id2 [$other_page set revision_id] + regexp {^([^.]+)[.]} $time2 _ time2 + + set title "Differences for [my set name]" + set context [list $title] + + set content [::xowiki::html_diff $text2 $text1] + $package_id return_page -adp /packages/xowiki/www/diff -variables { + content title context + time1 time2 user1 user2 revision_id1 revision_id2 + } + } + + proc html_diff {doc1 doc2} { + set out "" + set i 0 + set j 0 + + #set lines1 [split $doc1 "\n"] + #set lines2 [split $doc2 "\n"] + + regsub -all \n $doc1 "
      " doc1 + regsub -all \n $doc2 "
      " doc2 + set lines1 [split $doc1 " "] + set lines2 [split $doc2 " "] + + foreach { x1 x2 } [list::longestCommonSubsequence $lines1 $lines2] { + foreach p $x1 q $x2 { + while { $i < $p } { + set l [lindex $lines1 $i] + incr i + #puts "R\t$i\t\t$l" + append out "$l\n" + } + while { $j < $q } { + set m [lindex $lines2 $j] + incr j + #puts "A\t\t$j\t$m" + append out "$m\n" + } + set l [lindex $lines1 $i] + incr i; incr j + #puts "B\t$i\t$j\t$l" + append out "$l\n" + } + } + while { $i < [llength $lines1] } { + set l [lindex $lines1 $i] + incr i + puts "$i\t\t$l" + append out "$l\n" + } + while { $j < [llength $lines2] } { + set m [lindex $lines2 $j] + incr j + #puts "\t$j\t$m" + append out "$m\n" + } + return $out + } + + +# Page instproc new_name {name} { +# if {$name ne ""} { +# my instvar package_id +# set name [my complete_name $name] +# set name [::$package_id normalize_name $name] +# set suffix ""; set i 0 +# set folder_id [my parent_id] +# while {[CrItem lookup -name $name$suffix -parent_id $folder_id] != 0} { +# set suffix -[incr i] +# } +# set name $name$suffix +# } +# return $name +# } + +# Page instproc create-new {} { +# my instvar package_id +# set name [my new_name [::xo::cc form_parameter name ""]] +# set class [::xo::cc form_parameter class ::xowiki::Page] +# if {[::xotcl::Object isclass $class] && [$class info heritage ::xowiki::Page] ne ""} { +# set class [::xo::cc form_parameter class ::xowiki::Page] +# set f [$class new -destroy_on_cleanup \ +# -name $name \ +# -package_id $package_id \ +# -parent_id [my parent_id] \ +# -publish_status "production" \ +# -title [my title] \ +# -text [list [::xo::cc form_parameter content ""] text/html]] +# $f save_new +# $package_id returnredirect \ +# [my query_parameter "return_url" [$package_id pretty_link $name]?m=edit] +# } +# } + + PageTemplate instproc delete {} { + my instvar package_id item_id name + set count [my count_usages -all true] + #my msg count=$count + if {$count > 0} { + append error_msg \ + [_ xowiki.error-delete_entries_first [list count $count]] \ +

      \ + [my include_portlet [list form-usages -all true -form_item_id [my item_id]]] \ +

      + $package_id error_msg $error_msg + } else { + next + } + } + + Form instproc create-new {} { + my instvar package_id + set f [FormPage new -destroy_on_cleanup \ + -package_id $package_id \ + -parent_id [my parent_id] \ + -publish_status "production" \ + -page_template [my item_id]] + + # set some default values if they are provided + foreach key {name title page_order last_page_id} { + if {[$package_id exists_query_parameter $key]} { + $f set $key [$package_id query_parameter $key] + } + } + $f set __title_prefix [my title] + $f save_new + if {[my exists_query_parameter "return_url"]} { + set return_url [my query_parameter "return_url"] + } + $package_id returnredirect \ + [export_vars -base [$package_id pretty_link [$f name]] {{m edit} return_url}] + } + + + if {[apm_version_names_compare [ad_acs_version] 5.3.0] == 1} { + ns_log notice "Zen-state: 5.3.2 or newer" + Form set extraCSS "" + } else { + ns_log notice "Zen-state: pre 5.3.1, use backward compatible form css file" + Form set extraCSS "zen-forms-backward-compatibility.css" + } + Form proc requireFormCSS {} { + #my msg requireFormCSS + set css [my set extraCSS] + if {$css ne ""} { + #my msg "requireCSS $css" + ::xowiki::Page requireCSS $css + } + } + +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/diff.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/diff.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/diff.adp 1 Aug 2007 21:39:25 -0000 1.2.2.2 @@ -0,0 +1,29 @@ + + @title;noquote@ + @context;noquote@ + + + + + + + +

      Comparing +

        +
      • version @revision_id1@ modified by @user1@ at @time1@ with +
      • version @revision_id2@ modified by @user2@ at @time2@ +
      +

      +
      + +@content;noquote@ + Index: openacs-4/packages/xowiki/www/edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/Attic/edit.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/edit.adp 1 Aug 2007 21:39:25 -0000 1.3.2.2 @@ -0,0 +1,23 @@ + + @edit_form_page_title;noquote@ + @context;noquote@ + note.title + + + + + + Index: openacs-4/packages/xowiki/www/error-template.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/error-template.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/error-template.adp 1 Aug 2007 21:39:25 -0000 1.2.2.2 @@ -0,0 +1,24 @@ + + @title;noquote@ + @context;noquote@ + @header_stuff;noquote@ + + + @header_stuff;noquote@ + + + +
      + +

       

      +

      Error:

      +

      +

      +@error_msg;noquote@ +

       

      +
      +

      +
      Index: openacs-4/packages/xowiki/www/index.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/index.vuh,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/index.vuh 1 Aug 2007 21:39:25 -0000 1.5.2.2 @@ -0,0 +1,24 @@ +# -*- tcl -*- +::xowiki::Package initialize -ad_doc { + + This is the resolver for this package. It turns a request into + an object and executes the object with the computed method + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date July, 2006 + @cvs-id $Id: index.vuh,v 1.5.2.2 2007/08/01 21:39:25 gustafn Exp $ + +} -parameter { + {-m view} + {-folder_id:integer 0} +} + +::$package_id log "--starting... [ns_conn url] [ns_conn query] \ + form vars = [ns_set array [ns_getform]]" +#::$package_id exists_form_parameter creator +#::$package_id log "-- [::xo::cc serialize]" + +::$package_id reply_to_user [::$package_id invoke -method $m] + +::$package_id log "--i ::$package_id DONE" +ad_script_abort Index: openacs-4/packages/xowiki/www/oacs-view.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/oacs-view.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/oacs-view.adp 1 Aug 2007 21:39:25 -0000 1.39.2.2 @@ -0,0 +1,85 @@ + + + @title;noquote@ + @context;noquote@ + @header_stuff;noquote@ + + + + + + + @header_stuff;noquote@ + + + + + + + + +
      + +
      +
      + +
      +
      +@top_portlets;noquote@ +@content;noquote@ +
      + +@footer;noquote@ +
      Index: openacs-4/packages/xowiki/www/oacs-view2.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/oacs-view2.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/oacs-view2.adp 1 Aug 2007 21:39:25 -0000 1.18.2.2 @@ -0,0 +1,117 @@ + + + @title;noquote@ + @context;noquote@ + @header_stuff;noquote@ + + + + + + + + @header_stuff;noquote@ + + + + + + + + + +
      + +
      +
      + +
      +
      + +
      +@top_portlets;noquote@ +@content;noquote@ +
      + + +
      + +@footer;noquote@ +
      Index: openacs-4/packages/xowiki/www/oacs-view3.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/oacs-view3.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/oacs-view3.adp 1 Aug 2007 21:39:25 -0000 1.13.2.2 @@ -0,0 +1,117 @@ + + + @title;noquote@ + @context;noquote@ + @header_stuff;noquote@ + + + + + + + + @header_stuff;noquote@ + + + + + + + + + +
      + +
      + + +
      +
      + + + +
      + +
      +Contributors +
      +
      + +
      +
      + + +
      +
      +
      +@top_portlets;noquote@ +@content;noquote@ +
      + +@footer;noquote@ +
      Index: openacs-4/packages/xowiki/www/portlet-ajax.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlet-ajax.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlet-ajax.adp 1 Aug 2007 21:39:25 -0000 1.1.2.2 @@ -0,0 +1,24 @@ +
      +@title@ +
      + +
      +... loading .... +
      Index: openacs-4/packages/xowiki/www/portlet-ajax.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlet-ajax.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlet-ajax.tcl 1 Aug 2007 21:39:25 -0000 1.1.2.2 @@ -0,0 +1,8 @@ +# like portlet, except with background loading via ajax +# gustaf neumann, fecit may 2006 +::xowiki::Page requireJS "/resources/xowiki/get-http-object.js" +if {![string match "/*" $portlet]} { + set folder_id [$__including_page set parent_id] + set package_id [$folder_id set package_id] + set portlet [site_node::get_url_from_object_id -object_id $package_id]portlets/$portlet +} Index: openacs-4/packages/xowiki/www/portlet.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlet.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlet.adp 1 Aug 2007 21:39:25 -0000 1.1.2.2 @@ -0,0 +1,6 @@ +
      +@title@ +
      +
      + +
      Index: openacs-4/packages/xowiki/www/portlet.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlet.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlet.tcl 1 Aug 2007 21:39:25 -0000 1.2.2.2 @@ -0,0 +1,4 @@ +# +if {![string match "/*" $portlet]} { + set portlet /packages/xowiki/www/portlets/$portlet +} Index: openacs-4/packages/xowiki/www/revisions.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/revisions.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/revisions.adp 1 Aug 2007 21:39:25 -0000 1.2.2.2 @@ -0,0 +1,15 @@ + +@title;noquote@ +@title;noquote@ +@context;noquote@ +@page_id;noquote@ + +@content;noquote@ + + +

      #file-storage.lt_Comments_on_this_file# +

        @gc_comments;noquote@

      +
      + +

      @gc_link;noquote@

      +
      Index: openacs-4/packages/xowiki/www/view-book.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-book.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-book.adp 1 Aug 2007 21:39:25 -0000 1.10.2.2 @@ -0,0 +1,93 @@ + + @title;noquote@ + @context;noquote@ + @header_stuff;noquote@ + + + + + + + + + +
      +
      +
      +@toc;noquote@ +
      +
      @top_portlets;noquote@ + + +
      + + + + + + + + +
      + + + Previous + + + + No Previous + + + + + +
      @book_relpos@
      +
      +
      + + + Next + + + + No Next + +
      +
      +
      + +
      + +
      + +
      +@footer;noquote@ +
      Index: openacs-4/packages/xowiki/www/view-book.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-book.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-book.tcl 1 Aug 2007 21:39:25 -0000 1.5.2.2 @@ -0,0 +1,22 @@ +set title [[$package_id folder_id] title] +set toc [$page include_portlet [list toc -open_page $name -decoration plain -remove_levels 1]] +set i [$page set __last_includelet] +#my log "--last includelet = $i, class=[$i info class] [$page exists __is_book_page]" + +if {$i ne "" && ![$page exists __is_book_page]} { + set p [$i position] + set count [$i count] + #my log "--toc count=$count size=[$i array size page_name] indices=[lsort -integer [$i array names page_name]]" + if {$count > 0} { + set book_relpos [format %.2f%% [expr {100.0 * $p / $count}]] + + if {$p>1} {set book_prev_link [$package_id pretty_link [$i page_name [expr {$p - 1}]]]} + if {$p<$count} {set book_next_link [$package_id pretty_link [$i page_name [expr {$p + 1}]]]} + #ns_log notice "--p=$p, count=$count, relpos=$book_relpos, {100.0 * $p / $count} next=[info exists next_link], prev=[info exists prev_link]" + set page_title "

      [$i current] $title

      " + } else { + set book_relpos 0.0% + set page_title "

      $title

      " + } +} +set header_stuff [::xowiki::Page header_stuff] Index: openacs-4/packages/xowiki/www/view-default.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-default.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-default.adp 1 Aug 2007 21:39:25 -0000 1.35.2.2 @@ -0,0 +1,67 @@ + + + @title;noquote@ + @context;noquote@ + @header_stuff;noquote@ + + + + @header_stuff;noquote@ + + + + + +
      + +@top_portlets;noquote@ +@content;noquote@ +@footer;noquote@ +
      Index: openacs-4/packages/xowiki/www/view-links.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-links.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-links.adp 1 Aug 2007 21:39:25 -0000 1.25.2.2 @@ -0,0 +1,22 @@ + + + + Index: openacs-4/packages/xowiki/www/view-page.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-page.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-page.adp 1 Aug 2007 21:39:25 -0000 1.3.2.2 @@ -0,0 +1,25 @@ + Index: openacs-4/packages/xowiki/www/view-page.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-page.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-page.tcl 1 Aug 2007 21:39:25 -0000 1.1.2.2 @@ -0,0 +1 @@ +set page_title "[$page set page_order] [$page set title]" \ No newline at end of file Index: openacs-4/packages/xowiki/www/view-plain.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-plain.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-plain.adp 1 Aug 2007 21:39:25 -0000 1.21.2.2 @@ -0,0 +1,9 @@ + + + +
      + +@top_portlets;noquote@ +@content;noquote@ + +
      Index: openacs-4/packages/xowiki/www/admin/delete-type.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/delete-type.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/delete-type.tcl 1 Aug 2007 21:39:25 -0000 1.9.2.2 @@ -0,0 +1,24 @@ +::xowiki::Package initialize -ad_doc { + This deletes a type with all subtypes and instances + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Aug 11, 2006 + @cvs-id $Id: delete-type.tcl,v 1.9.2.2 2007/08/01 21:39:25 gustafn Exp $ + + @param object_type + @param query +} -parameter { + {-object_type ::xowiki::Page} + {-return_url "."} +} + +set sql [$object_type instance_select_query -with_subtypes 0 -folder_id [::$package_id folder_id]] +db_foreach retrieve_instances $sql { + permission::require_write_permission -object_id $item_id + $object_type delete -item_id $item_id +} + +# drop type requires that all pages of all xowiki instances are deleted +#foreach type [$object_type object_types -subtypes_first true] {$type drop_object_type} + +ad_returnredirect $return_url Index: openacs-4/packages/xowiki/www/admin/export.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/export.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/export.tcl 1 Aug 2007 21:39:25 -0000 1.5.2.2 @@ -0,0 +1,49 @@ +::xowiki::Package initialize -ad_doc { + export the objects of the specified type + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Aug 11, 2006 + @cvs-id $Id: export.tcl,v 1.5.2.2 2007/08/01 21:39:25 gustafn Exp $ + + @param object_type +} -parameter { + {-object_type ::xowiki::Page} + {-objects ""} +} + +set folder_id [::$package_id folder_id] +set item_ids [list] + +if {$objects eq ""} { + set sql [$object_type instance_select_query -folder_id $folder_id \ + -with_subtypes true] + db_foreach instance_select $sql { lappend item_ids $item_id } +} else { + foreach o $objects { + if {[set id [CrItem lookup -name $o -parent_id $folder_id]] != 0} { + lappend item_ids $id + } + } +} + +set content "" +foreach item_id $item_ids { + ::Generic::CrItem instantiate -item_id $item_id + # + # if the page belongs to an Form/PageTemplate, include it as well + # + if {[$item_id istype ::xowiki::PageInstance]} { + set template_id [$item_id page_template] + if {[lsearch $item_ids $template_id] == -1 && + ![info exists included($template_id)]} { + ::Generic::CrItem instantiate -item_id $template_id + $template_id volatile + append content [$template_id marshall] \n + set included($template_id) 1 + } + } + $item_id volatile + append content [$item_id marshall] \n +} + +ns_return 200 text/plain $content Index: openacs-4/packages/xowiki/www/admin/import.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/import.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/import.adp 1 Aug 2007 21:39:25 -0000 1.3.2.2 @@ -0,0 +1,29 @@ + + @title;noquote@ + @context;noquote@ + + + + + + + + + + +
      + + + + + + +
      @formerror.upload_file@
      +
      +
      + +
      +
      +@msg;noquote@ +
      Index + Index: openacs-4/packages/xowiki/www/admin/import.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/import.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/import.tcl 1 Aug 2007 21:39:25 -0000 1.10.2.2 @@ -0,0 +1,44 @@ +::xowiki::Package initialize -ad_doc { + import objects in xotcl format + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Aug 11, 2006 + @cvs-id $Id: import.tcl,v 1.10.2.2 2007/08/01 21:39:25 gustafn Exp $ + +} + +set msg "" +ad_form \ + -name upload_form \ + -mode edit \ + -export {fs_package_id folder_id orderby selector_type file_types} \ + -html { enctype multipart/form-data } \ + -form { + {upload_file:file(file) {html {size 30}} } + {ok_btn:text(submit) {label "[_ acs-templating.HTMLArea_SelectUploadBtn]"} + } + } \ + -on_submit { + # check file name + if {$upload_file eq ""} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SpecifyUploadFilename] + break + } + + set upload_tmpfile [template::util::file::get_property tmp_filename $upload_file] + set f [open $upload_tmpfile]; set content [read $f]; close $f + + foreach o [::xowiki::Page allinstances] { $o destroy } + if {[catch {namespace eval ::xo::import $content} error]} { + set msg "Error: $error" + } else { + set msg [$package_id import -replace 0] + } + namespace delete ::xo::import + } + + +set title "Import XoWiki Pages" +set context . +ad_return_template Index: openacs-4/packages/xowiki/www/admin/importmsg.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/importmsg.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/importmsg.adp 1 Aug 2007 21:39:25 -0000 1.3.2.2 @@ -0,0 +1,7 @@ + + @title;noquote@ + @context;noquote@ + +@msg;noquote@ +
      Index + Index: openacs-4/packages/xowiki/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/index.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/index.adp 1 Aug 2007 21:39:25 -0000 1.5.2.2 @@ -0,0 +1,24 @@ + + @title;noquote@ + @context;noquote@ + + + +Site-Wide Categories +RSS +@t1;noquote@ + + Index: openacs-4/packages/xowiki/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/index.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/index.tcl 1 Aug 2007 21:39:25 -0000 1.18.2.2 @@ -0,0 +1,67 @@ +::xowiki::Package initialize -ad_doc { + + This is the admin page for the package. It displays all of the types + of wiki pages provides links to delete them + + @author Gustaf Neumann neumann@wu-wien.ac.at + @cvs-id $Id: index.tcl,v 1.18.2.2 2007/08/01 21:39:25 gustafn Exp $ + +} -parameter { + {-object_type ::xowiki::Page} +} + +set context [list] +set title "Administer all kind of [$object_type set pretty_plural]" + +set object_type_key [$object_type set object_type_key] +set object_types [$object_type object_types] +set return_url [ns_conn url] + +TableWidget t1 -volatile \ + -actions [subst { + Action new -label "all pages" -url list + Action new -label parameters -url \ + [export_vars -base /shared/parameters {package_id return_url}] + Action new -label export -url export + Action new -label import -url import + Action new -label permissions -url [export_vars -base permissions {package_id}] + }] \ + -columns { + Field object_type -label [_ xowiki.page_type] + AnchorField instances -label Instances -html {align center} + ImageField_AddIcon edit -label "Add" -html {align center} + ImageField_DeleteIcon delete -label "Delete All" \ + -html {align center onClick "return(confirm('Delete really all?'));"} + } + +set base [::$package_id package_url] +foreach object_type $object_types { + set return_url [export_vars -base ${base}admin {object_type}] + if {[catch {set n [db_list count [$object_type instance_select_query \ + -folder_id [::$package_id set folder_id] \ + -count 1 -with_subtypes false]]}]} { + set n - + set add_title "" + set add_href "" + set delete_title "Delete all such items of this instance" + } else { + set add_title [_ xotcl-core.add [list type [$object_type pretty_name]]] + set add_href [$package_id make_link $package_id edit-new object_type return_url autoname] + set delete_title "Delete all [$object_type pretty_plural] of this instance" + } + t1 add \ + -object_type $object_type \ + -instances $n \ + -instances.href [export_vars -base ./list {object_type}] \ + -edit.href $add_href \ + -delete.href [export_vars -base delete-type {object_type}] \ + -edit.title $add_title \ + -delete.title $delete_title +} + +set t1 [t1 asHTML] + +# set up categories +set category_map_url [export_vars -base \ + [site_node::get_package_url -package_key categories]cadmin/object-map \ + { { object_id $package_id } }] \ No newline at end of file Index: openacs-4/packages/xowiki/www/admin/list.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/list.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/list.adp 1 Aug 2007 21:39:25 -0000 1.1.2.2 @@ -0,0 +1,24 @@ + + @title;noquote@ + @context;noquote@ + + + + +Site-Wide Categories... +RSS +@t1;noquote@ + Index: openacs-4/packages/xowiki/www/admin/list.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/list.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/list.tcl 1 Aug 2007 21:39:25 -0000 1.15.2.2 @@ -0,0 +1,146 @@ +::xowiki::Package initialize -ad_doc { + This is the admin page for the package. It displays all entries + provides links to create, edit and delete these + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Oct 23, 2005 + @cvs-id $Id: list.tcl,v 1.15.2.2 2007/08/01 21:39:25 gustafn Exp $ + + @param object_type show objects of this class and its subclasses +} -parameter { + {-object_type:optional} + {-orderby:optional "last_modified,desc"} +} + +set context [list index] + +# if object_type is specified, only list entries of this type; +# otherwise show types and subtypes of $supertype +if {![info exists object_type]} { + set per_type 0 + set supertype ::xowiki::Page + set object_types [$supertype object_types] + set title "List of all kind of [$supertype set pretty_plural]" + set with_subtypes true + set object_type $supertype +} else { + set per_type 1 + set object_types [list $object_type] + set title "Index of [$object_type set pretty_plural]" + set with_subtypes false +} + +set return_url [expr {$per_type ? [export_vars -base [::$package_id url] object_type] : + [::$package_id url]}] +# set up categories +set category_map_url [export_vars -base \ + [site_node::get_package_url -package_key categories]cadmin/one-object \ + { { object_id $package_id } }] + +set actions "" +foreach type $object_types { + append actions [subst { + Action new \ + -label "[_ xotcl-core.add [list type [$type pretty_name]]]" \ + -url [export_vars -base [::$package_id package_url] {{edit-new 1} {object_type $type} return_url}] \ + -tooltip "[_ xotcl-core.add_long [list type [$type pretty_name]]]" + }] +} + +set ::individual_permissions [expr {[$package_id set policy] eq "::xowiki::policy3"}] +set ::with_publish_status 1 + +TableWidget t1 -volatile \ + -actions $actions \ + -columns { + BulkAction objects -id name -actions { + Action new -label export -tooltip export -url export + } + ImageField_EditIcon edit -label "" -html {style "padding: 2px;"} + if {$::individual_permissions} { + ImageAnchorField permissions -src /resources/xowiki/permissions.png -width 16 \ + -height 16 -border 0 -title "Manage Individual Permssions for this Item" \ + -alt permsissions -label "" -html {style "padding: 2px;"} + } + if {$::with_publish_status} { + ImageAnchorField publish_status -src "" -width 8 \ + -height 8 -border 0 -title "Toggle Publish Status" \ + -alt "publish status" -label [_ xowiki.publish_status] -html {style "padding: 2px;"} + } + Field syndicated -label "RSS" -html {style "padding: 2px;"} + if {[::xo::db::has_ltree]} { + AnchorField page_order -label [_ xowiki.order] -orderby page_order -html {style "padding: 2px;"} + } + AnchorField name -label [_ xowiki.Page-name] -orderby name -html {style "padding: 2px;"} + AnchorField title -label [_ xowiki.Page-title] -orderby title + Field object_type -label [_ xowiki.page_type] -orderby object_type -html {style "padding: 2px;"} + Field size -label "Size" -orderby size -html {align right style "padding: 2px;"} + Field last_modified -label "Last Modified" -orderby last_modified + Field mod_user -label "By User" -orderby mod_user + ImageField_DeleteIcon delete -label "" ;#-html {onClick "return(confirm('Confirm delete?'));"} + } + +foreach {att order} [split $orderby ,] break +t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] $att + +# -page_size 10 +# -page_number 1 + +set attributes [list revision_id content_length creation_user title \ + "to_char(last_modified,'YYYY-MM-DD HH24:MI:SS') as last_modified"] +if {[::xo::db::has_ltree]} { + lappend attributes page_order +} + +set folder_id [::$package_id folder_id] +foreach i [db_list get_syndicated { + select object_id from syndication s, cr_items ci + where object_id = ci.live_revision and parent_id = :folder_id +}] { set syndicated($i) 1 } + +db_foreach instance_select \ + [$object_type instance_select_query \ + -folder_id $folder_id \ + -with_subtypes $with_subtypes \ + -from_clause ", xowiki_page p" \ + -where_clause "p.page_id = cr.revision_id" \ + -select_attributes $attributes \ + -orderby ci.name \ + ] { + set page_link [::$package_id pretty_link $name] + + t1 add \ + -name $name \ + -title $title \ + -object_type [string map [list "::xowiki::" ""] $object_type] \ + -name.href $page_link \ + -last_modified $last_modified \ + -syndicated [info exists syndicated($revision_id)] \ + -size [expr {$content_length ne "" ? $content_length : 0}] \ + -edit.href [export_vars -base $page_link {{m edit} return_url}] \ + -mod_user [::xo::get_user_name $creation_user] \ + -delete.href [export_vars -base [$package_id package_url] {{delete 1} item_id name return_url}] + if {$::individual_permissions} { + [t1 last_child] set permissions.href \ + [export_vars -base permissions {item_id return_url}] + } + if {$::with_publish_status} { + # TODO: this should get some architectural support + if {$publish_status eq "ready"} { + set image active.png + set state "production" + } else { + set image inactive.png + set state "ready" + } + [t1 last_child] set publish_status.src /resources/xowiki/$image + [t1 last_child] set publish_status.href \ + [export_vars -base [$package_id package_url]admin/set-publish-state \ + {state revision_id return_url}] + } + if {[::xo::db::has_ltree]} { + [t1 last_child] set page_order $page_order + } + } + +set t1 [t1 asHTML] Index: openacs-4/packages/xowiki/www/admin/permissions.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/permissions.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/permissions.adp 1 Aug 2007 21:39:25 -0000 1.2.2.2 @@ -0,0 +1,5 @@ + + @page_title@ + @context@ + + Index: openacs-4/packages/xowiki/www/admin/permissions.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/permissions.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/permissions.tcl 1 Aug 2007 21:39:25 -0000 1.2.2.2 @@ -0,0 +1,26 @@ +::xowiki::Package initialize -ad_doc { + Security management for xowiki pages + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Aug 16, 2006 + @cvs-id $Id: permissions.tcl,v 1.2.2.2 2007/08/01 21:39:25 gustafn Exp $ + +} -parameter { + {-item_id:optional} +} + +if {[info exists item_id]} { + set page [::Generic::CrItem instantiate -item_id $item_id] + $page volatile + set object_id $item_id + set page_title "Manage Permissions for Page: [$page name]" + set return_url [$package_id query_parameter return_url [$package_id package_url]admin/list] +} else { + set object_id $package_id + set page_title "Manage Permissions for Package [apm_instance_name_from_id $package_id]" + set return_url [$package_id query_parameter return_url [$package_id package_url]admin] +} + +set context [list $page_title] + + Index: openacs-4/packages/xowiki/www/admin/portal-element-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/portal-element-add.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/portal-element-add.tcl 1 Aug 2007 21:39:25 -0000 1.5.2.2 @@ -0,0 +1,45 @@ +::xowiki::Package initialize -ad_doc { + Add an element to a given portal + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Oct 23, 2005 + @cvs-id $Id: portal-element-add.tcl,v 1.5.2.2 2007/08/01 21:39:25 gustafn Exp $ + + @param object_type show objects of this class and its subclasses +} -parameter { + {-portal_id} + {-page_name} + {-referer .} +} + + +set page_id [$package_id resolve_request -path $page_name method] +set page_id [::Generic::CrItem lookup -name $page_name -parent_id [$package_id folder_id]] +set page_title [$page_id title] + +# for the time being, we add the portlet on the first page (page 0) +set portal_page_id [portal::get_page_id -portal_id $portal_id -sort_key 0] + +if {[db_string check_unique_name_on_page { + select 1 from portal_element_map + where page_id = :portal_page_id + and pretty_name = :page_title +} -default 0]} { + ad_return_error [_ xowiki.portlet_title_exists_error_short] [_ xowiki.portlet_title_exists_error_long] +} else { + db_transaction { + set element_id [portal::add_element \ + -portal_id $portal_id \ + -portlet_name [xowiki_portlet::get_my_name] \ + -pretty_name $page_title \ + -force_region [parameter::get_from_package_key \ + -parameter "xowiki_portal_content_force_region" \ + -package_key "xowiki-portlet"] + ] + portal::set_element_param $element_id package_id $package_id + portal::set_element_param $element_id page_name [$page_id name] + } + ad_returnredirect $referer +} +ad_script_abort + Index: openacs-4/packages/xowiki/www/admin/portal-element-remove.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/portal-element-remove.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/portal-element-remove.tcl 1 Aug 2007 21:39:25 -0000 1.1.2.2 @@ -0,0 +1,19 @@ +::xowiki::Package initialize -ad_doc { + Add an element to a given portal + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Oct 23, 2005 + @cvs-id $Id: portal-element-remove.tcl,v 1.1.2.2 2007/08/01 21:39:25 gustafn Exp $ + +} -parameter { + {-element_id} + {-portal_id} + {-referer .} +} + +# permissions? +portal::remove_element -element_id $element_id +# redirect and abort +ad_returnredirect $referer +ad_script_abort + Index: openacs-4/packages/xowiki/www/admin/set-publish-state.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/set-publish-state.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/set-publish-state.tcl 1 Aug 2007 21:39:25 -0000 1.7.2.2 @@ -0,0 +1,33 @@ +::xowiki::Package initialize -ad_doc { + Changes the publication state of a content item + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Nov 16, 2006 + @cvs-id $Id: set-publish-state.tcl,v 1.7.2.2 2007/08/01 21:39:25 gustafn Exp $ + + @param object_type + @param query +} -parameter { + {-state:required} + {-revision_id:required} + {-return_url "."} +} + +set item_id [db_string get_item_id \ + {select item_id from cr_revisions where revision_id = :revision_id}] + +ns_cache flush xotcl_object_cache ::$item_id +ns_cache flush xotcl_object_cache ::$revision_id + +::xo::db::sql::content_item set_live_revision \ + -revision_id $revision_id \ + -publish_status $state + +if {$state ne "production"} { + ::xowiki::notification::do_notifications -revision_id $revision_id + ::xowiki::datasource $revision_id +} else { + db_dml flush_syndication {delete from syndication where object_id = :revision_id} +} + +ad_returnredirect $return_url Index: openacs-4/packages/xowiki/www/admin/test.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/test.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/test.tcl 1 Aug 2007 21:39:25 -0000 1.9.2.2 @@ -0,0 +1,514 @@ +# regression test for xowiki +# $Id: test.tcl,v 1.9.2.2 2007/08/01 21:39:25 gustafn Exp $ +Object test +test set passed 0 +test set failed 0 +test proc case msg {ad_return_top_of_page "$msg

      $msg

      "} +test proc section msg {my reset; ns_write "

      $msg

      "} +test proc subsection msg {ns_write "

      $msg

      "} +test proc errmsg msg {ns_write "ERROR: $msg
      "; test incr failed} +test proc okmsg msg {ns_write "OK: $msg
      "; test incr passed} +test proc code msg {ns_write "
      $msg
      "} +test proc hint msg {ns_write "$msg
      "} +test proc reset {} { + array unset ::xotcl_cleanup + global af_parts af_key_name + array unset af_parts + array unset af_key_name +} +test proc without_ns_form {cmd} { + rename ::ns_queryget ::ns_queryget.orig + rename ::ns_querygetall ::ns_querygetall.orig + rename ::ad_returnredirect ::ad_returnredirect.orig + proc ::ns_queryget key {::xo::cc form_parameter $key ""} + proc ::ns_querygetall key {::xo::cc form_parameter $key {{}} } + proc ::ad_returnredirect url {::xo::cc returnredirect $url} + if {[catch {set r [uplevel $cmd]} errmsg]} { + if {$errmsg ne ""} {test code "error in command: $errmsg [info exists r]"} + set r "" + } + rename ::ns_queryget "" + rename ::ns_queryget.orig ::ns_queryget + rename ::ns_querygetall "" + rename ::ns_querygetall.orig ::ns_querygetall + rename ::ad_returnredirect "" + rename ::ad_returnredirect.orig ::ad_returnredirect + return $r +} + + +proc ? {cmd expected {msg ""}} { + set r [uplevel $cmd] + if {$msg eq ""} {set msg $cmd} + if {$r ne $expected} { + test errmsg "$msg returned '$r' ne '$expected'" + } else { + test okmsg "$msg - passed ([t1 diff] ms)" + } +} + +set instance_name XOWIKI-TEST +set index_vuh_parms { + {-m view} + {-folder_id:integer 0} +} +::xo::Timestamp t1 + +test case "XoWiki Test Cases" + +test section "Basic Setup" + +test hint "Using XOTcl $::xotcl::version$::xotcl::patchlevel" +? {expr {$::xotcl::version < 1.4}} 0 "XOTcl Version $::xotcl::version >= 1.4" + +set ns_cache_version_old [catch {ns_cache names xowiki_cache xxx}] +if {$ns_cache_version_old} { + ? {set x old} new "upgrade ns_cache: cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nscache" +} else { + ? {set x new} new "ns_cache version seems up to date" +} + +set tdom_version [package require tdom] +if {$tdom_version < "0.8.0"} { + ? {set x old} new "xowiki requires at least tdom 0.8.0 (released Aug 2004), \ + the installed tdom version is to old ($tdom_version).
         \ + Please Upgrade tdom from: cvs -z3 -d:pserver:anonymous@cvs.tdom.org:/usr/local/pubcvs co tdom
      " +} else { + ? {set x new} new "tdom version $tdom_version is ok" +} +######################################################################## +test section "Create New Package Instance of XoWiki" +# +# create a fresh instance for testing +# +if {[site_node::exists_p -url /$instance_name]} { + # we have already an instance, get rid of it + array set info [site_node::get_from_url -url /$instance_name -exact] + # is the instance mounted? + if {$info(package_id) ne ""} { + site_node::unmount -node_id $info(node_id) + } + site_node::delete -node_id $info(node_id) + #test code [array get info] +} + +? {site_node::exists_p -url /$instance_name} 0 \ + "the test instance does not exist" + +#set root_id [site_node::get_root_node_id] +set root_id [db_string "" {select node_id from site_nodes where parent_id is null}] + +if {[db_0or1row check_broken_site_nodes { + select node_id, name from site_nodes where name = :instance_name and parent_id = :root_id +}]} { + test hint "... site nodes seem broken, since we have an entry, but site_node::exists_p returns false" + test hint "... try to fix anyhow" + db_dml fix_broken_entry { + delete from site_nodes where name = :instance_name and parent_id = :root_id + } +} + +# create a fresh instance +array set node [site_node::get -url /] +site_node::instantiate_and_mount \ + -parent_node_id $node(node_id) \ + -node_name $instance_name \ + -package_name xowiki \ + -package_key xowiki +#test code [array get node] + +? {site_node::exists_p -url /$instance_name} 1 \ + "created test instance /$instance_name" +array set info [site_node::get_from_url -url /$instance_name -exact] +? {expr {$info(package_id) ne ""}} 1 "package is mounted, package_id provided" + + +test subsection "Basic Setup: Package, url= /$instance_name/" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/ \ + -actual_query "" \ + -user_id 0 + +? {info exists package_id} 1 "package_id is exported" +? {set package_id} $info(package_id) "package_id right value" +? {::xotcl::Object isobject ::$package_id} 1 "we have a package_id object" +? {$package_id package_url} /$instance_name/ "package_url" +? {$package_id url} /$instance_name/ +? {$package_id id} $package_id "the id of the package object = package_id" + +test code [$package_id serialize] + +test subsection "Basic Setup: Folder Object" +? {$package_id exists folder_id} 1 "folder_id is set" +set folder_id [::$package_id folder_id] +? {::xotcl::Object isobject ::$folder_id} 1 "we have a folder object" +? {::xotcl::Object isobject ::${folder_id}::payload} 1 "we have a payload" +? {::$folder_id name} ::$folder_id "name of folder object is ::folder_id" +? {::$folder_id parent_id} $folder_id "parent_id of folder object is folder_id" +? {expr {[::$folder_id item_id]>0}} 1 "item_id given" +? {expr {[::$folder_id revision_id]>0}} 1 "revision_id given" +? {db_string count "select count(*) from cr_items where parent_id = $folder_id"} 1 \ + "folder contains the folder object" + +test subsection "Create and Render Index Page" +? {$package_id set object} "" "object name parsed" +? {set m} view "method passed from package initialize" +set object [$package_id set object] +set page_item_id [$package_id resolve_page $object $m] +? {expr {$page_item_id ne ""}} 1 "index page resolved" +? {::xotcl::Object isobject ::$page_item_id} 1 "we have a page object" +? {expr {[::$page_item_id item_id]>0}} 1 "item_id given" +? {expr {[::$page_item_id revision_id]>0}} 1 "revision_id given" +? {::$page_item_id parent_id} $folder_id "parent_id of page object is folder_id" +? {::$page_item_id package_id} $package_id "package_id of page object" +? {::$page_item_id name} en:index "name of resolved index page" +? {::$page_item_id istype ::xowiki::Page} 1 "type or subtype of ::xowiki::Page" + +set content [$package_id call $page_item_id $m] +set content_length [string length $content] +? {expr {$content_length > 1000}} 1 \ + "page rendered, content-length $content_length > 1000" +? {string first Error $content} -1 "page contains no error" +? {db_string count "select count(*) from cr_items where parent_id = $folder_id"} 2 \ + "folder contains the folder object and the index page" +#test code [$page_item_id serialize] + +test subsection "Check Permissions based on default policy" +? {::xo::cc user_id} 0 "user_id is guest" +? {::$package_id make_link ::$page_item_id delete return_url} "" \ + "the public cannot delete this page" +? {::$package_id make_link -privilege admin -link admin/ $package_id {} {}} "" \ + "the public cannot admin this package" + +######################################################################## +# +# run a new query, use en/index explicitely +# +test section "New Query: /$instance_name/en/index" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/index \ + -actual_query "" \ + -user_id 0 + +? {info exists package_id} 1 "package_id is exported" +? {set package_id} $info(package_id) "package_id right value" +? {::xotcl::Object isobject ::$package_id} 1 "we have a package_id object" +? {$package_id package_url} /$instance_name/ "package_url" +? {$package_id url} /$instance_name/en/index "url" +? {$package_id id} $package_id "the id of the package object = package_id" +set object [::$package_id set object] +set page_item_id [::$package_id resolve_page $object $m] +set folder_id [::$package_id folder_id] +? {::$page_item_id parent_id} $folder_id "parent_id of page object is folder_id" +? {::$page_item_id package_id} $package_id "package_id of page object" +? {::$page_item_id name} en:index "name of resolved index page" + +######################################################################## +# +# run a new query +# +test section "New Query: /$instance_name/" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/ \ + -actual_query "" \ + -user_id 0 + +? {info exists package_id} 1 "package_id is exported" +? {set package_id} $info(package_id) "package_id right value" +? {::xotcl::Object isobject ::$package_id} 1 "we have a package_id object" +? {$package_id package_url} /$instance_name/ "package_url" +? {$package_id url} /$instance_name/ "url" +? {$package_id id} $package_id "the id of the package object = package_id" + +test subsection "Basic Setup: Folder Object (2nd)" +? {$package_id exists folder_id} 1 "folder_id is set" +set folder_id [::$package_id folder_id] +? {::xotcl::Object isobject ::$folder_id} 1 "we have a folder object" +? {::xotcl::Object isobject ::${folder_id}::payload} 1 "we have a payload" +? {::$folder_id name} ::$folder_id "name of folder object is ::folder_id" +? {::$folder_id parent_id} $folder_id "parent_id of folder object is folder_id" +? {expr {[::$folder_id item_id]>0}} 1 "item_id given" +? {expr {[::$folder_id revision_id]>0}} 1 "revision_id given" +? {db_string count "select count(*) from cr_items where parent_id = $folder_id"} 2 \ + "folder contains the folder object and index" + +test subsection "Render Index Page (2nd)" +? {$package_id set object} "" "object name parsed" +? {set m} view "method passed from package initialize" +set object [$package_id set object] +set page_item_id [$package_id resolve_page $object $m] +? {expr {$page_item_id ne ""}} 1 "index page resolved" +? {::xotcl::Object isobject ::$page_item_id} 1 "we have a page object" +? {expr {[::$page_item_id item_id]>0}} 1 "item_id given" +? {expr {[::$page_item_id revision_id]>0}} 1 "revision_id given" +? {::$page_item_id parent_id} $folder_id "parent_id of page object is folder_id" +? {::$page_item_id package_id} $package_id "package_id of page object" +? {::$page_item_id name} en:index "name of resolved index page" +? {::$page_item_id istype ::xowiki::Page} 1 "type or subtype of ::xowiki::Page" + +set content [$package_id call $page_item_id $m] +set content_length [string length $content] +? {expr {$content_length > 1000}} 1 \ + "page rendered, content-length $content_length > 1000" +? {string first Error $content} -1 "page contains no error" +#test code [$page_item_id serialize] + +######################################################################## +# +# run a new query +# +test section "New Query: /$instance_name/weblog" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/weblog \ + -actual_query "" \ + -user_id 0 + +? {$package_id package_url} /$instance_name/ "package_url" +? {$package_id url} /$instance_name/weblog "url" +? {$package_id id} $package_id "the id of the package object = package_id" +set folder_id [::$package_id folder_id] + +test subsection "Create and Render Weblog" +set content [::$package_id invoke -method $m] +set content_length [string length $content] +? {expr {$content_length > 1000}} 1 \ + "page rendered, content-length $content_length > 1000" +? {string first Error $content} -1 "page contains no error" + +? {db_string count "select count(*) from cr_items where parent_id = $folder_id"} 5 \ + "folder contains: folder object, index and weblog page (+2 includelets)" + + + +######################################################################## +test section "New Query: /$instance_name/en/weblog" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/weblog \ + -actual_query "" \ + -user_id 0 + +set content [::$package_id invoke -method $m] +set content_length [string length $content] +? {expr {$content_length > 1000}} 1 \ + "page rendered, content-length $content_length > 1000" +? {string first Error $content} -1 "page contains no error" + +set full_weblog_content_length $content_length + + +######################################################################## +test section "New Query: /$instance_name/en/weblog with summary=1" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/weblog \ + -actual_query "summary=1" \ + -user_id 0 + +set content [::$package_id invoke -method $m] +set content_length [string length $content] +? {expr {$content_length > 1000}} 1 \ + "page rendered, content-length $content_length > 1000" +? {string first Error $content} -1 "page contains no error" +? {expr {$full_weblog_content_length > $content_length}} 1 "summary is shorter" + + +######################################################################## +test section "Testing as SWA: query /$instance_name/ " + +set swas [db_list get_swa "select grantee_id from acs_permissions \ + where object_id = -4 and privilege = 'admin'"] + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/ \ + -actual_query "" \ + -user_id [lindex $swas 0] + +set content [::$package_id invoke -method $m] +? {string first Error $content} -1 "page contains no error" + +test subsection "Check Permissions based on default policy" +? {expr {[::xo::cc user_id] != 0}} 1 "user_id [lindex $swas 0] is not guest" +? {expr {[::$package_id make_link ::$page_item_id delete return_url] ne ""}} 1 \ + "SWA sees the delete link" +? {expr {[::$package_id make_link -privilege admin -link admin/ $package_id {} {}] ne ""}} 1 \ + "SWA sees admin link" +? {db_string count "select count(*) from cr_items where parent_id=[$package_id folder_id]"} 5 \ + "folder contains: folder object, index and weblog page (+2 includelets)" + + +######################################################################## +test section "Delete weblog-portlet via weblink" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/weblog-portlet \ + -actual_query "m=delete" \ + -user_id [lindex $swas 0] + +set content [::$package_id invoke -method $m] +? {string first Error $content} -1 "page contains no error" +? {::xo::cc exists __continuation} 1 "continuation exists" +? {::xo::cc set __continuation} "ad_returnredirect /$instance_name/" \ + "redirect to main instance" +? {db_string count "select count(*) from cr_items where parent_id=[$package_id folder_id]"} 4 \ + "folder contains: folder object, index and weblog page (+1 includelet)" + +test subsection "Create a test page named hello" + +set page [::xowiki::Page new \ + -title "Hello World" \ + -name en:hello \ + -package_id $package_id \ + -parent_id [$package_id folder_id] \ + -destroy_on_cleanup \ + -text { + Hello [[Wiki]] World. + }] +$page set_content [string trim [$page text] " \n"] +$page initialize_loaded_object +$page save_new +? {db_string count "select count(*) from cr_items where parent_id=[$package_id folder_id]"} 5 \ + "folder contains: folder object, index and weblog, hello page (+1 includelet)" +? {expr {[$page revision_id]>0}} 1 "revision_id given" +? {expr {[$page item_id]>0}} 1 "item_id given" +set revision_id1 [$page revision_id] +set item_id1 [$page item_id] + +$page append title "- V.2" +$page save +? {db_string count "select count(*) from cr_items where parent_id=[$package_id folder_id]"} 5 \ + "still 5 pages" +? {expr {[$page revision_id]>$revision_id1}} 1 "revision_id > old revision_id" +? {expr {[$page item_id] == $item_id1}} 1 "item id the same" + + + +######################################################################## +test section "Recreate weblog-portlet" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/weblog \ + -actual_query "summary=1" \ + -user_id 0 + +set content [::$package_id invoke -method $m] +set content_length [string length $content] +? {expr {$content_length > 1000}} 1 \ + "page rendered, content-length $content_length > 1000" +? {string first Error $content} -1 "page contains no error" +? {db_string count "select count(*) from cr_items where parent_id=[$package_id folder_id]"} 6 \ + "again, 6 pages" + + +######################################################################## +test section "Query revisions for hello page via weblink" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/hello \ + -actual_query "m=revisions" \ + -user_id [lindex $swas 0] + +set content [::$package_id invoke -method $m] +? {string first Error $content} -1 "page contains no error" +? {expr {[string first 2: $content]>-1}} 1 "page contains two revisions" + + +######################################################################## +test section "Edit hello page via weblink" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/hello \ + -actual_query "m=edit" \ + -user_id [lindex $swas 0] + +set content [::$package_id invoke -method $m] +? {string first Error $content} -1 "page contains no error" +? {expr {[string first "- V.2" $content]>-1}} 1 \ + "form page contains the modified title" + +regexp {name="item_id" value="([^\"]+)"} $content _ returned_item_id +? {info exists returned_item_id} 1 "item_id contained in form" +? {expr {$returned_item_id > 0}} 1 "item_id $returned_item_id > 0" +? {$package_id isobject $returned_item_id} 1 "item is instantiated" + +regexp {name="folder_id" value="([^\"]+)"} $content _ returned_folder_id +? {info exists returned_folder_id} 1 "folder_id contained in form" +? {expr {$returned_folder_id > 0}} 1 "returned folder id $returned_folder_id >0" + +regexp {name="__key_signature" value="([^\"]+)"} $content _ signature +? {info exists signature} 1 "signature contained in form" +? {expr {$signature ne ""}} 1 "signature not empty" + +set title [$returned_item_id title] +set text [lindex [$returned_item_id text] 0] + +######################################################################## +test section "Submit edited hello page via weblink" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/hello \ + -actual_query "m=edit" \ + -user_id [lindex $swas 0] \ + -form_parameter [subst { + form:id f1 + form:mode edit + formbutton:ok { OK } + __refreshing_p 0 + __confirmed_p 0 + __new_p 0 + __key_signature {$signature} + __object_name en:hello + name en:hello + object_type ::xowiki::Page + text.format text/html + creator {Gustaf Neumann} + description {{this is the description}} + text {$text ... just testing ..
      } + nls_language en_US + folder_id $returned_folder_id + title {$title} + item_id $returned_item_id }] + +set content [test without_ns_form {::$package_id invoke -method $m}] +? {string first Error $content} -1 "page contains no error" + +? {::xo::cc exists __continuation} 1 "continuation exists" +? {::xo::cc set __continuation} "ad_returnredirect /$instance_name/hello" \ + "redirect to hello page" + +######################################################################## +test section "Query revisions for hello page via weblink" + +::xowiki::Package initialize -parameter $index_vuh_parms \ + -package_id $info(package_id) \ + -url /$instance_name/en/hello \ + -actual_query "m=revisions" \ + -user_id [lindex $swas 0] + +set content [::$package_id invoke -method $m] +? {string first Error $content} -1 "page contains no error" +? {expr {[string first 3: $content]>-1}} 1 "page contains three revisions" + + +ns_write "

      +


      + Tests passed: [test set passed]
      + Tests failed: [test set failed]
      + Tests Time: [t1 diff -start]ms
      +" \ No newline at end of file Index: openacs-4/packages/xowiki/www/admin/samples/ajax-chat.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/samples/ajax-chat.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/samples/ajax-chat.tcl 1 Aug 2007 21:39:25 -0000 1.4.2.2 @@ -0,0 +1,21 @@ +namespace eval ::xowiki::tmp { + ::xowiki::Object create ajax-chat -noinit \ + -set object_type ::xowiki::Object \ + -set lang en \ + -set description {} \ + -set text { + proc content {} { + ::xowiki::Chat login -chat_id 22 + } + } \ + -set nls_language en_US \ + -set mime_type {text/html} \ + -set name en:ajax-chat \ + -set title en:ajax-chat +} + +set title "Import XoWiki Pages" +set context {} +set msg [::xowiki::Page import -objects ::xowiki::tmp::ajax-chat -replace true] +template::set_file "[file dir $__adp_stub]/../importmsg" +ad_return_template Index: openacs-4/packages/xowiki/www/ajax/chat.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/chat.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ajax/chat.js 1 Aug 2007 21:39:26 -0000 1.4.2.2 @@ -0,0 +1,78 @@ +// simple javascript support for polling ajax based chat interface +// $Id: chat.js,v 1.4.2.2 2007/08/01 21:39:26 gustafn Exp $ +// -gustaf neumann April 2006 + +function receiver1() { + if (http.readyState == 4) { + // alert('status code =' + http.status); + if (http.status != 200) { + alert('Something wrong in HTTP request, status code = ' + http.status); + } + } +} + +function chatReceiver() { + if (http.readyState == 4) { + // alert('status code =' + http.status); + if (http.status == 200) { + appendToMessages(http.responseText); + } else { + clearInterval(); + alert('Something wrong in HTTP request, status code = ' + http.status); + } + } +} + +function appendToMessages(content) { + var xmlobject = (new DOMParser()).parseFromString(content, 'application/xhtml+xml'); + var items = xmlobject.getElementsByTagName('TR'); + //alert('found ' + items.length + ' items'); + //var counter = document.getElementById('chatCounter'); + //counter.innerHTML = parseInt(counter.innerHTML) + 1; + //document.getElementById('chatResponse').innerHTML = 'items = ' + items.length + ' l=' + content.length + ' ' + escape(content); + + //if (items.length > 0) {alert('appending ' + content);} + var doc = frames['ichat'].document; + var tbody = frames['ichat'].document.getElementById('messages').tBodies[0]; + //var tbody = tbodies[tbodies.length -1]; + //for (var i = 0 ; i < items.length ; i++) { + // tbody.appendChild(frames['ichat'].document.importNode(items[i],true)); + //} + var tr, td, e, s; + for (var i = 0 ; i < items.length ; i++) { + tr = doc.createElement('tr'); + e = items[i].getElementsByTagName('TD'); + td = doc.createElement('td'); + td.innerHTML = decodeURIComponent(e[0].firstChild.nodeValue); + td.className = 'timestamp'; + tr.appendChild(td); + + td = doc.createElement('td'); + s = e[1].firstChild.nodeValue; + td.innerHTML = decodeURIComponent(e[1].firstChild.nodeValue.replace(/\+/g,' ')); + td.className = 'user'; + tr.appendChild(td); + + td = doc.createElement('td'); + td.innerHTML = decodeURIComponent(e[2].firstChild.nodeValue.replace(/\+/g,' ')); + td.className = 'message'; + tr.appendChild(td); + + tbody.appendChild(tr); + } + frames['ichat'].window.scrollTo(0,tbody.offsetHeight); +} + + +function chatSendMsg(send_url,handler) { + var msgField = document.getElementById('chatMsg'); + chatSendCmd(send_url + encodeURIComponent(msgField.value),handler); + msgField.value = ''; +} + +var msgcount = 0; // hack to overcome IE +function chatSendCmd(url,handler) { + http.open('GET', url + '&mc=' + msgcount++, true); + http.onreadystatechange = handler; + http.send(null); +} Index: openacs-4/packages/xowiki/www/ajax/chat.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/chat.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ajax/chat.tcl 1 Aug 2007 21:39:26 -0000 1.4.2.2 @@ -0,0 +1,40 @@ +ad_page_contract { + a tiny chat client + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Jan 31, 2006 + @cvs-id $Id: chat.tcl,v 1.4.2.2 2007/08/01 21:39:26 gustafn Exp $ +} -query { + m + id + s + msg:optional + {mode ""} +} + +#ns_log notice "--c m=$m session_id=$s [clock format [lindex [split $s .] 1] -format %H:%M:%S] mode=$mode" +::xowiki::Chat c1 -volatile -chat_id $id -session_id $s -mode $mode +switch -- $m { + add_msg { + #ns_log notice "--c call c1 $m '$msg'" + set _ [c1 $m $msg] + #ns_log notice "--c add_msg returns '$_'" + } + login - + subscribe - + get_new - + get_all {set _ [c1 $m]} + default {ns_log error "--c unknown method $m called."} +} + +ns_return 200 text/html " + + + +$_
      + +" \ No newline at end of file Index: openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/scripted-streaming-chat.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js 1 Aug 2007 21:39:26 -0000 1.1.2.2 @@ -0,0 +1,73 @@ +// simple javascript support for streaming ajax based chat interface +// $Id: scripted-streaming-chat.js,v 1.1.2.2 2007/08/01 21:39:26 gustafn Exp $ +// -gustaf neumann April 2006 + +function getHttpObject() { + var http_request = false; + if (window.XMLHttpRequest) { // Mozilla, Safari,... + http_request = new XMLHttpRequest(); + } else if (window.ActiveXObject) { // IE + try { + http_request = new ActiveXObject('Msxml2.XMLHTTP'); + } catch (e) { + try { + http_request = new ActiveXObject('Microsoft.XMLHTTP'); + } catch (e) {} + } + } + + if (!http_request) { + alert('Cannot create and instance of XMLHTTP'); + } + return http_request; +} + +function getData(data) { + var messages = document.getElementById('messages'); + for (var i=0;ixowiki-doc +
      +
      + Last modified: Mon Oct 31 13:36:50 CET 2005 + Index: openacs-4/packages/xowiki/www/portlets/calendar-portlet.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/calendar-portlet.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/calendar-portlet.adp 1 Aug 2007 21:39:26 -0000 1.1.2.2 @@ -0,0 +1,5 @@ + + Index: openacs-4/packages/xowiki/www/portlets/calendar-portlet.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/calendar-portlet.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/calendar-portlet.tcl 1 Aug 2007 21:39:26 -0000 1.2.2.2 @@ -0,0 +1,8 @@ +# +::xowiki::Page requireCSS "/resources/calendar/calendar.css" + +set date [dt_sysdate] +proc my_get_url_stub {args} { + return /dotlrn/calendar +} +set url_stub_callback "my_get_url_stub" Index: openacs-4/packages/xowiki/www/portlets/forums-portlet.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/forums-portlet.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/forums-portlet.adp 1 Aug 2007 21:39:26 -0000 1.1.2.2 @@ -0,0 +1,2 @@ + + Index: openacs-4/packages/xowiki/www/portlets/forums-portlet.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/forums-portlet.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/forums-portlet.tcl 1 Aug 2007 21:39:26 -0000 1.1.2.2 @@ -0,0 +1,10 @@ + +set portal_id [dotlrn::get_portal_id -user_id [ad_conn user_id]] +set config(shaded_p) f +set config(package_id) [db_list get_forum_ids " + select value from portal_pages, portal_element_map, portal_element_parameters + where portal_id = $portal_id and portal_pages.page_id = portal_element_map.page_id + and portal_element_parameters.element_id = portal_element_map.element_id + and portal_element_map.name = 'forums_portlet' + and key = 'package_id'"] +set cf [array get config] \ No newline at end of file Index: openacs-4/packages/xowiki/www/portlets/include.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/include.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/include.tcl 1 Aug 2007 21:39:26 -0000 1.3.2.2 @@ -0,0 +1,4 @@ +#ns_log notice "--including_page= $__including_page, portlet=$portlet" +set content [$__including_page include_portlet $portlet] +set header_stuff [::xowiki::Page header_stuff] +template::set_file [file dir $__adp_stub]/plain-include Index: openacs-4/packages/xowiki/www/portlets/plain-include.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/plain-include.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/plain-include.adp 1 Aug 2007 21:39:26 -0000 1.1.2.2 @@ -0,0 +1 @@ +@content;noquote@ Index: openacs-4/packages/xowiki/www/portlets/portlet-skin.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/portlet-skin.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/portlet-skin.adp 1 Aug 2007 21:39:26 -0000 1.1.2.2 @@ -0,0 +1,6 @@ +
      +@name@ +
      +
      +@content;noquote@ +
      Index: openacs-4/packages/xowiki/www/portlets/weblog-mini-calendar.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/weblog-mini-calendar.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/weblog-mini-calendar.adp 1 Aug 2007 21:39:26 -0000 1.1.2.2 @@ -0,0 +1,49 @@ + + + + + + + + +
      + + + + + + +
      + #calendar.prev_month# + @curr_month@ @year@ + #calendar.next_month# +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + +
      @days_of_week.day_short@
      + @days.count@ @days.day_number@ @days.day_number@
      + +
      Index: openacs-4/packages/xowiki/www/portlets/weblog-mini-calendar.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/portlets/weblog-mini-calendar.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/portlets/weblog-mini-calendar.tcl 1 Aug 2007 21:39:26 -0000 1.8.2.2 @@ -0,0 +1,146 @@ +::xowiki::Page requireCSS "/resources/calendar/calendar.css" +set package_id [::xo::cc package_id] +set folder_id [$__including_page set parent_id] +set including_item_id [$__including_page set item_id] + +if {![exists_and_not_null base_url]} { + if {![info exists page]} {set page [$package_id get_parameter weblog_page]} + set base_url [$package_id pretty_link $page] +} + +set date [ns_queryget date] +if {![exists_and_not_null date]} { + set date [dt_sysdate] +} + +#if {[exists_and_not_null page_num]} { +# set page_num "&page_num=$page_num" +#} else { +# set page_num "" +#} + +array set message_key_array { + list #acs-datetime.List# + day #acs-datetime.Day# + week #acs-datetime.Week# + month #acs-datetime.Month# +} + +# Get the current month, day, and the first day of the month +if {[catch { + dt_get_info $date +} errmsg]} { + set date [dt_sysdate] + dt_get_info $date +} + +set now [clock scan $date] +set date_list [dt_ansi_to_list $date] +set year [dt_trim_leading_zeros [lindex $date_list 0]] +set month [dt_trim_leading_zeros [lindex $date_list 1]] +set day [dt_trim_leading_zeros [lindex $date_list 2]] + +set months_list [dt_month_names] +set curr_month_idx [expr {[dt_trim_leading_zeros [clock format $now -format "%m"]]-1}] + +set curr_month [lindex $months_list $curr_month_idx ] +set prev_month [clock format [clock scan "1 month ago" -base $now] -format "%Y-%m-%d"] +set next_month [clock format [clock scan "1 month" -base $now] -format "%Y-%m-%d"] +set prev_month_url [export_vars -base $base_url {{date $prev_month} page_num summary}] +set next_month_url [export_vars -base $base_url {{date $next_month} page_num summary}] +#set next_month_url "$base_url?date=[ad_urlencode $next_month]${page_num}" + +set first_day_of_week [lc_get firstdayofweek] +set week_days [lc_get abday] +multirow create days_of_week day_short +for {set i 0} {$i < 7} {incr i} { + multirow append days_of_week [lindex $week_days [expr {($i + $first_day_of_week) % 7}]] +} + +db_foreach entries_this_month "select count(ci.item_id) as c, + [::xo::db::sql date_trunc day p.publish_date] as d \ + from xowiki_pagei p, cr_items ci \ + where ci.parent_id = $folder_id \ + and ci.item_id = p.item_id and ci.live_revision = p.page_id \ + and ci.content_type not in ('::xowiki::PageTemplate') \ + and ci.item_id != $including_item_id \ + and ci.publish_status <> 'production' \ + and [::xo::db::sql date_trunc_expression month p.publish_date $year-$month-01] \ + group by [::xo::db::sql date_trunc day p.publish_date]" { + set entries([lindex $d 0]) $c + } + +multirow create days day_number beginning_of_week_p end_of_week_p today_p active_p url count class + +set day_of_week 1 + +# Calculate number of active days +set active_days_before_month [expr {[dt_first_day_of_month $year $month] -1}] +set active_days_before_month [expr {($active_days_before_month + 7 - $first_day_of_week) % 7}] + +set calendar_starts_with_julian_date [expr {$first_julian_date_of_month - $active_days_before_month}] +set day_number [expr {$days_in_last_month - $active_days_before_month + 1}] + +for {set julian_date $calendar_starts_with_julian_date} {$julian_date <= $last_julian_date + 7} {incr julian_date} { + + if {$julian_date > $last_julian_date_in_month && $end_of_week_p eq "t" } { + break + } + set today_p f + set active_p t + + if {$julian_date < $first_julian_date_of_month} { + set active_p f + } elseif {$julian_date > $last_julian_date_in_month} { + set active_p f + } + set ansi_date [dt_julian_to_ansi $julian_date] + + if {$julian_date == $first_julian_date_of_month} { + set day_number 1 + } elseif {$julian_date == $last_julian_date_in_month +1} { + set day_number 1 + } + + if {$julian_date == $julian_date_today} { + set today_p t + } + + if { $day_of_week == 0} { + set beginning_of_week_p t + } else { + set beginning_of_week_p f + } + + if { $day_of_week == 7 } { + set day_of_week 0 + set end_of_week_p t + } else { + set end_of_week_p f + } + + # ns_log notice "--D julian_date = $julian_date [dt_julian_to_ansi $julian_date] //$ansi_date" + set count [expr {[info exists entries($ansi_date)] ? + ([info exists noparens] ? $entries($ansi_date) : "($entries($ansi_date))") + : ""}] + if {$today_p} { + set class today + } elseif {$active_p} { + set class active + } else { + set class inactive + } + multirow append days $day_number $beginning_of_week_p $end_of_week_p $today_p $active_p \ + "[export_vars -base $base_url {{date $ansi_date} summary}]" $count $class + incr day_number + incr day_of_week +} + +set sysdate [dt_sysdate] +set today_url [export_vars -base $base_url {{date $sysdate} page_num}] +if {$sysdate eq $date} { + set today_p t +} else { + set today_p f +} + Index: openacs-4/packages/xowiki/www/prototypes/CGI.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/CGI.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/CGI.page 1 Aug 2007 21:39:27 -0000 1.1.2.2 @@ -0,0 +1,11 @@ +# -*- tcl-*- +# $Id: CGI.page,v 1.1.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "CGI" -text { + proc content {} { + return "Hello \[\[Wiki\]\]-World. It is now [clock format [clock seconds]]." + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/CGI2.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/CGI2.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/CGI2.page 1 Aug 2007 21:39:27 -0000 1.2.2.2 @@ -0,0 +1,22 @@ +# -*- tcl-*- +# $Id: CGI2.page,v 1.2.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "CGI2" -text { + # + # The classes and objects here are all local to the object, + # as long as no absolute class or object names are used (no leading colons) + # + Class CGI + CGI instproc content {} { + set somevar 100 + return "Hello \[\[Wiki\]\]-World. It is now \ + [clock format [clock seconds]]. Somevar=$somevar" + } + + # mixin the Class CGI into the payload object of the ::xowiki::Object + # since the object renderer queries the method content, it picks up the + # above behavior + my mixin add CGI +} + + + Index: openacs-4/packages/xowiki/www/prototypes/CGI3.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/CGI3.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/CGI3.page 1 Aug 2007 21:39:27 -0000 1.2.2.2 @@ -0,0 +1,40 @@ +# -*- tcl-*- +# $Id: CGI3.page,v 1.2.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "CGI3" -text { + # + # The parameter declaration sets the context for the + # evaluation. It combines the provided values from an + # includelet with the values provided via the url with + # the specified default values. + # + my initialize -parameter { + {-object_type ::xowiki::Page} + {-text "Hello World"} + {-x:integer} + {-z:integer 100} + } + + # + # The classes and objects here are all local to the object, + # as long as no absolute class or object names are used (no leading colons) + # + + Class CGI + CGI instproc content {} { + my get_parameters + + set vars [info vars] + set somevar 100 + return "Hello \[\[Wiki\]\]-World. It is now \ + [clock format [clock seconds]]. Somevar=$somevar, vars=$vars, + package_id=$package_id, z=3. $text" + } + + # mixin the Class CGI into the payload object of the ::xowiki::Object + # since the object renderer queries the method content, it picks up the + # above behavior + my mixin add CGI +} + + + Index: openacs-4/packages/xowiki/www/prototypes/ajax-chat.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/ajax-chat.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/ajax-chat.page 1 Aug 2007 21:39:27 -0000 1.1.2.2 @@ -0,0 +1,13 @@ +# -*- tcl-*- +# $Id: ajax-chat.page,v 1.1.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "Ajax Chat" -text { + + proc content {} { + #::xowiki::Chat login -chat_id 22 -mode polling + ::xowiki::Chat login -chat_id 22 + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/announcements.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/Attic/announcements.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/announcements.page 1 Aug 2007 21:39:27 -0000 1.3.2.2 @@ -0,0 +1,122 @@ +# -*- tcl-*- +# $Id: announcements.page,v 1.3.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "Announcements" -text { + # + # A sample Announcements object. + # + my initialize -parameter { + {-page_size:integer 10} + {-page_number:integer 1} + {-summary:boolean 0} + {-date ""} + {-tag ""} + {-ptag ""} + {-entries_of en:announcement-entry} + } + + # The name filter is not the most efficient way of selecting + # autonamed entries. However, most times the number of announcements items + # is not overwhelming, so we can live with that for the time being. + # TODO: more efficient selection of autonamed entries + + # + # The following definition is the default rendering per + # announcements entry. This is executed in the context of every displayed page. + # + Class create EntryRenderer -instproc render {} { + my instvar package_id name title creator creation_user pretty_date description publish_date + [my set __parent] instvar weblog_obj + + set link [::$package_id pretty_link $name] + set more [expr {[$weblog_obj summary] ? + " \[#xowiki.weblog-more#\]" : ""}] + append more "

      " + set day [lc_time_fmt [my set publish_date] "%x"] + set my_footer [my htmlFooter] + + append content "
      " \ + "

      $title

      " \ + " ($day)
      " \ + $description $more $my_footer \n\ + "
      " + } + + # + # The following definition is the renderer for the full weblog. + # This is executed in the context of the whole weblog object + # + Class create AnnouncementsRenderer -instproc render {} { + my instvar filter_msg link name prev_page_link next_page_link title + + set filter "" + set prev "" + set next "" + + if {[info exists filter_msg]} { + set filter "
      $filter_msg
      " + } + if {[info exists prev_page_link]} { + set prev "\ + Previous Page" + } + if {[info exists next_page_link]} { + set next "\ + Next Page" + } + set page [my set __page] + [my set __parent] instvar weblog_obj + set rss [$page include_portlet \ + "rss-button -title {[$page title]} -entries_of [$weblog_obj entries_of]"] + #set rss [list [self] [lsort [my info vars]]] + return "
      $filter [next] $prev $next
      $rss
      " + } + + my proc content {} { + my get_parameters + set page [my info parent] + + if {[$page exists __including_page]} { + set i [$page set __including_page] + set exclude_item_ids [$i item_id] + $i set render_adp 0 ;# no double substitutions + #my log "--W including page $i" + } else { + #my log "--W NO including page" + set exclude_item_ids [$page item_id] + $page set __no_footer 1 + } + + # on the announcements page, an edit-new should not create an object + ::xo::cc set_parameter object_type ::xowiki::Page + ::xo::cc set_parameter autoname 1 + + # use the above defined custom renderers + set renderer [self]::AnnouncementsRenderer + set entry_renderer [self]::EntryRenderer + + set w [::xowiki::Weblog new -destroy_on_cleanup \ + -package_id $package_id \ + -page_size $page_size \ + -page_number $page_number \ + -summary $summary \ + -date $date \ + -category_id [ns_queryget category_id] \ + -tag $tag \ + -ptag $ptag \ + -entry_label "Announcements" \ + -exclude_item_ids $exclude_item_ids \ + -entry_renderer $entry_renderer \ + -entry_flag __no_form_page_footer \ + -entries_of $entries_of \ + ] + $w set __page $page + $w mixin add $renderer + return [$w render] + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/bib.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/bib.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/bib.page 1 Aug 2007 21:39:27 -0000 1.2.2.2 @@ -0,0 +1,99 @@ +# -*- tcl -*- +# $Id: bib.page,v 1.2.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "Bibliography Includelet" -text { + # + # A bibliography interface based on weblog. + # Bibliography entries are typically selected via + # entries_of (PageInstances, FormInstances). + # + # Gustaf Neumann fecit, May 2007 + # + my initialize -parameter { + {-summary:boolean 0} + {-date ""} + {-category_id ""} + {-tag ""} + {-ptag ""} + {-entries_of ""} + } + + # + # The following definition is the default rendering per + # weblog entry. This is executed in the context of every displayed page. + # + Class create EntryRenderer + EntryRenderer instproc render {} { + append content "
    • [next]
    • \n" + } + EntryRenderer instproc by_date {} { + array set ia [my set instance_attributes] + return "$ia(year)-[format %2d $ia(month)]" + } + + # + # The following definition is the renderer for the full weblog. + # This is executed in the context of the whole weblog object + # + Class create WeblogRenderer -instproc render {} { + my instvar filter_msg link name prev_page_link next_page_link + + set prev "" + set next "" + + if {[info exists prev_page_link]} { + set prev "\ + Previous Page" + } + if {[info exists next_page_link]} { + set next "\ + Next Page" + } + return "
        [next]
      $prev $next" + } + + my proc content {} { + my get_parameters + set page [my info parent] + + if {[$page exists __including_page]} { + set i [$page set __including_page] + set exclude_item_ids [$i item_id] + $i set render_adp 0 ;# no double substitutions + #my log "--W including page $i" + } else { + #my log "--W NO including page" + set exclude_item_ids [$page item_id] + $page set __no_footer 1 + } + + # on the current page, an edit-new should not create an ::xowiki::object + ::xo::cc set_parameter object_type ::xowiki::Page + + # use the custom renderers defined above + set renderer [self]::WeblogRenderer + set entry_renderer [self]::EntryRenderer + + set w [::xowiki::Weblog new -destroy_on_cleanup \ + -package_id $package_id \ + -summary $summary \ + -date $date \ + -category_id $category_id \ + -tag $tag \ + -ptag $ptag \ + -no_footer true \ + -sort_composite "method,by_date,desc" \ + -entries_of $entries_of \ + -exclude_item_ids $exclude_item_ids \ + -entry_renderer $entry_renderer \ + ] + + $w mixin add $renderer + return [$w render] + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/book.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/book.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/book.page 1 Aug 2007 21:39:27 -0000 1.2.2.2 @@ -0,0 +1,14 @@ +::xowiki::Page new -title "Book" -text { +{{set-parameter template_file view-default}} +

      +>>left-col25<< +{{toc -decoration plain -book_mode 1 -expand_all 1}} +>><< + +>>right-col75<< +

      @title@

      +

      Creator: @creator@

      +

      {{book}}

      +>><< + +} Index: openacs-4/packages/xowiki/www/prototypes/categories-portlet.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/categories-portlet.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/categories-portlet.page 1 Aug 2007 21:39:27 -0000 1.2.2.2 @@ -0,0 +1,111 @@ +# -*- tcl-*- +# $Id: categories-portlet.page,v 1.2.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "Categories" -text { + + # display the category tree with associated pages + # -gustaf neumann + # + # valid parameters from the adp include are + # tree_name: match pattern, if specified displays only the trees + # with matching names + # no_tree_name: if specified, tree names are not displayed + # open_page: name (e.g. en:iMacs) of the page to be opened initially + # tree_style: boolean, default: true, display based on mktree + + my initialize -parameter { + {-tree_name ""} + {-tree_style:boolean 1} + {-no_tree_name:boolean 0} + {-count:boolean 0} + {-summary:boolean 0} + {-open_page ""} + {-category_ids ""} + {-except_category_ids ""} + } + + #if {![info exists name]} {set name "Categories"} + + my proc content {} { + my get_parameters + set folder_id [$package_id folder_id] + + set open_item_id [expr {$open_page ne "" ? + [CrItem lookup -name $open_page -parent_id $folder_id] : 0}] + + set content "" + foreach tree [category_tree::get_mapped_trees $package_id] { + foreach {tree_id my_tree_name ...} $tree {break} + if {$tree_name ne "" && ![string match $tree_name $my_tree_name]} continue + if {!$no_tree_name} { + append content "

      $my_tree_name

      " + } + set categories [list] + set pos 0 + set cattree(0) [::xowiki::CatTree new -volatile -orderby pos -name $my_tree_name] + foreach category_info [category_tree::get_tree $tree_id] { + foreach {cid category_label deprecated_p level} $category_info {break} + set c [::xowiki::Category new -orderby pos -category_id $cid -package_id $package_id \ + -level $level -label $category_label -pos [incr pos]] + set cattree($level) $c + set plevel [expr {$level -1}] + $cattree($plevel) add $c + set category($cid) $c + lappend categories $cid + #set itemobj [Object new -set name en:index -set title MyTitle -set prefix "" -set suffix ""] + #$cattree(0) add_to_category -category $c -itemobj $itemobj -orderby title + } + + set sql "category_object_map c, cr_items ci, cr_revisions r, xowiki_page p \ + where c.object_id = ci.item_id and ci.parent_id = $folder_id \ + and ci.content_type not in ('::xowiki::PageTemplate') \ + and category_id in ([join $categories ,]) \ + and r.revision_id = ci.live_revision \ + and p.page_id = r.revision_id" + + if {$except_category_ids ne ""} { + append sql \ + " and not exists (select * from category_object_map c2 \ + where ci.item_id = c2.object_id \ + and c2.category_id in ($except_category_ids))" + } + #my log "--c category_ids=$category_ids" + if {$category_ids ne ""} { + foreach cid [split $category_ids ,] { + append sql " and exists (select * from category_object_map \ + where object_id = ci.item_id and category_id = $cid)" + } + } + + if {$count} { + db_foreach get_counts \ + "select count(*) as nr,category_id from $sql group by category_id" { + $category($category_id) set count $nr + set s [expr {$summary ? "&summary=$summary" : ""}] + $category($category_id) href [ad_conn url]?category_id=$category_id$s + $category($category_id) open_tree + } + append content [$cattree(0) render -tree_style $tree_style] + } else { + db_foreach get_pages \ + "select ci.item_id, ci.name, ci.content_type, r.title, category_id from $sql" { + if {$title eq ""} {set title $name} + set itemobj [Object new] + set prefix "" + set suffix "" + foreach var {name title prefix suffix} {$itemobj set $var [set $var]} + $cattree(0) add_to_category \ + -category $category($category_id) \ + -itemobj $itemobj \ + -orderby title \ + -open_item [expr {$item_id == $open_item_id}] + } + append content [$cattree(0) render -tree_style $tree_style] + } + } + return $content + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/contributors.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/contributors.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/contributors.page 1 Aug 2007 21:39:27 -0000 1.3.2.2 @@ -0,0 +1,33 @@ +# -*- tcl-*- +# $Id: contributors.page,v 1.3.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "Contributors" -text { + + my proc content {} { + my instvar package_id + set folder_id [$package_id folder_id] + + TableWidget t1 -volatile \ + -columns { + Field contributor -label "Contributor" + Field count -label "Page Revisions" -html { align right } + } + + db_foreach get_contributors {select count(object_id) as count, creation_user + from acs_objects o, cr_revisions cr,cr_items ci + where object_id = revision_id + and parent_id = :folder_id + and cr.item_id = ci.item_id + group by creation_user order by count desc + } { + if {$creation_user eq ""} continue + t1 add \ + -contributor [::xo::get_user_name $creation_user] \ + -count $count + } + return "The following users have contributed to this xowiki instance:

      [t1 asHTML]

      " + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/index.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/index.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/index.page 1 Aug 2007 21:39:27 -0000 1.2.2.2 @@ -0,0 +1,27 @@ +::xowiki::Page new -title "Index Page" -text { + +

      +This is the default start page of XoWiki. You can edit this page and save it to provide a personalized look of the XoWiki instance. You can as well provide a different index page through configuration. +You can also view the contents of the Wiki in a weblog style. +For more details, consult the [[http://media.wu-wien.ac.at/download/xowiki-doc/|XoWiki documentation]]. +

      +

      +A user can define notifications +for the whole XoWiki instance (by clicking on the notifications button +in the menu bar or for categories (by clicking on the letter symbol +next to the category entries at the bottom of the page) +

      +>>left-col<< +{{recent -max_entries 25}} +>><< +>>right-col<< +{{last-visited -title "Last Visited" -max_entries 10 }} +
      +{{most-popular -title "Most Popular" -max_entries 10 }} +>><< + +} + + + + Index: openacs-4/packages/xowiki/www/prototypes/news-item.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/Attic/news-item.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/news-item.page 1 Aug 2007 21:39:27 -0000 1.1.2.2 @@ -0,0 +1,17 @@ +# -*- tcl-*- +# $Id: news-item.page,v 1.1.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Form new \ + -set name en:news-item \ + -title "News Item" \ + -set anon_instances t \ + -set form {{
      @_title@ @_description@ @detail_link@ @_nls_language@
      } text/html} \ + -set text {

      @_description@

      @detail_link@

      } \ + -set form_constraints { + _page_order:hidden + _creator:hidden + _title:text,label=#acs-kernel.common_Title# + {detail_link:detail_link,label=Detail URL} + } + + + Index: openacs-4/packages/xowiki/www/prototypes/news.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/news.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/news.page 1 Aug 2007 21:39:27 -0000 1.1.2.2 @@ -0,0 +1,120 @@ +# -*- tcl-*- +# $Id: news.page,v 1.1.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "News" -text { + # + # A sample News object. + # + my initialize -parameter { + {-page_size:integer 10} + {-page_number:integer 1} + {-summary:boolean 0} + {-date ""} + {-tag ""} + {-ptag ""} + {-entries_of en:news-item} + } + + # The name filter is not the most efficient way of selecting + # autonamed entries. However, most times the number of news items + # is not overwhelming, so we can live with that for the time being. + # TODO: more efficient selection of autonamed entries + + # + # The following definition is the default rendering per + # news entry. This is executed in the context of every displayed page. + # + Class create EntryRenderer -instproc render {} { + my instvar package_id name title creator creation_user pretty_date description publish_date + [my set __parent] instvar weblog_obj + + set link [::$package_id pretty_link $name] + set more [expr {[$weblog_obj summary] ? + " \[#xowiki.weblog-more#\]" : ""}] + append more "

      " + set day [lc_time_fmt [my set publish_date] "%x"] + set my_footer [my htmlFooter] + + append content "
      " \ + "

      $title

      " \ + " ($day)
      " \ + $description $more $my_footer \n\ + "
      " + } + + # + # The following definition is the renderer for the full weblog. + # This is executed in the context of the whole weblog object + # + Class create NewsRenderer -instproc render {} { + my instvar filter_msg link name prev_page_link next_page_link title + + set filter "" + set prev "" + set next "" + + if {[info exists filter_msg]} { + set filter "
      $filter_msg
      " + } + if {[info exists prev_page_link]} { + set prev "\ + Previous Page" + } + if {[info exists next_page_link]} { + set next "\ + Next Page" + } + set page [my set __page] + set rss [$page include_portlet \ + "rss-button -title {[$page title]} -entries_of [my entries_of]"] + #set rss [list [self] [lsort [my info vars]]] + return "
      $filter [next] $prev $next
      $rss
      " + } + + my proc content {} { + my get_parameters + set page [my info parent] + + if {[$page exists __including_page]} { + set i [$page set __including_page] + set exclude_item_ids [$i item_id] + $i set render_adp 0 ;# no double substitutions + #my log "--W including page $i" + } else { + #my log "--W NO including page" + set exclude_item_ids [$page item_id] + } + + # on the news page, an edit-new should not create an object + ::xo::cc set_parameter object_type ::xowiki::Page + ::xo::cc set_parameter autoname 1 + + # use the above defined custom renderers + set renderer [self]::NewsRenderer + set entry_renderer [self]::EntryRenderer + + set w [::xowiki::Weblog new -destroy_on_cleanup \ + -package_id $package_id \ + -page_size $page_size \ + -page_number $page_number \ + -summary $summary \ + -date $date \ + -category_id [ns_queryget category_id] \ + -tag $tag \ + -ptag $ptag \ + -entry_label "News Articles" \ + -exclude_item_ids $exclude_item_ids \ + -entry_renderer $entry_renderer \ + -entry_flag __no_form_page_footer \ + -entries_of $entries_of \ + ] + $w set __page $page + $w mixin add $renderer + return [$w render] + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/podcast.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/podcast.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/podcast.page 1 Aug 2007 21:39:27 -0000 1.4.2.2 @@ -0,0 +1,31 @@ +# -*- tcl-*- +# $Id: podcast.page,v 1.4.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "XoWiki Podcast" -text { + + my initialize -parameter { + {-name_filter ""} + {-days ""} + } + + proc content {} { + my get_parameters + + ::xo::cc set_parameter master 0 + ::xo::cc set_parameter content-type text/xml + # -siteurl http://localhost:8053 + + set f [::xowiki::Podcast new -destroy_on_cleanup \ + -package_id $package_id \ + -name_filter $name_filter \ + -title [[my info parent] set title] \ + -description [[my info parent] set description] \ + -author [[my info parent] creator] \ + -subtitle "A Sample Collection of Podcast Items" \ + -days $days] + + return [$f render] + } +} + + + Index: openacs-4/packages/xowiki/www/prototypes/sitemap.xml.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/sitemap.xml.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/sitemap.xml.page 1 Aug 2007 21:39:27 -0000 1.1.2.2 @@ -0,0 +1,7 @@ +# -*- tcl-*- +::xowiki::Object new -title "sitemap.xml" -set publish_status production -text { + proc content {} { [my package_id] google-sitemap } +} + + + Index: openacs-4/packages/xowiki/www/prototypes/sitemapindex.xml.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/sitemapindex.xml.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/sitemapindex.xml.page 1 Aug 2007 21:39:27 -0000 1.1.2.2 @@ -0,0 +1,7 @@ +# -*- tcl-*- +::xowiki::Object new -title "sitemap.xml" -set publish_status production -text { + proc content {} { ::xowiki::Package google-sitemapindex } +} + + + Index: openacs-4/packages/xowiki/www/prototypes/weblog-portlet.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/weblog-portlet.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/weblog-portlet.page 1 Aug 2007 21:39:27 -0000 1.9.2.2 @@ -0,0 +1,123 @@ +# -*- tcl-*- +# $Id: weblog-portlet.page,v 1.9.2.2 2007/08/01 21:39:27 gustafn Exp $ +::xowiki::Object new -title "Weblog" -text { + # + # A sample Weblog object. + # + my initialize -parameter { + {-page_size:integer 10} + {-page_number:integer 1} + {-summary:boolean 0} + {-date ""} + {-tag ""} + {-ptag ""} + {-entries_of ""} + } + + # + # The following definition is the default rendering per + # weblog entry. This is executed in the context of every displayed page. + # + Class create EntryRenderer -instproc render {} { + my instvar package_id name title creator creation_user pretty_date description + [my set __parent] instvar weblog_obj + + # We get the instance_attributes, if these are available. For the + # time being, we have these only in full mode (no summary) + if {[my exists instance_attributes]} { + set instance_attributes [my set instance_attributes] + } else { + set instance_attributes "" + } + set link [::xowiki::Portlet detail_link -package_id $package_id -name $name \ + -instance_attributes $instance_attributes] + set show_more [expr {[$weblog_obj summary] && [my exists text] && [my text] ne ""}] + set more [expr {$show_more ? + " \[#xowiki.weblog-more#\]" : ""}] + append more "

      " + set my_footer [my htmlFooter] + + append content "
      " \ + "

      $title

      " \ + "

      Created by $creator, " \ + "last modified by [::xo::get_user_name $creation_user] " \ + "$pretty_date

      " \ + $description $more $my_footer \n\ + "
      " + } + + # + # The following definition is the renderer for the full weblog. + # This is executed in the context of the whole weblog object + # + Class create WeblogRenderer -instproc render {} { + my instvar filter_msg link name prev_page_link next_page_link + + set filter "" + set prev "" + set next "" + + if {[info exists filter_msg]} { + set filter "
      $filter_msg
      " + } + if {[info exists prev_page_link]} { + set prev "\ + Previous Page" + } + if {[info exists next_page_link]} { + set next "\ + Next Page" + } + return "
      $filter [next] $prev $next
      " + } + + my proc content {} { + my get_parameters + set page [my info parent] + + if {[$page exists __including_page]} { + set i [$page set __including_page] + set exclude_item_ids [$i item_id] + $i set render_adp 0 ;# no double substitutions + #my log "--W including page $i" + } else { + #my log "--W NO including page" + set exclude_item_ids [$page item_id] + $page set __no_footer 1 + } + + # on the weblog-portlet page, an edit-new should not create an object + ::xo::cc set_parameter object_type ::xowiki::Page + + # the default renderer + #set renderer ::xowiki::Weblog::WeblogRenderer + #set entry_renderer ::xowiki::Weblog::EntryRenderer + + # the above custom renderers + set renderer [self]::WeblogRenderer + set entry_renderer [self]::EntryRenderer + + set w [::xowiki::Weblog new -destroy_on_cleanup \ + -package_id $package_id \ + -page_size $page_size \ + -page_number $page_number \ + -summary $summary \ + -date $date \ + -category_id [ns_queryget category_id] \ + -tag $tag \ + -ptag $ptag \ + -entries_of $entries_of \ + -exclude_item_ids $exclude_item_ids \ + -entry_renderer $entry_renderer \ + ] + + $w mixin add $renderer + return [$w render] + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/weblog.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/weblog.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/weblog.page 1 Aug 2007 21:39:27 -0000 1.4.2.2 @@ -0,0 +1,16 @@ +::xowiki::Page new -title "Weblog Page" -set publish_status production -text { + +>>content<< +{{weblog-portlet}} +>><< +>>sidebar<< +{{adp portlets/weblog-mini-calendar}} +{{tags -decoration plain}} +{{tags -popular 1 -limit 30 -decoration plain}} +{{categories-portlet -count 1 -decoration plain}} +>><< + +} + + + Index: openacs-4/packages/xowiki/www/resources/active.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/active.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/aqua.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/aqua.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/bracket.gif =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/bracket.gif,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/bw-shadow.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/bw-shadow.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/cattree.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/cattree.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/cattree.css 1 Aug 2007 21:39:27 -0000 1.3.2.2 @@ -0,0 +1,39 @@ +/* Put this inside a @media qualifier so Netscape 4 ignores it */ +@media screen { + /* Turn off list bullets */ + ul.mktree li { list-style: none} + /* Control how "spaced out" the tree is */ + ul.mktree, ul.mktree ul , ul.mktree li { margin-left:0px; padding-left: 7px;} + /* Provide space for our own "bullet" inside the LI */ + ul.mktree li .bullet { padding-left: 15px; } + /* Show "bullets" in the links, depending on the class of the LI that the link's in */ + ul.mktree li.liOpen .bullet { cursor: pointer; background: url(/resources/acs-templating/minus.gif) center left no-repeat; } + ul.mktree li.liClosed .bullet { cursor: pointer; background: url(/resources/acs-templating/plus.gif) center left no-repeat; } + ul.mktree li.liBullet .bullet { margin-left:-15px; padding-left:10px; cursor: default; background: url(/resources/acs-templating/bullet.gif) center left no-repeat; } + /* Sublists are visible or not based on class of parent LI */ + ul.mktree li.liOpen ul { display: block; } + ul.mktree li.liClosed ul { display: none; } + /* Format menu items differently depending on what level of the tree they are in + ul.mktree li { font-size: 12pt; } + ul.mktree li ul li { font-size: 10pt; } + ul.mktree li ul li ul li { font-size: 8pt; } + ul.mktree ul li ul li ul li li { font-size: 6pt; } + */ + + ul.mktree ul li { list-style: none; } + ul.mktree ul li ul li { list-style: none; } + + .portlet ul.mktree { + list-style:none; + list-style-position:outside; + padding-top:0px; + display: inline; } + + .portlet ul.mktree li { + margin-left: 0px; + padding-left: 10px; + background: none; + padding-top:0px; } + +} + Index: openacs-4/packages/xowiki/www/resources/collab-graph.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/collab-graph.js,v diff -u -N -r1.1.2.1 -r1.1.2.2 --- openacs-4/packages/xowiki/www/resources/collab-graph.js 20 Mar 2007 10:09:38 -0000 1.1.2.1 +++ openacs-4/packages/xowiki/www/resources/collab-graph.js 1 Aug 2007 21:39:27 -0000 1.1.2.2 @@ -7,6 +7,13 @@ * The algorithm is based on a spring-style layouter of a Java-based social * network tracker PieSpy written by Paul Mutton Epaul@jibble.orgE. * + * Several add-ons by Gustaf Neumann (March 20, 2007) + * - fixed positioning of item labels when graph is not on top corner + * - new parameter width + * - new parameter arrow (0/1) + * - new parameter weight + * - several positioning fixes + * * Graph is freely distributable under the terms of an MIT-style license. * For details, see the Graph web site: http://dev.buildpatternd.com/trac * @@ -104,9 +111,17 @@ var point = this.translate([node.layoutPosX, node.layoutPosY]); node.value.style.position = 'absolute'; - node.value.style.top = document.getElementById("collab").offsetTop - 10 + point[1] + 'px'; - node.value.style.left = document.getElementById("collab").offsetLeft + point[0] + 'px'; - + var collab = document.getElementById("collab") + var top, left; + if (/MSIE/.test(navigator.userAgent) && !window.opera) { + top = collab.offsetParent.offsetTop; + left = collab.offsetParent.offsetLeft; + } else { + top = collab.offsetTop; + left = collab.offsetLeft; + } + node.value.style.top = top - 10 + point[1] + 'px'; + node.value.style.left = left + point[0] + 'px'; this.ctx.strokeStyle = 'black' this.ctx.beginPath(); this.ctx.arc(point[0], point[1], this.radius, 0, Math.PI*2, true); Index: openacs-4/packages/xowiki/www/resources/email.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/email.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/excanvas.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/excanvas.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/excanvas.js 1 Aug 2007 21:39:27 -0000 1.2.2.2 @@ -0,0 +1,705 @@ +// Copyright 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// TODO: Patterns +// TODO: Radial gradient +// TODO: Clipping paths +// TODO: Coordsize +// TODO: Painting mode +// TODO: Optimize +// TODO: canvas width/height sets content size in moz, border size in ie +// TODO: Painting outside the canvas should not be allowed + +// only add this code if we do not already have a canvas implementation +if (!window.CanvasRenderingContext2D) { + +(function () { + + var G_vmlCanvasManager_ = { + init: function (opt_doc) { + var doc = opt_doc || document; + if (/MSIE/.test(navigator.userAgent) && !window.opera) { + var self = this; +// doc.attachEvent("onreadystatechange", function () { +// self.init_(doc); +// }); + } + }, + + init_: function (doc, e) { +// alert(doc.readyState); + if (doc.readyState == "complete" || doc.readyState == "interactive" || 1) { + // create xmlns + if (!doc.namespaces["g_vml_"]) { + doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml"); + } + + // setup default css + var ss = doc.createStyleSheet(); + ss.cssText = "canvas{display:inline-block;overflow:hidden;" + + "text-align:left;}" + + "canvas *{behavior:url(#default#VML)}"; + + // find all canvas elements + var els = doc.getElementsByTagName("canvas"); + for (var i = 0; i < els.length; i++) { + if (!els[i].getContext) { + this.initElement(els[i]); + } + } + } + }, + + fixElement_: function (el) { + // in IE before version 5.5 we would need to add HTML: to the tag name + // but we do not care about IE before version 6 + var outerHTML = el.outerHTML; + var newEl = document.createElement(outerHTML); + // if the tag is still open IE has created the children as siblings and + // it has also created a tag with the name "/FOO" + if (outerHTML.slice(-2) != "/>") { + var tagName = "/" + el.tagName; + var ns; + // remove content + while ((ns = el.nextSibling) && ns.tagName != tagName) { + ns.removeNode(); + } + // remove the incorrect closing tag + if (ns) { + ns.removeNode(); + } + } + el.parentNode.replaceChild(newEl, el); + return newEl; + }, + + /** + * Public initializes a canvas element so that it can be used as canvas + * element from now on. This is called automatically before the page is + * loaded but if you are creating elements using createElement yuo need to + * make sure this is called on the element. + * @param el {HTMLElement} The canvas element to initialize. + */ + initElement: function (el) { + el = this.fixElement_(el); + el.getContext = function () { + if (this.context_) { + return this.context_; + } + return this.context_ = new CanvasRenderingContext2D_(this); + }; + + var self = this; //bind + el.attachEvent("onpropertychange", function (e) { + // we need to watch changes to width and height + switch (e.propertyName) { + case "width": + case "height": + // coord size changed? + break; + } + }); + + // if style.height is set + + var attrs = el.attributes; + if (attrs.width && attrs.width.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setWidth_(attrs.width.nodeValue); + el.style.width = attrs.width.nodeValue + "px"; + } + if (attrs.height && attrs.height.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setHeight_(attrs.height.nodeValue); + el.style.height = attrs.height.nodeValue + "px"; + } + //el.getContext().setCoordsize_() + } + }; + + G_vmlCanvasManager_.init(); + + // precompute "00" to "FF" + var dec2hex = []; + for (var i = 0; i < 16; i++) { + for (var j = 0; j < 16; j++) { + dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); + } + } + + function createMatrixIdentity() { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + } + + function matrixMultiply(m1, m2) { + var result = createMatrixIdentity(); + + for (var x = 0; x < 3; x++) { + for (var y = 0; y < 3; y++) { + var sum = 0; + + for (var z = 0; z < 3; z++) { + sum += m1[x][z] * m2[z][y]; + } + + result[x][y] = sum; + } + } + return result; + } + + function copyState(o1, o2) { + o2.fillStyle = o1.fillStyle; + o2.lineCap = o1.lineCap; + o2.lineJoin = o1.lineJoin; + o2.lineWidth = o1.lineWidth; + o2.miterLimit = o1.miterLimit; + o2.shadowBlur = o1.shadowBlur; + o2.shadowColor = o1.shadowColor; + o2.shadowOffsetX = o1.shadowOffsetX; + o2.shadowOffsetY = o1.shadowOffsetY; + o2.strokeStyle = o1.strokeStyle; + } + + function processStyle(styleString) { + var str, alpha = 1; + + styleString = String(styleString); + if (styleString.substring(0, 3) == "rgb") { + var start = styleString.indexOf("(", 3); + var end = styleString.indexOf(")", start + 1); + var guts = styleString.substring(start + 1, end).split(","); + + str = "#"; + for (var i = 0; i < 3; i++) { + str += dec2hex[parseInt(guts[i])]; + } + + if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) { + alpha = guts[3]; + } + } else { + str = styleString; + } + + return [str, alpha]; + } + + function processLineCap(lineCap) { + switch (lineCap) { + case "butt": + return "flat"; + case "round": + return "round"; + case "square": + default: + return "square"; + } + } + + /** + * This class implements CanvasRenderingContext2D interface as described by + * the WHATWG. + * @param surfaceElement {HTMLElement} The element that the 2D context should + * be associated with + */ + function CanvasRenderingContext2D_(surfaceElement) { + this.m_ = createMatrixIdentity(); + this.element_ = surfaceElement; + + this.mStack_ = []; + this.aStack_ = []; + this.currentPath_ = []; + + // Canvas context properties + this.strokeStyle = "#000"; + this.fillStyle = "#ccc"; + + this.lineWidth = 1; + this.lineJoin = "miter"; + this.lineCap = "butt"; + this.miterLimit = 10; + this.globalAlpha = 1; + }; + + var contextPrototype = CanvasRenderingContext2D_.prototype; + contextPrototype.clearRect = function() { + this.element_.innerHTML = ""; + this.currentPath_ = []; + }; + + contextPrototype.beginPath = function() { + // TODO: Branch current matrix so that save/restore has no effect + // as per safari docs. + + this.currentPath_ = []; + }; + + contextPrototype.moveTo = function(aX, aY) { + this.currentPath_.push({type: "moveTo", x: aX, y: aY}); + }; + + contextPrototype.lineTo = function(aX, aY) { + this.currentPath_.push({type: "lineTo", x: aX, y: aY}); + }; + + contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, + aCP2x, aCP2y, + aX, aY) { + this.currentPath_.push({type: "bezierCurveTo", + cp1x: aCP1x, + cp1y: aCP1y, + cp2x: aCP2x, + cp2y: aCP2y, + x: aX, + y: aY}); + }; + + contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { + // VML's qb produces different output to Firefox's + // FF's behaviour seems to have changed in 1.5.0.1, check this + this.bezierCurveTo(aCPx, aCPy, aCPx, aCPy, aX, aY); + }; + + contextPrototype.arc = function(aX, aY, aRadius, + aStartAngle, aEndAngle, aClockwise) { + if (!aClockwise) { + var t = aStartAngle; + aStartAngle = aEndAngle; + aEndAngle = t; + } + + var xStart = aX + (Math.cos(aStartAngle) * aRadius); + var yStart = aY + (Math.sin(aStartAngle) * aRadius); + + var xEnd = aX + (Math.cos(aEndAngle) * aRadius); + var yEnd = aY + (Math.sin(aEndAngle) * aRadius); + + this.currentPath_.push({type: "arc", + x: aX, + y: aY, + radius: aRadius, + xStart: xStart, + yStart: yStart, + xEnd: xEnd, + yEnd: yEnd}); + + }; + + contextPrototype.rect = function(aX, aY, aWidth, aHeight) { + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + }; + + contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { + // Will destroy any existing path (same as FF behaviour) + this.beginPath(); + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.stroke(); + }; + + contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { + // Will destroy any existing path (same as FF behaviour) + this.beginPath(); + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.fill(); + }; + + contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { + var gradient = new CanvasGradient_("gradient"); + return gradient; + }; + + contextPrototype.createRadialGradient = function(aX0, aY0, + aR0, aX1, + aY1, aR1) { + var gradient = new CanvasGradient_("gradientradial"); + gradient.radius1_ = aR0; + gradient.radius2_ = aR1; + gradient.focus_.x = aX0; + gradient.focus_.y = aY0; + return gradient; + }; + + contextPrototype.drawImage = function (image, var_args) { + var dx, dy, dw, dh, sx, sy, sw, sh; + var w = image.width; + var h = image.height; + + if (arguments.length == 3) { + dx = arguments[1]; + dy = arguments[2]; + sx = sy = 0; + sw = dw = w; + sh = dh = h; + } else if (arguments.length == 5) { + dx = arguments[1]; + dy = arguments[2]; + dw = arguments[3]; + dh = arguments[4]; + sx = sy = 0; + sw = w; + sh = h; + } else if (arguments.length == 9) { + sx = arguments[1]; + sy = arguments[2]; + sw = arguments[3]; + sh = arguments[4]; + dx = arguments[5]; + dy = arguments[6]; + dw = arguments[7]; + dh = arguments[8]; + } else { + throw "Invalid number of arguments"; + } + + var d = this.getCoords_(dx, dy); + + var w2 = (sw / 2); + var h2 = (sh / 2); + + var vmlStr = []; + + // For some reason that I've now forgotten, using divs didn't work + vmlStr.push(' ' , + '', + ''); + + this.element_.insertAdjacentHTML("BeforeEnd", + vmlStr.join("")); + }; + + contextPrototype.stroke = function(aFill) { + var lineStr = []; + var lineOpen = false; + var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); + var color = a[0]; + var opacity = a[1] * this.globalAlpha; + + lineStr.push(' max.x) { + max.x = c.x; + } + if (min.y == null || c.y < min.y) { + min.y = c.y; + } + if (max.y == null || c.y > max.y) { + max.y = c.y; + } + } + } + lineStr.push(' ">'); + + if (typeof this.fillStyle == "object") { + var focus = {x: "50%", y: "50%"}; + var width = (max.x - min.x); + var height = (max.y - min.y); + var dimension = (width > height) ? width : height; + + focus.x = Math.floor((this.fillStyle.focus_.x / width) * 100 + 50) + "%"; + focus.y = Math.floor((this.fillStyle.focus_.y / height) * 100 + 50) + "%"; + + var colors = []; + + // inside radius (%) + if (this.fillStyle.type_ == "gradientradial") { + var inside = (this.fillStyle.radius1_ / dimension * 100); + + // percentage that outside radius exceeds inside radius + var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside; + } else { + var inside = 0; + var expansion = 100; + } + + var insidecolor = {offset: null, color: null}; + var outsidecolor = {offset: null, color: null}; + + // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie + // won't interpret it correctly + this.fillStyle.colors_.sort(function (cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + for (var i = 0; i < this.fillStyle.colors_.length; i++) { + var fs = this.fillStyle.colors_[i]; + + colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ","); + + if (fs.offset > insidecolor.offset || insidecolor.offset == null) { + insidecolor.offset = fs.offset; + insidecolor.color = fs.color; + } + + if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) { + outsidecolor.offset = fs.offset; + outsidecolor.color = fs.color; + } + } + colors.pop(); + + lineStr.push(''); + } else if (aFill) { + lineStr.push(''); + } else { + lineStr.push( + '' + ); + } + + lineStr.push(""); + + this.element_.insertAdjacentHTML("beforeEnd", lineStr.join("")); + + this.currentPath_ = []; + }; + + contextPrototype.fill = function() { + this.stroke(true); + } + + contextPrototype.closePath = function() { + this.currentPath_.push({type: "close"}); + }; + + /** + * @private + */ + contextPrototype.getCoords_ = function(aX, aY) { + return { + x: (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]), + y: (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) + } + }; + + contextPrototype.save = function() { + var o = {}; + copyState(this, o); + this.aStack_.push(o); + this.mStack_.push(this.m_); + this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); + }; + + contextPrototype.restore = function() { + copyState(this.aStack_.pop(), this); + this.m_ = this.mStack_.pop(); + }; + + contextPrototype.translate = function(aX, aY) { + var m1 = [ + [1, 0, 0], + [0, 1, 0], + [aX, aY, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + contextPrototype.rotate = function(aRot) { + var c = Math.cos(aRot); + var s = Math.sin(aRot); + + var m1 = [ + [c, s, 0], + [-s, c, 0], + [0, 0, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + contextPrototype.scale = function(aX, aY) { + var m1 = [ + [aX, 0, 0], + [0, aY, 0], + [0, 0, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + /******** STUBS ********/ + contextPrototype.clip = function() { + // TODO: Implement + }; + + contextPrototype.arcTo = function() { + // TODO: Implement + }; + + contextPrototype.createPattern = function() { + return new CanvasPattern_; + }; + + // Gradient / Pattern Stubs + function CanvasGradient_(aType) { + this.type_ = aType; + this.radius1_ = 0; + this.radius2_ = 0; + this.colors_ = []; + this.focus_ = {x: 0, y: 0}; + } + + CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { + aColor = processStyle(aColor); + this.colors_.push({offset: 1-aOffset, color: aColor}); + }; + + function CanvasPattern_() {} + + // set up externs + G_vmlCanvasManager = G_vmlCanvasManager_; + CanvasRenderingContext2D = CanvasRenderingContext2D_; + CanvasGradient = CanvasGradient_; + CanvasPattern = CanvasPattern_; + +})(); + +} // if Index: openacs-4/packages/xowiki/www/resources/external.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/external.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/file.jpg =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/file.jpg,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/get-http-object.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/get-http-object.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/get-http-object.js 1 Aug 2007 21:39:28 -0000 1.1.2.2 @@ -0,0 +1,40 @@ +// small cross browser function to get an HTTP object for making +// AJAX style http requests in the background +// -gustaf neumann Jan, 2006 + +function getHttpObject() { + var http_request = false; + if (window.XMLHttpRequest) { // Mozilla, Safari,... + http_request = new XMLHttpRequest(); + if (http_request.overrideMimeType) { + http_request.overrideMimeType('text/xml'); + } + } else if (window.ActiveXObject) { // IE + try { + http_request = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + http_request = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (e) {} + } + } + + if (!http_request) { + alert('Cannot create and instance of XMLHTTP'); + } + return http_request; +} + +if (typeof DOMParser == "undefined") { + DOMParser = function () {} + + DOMParser.prototype.parseFromString = function (str, contentType) { + if (typeof ActiveXObject != "undefined") { + var d = new ActiveXObject("MSXML.DomDocument"); + d.loadXML(str); + return d; + } + } +} + +var http = getHttpObject(); Index: openacs-4/packages/xowiki/www/resources/glossary.gif =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/glossary.gif,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/inactive.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/inactive.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/next-end.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/next-end.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/next.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/next.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/permissions.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/permissions.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/popup-handler.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/popup-handler.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/popup-handler.js 1 Aug 2007 21:39:28 -0000 1.1.2.2 @@ -0,0 +1,33 @@ +var ol_close = "X"; +var ol_closeclick = 1; +//var ol_fgclass="overlibFg"; +//var ol_bgclass="overlibBg"; +var ol_textfontclass="overlibFont"; +var ol_captionfontclass="overlibCapfont"; +var ol_closefontclass="overlibClosefont"; + +var PopupHandler = { + popupTitle : "Definiton", + popupWidth : 250, + init : function (url, title, width) { + if (title) {this.title = title;} else {this.title = this.popupTitle;}; + if (width) {this.width = width;} else {this.width = this.popupWidth;}; + http.open('GET', url, true); + http.onreadystatechange = function() { + if (http.readyState == 4) { + if (http.status != 200) { + alert('Something wrong in HTTP request, status code = ' + http.status); + } + overlib(http.responseText, STICKY, CAPTION, + PopupHandler.title, WIDTH, PopupHandler.width, + FGCOLOR, '#FFFFFF', CAPCOLOR, '#000000', BGCOLOR, '#CCBBBB' ); + } + }; + http.send(null); + } +}; + +function showInfo(url,title, w) { + PopupHandler.init(url,title, w); + return false; +} Index: openacs-4/packages/xowiki/www/resources/previous-end.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/previous-end.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/previous.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/previous.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/swfobject.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/swfobject.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/swfobject.js 1 Aug 2007 21:39:28 -0000 1.1.2.2 @@ -0,0 +1,8 @@ +/** + * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/ + * + * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ +if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="";_19+="";var _1d=this.getParams();for(var key in _1d){_19+="";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="";}_19+="";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.majorfv.major){return true;}if(this.minorfv.minor){return true;}if(this.rev=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject; \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/xowiki.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/xowiki.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/xowiki.css 1 Aug 2007 21:39:28 -0000 1.19.2.2 @@ -0,0 +1,153 @@ +#at-a-glance :active {background: #999999;} +#at-a-glance td.inactive {color: #999999;} +#at-a-glance td.active {color: #003b53;} +#at-a-glance td.today {color: #FFFFFF;} + + +div.wiki-menu { + position: relative; right: 0px; + text-align: right; font-family: sans-serif; font-size: 85%;color: #7A7A78 +} + +#wikicmds {position: relative; top: -24px; right: 0px; height: 0px; + text-align: right; font-family: sans-serif; font-size: 85%;color: #7A7A78;} +/*#portal #wikicmds {top: -90px;}*/ +div.portlet #wikicmds {float: inherit ! important; top: 0px ! important; height: inherit;} +#page-body #wikicmds {top: -30px;} + +#wikicmds a, #wikicmds a:visited, div.wiki-menu a { color: #7A7A78; text-decoration: none;} +#wikicmds a:hover {text-decoration: underline;} +#wikicmds a:active {color: rgb(255,153,51);} +#cmdbar { + background: transparent repeat-x url(/resources/xowiki/aqua.png); + border-bottom: solid 1px rgb(221,221,221); + font-family: sans-serif; font-size: 85%; + padding: 0.25em 0.5em 0.25em 0.5em; + color: #7A7A78; + margin-bottom: 2px; +} +a.external { + color: #002bb8; + background: url(/resources/xowiki/external.png) right center no-repeat; + padding-right: 12px; +} + + +div.xowiki-content {background: #fff; font: 10pt Verdana, Arial, Helvetica, sans-serif;} +/* table, td {font: 10px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif; color: #000;}*/ +#main div.column {text-align: left; margin-bottom: 1em;} +#content {float: left; width: 70%} +div.xowiki-content h1 { + font-size: 24px; clear: both; + border-bottom: solid silver 1px; color: #222222; + margin-top: 1em; margin-bottom: 0.5em; + text-align: left; font-weight: normal; +} +div.xowiki-content h2 { + font-size: 16px; + clear: both; + border-bottom: 1px solid silver; color: #222222; + margin-top: 1em; margin-bottom: 0.25em; + text-align: left; font-weight: normal; +} +div.xowiki-content h3 { + font-size: 14px + text-indent: 0em; + margin-top: 0.75em; margin-bottom: 0.1em; + letter-spacing: 0px; color: #222222; + text-align: left; font-weight: bold; +} +div.xowiki-content h4 {font-size: 12px; margin: 0;} +div.xowiki-content .box {border: 1px solid #a1a5a9; padding: 0 5px 5px 5px; margin: 0 0 1.25em 0;} +div.xowiki-content .errorMsg {color: red; font-weight: bold;} +div.xowiki-content .hr { + height: 1px; border: none; + color: silver; background-color: silver; +} + +#bookNavBar { top: 0px; height: 2px; background-color: #859db8; } + +#content .box h2 {border-bottom: 1px solid #a1a5a9; padding: 5px; background: #f2f2f2; margin: 0 -5px 5px -5px; font-size: 12px;} +#sidebar {float: right; top: 0px; width: 29%; font: 10px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif;} +#sidebar h2 {font-size: 12px; margin: 0;} +#sidebar h3 {font-size: 11px; margin: 0;} +#sidebar h4 {font-size: 10px; margin: 0;} +#sidebar .sidebox li {font-size: 10px; margin: 0;} +img.found {border-width: 0px; height: 12px} +img.undefined {border-width: 2px; border-color: #859db8; height: 8px} + +#left-col {float: left; width: 50%; top: 0px;} +#right-col {float: right; width: 49%; top: 0px;} + +#left-col20 {float: left; width: 14%; top: 0px; margin-right: 10px;} +#left-col25 {float: left; width: 24%; top: 0px; margin-right: 10px;} +#left-col30 {float: left; width: 29%; top: 0px; margin-right: 10px;} +#left-col70 {float: left; width: 69%; top: 0px;} +#left-col75 {float: left; width: 74%; top: 0px;} +#left-col80 {float: left; width: 79%; top: 0px;} + +#right-col20 {float: right; width: 14%; top: 0px; margin-right: 10px;} +#right-col25 {float: right; width: 24%; top: 0px; margin-right: 10px;} +#right-col30 {float: right; width: 29%; top: 0px; margin-right: 10px;} +#right-col70 {float: right; width: 69%; top: 0px;} +#right-col75 {float: right; width: 74%; top: 0px;} +#right-col80 {float: right; width: 79%; top: 0px;} + +#messages .timestamp {font-size: 80%; color: grey} +#messages .user {font-size: 80%; font-weight: bold; color: grey} +#messages .message {vertical-align: top} + +.rss {border:1px solid; + border-color:#FC9 #630 #330 #F96; + padding: 2px; + font: 9px verdana,sans-serif; + color: #FFF; + background: #F60; + text-decoration:none; + margin:0; + margin-right:10px;} +a:hover.rss {color:#dddddd;} +a:visited.rss {color: #FFF} +a:link.rss {color: #FFF} + +div.rightbox {float:right; right: 1em; clear: right; font-size: 75%; padding: 5px; + border:dotted; border-width:1px;background: #f8f8f8 +} +div.presence h1 {font-size: 90%; margin-bottom: 0px} + +div.xowiki-content pre, .code { + font-family: "Courier", monospace; +} + +.string { + color: #7D615B; +} +div.xowiki-content pre, div.code { + font-size: 90%; + font-family: "Courier", monospace; + white-space: pre; + margin-right: 15px; + margin-left: 15px; + margin-bottom: 15px; + padding: 5px 5px; + background-color: #FFFFF8; + border: #cccccc 1px solid; +} + +div.xowiki-content pre p i, div.code p i { + color: #008000; +} +div.xowiki-content pre i, div.code i { + color: #008000; +} +div.xowiki-content pre em, div.code p em { + color: #008000; +} +div.xowiki-content pre em, div.code em { + color: #008000; +} +strong.code { + font-weight: bolder; +} +div.collab-graph div {font-size: 85%;} +div.activity-graph div {font-size: 85%;} Index: openacs-4/packages/xowiki/www/resources/zen-forms-backward-compatibility.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/zen-forms-backward-compatibility.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/zen-forms-backward-compatibility.css 1 Aug 2007 21:39:28 -0000 1.1.2.2 @@ -0,0 +1,108 @@ +/*form fieldset{ + border: 0px solid #F00; +} + +form .form-required-mark { + color: #ff0000; + display: inline; +} + +form .form-item-wrapper { + clear: both; + padding: 5px; +} + +form .form-item-wrapper .form-label { + float: left; + text-align: right; + display: block; + width: 12em; +} + +form .form-item-wrapper .form-widget, form .form-button, form .form-help-text { + display: block; + margin-left: 13em; +} + +form .form-item-wrapper .form-error { + display: block; + margin-left: 13em; + color: #ff0000; +} +*/ + +.form-label-error, .form-widget-error, .form-required-mark, .form-error { + color: #c30000; +} + +/* form layout for forms with divs*/ + +.margin-form fieldset, .vertical-form fieldset, fieldset { + border: 0px solid #000; +} + +.margin-form .form-required-mark { + display: inline; +} + +.margin-form fieldset { + border: 0 solid #FFFFFF; +} + +.margin-form .form-item-wrapper { + clear: both; + padding: 5px; +} + +.margin-form .form-item-wrapper .form-label { + float: left; + text-align: right; + display: block; + width: 15em; +} + +.margin-form .form-item-wrapper .form-widget, .margin-form .form-button, .margin-form div.form-help-text { + display: block; + margin-left: 16em; +} + +.margin-form .form-item-wrapper .form-error, .margin-form .form-item-wrapper .form-widget-error { + display: block; + margin-left: 16em; +} + + +.vertical-form .form-required-mark { + display: inline; +} + +.vertical-form .form-item-wrapper { + clear: both; + padding: 8px; +} + +.vertical-form .form-item-wrapper .form-label{ + text-align: left; + display: block; + +} + +.vertical-form .form-item-wrapper .form-widget{ + display: inline; + +} + + +.inline-form div { + display: inline; +} + + +/* pages that are laid out like forms but do not use the form builder and do not have input fields*/ +.margin-form-div .form-item-wrapper { + padding-bottom: 10px; +} + +.margin-form-div h1 { + margin-left: 13.5em; +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/examples/check_falsch.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/examples/check_falsch.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/examples/check_richtig.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/examples/check_richtig.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/examples/xinha-mc-styles.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/examples/xinha-mc-styles.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/examples/xinha-mc-styles.css 1 Aug 2007 21:39:28 -0000 1.1.2.2 @@ -0,0 +1,34 @@ + +p.angabe { + font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif; + color: #222222; +} +p.loesungshinweis { + font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif; + color: #444444; + background-color: #FFFFF4; + border: #cccccc 1px solid; + padding-right: 5px; + padding-left: 8px; + padding-bottom: 0px; + padding-top: 0px; + margin-bottom: 15px; +} +li.correct_choice { + font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif; + color: #006600; + list-style: none; + background: url(/resources/xowiki/examples/check_richtig.png) center left no-repeat; + margin-left:-30px; + padding-left: 30px; + margin-bottom:12px; +} +li.incorrect_choice { + font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif; + color: #660000; + list-style: none; + background: url(/resources/xowiki/examples/check_falsch.png) center left no-repeat; + margin-left:-30px; + padding-left: 30px; + margin-bottom:12px; +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/flags/cy.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/flags/cy.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/flags/cz.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/flags/cz.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/flags/de.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/flags/de.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/flags/en.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/flags/en.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/flags/es.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/flags/es.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/flags/it.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/flags/it.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/overlib/makemini.pl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/makemini.pl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/makemini.pl 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,95 @@ +#!/usr/bin/perl + +my $doPlugin = 0; +my $x = shift(@ARGV); +if ($x !~ /^-p/) { unshift(@ARGV, $x); } +else { $doPlugin=1; } +my $injs = shift(@ARGV); +my $outjs = shift(@ARGV); + +if ($injs eq '' or $outjs eq '') { + print "Please use this script like this: makemini.pl [-p] in.js out.js\n"; + exit(0); +} + + +open(INJS, $injs); +open(OUTJS, ">$outjs"); + +my $output = ''; + +while () { + my $line = $_; + + if ($line =~ /^\/\//) { + # Remove lines that aren't important: //\ + $line = "" if ($line !~ /^\/\/\\/); + $line = "\n//\\ THIS IS A VERY MODIFIED VERSION. DO NOT EDIT OR PUBLISH. GET THE ORIGINAL!\n\n" if ($line =~ /\/\/\\mini/); + } else { + chop $line; + + $line =~ s/, /,/g unless ($line =~ /'\], '/); # ,{sp} -> , + $line =~ s/; /;/g; # ;{sp} -> ; + $line =~ s/ = /=/g; # {sp}={sp} -> = + $line =~ s/ == /==/g; # {sp}=={sp} -> == + $line =~ s/ < / < + $line =~ s/ > />/g; # {sp}>{sp} -> > + $line =~ s/ & /&/g; # {sp}&{sp} -> & + $line =~ s/ \| /\|/g; # {sp}|{sp} -> | + $line =~ s/ <= /<=/g; # {sp}<={sp} -> <= + $line =~ s/ >= />=/g; # {sp}>={sp} -> >= + $line =~ s/ \+ /\+/g; # {sp}+{sp} -> + + $line =~ s/ - /-/g; # {sp}-{sp} -> - + $line =~ s/ \/ /\//g; + $line =~ s/ \|\| /\|\|/g; # {sp}||{sp} -> || + $line =~ s/ && /&&/g; # {sp}&&{sp} -> && + $line =~ s/ \? /\?/g; # {sp?{sp} -> ? + $line =~ s/ \: /\:/g; # {sp}:{sp} -> : + $line =~ s/ != /!=/g; # {sp}!={sp} -> != + $line =~ s/ += /+=/g; # {sp}+={sp} -> += + $line =~ s/ -= /-=/g; # {sp}-={sp} -> -= + $line =~ s/ \*= /\*=/g; # {sp}*={sp} -> *= + $line =~ s/ \|= /\|=/g; # {sp}|={sp} -> |= + $line =~ s/ \^= /\^=/g; # {sp}^={sp} -> ^= + $line =~ s/= /=/g; # ={sp} -> = + $line =~ s/ =/=/g; # {sp}= -> = + $line =~ s/\+ /\+/g; + $line =~ s/ \+/\+/g; + $line =~ s/- /-/g; + $line =~ s/ -/-/g; + + $line =~ s/\/\/(.*)$//g if ($line !~ /\/\/-->(.*)$/ && $line !~ /http:\/\/(.*)$/); # remove trailing comments unless its part of a javascript insert or web address + $line = '' if $line =~ /^[\n|\/\/]/; # skip blank lines or any line starting with // + + $line =~ s/^\s+//g; + $line =~ s/\s+$//g; + $line =~ s/(.+)\s+(.+)/$1 $2/g; + $line =~ s/\{ (\w)/\{$1/g; + $line =~ s/\) (\w)/\)$1/g; + $line =~ s/\) var/\)var/g; + $line =~ s/[ ]+\(/\(/g; + $line =~ s/\) \{/\)\{/g; + $line =~ s/\} else/\}else/g; + $line =~ s/else \{/else\{/g; + if ($line =~ /^\}$/) { + if ($output =~ /;$/) { + $output .= "}"; + } else { + $output = substr($output,0,length($output)-1) . "}"; + } + $line = ''; + } + } + + $output .= $line if ($line ne ''); + $output .= "\n" unless ($line =~ /;\n*$/ or $line =~ /{\n*$/); +} + +$output =~ s/\n+/\n/g; +$output .= "}\n" if ($doPlugin && $output !~ /\}\s+$/); +# replace multiple ;var xx to ,xx if the line contains var +@lines = split(/^/,$output); +foreach $line (@lines) { + $line =~ s/;var /,/g if ($line =~ /^\s*var / && $line !~ /(turn|ment|Capture\(\)|Div'\)|1000\));var /); + print OUTJS $line; +} Index: openacs-4/packages/xowiki/www/resources/overlib/overlib.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,1491 @@ +//\///// +//\ overLIB 4.21 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2004. All rights reserved. +//\ +//\ Contributors are listed on the homepage. +//\ This file might be old, always check for the latest version at: +//\ http://www.bosrup.com/web/overlib/ +//\ +//\ Please read the license agreement (available through the link above) +//\ before using overLIB. Direct any licensing questions to erik@bosrup.com. +//\ +//\ Do not sell this as your own work or remove this copyright notice. +//\ For full details on copying or changing this script please read the +//\ license agreement at the link above. Please give credit on sites that +//\ use overLIB and submit changes of the script so other people can use +//\ them as well. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +//\///// +//\mini + +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +var olLoaded = 0;var pmStart = 10000000; var pmUpper = 10001000; var pmCount = pmStart+1; var pmt=''; var pms = new Array(); var olInfo = new Info('4.21', 1); +var FREPLACE = 0; var FBEFORE = 1; var FAFTER = 2; var FALTERNATE = 3; var FCHAIN=4; +var olHideForm=0; // parameter for hiding SELECT and ActiveX elements in IE5.5+ +var olHautoFlag = 0; // flags for over-riding VAUTO and HAUTO if corresponding +var olVautoFlag = 0; // positioning commands are used on the command line +var hookPts = new Array(), postParse = new Array(), cmdLine = new Array(), runTime = new Array(); +// for plugins +registerCommands('donothing,inarray,caparray,sticky,background,noclose,caption,left,right,center,offsetx,offsety,fgcolor,bgcolor,textcolor,capcolor,closecolor,width,border,cellpad,status,autostatus,autostatuscap,height,closetext,snapx,snapy,fixx,fixy,relx,rely,fgbackground,bgbackground,padx,pady,fullhtml,above,below,capicon,textfont,captionfont,closefont,textsize,captionsize,closesize,timeout,function,delay,hauto,vauto,closeclick,wrap,followmouse,mouseoff,closetitle,cssoff,compatmode,cssclass,fgclass,bgclass,textfontclass,captionfontclass,closefontclass'); + +//////// +// DEFAULT CONFIGURATION +// Settings you want everywhere are set here. All of this can also be +// changed on your html page or through an overLIB call. +//////// +if (typeof ol_fgcolor=='undefined') var ol_fgcolor="#CCCCFF"; +if (typeof ol_bgcolor=='undefined') var ol_bgcolor="#333399"; +if (typeof ol_textcolor=='undefined') var ol_textcolor="#000000"; +if (typeof ol_capcolor=='undefined') var ol_capcolor="#FFFFFF"; +if (typeof ol_closecolor=='undefined') var ol_closecolor="#9999FF"; +if (typeof ol_textfont=='undefined') var ol_textfont="Verdana,Arial,Helvetica"; +if (typeof ol_captionfont=='undefined') var ol_captionfont="Verdana,Arial,Helvetica"; +if (typeof ol_closefont=='undefined') var ol_closefont="Verdana,Arial,Helvetica"; +if (typeof ol_textsize=='undefined') var ol_textsize="1"; +if (typeof ol_captionsize=='undefined') var ol_captionsize="1"; +if (typeof ol_closesize=='undefined') var ol_closesize="1"; +if (typeof ol_width=='undefined') var ol_width="200"; +if (typeof ol_border=='undefined') var ol_border="1"; +if (typeof ol_cellpad=='undefined') var ol_cellpad=2; +if (typeof ol_offsetx=='undefined') var ol_offsetx=10; +if (typeof ol_offsety=='undefined') var ol_offsety=10; +if (typeof ol_text=='undefined') var ol_text="Default Text"; +if (typeof ol_cap=='undefined') var ol_cap=""; +if (typeof ol_sticky=='undefined') var ol_sticky=0; +if (typeof ol_background=='undefined') var ol_background=""; +if (typeof ol_close=='undefined') var ol_close="Close"; +if (typeof ol_hpos=='undefined') var ol_hpos=RIGHT; +if (typeof ol_status=='undefined') var ol_status=""; +if (typeof ol_autostatus=='undefined') var ol_autostatus=0; +if (typeof ol_height=='undefined') var ol_height=-1; +if (typeof ol_snapx=='undefined') var ol_snapx=0; +if (typeof ol_snapy=='undefined') var ol_snapy=0; +if (typeof ol_fixx=='undefined') var ol_fixx=-1; +if (typeof ol_fixy=='undefined') var ol_fixy=-1; +if (typeof ol_relx=='undefined') var ol_relx=null; +if (typeof ol_rely=='undefined') var ol_rely=null; +if (typeof ol_fgbackground=='undefined') var ol_fgbackground=""; +if (typeof ol_bgbackground=='undefined') var ol_bgbackground=""; +if (typeof ol_padxl=='undefined') var ol_padxl=1; +if (typeof ol_padxr=='undefined') var ol_padxr=1; +if (typeof ol_padyt=='undefined') var ol_padyt=1; +if (typeof ol_padyb=='undefined') var ol_padyb=1; +if (typeof ol_fullhtml=='undefined') var ol_fullhtml=0; +if (typeof ol_vpos=='undefined') var ol_vpos=BELOW; +if (typeof ol_aboveheight=='undefined') var ol_aboveheight=0; +if (typeof ol_capicon=='undefined') var ol_capicon=""; +if (typeof ol_frame=='undefined') var ol_frame=self; +if (typeof ol_timeout=='undefined') var ol_timeout=0; +if (typeof ol_function=='undefined') var ol_function=null; +if (typeof ol_delay=='undefined') var ol_delay=0; +if (typeof ol_hauto=='undefined') var ol_hauto=0; +if (typeof ol_vauto=='undefined') var ol_vauto=0; +if (typeof ol_closeclick=='undefined') var ol_closeclick=0; +if (typeof ol_wrap=='undefined') var ol_wrap=0; +if (typeof ol_followmouse=='undefined') var ol_followmouse=1; +if (typeof ol_mouseoff=='undefined') var ol_mouseoff=0; +if (typeof ol_closetitle=='undefined') var ol_closetitle='Close'; +if (typeof ol_compatmode=='undefined') var ol_compatmode=0; +if (typeof ol_css=='undefined') var ol_css=CSSOFF; +if (typeof ol_fgclass=='undefined') var ol_fgclass=""; +if (typeof ol_bgclass=='undefined') var ol_bgclass=""; +if (typeof ol_textfontclass=='undefined') var ol_textfontclass=""; +if (typeof ol_captionfontclass=='undefined') var ol_captionfontclass=""; +if (typeof ol_closefontclass=='undefined') var ol_closefontclass=""; + +//////// +// ARRAY CONFIGURATION +//////// + +// You can use these arrays to store popup text here instead of in the html. +if (typeof ol_texts=='undefined') var ol_texts = new Array("Text 0", "Text 1"); +if (typeof ol_caps=='undefined') var ol_caps = new Array("Caption 0", "Caption 1"); + +//////// +// END OF CONFIGURATION +// Don't change anything below this line, all configuration is above. +//////// + + + + + +//////// +// INIT +//////// +// Runtime variables init. Don't change for config! +var o3_text=""; +var o3_cap=""; +var o3_sticky=0; +var o3_background=""; +var o3_close="Close"; +var o3_hpos=RIGHT; +var o3_offsetx=2; +var o3_offsety=2; +var o3_fgcolor=""; +var o3_bgcolor=""; +var o3_textcolor=""; +var o3_capcolor=""; +var o3_closecolor=""; +var o3_width=100; +var o3_border=1; +var o3_cellpad=2; +var o3_status=""; +var o3_autostatus=0; +var o3_height=-1; +var o3_snapx=0; +var o3_snapy=0; +var o3_fixx=-1; +var o3_fixy=-1; +var o3_relx=null; +var o3_rely=null; +var o3_fgbackground=""; +var o3_bgbackground=""; +var o3_padxl=0; +var o3_padxr=0; +var o3_padyt=0; +var o3_padyb=0; +var o3_fullhtml=0; +var o3_vpos=BELOW; +var o3_aboveheight=0; +var o3_capicon=""; +var o3_textfont="Verdana,Arial,Helvetica"; +var o3_captionfont="Verdana,Arial,Helvetica"; +var o3_closefont="Verdana,Arial,Helvetica"; +var o3_textsize="1"; +var o3_captionsize="1"; +var o3_closesize="1"; +var o3_frame=self; +var o3_timeout=0; +var o3_timerid=0; +var o3_allowmove=0; +var o3_function=null; +var o3_delay=0; +var o3_delayid=0; +var o3_hauto=0; +var o3_vauto=0; +var o3_closeclick=0; +var o3_wrap=0; +var o3_followmouse=1; +var o3_mouseoff=0; +var o3_closetitle=''; +var o3_compatmode=0; +var o3_css=CSSOFF; +var o3_fgclass=""; +var o3_bgclass=""; +var o3_textfontclass=""; +var o3_captionfontclass=""; +var o3_closefontclass=""; + +// Display state variables +var o3_x = 0; +var o3_y = 0; +var o3_showingsticky = 0; +var o3_removecounter = 0; + +// Our layer +var over = null; +var fnRef, hoveringSwitch = false; +var olHideDelay; + +// Decide browser version +var isMac = (navigator.userAgent.indexOf("Mac") != -1); +var olOp = (navigator.userAgent.toLowerCase().indexOf('opera') > -1 && document.createTextNode); // Opera 7 +var olNs4 = (navigator.appName=='Netscape' && parseInt(navigator.appVersion) == 4); +var olNs6 = (document.getElementById) ? true : false; +var olKq = (olNs6 && /konqueror/i.test(navigator.userAgent)); +var olIe4 = (document.all) ? true : false; +var olIe5 = false; +var olIe55 = false; // Added additional variable to identify IE5.5+ +var docRoot = 'document.body'; + +// Resize fix for NS4.x to keep track of layer +if (olNs4) { + var oW = window.innerWidth; + var oH = window.innerHeight; + window.onresize = function() { if (oW != window.innerWidth || oH != window.innerHeight) location.reload(); } +} + +// Microsoft Stupidity Check(tm). +if (olIe4) { + var agent = navigator.userAgent; + if (/MSIE/.test(agent)) { + var versNum = parseFloat(agent.match(/MSIE[ ](\d\.\d+)\.*/i)[1]); + if (versNum >= 5){ + olIe5=true; + olIe55=(versNum>=5.5&&!olOp) ? true : false; + if (olNs6) olNs6=false; + } + } + if (olNs6) olIe4 = false; +} + +// Check for compatability mode. +if (document.compatMode && document.compatMode == 'CSS1Compat') { + docRoot= ((olIe4 && !olOp) ? 'document.documentElement' : docRoot); +} + +// Add window onload handlers to indicate when all modules have been loaded +// For Netscape 6+ and Mozilla, uses addEventListener method on the window object +// For IE it uses the attachEvent method of the window object and for Netscape 4.x +// it sets the window.onload handler to the OLonload_handler function for Bubbling +if(window.addEventListener) window.addEventListener("load",OLonLoad_handler,false); +else if (window.attachEvent) window.attachEvent("onload",OLonLoad_handler); + +var capExtent; + +//////// +// PUBLIC FUNCTIONS +//////// + +// overlib(arg0,...,argN) +// Loads parameters into global runtime variables. +function overlib() { + if (!olLoaded || isExclusive(overlib.arguments)) return true; + if (olCheckMouseCapture) olMouseCapture(); + if (over) { + over = (typeof over.id != 'string') ? o3_frame.document.all['overDiv'] : over; + cClick(); + } + + // Load defaults to runtime. + olHideDelay=0; + o3_text=ol_text; + o3_cap=ol_cap; + o3_sticky=ol_sticky; + o3_background=ol_background; + o3_close=ol_close; + o3_hpos=ol_hpos; + o3_offsetx=ol_offsetx; + o3_offsety=ol_offsety; + o3_fgcolor=ol_fgcolor; + o3_bgcolor=ol_bgcolor; + o3_textcolor=ol_textcolor; + o3_capcolor=ol_capcolor; + o3_closecolor=ol_closecolor; + o3_width=ol_width; + o3_border=ol_border; + o3_cellpad=ol_cellpad; + o3_status=ol_status; + o3_autostatus=ol_autostatus; + o3_height=ol_height; + o3_snapx=ol_snapx; + o3_snapy=ol_snapy; + o3_fixx=ol_fixx; + o3_fixy=ol_fixy; + o3_relx=ol_relx; + o3_rely=ol_rely; + o3_fgbackground=ol_fgbackground; + o3_bgbackground=ol_bgbackground; + o3_padxl=ol_padxl; + o3_padxr=ol_padxr; + o3_padyt=ol_padyt; + o3_padyb=ol_padyb; + o3_fullhtml=ol_fullhtml; + o3_vpos=ol_vpos; + o3_aboveheight=ol_aboveheight; + o3_capicon=ol_capicon; + o3_textfont=ol_textfont; + o3_captionfont=ol_captionfont; + o3_closefont=ol_closefont; + o3_textsize=ol_textsize; + o3_captionsize=ol_captionsize; + o3_closesize=ol_closesize; + o3_timeout=ol_timeout; + o3_function=ol_function; + o3_delay=ol_delay; + o3_hauto=ol_hauto; + o3_vauto=ol_vauto; + o3_closeclick=ol_closeclick; + o3_wrap=ol_wrap; + o3_followmouse=ol_followmouse; + o3_mouseoff=ol_mouseoff; + o3_closetitle=ol_closetitle; + o3_css=ol_css; + o3_compatmode=ol_compatmode; + o3_fgclass=ol_fgclass; + o3_bgclass=ol_bgclass; + o3_textfontclass=ol_textfontclass; + o3_captionfontclass=ol_captionfontclass; + o3_closefontclass=ol_closefontclass; + + setRunTimeVariables(); + + fnRef = ''; + + // Special for frame support, over must be reset... + o3_frame = ol_frame; + + if(!(over=createDivContainer())) return false; + + parseTokens('o3_', overlib.arguments); + if (!postParseChecks()) return false; + + if (o3_delay == 0) { + return runHook("olMain", FREPLACE); + } else { + o3_delayid = setTimeout("runHook('olMain', FREPLACE)", o3_delay); + return false; + } +} + +// Clears popups if appropriate +function nd(time) { + if (olLoaded && !isExclusive()) { + hideDelay(time); // delay popup close if time specified + + if (o3_removecounter >= 1) { o3_showingsticky = 0 }; + + if (o3_showingsticky == 0) { + o3_allowmove = 0; + if (over != null && o3_timerid == 0) runHook("hideObject", FREPLACE, over); + } else { + o3_removecounter++; + } + } + + return true; +} + +// The Close onMouseOver function for stickies +function cClick() { + if (olLoaded) { + runHook("hideObject", FREPLACE, over); + o3_showingsticky = 0; + } + return false; +} + +// Method for setting page specific defaults. +function overlib_pagedefaults() { + parseTokens('ol_', overlib_pagedefaults.arguments); +} + + +//////// +// OVERLIB MAIN FUNCTION +//////// + +// This function decides what it is we want to display and how we want it done. +function olMain() { + var layerhtml, styleType; + runHook("olMain", FBEFORE); + + if (o3_background!="" || o3_fullhtml) { + // Use background instead of box. + layerhtml = runHook('ol_content_background', FALTERNATE, o3_css, o3_text, o3_background, o3_fullhtml); + } else { + // They want a popup box. + styleType = (pms[o3_css-1-pmStart] == "cssoff" || pms[o3_css-1-pmStart] == "cssclass"); + + // Prepare popup background + if (o3_fgbackground != "") o3_fgbackground = "background=\""+o3_fgbackground+"\""; + if (o3_bgbackground != "") o3_bgbackground = (styleType ? "background=\""+o3_bgbackground+"\"" : o3_bgbackground); + + // Prepare popup colors + if (o3_fgcolor != "") o3_fgcolor = (styleType ? "bgcolor=\""+o3_fgcolor+"\"" : o3_fgcolor); + if (o3_bgcolor != "") o3_bgcolor = (styleType ? "bgcolor=\""+o3_bgcolor+"\"" : o3_bgcolor); + + // Prepare popup height + if (o3_height > 0) o3_height = (styleType ? "height=\""+o3_height+"\"" : o3_height); + else o3_height = ""; + + // Decide which kinda box. + if (o3_cap=="") { + // Plain + layerhtml = runHook('ol_content_simple', FALTERNATE, o3_css, o3_text); + } else { + // With caption + if (o3_sticky) { + // Show close text + layerhtml = runHook('ol_content_caption', FALTERNATE, o3_css, o3_text, o3_cap, o3_close); + } else { + // No close text + layerhtml = runHook('ol_content_caption', FALTERNATE, o3_css, o3_text, o3_cap, ""); + } + } + } + + // We want it to stick! + if (o3_sticky) { + if (o3_timerid > 0) { + clearTimeout(o3_timerid); + o3_timerid = 0; + } + o3_showingsticky = 1; + o3_removecounter = 0; + } + + // Created a separate routine to generate the popup to make it easier + // to implement a plugin capability + if (!runHook("createPopup", FREPLACE, layerhtml)) return false; + + // Prepare status bar + if (o3_autostatus > 0) { + o3_status = o3_text; + if (o3_autostatus > 1) o3_status = o3_cap; + } + + // When placing the layer the first time, even stickies may be moved. + o3_allowmove = 0; + + // Initiate a timer for timeout + if (o3_timeout > 0) { + if (o3_timerid > 0) clearTimeout(o3_timerid); + o3_timerid = setTimeout("cClick()", o3_timeout); + } + + // Show layer + runHook("disp", FREPLACE, o3_status); + runHook("olMain", FAFTER); + + return (olOp && event && event.type == 'mouseover' && !o3_status) ? '' : (o3_status != ''); +} + +//////// +// LAYER GENERATION FUNCTIONS +//////// +// These functions just handle popup content with tags that should adhere to the W3C standards specification. + +// Makes simple table without caption +function ol_content_simple(text) { + var cpIsMultiple = /,/.test(o3_cellpad); + var txt = '
      ' : ((!olNs4&&cpIsMultiple) ? ' style="'+setCellPadStr(o3_cellpad)+'">' : '>'))+(o3_textfontclass ? '' : wrapStr(0,o3_textsize,'text'))+text+(o3_textfontclass ? '' : wrapStr(1,o3_textsize))+'
      '; + + set_background(""); + return txt; +} + +// Makes table with caption and optional close link +function ol_content_caption(text,title,close) { + var nameId, txt, cpIsMultiple = /,/.test(o3_cellpad); + var closing, closeevent; + + closing = ""; + closeevent = "onmouseover"; + if (o3_closeclick == 1) closeevent = (o3_closetitle ? "title='" + o3_closetitle +"'" : "") + " onclick"; + if (o3_capicon != "") { + nameId = ' hspace = \"5\"'+' align = \"middle\" alt = \"\"'; + if (typeof o3_dragimg != 'undefined' && o3_dragimg) nameId =' hspace=\"5\"'+' name=\"'+o3_dragimg+'\" id=\"'+o3_dragimg+'\" align=\"middle\" alt=\"Drag Enabled\" title=\"Drag Enabled\"'; + o3_capicon = ''; + } + + if (close != "") + closing = ''+(o3_closefontclass ? '' : wrapStr(0,o3_closesize,'close'))+close+(o3_closefontclass ? '' : wrapStr(1,o3_closesize,'close'))+''; + txt = '
      ' : '>')+(o3_captionfontclass ? '' : ''+wrapStr(0,o3_captionsize,'caption'))+o3_capicon+title+(o3_captionfontclass ? '' : wrapStr(1,o3_captionsize)+'')+''+closing+'
      ' :((!olNs4&&cpIsMultiple) ? ' style="'+setCellPadStr(o3_cellpad)+'">' : '>'))+(o3_textfontclass ? '' : wrapStr(0,o3_textsize,'text'))+text+(o3_textfontclass ? '' : wrapStr(1,o3_textsize)) + '
      '; + + set_background(""); + return txt; +} + +// Sets the background picture,padding and lots more. :) +function ol_content_background(text,picture,hasfullhtml) { + if (hasfullhtml) { + txt=text; + } else { + txt='
      '+(o3_textfontclass ? '' : wrapStr(0,o3_textsize,'text'))+text+(o3_textfontclass ? '' : wrapStr(1,o3_textsize))+'
      '; + } + + set_background(picture); + return txt; +} + +// Loads a picture into the div. +function set_background(pic) { + if (pic == "") { + if (olNs4) { + over.background.src = null; + } else if (over.style) { + over.style.backgroundImage = "none"; + } + } else { + if (olNs4) { + over.background.src = pic; + } else if (over.style) { + over.style.width=o3_width + 'px'; + over.style.backgroundImage = "url("+pic+")"; + } + } +} + +//////// +// HANDLING FUNCTIONS +//////// +var olShowId=-1; + +// Displays the popup +function disp(statustext) { + runHook("disp", FBEFORE); + + if (o3_allowmove == 0) { + runHook("placeLayer", FREPLACE); + (olNs6&&olShowId<0) ? olShowId=setTimeout("runHook('showObject', FREPLACE, over)", 1) : runHook("showObject", FREPLACE, over); + o3_allowmove = (o3_sticky || o3_followmouse==0) ? 0 : 1; + } + + runHook("disp", FAFTER); + + if (statustext != "") self.status = statustext; +} + +// Creates the actual popup structure +function createPopup(lyrContent){ + runHook("createPopup", FBEFORE); + + if (o3_wrap) { + var wd,ww,theObj = (olNs4 ? over : over.style); + theObj.top = theObj.left = ((olIe4&&!olOp) ? 0 : -10000) + (!olNs4 ? 'px' : 0); + layerWrite(lyrContent); + wd = (olNs4 ? over.clip.width : over.offsetWidth); + if (wd > (ww=windowWidth())) { + lyrContent=lyrContent.replace(/\ /g, ' '); + o3_width=ww; + o3_wrap=0; + } + } + + layerWrite(lyrContent); + + // Have to set o3_width for placeLayer() routine if o3_wrap is turned on + if (o3_wrap) o3_width=(olNs4 ? over.clip.width : over.offsetWidth); + + runHook("createPopup", FAFTER, lyrContent); + + return true; +} + +// Decides where we want the popup. +function placeLayer() { + var placeX, placeY, widthFix = 0; + + // HORIZONTAL PLACEMENT, re-arranged to work in Safari + if (o3_frame.innerWidth) widthFix=18; + iwidth = windowWidth(); + + // Horizontal scroll offset + winoffset=(olIe4) ? eval('o3_frame.'+docRoot+'.scrollLeft') : o3_frame.pageXOffset; + + placeX = runHook('horizontalPlacement',FCHAIN,iwidth,winoffset,widthFix); + + // VERTICAL PLACEMENT, re-arranged to work in Safari + if (o3_frame.innerHeight) { + iheight=o3_frame.innerHeight; + } else if (eval('o3_frame.'+docRoot)&&eval("typeof o3_frame."+docRoot+".clientHeight=='number'")&&eval('o3_frame.'+docRoot+'.clientHeight')) { + iheight=eval('o3_frame.'+docRoot+'.clientHeight'); + } + + // Vertical scroll offset + scrolloffset=(olIe4) ? eval('o3_frame.'+docRoot+'.scrollTop') : o3_frame.pageYOffset; + placeY = runHook('verticalPlacement',FCHAIN,iheight,scrolloffset); + + // Actually move the object. + repositionTo(over, placeX, placeY); +} + +// Moves the layer +function olMouseMove(e) { + var e = (e) ? e : event; + + if (e.pageX) { + o3_x = e.pageX; + o3_y = e.pageY; + } else if (e.clientX) { + o3_x = eval('e.clientX+o3_frame.'+docRoot+'.scrollLeft'); + o3_y = eval('e.clientY+o3_frame.'+docRoot+'.scrollTop'); + } + + if (o3_allowmove == 1) runHook("placeLayer", FREPLACE); + + // MouseOut handler + if (hoveringSwitch && !olNs4 && runHook("cursorOff", FREPLACE)) { + (olHideDelay ? hideDelay(olHideDelay) : cClick()); + hoveringSwitch = !hoveringSwitch; + } +} + +// Fake function for 3.0 users. +function no_overlib() { return ver3fix; } + +// Capture the mouse and chain other scripts. +function olMouseCapture() { + capExtent = document; + var fN, str = '', l, k, f, wMv, sS, mseHandler = olMouseMove; + var re = /function[ ]*(\w*)\(/; + + wMv = (!olIe4 && window.onmousemove); + if (document.onmousemove || wMv) { + if (wMv) capExtent = window; + f = capExtent.onmousemove.toString(); + fN = f.match(re); + if (fN == null) { + str = f+'(e); '; + } else if (fN[1] == 'anonymous' || fN[1] == 'olMouseMove' || (wMv && fN[1] == 'onmousemove')) { + if (!olOp && wMv) { + l = f.indexOf('{')+1; + k = f.lastIndexOf('}'); + sS = f.substring(l,k); + if ((l = sS.indexOf('(')) != -1) { + sS = sS.substring(0,l).replace(/^\s+/,'').replace(/\s+$/,''); + if (eval("typeof " + sS + " == 'undefined'")) window.onmousemove = null; + else str = sS + '(e);'; + } + } + if (!str) { + olCheckMouseCapture = false; + return; + } + } else { + if (fN[1]) str = fN[1]+'(e); '; + else { + l = f.indexOf('{')+1; + k = f.lastIndexOf('}'); + str = f.substring(l,k) + '\n'; + } + } + str += 'olMouseMove(e); '; + mseHandler = new Function('e', str); + } + + capExtent.onmousemove = mseHandler; + if (olNs4) capExtent.captureEvents(Event.MOUSEMOVE); +} + +//////// +// PARSING FUNCTIONS +//////// + +// Does the actual command parsing. +function parseTokens(pf, ar) { + // What the next argument is expected to be. + var v, i, mode=-1, par = (pf != 'ol_'); + var fnMark = (par && !ar.length ? 1 : 0); + + for (i = 0; i < ar.length; i++) { + if (mode < 0) { + // Arg is maintext,unless its a number between pmStart and pmUpper + // then its a command. + if (typeof ar[i] == 'number' && ar[i] > pmStart && ar[i] < pmUpper) { + fnMark = (par ? 1 : 0); + i--; // backup one so that the next block can parse it + } else { + switch(pf) { + case 'ol_': + ol_text = ar[i].toString(); + break; + default: + o3_text=ar[i].toString(); + } + } + mode = 0; + } else { + // Note: NS4 doesn't like switch cases with vars. + if (ar[i] >= pmCount || ar[i]==DONOTHING) { continue; } + if (ar[i]==INARRAY) { fnMark = 0; eval(pf+'text=ol_texts['+ar[++i]+'].toString()'); continue; } + if (ar[i]==CAPARRAY) { eval(pf+'cap=ol_caps['+ar[++i]+'].toString()'); continue; } + if (ar[i]==STICKY) { if (pf!='ol_') eval(pf+'sticky=1'); continue; } + if (ar[i]==BACKGROUND) { eval(pf+'background="'+ar[++i]+'"'); continue; } + if (ar[i]==NOCLOSE) { if (pf!='ol_') opt_NOCLOSE(); continue; } + if (ar[i]==CAPTION) { eval(pf+"cap='"+escSglQuote(ar[++i])+"'"); continue; } + if (ar[i]==CENTER || ar[i]==LEFT || ar[i]==RIGHT) { eval(pf+'hpos='+ar[i]); if(pf!='ol_') olHautoFlag=1; continue; } + if (ar[i]==OFFSETX) { eval(pf+'offsetx='+ar[++i]); continue; } + if (ar[i]==OFFSETY) { eval(pf+'offsety='+ar[++i]); continue; } + if (ar[i]==FGCOLOR) { eval(pf+'fgcolor="'+ar[++i]+'"'); continue; } + if (ar[i]==BGCOLOR) { eval(pf+'bgcolor="'+ar[++i]+'"'); continue; } + if (ar[i]==TEXTCOLOR) { eval(pf+'textcolor="'+ar[++i]+'"'); continue; } + if (ar[i]==CAPCOLOR) { eval(pf+'capcolor="'+ar[++i]+'"'); continue; } + if (ar[i]==CLOSECOLOR) { eval(pf+'closecolor="'+ar[++i]+'"'); continue; } + if (ar[i]==WIDTH) { eval(pf+'width='+ar[++i]); continue; } + if (ar[i]==BORDER) { eval(pf+'border='+ar[++i]); continue; } + if (ar[i]==CELLPAD) { i=opt_MULTIPLEARGS(++i,ar,(pf+'cellpad')); continue; } + if (ar[i]==STATUS) { eval(pf+"status='"+escSglQuote(ar[++i])+"'"); continue; } + if (ar[i]==AUTOSTATUS) { eval(pf +'autostatus=('+pf+'autostatus == 1) ? 0 : 1'); continue; } + if (ar[i]==AUTOSTATUSCAP) { eval(pf +'autostatus=('+pf+'autostatus == 2) ? 0 : 2'); continue; } + if (ar[i]==HEIGHT) { eval(pf+'height='+pf+'aboveheight='+ar[++i]); continue; } // Same param again. + if (ar[i]==CLOSETEXT) { eval(pf+"close='"+escSglQuote(ar[++i])+"'"); continue; } + if (ar[i]==SNAPX) { eval(pf+'snapx='+ar[++i]); continue; } + if (ar[i]==SNAPY) { eval(pf+'snapy='+ar[++i]); continue; } + if (ar[i]==FIXX) { eval(pf+'fixx='+ar[++i]); continue; } + if (ar[i]==FIXY) { eval(pf+'fixy='+ar[++i]); continue; } + if (ar[i]==RELX) { eval(pf+'relx='+ar[++i]); continue; } + if (ar[i]==RELY) { eval(pf+'rely='+ar[++i]); continue; } + if (ar[i]==FGBACKGROUND) { eval(pf+'fgbackground="'+ar[++i]+'"'); continue; } + if (ar[i]==BGBACKGROUND) { eval(pf+'bgbackground="'+ar[++i]+'"'); continue; } + if (ar[i]==PADX) { eval(pf+'padxl='+ar[++i]); eval(pf+'padxr='+ar[++i]); continue; } + if (ar[i]==PADY) { eval(pf+'padyt='+ar[++i]); eval(pf+'padyb='+ar[++i]); continue; } + if (ar[i]==FULLHTML) { if (pf!='ol_') eval(pf+'fullhtml=1'); continue; } + if (ar[i]==BELOW || ar[i]==ABOVE) { eval(pf+'vpos='+ar[i]); if (pf!='ol_') olVautoFlag=1; continue; } + if (ar[i]==CAPICON) { eval(pf+'capicon="'+ar[++i]+'"'); continue; } + if (ar[i]==TEXTFONT) { eval(pf+"textfont='"+escSglQuote(ar[++i])+"'"); continue; } + if (ar[i]==CAPTIONFONT) { eval(pf+"captionfont='"+escSglQuote(ar[++i])+"'"); continue; } + if (ar[i]==CLOSEFONT) { eval(pf+"closefont='"+escSglQuote(ar[++i])+"'"); continue; } + if (ar[i]==TEXTSIZE) { eval(pf+'textsize="'+ar[++i]+'"'); continue; } + if (ar[i]==CAPTIONSIZE) { eval(pf+'captionsize="'+ar[++i]+'"'); continue; } + if (ar[i]==CLOSESIZE) { eval(pf+'closesize="'+ar[++i]+'"'); continue; } + if (ar[i]==TIMEOUT) { eval(pf+'timeout='+ar[++i]); continue; } + if (ar[i]==FUNCTION) { if (pf=='ol_') { if (typeof ar[i+1]!='number') { v=ar[++i]; ol_function=(typeof v=='function' ? v : null); }} else {fnMark = 0; v = null; if (typeof ar[i+1]!='number') v = ar[++i]; opt_FUNCTION(v); } continue; } + if (ar[i]==DELAY) { eval(pf+'delay='+ar[++i]); continue; } + if (ar[i]==HAUTO) { eval(pf+'hauto=('+pf+'hauto == 0) ? 1 : 0'); continue; } + if (ar[i]==VAUTO) { eval(pf+'vauto=('+pf+'vauto == 0) ? 1 : 0'); continue; } + if (ar[i]==CLOSECLICK) { eval(pf +'closeclick=('+pf+'closeclick == 0) ? 1 : 0'); continue; } + if (ar[i]==WRAP) { eval(pf +'wrap=('+pf+'wrap == 0) ? 1 : 0'); continue; } + if (ar[i]==FOLLOWMOUSE) { eval(pf +'followmouse=('+pf+'followmouse == 1) ? 0 : 1'); continue; } + if (ar[i]==MOUSEOFF) { eval(pf +'mouseoff=('+pf+'mouseoff==0) ? 1 : 0'); v=ar[i+1]; if (pf != 'ol_' && eval(pf+'mouseoff') && typeof v == 'number' && (v < pmStart || v > pmUpper)) olHideDelay=ar[++i]; continue; } + if (ar[i]==CLOSETITLE) { eval(pf+"closetitle='"+escSglQuote(ar[++i])+"'"); continue; } + if (ar[i]==CSSOFF||ar[i]==CSSCLASS) { eval(pf+'css='+ar[i]); continue; } + if (ar[i]==COMPATMODE) { eval(pf+'compatmode=('+pf+'compatmode==0) ? 1 : 0'); continue; } + if (ar[i]==FGCLASS) { eval(pf+'fgclass="'+ar[++i]+'"'); continue; } + if (ar[i]==BGCLASS) { eval(pf+'bgclass="'+ar[++i]+'"'); continue; } + if (ar[i]==TEXTFONTCLASS) { eval(pf+'textfontclass="'+ar[++i]+'"'); continue; } + if (ar[i]==CAPTIONFONTCLASS) { eval(pf+'captionfontclass="'+ar[++i]+'"'); continue; } + if (ar[i]==CLOSEFONTCLASS) { eval(pf+'closefontclass="'+ar[++i]+'"'); continue; } + i = parseCmdLine(pf, i, ar); + } + } + + if (fnMark && o3_function) o3_text = o3_function(); + + if ((pf == 'o3_') && o3_wrap) { + o3_width = 0; + + var tReg=/<.*\n*>/ig; + if (!tReg.test(o3_text)) o3_text = o3_text.replace(/[ ]+/g, ' '); + if (!tReg.test(o3_cap))o3_cap = o3_cap.replace(/[ ]+/g, ' '); + } + if ((pf == 'o3_') && o3_sticky) { + if (!o3_close && (o3_frame != ol_frame)) o3_close = ol_close; + if (o3_mouseoff && (o3_frame == ol_frame)) opt_NOCLOSE(' '); + } +} + + +//////// +// LAYER FUNCTIONS +//////// + +// Writes to a layer +function layerWrite(txt) { + txt += "\n"; + if (olNs4) { + var lyr = o3_frame.document.layers['overDiv'].document + lyr.write(txt) + lyr.close() + } else if (typeof over.innerHTML != 'undefined') { + if (olIe5 && isMac) over.innerHTML = ''; + over.innerHTML = txt; + } else { + range = o3_frame.document.createRange(); + range.setStartAfter(over); + domfrag = range.createContextualFragment(txt); + + while (over.hasChildNodes()) { + over.removeChild(over.lastChild); + } + + over.appendChild(domfrag); + } +} + +// Make an object visible +function showObject(obj) { + runHook("showObject", FBEFORE); + + var theObj=(olNs4 ? obj : obj.style); + theObj.visibility = 'visible'; + + runHook("showObject", FAFTER); +} + +// Hides an object +function hideObject(obj) { + runHook("hideObject", FBEFORE); + + var theObj=(olNs4 ? obj : obj.style); + if (olNs6 && olShowId>0) { clearTimeout(olShowId); olShowId=0; } + theObj.visibility = 'hidden'; + theObj.top = theObj.left = ((olIe4&&!olOp) ? 0 : -10000) + (!olNs4 ? 'px' : 0); + + if (o3_timerid > 0) clearTimeout(o3_timerid); + if (o3_delayid > 0) clearTimeout(o3_delayid); + + o3_timerid = 0; + o3_delayid = 0; + self.status = ""; + + if (obj.onmouseout||obj.onmouseover) { + if (olNs4) obj.releaseEvents(Event.MOUSEOUT || Event.MOUSEOVER); + obj.onmouseout = obj.onmouseover = null; + } + + runHook("hideObject", FAFTER); +} + +// Move a layer +function repositionTo(obj, xL, yL) { + var theObj=(olNs4 ? obj : obj.style); + theObj.left = xL + (!olNs4 ? 'px' : 0); + theObj.top = yL + (!olNs4 ? 'px' : 0); +} + +// Check position of cursor relative to overDiv DIVision; mouseOut function +function cursorOff() { + var left = parseInt(over.style.left); + var top = parseInt(over.style.top); + var right = left + (over.offsetWidth >= parseInt(o3_width) ? over.offsetWidth : parseInt(o3_width)); + var bottom = top + (over.offsetHeight >= o3_aboveheight ? over.offsetHeight : o3_aboveheight); + + if (o3_x < left || o3_x > right || o3_y < top || o3_y > bottom) return true; + + return false; +} + + +//////// +// COMMAND FUNCTIONS +//////// + +// Calls callme or the default function. +function opt_FUNCTION(callme) { + o3_text = (callme ? (typeof callme=='string' ? (/.+\(.*\)/.test(callme) ? eval(callme) : callme) : callme()) : (o3_function ? o3_function() : 'No Function')); + + return 0; +} + +// Handle hovering +function opt_NOCLOSE(unused) { + if (!unused) o3_close = ""; + + if (olNs4) { + over.captureEvents(Event.MOUSEOUT || Event.MOUSEOVER); + over.onmouseover = function () { if (o3_timerid > 0) { clearTimeout(o3_timerid); o3_timerid = 0; } } + over.onmouseout = function (e) { if (olHideDelay) hideDelay(olHideDelay); else cClick(e); } + } else { + over.onmouseover = function () {hoveringSwitch = true; if (o3_timerid > 0) { clearTimeout(o3_timerid); o3_timerid =0; } } + } + + return 0; +} + +// Function to scan command line arguments for multiples +function opt_MULTIPLEARGS(i, args, parameter) { + var k=i, re, pV, str=''; + + for(k=i; kpmStart) break; + str += args[k] + ','; + } + if (str) str = str.substring(0,--str.length); + + k--; // reduce by one so the for loop this is in works correctly + pV=(olNs4 && /cellpad/i.test(parameter)) ? str.split(',')[0] : str; + eval(parameter + '="' + pV + '"'); + + return k; +} + +// Remove   in texts when done. +function nbspCleanup() { + if (o3_wrap) { + o3_text = o3_text.replace(/\ /g, ' '); + o3_cap = o3_cap.replace(/\ /g, ' '); + } +} + +// Escape embedded single quotes in text strings +function escSglQuote(str) { + return str.toString().replace(/'/g,"\\'"); +} + +// Onload handler for window onload event +function OLonLoad_handler(e) { + var re = /\w+\(.*\)[;\s]+/g, olre = /overlib\(|nd\(|cClick\(/, fn, l, i; + + if(!olLoaded) olLoaded=1; + + // Remove it for Gecko based browsers + if(window.removeEventListener && e.eventPhase == 3) window.removeEventListener("load",OLonLoad_handler,false); + else if(window.detachEvent) { // and for IE and Opera 4.x but execute calls to overlib, nd, or cClick() + window.detachEvent("onload",OLonLoad_handler); + var fN = document.body.getAttribute('onload'); + if (fN) { + fN=fN.toString().match(re); + if (fN && fN.length) { + for (i=0; i' : '') : ''; + else { + fontStr='o3_'+whichString+'font'; + fontColor='o3_'+((whichString=='caption')? 'cap' : whichString)+'color'; + return (hasDims&&!olNs4) ? (isClose ? '' : '
      ') : ''; + } +} + +// Quotes Multi word font names; needed for CSS Standards adherence in font-family +function quoteMultiNameFonts(theFont) { + var v, pM=theFont.split(','); + for (var i=0; i 0) clearTimeout(o3_timerid); + + o3_timerid=setTimeout("cClick()",(o3_timeout=time)); + } +} + +// Was originally in the placeLayer() routine; separated out for future ease +function horizontalPlacement(browserWidth, horizontalScrollAmount, widthFix) { + var placeX, iwidth=browserWidth, winoffset=horizontalScrollAmount; + var parsedWidth = parseInt(o3_width); + + if (o3_fixx > -1 || o3_relx != null) { + // Fixed position + placeX=(o3_relx != null ? ( o3_relx < 0 ? winoffset +o3_relx+ iwidth - parsedWidth - widthFix : winoffset+o3_relx) : o3_fixx); + } else { + // If HAUTO, decide what to use. + if (o3_hauto == 1) { + if ((o3_x - winoffset) > (iwidth / 2)) { + o3_hpos = LEFT; + } else { + o3_hpos = RIGHT; + } + } + + // From mouse + if (o3_hpos == CENTER) { // Center + placeX = o3_x+o3_offsetx-(parsedWidth/2); + + if (placeX < winoffset) placeX = winoffset; + } + + if (o3_hpos == RIGHT) { // Right + placeX = o3_x+o3_offsetx; + + if ((placeX+parsedWidth) > (winoffset+iwidth - widthFix)) { + placeX = iwidth+winoffset - parsedWidth - widthFix; + if (placeX < 0) placeX = 0; + } + } + if (o3_hpos == LEFT) { // Left + placeX = o3_x-o3_offsetx-parsedWidth; + if (placeX < winoffset) placeX = winoffset; + } + + // Snapping! + if (o3_snapx > 1) { + var snapping = placeX % o3_snapx; + + if (o3_hpos == LEFT) { + placeX = placeX - (o3_snapx+snapping); + } else { + // CENTER and RIGHT + placeX = placeX+(o3_snapx - snapping); + } + + if (placeX < winoffset) placeX = winoffset; + } + } + + return placeX; +} + +// was originally in the placeLayer() routine; separated out for future ease +function verticalPlacement(browserHeight,verticalScrollAmount) { + var placeY, iheight=browserHeight, scrolloffset=verticalScrollAmount; + var parsedHeight=(o3_aboveheight ? parseInt(o3_aboveheight) : (olNs4 ? over.clip.height : over.offsetHeight)); + + if (o3_fixy > -1 || o3_rely != null) { + // Fixed position + placeY=(o3_rely != null ? (o3_rely < 0 ? scrolloffset+o3_rely+iheight - parsedHeight : scrolloffset+o3_rely) : o3_fixy); + } else { + // If VAUTO, decide what to use. + if (o3_vauto == 1) { + if ((o3_y - scrolloffset) > (iheight / 2) && o3_vpos == BELOW && (o3_y + parsedHeight + o3_offsety - (scrolloffset + iheight) > 0)) { + o3_vpos = ABOVE; + } else if (o3_vpos == ABOVE && (o3_y - (parsedHeight + o3_offsety) - scrolloffset < 0)) { + o3_vpos = BELOW; + } + } + + // From mouse + if (o3_vpos == ABOVE) { + if (o3_aboveheight == 0) o3_aboveheight = parsedHeight; + + placeY = o3_y - (o3_aboveheight+o3_offsety); + if (placeY < scrolloffset) placeY = scrolloffset; + } else { + // BELOW + placeY = o3_y+o3_offsety; + } + + // Snapping! + if (o3_snapy > 1) { + var snapping = placeY % o3_snapy; + + if (o3_aboveheight > 0 && o3_vpos == ABOVE) { + placeY = placeY - (o3_snapy+snapping); + } else { + placeY = placeY+(o3_snapy - snapping); + } + + if (placeY < scrolloffset) placeY = scrolloffset; + } + } + + return placeY; +} + +// checks positioning flags +function checkPositionFlags() { + if (olHautoFlag) olHautoFlag = o3_hauto=0; + if (olVautoFlag) olVautoFlag = o3_vauto=0; + return true; +} + +// get Browser window width +function windowWidth() { + var w; + if (o3_frame.innerWidth) w=o3_frame.innerWidth; + else if (eval('o3_frame.'+docRoot)&&eval("typeof o3_frame."+docRoot+".clientWidth=='number'")&&eval('o3_frame.'+docRoot+'.clientWidth')) + w=eval('o3_frame.'+docRoot+'.clientWidth'); + return w; +} + +// create the div container for popup content if it doesn't exist +function createDivContainer(id,frm,zValue) { + id = (id || 'overDiv'), frm = (frm || o3_frame), zValue = (zValue || 1000); + var objRef, divContainer = layerReference(id); + + if (divContainer == null) { + if (olNs4) { + divContainer = frm.document.layers[id] = new Layer(window.innerWidth, frm); + objRef = divContainer; + } else { + var body = (olIe4 ? frm.document.all.tags('BODY')[0] : frm.document.getElementsByTagName("BODY")[0]); + if (olIe4&&!document.getElementById) { + body.insertAdjacentHTML("beforeEnd",'
      '); + divContainer=layerReference(id); + } else { + divContainer = frm.document.createElement("DIV"); + divContainer.id = id; + body.appendChild(divContainer); + } + objRef = divContainer.style; + } + + objRef.position = 'absolute'; + objRef.visibility = 'hidden'; + objRef.zIndex = zValue; + if (olIe4&&!olOp) objRef.left = objRef.top = '0px'; + else objRef.left = objRef.top = -10000 + (!olNs4 ? 'px' : 0); + } + + return divContainer; +} + +// get reference to a layer with ID=id +function layerReference(id) { + return (olNs4 ? o3_frame.document.layers[id] : (document.all ? o3_frame.document.all[id] : o3_frame.document.getElementById(id))); +} +//////// +// UTILITY FUNCTIONS +//////// + +// Checks if something is a function. +function isFunction(fnRef) { + var rtn = true; + + if (typeof fnRef == 'object') { + for (var i = 0; i < fnRef.length; i++) { + if (typeof fnRef[i]=='function') continue; + rtn = false; + break; + } + } else if (typeof fnRef != 'function') { + rtn = false; + } + + return rtn; +} + +// Converts an array into an argument string for use in eval. +function argToString(array, strtInd, argName) { + var jS = strtInd, aS = '', ar = array; + argName=(argName ? argName : 'ar'); + + if (ar.length > jS) { + for (var k = jS; k < ar.length; k++) aS += argName+'['+k+'], '; + aS = aS.substring(0, aS.length-2); + } + + return aS; +} + +// Places a hook in the correct position in a hook point. +function reOrder(hookPt, fnRef, order) { + var newPt = new Array(), match, i, j; + + if (!order || typeof order == 'undefined' || typeof order == 'number') return hookPt; + + if (typeof order=='function') { + if (typeof fnRef=='object') { + newPt = newPt.concat(fnRef); + } else { + newPt[newPt.length++]=fnRef; + } + + for (i = 0; i < hookPt.length; i++) { + match = false; + if (typeof fnRef == 'function' && hookPt[i] == fnRef) { + continue; + } else { + for(j = 0; j < fnRef.length; j++) if (hookPt[i] == fnRef[j]) { + match = true; + break; + } + } + if (!match) newPt[newPt.length++] = hookPt[i]; + } + + newPt[newPt.length++] = order; + + } else if (typeof order == 'object') { + if (typeof fnRef == 'object') { + newPt = newPt.concat(fnRef); + } else { + newPt[newPt.length++] = fnRef; + } + + for (j = 0; j < hookPt.length; j++) { + match = false; + if (typeof fnRef == 'function' && hookPt[j] == fnRef) { + continue; + } else { + for (i = 0; i < fnRef.length; i++) if (hookPt[j] == fnRef[i]) { + match = true; + break; + } + } + if (!match) newPt[newPt.length++]=hookPt[j]; + } + + for (i = 0; i < newPt.length; i++) hookPt[i] = newPt[i]; + newPt.length = 0; + + for (j = 0; j < hookPt.length; j++) { + match = false; + for (i = 0; i < order.length; i++) { + if (hookPt[j] == order[i]) { + match = true; + break; + } + } + if (!match) newPt[newPt.length++] = hookPt[j]; + } + newPt = newPt.concat(order); + } + + hookPt = newPt; + + return hookPt; +} + +//////// +// PLUGIN ACTIVATION FUNCTIONS +//////// + +// Runs plugin functions to set runtime variables. +function setRunTimeVariables(){ + if (typeof runTime != 'undefined' && runTime.length) { + for (var k = 0; k < runTime.length; k++) { + runTime[k](); + } + } +} + +// Runs plugin functions to parse commands. +function parseCmdLine(pf, i, args) { + if (typeof cmdLine != 'undefined' && cmdLine.length) { + for (var k = 0; k < cmdLine.length; k++) { + var j = cmdLine[k](pf, i, args); + if (j >- 1) { + i = j; + break; + } + } + } + + return i; +} + +// Runs plugin functions to do things after parse. +function postParseChecks(pf,args){ + if (typeof postParse != 'undefined' && postParse.length) { + for (var k = 0; k < postParse.length; k++) { + if (postParse[k](pf,args)) continue; + return false; // end now since have an error + } + } + return true; +} + + +//////// +// PLUGIN REGISTRATION FUNCTIONS +//////// + +// Registers commands and creates constants. +function registerCommands(cmdStr) { + if (typeof cmdStr!='string') return; + + var pM = cmdStr.split(','); + pms = pms.concat(pM); + + for (var i = 0; i< pM.length; i++) { + eval(pM[i].toUpperCase()+'='+pmCount++); + } +} + +// Registers no-parameter commands +function registerNoParameterCommands(cmdStr) { + if (!cmdStr && typeof cmdStr != 'string') return; + pmt=(!pmt) ? cmdStr : pmt + ',' + cmdStr; +} + +// Register a function to hook at a certain point. +function registerHook(fnHookTo, fnRef, hookType, optPm) { + var hookPt, last = typeof optPm; + + if (fnHookTo == 'plgIn'||fnHookTo == 'postParse') return; + if (typeof hookPts[fnHookTo] == 'undefined') hookPts[fnHookTo] = new FunctionReference(); + + hookPt = hookPts[fnHookTo]; + + if (hookType != null) { + if (hookType == FREPLACE) { + hookPt.ovload = fnRef; // replace normal overlib routine + if (fnHookTo.indexOf('ol_content_') > -1) hookPt.alt[pms[CSSOFF-1-pmStart]]=fnRef; + + } else if (hookType == FBEFORE || hookType == FAFTER) { + var hookPt=(hookType == 1 ? hookPt.before : hookPt.after); + + if (typeof fnRef == 'object') { + hookPt = hookPt.concat(fnRef); + } else { + hookPt[hookPt.length++] = fnRef; + } + + if (optPm) hookPt = reOrder(hookPt, fnRef, optPm); + + } else if (hookType == FALTERNATE) { + if (last=='number') hookPt.alt[pms[optPm-1-pmStart]] = fnRef; + } else if (hookType == FCHAIN) { + hookPt = hookPt.chain; + if (typeof fnRef=='object') hookPt=hookPt.concat(fnRef); // add other functions + else hookPt[hookPt.length++]=fnRef; + } + + return; + } +} + +// Register a function that will set runtime variables. +function registerRunTimeFunction(fn) { + if (isFunction(fn)) { + if (typeof fn == 'object') { + runTime = runTime.concat(fn); + } else { + runTime[runTime.length++] = fn; + } + } +} + +// Register a function that will handle command parsing. +function registerCmdLineFunction(fn){ + if (isFunction(fn)) { + if (typeof fn == 'object') { + cmdLine = cmdLine.concat(fn); + } else { + cmdLine[cmdLine.length++] = fn; + } + } +} + +// Register a function that does things after command parsing. +function registerPostParseFunction(fn){ + if (isFunction(fn)) { + if (typeof fn == 'object') { + postParse = postParse.concat(fn); + } else { + postParse[postParse.length++] = fn; + } + } +} + +//////// +// PLUGIN REGISTRATION FUNCTIONS +//////// + +// Runs any hooks registered. +function runHook(fnHookTo, hookType) { + var l = hookPts[fnHookTo], k, rtnVal = null, optPm, arS, ar = runHook.arguments; + + if (hookType == FREPLACE) { + arS = argToString(ar, 2); + + if (typeof l == 'undefined' || !(l = l.ovload)) rtnVal = eval(fnHookTo+'('+arS+')'); + else rtnVal = eval('l('+arS+')'); + + } else if (hookType == FBEFORE || hookType == FAFTER) { + if (typeof l != 'undefined') { + l=(hookType == 1 ? l.before : l.after); + + if (l.length) { + arS = argToString(ar, 2); + for (var k = 0; k < l.length; k++) eval('l[k]('+arS+')'); + } + } + } else if (hookType == FALTERNATE) { + optPm = ar[2]; + arS = argToString(ar, 3); + + if (typeof l == 'undefined' || (l = l.alt[pms[optPm-1-pmStart]]) == 'undefined') { + rtnVal = eval(fnHookTo+'('+arS+')'); + } else { + rtnVal = eval('l('+arS+')'); + } + } else if (hookType == FCHAIN) { + arS=argToString(ar,2); + l=l.chain; + + for (k=l.length; k > 0; k--) if((rtnVal=eval('l[k-1]('+arS+')'))!=void(0)) break; + } + + return rtnVal; +} + +//////// +// OBJECT CONSTRUCTORS +//////// + +// Object for handling hooks. +function FunctionReference() { + this.ovload = null; + this.before = new Array(); + this.after = new Array(); + this.alt = new Array(); + this.chain = new Array(); +} + +// Object for simple access to the overLIB version used. +// Examples: simpleversion:351 major:3 minor:5 revision:1 +function Info(version, prerelease) { + this.version = version; + this.prerelease = prerelease; + + this.simpleversion = Math.round(this.version*100); + this.major = parseInt(this.simpleversion / 100); + this.minor = parseInt(this.simpleversion / 10) - this.major * 10; + this.revision = parseInt(this.simpleversion) - this.major * 100 - this.minor * 10; + this.meets = meets; +} + +// checks for Core Version required +function meets(reqdVersion) { + return (!reqdVersion) ? false : this.simpleversion >= Math.round(100*parseFloat(reqdVersion)); +} + + +//////// +// STANDARD REGISTRATIONS +//////// +registerHook("ol_content_simple", ol_content_simple, FALTERNATE, CSSOFF); +registerHook("ol_content_caption", ol_content_caption, FALTERNATE, CSSOFF); +registerHook("ol_content_background", ol_content_background, FALTERNATE, CSSOFF); +registerHook("ol_content_simple", ol_content_simple, FALTERNATE, CSSCLASS); +registerHook("ol_content_caption", ol_content_caption, FALTERNATE, CSSCLASS); +registerHook("ol_content_background", ol_content_background, FALTERNATE, CSSCLASS); +registerPostParseFunction(checkPositionFlags); +registerHook("hideObject", nbspCleanup, FAFTER); +registerHook("horizontalPlacement", horizontalPlacement, FCHAIN); +registerHook("verticalPlacement", verticalPlacement, FCHAIN); +if (olNs4||(olIe5&&isMac)||olKq) olLoaded=1; +registerNoParameterCommands('sticky,autostatus,autostatuscap,fullhtml,hauto,vauto,closeclick,wrap,followmouse,mouseoff,compatmode'); +/////// +// ESTABLISH MOUSECAPTURING +/////// + +// Capture events, alt. diffuses the overlib function. +var olCheckMouseCapture=true; +if ((olNs4 || olNs6 || olIe4)) { + olMouseCapture(); +} else { + overlib = no_overlib; + nd = no_overlib; + ver3fix = true; +} Index: openacs-4/packages/xowiki/www/resources/overlib/overlib_anchor.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib_anchor.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib_anchor.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,333 @@ +//\///// +//\ overLIB Anchor Plugin +//\ This file requires overLIB 4.10 or later. +//\ +//\ overLIB 4.10 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2004. All rights reserved. +//\ Contributors are listed on the homepage. +//\ See http://www.bosrup.com/web/overlib/ for details. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +//\///// +//\mini + + +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +if (typeof olInfo == 'undefined' || typeof olInfo.meets == 'undefined' || !olInfo.meets(4.10)) alert('overLIB 4.10 or later is required for the Anchor Plugin.'); +else { +registerCommands('anchor,anchorx,anchory,noanchorwarn,anchoralign'); + + + +//////// +// DEFAULT CONFIGURATION +// Settings you want everywhere are set here. All of this can also be +// changed on your html page or through an overLIB call. +//////// +if (typeof ol_anchor == 'undefined') var ol_anchor = ''; +if (typeof ol_anchorx == 'undefined') var ol_anchorx = 0; +if (typeof ol_anchory == 'undefined') var ol_anchory = 0; +if (typeof ol_noanchorwarn == 'undefined') var ol_noanchorwarn = 1; +if (typeof ol_anchoralign == 'undefined') var ol_anchoralign = 'UL'; + +//////// +// END OF CONFIGURATION +// Don't change anything below this line, all configuration is above. +//////// + + + + + +//////// +// INIT +//////// +// Runtime variables init. Don't change for config! +var o3_anchor = ""; +var o3_anchorx = 0; +var o3_anchory = 0; +var o3_noanchorwarn = 1; +var o3_anchoralign = 'UL'; +var mrkObj, rmrkPosition; //reference mark object, reference mark position, an array; + + +//////// +// PLUGIN FUNCTIONS +//////// +function setAnchorVariables() { + o3_anchor = ol_anchor; + o3_anchorx = ol_anchorx; + o3_anchory = ol_anchory; + o3_noanchorwarn = ol_noanchorwarn; + o3_anchoralign = ol_anchoralign; + mrkObj = null; // initialize this variable +} + +// Parses Reference Mark commands +function parseAnchorExtras(pf,i,ar) { + var v, k=i; + + if (k < ar.length) { + if (ar[k] == ANCHOR) { eval(pf + "anchor = '" + escSglQuote(ar[++k]) + "'"); return k; } + if (ar[k] == ANCHORX) { eval(pf + 'anchorx = ' + ar[++k]); return k; } + if (ar[k] == ANCHORY) { eval(pf + 'anchory = ' + ar[++k]); return k; } + if (ar[k] == NOANCHORWARN) { eval(pf + 'noanchorwarn = (' + pf + 'noanchorwarn==1) ? 0 : 1'); return k; } + if (ar[k] == ANCHORALIGN) { k = opt_MULTIPLEARGS(++k, ar, (pf + 'anchoralign')); return k; } + } + + return -1; +} + + +/////// +// FUNCTION WHICH CHECKS FOR THE EXISTENCE OF A REFERENCE MARKER +/////// +function checkAnchorObject() { + var w = o3_anchor; + + if (w) { + if (!(mrkObj = getAnchorObjectRef(w))) { + if (o3_noanchorwarn) { + alert('WARNING! Reference mark "' + w + '" not found.'); + return false; + } else w = ''; + } + } + + return true; +} + +/////// +// EXTERNAL SUPPORT FUNCTIONS TO HANDLE ANCHOR PROPERTIES +/////// + +// Horizontal placement routine with anchors +function anchorHorizontal(browserWidth, horizontalScrollAmount, widthFix) { + var hasAnchor = (typeof o3_anchor != 'undefined' && o3_anchor); + if (!hasAnchor) return void(0); + + // set o3_relx for follow scroll if defined + if (typeof o3_followscroll != 'undefined' && o3_followscroll && o3_sticky) o3_relx = rmrkPosition[0]; + + return rmrkPosition[0]; +} + +// Vertical placement routine with anchors +function anchorVertical(browserHeight,verticalScrollAmount) { + var hasAnchor = (typeof o3_anchor != 'undefined' && o3_anchor); + if (!hasAnchor) return void(0); + + // set o3_rely for follow scroll if defined + if (typeof o3_followscroll != 'undefined' && o3_followscroll && o3_sticky) o3_rely = rmrkPosition[1]; + + return rmrkPosition[1]; +} + +// Stub function for the runHook routine +function anchorPreface() { + if (!mrkObj) return; + rmrkPosition = getAnchorLocation(mrkObj); +} + +// Get Reference Mark object +function getAnchorObjectRef(aObj) { + return getRefById(aObj, o3_frame.document) || getRefByName(aObj, o3_frame.document) +} + +// Adapted to overlib from jwin by Jason Anderson -- http://www.jwinlib.com +function getAnchorLocation(objRef){ + var mkObj, of, offsets, mlyr + + mkObj = mlyr = objRef + offsets = [o3_anchorx, o3_anchory] + + if (document.layers){ + if (typeof mlyr.length != 'undefined' && mlyr.length > 1) { + mkObj = mlyr[0] + offsets[0] += mlyr[0].x + mlyr[1].pageX + offsets[1] += mlyr[0].y + mlyr[1].pageY + } else { + if(mlyr.toString().indexOf('Image') != -1 || mlyr.toString().indexOf('Anchor') != -1){ + offsets[0] += mlyr.x + offsets[1] += mlyr.y + } else { + offsets[0] += mlyr.pageX + offsets[1] += mlyr.pageY + } + } + } else { + offsets[0] += pageLocation(mlyr, 'Left') + offsets[1] += pageLocation(mlyr, 'Top') + } + + of = getAnchorOffsets(mkObj) + + if (typeof o3_dragimg != 'undefined' && o3_dragimg) { + olImgLeft = offsets[0]; + olImgTop = offsets[1]; + } + + offsets[0] += of[0] + offsets[1] += of[1] + + if (typeof o3_dragimg != 'undefined' && o3_dragimg) { + olImgRight = offsets[0]; + olImgBottom = offsets[1]; + return; + } + + return offsets; +} + +// Adapted to overlib from jwin by Jason Anderson -- http://www.jwinlib.com +function getAnchorOffsets(mkObj){ + var fx = fy = 0, mp, puc, mkAry, sx = sy = 0, w = o3_anchoralign + var mW = mH = pW = pH = 0 + var off = [0, 0] + + mkAry = w.split(','); + + if (mkAry.length < 3) { + mp = mkAry[0].toUpperCase(); + puc = (mkAry.length == 1) ? mp : mkAry[1].toUpperCase(); + } else if (mkAry.length == 3) { + if (!isNaN(mkAry[0])) { + mp = mkAry.slice(0, 2); + puc = mkAry[2].toUpperCase(); + } else { + mp = mkAry[0].toUpperCase(); + puc = mkAry.slice(1); + } + } else { + mp = mkAry.slice(0, 2); + puc = mkAry.slice(2); + } + + var shdwPresent = typeof o3_shadow != 'undefined' && o3_shadow + + if (shdwPresent) { + sx = Math.abs(o3_shadowx); + sy = Math.abs(o3_shadowy); + } + + pW = (shdwPresent ? parseInt(o3_width) : (olNs4 ? over.clip.width : over.offsetWidth)) + pH = (shdwPresent ? parseInt(o3_aboveheight) : (olNs4 ? over.clip.height : over.offsetHeight)) + + if (olOp && o3_wrap) { + pW = (shdwPresent ? parseInt(o3_width) : (olNs4 ? over.clip.width : over.offsetWidth)) + pH = (shdwPresent ? parseInt(o3_aboveheight) : (olNs4 ? over.clip.height : over.offsetHeight)) + } + + if (!olOp && mkObj.toString().indexOf('Image') != -1){ + mW = mkObj.width + mH = mkObj.height + } else if (!olOp && mkObj.toString().indexOf('Anchor') != -1) { // enforced only for NS4 + mp = 'UL' + } else { + mW = (olNs4) ? mkObj.clip.width : mkObj.offsetWidth + mH = (olNs4) ? mkObj.clip.height : mkObj.offsetHeight + } + + if (!isNaN(mp) || typeof mp == 'object') { + if (typeof mp == 'object') { + fx = parseFloat(mp[0]); + fy = parseFloat(mp[1]); + } else + fx = fy = parseFloat(mp); + off = [Math.round(fx*mW), Math.round(fy*mH)]; + } else { + if (mp == 'UR') off = [mW, 0] + else if (mp == 'LL') off = [0, mH] + else if (mp == 'LR') off = [mW, mH] + } + + if (typeof o3_dragimg != 'undefined' && o3_dragimg) return off; + else { + if (!isNaN(puc) || typeof puc == 'object' ) { + if (typeof puc == 'object') { + fx = parseFloat(puc[0]); + fy = parseFloat(puc[1]); + } else + fx = fy = parseFloat(puc); + off[0] -= Math.round(fx*(pW - sx)); + off[1] -= Math.round(fy*(pH - sy)); + } else { + if (puc == 'UR') { + off[0] -= (pW - sx); + off[1] -= sy + } else if (puc == 'LL') { + off[0] -= sx; + off[1] -= (pH - sy) + } else if (puc == 'LR') { + off[0] -= (pW-sx); + off[1] -= (pH - sy) + } + } + return off + } +} + +// Adapted to overlib from jwin by Jason Anderson -- http://www.jwinlib.com +function pageLocation(o, t){ + var x = 0 + + while(o.offsetParent){ + x += o['offset' + t] + o = o.offsetParent + } + x += o['offset' + t] + + return x +} + +// Adapted to overlib from jwin by Jason Anderson -- http://www.jwinlib.com +function getRefById(l, d){ + var r = "", j + + d = (d || document) + if (d.all) return d.all[l] + else if (d.getElementById) return d.getElementById(l) + else if (d.layers && d.layers.length > 0) { + if (d.layers[l]) return d.layers[l] + + for (j=0; j < d.layers.length; j++) { + r = getRefById(l, d.layers[j].document) + if(r) return r + } + } + + return false +} + +// Adapted to overlib from jwin by Jason Anderson -- http://www.jwinlib.com +function getRefByName(l, d) { + var r = null, j + + d = (d || document) + + if (d.images[l]) return d.images[l] + else if (d.anchors[l]) return d.anchors[l]; + else if (d.layers && d.layers.length > 0) { + for (j=0; j < d.layers.length; j++) { + r = getRefByName(l, d.layers[j].document) + if (r && r.length > 0) return r + else if (r) return [r, d.layers[j]] + } + } + + return null +} + +//////// +// PLUGIN REGISTRATIONS +//////// +registerRunTimeFunction(setAnchorVariables); +registerCmdLineFunction(parseAnchorExtras); +registerPostParseFunction(checkAnchorObject); +registerHook("createPopup", anchorPreface, FAFTER); +registerHook("horizontalPlacement", anchorHorizontal, FCHAIN); +registerHook("verticalPlacement", anchorVertical, FCHAIN); +if(olInfo.meets(4.10)) registerNoParameterCommands('noanchorwarn'); +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/overlib/overlib_centerpopup.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib_centerpopup.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib_centerpopup.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,89 @@ +//\///// +//\ overLIB Center Popup Plugin +//\ This file requires overLIB 4.10 or later. +//\ +//\ overLIB 4.10 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2003. All rights reserved. +//\ Contributors are listed on the homepage. +//\ See http://www.bosrup.com/web/overlib/ for details. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +// +//\///// +//\mini +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +if (typeof olInfo == 'undefined' || typeof olInfo.meets == 'undefined' || !olInfo.meets(4.10)) alert('overLIB 4.10 or later is required for the Center Popup Plugin.'); +else { +registerCommands('centerpopup,centeroffset'); +//////// +// DEFAULT CONFIGURATION +// You don't have to change anything here if you don't want to. All of this can be +// changed on your html page or through an overLIB call. +//////// +// Default value for centerpopup is to not center the popup +if (typeof ol_centerpopup == 'undefined') var ol_centerpopup = 0; +if (typeof ol_centeroffset == 'undefined') var ol_centeroffset = '0'; +//////// +// END OF CONFIGURATION +// Don't change anything below this line, all configuration is above. +//////// +//////// +// INIT +//////// +// Runtime variables init. Don't change for config! +var o3_centerpopup = 0; +var o3_centeroffset = '0'; +//////// +// PLUGIN FUNCTIONS +//////// +function setCenterPopupVariables() { + o3_centerpopup = ol_centerpopup; + o3_centeroffset = ol_centeroffset; +} +// Parses Shadow and Scroll commands +function parseCenterPopupExtras(pf,i,ar) { + var k = i,v; + + if (k < ar.length) { + if (ar[k] == CENTERPOPUP) { eval(pf + 'centerpopup = (' + pf + 'centerpopup == 0) ? 1 : 0'); return k; } + if (ar[k] == CENTEROFFSET) { k = opt_MULTIPLEARGS(++k,ar,(pf + 'centeroffset')); return k; } + } + + return -1; +} +// Function which positions popup in Center of screen +function centerPopupHorizontal(browserWidth, horizontalScrollAmount, widthFix) { + if (!o3_centerpopup) return void(0); + + var vdisp = o3_centeroffset.split(','); + var placeX, iwidth = browserWidth, winoffset = horizontalScrollAmount; + var pWd = parseInt(o3_width); + + placeX = winoffset + Math.round((iwidth - widthFix - pWd)/2) + parseInt(vdisp[0]); + if(typeof o3_followscroll != 'undefined' && o3_followscroll && o3_sticky) o3_relx = placeX; + + return placeX; +} +function centerPopupVertical(browserHeight,verticalScrollAmount) { + if (!o3_centerpopup) return void(0); + + var placeY, iheight = browserHeight, scrolloffset = verticalScrollAmount; + var vdisp = o3_centeroffset.split(','); + var pHeight = (o3_aboveheight ? parseInt(o3_aboveheight) : (olNs4 ? over.clip.height : over.offsetHeight)); + + placeY = scrolloffset + Math.round((iheight - pHeight)/2) + (vdisp.length > 1 ? parseInt(vdisp[1]) : 0); + if(typeof o3_followscroll != 'undefined' && o3_followscroll && o3_sticky) o3_rely = placeY; + + return placeY; +} +//////// +// PLUGIN REGISTRATIONS +//////// +registerRunTimeFunction(setCenterPopupVariables); +registerCmdLineFunction(parseCenterPopupExtras); +registerHook('horizontalPlacement',centerPopupHorizontal,FCHAIN); +registerHook('verticalPlacement', centerPopupVertical, FCHAIN); +if(olInfo.meets(4.10)) registerNoParameterCommands('centerpopup'); +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/overlib/overlib_crossframe.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib_crossframe.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib_crossframe.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,105 @@ +//\///// +//\ overLIB Crossframe Support Plugin +//\ This file requires overLIB 4.10 or later. +//\ +//\ overLIB 4.05 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2004. All rights reserved. +//\ Contributors are listed on the homepage. +//\ See http://www.bosrup.com/web/overlib/ for details. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +//\///// +//\mini + +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +if (typeof olInfo == 'undefined' || typeof olInfo.meets == 'undefined' || !olInfo.meets(4.10)) alert('overLIB 4.10 or later is required for the Cross Frame Support Plugin.'); +else { +registerCommands('frame'); + + +//////// +// PLUGIN FUNCTIONS +/////// + +// Parses FRAME command +function parseFrameExtras(pf,i,ar) { + var k = i,v; + + if (k < ar.length) { + if (ar[k] == FRAME) { v = ar[++k]; if(pf == 'ol_') ol_frame = v; else opt_FRAME(v); return k; } + } + + return -1; +} + +//////// +// SUPPORT FUNCTIONS +//////// + +// Defines which frame we should point to. +function opt_FRAME(frm) { + o3_frame = frm; + over = createDivContainer('overDiv'); + return 0; +} + +// Get frame depth of nested frames +function frmDepth(thisFrame,ofrm) { + var retVal = ''; + + for (var i = 0; i 0) { + retVal = frmDepth(thisFrame[i],ofrm); + if (retVal == '') continue; + } else if (thisFrame[i] != ofrm) continue; + retVal = '[' + i + ']' + retVal; + break; + } + + return retVal; +} + +// Gets frame reference value relative to top frame +function getFrmRef(srcFrm,tgetFrm) { + var rtnVal = '' + + if (tgetFrm != srcFrm) { + var tFrm = frmDepth(top.frames,tgetFrm) + var sFrm = frmDepth(top.frames,srcFrm) + if (sFrm.length == tFrm.length) { + l = tFrm.lastIndexOf('[') + + if (l) { + while ( sFrm.substring(0,l) != tFrm.substring(0,l) ) + l = tFrm.lastIndexOf('[',l-1) + tFrm = tFrm.substr(l) + sFrm = sFrm.substr(l) + } + } + + var cnt = 0, p = '',str = tFrm + while ((k = str.lastIndexOf('[')) != -1) { + cnt++ + str = str.substring(0,k) + } + + for (var i = 0; i
      '+text+'
      '; + set_background(""); + + return txt; +} + +// Makes table with caption and optional close link +function ol_content_caption_cssstyle(text, title, close) { + var nameId; + closing = ""; + closeevent = "onMouseOver"; + + if (o3_closeclick == 1) closeevent= (o3_closetitle ? "title='" + o3_closetitle +"'" : "") + " onClick"; + + if (o3_capicon!="") { + nameId=' hspace=\"5\"'+' align=\"middle\" alt=\"\"'; + if (typeof o3_dragimg != 'undefined' && o3_dragimg) nameId = ' hspace=\"5\"'+' name=\"'+o3_dragimg+'\" id=\"'+o3_dragimg+'\" align=\"middle\" alt=\"Drag Enabled\" title=\"Drag Enabled\"'; + o3_capicon = ''; + } + + if (close != "") { + closing = ''+close+''; + } + + txt = '
      '+closing+'
      '+o3_capicon+title+'
      '+text+'
      '; + set_background(""); + + return txt; +} + +// Sets the background picture, padding and lots more. :) +function ol_content_background_cssstyle(text, picture, hasfullhtml) { + if (hasfullhtml) { + txt = text; + } else { + var pU, hU, wU; + pU = (o3_padunit == '%' ? '%' : ''); + hU = (o3_heightunit == '%' ? '%' : ''); + wU = (o3_widthunit == '%' ? '%' : ''); + txt = '
      '+text+'
      '; + } + + set_background(picture); + + return txt; +} + +//////// +// PLUGIN REGISTRATIONS +//////// +registerRunTimeFunction(setCSSStyleVariables); +registerCmdLineFunction(parseCSSStyleExtras); +registerHook("ol_content_simple", ol_content_simple_cssstyle, FALTERNATE, CSSSTYLE); +registerHook("ol_content_caption", ol_content_caption_cssstyle, FALTERNATE, CSSSTYLE); +registerHook("ol_content_background", ol_content_background_cssstyle, FALTERNATE, CSSSTYLE); +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/overlib/overlib_debug.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib_debug.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib_debug.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,177 @@ +//\///// +//\ overLIB Debug Plugin +//\ This file requires overLIB 4.10 or later. +//\ +//\ overLIB 4.05 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2003. All rights reserved. +//\ Contributors are listed on the homepage. +//\ See http://www.bosrup.com/web/overlib/ for details. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +// +//\///// +//\mini +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +if (typeof olInfo == 'undefined' || typeof olInfo.meets == 'undefined' || !olInfo.meets(4.10)) alert('overLIB 4.10 or later is required for the Debug Plugin.'); +else { +var olZindex; +registerCommands('allowdebug'); +//////// +// PLUGIN FUNCTIONS +//////// +// Parses Debug Parameters +function parseDebugExtras(pf, i, ar) { + var k = i, v; + + if (k < ar.length) { + if (ar[k] == ALLOWDEBUG) { v = ar[k + 1]; if(typeof v == 'string') {v = ar[++k]; if (pf != 'ol_') setCanShowParm(v);} return k; } + } + + return -1; +} +// Debug main routine +function showProperties() { + var args = showProperties.arguments, sho, shoObj, vis, lvl = 0, istrt = 0, theDiv = 'showProps', txt = ''; + + if (args.length == 0) return; + if (args.length % 2 && typeof args[0] == 'string') { + istrt = 1; + theDiv = args[0]; + } + + sho = createDivContainer(theDiv); + + if (olNs4) { + shoObj = sho; + txt += '
      '; + } else { + with(sho.style) { + backgroundColor = '#ffffcc'; + padding = '5px'; + border = '1px #000000 solid'; + } + shoObj = sho.style; + } + + lvl = getLayerLevel(theDiv); + + if(typeof sho.position == 'undefined') { + sho.position = new Pagelocation(10 + lvl*20, 10, 1); + if(typeof olZindex == 'undefined') olZindex = getDivZindex(); + shoObj.zIndex = olZindex + 1 + lvl; + } + + txt += ''; + txt += ''; + txt += ''; + for (var i = istrt; i'; + txt += '
      ' + theDiv + 'X
      ItemValue
      ' + args[++i] + '
      ' + (olNs4 ? '
      ' : ''); + + if (olNs4) { + sho.document.open(); + sho.document.write(txt); + sho.document.close(); + } else { + if(olIe5&&isMac) sho.innerHTML = ''; + sho.innerHTML = txt; + } + + showAllVisibleLayers(); +} +function getLayerLevel(lyr) { + var i = 0; + + if (typeof document.popups == 'undefined') { + document.popups = new Array(lyr); + } else { + var l = document.popups; + for (var i = 0; i/g,">").replace(/"/g,"""); +} +//////// +// PLUGIN REGISTRATIONS +//////// +registerCmdLineFunction(parseDebugExtras); +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/overlib/overlib_exclusive.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib_exclusive.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib_exclusive.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,123 @@ +//\///// +//\ overLIB Exclusive Plugin +//\ This file requires overLIB 4.10 or later. +//\ +//\ overLIB 4.05 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2004. All rights reserved. +//\ Contributors are listed on the homepage. +//\ See http://www.bosrup.com/web/overlib/ for details. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +//\///// +//\mini +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +if (typeof olInfo == 'undefined' || typeof olInfo.meets == 'undefined' || !olInfo.meets(4.10)) alert('overLIB 4.10 or later is required for the Debug Plugin.'); +else { +registerCommands('exclusive,exclusivestatus,exclusiveoverride'); +var olOverrideIsSet; // variable which tells if override is set + + +//////// +// DEFAULT CONFIGURATION +// Settings you want everywhere are set here. All of this can also be +// changed on your html page or through an overLIB call. +//////// +if (typeof ol_exclusive == 'undefined') var ol_exclusive = 0; +if (typeof ol_exclusivestatus == 'undefined') var ol_exclusivestatus = 'Please close open popup first.'; + +//////// +// END OF CONFIGURATION +// Don't change anything below this line, all configuration is above. +//////// + + +//////// +// INIT +//////// +// Runtime variables init. Don't change for config! +var o3_exclusive = 0; +var o3_exclusivestatus = ''; + +//////// +// PLUGIN FUNCTIONS +//////// + +// Set runtime variables +function setExclusiveVariables() { + o3_exclusive = ol_exclusive; + o3_exclusivestatus = ol_exclusivestatus; +} + +// Parses Exclusive Parameters +function parseExclusiveExtras(pf,i,ar) { + var k = i,v; + + olOverrideIsSet = false; // a global variable + + if (k < ar.length) { + if (ar[k] == EXCLUSIVEOVERRIDE) { if(pf != 'ol_') olOverrideIsSet = true; return k; } + if (ar[k] == EXCLUSIVE) { eval(pf + 'exclusive = (' + pf + 'exclusive == 0) ? 1 : 0'); return k; } + if (ar[k] == EXCLUSIVESTATUS) { eval(pf + "exclusivestatus = '" + escSglQuote(ar[++k]) + "'"); return k; } + } + + return -1; +} + +/////// +// HELPER FUNCTIONS +/////// +// set status message and indicate whether popup is exclusive +function isExclusive(args) { + var rtnVal = false; + + if(args != null) rtnVal = hasCommand(args, EXCLUSIVEOVERRIDE); + + if(rtnVal) return false; + else { + self.status = (o3_exclusive) ? o3_exclusivestatus : ''; + return o3_exclusive; + } + +} + +// checks overlib argument list to see if it has a COMMAND argument +function hasCommand(args, COMMAND) { + var rtnFlag = false; + + for (var i=0; i' + content + '
      '; + layerWrite(txt); +} + +// Code for the IFRAME which is used in other places +function backDropSource(width, height, Z) { + return ''; +} + +// Hides SELECT boxes that will be under the popup +// Checking Gecko version number to try to include other browsers based on the Gecko engine +function hideSelectBox() { + if(olNs4 || olOp || olIe55) return; + var px, py, pw, ph, sx, sw, sy, sh, selEl, v; + + if(olIe4) v = 0; + else { + v = navigator.userAgent.match(/Gecko\/(\d{8})/i); + if(!v) return; // return if no string match + v = parseInt(v[1]); + } + + if (v < 20030624) { // versions less than June 24, 2003 were earlier Netscape browsers + px = parseInt(over.style.left); + py = parseInt(over.style.top); + pw = o3_width; + ph = (o3_aboveheight ? parseInt(o3_aboveheight) : over.offsetHeight); + selEl = (olIe4) ? o3_frame.document.all.tags("SELECT") : o3_frame.document.getElementsByTagName("SELECT"); + for (var i=0; i (sx+sw) || (py+ph) < sy || py > (sy+sh)) continue; + selEl[i].isHidden = 1; + selEl[i].style.visibility = 'hidden'; + } + } +} + +// Shows previously hidden SELECT Boxes +function showSelectBox() { + if(olNs4 || olOp || olIe55) return; + var selEl, v; + + if(olIe4) v = 0; + else { + v = navigator.userAgent.match(/Gecko\/(\d{8})/i); + if(!v) return; + v = parseInt(v[1]); + } + + if(v < 20030624) { + selEl = (olIe4) ? o3_frame.document.all.tags("SELECT") : o3_frame.document.getElementsByTagName("SELECT"); + for (var i=0; i\n\n'); + } + + f = capExtent.onmousemove.toString().match(/function[ ]+(\w*)\(/); + if (f&&f[1] != 'anonymous') capExtent.onmousemove = olMouseMove; +} + + +//////// +// PLUGIN REGISTRATIONS +//////// +registerHook("createPopup",generatePopUp,FAFTER); +registerHook("hideObject",showSelectBox,FAFTER); +olHideForm=1; +} Index: openacs-4/packages/xowiki/www/resources/overlib/overlib_setonoff.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib_setonoff.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib_setonoff.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,101 @@ +//\///// +//\ overLIB Set On/Off Plugin +//\ This file requires overLIB 4.10 or later. +//\ +//\ overLIB 4.10 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2003. All rights reserved. +//\ Contributors are listed on the homepage. +//\ See http://www.bosrup.com/web/overlib/ for details. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +// +//\///// +//\mini +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +if (typeof olInfo == 'undefined' || typeof olInfo.meets == 'undefined' || !olInfo.meets(4.10)) alert('overLIB 4.10 or later is required for the Set On/Off Plugin.'); +else { +registerCommands('seton, setoff'); +var olSetType; +// END OF CONFIGURATION +// Don't change anything below this line, all configuration is above. +//////// +// PLUGIN FUNCTIONS +//////// +// Set runtime variables +function setOnOffVariables() { + olSetType = 0; +} +// Parses Set On/Off Parameters +function parseOnOffExtras(pf, i, ar) { + var k = i, v; + + if (k < ar.length) { + if (ar[k] == SETON||ar[k] == SETOFF) { olSetType = 1; k = opt_MULTICOMMANDS(++k, ar); return k; } + } + + return -1; +} +/////// +// HELPER FUNCTIONS +/////// +// searches arg list for COMMAND; +function hasCommand(istrt, args, COMMAND) { + for (var i = istrt; i < args.length; i++) { + if (typeof args[i] == 'number' && args[i] == COMMAND) return i; + } + + return -1; +} +// scans for toggle like commands to be forced ON/OFF +function scanCommandSet(pf, args) { + var k = -1, j, je; + + if (olSetType) { + // search for SETON command + while ((k = hasCommand(++k, args, SETON)) < args.length && k > -1) { + je = opt_MULTICOMMANDS(k + 1, args); + for (j = k + 1; j < (k + je); j++) setNoParamCommand(1, pf, args[j]); + k += (je - 1); + } + // search for SETOFF command + k = -1; + while ((k = hasCommand(++k, args, SETOFF)) < args.length && k > -1) { + je = opt_MULTICOMMANDS(k + 1, args); + for (j = k + 1; j < (k + je); j++) setNoParamCommand(0, pf, args[j]); + k += (je - 1); + } + } + + return true; +} +var olRe; +// set command according to whichType (0 or 1) +function setNoParamCommand(whichType, pf, COMMAND) { + var v = pms[COMMAND - 1 - pmStart]; + + if(pmt && !olRe) olRe = eval('/' + pmt.split(',').join('|') + '/'); + if (pf != 'ol_' && /capturefirst/.test(v)) return; // no o3_capturefirst variable + if (pf != 'ol_' && /wrap/.test(v) && eval(pf + 'wrap') && (whichType == 0)) { + nbspCleanup(); // undo wrap effects since checked after all parsing + o3_width = ol_width; + } + + if (olRe.test(v)) eval(pf + v + '=' + ((whichType && COMMAND == AUTOSTATUSCAP) ? whichType++ : whichType)); +} +function opt_MULTICOMMANDS(i, ar) { + var k = i; + + while (k < ar.length && typeof ar[k] == 'number' && ar[k] > pmStart) {k++; if (ar[k - 1] == 'SETON'||ar[k - 1] == 'SETOFF') break;} + k -= (k < ar.length ? 2 : 1); + + return k; +} +//////// +// PLUGIN REGISTRATIONS +//////// +registerRunTimeFunction(setOnOffVariables); +registerCmdLineFunction(parseOnOffExtras); +registerPostParseFunction(scanCommandSet); +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/overlib/overlib_shadow.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/overlib/overlib_shadow.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/overlib/overlib_shadow.js 1 Aug 2007 21:39:29 -0000 1.1.2.2 @@ -0,0 +1,270 @@ +//\///// +//\ overLIB Shadow Plugin +//\ This file requires overLIB 4.10 or later. +//\ +//\ overLIB 4.05 - You may not remove or change this notice. +//\ Copyright Erik Bosrup 1998-2003. All rights reserved. +//\ Contributors are listed on the homepage. +//\ See http://www.bosrup.com/web/overlib/ for details. +// $Revision: 1.1.2.2 $ $Date: 2007/08/01 21:39:29 $ +//\///// +//\mini + +//////// +// PRE-INIT +// Ignore these lines, configuration is below. +//////// +if (typeof olInfo == 'undefined' || typeof olInfo.meets == 'undefined' || !olInfo.meets(4.10)) alert('overLIB 4.10 or later is required for the Shadow Plugin.'); +else { +registerCommands('shadow,shadowcolor,shadowimage,shadowopacity,shadowx,shadowy'); + + +//////// +// DEFAULT CONFIGURATION +// You don't have to change anything here if you don't want to. All of this can be +// changed on your html page or through an overLIB call. +//////// +if (typeof ol_shadowadjust=='undefined') var ol_shadowadjust=2; // for Ns4.x only +if (typeof ol_shadow=='undefined') var ol_shadow=0; +if (typeof ol_shadowcolor=='undefined') var ol_shadowcolor='#CCCCCC'; +if (typeof ol_shadowimage=='undefined') var ol_shadowimage=''; +if (typeof ol_shadowopacity=='undefined') var ol_shadowopacity=0; +if (typeof ol_shadowx=='undefined') var ol_shadowx=5; +if (typeof ol_shadowy=='undefined') var ol_shadowy=5; + +//////// +// END OF CONFIGURATION +// Don't change anything below this line, all configuration is above. +//////// + + + + +//////// +// INIT +//////// +// Runtime variables init. Don't change for config! +var o3_shadow=0; +var o3_shadowcolor="#cccccc"; +var o3_shadowimage=''; +var o3_shadowopacity=0; +var o3_shadowx=5; +var o3_shadowy=5; +var bkSet=0; // Needed for this effect in NS4 + + + +// Function which sets runtime variables to their default values +function setShadowVariables() { + o3_shadow=ol_shadow; + o3_shadowcolor=ol_shadowcolor; + o3_shadowimage=ol_shadowimage; + o3_shadowopacity=ol_shadowopacity; + o3_shadowx=ol_shadowx; + o3_shadowy=ol_shadowy; +} + + +// Parses shadow commands +function parseShadowExtras(pf,i,ar) { + var k = i, v; + + if (k < ar.length) { + if (ar[k]==SHADOW) { eval(pf +'shadow=('+pf+'shadow==0) ? 1 : 0'); return k; } + if (ar[k]==SHADOWCOLOR) { eval(pf+'shadowcolor="'+ar[++k]+'"'); return k; } + if (ar[k]==SHADOWOPACITY) {v=ar[++k]; eval(pf+'shadowopacity='+(olOp ? 0 : v)); return k; } + if (ar[k]==SHADOWIMAGE) { eval(pf+'shadowimage="'+ar[++k]+'"'); return k; } + if (ar[k]==SHADOWX) { eval(pf+'shadowx='+ar[++k]); return k; } + if (ar[k]==SHADOWY) { eval(pf+'shadowy='+ar[++k]); return k; } + } + + return -1; +} + + +// Function for MOUSEOUT/MOUSEOFF feature with shadow +function shadow_cursorOff() { + var left= parseInt(over.style.left); + var top=parseInt(over.style.top); + var right=left+(o3_shadow ? o3_width : over.offsetWidth); + var bottom=top+(o3_shadow ? o3_aboveheight : over.offsetHeight); + + if (o3_x < left || o3_x > right || o3_y < top || o3_y > bottom) return true; + return false; +} + +// Pre-hide processing to clean-up. +function checkShadowPreHide() { + if (o3_shadow && o3_shadowopacity) cleanUpShadowEffects(); + if (o3_shadow && (olIe4 && isMac) ) over.style.pixelWidth=over.style.pixelHeight = 0; +} + + +// Funciton that creates the actual shadow +function generateShadow(content) { + var wd, ht, X = 0, Y = 0, zIdx = 0, txt, dpObj, puObj, bS= '', aPos, posStr=new Array(); + + if (!o3_shadow || (o3_shadowx == 0 && o3_shadowy == 0)) return; + + X = Math.abs(o3_shadowx); + Y = Math.abs(o3_shadowy); + wd = parseInt(o3_width); + ht = (olNs4) ? over.clip.height : over.offsetHeight; + + if (o3_shadowx == 0) { + if (o3_shadowy < 0) { + posStr[0]=' left:0; top: 0'; + posStr[1]=' left:0; top: '+Y+'px'; + } else if (o3_shadowy > 0) { + posStr[0]=' left:0; top: '+Y+'px'; + posStr[1]=' left:0; top:0'; + } + } else if (o3_shadowy == 0) { + if (o3_shadowx < 0) { + posStr[0]=' left:0; top: 0'; + posStr[1]=' left: '+X+'px'; + } else if (o3_shadowx > 0) { + posStr[0]=' left: '+ X+'px; top: 0'; + posStr[1]=' left:0; top:0'; + } + } else if (o3_shadowx > 0) { + if (o3_shadowy > 0) { + posStr[0]=' left:'+ X+'px; top:'+Y+'px'; + posStr[1]=' left:0; top:0'; + } else if (o3_shadowy < 0) { + posStr[0]=' left:'+X+'px; top:0'; + posStr[1]=' left:0; top: '+Y+'px'; + } + } else if (o3_shadowx < 0) { + if (o3_shadowy > 0) { + posStr[0]=' left:0; top:'+Y+'px'; + posStr[1]=' left:'+X+'px; top:0'; + } else if (o3_shadowy < 0) { + posStr[0]=' left:0; top:0'; + posStr[1]=' left:'+X+'px; top:'+Y+'px'; + } + } + + txt = (olNs4) ? '
      ' : ((olIe55&&olHideForm) ? backDropSource(wd+X,ht+Y,zIdx++) : '') + '
      '+content+'
      '; + } else { + txt += bS+'">
      '+content+'
      '; + } + + layerWrite(txt); + + if (olNs4 && bkSet) { + dpObj = over.document.layers['backdrop']; + if (typeof dpObj == 'undefined') return; // if shadow layer not found, then content layer won't be either + + puObj = over.document.layers['PUContent']; + wd = puObj.clip.width; + ht = puObj.clip.height; + aPos = posStr[0].split(';'); + + dpObj.clip.width = wd; + dpObj.clip.height = ht; + dpObj.left = parseInt(aPos[0].split(':')[1]); + dpObj.top = parseInt(aPos[1].split(':')[1]); + + dpObj.bgColor = (bkSet == 1) ? null : o3_shadowcolor; + dpObj.background.src = (bkSet==2) ? null : o3_shadowimage; + dpObj.zIndex = 0; + + aPos = posStr[1].split(';'); + puObj.left = parseInt(aPos[0].split(':')[1]); + puObj.top = parseInt(aPos[1].split(':')[1]); + puObj.zIndex = 1; + + } else { + puObj = (olIe4 ? o3_frame.document.all['PUContent'] : o3_frame.document.getElementById('PUContent')); + dpObj = (olIe4 ? o3_frame.document.all['backdrop'] : o3_frame.document.getElementById('backdrop')); + ht = puObj.offsetHeight; + dpObj.style.height = ht + 'px'; + + if (o3_shadowopacity) { + var op = o3_shadowopacity; + op = (op <= 100 ? op : 100); + + setBrowserOpacity(op,dpObj); + } + } + + // Set popup's new width and height values here so they are available in placeLayer() + o3_width = wd+X; + o3_aboveheight = ht+Y; +} + + +//////// +// SUPPORT FUNCTIONS +//////// + +// Cleans up opacity settings if any. +function cleanUpShadowEffects() { + if (olNs4 || olOp) return; + var dpObj=(olIe4 ? o3_frame.document.all['backdrop'] : o3_frame.document.getElementById('backdrop')); + cleanUpBrowserOpacity(dpObj); +} + +// multi browser opacity support +function setBrowserOpacity(op,lyr){ + if (olNs4||!op) return; // if Ns4.x or opacity not given return; + lyr=(lyr) ? lyr : over; + if (olIe4&&typeof lyr.filters != 'undefined') { + lyr.style.filter='Alpha(Opacity='+op+')'; + lyr.filters.alpha.enabled=true; + } else { + var sOp=(typeof(lyr.style.MozOpacity)!='undefined') ? 'MozOpacity' : (typeof(lyr.style.KhtmlOpacity)!='undefined' ? 'KhtmlOpacity' : (typeof(lyr.style.opacity)!='undefined' ? 'opacity' : '')); + if (sOp) eval('lyr.style.'+sOp+'=op/100'); + } +} + +// multi-browser Opacity cleanup +function cleanUpBrowserOpacity(lyr) { + if (olNs4) return; + lyr=(lyr) ? lyr : over; + if (olIe4&&(typeof lyr.filters != 'undefined'&&lyr.filters.alpha.enabled)) { + lyr.style.filter='Alpha(Opacity=100)'; + lyr.filters.alpha.enabled=false; + } else { + var sOp=(typeof(lyr.style.MozOpacity)!='undefined') ? 'MozOpacity' : (typeof(lyr.style.KhtmlOpacity)!='undefined' ? 'KhtmlOpacity' : (typeof(lyr.style.opacity)!='undefined' ? 'opacity' : '')); + if (sOp) eval('lyr.style.'+sOp+'=1.0'); + } +} + +// This routine is needed only for Ns4.x to allow use of popups with dropshadows and CSSCLASS at the same time on a page +function shadowAdjust() { + if (!olNs4) return; + var fac = ol_shadowadjust; + if (olNs4) { + document.write('", 'Css'); +} + +XhtmlLexer.prototype.addTagTokens = function(scope) +{ + this.addSpecialPattern("<\\s*[a-z0-9:\-]+\\s*>", scope, 'OpeningTag'); + this.addEntryPattern("<[a-z0-9:\-]+"+'[\\\/ \\\>]+', scope, 'OpeningTag'); + this.addInTagDeclarationTokens('OpeningTag'); + + this.addSpecialPattern("", scope, 'ClosingTag'); + +} + +XhtmlLexer.prototype.addInTagDeclarationTokens = function(scope) +{ + this.addSpecialPattern('\\s+', scope, 'Ignore'); + + this.addAttributeTokens(scope); + + this.addExitPattern('/>', scope); + this.addExitPattern('>', scope); + +} + +XhtmlLexer.prototype.addAttributeTokens = function(scope) +{ + this.addSpecialPattern("\\s*[a-z-_0-9]+\\s*(?=\=)\\s*", scope, 'TagAttributes'); + + this.addEntryPattern('=\\s*"', scope, 'DoubleQuotedAttribute'); + this.addPattern("\\\\\"", 'DoubleQuotedAttribute'); + this.addExitPattern('"', 'DoubleQuotedAttribute'); + + this.addEntryPattern("=\\s*'", scope, 'SingleQuotedAttribute'); + this.addPattern("\\\\'", 'SingleQuotedAttribute'); + this.addExitPattern("'", 'SingleQuotedAttribute'); + + this.addSpecialPattern('=\\s*[^>\\s]*', scope, 'UnquotedAttribute'); +} + + + +/** +* XHTML Parser. +* +* This XHTML parser will trigger the events available on on +* current SaxListener +* +* @author Bermi Ferrer (http://bermi.org) +*/ +function XhtmlParser(Listener, mode) +{ + var mode = mode || 'Text'; + this._Lexer = new XhtmlLexer(this); + this._Listener = Listener; + this._mode = mode; + this._matches = []; + this._last_match = ''; + this._current_match = ''; + + return this; +} + +XhtmlParser.prototype.parse = function(raw) +{ + this._Lexer.parse(this.beforeParsing(raw)); + return this.afterParsing(this._Listener.getResult()); +} + +XhtmlParser.prototype.beforeParsing = function(raw) +{ + if(raw.match(/class="MsoNormal"/) || raw.match(/ns = "urn:schemas-microsoft-com/)){ + // Usefull for cleaning up content pasted from other sources (MSWord) + this._Listener.avoidStylingTagsAndAttributes(); + } + return this._Listener.beforeParsing(raw); +} + +XhtmlParser.prototype.afterParsing = function(parsed) +{ + if(this._Listener._avoiding_tags_implicitly){ + this._Listener.allowStylingTagsAndAttributes(); + } + return this._Listener.afterParsing(parsed); +} + + +XhtmlParser.prototype.Ignore = function(match, state) +{ + return true; +} + +XhtmlParser.prototype.Text = function(text) +{ + this._Listener.addContent(text); + return true; +} + +XhtmlParser.prototype.Comment = function(match, status) +{ + return this._addNonTagBlock(match, status, 'addComment'); +} + +XhtmlParser.prototype.Script = function(match, status) +{ + return this._addNonTagBlock(match, status, 'addScript'); +} + +XhtmlParser.prototype.Css = function(match, status) +{ + return this._addNonTagBlock(match, status, 'addCss'); +} + +XhtmlParser.prototype._addNonTagBlock = function(match, state, type) +{ + switch (state){ + case LEXER_ENTER: + this._non_tag = match; + break; + case LEXER_UNMATCHED: + this._non_tag += match; + break; + case LEXER_EXIT: + switch(type) { + case 'addComment': + this._Listener.addComment(this._non_tag+match); + break; + case 'addScript': + this._Listener.addScript(this._non_tag+match); + break; + case 'addCss': + this._Listener.addCss(this._non_tag+match); + break; + } + } + return true; +} + +XhtmlParser.prototype.OpeningTag = function(match, state) +{ + switch (state){ + case LEXER_ENTER: + this._tag = this.normalizeTag(match); + this._tag_attributes = {}; + break; + case LEXER_SPECIAL: + this._callOpenTagListener(this.normalizeTag(match)); + break; + case LEXER_EXIT: + this._callOpenTagListener(this._tag, this._tag_attributes); + } + return true; +} + +XhtmlParser.prototype.ClosingTag = function(match, state) +{ + this._callCloseTagListener(this.normalizeTag(match)); + return true; +} + +XhtmlParser.prototype._callOpenTagListener = function(tag, attributes) +{ + var attributes = attributes || {}; + this.autoCloseUnclosedBeforeNewOpening(tag); + + if(this._Listener.isBlockTag(tag)){ + this._Listener._tag_stack.push(tag); + this._Listener.openBlockTag(tag, attributes); + this._increaseOpenTagCounter(tag); + }else if(this._Listener.isInlineTag(tag)){ + this._Listener.inlineTag(tag, attributes); + }else{ + this._Listener.openUnknownTag(tag, attributes); + this._increaseOpenTagCounter(tag); + } + this._Listener.last_tag = tag; + this._Listener.last_tag_opened = true; + this._Listener.last_tag_attributes = attributes; +} + +XhtmlParser.prototype._callCloseTagListener = function(tag) +{ + if(this._decreaseOpenTagCounter(tag)){ + this.autoCloseUnclosedBeforeTagClosing(tag); + + if(this._Listener.isBlockTag(tag)){ + var expected_tag = this._Listener._tag_stack.pop(); + if(expected_tag == false){ + return; + }else if(expected_tag != tag){ + tag = expected_tag; + } + this._Listener.closeBlockTag(tag); + }else{ + this._Listener.closeUnknownTag(tag); + } + }else{ + this._Listener.closeUnopenedTag(tag); + } + this._Listener.last_tag = tag; + this._Listener.last_tag_opened = false; +} + +XhtmlParser.prototype._increaseOpenTagCounter = function(tag) +{ + this._Listener._open_tags[tag] = this._Listener._open_tags[tag] || 0; + this._Listener._open_tags[tag]++; +} + +XhtmlParser.prototype._decreaseOpenTagCounter = function(tag) +{ + if(this._Listener._open_tags[tag]){ + this._Listener._open_tags[tag]--; + if(this._Listener._open_tags[tag] == 0){ + this._Listener._open_tags[tag] = undefined; + } + return true; + } + return false; +} + +XhtmlParser.prototype.autoCloseUnclosedBeforeNewOpening = function(new_tag) +{ + this._autoCloseUnclosed(new_tag, false); +} + +XhtmlParser.prototype.autoCloseUnclosedBeforeTagClosing = function(tag) +{ + this._autoCloseUnclosed(tag, true); +} + +XhtmlParser.prototype._autoCloseUnclosed = function(new_tag, closing) +{ + var closing = closing || false; + if(this._Listener._open_tags){ + for (tag in this._Listener._open_tags) { + counter = this._Listener._open_tags[tag]; + if(counter > 0 && this._Listener.shouldCloseTagAutomatically(tag, new_tag, closing)){ + this._callCloseTagListener(tag, true); + } + } + } +} + +XhtmlParser.prototype.getTagReplacements = function() +{ + return this._Listener.getTagReplacements(); +} + +XhtmlParser.prototype.normalizeTag = function(tag) +{ + tag = tag.replace(/^([\s<\/>]*)|([\s<\/>]*)$/gm,'').toLowerCase(); + tags = this._Listener.getTagReplacements(); + if(tags[tag]){ + return tags[tag]; + } + return tag; +} + +XhtmlParser.prototype.TagAttributes = function(match, state) +{ + if(LEXER_SPECIAL == state){ + this._current_attribute = match; + } + return true; +} + +XhtmlParser.prototype.DoubleQuotedAttribute = function(match, state) +{ + if(LEXER_UNMATCHED == state){ + this._tag_attributes[this._current_attribute] = match; + } + return true; +} +XhtmlParser.prototype.SingleQuotedAttribute = function(match, state) +{ + if(LEXER_UNMATCHED == state){ + this._tag_attributes[this._current_attribute] = match; + } + return true; +} +XhtmlParser.prototype.UnquotedAttribute = function(match, state) +{ + this._tag_attributes[this._current_attribute] = match.replace(/^=/,''); + return true; +} + + + +/** +* XHTML Sax parser. +* +* @author Bermi Ferrer (http://bermi.org) +*/ +function XhtmlSaxListener() +{ + this.output = ''; + this.helper = new XmlHelper(); + this._open_tags = {}; + this.validator = XhtmlValidator; + this._tag_stack = []; + this.avoided_tags = []; + + this.entities = { + ' ':' ','¡':'¡','¢':'¢', + '£':'£','¤':'¤','¥':'¥', + '¦':'¦','§':'§','¨':'¨', + '©':'©','ª':'ª','«':'«', + '¬':'¬','­':'­','®':'®', + '¯':'¯','°':'°','±':'±', + '²':'²','³':'³','´':'´', + 'µ':'µ','¶':'¶','·':'·', + '¸':'¸','¹':'¹','º':'º', + '»':'»','¼':'¼','½':'½', + '¾':'¾','¿':'¿','À':'À', + 'Á':'Á','Â':'Â','Ã':'Ã', + 'Ä':'Ä','Å':'Å','Æ':'Æ', + 'Ç':'Ç','È':'È','É':'É', + 'Ê':'Ê','Ë':'Ë','Ì':'Ì', + 'Í':'Í','Î':'Î','Ï':'Ï', + 'Ð':'Ð','Ñ':'Ñ','Ò':'Ò', + 'Ó':'Ó','Ô':'Ô','Õ':'Õ', + 'Ö':'Ö','×':'×','Ø':'Ø', + 'Ù':'Ù','Ú':'Ú','Û':'Û', + 'Ü':'Ü','Ý':'Ý','Þ':'Þ', + 'ß':'ß','à':'à','á':'á', + 'â':'â','ã':'ã','ä':'ä', + 'å':'å','æ':'æ','ç':'ç', + 'è':'è','é':'é','ê':'ê', + 'ë':'ë','ì':'ì','í':'í', + 'î':'î','ï':'ï','ð':'ð', + 'ñ':'ñ','ò':'ò','ó':'ó', + 'ô':'ô','õ':'õ','ö':'ö', + '÷':'÷','ø':'ø','ù':'ù', + 'ú':'ú','û':'û','ü':'ü', + 'ý':'ý','þ':'þ','ÿ':'ÿ', + 'Œ':'Œ','œ':'œ','Š':'Š', + 'š':'š','Ÿ':'Ÿ','ƒ':'ƒ', + 'ˆ':'ˆ','˜':'˜','Α':'Α', + 'Β':'Β','Γ':'Γ','Δ':'Δ', + 'Ε':'Ε','Ζ':'Ζ','Η':'Η', + 'Θ':'Θ','Ι':'Ι','Κ':'Κ', + 'Λ':'Λ','Μ':'Μ','Ν':'Ν', + 'Ξ':'Ξ','Ο':'Ο','Π':'Π', + 'Ρ':'Ρ','Σ':'Σ','Τ':'Τ', + 'Υ':'Υ','Φ':'Φ','Χ':'Χ', + 'Ψ':'Ψ','Ω':'Ω','α':'α', + 'β':'β','γ':'γ','δ':'δ', + 'ε':'ε','ζ':'ζ','η':'η', + 'θ':'θ','ι':'ι','κ':'κ', + 'λ':'λ','μ':'μ','ν':'ν', + 'ξ':'ξ','ο':'ο','π':'π', + 'ρ':'ρ','ς':'ς','σ':'σ', + 'τ':'τ','υ':'υ','φ':'φ', + 'χ':'χ','ψ':'ψ','ω':'ω', + 'ϑ':'ϑ','ϒ':'ϒ','ϖ':'ϖ', + ' ':' ',' ':' ',' ':' ', + '‌':'‌','‍':'‍','‎':'‎', + '‏':'‏','–':'–','—':'—', + '‘':'‘','’':'’','‚':'‚', + '“':'“','”':'”','„':'„', + '†':'†','‡':'‡','•':'•', + '…':'…','‰':'‰','′':'′', + '″':'″','‹':'‹','›':'›', + '‾':'‾','⁄':'⁄','€':'€', + 'ℑ':'ℑ','℘':'℘','ℜ':'ℜ', + '™':'™','ℵ':'ℵ','←':'←', + '↑':'↑','→':'→','↓':'↓', + '↔':'↔','↵':'↵','⇐':'⇐', + '⇑':'⇑','⇒':'⇒','⇓':'⇓', + '⇔':'⇔','∀':'∀','∂':'∂', + '∃':'∃','∅':'∅','∇':'∇', + '∈':'∈','∉':'∉','∋':'∋', + '∏':'∏','∑':'∑','−':'−', + '∗':'∗','√':'√','∝':'∝', + '∞':'∞','∠':'∠','∧':'∧', + '∨':'∨','∩':'∩','∪':'∪', + '∫':'∫','∴':'∴','∼':'∼', + '≅':'≅','≈':'≈','≠':'≠', + '≡':'≡','≤':'≤','≥':'≥', + '⊂':'⊂','⊃':'⊃','⊄':'⊄', + '⊆':'⊆','⊇':'⊇','⊕':'⊕', + '⊗':'⊗','⊥':'⊥','⋅':'⋅', + '⌈':'⌈','⌉':'⌉','⌊':'⌊', + '⌋':'⌋','⟨':'〈','⟩':'〉', + '◊':'◊','♠':'♠','♣':'♣', + '♥':'♥','♦':'♦'}; + + this.block_tags = ["a", "abbr", "acronym", "address", "area", "b", + "base", "bdo", "big", "blockquote", "body", "button", + "caption", "cite", "code", "col", "colgroup", "dd", "del", "div", + "dfn", "dl", "dt", "em", "fieldset", "form", "head", "h1", "h2", + "h3", "h4", "h5", "h6", "html", "i", "ins", + "kbd", "label", "legend", "li", "map", "noscript", + "object", "ol", "optgroup", "option", "p", "param", "pre", "q", + "samp", "script", "select", "small", "span", "strong", "style", + "sub", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", + "thead", "title", "tr", "tt", "ul", "var", "extends"]; + + + this.inline_tags = ["br", "hr", "img", "input"]; + + return this; +} + +XhtmlSaxListener.prototype.shouldCloseTagAutomatically = function(tag, now_on_tag, closing) +{ + var closing = closing || false; + if(tag == 'td'){ + if((closing && now_on_tag == 'tr') || (!closing && now_on_tag == 'td')){ + return true; + } + } + if(tag == 'option'){ + if((closing && now_on_tag == 'select') || (!closing && now_on_tag == 'option')){ + return true; + } + } + return false; +} + +XhtmlSaxListener.prototype.beforeParsing = function(raw) +{ + this.output = ''; + return raw; +} + +XhtmlSaxListener.prototype.afterParsing = function(xhtml) +{ + xhtml = this.replaceNamedEntities(xhtml); + xhtml = this.joinRepeatedEntities(xhtml); + xhtml = this.removeEmptyTags(xhtml); + return xhtml; +} + +XhtmlSaxListener.prototype.replaceNamedEntities = function(xhtml) +{ + for (entity in this.entities) { + xhtml = xhtml.replace(entity, this.entities[entity]); + } + return xhtml; +} + +XhtmlSaxListener.prototype.joinRepeatedEntities = function(xhtml) +{ + var tags = 'em|strong|sub|sup|acronym|pre|del|blockquote|address'; + return xhtml.replace(new RegExp('<\/('+tags+')><\\1>' ,''),''). + replace(new RegExp('(\s*<('+tags+')>\s*){2}(.*)(\s*<\/\\2>\s*){2}' ,''),'<\$2>\$3<\$2>'); +} + +XhtmlSaxListener.prototype.removeEmptyTags = function(xhtml) +{ + return xhtml.replace(new RegExp('<('+this.block_tags.join("|")+')>(
      | | |\s)*<\/\\1>' ,'g'),''); +} + +XhtmlSaxListener.prototype.getResult = function() +{ + return this.output; +} + +XhtmlSaxListener.prototype.getTagReplacements = function() +{ + return {'b':'strong', 'i':'em'}; +} + +XhtmlSaxListener.prototype.addContent = function(text) +{ + this.output += text; +} + +XhtmlSaxListener.prototype.addComment = function(text) +{ + if(this.remove_comments){ + this.output += text; + } +} + +XhtmlSaxListener.prototype.addScript = function(text) +{ + if(!this.remove_scripts){ + this.output += text; + } +} + +XhtmlSaxListener.prototype.addCss = function(text) +{ + if(!this.remove_embeded_styles){ + this.output += text; + } +} +XhtmlSaxListener.prototype.openBlockTag = function(tag, attributes) +{ + this.output += this.helper.tag(tag, this.validator.getValidTagAttributes(tag, attributes), true); +} + +XhtmlSaxListener.prototype.inlineTag = function(tag, attributes) +{ + this.output += this.helper.tag(tag, this.validator.getValidTagAttributes(tag, attributes)); +} + +XhtmlSaxListener.prototype.openUnknownTag = function(tag, attributes) +{ + //this.output += this.helper.tag(tag, attributes, true); +} + +XhtmlSaxListener.prototype.closeBlockTag = function(tag) +{ + this.output += this._getClosingTagContent('before', tag)+""+this._getClosingTagContent('after', tag); +}; + +XhtmlSaxListener.prototype.closeUnknownTag = function(tag) +{ + //this.output += ""; +} + +XhtmlSaxListener.prototype.closeUnopenedTag = function(tag) +{ + this.output += ""; +} + +XhtmlSaxListener.prototype.avoidStylingTagsAndAttributes = function() +{ + this.avoided_tags = ['div','span']; + this.validator.skiped_attributes = ['style']; + this.validator.skiped_attribute_values = ['MsoNormal','main1']; // MS Word attributes for class + this._avoiding_tags_implicitly = true; +} + +XhtmlSaxListener.prototype.allowStylingTagsAndAttributes = function() +{ + this.avoided_tags = []; + this.validator.skiped_attributes = []; + this.validator.skiped_attribute_values = []; + this._avoiding_tags_implicitly = false; +} + +XhtmlSaxListener.prototype.isBlockTag = function(tag) +{ + return !this.avoided_tags.contains(tag) && this.block_tags.contains(tag); +} + +XhtmlSaxListener.prototype.isInlineTag = function(tag) +{ + return !this.avoided_tags.contains(tag) && this.inline_tags.contains(tag); +} + +XhtmlSaxListener.prototype.insertContentAfterClosingTag = function(tag, content) +{ + this._insertContentWhenClosingTag('after', tag, content); +}; + +XhtmlSaxListener.prototype.insertContentBeforeClosingTag = function(tag, content) +{ + this._insertContentWhenClosingTag('before', tag, content); +}; + +XhtmlSaxListener.prototype._insertContentWhenClosingTag = function(position, tag, content) +{ + if(!this['_insert_'+position+'_closing']){ + this['_insert_'+position+'_closing'] = []; + } + if(!this['_insert_'+position+'_closing'][tag]){ + this['_insert_'+position+'_closing'][tag] = []; + } + this['_insert_'+position+'_closing'][tag].push(content); +}; + +XhtmlSaxListener.prototype._getClosingTagContent = function(position, tag) +{ + if( this['_insert_'+position+'_closing'] && + this['_insert_'+position+'_closing'][tag] && + this['_insert_'+position+'_closing'][tag].length > 0){ + return this['_insert_'+position+'_closing'][tag].pop(); + } + return ''; +}; Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-blockquote.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-blockquote.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h1.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h1.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h2.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h2.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h3.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h3.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h4.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h4.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h5.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h5.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h6.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-h6.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-p.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-p.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-pre.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/lbl-pre.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/wymiframe.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/wymiframe.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/wymiframe.css 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,89 @@ +/* + * WYMeditor : what you see is What You Mean web-based editor + * Copyright (C) 2007 H.O.net - http://www.honet.be/ + * Dual licensed under the MIT (MIT-license.txt) + * and GPL (GPL-license.txt) licenses. + * + * For further information visit: + * http://www.wymeditor.org/ + * + * File Name: + * wymeditor.css + * Main editor css file. + * See the documentation for more info. + * + * File Authors: + * Jean-Francois Hovinne (jf.hovinne@wymeditor.org) + * Daniel Reszka (d.reszka@wymeditor.org) +*/ + +/* VISUAL FEEDBACK */ + +/* basic */ + body { background: #e1e8f1;} + +/* make HTML blocs visible */ + p, + h1, + h2, + h3, + h4, + h5, + h6, + ul, + ol, + table, + blockquote, + pre { background: #FFFFFF no-repeat 2px 2px; + padding:8px 5px 5px; + margin:10px; } + td { background: #F0F4F8; } + th { background: #ffffcc; } + ul, + ol { border-left:20px solid #B9C4D0; padding:0px 5px; } + caption { background: #E4E4B0; padding: 5px; font-weight: bold; } + table { font-size: 12px; width: 500px; } + td { width: 25%; } + blockquote { margin-left: 30px; } + pre { background-color:transparent; border: 1px solid white; } + +/* Gecko min height fix */ + p { min-height: 1em; } /*min-height is needed under Firefox, because empty parargraphs */ + *+html p { min-height: auto; } /* but we have to remove it under IE7 because it triggers the 'haslayout' mode */ + td { height: 1.6em; } + +/* labels */ + p { background-image: url(lbl-p.png); } + h1 { background-image: url(lbl-h1.png); } + h2 { background-image: url(lbl-h2.png); } + h3 { background-image: url(lbl-h3.png); } + h4 { background-image: url(lbl-h4.png); } + h5 { background-image: url(lbl-h5.png); } + h6 { background-image: url(lbl-h6.png); } + blockquote{ background-image: url(lbl-blockquote.png); } + pre { background-image: url(lbl-pre.png); } + +/* specific HTML elements */ + caption { text-align: left; } + img { margin-right: 5px; + border-style: solid; + border-color: gray; + border-width: 0; } + a img { border-width: 1px; border-color: blue; } + acronym { border: 1px solid gray; } + +/* visual feedback for non-valid nesting of elements*/ + h1 h1, h1 h2, h1 h3, h1 h4, h1 h5, h1 h6, h1 p, h1 pre, h1 address, + h2 h1, h2 h2, h2 h3, h2 h4, h2 h5, h2 h6, h2 p, h2 pre, h2 address, + h3 h1, h3 h2, h3 h3, h3 h4, h3 h5, h3 h6, h3 p, h3 pre, h3 address, + h4 h1, h4 h2, h4 h3, h4 h4, h4 h5, h4 h6, h4 p, h4 pre, h4 address, + h5 h1, h5 h2, h5 h3, h5 h4, h5 h5, h5 h6, h5 p, h5 pre, h5 address, + h6 h1, h6 h2, h6 h3, h6 h4, h6 h4, h6 h6, h6 p, h6 pre, h6 address, + p h1, p h2, p h3, p h4, p h5, p h6, p pre, p address, + pre h1, pre h2, pre h3, pre h4, pre h5, pre h6, pre p, pre pre, pre address, + address h1, address h2, address h3, address h4, address h5, address h6, + address p, address pre, address address + { background-color: #ff9999 !important; + border: 1px solid red !important; + font-size: 12px !important; + font-weight: normal; } Index: openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/wymiframe.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/wymiframe.html,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/iframe/default/wymiframe.html 1 Aug 2007 21:39:30 -0000 1.2.2.2 @@ -0,0 +1,25 @@ + + + + +WYMeditor iframe + + + + Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/ca.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/ca.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/ca.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_CA = { + Strong: 'Ressaltar', + Emphasis: 'Emfatitzar', + Superscript: 'Superindex', + Subscript: 'Subindex', + Ordered_List: 'Llistat ordenat', + Unordered_List: 'Llistat sense ordenar', + Indent: 'Indentat', + Outdent: 'Sense indentar', + Undo: 'Desfer', + Redo: 'Refer', + Link: 'Enllaçar', + Unlink: 'Eliminar enllaç', + Image: 'Imatge', + Table: 'Taula', + HTML: 'HTML', + Paragraph: 'Paràgraf', + Heading_1: 'Capçalera 1', + Heading_2: 'Capçalera 2', + Heading_3: 'Capçalera 3', + Heading_4: 'Capçalera 4', + Heading_5: 'Capçalera 5', + Heading_6: 'Capçalera 6', + Preformatted: 'Pre-formatejat', + Blockquote: 'Cita', + Table_Header: 'Capçalera de la taula', + URL: 'URL', + Title: 'Títol', + Alternative_Text: 'Text alternatiu', + Caption: 'Llegenda', + Number_Of_Rows: 'Nombre de files', + Number_Of_Cols: 'Nombre de columnes', + Submit: 'Enviar', + Cancel: 'Cancel·lar', + Choose: 'Triar', + Preview: 'Vista prèvia', + Paste_From_Word: 'Pegar des de Word', + Tools: 'Eines', + Containers: 'Contenidors', + Classes: 'Classes', + Status: 'Estat', + Source_Code: 'Codi font' +}; + +WYM_STRINGS['ca'] = WYM_STRINGS_CA; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/de.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/de.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/de.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_DE = { + Strong: 'Fett', + Emphasis: 'Kursiv', + Superscript: 'Text hochstellen', + Subscript: 'Text tiefstellen', + Ordered_List: 'Geordnete Liste einfügen', + Unordered_List: 'Ungeordnete Liste einfügen', + Indent: 'Einzug erhöhen', + Outdent: 'Einzug vermindern', + Undo: 'Befehle rückgängig machen', + Redo: 'Befehle wiederherstellen', + Link: 'Hyperlink einfügen', + Unlink: 'Hyperlink entfernen', + Image: 'Bild einfügen', + Table: 'Tabelle einfügen', + HTML: 'HTML anzeigen/verstecken', + Paragraph: 'Absatz', + Heading_1: 'Überschrift 1', + Heading_2: 'Überschrift 2', + Heading_3: 'Überschrift 3', + Heading_4: 'Überschrift 4', + Heading_5: 'Überschrift 5', + Heading_6: 'Überschrift 6', + Preformatted: 'Vorformatiert', + Blockquote: 'Zitat', + Table_Header: 'Tabellenüberschrift', + URL: 'URL', + Title: 'Titel', + Alternative_Text: 'Alternativer Text', + Caption: 'Tabellenüberschrift', + Number_Of_Rows: 'Anzahl Zeilen', + Number_Of_Cols: 'Anzahl Spalten', + Submit: 'Absenden', + Cancel: 'Abbrechen', + Choose: 'Auswählen', + Preview: 'Vorschau', + Paste_From_Word: 'Aus Word einfügen', + Tools: 'Werkzeuge', + Containers: 'Inhaltstyp', + Classes: 'Klassen', + Status: 'Status', + Source_Code: 'Quellcode' +}; + +WYM_STRINGS['de'] = WYM_STRINGS_DE; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/en.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/en.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/en.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_EN = { + Strong: 'Strong', + Emphasis: 'Emphasis', + Superscript: 'Superscript', + Subscript: 'Subscript', + Ordered_List: 'Ordered List', + Unordered_List: 'Unordered List', + Indent: 'Indent', + Outdent: 'Outdent', + Undo: 'Undo', + Redo: 'Redo', + Link: 'Link', + Unlink: 'Unlink', + Image: 'Image', + Table: 'Table', + HTML: 'HTML', + Paragraph: 'Paragraph', + Heading_1: 'Heading 1', + Heading_2: 'Heading 2', + Heading_3: 'Heading 3', + Heading_4: 'Heading 4', + Heading_5: 'Heading 5', + Heading_6: 'Heading 6', + Preformatted: 'Preformatted', + Blockquote: 'Blockquote', + Table_Header: 'Table Header', + URL: 'URL', + Title: 'Title', + Alternative_Text: 'Alternative text', + Caption: 'Caption', + Number_Of_Rows: 'Number of rows', + Number_Of_Cols: 'Number of cols', + Submit: 'Submit', + Cancel: 'Cancel', + Choose: 'Choose', + Preview: 'Preview', + Paste_From_Word: 'Paste from Word', + Tools: 'Tools', + Containers: 'Containers', + Classes: 'Classes', + Status: 'Status', + Source_Code: 'Source code' +}; + +WYM_STRINGS['en'] = WYM_STRINGS_EN; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/es.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/es.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/es.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_ES = { + Strong: 'Resaltar', + Emphasis: 'Enfatizar', + Superscript: 'Superindice', + Subscript: 'Subindice', + Ordered_List: 'Lista ordenada', + Unordered_List: 'Lista sin ordenar', + Indent: 'Indentado', + Outdent: 'Sin indentar', + Undo: 'Deshacer', + Redo: 'Rehacer', + Link: 'Enlazar', + Unlink: 'Eliminar enlace', + Image: 'Imagen', + Table: 'Tabla', + HTML: 'HTML', + Paragraph: 'Párrafo', + Heading_1: 'Cabecera 1', + Heading_2: 'Cabecera 2', + Heading_3: 'Cabecera 3', + Heading_4: 'Cabecera 4', + Heading_5: 'Cabecera 5', + Heading_6: 'Cabecera 6', + Preformatted: 'Preformateado', + Blockquote: 'Cita', + Table_Header: 'Cabecera de la tabla', + URL: 'URL', + Title: 'Título', + Alternative_Text: 'Texto alternativo', + Caption: 'Leyenda', + Number_Of_Rows: 'Número de filas', + Number_Of_Cols: 'Número de columnas', + Submit: 'Enviar', + Cancel: 'Cancelar', + Choose: 'Seleccionar', + Preview: 'Vista previa', + Paste_From_Word: 'Pegar desde Word', + Tools: 'Herramientas', + Containers: 'Contenedores', + Classes: 'Clases', + Status: 'Estado', + Source_Code: 'Código fuente' +}; + +WYM_STRINGS['es'] = WYM_STRINGS_ES; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/fr.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/fr.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/fr.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_FR = { + Strong: 'Mise en évidence', + Emphasis: 'Emphase', + Superscript: 'Exposant', + Subscript: 'Indice', + Ordered_List: 'Liste Ordonnée', + Unordered_List: 'Liste Non-Ordonnée', + Indent: 'Imbriqué', + Outdent: 'Non-imbriqué', + Undo: 'Annuler', + Redo: 'Rétablir', + Link: 'Lien', + Unlink: 'Supprimer le Lien', + Image: 'Image', + Table: 'Tableau', + HTML: 'HTML', + Paragraph: 'Paragraphe', + Heading_1: 'Titre 1', + Heading_2: 'Titre 2', + Heading_3: 'Titre 3', + Heading_4: 'Titre 4', + Heading_5: 'Titre 5', + Heading_6: 'Titre 6', + Preformatted: 'Pré-formatté', + Blockquote: 'Citation', + Table_Header: 'Cellule de titre', + URL: 'URL', + Title: 'Titre', + Alternative_Text: 'Texte alternatif', + Caption: 'Légende', + Number_Of_Rows: 'Nombre de lignes', + Number_Of_Cols: 'Nombre de colonnes', + Submit: 'Envoyer', + Cancel: 'Annuler', + Choose: 'Choisir', + Preview: 'Prévisualisation', + Paste_From_Word: 'Copier depuis Word', + Tools: 'Outils', + Containers: 'Type de texte', + Classes: 'Type de contenu', + Status: 'Infos', + Source_Code: 'Code source' +}; + +WYM_STRINGS['fr'] = WYM_STRINGS_FR; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/hu.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/hu.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/hu.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_HU = { + Strong: 'Félkövér', + Emphasis: 'Kiemelt', + Superscript: 'Felső index', + Subscript: 'Alsó index', + Ordered_List: 'Rendezett lista', + Unordered_List: 'Rendezetlen lista', + Indent: 'Bekezdés', + Outdent: 'Bekezdés törlése', + Undo: 'Visszavon', + Redo: 'Visszaállít', + Link: 'Link', + Unlink: 'Link törlése', + Image: 'Kép', + Table: 'Tábla', + HTML: 'HTML', + Paragraph: 'Bekezdés', + Heading_1: 'Címsor 1', + Heading_2: 'Címsor 2', + Heading_3: 'Címsor 3', + Heading_4: 'Címsor 4', + Heading_5: 'Címsor 5', + Heading_6: 'Címsor 6', + Preformatted: 'Előformázott', + Blockquote: 'Idézet', + Table_Header: 'Tábla Fejléc', + URL: 'Webcím', + Title: 'Megnevezés', + Alternative_Text: 'Alternatív szöveg', + Caption: 'Fejléc', + Number_Of_Rows: 'Sorok száma', + Number_Of_Cols: 'Oszlopok száma', + Submit: 'Elküld', + Cancel: 'Mégsem', + Choose: 'Választ', + Preview: 'Előnézet', + Paste_From_Word: 'Másolás Word-ból', + Tools: 'Eszközök', + Containers: 'Tartalmak', + Classes: 'Osztályok', + Status: 'Állapot', + Source_Code: 'Forráskód' +}; + +WYM_STRINGS['hu'] = WYM_STRINGS_HU; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/it.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/it.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/it.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_IT = { + Strong: 'Grassetto', + Emphasis: 'Corsetto', + Superscript: 'Apice', + Subscript: 'Pedice', + Ordered_List: 'Lista Ordinata', + Unordered_List: 'Lista Puntata', + Indent: 'Indenta', + Outdent: 'Caccia', + Undo: 'Indietro', + Redo: 'Avanti', + Link: 'Inserisci Link', + Unlink: 'Togli Link', + Image: 'Inserisci Immagine', + Table: 'Inserisci Tabella', + HTML: 'HTML', + Paragraph: 'Paragrafo', + Heading_1: 'Heading 1', + Heading_2: 'Heading 2', + Heading_3: 'Heading 3', + Heading_4: 'Heading 4', + Heading_5: 'Heading 5', + Heading_6: 'Heading 6', + Preformatted: 'Preformattato', + Blockquote: 'Blockquote', + Table_Header: 'Header Tabella', + URL: 'Indirizzo', + Title: 'Titolo', + Alternative_Text: 'Testo Alternativo', + Caption: 'Caption', + Number_Of_Rows: 'Numero di Righe', + Number_Of_Cols: 'Numero di Colonne', + Submit: 'Invia', + Cancel: 'Cancella', + Choose: 'Scegli', + Preview: 'Anteprima', + Paste_From_Word: 'Incolla', + Tools: 'Tools', + Containers: 'Contenitori', + Classes: 'Classi', + Status: 'Stato', + Source_Code: 'Codice Sorgente' +}; + +WYM_STRINGS['it'] = WYM_STRINGS_IT; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/nl.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/nl.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/nl.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_NL = { + Strong: 'Sterk benadrukken', + Emphasis: 'Benadrukken', + Superscript: 'Bovenschrift', + Subscript: 'Onderschrift', + Ordered_List: 'Geordende lijst', + Unordered_List: 'Ongeordende lijst', + Indent: 'Inspringen', + Outdent: 'Terugspringen', + Undo: 'Ongedaan maken', + Redo: 'Opnieuw uitvoeren', + Link: 'Linken', + Unlink: 'Ontlinken', + Image: 'Afbeelding', + Table: 'Tabel', + HTML: 'HTML', + Paragraph: 'Paragraaf', + Heading_1: 'Hoofding 1', + Heading_2: 'Hoofding 2', + Heading_3: 'Hoofding 3', + Heading_4: 'Hoofding 4', + Heading_5: 'Hoofding 5', + Heading_6: 'Hoofding 6', + Preformatted: 'Voorgeformatteerd', + Blockquote: 'Aanhaling', + Table_Header: 'Tabel hoofding', + URL: 'URL', + Title: 'Titel', + Alternative_Text: 'Alternatieve tekst', + Caption: 'Bijschrift', + Number_Of_Rows: 'Aantal rijen', + Number_Of_Cols: 'Aantal kolommen', + Submit: 'Versturen', + Cancel: 'Annuleren', + Choose: 'Kiezen', + Preview: 'Voorbeeld bekijken', + Paste_From_Word: 'Plakken uit Word', + Tools: 'Tools', + Containers: 'Containers', + Classes: 'Classes', + Status: 'Status', + Source_Code: 'Broncode' +}; + +WYM_STRINGS['nl'] = WYM_STRINGS_NL; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/pl.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/pl.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/pl.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_PL = { + Strong: 'Nacisk', + Emphasis: 'Emfaza', + Superscript: 'Indeks górny', + Subscript: 'Indeks dolny', + Ordered_List: 'Lista numerowana', + Unordered_List: 'Lista wypunktowana', + Indent: 'Zwiększ wcięcie', + Outdent: 'Zmniejsz wcięcie', + Undo: 'Cofnij', + Redo: 'Ponów', + Link: 'Wstaw link', + Unlink: 'Usuń link', + Image: 'Obraz', + Table: 'Tabela', + HTML: 'Źródło HTML', + Paragraph: 'Akapit', + Heading_1: 'Nagłówek 1', + Heading_2: 'Nagłówek 2', + Heading_3: 'Nagłówek 3', + Heading_4: 'Nagłówek 4', + Heading_5: 'Nagłówek 5', + Heading_6: 'Nagłówek 6', + Preformatted: 'Preformatowany', + Blockquote: 'Cytat blokowy', + Table_Header: 'Nagłówek tabeli', + URL: 'URL', + Title: 'Tytuł', + Alternative_Text: 'Tekst alternatywny', + Caption: 'Tytuł tabeli', + Number_Of_Rows: 'Liczba wierszy', + Number_Of_Cols: 'Liczba kolumn', + Submit: 'Wyślij', + Cancel: 'Anuluj', + Choose: 'Wybierz', + Preview: 'Podgląd', + Paste_From_Word: 'Wklej z Worda', + Tools: 'Narzędzia', + Containers: 'Format', + Classes: 'Styl', + Status: 'Status', + Source_Code: 'Kod źródłowy' +}; + +WYM_STRINGS['pl'] = WYM_STRINGS_PL; Index: openacs-4/packages/xowiki/www/resources/wymeditor/lang/sv.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/lang/sv.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/lang/sv.js 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,47 @@ +if(!WYM_STRINGS) var WYM_STRINGS = new Array(); + +var WYM_STRINGS_SV = { + Strong: 'Viktigt', + Emphasis: 'Betoning', + Superscript: 'Upphöjt', + Subscript: 'Nedsänkt', + Ordered_List: 'Nummerlista', + Unordered_List: 'Punktlista', + Indent: 'Indrag', + Outdent: 'Utdrag', + Undo: 'Ångra', + Redo: 'Gör om', + Link: 'Länk', + Unlink: 'Ta bort länk', + Image: 'Bild', + Table: 'Tabell', + HTML: 'HTML', + Paragraph: 'Paragraf', + Heading_1: 'Rubrik 1', + Heading_2: 'Rubrik 2', + Heading_3: 'Rubrik 3', + Heading_4: 'Rubrik 4', + Heading_5: 'Rubrik 5', + Heading_6: 'Rubrik 6', + Preformatted: 'Förformaterad', + Blockquote: 'Blockcitat', + Table_Header: 'Tabellrubrik', + URL: 'URL', + Title: 'Titel', + Alternative_Text: 'Alternativ text', + Caption: 'Överskrift', + Number_Of_Rows: 'Antal rader', + Number_Of_Cols: 'Antal kolumner', + Submit: 'Skicka', + Cancel: 'Avbryt', + Choose: 'Välj', + Preview: 'Förhandsgranska', + Paste_From_Word: 'Klistra in från Word', + Tools: 'Verktyg', + Containers: 'Formatering', + Classes: 'Klasser', + Status: 'Status', + Source_Code: 'Källkod' +}; + +WYM_STRINGS['sv'] = WYM_STRINGS_SV; Index: openacs-4/packages/xowiki/www/resources/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js 1 Aug 2007 21:39:30 -0000 1.2.2.2 @@ -0,0 +1,57 @@ +/* + * WYMeditor : what you see is What You Mean web-based editor + * Copyright (C) 2007 H.O.net - http://www.honet.be/ + * Dual licensed under the MIT (MIT-license.txt) + * and GPL (GPL-license.txt) licenses. + * + * For further information visit: + * http://www.wymeditor.org/ + * + * File Name: + * jquery.wymeditor.hovertools.js + * hovertools plugin for WYMeditor + * + * File Authors: + * Jean-Francois Hovinne (jf.hovinne@wymeditor.org) + */ + +//Extend WYMeditor +Wymeditor.prototype.hovertools = function() { + + var wym = this; + + //bind events on buttons + jQuery(this._box).find(this._options.toolSelector).hover( + function() { + wym.status(jQuery(this).html()); + }, + function() { + wym.status(' '); + } + ); + + //classes: add/remove a style attr to matching elems + //while mouseover/mouseout + jQuery(this._box).find(this._options.classSelector).hover( + function() { + var aClasses = eval(wym._options.classesItems); + var sName = jQuery(this).attr(WYM_NAME); + var oClass = aClasses.findByName(sName); + + if(oClass){ + jqexpr = oClass.expr; + //don't use jQuery.find() on the iframe body + //because of MSIE + jQuery + expando issue (#JQ1143) + if(!jQuery.browser.msie) + jQuery(wym._doc).find(jqexpr).css('background-color','#cfc'); + } + }, + function() { + //don't use jQuery.find() on the iframe body + //because of MSIE + jQuery + expando issue (#JQ1143) + if(!jQuery.browser.msie) + jQuery(wym._doc).find('*').removeAttr('style'); + } + ); + +}; Index: openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/README =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/README,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/README 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,19 @@ +WYMeditor : what you see is What You Mean web-based editor +Copyright (C) 2007 H.O.net - http://www.honet.be/ +Dual licensed under the MIT (MIT-license.txt) +and GPL (GPL-license.txt) licenses. + +For further information visit: + http://www.wymeditor.org/ + +File Name: + README - HTML Tidy plugin for WYMeditor + +File Authors: + Jean-François Hovinne (jf.hovinne@wymeditor.org) + +Credits: + 'HTML Tidy' by Dave Ragget - http://tidy.sourceforge.net/ + Icon 'wand' by Mark James - http://famfamfam.com/ + +WYMeditor documentation is available online at http://www.wymeditor.org/ Index: openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js 1 Aug 2007 21:39:30 -0000 1.2.2.2 @@ -0,0 +1,82 @@ +/* + * WYMeditor : what you see is What You Mean web-based editor + * Copyright (C) 2007 H.O.net - http://www.honet.be/ + * Dual licensed under the MIT (MIT-license.txt) + * and GPL (GPL-license.txt) licenses. + * + * For further information visit: + * http://www.wymeditor.org/ + * + * File Name: + * jquery.wymeditor.tidy.js + * HTML Tidy plugin for WYMeditor + * + * File Authors: + * Jean-Francois Hovinne (jf.hovinne@wymeditor.org) + */ + +//Extend WYMeditor +Wymeditor.prototype.tidy = function(options) { + var tidy = new WymTidy(options, this); + return(tidy); +}; + +//WymTidy constructor +function WymTidy(options, wym) { + + options = jQuery.extend({ + + sUrl: "wymeditor/plugins/tidy/tidy.php", + sButtonHtml: "
    • " + + "" + + "Clean up HTML" + + "
    • ", + + sButtonSelector: "li.wym_tools_tidy a" + + }, options); + + this._options = options; + this._wym = wym; + +}; + +//WymTidy initialization +WymTidy.prototype.init = function() { + + var tidy = this; + + jQuery(this._wym._box).find( + this._wym._options.toolsSelector + this._wym._options.toolsListSelector) + .append(this._options.sButtonHtml); + + //handle click event + jQuery(this._wym._box).find(this._options.sButtonSelector).click(function() { + tidy.cleanup(); + return(false); + }); + +}; + +//WymTidy cleanup +WymTidy.prototype.cleanup = function() { + + var wym = this._wym; + var html = "" + wym.xhtml() + ""; + + jQuery.post(this._options.sUrl, { html: html}, function(data) { + + if(data.length > 0 && data != '0') { + if(data.indexOf(" 0) { + + // Specify configuration + $config = array( + 'bare' => true, + 'clean' => true, + 'doctype' => 'strict', + 'drop-empty-paras' => true, + 'drop-font-tags' => true, + 'drop-proprietary-attributes' => true, + 'enclose-block-text' => true, + 'indent' => false, + 'join-classes' => true, + 'join-styles' => true, + 'logical-emphasis' => true, + 'output-xhtml' => true, + 'show-body-only' => true, + 'wrap' => 0); + + // Tidy + $tidy = new tidy; + $tidy->parseString($html, $config, 'utf8'); + $tidy->cleanRepair(); + + // Output + echo $tidy; +} else { + +echo ('0'); +} +?> Index: openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/wand.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/plugins/tidy/wand.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/skins/default/icons.png =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/skins/default/icons.png,v diff -u -N -r1.1.2.1 -r1.1.2.2 Binary files differ Index: openacs-4/packages/xowiki/www/resources/wymeditor/skins/default/screen.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wymeditor/skins/default/screen.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wymeditor/skins/default/screen.css 1 Aug 2007 21:39:30 -0000 1.1.2.2 @@ -0,0 +1,131 @@ +/* + * WYMeditor : what you see is What You Mean web-based editor + * Copyright (C) 2007 H.O.net - http://www.honet.be/ + * Dual licensed under the MIT (MIT-license.txt) + * and GPL (GPL-license.txt) licenses. + * + * For further information visit: + * http://www.wymeditor.org/ + * + * File Name: + * screen.css + * main stylesheet for the default WYMeditor skin + * See the documentation for more info. + * + * File Authors: + * Daniel Reszka (d.reszka@wymeditor.org) +*/ + +/*TRYING TO RESET STYLES THAT MAY INTERFERE WITH WYMEDITOR*/ + .wym_skin_default p, .wym_skin_default h2, .wym_skin_default h3, + .wym_skin_default ul, .wym_skin_default li { background: transparent url(); margin: 0; padding: 0; border-width:0; list-style: none; } + + +/*HIDDEN BY DEFAULT*/ + .wym_skin_default .wym_area_left, + .wym_skin_default .wym_area_right { display: none; } + + +/*TYPO*/ + .wym_skin_default { font-size: 62.5%; font-family: Verdana, Arial, sans-serif; } + .wym_skin_default h2 { font-size: 110%; /* = 11px */} + .wym_skin_default h3 { font-size: 100%; /* = 10px */} + .wym_skin_default li { font-size: 100%; /* = 10px */} + + +/*WYM_BOX*/ + .wym_skin_default { border: 1px solid gray; background: #f2f2f2; padding: 5px} + + /*auto-clear the wym_box*/ + .wym_skin_default:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } + * html .wym_skin_default { height: 1%;} + + +/*WYM_HTML*/ + .wym_skin_default .wym_html { width: 98%;} + .wym_skin_default .wym_html textarea { width: 100%; height: 200px; border: 1px solid gray; background: white; } + + +/*WYM_IFRAME*/ + .wym_skin_default .wym_iframe { width: 98%;} + .wym_skin_default .wym_iframe iframe { width: 100%; height: 200px; border: 1px solid gray; background: white } + + +/*AREAS*/ + .wym_skin_default .wym_area_left { width: 150px; float: left;} + .wym_skin_default .wym_area_right { width: 150px; float: right;} + .wym_skin_default .wym_area_bottom { clear: both;} + * html .wym_skin_default .wym_area_main { height: 1%;} + * html .wym_skin_default .wym_area_top { height: 1%;} + *+html .wym_skin_default .wym_area_top { height: 1%;} + +/*SECTIONS SYSTEM*/ + + /*common defaults for all sections*/ + .wym_skin_default .wym_section { margin-bottom: 5px; } + .wym_skin_default .wym_section h2, + .wym_skin_default .wym_section h3 { padding: 1px 3px; margin: 0; } + .wym_skin_default .wym_section a { padding: 0 3px; display: block; text-decoration: none; color: black; } + .wym_skin_default .wym_section a:hover { background-color: yellow; } + /*hide section titles by default*/ + .wym_skin_default .wym_section h2 { display: none; } + /*disable any margin-collapse*/ + .wym_skin_default .wym_section { padding-top: 1px; padding-bottom: 1px; } + /*auto-clear sections*/ + .wym_skin_default .wym_section ul:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } + * html .wym_skin_default .wym_section ul { height: 1%;} + + /*option: add this class to a section to make it render as a panel*/ + .wym_skin_default .wym_panel { } + .wym_skin_default .wym_panel h2 { display: block; } + + /*option: add this class to a section to make it render as a dropdown menu*/ + .wym_skin_default .wym_dropdown h2 { display: block; } + .wym_skin_default .wym_dropdown ul { display: none; position: absolute; background: white; } + .wym_skin_default .wym_dropdown:hover ul, + .wym_skin_default .wym_dropdown.hover ul { display: block; } + + /*option: add this class to a section to make its elements render buttons (icons are only available for the wym_tools section for now)*/ + .wym_skin_default .wym_buttons li { float:left;} + .wym_skin_default .wym_buttons a { width: 20px; height: 20px; overflow: hidden; padding: 2px } + /*image replacements*/ + .wym_skin_default .wym_buttons li a { background: url(icons.png) no-repeat; text-indent: -9999px;} + .wym_skin_default .wym_buttons li.wym_tools_strong a { background-position: 0 -382px;} + .wym_skin_default .wym_buttons li.wym_tools_emphasis a { background-position: 0 -22px;} + .wym_skin_default .wym_buttons li.wym_tools_superscript a { background-position: 0 -430px;} + .wym_skin_default .wym_buttons li.wym_tools_subscript a { background-position: 0 -454px;} + .wym_skin_default .wym_buttons li.wym_tools_ordered_list a { background-position: 0 -48px;} + .wym_skin_default .wym_buttons li.wym_tools_unordered_list a{ background-position: 0 -72px;} + .wym_skin_default .wym_buttons li.wym_tools_indent a { background-position: 0 -574px;} + .wym_skin_default .wym_buttons li.wym_tools_outdent a { background-position: 0 -598px;} + .wym_skin_default .wym_buttons li.wym_tools_undo a { background-position: 0 -502px;} + .wym_skin_default .wym_buttons li.wym_tools_redo a { background-position: 0 -526px;} + .wym_skin_default .wym_buttons li.wym_tools_link a { background-position: 0 -96px;} + .wym_skin_default .wym_buttons li.wym_tools_unlink a { background-position: 0 -168px;} + .wym_skin_default .wym_buttons li.wym_tools_image a { background-position: 0 -121px;} + .wym_skin_default .wym_buttons li.wym_tools_table a { background-position: 0 -144px;} + .wym_skin_default .wym_buttons li.wym_tools_paste a { background-position: 0 -552px;} + .wym_skin_default .wym_buttons li.wym_tools_html a { background-position: 0 -193px;} + .wym_skin_default .wym_buttons li.wym_tools_preview a { background-position: 0 -408px;} + +/*DECORATION*/ + .wym_skin_default .wym_section h2 { background: #ddd; border: solid gray; border-width: 0 0 1px;} + .wym_skin_default .wym_section h2 span { color: gray;} + .wym_skin_default .wym_panel { padding: 0; border: solid gray; border-width: 1px; background: white;} + .wym_skin_default .wym_panel ul { margin: 2px 0 5px; } + .wym_skin_default .wym_dropdown { padding: 0; border: solid gray; border-width: 1px 1px 0 1px; } + .wym_skin_default .wym_dropdown ul { border: solid gray; border-width: 0 1px 1px 1px; margin-left: -1px; padding: 5px 10px 5px 3px;} + +/*DIALOGS*/ + .wym_dialog div.row { margin-bottom: 5px;} + .wym_dialog div.row input { margin-right: 5px;} + .wym_dialog div.row label { float: left; width: 150px; display: block; text-align: right; margin-right: 10px; } + .wym_dialog div.row-indent { padding-left: 160px; } + /*autoclearing*/ + .wym_dialog div.row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } + .wym_dialog div.row { display: inline-block; } + /* Hides from IE-mac \*/ + * html .wym_dialog div.row { height: 1%; } + .wym_dialog div.row { display: block; } + /* End hide from IE-mac */ + Index: openacs-4/packages/xowiki/www/xinha/Makefile =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/Makefile,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/Makefile 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1,14 @@ +FILES = *.adp *.tcl blank.html + +SOURCE = /usr/local/openacs-4/packages/acs-templating/www/resources/xinha-nightly/plugins/OacsFs/popups/ + +unlink: + rm -f ${FILES} + cp -p ${SOURCE}/*.html . + cp -p ${SOURCE}/*.adp . + cp -p ${SOURCE}/*.tcl . + +link: + ln -sf ${SOURCE}/*.html . + ln -sf ${SOURCE}/*.adp . + ln -sf ${SOURCE}/*.tcl . Index: openacs-4/packages/xowiki/www/xinha/attach-file.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/attach-file.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/attach-file.adp 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1,285 @@ + + + #acs-templating.HTMLArea_InsertImageTitle# + + + + + + + + + + + + +
      #acs-templating.HTMLArea_InsertImageTitle# URL click here
      + + +
      #acs-templating.HTMLArea_InsertImageTitle# Upload click here
      +
      + + + + + + + + +
      + +
      + @HTML_UploadTitle@ + + + + + + + + + +
      + + + + + + +
      @formerror.upload_file@
      +

      + #acs-templating.This_image_can_be_reused_by#
      + + @formgroup.widget;noquote@ @formgroup.label@ +
      + [i] + #acs-templating.This_image_can_be_reused_help# + +
      @formerror.share@
      +
      +
      +   +
      +
      +
      +
      +
      +
      +
      + + + Index: openacs-4/packages/xowiki/www/xinha/attach-file.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/attach-file.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/attach-file.tcl 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1,145 @@ +ad_page_contract { + Simple image upload, attach image to object_id passed in, if no + object_id, use the current package_id + @author Guenter Ernst guenter.ernst@wu-wien.ac.at, + @author Gustaf Neumann neumann@wu-wien.ac.at + @author Dave Bauer (dave@solutiongrove.com) + @creation-date 13.07.2004 + @cvs-id $Id: attach-file.tcl,v 1.1.2.2 2007/08/01 21:39:31 gustafn Exp $ +} { + {parent_id:integer} + {selector_type "image"} +} + +set f_url "" + +set user_id [ad_conn user_id] +# if user has write permission, create image upload form, +if {[permission::permission_p -party_id $user_id -object_id $parent_id \ + -privilege "write"]} { + + set write_p 1 + + # FIXME DAVEB i18n for share_options + set share_options [list [list "[_ acs-templating.Only_myself]" private] [list "[_ acs-templating.This_Group]" group] [list "[_ acs-templating.Anyone_on_this_system]" site] [list "[_ acs-templating.Anyone_on_the_internet]" public]] + ad_form \ + -name upload_form \ + -mode edit \ + -export {selector_type file_types parent_id} \ + -html { enctype multipart/form-data } \ + -form { + item_id:key + {upload_file:file(file) {html {size 30}} } + {share:text(radio),optional {label "[_ acs-templating.This_image_can_be_reused_by]"} {options $share_options} {help_text "[_ acs-templating.This_image_can_be_reused_help]"}} + {ok_btn:text(submit) {label "[_ acs-templating.HTMLArea_SelectUploadBtn]"} + } + } \ + -on_request { + set share site + } \ + -on_submit { + # check file name + if {$upload_file eq ""} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SpecifyUploadFilename] + break + } + + # check quota + # FIXME quota is a good idea, set per-user upload quota?? +# set maximum_folder_size [ad_parameter "MaximumFolderSize"] + +# if { $maximum_folder_size ne "" } { +# set max [ad_parameter "MaximumFolderSize"] +# if { $folder_size+[file size ${upload_file.tmpfile}] > $max } { +# template::form::set_error upload_form upload_file \ + [_ file-storage.out_of_space] + # break + # } + # } + + set file_name [template::util::file::get_property filename $upload_file] + set upload_tmpfile [template::util::file::get_property tmp_filename $upload_file] + set mime_type [template::util::file::get_property mime_type $upload_file] + if {$mime_type eq ""} { + set mime_type [ns_guesstype $file_name] + } + if {$selector_type eq "image" \ + && ![string match "image/*" $mime_type]} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SelectImageUploadNoImage] + break + } + if {[string match "image/*" $mime_type]} { + + image::new \ + -item_id $item_id \ + -name ${item_id}_$file_name \ + -parent_id $parent_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id [ad_conn package_id] + } else { + content::item::new \ + -item_id $item_id \ + -name ${item_id}_$file_name \ + -parent_id $parent_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id [ad_conn package_id] + } + file delete $upload_tmpfile + permission::grant \ + -object_id $item_id \ + -party_id $user_id \ + -privilege admin + + switch -- $share { + private { + permission::set_not_inherit -object_id $item_id + } + group { + # Find the closest application group + # either dotlrn or acs-subsite + + permission::grant \ + -party_id [acs_magic_object "registered_users"] \ + -object_id $item_id \ + -privilege "read" + } + public { + permission::grant \ + -party_id [acs_magic_object "the_public"] \ + -object_id $item_id \ + -privilege "read" + } + site - + default { + permission::grant \ + -party_id [acs_magic_object "registered_users"] \ + -object_id $item_id \ + -privilege "read" + } + + } + if {$share eq "private"} { + # need a private URL that allows viewers of this + # object to see the image + # this isn't totally secure, because of course + # you need to be able to see the image somehow + # but we only allow read on the image if you can + # see the parent object + set f_url "/image/$item_id/private/$file_name" + } else { + set f_url "/image/$item_id/$file_name" + } + } + +} else { + set write_p 0 +} + +set HTML_Preview "Preview" +set HTML_UploadTitle "" \ No newline at end of file Index: openacs-4/packages/xowiki/www/xinha/blank.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/blank.html,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/blank.html 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1 @@ \ No newline at end of file Index: openacs-4/packages/xowiki/www/xinha/file-selector.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/file-selector.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/file-selector.adp 1 Aug 2007 21:39:31 -0000 1.3.2.2 @@ -0,0 +1,170 @@ + + + @HTML_Title@ + + + + + + + + + + +
      @HTML_Title@
      +
      @HTML_Context@
      + +
      + @HTML_Legend@ + + + +
      @folder_name@
      +
      + +
      +
      + + + + + + + + + + + +
      +
      + @HTML_Preview@ + +
      +
      + +
      + @HTML_UploadTitle@ + + + + + + + + + +
      + + + + + + +
      @formerror.upload_file@
      +
      +
      + +
      +
      +
      +
      +
      +
      + + +
      +
      + + + + Index: openacs-4/packages/xowiki/www/xinha/file-selector.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/file-selector.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/file-selector.tcl 1 Aug 2007 21:39:31 -0000 1.9.2.2 @@ -0,0 +1,319 @@ +ad_page_contract { + @author Guenter Ernst guenter.ernst@wu-wien.ac.at + @author Gustaf Neumann neumann@wu-wien.ac.at + @creation-date 13.10.2005 + @cvs-id $Id: file-selector.tcl,v 1.9.2.2 2007/08/01 21:39:31 gustafn Exp $ +} { + {fs_package_id:integer,notnull,optional} + {folder_id:integer,optional} + {orderby:optional} + {selector_type "image"} + {file_types "*"} +} + +if {![info exists fs_package_id]} { + # we have not filestore package_id. This must be the first call. + if {[info exists folder_id]} { + # get package_id from folder_id + foreach {fs_package_id root_folder_id} \ + [fs::get_folder_package_and_root $folder_id] break + } else { + # get package_id from package name + set key file-storage + # get file-storage instance from this subsite + set subsite_node [subsite::get_element -element node_id] + set mount_url [site_node::get_children -package_key $key -node_id $subsite_node] + if { $mount_url eq "" } { + # no file-storage instance at this subsite so look to main site + set subsite_node [subsite::get_element -subsite_id [subsite::main_site_id] -element node_id] + set mount_url [site_node::get_children -package_key file-storage -node_id $subsite_node] + } + if { $mount_url ne "" } { + # file-storage instance IS at main site + array set site_node [site_node::get -url $mount_url] + set fs_package_id $site_node(package_id) + } else { + # look for any file-storage instance + # probably not what user wants; could return error instead + set id [apm_version_id_from_package_key $key] + set mount_url [site_node::get_children -all -package_key $key -node_id $id] + array set site_node [site_node::get -url $mount_url] + set fs_package_id $site_node(package_id) + } + } +} + +if {![info exists folder_id]} { + set folder_id [fs_get_root_folder -package_id $fs_package_id] + set root_folder_id $folder_id +} + +if {![fs_folder_p $folder_id]} { + ad_complain [_ file-storage.lt_The_specified_folder__1] + return +} + +# now we have at least a valid folder_id and a valid fs_package_id +if {![info exists root_folder_id]} { + set root_folder_id [fs_get_root_folder -package_id $fs_package_id] +} + +set fs_url [site_node::get_url_from_object_id -object_id $fs_package_id] + +# # Don't allow delete if root folder +set root_folder_p [expr {$folder_id == $root_folder_id}] + +set user_id [ad_conn user_id] +permission::require_permission \ + -party_id $user_id -object_id $folder_id \ + -privilege "read" + +set up_url {} + +if { !$root_folder_p} { + set parent_folder_id [fs::get_parent -item_id $folder_id] + set up_name [fs::get_object_name -object_id $parent_folder_id] + set up_url [export_vars -base file-selector \ + {fs_package_id {folder_id $parent_folder_id} + selector_type file_types}] +} + + +# if user has write permission, create image upload form, +if {[permission::permission_p -party_id $user_id -object_id $folder_id \ + -privilege "write"]} { + set write_p 1 + ad_form \ + -name upload_form \ + -mode edit \ + -export {fs_package_id folder_id orderby selector_type file_types} \ + -html { enctype multipart/form-data } \ + -form { + {upload_file:file(file) {html {size 30}} } + {ok_btn:text(submit) {label "[_ acs-templating.HTMLArea_SelectUploadBtn]"} + } + } \ + -on_submit { + # check file name + if {$upload_file eq ""} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SpecifyUploadFilename] + break + } + + # check quota + set maximum_folder_size [ad_parameter "MaximumFolderSize"] + + if { $maximum_folder_size ne "" } { + set max [ad_parameter "MaximumFolderSize"] + if { $folder_size+[file size ${upload_file.tmpfile}] > $max } { + template::form::set_error upload_form upload_file \ + [_ file-storage.out_of_space] + break + } + } + + set file_name [template::util::file::get_property filename $upload_file] + set upload_tmpfile [template::util::file::get_property tmp_filename $upload_file] + set mime_type [template::util::file::get_property mime_type $upload_file] + + if {$selector_type eq "image" && ![string match "image/*" $mime_type]} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SelectImageUploadNoImage] + break + } + + set existing_file_id [fs::get_item_id -name $file_name -folder_id $folder_id] + + if {$existing_file_id ne ""} { + # write new revision + fs::add_file \ + -name $file_name \ + -item_id $existing_file_id \ + -parent_id $folder_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id $fs_package_id + } else { + # write file + fs::add_file \ + -name $file_name \ + -parent_id $folder_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id $fs_package_id + } + + } +} else { + set write_p 0 +} + + +# display the contents + +set folder_name [lang::util::localize [fs::get_object_name -object_id $folder_id]] +set content_size_total 0 + +set folder_path [::xo::db::sql::content_item get_path \ + -item_id $folder_id \ + -root_folder_id $root_folder_id] + +# -pass_to_urls {c} + +template::list::create \ + -name contents \ + -multirow contents \ + -pass_properties {fs_package_id selector_type folder_id} \ + -key object_id \ + -html {width 100%}\ + -filters {folder_id {} file_types {} selector_type {} fs_package_id {}} \ + -elements { + name { + label "[_ file-storage.Name]" + display_template { + + + + + + + #file-storage.@contents.type@# + onclick="selectImage('@contents.object_id@','@contents.file_url@','@contents.type@');return false;">@contents.name@ + } + orderby_desc {name desc} + orderby_asc {name asc} + html {nowrap ""} + } + content_size_pretty { + label "[_ file-storage.Size]" + orderby_desc {content_size desc} + orderby_asc {content_size asc} + } + type { + label "[_ file-storage.Type]" + orderby_desc {type desc} + orderby_asc {type asc} + } + last_modified_pretty { + label "[_ file-storage.Last_Modified]" + orderby_desc {last_modified_ansi desc} + orderby_asc {last_modified_ansi asc} + html {nowrap ""} + } + } + +set order_by_clause [expr {[exists_and_not_null orderby] ? + [template::list::orderby_clause -orderby -name contents] : + " order by fs_objects.sort_key, fs_objects.name asc"}] + + +if {$selector_type eq "image"} { + set file_types "image/%" +} +set filter_clause [expr {$file_types eq "*" ? "" : + "and (type like '$file_types' or type = 'folder')" }] + +set fs_sql "select object_id, name, live_revision, type, title, + to_char(last_modified, 'YYYY-MM-DD HH24:MI:SS') as last_modified_ansi, + content_size, url, sort_key, file_upload_name, + case + when :folder_path is null + then fs_objects.name + else :folder_path || '/' || name + end as file_url, + case + when last_modified >= (now() - cast('99999' as interval)) + then 1 + else 0 + end as new_p + from fs_objects + where parent_id = :folder_id + and exists (select 1 + from acs_object_party_privilege_map m + where m.object_id = fs_objects.object_id + and m.party_id = :user_id + and m.privilege = 'read') + $filter_clause + $order_by_clause" + +db_multirow -extend { + icon last_modified_pretty content_size_pretty + properties_link properties_url folder_p title +} contents get_fs_contents $fs_sql { + set last_modified_ansi [lc_time_system_to_conn $last_modified_ansi] + set last_modified_pretty [lc_time_fmt $last_modified_ansi "%x %X"] + set content_size_pretty [lc_numeric $content_size] + + if {$type eq "folder"} { + # append content_size_pretty " [_ file-storage.items]" + set content_size_pretty "" + } else { + append content_size_pretty " [_ file-storage.bytes]" + } + if {$title eq ""} {set title $name} + + set file_upload_name [fs::remove_special_file_system_characters \ + -string $file_upload_name] + + if { $content_size ne "" } { + incr content_size_total $content_size + } + + set name [lang::util::localize $name] + + switch -- $type { + folder { + set folder_p 1 + set icon /resources/file-storage/folder.gif + set file_url [export_vars -base file-selector \ + {fs_package_id {folder_id $object_id} + selector_type file_types}] + } + url { + set folder_p 1 + set icon /resources/url-button.gif + set file_url $fs_url/$url + } + default { + set folder_p 0 + set icon /resources/file-storage/file.gif + set file_url ${fs_url}view/$file_url + } + } + + + # We need to encode the hashes in any i18n message keys (.LRN plays + # this trick on some of its folders). If we don't, the hashes will cause + # the path to be chopped off (by ns_conn url) at the leftmost hash. + regsub -all {\#} $file_url {%23} file_url +} + +set HTML_NothingSelected [_ acs-templating.HTMLArea_SelectImageNothingSelected] +switch $selector_type { + "image" { + set HTML_Title [_ acs-templating.HTMLArea_SelectImageTitle] + set HTML_Legend [_ acs-templating.HTMLArea_SelectImage] + set HTML_Preview [_ acs-templating.HTMLArea_SelectImagePreview] + set HTML_UploadTitle [_ acs-templating.HTMLArea_SelectImageUploadTitle] + set HTML_Context "COMMUNITY NAME" + } + "file" { + set HTML_Title [_ acs-templating.HTMLArea_SelectFileTitle] + set HTML_Legend [_ acs-templating.HTMLArea_SelectFile] + set HTML_Preview [_ acs-templating.HTMLArea_SelectImagePreview] + set HTML_UploadTitle [_ acs-templating.HTMLArea_SelectFileUploadTitle] + set HTML_Context "COMMUNITY NAME" + } +} + + +ad_return_template Index: openacs-4/packages/xowiki/www/xinha/insert-file.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/insert-file.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/insert-file.adp 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1,285 @@ + + + #acs-templating.HTMLArea_InsertImageTitle# + + + + + + + + + + + + +
      #acs-templating.HTMLArea_InsertImageTitle# URL click here
      + + +
      #acs-templating.HTMLArea_InsertImageTitle# Upload click here
      +
      + + + + + + + + +
      + +
      + @HTML_UploadTitle@ + + + + + + + + + +
      + + + + + + +
      @formerror.upload_file@
      +

      + #acs-templating.This_image_can_be_reused_by#
      + + @formgroup.widget;noquote@ @formgroup.label@ +
      + [i] + #acs-templating.This_image_can_be_reused_help# + +
      @formerror.share@
      +
      +
      +   +
      +
      +
      +
      +
      +
      +
      + + + Index: openacs-4/packages/xowiki/www/xinha/insert-file.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/insert-file.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/insert-file.tcl 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1,145 @@ +ad_page_contract { + Simple image upload, attach image to object_id passed in, if no + object_id, use the current package_id + @author Guenter Ernst guenter.ernst@wu-wien.ac.at, + @author Gustaf Neumann neumann@wu-wien.ac.at + @author Dave Bauer (dave@solutiongrove.com) + @creation-date 13.07.2004 + @cvs-id $Id: insert-file.tcl,v 1.1.2.2 2007/08/01 21:39:31 gustafn Exp $ +} { + {parent_id:integer} + {selector_type "image"} +} + +set f_url "" + +set user_id [ad_conn user_id] +# if user has write permission, create image upload form, +if {[permission::permission_p -party_id $user_id -object_id $parent_id \ + -privilege "write"]} { + + set write_p 1 + + # FIXME DAVEB i18n for share_options + set share_options [list [list "[_ acs-templating.Only_myself]" private] [list "[_ acs-templating.This_Group]" group] [list "[_ acs-templating.Anyone_on_this_system]" site] [list "[_ acs-templating.Anyone_on_the_internet]" public]] + ad_form \ + -name upload_form \ + -mode edit \ + -export {selector_type file_types parent_id} \ + -html { enctype multipart/form-data } \ + -form { + item_id:key + {upload_file:file(file) {html {size 30}} } + {share:text(radio),optional {label "[_ acs-templating.This_image_can_be_reused_by]"} {options $share_options} {help_text "[_ acs-templating.This_image_can_be_reused_help]"}} + {ok_btn:text(submit) {label "[_ acs-templating.HTMLArea_SelectUploadBtn]"} + } + } \ + -on_request { + set share site + } \ + -on_submit { + # check file name + if {$upload_file eq ""} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SpecifyUploadFilename] + break + } + + # check quota + # FIXME quota is a good idea, set per-user upload quota?? +# set maximum_folder_size [ad_parameter "MaximumFolderSize"] + +# if { $maximum_folder_size ne "" } { +# set max [ad_parameter "MaximumFolderSize"] +# if { $folder_size+[file size ${upload_file.tmpfile}] > $max } { +# template::form::set_error upload_form upload_file \ + [_ file-storage.out_of_space] + # break + # } + # } + + set file_name [template::util::file::get_property filename $upload_file] + set upload_tmpfile [template::util::file::get_property tmp_filename $upload_file] + set mime_type [template::util::file::get_property mime_type $upload_file] + if {$mime_type eq ""} { + set mime_type [ns_guesstype $file_name] + } + if {$selector_type eq "image" \ + && ![string match "image/*" $mime_type]} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SelectImageUploadNoImage] + break + } + if {[string match "image/*" $mime_type]} { + + image::new \ + -item_id $item_id \ + -name ${item_id}_$file_name \ + -parent_id $parent_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id [ad_conn package_id] + } else { + content::item::new \ + -item_id $item_id \ + -name ${item_id}_$file_name \ + -parent_id $parent_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id [ad_conn package_id] + } + file delete $upload_tmpfile + permission::grant \ + -object_id $item_id \ + -party_id $user_id \ + -privilege admin + + switch -- $share { + private { + permission::set_not_inherit -object_id $item_id + } + group { + # Find the closest application group + # either dotlrn or acs-subsite + + permission::grant \ + -party_id [acs_magic_object "registered_users"] \ + -object_id $item_id \ + -privilege "read" + } + public { + permission::grant \ + -party_id [acs_magic_object "the_public"] \ + -object_id $item_id \ + -privilege "read" + } + site - + default { + permission::grant \ + -party_id [acs_magic_object "registered_users"] \ + -object_id $item_id \ + -privilege "read" + } + + } + if {$share eq "private"} { + # need a private URL that allows viewers of this + # object to see the image + # this isn't totally secure, because of course + # you need to be able to see the image somehow + # but we only allow read on the image if you can + # see the parent object + set f_url "/image/$item_id/private/$file_name" + } else { + set f_url "/image/$item_id/$file_name" + } + } + +} else { + set write_p 0 +} + +set HTML_Preview "Preview" +set HTML_UploadTitle "" \ No newline at end of file Index: openacs-4/packages/xowiki/www/xinha/insert-ilink.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/insert-ilink.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/insert-ilink.adp 1 Aug 2007 21:39:31 -0000 1.1.2.2 @@ -0,0 +1,210 @@ + + + #acs-templating.HTMLArea_InsertModifyLink# + + + + + + + + + + + +
      #acs-templating.HTMLArea_InsertModifyLink#
      +
      +
      + + + + + + + + + + + + + + + +
      URL:
      Title (tooltip):
      Target: + + + + + + #acs-templating.HTMLArea_OpenFileStorage# + + +
        + + +
      + + + +
      + + Index: openacs-4/packages/xowiki/www/xinha/insert-ilink.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/insert-ilink.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/insert-ilink.tcl 1 Aug 2007 21:39:31 -0000 1.4.2.2 @@ -0,0 +1,21 @@ +ad_page_contract { + @author Guenter Ernst guenter.ernst@wu-wien.ac.at, + @author Gustaf Neumann neumann@wu-wien.ac.at + @creation-date 13.07.2004 + @cvs-id $Id: insert-ilink.tcl,v 1.4.2.2 2007/08/01 21:39:31 gustafn Exp $ +} { + {fs_package_id:integer,optional} + {folder_id:integer,optional} + {file_types *} +} + +set selector_type "file" +set file_selector_link [export_vars -base file-selector \ + {fs_package_id folder_id selector_type file_types}] +set fs_found 1 + +#set user_id [ad_verify_and_get_user_id] +#permission::require_permission -party_id $user_id -object_id $fs_package_id \ +# -privilege "admin" + +ad_return_template Index: openacs-4/packages/xowiki/www/xinha/insert-image.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/insert-image.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/insert-image.adp 1 Aug 2007 21:39:31 -0000 1.2.2.2 @@ -0,0 +1,235 @@ + + + #acs-templating.HTMLArea_InsertImageTitle# + + + + + + + + + + + +
      #acs-templating.HTMLArea_InsertImageTitle#
      + +
      + +
      + + + + + + + + + + + + + + +
      #acs-templating.HTMLArea_ImageURL# + +
      #acs-templating.HTMLArea_ImageAlternateText#
      + + + + + #acs-templating.HTMLArea_OpenFileStorage# +
      +
      +

      + + + + + + +
      +
      + Layout + + + + + + + + + + +
      #acs-templating.HTMLArea_ImageAlignment# + +
      #acs-templating.HTMLArea_ImageBorderSize#
      +
      +
      +
      + #acs-templating.HTMLArea_ImageSpacing# + + + + + + + + + + +
      #acs-templating.HTMLArea_ImageSpacingHorizontal#
      #acs-templating.HTMLArea_ImageSpacingVertical#
      +
      +
      + + + + + + + +
      + Image Preview:
      + +
      +
      + +
      +

      + + + Index: openacs-4/packages/xowiki/www/xinha/insert-image.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/xinha/insert-image.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/xinha/insert-image.tcl 1 Aug 2007 21:39:31 -0000 1.4.2.2 @@ -0,0 +1,14 @@ +ad_page_contract { + @author Guenter Ernst guenter.ernst@wu-wien.ac.at, + @author Gustaf Neumann neumann@wu-wien.ac.at + @creation-date 13.07.2004 + @cvs-id $Id: insert-image.tcl,v 1.4.2.2 2007/08/01 21:39:31 gustafn Exp $ +} { + {fs_package_id:integer,optional} + {folder_id:integer,optional} +} + +set selector_type "image" +set file_selector_link [export_vars -base file-selector \ + {fs_package_id folder_id selector_type}] +set fs_found 1