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 13 Sep 2012 16:05:25 -0000 1.4 @@ -0,0 +1,23 @@ + * xowiki + * + * Copyright (C) 2005-2008 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 13 Sep 2012 16:05:26 -0000 1.146 @@ -0,0 +1,126 @@ + + + + + xowiki + xowikis + f + f + f + t + xowiki + + + Gustaf Neumann + A xotcl-based enterprise wiki wiki system with different object types +based on the content OpenACS repository + 2011-05-16 + Gustaf Neumann, WU Wien + <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 wikis (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 13 Sep 2012 16:05:26 -0000 1.42 @@ -0,0 +1,167 @@ + + + + Zusammenfassung + Hinzuf�gen + Verwalten + Alle Arten von %pretty_plural% verwalten + Verwaltungsoptionen f�r dieses Wiki... + vor %time% + Alle Eintr�ge + Zur�ck + von User/in + Kategorien + %errorMsg% + Einstellungen + Inhalt + Kopiere Eintrag + Neuen Eintrag vom Typ %type% erstellen + Erzeuge diese Seite in der folgenden Sprache: + Ersteller/in + Tag + Tage + L�schen + Alle l�schen + Wirklich alles l�schen? + Alle %pretty_plural% dieses Wikis l�schen + Alle Eintr�ge dieser Art l�schen + L�schen best�tigen? + L�sche diese Seite ... + Kurzbeschreibung + Details + Bearbeiten + bearbeiten + Diese Seite bearbeiten ... + Eintr�ge f�r das Formular %form%: + Dieses Formular wird noch von %count% Eintr�gen verwendet. Bitte l�schen Sie diese, bevor Sie das Formular l�schen. + Fehler: Includelet '%page_name%' nicht bekannt + Fehler in Includelet '{{%arg%}}' auf Seite %name%: + Termin + Endzeit + Vortragsende + um + Ort + Beginnzeit + Vortragsbeginn + Titel + Vortragstitel + Exportieren + Kann von hochgeladener Datei �bernommen werden + Wiki File + Wiki Files + Erstelltes Formular + Formular + Einschr�nkungen + Eintr�ge f�r dieses Formular + Eintr�ge f�r dieses Formular + Formular %form_name% + Formular ausf�llen + Workflow %form_name% + Auspr�gungen von %form_name% + Formular ausf�llen + OK + Template + Aktualisiertes Formular + %errorMsg% + Ung�ltiges Formular %errorMsg% + Wiki Forms + Wiki Form + Verfasser/in + URL des Bildes (Sie k�nnen die URL des Bildes, die im Webbrowser angezeigt wird, hier einf�gen) + Name des -zip- oder .tar.gz-Files ausw�hlen + Archiv importieren + Cut&Paste URL eines YouTube-Videos (http://www.youtube.com/....) + Zustand + Wiki Einstellungen + Wiki FormPage + Wiki FormPages + Stunde + Stunden + Importieren + User-IDs erstellen + Falls dieses K�stchen aktiviert ist, werden beim Import gegebenenfalls neue User-IDs erstellt. + Objekte ersetzen + Falls dieses K�stchen aktiviert ist, werden beim Import bereits bestehende Objekte ersetzt. Bei Nicht-Aktivieren wird beim Import eine neue Version des Objekts hinzugef�gt. + Wiki Seiten importieren + Datei f�r Upload ausw�hlen + Besucher/innen + Besuche + Index + Zur Startseite + Eintr�ge + Sprache + Zuletzt besuchte Seiten + Inhaltsverzeichnis der %pretty_plural% + Liste aller Arten von %pretty_plural% + Hinzuf�gen + Inhalt + Kopieren + Kopieren + Export + Archiv importieren + Minute + Minuten + Monat + Monaten + Die h�ufigsten Besucher/innen + Am h�ufigsten besuchte Seiten + Name + Neue Seite + Neue Seite + Neue Seite erstellen ... + Quelle + Kurztext + Benachrichtigungen + Verwalten der Benachrichtigungen... + ung�ltiger numerischer Wert + Wiki Objekt + Wiki Objekte + Abschnitt + Ersteller/in + Kurzbeschreibung + �nderungsdatum + Name + Eindeutige Kurzbezeichnung f�r einen Eintrag im Ordner; enth�lt meist nur Kleinbuchstaben + Sprache + Abschnitt + Ver�ffentlichungsdatum + Inhalt + Titel der Seite + Another item with the name '%value%' exists already in this folder + Art + Typ der Seite + Instanzattribute + Seitenvorlage + Automatische Namensvergabe + 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 + Zuletzt ge�nderte Seiten + Zuletzt ge�nderte Seiten (nach Kategorien) + Verweise auf diese Seite: + Verweise dieser Seite: + Verlauf + �nderungsgeschichte dieser Seite ... + RSS-Klient + Suche + Suche in diesem Wiki... + Sekunde + Sekunden + Abonnieren + Titel + Titel + Ungelesene Seiten + Ansehen + mehr... + Woche + Wochen + Jahr + Jahren + 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 13 Sep 2012 16:05:26 -0000 1.63 @@ -0,0 +1,212 @@ + + + + Abstract + Add + Admin + Administer all kind of %pretty_plural% + Administer this package ... + %time% ago + All items + Back + By User + Categories + %errorMsg% + Configure + Content + Content Type + Copy Entry + Create new entry of type %type% + Create this page in a different language + day + days + Delete + Delete All + Delete really all? + Delete all %pretty_plural% of this instance + Delete all such items of this instances + Confirm delete? + Delete this page ... + Details + Edit + edit tags + Edit this page ... + Entries for form %form% + This page is still used by %count% entries. Please delete these first before deleting this page. + Form constraint contains invalid characters + From field '%name%' (class %class%) 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%: + Event + End Time + End of Lecture + at + Location + Start Time + Start of Lecture + Title + Title of Lecture + Export + Can be obtained from the name of the uploaded file + Wiki File + Wiki Files + Created form + Form + Form Constraints + Entries for this form + Entries for this form + Form %form_name% + Fill out + Workflow %form_name% + Instances of %form_name% + Fill out + OK + Template + Updated form + %errorMsg% + Invalid Form %errorMsg% + Wiki Forms + Wiki Form + Author + HTTP Url of the Image (you might drag an image displayed by a web-browser here) + Select the Name of a .zip or .tar.gz File + Import Archive + Cut&Paste URL of YouTube video (http://www.youtube.com/....) + Assignee + State + Wiki parameters + Wiki FormPage + Wiki FormPages + hour + hours + Import + Create user_ids + If checked, import will create new user_ids if necessary + Replace objects + If checked, import will delete the object if it exists and create it new, otherwise import just adds a revision + Import Wiki Pages + Import file for upload + Visitors + Visits + Index + Go to the start page of this package ... + Instances + Language + Last Visited Pages + Index of %pretty_plural% + List of all kind of %pretty_plural% + Add + Clear + Content + Copy + Copy + Export + Import Archive + Import Dump + minute + minutes + month + months + Most Frequent Visitors + Most Popular Pages + Name + New Page + New Page + Create a new page ... + Source + Teaser + Notifications + Manage notifications ... + Invalid numeric value + Wiki Object + Wiki Objects + Section + Creation User + Creator + Description + Last Modified + Name + Shortname to identify an entry within a folder, typically lowercase characters + Language + Section + Publish Date + Content + Page Title + %errorMsg% + Another item with the name '%value%' exists already in this folder + Page Order invalid; might only contain upper and lower case letters, underscore, digits and dots + Type + XoWiki Page + Wiki Pages + Page Title + Page Type + Instance Attributes + Page Instance + Wiki Page Instance + Wiki Page Instances + Autonamed Entries + Wiki Page Template + Wiki Page Templates + Value is not a valid party_id + Manage Permissions for Wiki: %package_name% + Manage Permissions for Page: %page_name% + Wiki Plain Page + Wiki Plain Pages + 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 + Podcast Item + Podcast Items + Popular tags + popular tags + There is no page with name "%page_name%" available. + The given page does not exist + 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. + Wiki + Published + Recently Changed Pages + Recently Changed Pages (by categories) + References to this Page: + References of this Page: + Revisions + Show revisions of this page ... + %errorMsg% + RSS Client + Search + Search pages of this package ... + second + seconds + To create a click, click on a page name + Size + Subscribe + Title + Title + Unread Items + View + View page in original context %context% + View this page ... + more... + week + weeks + %errorMsg% + year + years + 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 13 Sep 2012 16:05:26 -0000 1.15 @@ -0,0 +1,53 @@ + + + + Administrar + Administrar este paquete + Volver + Categor�as + Contenido + Crear esta p�gina en un lenguaje diferente + Borrar + Borrar esta p�gina + Detalles + Editar + editar tags + Editar esta p�gina + Entradas para la forma %form% + Forme + �ndice + Nueva P�gina + Origen + Notificaciones + Autor + Descripci�n + Nombre + Idioma + Secci�n + Fecha de publicaci�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 + Buscar p�ginas de este paquete + T�tulo + T�tulo + Vista + Ver esta p�gina + 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 13 Sep 2012 16:05:26 -0000 1.4 @@ -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 13 Sep 2012 16:05:26 -0000 1.12 @@ -0,0 +1,30 @@ +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] +set ::xowiki_head [::xo::Page header_stuff] + +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 13 Sep 2012 16:05:26 -0000 1.39 @@ -0,0 +1,400 @@ +::xo::library doc { + 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.39 2012/09/13 16:05:26 victorg 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@ + @item_id@ + property_body + property_doc + + + [my extra_header_stuff]@header_stuff;noquote@ + [my ajax_tag_definition] + + + + [my extra_header_stuff]@header_stuff;noquote@ + [my ajax_tag_definition] + }]\n + } + + ADP_Generator instproc wikicmds_part {} { + if {![my wikicmds]} {return ""} + return {
+ #xowiki.view# · + #xowiki.edit# · + #xotcl-core.revisions# · + #xowiki.new_page# · + #xowiki.delete# · + #xowiki.admin# · + #xowiki.notifications# +   · + #xowiki.search# · + #xowiki.index# + +
} + } + + ADP_Generator instproc footer_part {} { + if {![my footer]} {return ""} + return "@footer;noquote@" + } + + ADP_Generator instproc content_part {} { + return "@top_includelets;noquote@\n\ +

@title@ (@page_context@)

\n\ +

@title@

\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 "Warning: cannot overwrite $filename, ignoring possible changes" + } else { + ::puts -nonewline $f [my generate] + close $f + } + } +#################################################################################### +# Definition of Templates +#################################################################################### +# +# view-plain +# + ADP_Generator create view-plain -master 0 -wikicmds 0 -footer 0 + +#################################################################################### +# +# view-links +# + ADP_Generator create view-links -master 0 -footer 0 + +##################################################################################### +# +# view-default +# + ADP_Generator create view-default -master 1 -footer 1 + +#################################################################################### +# +# oacs-view +# + ADP_Generator create oacs-view -master 1 -footer 1 \ + -extra_header_stuff { + + + } \ + -proc content_part {} { + return [subst -novariables -nobackslashes \ +{
+
+ +
+
+[next] +
+}] + } + +#################################################################################### +# +# oacs-view2 +# +# 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] +
+ + +
+}] + } + +#################################################################################### +# +# oacs-view3 +# +# 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 {\ + +
+
+[next] +
+
+ +
+
+
+ + + +
+ +
+Contributors +
+
+ +
+
+ +
+
+ +}] + } + +#################################################################################### +# +# view-book +# +# wiki cmds in rhs +# + ADP_Generator create view-book -master 1 -footer 1 -wikicmds 0 \ + -extra_header_stuff { + } \ + -proc before_render {page} { + #::xo::cc set_parameter weblog_page weblog-portlet + } \ + -proc content_part {} { + return [subst -novariables -nobackslashes \ +{
+
+@toc;noquote@ +
+
+ +
+ + + + + + + + + + +
+ + + Previous + + + + No Previous + + + + + + + +
@book_relpos@
+
+
+ + + Next + + + + No Next + +
+
+
+ +
+ +
+
+}]} + +#################################################################################### +# +# view-book-no-ajax +# +# adp identical to view-book. +# + ADP_Generator create view-book-no-ajax -master 1 -footer 1 -wikicmds 0 \ + -extra_header_stuff { + } \ + -proc before_render {page} { + #::xo::cc set_parameter weblog_page weblog-portlet + } \ + -proc content_part {} { + return [view-book content_part] + } + +} \ No newline at end of file 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 13 Sep 2012 16:05:26 -0000 1.25 @@ -0,0 +1,75 @@ +::xo::library doc { + XoWiki - category specific code + + @creation-date 2006-10-10 + @author Gustaf Neumann + @cvs-id $Id: category-procs.tcl,v 1.25 2012/09/13 16:05:26 victorg Exp $ +} + +namespace eval ::xowiki { + # + # Commonly used code for categories + # + Class create Category + Category proc get_mapped_trees { + -object_id + {-locale ""} + {-names ""} + {-output {tree_id tree_name subtree_category_id assign_single_p require_category_p}} + } { + # Return matched category trees matching the specified names (or all) + + # provide compatibility with earlier versions of categories + set have_locale [expr {[lsearch [info args category_tree::get_mapped_trees] locale] > -1}] + set mapped_trees [expr {$have_locale ? + [category_tree::get_mapped_trees $object_id $locale] : + [category_tree::get_mapped_trees $object_id]}] + set trees [list] + foreach tree $mapped_trees { + foreach {tree_id my_tree_name ...} $tree {break} + + # "names" is a list of category names + if {$names ne ""} { + # Check, if the current name matches any of the given + # names. If the name contains wild-cards, perform a string + # match, otherwise a string equal. + set match 0 + foreach n $names { + if {[string first * $n] > -1} { + if {![string match $n $my_tree_name]} { + set match 1 + break + } + } elseif {$n eq $my_tree_name} { + set match 1 + break + } + } + if {!$match} continue + } + # Get the values from info in "tree" into separate variables given by output. + # Note, that the order matters! + foreach $output $tree break + set l [list] + foreach __var $output {lappend l [set $__var]} + lappend trees $l + } + return $trees + } + + Category proc get_category_infos {{-all false} {-subtree_id ""} {-locale ""} -tree_id} { + # + # provide a common interface to older versions of categories + # + # provide compatibility with earlier versions of categories + #set have_locale [expr {[lsearch [info args category_tree::get_tree] locale] > -1}] + set have_locale 1 + set all_arg [expr {$all ? "-all" : ""}] + return [expr {$have_locale ? + [eval category_tree::get_tree $all_arg -subtree_id [list $subtree_id] $tree_id $locale] : + [eval category_tree::get_tree $all_arg -subtree_id [list $subtree_id] $tree_id]}] + } +} + +::xo::library source_dependent + 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 13 Sep 2012 16:05:26 -0000 1.15 @@ -0,0 +1,150 @@ +::xo::library doc { + XoWiki - chat procs + + @creation-date 2006-02-02 + @author Gustaf Neumann + @cvs-id $Id: chat-procs.tcl,v 1.15 2012/09/13 16:05:26 victorg 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 [lindex [site_node::get_url_from_object_id -object_id $package_id] 0] + + 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 "--chat mode $mode" + } + + switch $mode { + polling { + ::xo::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/folder-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/folder-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/folder-procs.tcl 13 Sep 2012 16:05:26 -0000 1.17 @@ -0,0 +1,928 @@ +::xo::library doc { + + This is an experimental implemetation for folders + based on xowiki form pages. In particular, this file provides + + * An xowiki includelet to display the "folders" + * An xowiki includelet to display the "child-resources" + of a page (e.g. the contents of a folder) + + @author Michael Aram + @author Gustaf Neumann +} + +::xo::library require xowiki-procs +::xo::library require includelet-procs +::xo::library require form-field-procs +::xo::library require -package xotcl-core 30-widget-procs + +namespace eval ::xowiki::includelet { + ########################################################### + # + # ::xowiki::includelet::folders + # + ########################################################### + ::xowiki::IncludeletClass create folders \ + -superclass ::xowiki::Includelet \ + -cacheable false \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-show_full_tree false} + {-context_tree_view false} + }} + {id "[xowiki::Includelet js_name [self]]"} + } + + folders instproc include_head_entries {} { + ::xowiki::Tree include_head_entries -renderer yuitree -style folders + } + + folders instproc render {} { + my get_parameters + set js " + var [my js_name]; + YAHOO.util.Event.onDOMReady(function() { + [my js_name] = new YAHOO.widget.TreeView('foldertree_[my id]'); + [my js_name].subscribe('clickEvent',function(oArgs) { + var m = /href=\"(\[^\"\]+)\"/.exec(oArgs.node.html); + return false; + }); + [my js_name].render(); + }); + " + set tree [my build_tree] + return [$tree render -style yuitree -js $js] + } + + folders instproc collect_folders { + -package_id:required + -folder_form_id:required + -link_form_id:required + {-subtree_query ""} + {-depth 3} + } { + set folders [list] + + # safety belt, for recursive structures + if {$depth < 1} {return $folders} + + # + # get folders + # + set folder_pages [::xowiki::FormPage get_form_entries \ + -base_item_ids $folder_form_id -form_fields "" \ + -extra_where_clause $subtree_query \ + -publish_status ready -package_id $package_id] + # + # get links + # + set links [::xowiki::FormPage get_form_entries \ + -base_item_ids $link_form_id -form_fields "" \ + -extra_where_clause $subtree_query \ + -publish_status ready -package_id $package_id] + #my msg "[llength [$links children]] links" + + set folders [$folder_pages children] + my instvar current_folder_id + + # + # filter links to folders. + # links might be cross-package links + # + foreach l [$links children] { + set link_type [$l get_property_from_link_page link_type] + set cross_package [$l get_property_from_link_page cross_package] + + if {$link_type ne "folder_link"} continue + + if {$cross_package} { + # + # we found a cross-package link. These kind of links require further queries + # + set target [$l get_target_from_link_page] + + # the following clause needs an oracle counter-part + set tree_sortkey [db_string get_tree_sort_key "select tree_sortkey from acs_objects where object_id = [$target item_id]"] + set extra_where "and bt.item_id in (select object_id from acs_objects \ + where tree_sortkey between '$tree_sortkey' and tree_right('$tree_sortkey') \ + and object_type = 'content_item')" + + set sub_folders [my collect_folders -package_id [$target package_id] \ + -folder_form_id $folder_form_id -link_form_id $link_form_id \ + -subtree_query $extra_where -depth [expr {$depth -1}]] + + + foreach f $sub_folders { + + #my msg "$f [$f name] is a folder-link pointing to $target [$target name] current $current_folder_id" + if {[$f parent_id] eq [$target item_id]} { + #my msg "1 found child [$f name] and reset parent_id from [$f parent_id] to [$l item_id], package_id [$l package_id]" + # + # reset the current_folder if necessary + # + if {$current_folder_id eq [$f parent_id]} {set current_folder_id [$l item_id]} + # + # set the resolve_context + # + $f set_resolve_context -package_id [$l package_id] -parent_id [$l item_id] + # + # TODO we could save the double-fetch by collecing in + # get_form_entries via item-ids, not via new-objects + # + ::xo::db::CrClass get_instance_from_db -item_id [$f item_id] + [$f item_id] set_resolve_context -package_id [$l package_id] -parent_id [$l item_id] + } else { + #my msg "2 found child [$f name] and reset parent_id from [$f parent_id] to [$f parent_id], package id [$l package_id]" + $f set_resolve_context -package_id [$l package_id] -parent_id [$f parent_id] + ::xo::db::CrClass get_instance_from_db -item_id [$f item_id] + [$f item_id] set_resolve_context -package_id [$l package_id] -parent_id [$f parent_id] + } + + #my msg "including $f [$f name] [$f item_id]" + lappend folders $f + } + } + #my msg link=$link + lappend folders $l + } + return $folders + } + + folders instproc build_tree {} { + my instvar current_folder current_folder_id folder_form_id link_form_id + my get_parameters + + set with_links 0 + + set page [my set __including_page] + set package_id [::xo::cc package_id] + #my ds [::xo::cc serialize] + set lang [::xo::cc lang] + #set lang en + set return_url [::xo::cc url] + set nls_language [$page get_nls_language_from_lang $lang] + + set folder_form_id [::xowiki::Weblog instantiate_forms -forms en:folder.form \ + -package_id $package_id] + set link_form_id [::xowiki::Weblog instantiate_forms -forms en:link.form \ + -package_id $package_id] + #my msg folder_form=$folder_form_id + + set current_folder [$page get_folder -folder_form_ids $folder_form_id] + set current_folder_id [$current_folder item_id] + + #my msg "FOLDERS [$page name] package_id $package_id current_folder $current_folder [$current_folder name]" + + # Start with the "package's folder" as root folder + set root_folder_id [::$package_id folder_id] + set root_folder [::xo::db::CrClass get_instance_from_db -item_id $root_folder_id] + set root_folder_is_current [expr {$current_folder_id == [$root_folder item_id]}] + + set mb [info command ::__xowiki__MenuBar] + if {$mb ne ""} { + # + # We have a menubar. Add folder-specific content to the + # menubar. + # + if {$root_folder_is_current} { + # + # We do not want to see unneeded parent_ids in the links. When + # we insert to the root folder, set opt_parent_id to empty to + # make argument passing easy. "make_link" just checks for the + # existance of the variable, so we unset parent_id in this case. + # + set opt_parent_id "" + set folder_link [$package_id package_url] + if {[info exists parent_id]} {unset parent_id} + } else { + set parent_id $current_folder_id + set opt_parent_id $parent_id + ::xo::db::CrClass get_instance_from_db -item_id $parent_id + set folder_link [$current_folder pretty_link] + } + set return_url [::xo::cc url] + set new_folder_link [$package_id make_form_link -form en:folder.form \ + -parent_id $opt_parent_id \ + -return_url $return_url] + if {$with_links} { + set new_sym_link [$package_id make_form_link -form en:link.form \ + -parent_id $opt_parent_id \ + -nls_language $nls_language -return_url $return_url] + } +# set new_page_link [$package_id make_link -with_entities 0 \ +# $package_id edit-new \ +# {object_type ::xowiki::Page} \ +# parent_id return_url autoname template_file] + + set new_page_link [$package_id make_form_link -form en:page.form \ + -parent_id $opt_parent_id \ + -return_url $return_url] + set new_file_link [$package_id make_link -with_entities 0 \ + $package_id edit-new \ + {object_type ::xowiki::File} \ + parent_id return_url autoname template_file] + set new_form_link [$package_id make_link -with_entities 0 \ + $package_id edit-new \ + {object_type ::xowiki::Form} \ + parent_id return_url autoname template_file] + set import_link [$package_id make_link -privilege admin \ + -link "admin/import" $package_id {} parent_id return_url] + set import_archive_link [$package_id make_form_link -form en:import-archive.form \ + -parent_id $opt_parent_id] + + set index_link [$package_id make_link -link $folder_link $current_folder list] + + $mb add_menu_item -name Package.Startpage \ + -item [list text #xowiki.index# url $index_link] + + $mb add_menu_item -name New.Page \ + -item [list text #xowiki.new# url $new_page_link] + $mb add_menu_item -name New.File \ + -item [list text File url $new_file_link] + $mb add_menu_item -name New.Folder \ + -item [list text Folder url $new_folder_link] + if {$with_links} { + $mb add_menu_item -name New.SymLink \ + -item [list text SymLink url $new_sym_link] + } + $mb add_menu_item -name New.Form \ + -item [list text Form url $new_form_link] + $mb add_menu_item -name Package.ImportDump -item [list url $import_link] + $mb add_menu_item -name Package.ImportArchive -item [list url $import_archive_link] + + if {[::xowiki::clipboard is_empty]} { + set clipboard_copy_link "" + set clipboard_export_link "" + set clipboard_content_link "" + set clipboard_clear_link "" + } else { + # todo: check, whether the use is allowed to insert into the current folder + set clipboard_copy_link [$current_folder pretty_link]?m=clipboard-copy + set clipboard_export_link [$current_folder pretty_link]?m=clipboard-export + set clipboard_content_link [$current_folder pretty_link]?m=clipboard-content + set clipboard_clear_link [$current_folder pretty_link]?m=clipboard-clear + } + # todo: we should check either, whether to user is allowed to + # copy-to-clipboard from the current folder, and/or the user is + # allowed to do this with certain items.... (the latter in + # clipboad-add) + $mb add_menu_item -name Clipboard.Add \ + -item [list url javascript:acs_ListBulkActionClick("objects","$folder_link?m=clipboard-add")] + $mb add_menu_item -name Clipboard.Content -item [list url $clipboard_content_link] + $mb add_menu_item -name Clipboard.Clear -item [list url $clipboard_clear_link] + $mb add_menu_item -name Clipboard.Use.Copy -item [list url $clipboard_copy_link] + $mb add_menu_item -name Clipboard.Use.Export -item [list url $clipboard_export_link] + + # A folder page can contain extra menu entries (sample + # below). Iterate of the extra_menu property and add according + # menu entries. + foreach me [$current_folder property extra_menu_entries] { + array unset "" + set kind [lindex $me 0] + if {[string range $kind 0 0] eq "#"} continue + switch $kind { + clear_menu { + # sample entry: clear_menu -menu New + array set "" [lrange $me 1 end] + $mb clear_menu -menu $(-menu) + } + + form_link - + entry { + # sample entry: form_entry -name New.YouTubeLink -label YouTube -form en:YouTube.form + if {$kind eq "form_link"} { + my log "$me, name 'form_link' is deprecated, use 'entry' instead" + } + array set "" [lrange $me 1 end] + if {[info exists (-form)]} { + set link [$package_id make_form_link -form $(-form) \ + -parent_id $opt_parent_id \ + -nls_language $nls_language -return_url $return_url] + } elseif {[info exists (-object_type)]} { + set link [$package_id make_link -with_entities 0 \ + $package_id edit-new \ + [list object_type $(-object_type)] \ + parent_id return_url autoname template_file] + } else { + my log "Warning: no link specified" + set link "" + } + set item [list url $link] + if {[info exists (-label)]} {lappend item text $(-label)} + $mb add_menu_item -name $(-name) -item $item + } + + default { error "unknown kind of menu entry: $kind" } + } + } + } + + set top_folder_of_tree $root_folder + # + # Check, if the optional context tree view is activated + # + if {$context_tree_view || [$package_id get_parameter FolderContextTreeView false]} { + set parent_id [$current_folder parent_id] + if {$parent_id ne -100} { + set top_folder_of_tree $parent_id + #my msg top_folder_of_tree=$top_folder_of_tree + } + } + + set parent_folder [$top_folder_of_tree parent_id] + if {$top_folder_of_tree eq $root_folder || $parent_folder eq "-100"} { + set href [::$package_id package_url] + set label [::$package_id instance_name] + #my msg "use instance name" + } else { + set href [$top_folder_of_tree pretty_link] + set label "[$top_folder_of_tree title] ..." + } + + set t [::xowiki::Tree new -id foldertree_[my id] ] + set node [::xowiki::TreeNode new \ + -href $href \ + -label $label \ + -highlight [expr {$current_folder_id == [$top_folder_of_tree item_id]}] \ + -object $top_folder_of_tree \ + -expanded 1 \ + -open_requests 1] + $t add $node + set folders [my collect_folders \ + -package_id $package_id \ + -folder_form_id $folder_form_id \ + -link_form_id $link_form_id] + + #my msg "folder [my set folder_form_id] has [llength $folders] entries" + #foreach f $folders {lappend _ [$f item_id]}; my msg $_ + + my build_sub_tree -node $node -folders $folders + return $t + } + + folders instproc build_sub_tree { + {-node} + {-folders} + + } { + my get_parameters + my instvar current_folder_id + + set current_object [$node object] + set current_item_id [$current_object item_id] + + set sub_folders [list] + set remaining_folders [list] + foreach f $folders { + if {[$f parent_id] ne $current_item_id} { + lappend remaining_folders $f + } else { + lappend sub_folders $f + } + } + + foreach c $sub_folders { + + set label [$c title] + set object $c + set folder_href [$c pretty_link] + + set is_current [expr {$current_folder_id eq [$c item_id]}] + set is_open [expr {$is_current || $show_full_tree}] + + #regexp {^..:(.+)$} $label _ label + + set subnode [::xowiki::TreeNode new \ + -href $folder_href \ + -label $label \ + -object $c \ + -highlight $is_current \ + -expanded $is_open \ + -open_requests 1] + $node add $subnode + + if {$is_current} { + $node open_tree + + if {[info command ::__xowiki__MenuBar] ne "" + && [::__xowiki__MenuBar exists submenu_pages(folder)]} { + set owner [::__xowiki__MenuBar set submenu_owner(folder)] + $subnode add_pages -full true \ + -book_mode [$owner set book_mode] \ + -owner $owner \ + [::__xowiki__MenuBar set submenu_pages(folder)] + } + } + + my build_sub_tree -node $subnode -folders $remaining_folders + } + } +} + + +namespace eval ::xowiki::includelet { + + ########################################################### + # + # ::xowiki::includelet::child-resources + # + ########################################################### + ::xowiki::IncludeletClass create child-resources \ + -superclass ::xowiki::Includelet \ + -parameter { + { + parameter_declaration { + {-skin:optional "yui-skin-sam"} + {-show_types "::xowiki::Page,::xowiki::File,::xowiki::Form,::xowiki::FormPage"} + {-regexp:optional} + {-with_subtypes:optional false} + {-orderby:optional "last_modified,desc"} + {-publish_status "ready"} + {-view_target ""} + {-html-content} + {-parent .} + {-hide} + } + } + } + + child-resources instproc types_to_show {} { + my get_parameters + foreach type [split $show_types ,] {set ($type) 1} + return [lsort [array names ""]] + } + + child-resources instproc render {} { + my get_parameters + + set current_folder [my set __including_page] + + if {$parent eq ".."} { + set current_folder [$current_folder parent_id] + ::xo::db::CrClass get_instance_from_db -item_id $current_folder + } + if {![$current_folder istype ::xowiki::FormPage]} { + # current folder has to be a FormPage + set current_folder [$current_folder parent_id] + if {![$current_folder istype ::xowiki::FormPage]} { + error "child-resources not included from a FormPage" + } + } + set current_folder_id [$current_folder item_id] + + if {[::xo::cc query_parameter m] ne "list" && $parent ne ".."} { + set index [$current_folder property index] + if {$index ne ""} { + set download [string match "file:*" $index] + set index_link [$package_id pretty_link \ + -parent_id [$current_folder item_id] \ + -download $download \ + $index] + return [$package_id returnredirect $index_link] + } + } + + set logical_folder_id $current_folder_id + if {[$current_folder exists physical_item_id]} { + set current_folder_id [$current_folder set physical_item_id] + } + + $package_id instvar package_key + + set return_url [::xo::cc url] ;#"[$package_id package_url]edit-done" + set category_url [export_vars -base [$package_id package_url] { {manage-categories 1} {object_id $package_id}}] + + set columns {objects edit object_type name last_modified delete} + foreach column $columns {set ::hidden($column) 0 } + if {[info exists hide]} { + foreach column $hide {if {[info exists ::hidden($column)]} {set ::hidden($column) 1}} + } + + set t [::YUI::DataTable new -skin $skin -volatile \ + -columns { + BulkAction objects -id ID -hide $::hidden(objects) -actions { + Action new -label select -tooltip select -url admin/select + } + # The "-html" options are currenty ignored in the YUI + # DataTable. Not sure, it can be integrated in the traditional way. + # + # A full example for skinning the datatable is here: + # http://developer.yahoo.com/yui/examples/datatable/dt_skinning.html + # + HiddenField ID + AnchorField edit -CSSclass edit-item-button -label "" \ + -hide $::hidden(edit) \ + -html {style "padding: 0px;"} + Field object_type -label [_ xowiki.page_kind] -orderby object_type -richtext false \ + -hide $::hidden(object_type) \ + -html {style "padding: 0px;"} + AnchorField name -label [_ xowiki.Page-name] -orderby name \ + -hide $::hidden(name) \ + -html {style "padding: 2px;"} + Field last_modified -label [_ xowiki.Page-last_modified] -orderby last_modified \ + -hide $::hidden(last_modified) + AnchorField delete -CSSclass delete-item-button \ + -hide $::hidden(delete) \ + -label "" ;#-html {onClick "return(confirm('Confirm delete?'));"} + }] + + + set extra_where_clause "true" + # TODO: why filter on title and name? + if {[info exists regexp]} {set extra_where_clause "(bt.title ~ '$regexp' OR ci.name ~ '$regexp' )"} + set publish_status_clause [::xowiki::Includelet publish_status_clause $publish_status] + + set items [::xowiki::FormPage get_all_children \ + -folder_id $current_folder_id \ + -object_types [my types_to_show] \ + -extra_where_clause $extra_where_clause] + + set package_id [::xo::cc package_id] + set pkg ::$package_id + set url [::xo::cc url] + $pkg get_lang_and_name -default_lang "" -name [$current_folder name] lang name + set folder [$pkg folder_path -parent_id [$current_folder parent_id]] + set folder_ids [$items set folder_ids] + + foreach c [$items children] { + set name [$c name] + set page_link [::$package_id pretty_link \ + -parent_id $logical_folder_id \ + -context_url $url \ + -folder_ids $folder_ids \ + $name] + array set icon [$c render_icon] + + if {[catch {set prettyName [$c pretty_name]} errorMsg]} { + my msg "can't obtain pretty name of [$c item_id] [$c name]: $errorMsg" + set prettyName $name + } + + #set delete_link [export_vars -base [$package_id package_url] \ + # [list {delete 1} \ + # [list item_id [$c item_id]] \ + # [list name [$c pretty_link]] return_url]] + + set delete_link [export_vars -base $page_link {{m delete} return_url}] + + $t add \ + -ID [$c name] \ + -name $prettyName \ + -name.href [export_vars -base $page_link {template_file html-content}] \ + -name.title [$c set title] \ + -object_type $icon(text) \ + -object_type.richtext $icon(is_richtext) \ + -last_modified [$c set last_modified] \ + -edit "" \ + -edit.href [export_vars -base $page_link {{m edit} return_url}] \ + -edit.title #xowiki.edit# \ + -delete "" \ + -delete.href $delete_link \ + -delete.title #xowiki.delete# + } + + foreach {att order} [split $orderby ,] break + $t orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] $att + set resources_list "[$t asHTML]" + + set viewers [util_coalesce [$current_folder property viewers] [$current_folder get_parameter viewers]] + set viewer_links "" + foreach v $viewers { + set wf_link "${v}?p.folder=[${current_folder} name]" + append wf_link "&m=create-or-use" + append viewer_links [subst -nocommands -nobackslashes {
  • view with $v
  • }] + } + return " [$t asHTML]" + + } +} + +namespace eval ::xowiki::formfield { + + ########################################################### + # + # ::xowiki::formfield::menuentries + # + ########################################################### + + Class menuentries -superclass textarea -parameter { + {rows 10} + {cols 80} + } + menuentries instproc pretty_value {v} { + [my object] do_substitutions 0 + return "
    [string map [list & {&} < {<} > {>}]  [my value]]
    " + } +} + +##################### +# # +# YUI stuff # +# # +##################### + +namespace eval ::YUI { + + Object loader -ad_doc { + The YUI Library comes with a "Loader" module, that resolves YUI-module + dependencies. Also, it combines numerous files into one single file to + increase page loading performance. + This works only for the "hosted" YUI library. This Loader module should + basically do the same (in future). For two simple calls like e.g. + "::YUI::loader require menu" and "::YUI::loader require datatable" + it should take care of selecting all the files needed and assemble them + into one single resource, that may be delivered. + Note, that this is not implemented yet. + } + + loader set ajaxhelper 1 + + # TODO: Make "::YUI::loader require -module XYZ" work everywhere "out-of-the-box" + # Now, as we use "::xo:Page require_JS" we have to include the generated + # header_stuff "manually" (e.g. in tcl-adp pairs), whereas ::template::head... + # includes it directly, which is nice. + + loader ad_proc require { + -module + {-version "2.7.0b"} + } { + This is the key function of the loader, that will be used by other packages. + @param module + The YUI Module to be loaded + } { + my instvar ajaxhelper + switch -- [string tolower $module] { + + utilities { + # utilities.js: The utilities.js aggregate combines the Yahoo Global Object, + # Dom Collection, Event Utility, Element Utility, Connection Manager, + # Drag & Drop Utility, Animation Utility, YUI Loader and the Get Utility. + # Use this file to reduce HTTP requests whenever you are including more + # than three of its constituent components. + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "yahoo-dom-event/yahoo-dom-event.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "utilities/utilities.js" + } + menubar { + # + # We should not have two different versions of the YUI + # library on one page, because YUI2 (afaik) doesnt support + # "sandboxing". If we use e.g. the yui-hosted utilities.js file here + # we may end up with two YAHOO object definitions, because e.g. + # the tree-procs uses the local yahoo-dom-event. + + # In future, the YUI loader object should be capable of + # resolving such conflicts. for now, the simple fix is to stick to + # the local versions, because then the requireJS function takes care + # of duplicates. + # + my require -module "utilities" + # todo : this is more than necessary + foreach jsFile { + "container/container-min.js" + "treeview/treeview-min.js" + "button/button-min.js" + "menu/menu-min.js" + "datasource/datasource-min.js" + "autocomplete/autocomplete-min.js" + "datatable/datatable-min.js" + "selector/selector-min.js" + } { + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper $jsFile + } + + my require -module "reset-fonts-grids" + my require -module "base" + + foreach cssFile { + "container/assets/container.css" + "datatable/assets/skins/sam/datatable.css" + "button/assets/skins/sam/button.css" + "assets/skins/sam/skin.css" + "menu/assets/skins/sam/menu.css" + } { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper $cssFile + } + ::xowiki::Includelet require_YUI_CSS -ajaxhelper 1 "treeview/assets/folders/tree.css" + } + datatable { + # see comment above + my require -module "utilities" + # todo : this is more than necessary + foreach jsFile { + "container/container-min.js" + "treeview/treeview-min.js" + "button/button-min.js" + "menu/menu-min.js" + "datasource/datasource-min.js" + "autocomplete/autocomplete-min.js" + "datatable/datatable-min.js" + "selector/selector-min.js" + } { + ::xowiki::Includelet require_YUI_JS -version "2.7.0b" -ajaxhelper $ajaxhelper $jsFile + } + + my require -module "reset-fonts-grids" + my require -module "base" + + foreach cssFile { + "container/assets/container.css" + "datatable/assets/skins/sam/datatable.css" + "button/assets/skins/sam/button.css" + "assets/skins/sam/skin.css" + "menu/assets/skins/sam/menu.css" + } { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper $cssFile + } + #::xowiki::Includelet require_YUI_CSS -ajaxhelper 1 "treeview/assets/skins/sam/treeview.css" + #::xowiki::Includelet require_YUI_CSS -ajaxhelper 1 "treeview/assets/folders/tree.css" + } + reset { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper "reset/reset.css" + } + fonts { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper "fonts/fonts.css" + } + grids { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper "grids/grids.css" + } + base { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper "base/base.css" + } + "reset-fonts-grids" { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper "reset-fonts-grids/reset-fonts-grids.css" + } + } + } + + Class DataTable \ + -superclass ::xo::Table \ + -parameter { + {skin "yui-skin-sam"} + } + + DataTable instproc init {} { + set trn_mixin [expr {[lang::util::translator_mode_p] ?"::xo::TRN-Mode" : ""}] + my render_with YUIDataTableRenderer $trn_mixin + next + } + + Class AnchorField \ + -superclass ::xo::Table::AnchorField \ + -ad_doc " + In addition to the standard TableWidget's AnchorField, we also allow the attributes + + " \ + -instproc get-slots {} { + set slots [list -[my name]] + foreach subfield {href title CSSclass target onclick} { + lappend slots [list -[my name].$subfield ""] + } + return $slots + } +} + +# TODO Allow renderers from other namespaces in 30-widget-procs + +namespace eval ::xo::Table { + + Class create YUIDataTableRenderer \ + -superclass TABLE3 \ + -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 + my set id [::xowiki::Includelet js_name [::xowiki::Includelet html_id [self]]] + } + + YUIDataTableRenderer ad_instproc -private render_yui_js {} { + Generates the JavaScript fragment, that is put below and + (progressively enhances) the HTML table. + } { + my instvar id + set container ${id}_container + set datasource ${id}_datasource + set datatable ${id}_datatable + set coldef ${id}_coldef + + set js "var $datasource = new YAHOO.util.DataSource(YAHOO.util.Dom.get('$id')); \n" + append js "$datasource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE; \n" + append js "$datasource.responseSchema = \{ \n" + append js " fields: \[ \n" + set js_fields [list] + foreach field [[self]::__columns children] { + if {[$field hide]} continue + lappend js_fields " \{ key: \"[$field set name]\" \}" + } + append js [join $js_fields ", "] " \] \n\};\n" + append js "var $coldef = \[\n" + set js_fields [list] + foreach field [[self]::__columns children] { + if {[$field hide]} continue + if {[$field istype HiddenField]} continue + if {[$field istype BulkAction]} { + set label "" + set sortable false + } else { + set label [$field label] + set sortable [expr {[$field exists sortable] ? [$field set sortable] : true}] + } + lappend js_fields " \{ key: \"[$field set name]\" , sortable: $sortable, label: \"$label\" \}" + } + append js [join $js_fields ", "] "\];\n" + append js "var $datatable = new YAHOO.widget.DataTable('$container', $coldef, $datasource);\n" + return $js + } + + YUIDataTableRenderer instproc render-body {} { + html::thead { + html::tr -class list-header { + foreach o [[self]::__columns children] { + if {[$o hide]} continue + $o render + } + } + } + set children [my children] + html::tbody { + foreach line [my children] { + 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] { + if {[$field hide]} continue + html::td [concat [list class list] [$field html]] { + $field render-data $line + } + } + } + } + } + } + + YUIDataTableRenderer instproc render {} { + ::YUI::loader require -module "datatable" + if {![my isobject [self]::__actions]} {my actions {}} + if {![my isobject [self]::__bulkactions]} {my __bulkactions {}} + set bulkactions [[self]::__bulkactions children] + if {[llength $bulkactions]>0} { + set name [[self]::__bulkactions set __identifier] + } else { + set name [::xowiki::Includelet js_name [self]] + } + # TODO: maybe use skin everywhere? hen to use style/CSSclass or skin? + set skin [expr {[my exists skin] ? [my set skin] : ""}] + html::div -id [my set id]_wrapper -class $skin { + html::form -name $name -id $name -method POST { + html::div -id [my set id]_container { + html::table -id [my set id] -class [my set css.table-class] { + # TODO do i need that? + my render-actions + my render-body + } + if {[llength $bulkactions]>0} { my render-bulkactions } + } + } + ::xo::Page requireJS "YAHOO.util.Event.onDOMReady(function () {\n[my render_yui_js]});" + } + } + + + #Class create YUIDataTableRenderer::AnchorField -superclass TABLE::AnchorField + + Class create YUIDataTableRenderer::AnchorField \ + -superclass TABLE::Field \ + -ad_doc " + In addition to the standard TableWidget's AnchorField, we also allow the attributes + + " \ + -instproc render-data {line} { + set __name [my name] + if {[$line exists $__name.href] && + [set href [$line set $__name.href]] ne ""} { + # use the CSS class rather from the Field than not the line + my instvar CSSclass + $line instvar [list $__name.title title] \ + [list $__name.target target] \ + [list $__name.onclick onclick] + html::a [my get_local_attributes href title {CSSclass class} target onclick] { + return "[next]" + } + } + next + } + + Class create YUIDataTableRenderer::Action -superclass TABLE::Action + Class create YUIDataTableRenderer::Field -superclass TABLE::Field + Class create YUIDataTableRenderer::HiddenField -superclass TABLE::HiddenField + Class create YUIDataTableRenderer::ImageField -superclass TABLE::ImageField + Class create YUIDataTableRenderer::ImageAnchorField -superclass TABLE::ImageAnchorField + Class create YUIDataTableRenderer::BulkAction -superclass TABLE::BulkAction +} + +::xo::library source_dependent 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 13 Sep 2012 16:05:27 -0000 1.219 @@ -0,0 +1,3481 @@ +::xo::library doc { + XoWiki - form fields + + @creation-date 2007-06-22 + @author Gustaf Neumann + @cvs-id $Id: form-field-procs.tcl,v 1.219 2012/09/13 16:05:27 victorg Exp $ +} + +namespace eval ::xowiki::formfield { + + # 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 could go into xotcl-core + + ########################################################### + # + # ::xowiki::FormField (Base Class) + # + ########################################################### + Class create FormField -superclass ::xo::tdom::Object -parameter { + {required false} + {display_field true} + {hide_value false} + {inline false} + {disabled} + {show_raw_value} + CSSclass + style + {form_widget_CSSclass form-widget} + {form_item_wrapper_CSSclass form-item-wrapper} + {type text} + {label} + {name} + {id} + {value ""} + {spec ""} + {help_text ""} + {error_msg ""} + {validator ""} + {validate_via_ajax} + + {autocomplete} + {autofocus} + {formnovalidate} + {multiple} + {pattern} + {placeholder} + {readonly} + + locale + default + object + slot + answer + correct_when + feedback_answer_correct + feedback_answer_incorrect + } + FormField set abstract 1 + + FormField proc fc_encode {string} { + return [string map [list , __COMMA__] $string] + } + FormField proc fc_decode {string} { + return [string map [list __COMMA__ ,] $string] + } + #FormField proc fc_decode_colon {string} { + # return [string map [list __COLON__ :] $string] + #} + + FormField proc get_from_name {object name} { + # + # Get a form field via name. The provided names are unique for a + # form. If multiple forms should be rendered simultaneously, we + # have to extend the addressing mechanism. + # + # todo: we could speed this up by an index if needed + foreach f [::xowiki::formfield::FormField info instances -closure] { + if {[$f name] eq $name} { + if {![$f exists object]} { + my msg "strange, $f [$f name] was created without object but fits name" + return $f + } elseif {$object eq [$f object]} { + return $f + } + } + } + #my msg not-found-$object-$name + return "" + } + + + 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] + } + + # + # Basic initialze method, doing nothing; should be subclassed by the + # application classes + FormField instproc initialize {} {next} + + FormField instproc get_json {} { + return [util_spec2json [list [my get_spec]]] + } + + FormField instproc get_spec {} { + set pairs [list [list CSSclass class]] + # Special handling of HTML boolean attributes, since they require a + # different coding; it would be nice, if tdom would care for this. + set booleanAtts [list required readonly disabled multiple formnovalidate autofocus] + foreach att $booleanAtts { + if {[my exists $att] && [my set $att]} { + my set __#$att $att + lappend pairs [list __#$att $att] + } + } + + set atts [eval my get_attributes type size maxlength id name value \ + pattern placeholder $pairs] + + foreach att $booleanAtts { + if {[my exists __#$att]} {my unset __#$att} + } + + return [list "input" $atts {}] + } + + FormField instproc validation_check {validator_method value} { + return [my $validator_method $value] + } + + FormField instproc validate {obj} { + my instvar name required + + # use the 'value' method to deal e.g. with compound fields + set value [my value] + #my msg "[my info class] value=$value req=$required // [my set value] //" + + if {$required && $value eq "" && ![my istype ::xowiki::formfield::hidden]} { + my instvar label + return [_ acs-templating.Element_is_required] + } + # + #my msg "++ [my name] [my info class] validator=[my validator] ([llength [my validator]]) value=$value" + foreach validator [my validator] { + set errorMsg "" + # + # The validator might set the variable errorMsg in this scope. + # + set success 1 + set validator_method check=$validator + set proc_info [my procsearch $validator_method] + #my msg "++ [my name]: field-level validator exists '$validator_method' ? [expr {$proc_info ne {}}]" + if {$proc_info ne ""} { + # we have a slot checker, call it + #my msg "++ call-field level validator $validator_method '$value'" + set success [my validation_check $validator_method $value] + } + if {$success == 1} { + # the previous check was ok, check now for a validator on the + # object level + set validator_method validate=$validator + set proc_info [$obj procsearch $validator_method] + #my msg "++ [my name]: page-level validator exists ? [expr {$proc_info ne {}}]" + if {$proc_info ne ""} { + set success [$obj $validator_method $value] + #my msg "++ call page-level validator $validator_method '$value' returns $success" + } + } + 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_$validator [list value $value errorMsg $errorMsg]] + #return [::lang::message::lookup "" xowiki.$cl-validate_$validator %errorMsg% [list value $value errorMsg $errorMsg] 1] + } + } + return "" + } + + FormField instproc reset_parameter {} { + # reset application specific parameters (defined below ::xowiki::formfield::FormField) + # such that searchDefaults will pick up the new defaults, when a form field + # is reclassed. + + if {[my exists per_object_behavior]} { + # remove per-object mixin from the "behavior" + my mixin delete [my set per_object_behavior] + my unset per_object_behavior + } + + #my msg "reset along [my info precedence]" + foreach c [my info precedence] { + if {$c eq "::xowiki::formfield::FormField"} break + foreach s [$c info slots] { + if {![$s exists default]} continue + set var [$s name] + set key processed($var) + if {[info exists $key]} continue + my set $var [$s default] + set $key 1 + } + } + if {[my exists disabled]} { + my set_disabled 0 + } + } + + FormField proc interprete_condition {-package_id -object cond} { + if {[::xo::cc info methods role=$cond] ne ""} { + if {$cond eq "creator"} { + set success [::xo::cc role=$cond \ + -object $object \ + -user_id [::xo::cc user_id] \ + -package_id $package_id] + } else { + set success [::xo::cc role=$cond \ + -user_id [::xo::cc user_id] \ + -package_id $package_id] + } + } else { + set success 0 + } + return $success + } + + FormField set cond_regexp {^([^=?]+)[?]([^:]*)[:](.*)$} + + FormField proc get_single_spec {-package_id -object string} { + if {[regexp [my set cond_regexp] $string _ condition true_spec false_spec]} { + if {[my interprete_condition -package_id $package_id -object $object $condition]} { + return [my get_single_spec -package_id $package_id -object $object $true_spec] + } else { + return [my get_single_spec -package_id $package_id -object $object $false_spec] + } + } + return $string + } + + FormField instproc remove_omit {} { + set m ::xowiki::formfield::omit + if {[my ismixin $m]} {my mixin delete $m} + } + FormField instproc set_disabled {disable} { + #my msg "[my name] set disabled $disable" + if {$disable} { + my set disabled true + } else { + my unset -nocomplain disabled + } + } + + FormField instproc behavior {mixin} { + + # + # Specify the behavior of a form field via + # per object mixins + # + set obj [my object] + set pkgctx [[$obj package_id] context] + if {[$pkgctx exists embedded_context]} { + set ctx [$pkgctx set embedded_context] + set classname ${ctx}::$mixin + #my msg ctx=$ctx-viewer=$mixin,found=[my isclass $classname] + # TODO: search different places for the mixin. Special namespace? + if {[my isclass $classname]} { + if {[my exists per_object_behavior]} { + my mixin delete [my set per_object_behavior] + } + my mixin add $classname + my set per_object_behavior $classname + } else { + my msg "Could not find mixin '$mixin'" + } + } + } + + FormField instproc repeatable {} { + my mixin add ::xowiki::formfield::repeatable + my reset_parameter + } + + FormField instproc interprete_single_spec {s} { + if {$s eq ""} return + + set object [my object] + set package_id [$object package_id] + set s [::xowiki::formfield::FormField get_single_spec -object $object -package_id $package_id $s] + + switch -glob -- $s { + optional {my set required false} + required {my set required true; my remove_omit} + omit {my mixin add ::xowiki::formfield::omit} + repeatable {my repeatable} + noomit {my remove_omit} + disabled {my set_disabled true} + enabled {my set_disabled false} + label=* {my label [lindex [split $s =] 1]} + help_text=* {my help_text [lindex [split $s =] 1]} + *=* { + set p [string first = $s] + set attribute [string range $s 0 [expr {$p-1}]] + set value [string range $s [expr {$p+1}] end] + set definition_class [lindex [my procsearch $attribute] 0] + set method [my info methods $attribute] + if {[string match "::xotcl::*" $definition_class] || $method eq ""} { + error [_ xowiki.error-form_constraint-unknown_attribute [list class [my info class] 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 $attribute $value + } errMsg]} { + error "Error during setting attribute '$attribute' to value '$value': $errMsg" + } + } + default { + # Check, if the spec value $s is a class. + set old_class [my info class] + # Don't allow to use namespaced values, since we would run + # into a recursive loop for richtext::wym (could be altered there as well). + if {[my isclass ::xowiki::formfield::$s] && ![string match "*:*" $s]} { + my class ::xowiki::formfield::$s + my remove_omit + if {$old_class ne [my info class]} { + #my msg "[my name]: reset class from $old_class to [my info class]" + my reset_parameter + my set __state reset + my initialize + } + } 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'"]] + } + } + } + } + } + + FormField instproc config_from_spec {spec} { + #my log "spec=$spec [my info class] [[my info class] exists abstract]" + + my instvar type + if {[[my info class] exists abstract]} { + # had earlier here: [my info class] eq [self class] + # Check, wether the actual class is a concrete class (mapped to + # concrete field type) or an abstact class. Since + # config_from_spec can be called multiple times, we want to do + # the reclassing only once. + if {[my isclass ::xowiki::formfield::$type]} { + my class ::xowiki::formfield::$type + } else { + my class ::xowiki::formfield::text + } + # set missing instance vars with defaults + my set_instance_vars_defaults + } + regsub -all {,\s+} $spec , spec + foreach s [split $spec ,] { + my interprete_single_spec [FormField fc_decode $s] + } + + #my msg "[my name]: after specs" + my set __state after_specs + my initialize + + # + # 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 add "::xo::TRN-Mode" + } + + } + + 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 [my localize $help_text] + append spec " {help_text {$internationalized}}" + } else { + append spec " {help_text {$help_text}}" + } + } + return $spec + } + + 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 + } + my set __rendered 1 + } + + FormField instproc render_form_widget {} { + # This method provides the form-widget wrapper + set CSSclass [my form_widget_CSSclass] + if {[my error_msg] ne ""} {append CSSclass " form-widget-error"} + set atts [list class $CSSclass] + if {[my inline]} {lappend atts style "display: inline;"} + ::html::div $atts { my render_input } + } + + FormField instproc render_input {} { + # + # 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. + # + if {[my exists validate_via_ajax] && [my validator] ne ""} { + set ajaxhelper 1 + ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "yahoo/yahoo-min.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "dom/dom-min.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "event/event-min.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "connection/connection-min.js" + ::xo::Page requireJS "/resources/xowiki/yui-form-field-validate.js" + set package_url [[[my object] package_id] package_url] + ::xo::Page requireJS "YAHOO.xo_form_field_validate.add('[my id]','$package_url');" + } + + #::html::input [eval my get_attributes type size maxlength id name value \ + # pattern placeholder $pairs] {} + util_createDom [list [my get_spec]] + + # + # Disabled fieds are not returned by the browsers. For some + # fields, we require to be sent. therefore we include in these + # cases the value in an additional hidden field. Maybe we should + # change in the future the "name" of the disabled entry to keep + # some hypothetical html-checker quiet. + # + if {[my exists disabled] && [my exists transmit_field_always]} { + ::html::input [list type hidden name [my name] value [my set value]] {} + } + my set __rendered 1 + } + + FormField instproc render_item {} { + ::html::div -class [my form_item_wrapper_CSSclass] { + if {[my error_msg] ne ""} { + set CSSclass form-label-error + } else { + set CSSclass form-label + } + ::html::div -class $CSSclass { + ::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 render_error_msg {} { + if {[my error_msg] ne "" && ![my exists error_reported]} { + ::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 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 value_if_nothing_is_returned_from_form {default} { + return $default + } + + FormField instproc pretty_value {v} { + #my log "mapping $v" + return [string map [list & "&" < "<" > ">" \" """ ' "'" @ "@"] $v] + } + + FormField instproc has_instance_variable {var value} { + if {[my exists $var] && [my set $var] eq $value} {return 1} + return 0 + } + FormField instproc convert_to_internal {} { + # to be overloaded + } + FormField instproc convert_to_external {value} { + # to be overloaded + return $value + } + + FormField instproc answer_check=eq {} { + my instvar value + set arg1 [lindex [my correct_when] 1] + return [expr {$value eq $arg1}] + } + FormField instproc answer_check=gt {} { + my instvar value + set arg1 [lindex [my correct_when] 1] + return [expr {$value > $arg1}] + } + FormField instproc answer_check=ge {} { + my instvar value + set arg1 [lindex [my correct_when] 1] + return [expr {$value >= $arg1}] + } + FormField instproc answer_check=lt {} { + my instvar value + set arg1 [lindex [my correct_when] 1] + return [expr {$value < $arg1}] + } + FormField instproc answer_check=le {} { + my instvar value + set arg1 [lindex [my correct_when] 1] + return [expr {$value <= $arg1}] + } + FormField instproc answer_check=btwn {} { + my instvar value + set arg1 [lindex [my correct_when] 1] + set arg2 [lindex [my correct_when] 2] + return [expr {$value >= $arg1 && $value <= $arg2}] + } + FormField instproc answer_check=in {} { + my instvar value + set values [lrange [my correct_when] 1 end] + return [expr {[lsearch -exact $values $value] > -1}] + } + FormField instproc answer_check=match {} { + return [string match [lindex [my correct_when] 1] [my value]] + } + FormField instproc answer_check=answer_words {} { + set value [regsub -all { +} [my value] " "] + if {[string match "*lower*" [lindex [my correct_when] 1]]} { + set value [string tolower $value] + } + return [expr {$value eq [my answer]}] + } + + FormField instproc answer_is_correct {} { + #my msg "[my name] ([my info class]): value=[my value], answer=[expr {[my exists answer]?[my set answer]:{NONE}}]" + if {[my exists correct_when]} { + set op [lindex [my correct_when] 0] + if {[my procsearch answer_check=$op] ne ""} { + set r [my answer_check=$op] + if {$r == 0} {return -1} {return 1} + } else { + error "invalid operator '$op'" + } + } elseif {![my exists answer]} { + return 0 + } elseif {[my value] ne [my answer]} { + #my msg "v='[my value]' NE a='[my answer]'" + return -1 + } else { + return 1 + } + } + + FormField instproc field_value {v} { + if {[my exists show_raw_value]} { + return $v + } else { + return [my pretty_value] + } + } + + FormField instproc pretty_image {-parent_id:required entry_name} { + if {$entry_name eq ""} return + if {[my set value] eq ""} return + my instvar object value + + array set "" [$object item_ref -default_lang [$object lang] -parent_id $parent_id $entry_name] + + set label [my label] ;# the label is used for alt und title + if {$label eq $(stripped_name)} { + # The label is apparently the default. For Photo.form instances, + # this is always "image". In such cases, use the title of the + # parent object as label. + set label [[my object] title] + } + + set l [::xowiki::Link create new -destroy_on_cleanup \ + -page $object -type "image" -lang $(prefix) \ + [list -stripped_name $(stripped_name)] [list -label $label] \ + -parent_id $(parent_id) -item_id $(item_id)] + + if {[my istype file]} { + set revision_id [my get_from_value $value revision_id] + if {$revision_id ne ""} { + $l revision_id $revision_id + } + } + + foreach option { + 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 + geometry + } { + if {[my exists $option]} {$l set $option [my set $option]} + } + set html [$l render] + return $html + } + + ########################################################### + # + # helper method for extending slots: + # either, we make a meta class for form-fields, or this should + # should go into xotcl-core + # + ########################################################### + + ::Serializer exportMethods { + ::xotcl::Class instproc extend_slot + } + Class instproc extend_slot {name value} { + # create a mirroring slot and add the specified value to the default + foreach c [my info heritage] { + if {[info command ${c}::slot::$name] ne ""} { + set value [concat $value [${c}::slot::$name default]] + break + } + } + my slots [list Attribute create validator -default $value] + } + + ########################################################### + # + # ::xowiki::formfield::submit_button + # + ########################################################### + + Class submit_button -superclass FormField + submit_button instproc initialize {} { + my set type submit + my set value [::xo::localize [_ xowiki.Form-submit_button]] + } + submit_button instproc render_input {} { + # don't disable submit buttons + if {[my type] eq "submit"} {my unset -nocomplain disabled} + ::html::input [my get_attributes name type {CSSclass class} value disabled] {} + my render_localizer + } + + ########################################################### + # + # ::xowiki::formfield::file + # + ########################################################### + + Class create file -superclass FormField -parameter { + {size 40} + {sticky false} + link_label + } + file instproc tmpfile {value} {my set [self proc] $value} + file instproc content-type {value} {my set [self proc] $value} + file instproc initialize {} { + my type file + my set widget_type file(file) + next + } + file instproc entry_info {value} { + return [list name file:[my name] parent_id [[my object] item_id]] + } + + file instproc get_value_from_form {} { + set old_value [[my object] form_parameter __old_value_[my name] ""] + set v [my set value] + #my msg "value '$v' // old_value '$old_value'" + # + # Figure out, if we got a different file-name (value). If the + # file-name is the same as in the last revision, we return a + # "-". This has the effect, that file file is not uploaded again. + # + #if {$old_value ne "" && $old_value eq [my set value]} {} + + if {$old_value ne "" && $v eq ""} { + return "-" + } + return $v + } + + file instproc get_from_value {value attribute {raw ""}} { + # + # The value of of a form entry might be: + # - an atomic list element + # - a list with attribute value pairs + # + # This function tries to obtain the queried attribute from the + # attribute value pair notation. If this fails, it returns a + # default value. + # + set valueLength [llength $value] + if {$valueLength > 1 && $valueLength %2 == 0} { + array set "" $value + if {[info exists ($attribute)]} { + return $($attribute) + } + } + return [lindex $raw 0] + } + + file instproc convert_to_internal {} { + my instvar value + + set v [my get_value_from_form] + if {$v eq "-" || $v eq ""} { + # nothing to do, keep the old value + #my msg "nothing to do with '$v'" + set value [[my object] form_parameter __old_value_[my name] ""] + [my object] set_property [my name] $value + return + } + regsub -all {\\+} $value {/} value ;# fix IE upload path + set value [::file tail $value] + [my object] set_property [my name] $value + + set package_id [[my object] package_id] + array set entry_info [my entry_info $value] + + set content_type [my set content-type] + if {$content_type eq "application/octetstream" + || $content_type eq "application/force-download" + } { + set content_type [::xowiki::guesstype $value] + } + #my msg "mime_type of $entry_info(name) = [::xowiki::guesstype $value] // [my set content-type] ==> $content_type" + set file_object [$package_id get_page_from_name -name $entry_info(name) -parent_id $entry_info(parent_id)] + if {$file_object ne ""} { + # file entry exists already, create a new revision + #my msg "new revision (value $value)" + $file_object set import_file [my set tmpfile] + $file_object set mime_type $content_type + $file_object set title $value + $file_object save + # + # Update the value with the attribute value pair list containing + # the revision_id. TODO: clear revision_id on export. + # + [my object] set_property -new 1 [my name] [list name $value revision_id [$file_object revision_id]] + } else { + # create a new file + #my msg "new file" + set file_object [::xowiki::File new -destroy_on_cleanup \ + -title $value \ + -name $entry_info(name) \ + -parent_id $entry_info(parent_id) \ + -mime_type $content_type \ + -package_id [[my object] package_id] \ + -creation_user [::xo::cc user_id] ] + $file_object set import_file [my set tmpfile] + $file_object save_new + # Make sure the value is just one list item + [my object] set_property -new 1 [my name] [list $value] + } + } + + file instproc label_or_value {v} { + if {[my exists link_label]} { + return [my localize [my link_label]] + } + return $v + } + + file instproc pretty_value {v} { + if {$v ne ""} { + my instvar object + array set "" [my entry_info $v] + array set "" [$object item_ref -default_lang [[my object] lang] -parent_id $(parent_id) $(name)] + #my msg "pretty value name '$(stripped_name)'" + set l [::xowiki::Link create new -destroy_on_cleanup \ + -page $object -type "file" -lang $(prefix) \ + [list -stripped_name $(stripped_name)] [list -label [my label]] \ + [list -extra_query_parameter [list [list filename [my get_from_value $v name $v]]]] \ + -parent_id $(parent_id) -item_id $(item_id)] + return [$l render] + } + } + + file instproc render_input {} { + util_createDom [list [my get_spec]] + } + + file instproc get_spec {} { + my instvar value + set package_id [[my object] package_id] + array set entry_info [my entry_info $value] + set fn [my get_from_value $value name $value] + set href [$package_id pretty_link -download 1 -parent_id $entry_info(parent_id) $entry_info(name)] + if {![my istype image]} { + append href ?filename=[ns_urlencode $fn] + } + # + # The HTML5 handling of "required" would force us to upload in + # every form the file again. To implement the sticky option, we + # set temporarily the "required" attribute to false + # + if {[my exists required]} { + set reset_required 1 + my set required false + } + + lassign [next] tag atts children + + if {[info exists reset_required]} { + my set required true + } + + set additional_spec [util_tdom2list { + # FOLLOWING GIVES TROUBLE, SEE util_spec2json FOR DETAILS + ::html::t " " + set id __old_value_[my name] + ::html::input -type hidden -name $id -id $id -value $value + #my msg "old_value '$value'" + ::html::span -class file-control -id __a$id { + ::html::a -href $href {::html::t [my label_or_value $fn] } + # Show the clear button just when + # - there is something to clear, and + # - the formfield is not disabled, and + # - the form-field is not sticky (default) + set disabled [expr {[my exists disabled] && [my disabled] ne "false"}] + if {$value ne "" && !$disabled && ![my sticky] } { + ::html::input -type button -value clear \ + -onClick "document.getElementById('$id').value = ''; document.getElementById('__a$id').style.display = 'none';" + } + } + }] + + lappend children $additional_spec + return [list $tag $atts $children] + } + + ########################################################### + # + # ::xowiki::formfield::import_archive + # + ########################################################### + + Class import_archive -superclass file -parameter { + {cleanup false} + } + import_archive instproc initialize {} { + next + if {[my help_text] eq ""} {my help_text "#xowiki.formfield-import_archive-help_text#"} + } + import_archive instproc pretty_value {v} { + my instvar object + set package_id [$object package_id] + set parent_id [$object parent_id] + if {$v eq ""} {return ""} + array set "" [my entry_info $v] + set fn [my get_from_value $v name $v] + # + # Get the file object of the imported file to obtain is full name and path + # + set file_id [$package_id lookup -parent_id [$object item_id] -name $(name)] + ::xo::db::CrClass get_instance_from_db -item_id $file_id + set full_file_name [$file_id full_file_name] + # + # Call the archiver to unpack and handle the archive + # + set f [::xowiki::ArchiveFile new -file $full_file_name -name $fn -parent_id $parent_id] + if {[$f unpack]} { + # + # So, all the hard work is done. We take a hard measure here to + # cleanup the entry in case everything was imported + # successful. Note that setting "cleanup" without thought might + # lead to maybe unexpected deletions of the form-page + # + if {[my cleanup]} { + set return_url [$package_id query_parameter "return_url" [$parent_id pretty_link]] + $package_id returnredirect [export_vars -base [$object pretty_link] [list {m delete} return_url]] + } + } + } + + ########################################################### + # + # ::xowiki::formfield::image + # + ########################################################### + + Class image -superclass file -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 + } + image instproc pretty_value {v} { + array set "" [my entry_info $v] + + return [my pretty_image -parent_id $(parent_id) $(name)] + } + + ########################################################### + # + # ::xowiki::formfield::hidden + # + ########################################################### + + Class hidden -superclass FormField + hidden instproc initialize {} { + my type hidden + my set widget_type text(hidden) + # remove mixins in case of retyping + my mixin "" + } + hidden instproc render_item {} { + # don't render the labels + my render_form_widget + } + hidden instproc render_help_text {} { + } + + ########################################################### + # + # ::xowiki::formfield::omit + # + ########################################################### + + Class omit -superclass FormField + omit instproc render_item {} { + # don't render the labels + #my render_form_widget + } + omit instproc render_help_text {} { + } + + ########################################################### + # + # ::xowiki::formfield::inform + # + ########################################################### + + Class inform -superclass FormField + inform instproc initialize {} { + my type hidden + my set widget_type text(inform) + } + inform instproc render_input {} { + ::html::t [my value] + ::html::input [my get_attributes type id name value disabled {CSSclass class}] {} + } + inform instproc render_help_text {} { + } + + ########################################################### + # + # ::xowiki::formfield::text + # + ########################################################### + + Class text -superclass FormField -parameter { + {size 80} + maxlength + } + text instproc initialize {} { + my type text + my set widget_type text + foreach p [list size maxlength] {if {[my exists $p]} {my set html($p) [my $p]}} + } + text instproc get_spec {} { + set atts [my get_attributes type size maxlength id name value \ + pattern placeholder] + + return [list input $atts {}] + } + + ########################################################### + # + # ::xowiki::formfield::color + # + ########################################################### + + Class color -superclass text + color instproc initialize {} { + next + my type color + } + + ########################################################### + # + # ::xowiki::formfield::datetime + # + ########################################################### + + Class datetime -superclass text + datetime instproc initialize {} { + next + my type datetime + } + # names for HTML5 types + # date, month + # already in use, should redefine accordingly when avail + + ########################################################### + # + # ::xowiki::formfield::datetime-local + # + ########################################################### + + Class datetime-local -superclass text + datetime-local instproc initialize {} { + next + my type datetime-local + } + + ########################################################### + # + # ::xowiki::formfield::time + # + ########################################################### + + Class time -superclass text + time instproc initialize {} { + next + my type time + } + + ########################################################### + # + # ::xowiki::formfield::week + # + ########################################################### + + Class week -superclass text + week instproc initialize {} { + next + my type datetime + } + + ########################################################### + # + # ::xowiki::formfield::email + # + ########################################################### + + Class email -superclass text + email instproc initialize {} { + next + my type email + } + + ########################################################### + # + # ::xowiki::formfield::search + # + ########################################################### + + Class search -superclass text + search instproc initialize {} { + next + my type search + } + ########################################################### + # + # ::xowiki::formfield::tel + # + ########################################################### + + Class tel -superclass text + tel instproc initialize {} { + next + my type tel + } + + ########################################################### + # + # ::xowiki::formfield::number + # + ########################################################### + + Class number -superclass FormField -parameter { + min max step value + } + number instproc initialize {} { + my type number + my set widget_type text + } + number instproc render_input {} { + ::html::input [my get_attributes type id name value disabled {CSSclass class} min max step value \ + autofocus formnovalidate multiple pattern placeholder readonly required] {} + } + + ########################################################### + # + # ::xowiki::formfield::range + # + ########################################################### + + Class range -superclass FormField -parameter { + min max step value + } + range instproc initialize {} { + my type range + my set widget_type text + } + range instproc render_input {} { + ::html::input [my get_attributes type id name value disabled {CSSclass class} min max step value \ + autofocus formnovalidate multiple pattern placeholder readonly required] {} + } + + + ########################################################### + # + # ::xowiki::formfield::password + # + ########################################################### + + Class password -superclass text + password instproc initialize {} { + next + my set widget_type password + my type password + } + ########################################################### + # + # ::xowiki::formfield::numeric + # + ########################################################### + + Class numeric -superclass text -parameter { + {format %.2f} + } -extend_slot validator numeric + numeric instproc initialize {} { + next + my set widget_type numeric + # check, if we we have an integer format + my set is_integer [regexp {%[0-9.]*d} [my format]] + } + numeric instproc convert_to_external value { + if {$value ne ""} { + if { [catch "lc_numeric $value [my format] [my locale]" result] } { + util_user_message -message "[my label]: $result (locale=[my locale])" + #my msg [list lc_numeric $value [my format] [my locale]] + set converted_value $value + if {[catch {scan $value [my format] converted_value}]} { + return $value + } else { + return $converted_value + } + } + return $result + } + return $value + } + numeric instproc convert_to_internal {} { + if {[my value] ne ""} { + set value [lc_parse_number [my value] [my locale] [my set is_integer]] + [my object] set_property -new 1 [my name] [expr {$value}] + return + } + } + numeric instproc check=numeric {value} { + return [expr {[catch {lc_parse_number $value [my locale] [my set is_integer]}] == 0}] + } + numeric instproc pretty_value value { + return [my convert_to_external $value] + } + numeric instproc answer_check=eq {} { + # use numeric equality + return [expr {[my value] == [lindex [my correct_when] 1]}] + } + + ########################################################### + # + # ::xowiki::formfield::user_id + # + ########################################################### + + Class user_id -superclass numeric -parameter { + {format %d} + } + user_id instproc initialize {} { + next + my set is_party_id 1 + } + user_id instproc pretty_value {v} { + return [::xo::get_user_name $v] + } + + ########################################################### + # + # ::xowiki::formfield::author + # + ########################################################### + + Class author -superclass user_id -parameter { + {photo_size 54} + {with_photo true} + {with_user_link false} + {label #xowiki.formfield-author#} + } + author instproc pretty_value {v} { + if {$v ne ""} { + my instvar object + acs_user::get -user_id $v -array user + if {[my with_photo]} { + set portrait_id [acs_user::get_portrait_id -user_id $v] + if {$portrait_id == 0} { + package require md5 + set md5 [string tolower [md5::Hex [md5::md5 -- $user(email)]]] + set src http://www.gravatar.com/avatar/$md5?size=[my photo_size]&d=mm + } else { + set src "/shared/portrait-bits.tcl?user_id=$v" + } + set photo "" + set photo_class "photo" + } else { + set photo "" + set photo_class "" + } + set date_field [::xowiki::FormPage get_table_form_fields \ + -base_item $object \ + -field_names _last_modified \ + -form_constraints ""] + set date [$date_field pretty_value [$object property _last_modified]] + + if {[my with_user_link]} { + set user_link_begin "" + set user_link_end "" + } else { + set user_link_begin "" + set user_link_end "" + } + + return [subst { +
    $photo +

    $user_link_begin$user(first_names) $user(last_name)$user_link_end

    +

    $date

    +
    + }] + } + return "" + } + + ########################################################### + # + # ::xowiki::formfield::party_id + # + ########################################################### + + Class party_id -superclass user_id \ + -extend_slot validator party_id_check + party_id instproc check=party_id_check {value} { + if {$value eq ""} {return 1} + return [db_0or1row [my qn check_party] "select 1 from parties where party_id = :value"] + } + + ########################################################### + # + # ::xowiki::formfield::url + # + ########################################################### + + Class url -superclass text -parameter { + {link_label} + } + url instproc initialize {} { + next + my type url + } + 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 + } + regsub -all & $v "&" v + return "$link_label" + } + } + + ########################################################### + # + # ::xowiki::formfield::detail_link + # + ########################################################### + + Class detail_link -superclass url -parameter { + {link_label "#xowiki.weblog-more#"} + } + detail_link instproc pretty_value {v} { + if {$v eq ""} { + return "" + } + if {$v ne ""} { + set link_label [my localize [my link_label]] + regsub -all & $v "&" v + return " \[ $link_label \]" + } + } + + ########################################################### + # + # ::xowiki::formfield::textarea + # + ########################################################### + + Class textarea -superclass FormField -parameter { + {rows 2} + {cols 80} + {spell false} + } + 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]}} + if {![my istype ::xowiki::formfield::richtext] && [my exists editor]} { + # downgrading + #my msg "downgrading [my info class]" + foreach m [my info mixin] {if {[$m exists editor_mixin]} {my mixin delete $m}} + foreach v {editor options} {if {[my exists $v]} {my unset $v}} + } + next + } + + textarea instproc render_input {} { + ::html::textarea [my get_attributes id name cols rows style {CSSclass class} disabled] { + ::html::t [my value] + } + } + + ########################################################### + # + # ::xowiki::formfield::code_listing + # + ########################################################### + + Class code_listing -superclass textarea -parameter { + {rows 20} + {cols 80} + } + code_listing instproc pretty_value {v} { + [my object] do_substitutions 0 + if {[info command api_tclcode_to_html] ne ""} { + set html [api_tclcode_to_html [my value]] + regsub -all "\n?\r" $html html + return "
    $html
    " + } else { + return "
    [string map [list & {&} < {<} > {>}]  [my value]]
    " + } + } + + ########################################################### + # + # ::xowiki::formfield::richtext + # + ########################################################### + + Class richtext -superclass textarea \ + -extend_slot validator safe_html \ + -parameter { + plugins + folder_id + script_dir + width + height + {wiki false} + } + + richtext instproc editor {args} { + # + # TODO: this should be made a slot setting + # + #my msg "setting editor for [my name], args=$args,[llength $args]" + if {[llength $args] == 0} {return [my set editor]} + set editor [lindex $args 0] + if {[my exists editor] && $editor eq [my set editor] && [my exists __initialized]} return + + set editor_class [self class]::$editor + if {$editor ne "" && ![my hasclass $editor_class]} { + if {![my isclass $editor_class]} { + set editors [list] + foreach c [::xowiki::formfield::richtext info subclass] { + if {![$c exists editor_mixin]} continue + lappend editors [namespace tail $c] + } + error [_ xowiki.error-form_constraint-unknown_editor \ + [list name [my name] editor [my editor] editors $editors]] + } + foreach m [my info mixin] {if {[$m exists editor_mixin]} {my mixin delete $m}} + my mixin add $editor_class + #my msg "MIXIN $editor: [my info precedence]" + my reset_parameter + my set __initialized 1 + } + my set editor $editor + } + + richtext instproc initialize {} { + my display_field false + next + if {![my exists editor]} {my set editor xinha} ;# set the default editor + if {![my exists __initialized]} { + # Mixin the editor based on the attribute 'editor' if necessary + # and call initialize again in this case... + my editor [my set editor] + my initialize + } + } + + richtext instproc render_richtext_as_div {} { + #my msg "[my get_attributes id style {CSSclass class}]" + ::html::div [my get_attributes id style {CSSclass class}] { + if {[my wiki]} { + [my object] set unresolved_references 0 + [my object] set __unresolved_references [list] + #::html::t -disableOutputEscaping [[my object] substitute_markup [list [my value] text/html]] + ::html::t -disableOutputEscaping [[my object] substitute_markup [my value]] + } else { + ::html::t -disableOutputEscaping [my value] + } + } + ::html::div + } + + richtext instproc check=safe_html {value} { + # don't check if the user has sufficient permissions on the package + if {[::xo::cc permission \ + -object_id [::xo::cc package_id] \ + -privilege swa \ + -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 + } + richtext instproc pretty_value {v} { + # for richtext, perform minimal output escaping + if {[my wiki]} { + return [[my object] substitute_markup $v] + } else { + return [string map [list @ "@"] $v] + } + } + + ########################################################### + # + # ::xowiki::formfield::richtext::ckeditor + # + # mode: wysiwyg, source + # skin: kama, v2, office2003 + # extraPlugins: tcl-list, is converted to comma list for js + # + ########################################################### + Class richtext::ckeditor -superclass richtext -parameter { + {editor ckeditor} + {mode wysiwyg} + {skin kama} + {toolbar Full} + {CSSclass xowiki-ckeditor} + {uiColor ""} + {inplace false} + {CSSclass xowiki-ckeditor} + {customConfig "../ck_config.js"} + {callback "/* callback code */"} + {destroy_callback "/* callback code */"} + {extraPlugins ""} + {templatesFiles ""} + {templates ""} + {contentsCss /resources/xowiki/ck_contents.css} + {imageSelectorDialog /xowiki/ckeditor-images/} + } + richtext::ckeditor set editor_mixin 1 + richtext::ckeditor instproc initialize {} { + if {[my set inplace]} { + my append help_text " #xowiki.ckeip_help#" + } + next + my set widget_type richtext + # Mangle the id to make it compatible with jquery; most probably + # not optimal and just a temporary solution + regsub -all {[.:]} [my id] "" id + my id $id + } + + richtext::ckeditor instproc js_image_helper {} { + ::xo::Page requireJS { + function xowiki_image_callback(editor) { + $(editor.element.$.form).submit(function(e) { + calc_image_tags_to_wiki_image_links(this); + }); + editor.setData(calc_wiki_image_links_to_image_tags(editor.getData())); + } + + function calc_image_tags_to_wiki_image_links (form) { + var calc = function() { + var wiki_link = $(this).attr('alt'); + $(this).replaceWith('[['+wiki_link+']]'); + } + $(form).find('iframe').each(function() { + $(this).contents().find('img[type="wikilink"]').each(calc); + }); + + $(form).find('textarea.ckeip').each(function() { + var contents = $('
    '+this.value+'
    '); + contents.find('img[type="wikilink"]').each(calc); + this.value = contents.html(); + }); + return true; + } + + function calc_wiki_image_links_to_image_tags (data) { + var pathname = window.location.pathname; + pathname = pathname.substr(pathname.lastIndexOf("/")+1,pathname.length) + console.log('pathname' + pathname); + pathname = pathname.replace(/:/ig,"%3a"); + var regex_wikilink = new RegExp('(\\[\\[./image:)(.*?)(\\]\\])', 'g'); + data = data.replace(regex_wikilink,'./image:$2'); + console.log('data' + data); + return data + } + } + } + + richtext::ckeditor instproc pathNames {fileNames} { + set result [list] + foreach fn $fileNames { + if {[regexp {^[./]} $fn]} { + append result $fn + } else { + append result "/resources/xowiki/$fn" + } + } + return $result + } + + richtext::ckeditor instproc render_input {} { + set disabled [expr {[my exists disabled] && [my disabled] ne "false"}] + if {![my istype ::xowiki::formfield::richtext] || $disabled } { + my render_richtext_as_div + } else { + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" + ::xo::Page requireJS "/resources/xowiki/ckeditor/ckeditor_source.js" + #::xo::Page requireJS "/resources/xowiki/ckeditor/ckeditor.js" + ::xo::Page requireJS "/resources/xowiki/ckeditor/adapters/jquery.js" + ::xo::Page requireJS "/resources/xowiki/jquery-ui-1.8.17.custom.min.js" + ::xo::Page requireCSS "/resources/xowiki/jquery-ui-1.8.17.custom.css" + + # In contrary to the doc, ckeditor names instances after the id, + # not the name. + set id [my id] + set name [my name] + set package_id [[my object] package_id] + #my extraPlugins {timestamp xowikiimage} + + if {[lsearch [my extraPlugins] xowikiimage] > -1} { + my js_image_helper + set ready_callback {xowiki_image_callback(e.editor);} + } else { + set ready_callback "/*none*/;" + } + + set options [subst { + toolbar : '[my toolbar]', + uiColor: '[my uiColor]', + language: '[lang::conn::language]', + skin: '[my skin]', + startupMode: '[my mode]', + parent_id: '[[my object] item_id]', + package_url: '[$package_id package_url]', + extraPlugins: '[join [my extraPlugins] ,]', + contentsCss: '[my contentsCss]', + imageSelectorDialog: '[my imageSelectorDialog]', + ready_callback: '$ready_callback', + customConfig: '[my customConfig]' + }] + if {[my templatesFiles] ne ""} { + append options " , templates_files: \['[join [my pathNames [my templatesFiles]] ',' ]' \]\n" + } + if {[my templates] ne ""} { + append options " , templates: '[my templates]'\n" + } + + #set parent [[[my object] package_id] get_page_from_item_or_revision_id [[my object] parent_id]];# ??? + + if {[my set inplace]} { + if {[my value] eq ""} {my value " "} + my render_richtext_as_div + if {[my inline]} { + set wrapper_class "" + } else { + set wrapper_class "form-item-wrapper" + my callback {$(this.element.$).closest('.form-widget').css('clear','both').css('display', 'block');} + my destroy_callback {$(this).closest('.form-widget').css('clear','none');} + } + set callback [my callback] + set destroy_callback [my destroy_callback] + + ::xo::Page requireJS "/resources/xowiki/ckeip.js" + ::xo::Page requireJS [subst -nocommands { + \$(document).ready(function() { + \$( '\#$id' ).ckeip(function() { $callback }, { + name: '$name', + ckeditor_config: { + $options, + destroy_callback: function() { $destroy_callback } + }, + wrapper_class: '$wrapper_class' + }); + }); + }] + } else { + set callback [my callback] + ::xo::Page requireJS [subst -nocommands { + \$(document).ready(function() { + \$( '#$id' ).ckeditor(function() { $callback }, { + $options + }); + CKEDITOR.instances['$id'].on('instanceReady',function(e) {$ready_callback}); + }); + }] + next + } + } + } + + ########################################################### + # + # ::xowiki::formfield::richtext::wym + # + ########################################################### + Class richtext::wym -superclass richtext -parameter { + {editor wym} + {CSSclass wymeditor} + width + height + {skin silver} + {plugins "hovertools resizable fullscreen"} + } + richtext::wym set editor_mixin 1 + richtext::wym instproc initialize {} { + next + my set widget_type richtext + } + richtext::wym instproc render_input {} { + set disabled [expr {[my exists disabled] && [my disabled] ne "false"}] + if {![my istype ::xowiki::formfield::richtext] || $disabled } { + my render_richtext_as_div + } else { + ::xo::Page requireCSS "/resources/xowiki/wymeditor/skins/default/screen.css" + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" + ::xo::Page requireJS "/resources/xowiki/wymeditor/jquery.wymeditor.pack.js" + set postinit "" + foreach plugin {hovertools resizable fullscreen embed} { + if {[lsearch -exact [my plugins] $plugin] > -1} { + switch -- $plugin { + embed {} + resizable { + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.ui.js" + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.ui.resizable.js" + append postinit "wym.${plugin}();\n" + } + default {append postinit "wym.${plugin}();\n"} + } + ::xo::Page requireJS "/resources/xowiki/wymeditor/plugins/$plugin/jquery.wymeditor.$plugin.js" + } + } + regsub -all {[.:]} [my id] {\\\\&} JID + + # possible skins are per in the distribution: "default", "sliver", "minimal" and "twopanels" + set config [list "skin: '[my skin]'"] + + #my msg "wym, h [my exists height] || w [my exists width]" + if {[my exists height] || [my exists width]} { + set height_cmd "" + set width_cmd "" + if {[my exists height]} {set height_cmd "jQuery(wym._box).find(wym._options.iframeSelector).css('height','[my height]');"} + if {[my exists width]} {set width_cmd "wym_box.css('width', '[my width]');"} + set postInit [subst -nocommand -nobackslash { + postInit: function(wym) { + wym_box = jQuery(".wym_box"); + $height_cmd + $width_cmd + $postinit + }}] + lappend config $postInit + } + if {$config ne ""} { + set config \{[join $config ,]\} + } + ::xo::Page requireJS [subst -nocommand -nobackslash { + jQuery(function() { + jQuery("#$JID").wymeditor($config); + }); + }] + + next + } + } + + ########################################################### + # + # ::xowiki::formfield::richtext::xinha + # + ########################################################### + + Class richtext::xinha -superclass richtext -parameter { + javascript + {height} + {style} + {wiki_p true} + {inplace false} + {slim false} + {CSSclass xinha} + } + richtext::xinha set editor_mixin 1 + richtext::xinha instproc initialize {} { + next + my set widget_type richtext + if {![my exists plugins]} { + my plugins \ + [parameter::get -parameter "XowikiXinhaDefaultPlugins" \ + -default [::xo::parameter get_from_package_key \ + -package_key "acs-templating" -parameter "XinhaDefaultPlugins"]] + } + my set options [my get_attributes editor plugins width height folder_id script_dir javascript wiki_p] + # for the time being, we can't set the defaults via parameter, + # but only manually, since the editor is used as a mixin, the parameter + # would have precedence over the defaults of subclasses + if {![my exists slim]} {my set slim false} + if {![my exists style]} {my set style "width: 100%;"} + if {![my exists height]} {my set height 350px} + if {![my exists wiki_p]} {my set wiki_p 1} + if {![my exists inplace]} {my set inplace false} + if {[my set inplace]} { + ::xo::Page requireJS "/resources/xowiki/xinha-inplace.js" + if {![info exists ::__xinha_inplace_init_done]} { + template::add_body_handler -event onload -script "xinha.inplace.init();" + set ::__xinha_inplace_init_done 1 + } + } + if {[my set slim]} { + my lappend options javascript { + xinha_config.toolbar = [['popupeditor', 'formatblock', 'bold','italic','createlink','insertimage'], + ['separator','insertorderedlist','insertunorderedlist','outdent','indent'], + ['separator','killword','removeformat','htmlmode'] + ]; + } + } + } + + richtext::xinha instproc render_input {} { + set disabled [expr {[my exists disabled] && [my disabled] ne "false"}] + if {![my istype ::xowiki::formfield::richtext] || $disabled} { + my render_richtext_as_div + } else { + # 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 wiki_p package_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] + + if {[my set inplace]} { + ::html::div [my get_attributes id name {CSSclass class} disabled] { + set href \# + set onclick "xinha.inplace.openEditor('[my id]');return false;" + ::html::a -style "float: right;" -class edit-item-button -href $href -onclick $onclick { + ::html::t -disableOutputEscaping   + } + ::html::div -id "[my id]__CONTENT__" { + ::html::t -disableOutputEscaping [my value] + } + } + my set hiddenid [my id]__HIDDEN__ + my set type hidden + ::html::input [my get_attributes {hiddenid id} name type value] {} + } else { + #::html::div [my get_attributes id name cols rows style {CSSclass class} disabled] {} + next + } + } + } + + ########################################################### + # + # ::xowiki::formfield::enumeration + # + ########################################################### + + # abstract superclass for select and radio + Class enumeration -superclass FormField -parameter { + {options} + {category_tree} + } + enumeration set abstract 1 + enumeration instproc initialize {} { + if {[my exists category_tree]} { + my config_from_category_tree [my category_tree] + } + next + } + enumeration abstract instproc render_input {} + + enumeration instproc get_labels {values} { + if {[my multiple]} { + set labels [list] + foreach v $values {lappend labels [list [my get_entry_label $v] $v]} + return $labels + } else { + return [list [list [my get_entry_label $values] $values]] + } + } + + enumeration instproc pretty_value {v} { + if {[my exists category_label($v)]} { + return [my set category_label($v)] + } + if {[my exists multiple] && [my set multiple]} { + foreach o [my set options] { + foreach {label value} $o break + set labels($value) [my localize $label] + } + set values [list] + foreach i $v {lappend values $labels($i)} + return [join $values {, }] + } else { + foreach o [my set options] { + foreach {label value} $o break + if {$value eq $v} {return [my localize $label]} + } + } + } + enumeration instproc config_from_category_tree {tree_name} { + # Get the options of a select or radio from the specified + # category tree. + # + # We could config as well from the mapped category tree, + # and get required and multiple from there.... + # + # The usage of the label does not seem to be very useful. + # + #set tree_id [category_tree::get_id $tree_name [my locale]] + + set package_id [[my object] package_id] + set tree_ids [::xowiki::Category get_mapped_trees -object_id $package_id -locale [my locale] \ + -names $tree_name -output tree_id] + + # In case there are multiple trees with the same name, + # take the first one. + # + set tree_id [lindex $tree_ids 0] + + if {$tree_id eq ""} { + my msg "cannot lookup mapped category tree name '$tree_name'" + return + } + set subtree_id "" + set options [list] + + foreach category [::xowiki::Category get_category_infos \ + -subtree_id $subtree_id -tree_id $tree_id] { + foreach {category_id category_name deprecated_p level} $category break + set category_name [ad_quotehtml [lang::util::localize $category_name]] + my set category_label($category_id) $category_name + if { $level>1 } { + set category_name "[string repeat {.} [expr {2*$level-4}]]..$category_name" + } + lappend options [list $category_name $category_id] + } + my options $options + my set is_category_field 1 + # my msg label_could_be=$tree_name,existing=[my label] + # if {![my exists label]} { + # my label $tree_name + # } + } + + ########################################################### + # + # ::xowiki::formfield::radio + # + ########################################################### + + Class radio -superclass enumeration -parameter { + {horizontal false} + {forced_name} + } + radio instproc initialize {} { + my set widget_type text(radio) + next + } + radio instproc render_input {} { + set value [my value] + foreach o [my options] { + foreach {label rep} $o break + set atts [my get_attributes disabled {CSSclass class}] + if {[my exists forced_name]} {set name [my forced_name]} {set name [my name]} + lappend atts id [my id]:$rep name $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::checkbox + # + ########################################################### + + Class checkbox -superclass enumeration -parameter { + {horizontal false} + } + checkbox instproc initialize {} { + my set multiple true + my set widget_type text(checkbox) + next + } + + + checkbox instproc value_if_nothing_is_returned_from_form {default} { + # Here we have to distinguish between two cases to: + # - edit mode: somebody has removed a mark from a check button; + # this means: clear the field + # - view mode: the fields were deactivted (made insensitive); + # this means: keep the old value + + #my msg "[my name] disabled=[my exists disabled]" + if {[my exists disabled]} {return $default} else {return ""} + } + checkbox instproc render_input {} { + # identical to radio, except "checkbox" type and lsearch; + # maybe we can push this up to enumeration.... + set value [my value] + foreach o [my options] { + foreach {label rep} $o break + set atts [my get_attributes disabled {CSSclass class}] + lappend atts id [my id]:$rep name [my name] type checkbox value $rep + if {[lsearch -exact $value $rep] > -1} {lappend atts checked checked} + ::html::input $atts {} + html::t "$label " + if {![my horizontal]} {html::br} + } + } + + + ########################################################### + # + # ::xowiki::formfield::select + # + ########################################################### + + Class select -superclass enumeration -parameter { + {multiple "false"} + } + + select instproc initialize {} { + my set widget_type text(select) + next + if {![my exists options]} {my options [list]} + } + + select instproc get_spec {} { + set select_atts [my get_attributes id name disabled {CSSclass class}] + if {[my multiple]} {lappend atts multiple [my multiple]} + set options [my options] + if {![my required]} { + set options [linsert $options 0 [list "--" ""]] + } + + set spec_options [list] + foreach o $options { + foreach {label rep} $o break + set atts [my get_attributes disabled] + lappend atts value $rep + if {[lsearch [my value] $rep] > -1} { + lappend atts selected on + } + lappend spec_options [list "option" $atts [list [list "#text" $label]]] + #lappend spec_options [list "#text" "\n"] + } + return [list select $select_atts $spec_options] + } + + select instproc render_input {} { + util_createDom [list [my get_spec]] + } + + select instproc render_input_old {} { + set atts [my get_attributes id name disabled {CSSclass class}] + 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 [my get_attributes disabled] + lappend atts value $rep + #my msg "lsearch {[my value]} $rep ==> [lsearch [my value] $rep]" + if {[lsearch [my value] $rep] > -1} { + lappend atts selected on + } + ::html::option $atts {::html::t $label} + ::html::t \n + }} + } + + + ########################################################### + # + # ::xowiki::formfield::candidate_box_select + # + ########################################################### + Class create candidate_box_select -superclass select -parameter { + {as_box false} + {dnd true} + } + candidate_box_select set abstract 1 + + candidate_box_select instproc render_input {} { + #my msg "mul=[my multiple]" + # makes only sense currently for multiple selects + if {[my multiple] && [my dnd]} { + if {([my exists disabled] && [my disabled])} { + html::t -disableOutputEscaping [my pretty_value [my value]] + } else { + + # utilities.js aggregates "yahoo, dom, event, connection, animation, dragdrop" + set ajaxhelper 0 + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "utilities/utilities.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "selector/selector-min.js" + ::xo::Page requireJS "/resources/xowiki/yui-selection-area.js" + + set js "" + foreach o [my options] { + foreach {label rep} $o break + set js_label [::xowiki::Includelet js_encode $label] + set js_rep [::xowiki::Includelet js_encode $rep] + append js "YAHOO.xo_sel_area.DDApp.values\['$js_label'\] = '$js_rep';\n" + append js "YAHOO.xo_sel_area.DDApp.dict\['$js_rep'\] = '$js_label';\n" + } + + ::html::div -class workarea { + ::html::h3 { ::html::t "Selection"} + set values "" + foreach v [my value] { + append values $v \n + set __values($v) 1 + } + my CSSclass selection + my set cols 30 + set atts [my get_attributes id name disabled {CSSclass class}] + + # TODO what todo with DISABLED? + ::html::textarea [my get_attributes id name cols rows style {CSSclass class} disabled] { + ::html::t $values + } + } + ::html::div -class workarea { + ::html::h3 { ::html::t "Candidates"} + ::html::ul -id [my id]_candidates -class region { + #my msg [my options] + foreach o [my options] { + foreach {label rep} $o break + # Don't show current values under candidates + if {[info exists __values($rep)]} continue + ::html::li -class candidates {::html::t $rep} + } + } + } + ::html::div -class visual-clear { + ;# maybe some comment + } + ::html::script { html::t $js } + } + } else { + next + } + } + + ########################################################### + # + # ::xowiki::formfield::abstract_page + # + ########################################################### + + Class abstract_page -superclass candidate_box_select -parameter { + {as_box false} + {multiple_style comma} + } + abstract_page set abstract 1 + + abstract_page instproc initialize {} { + my set package_id [[my object] package_id] + #my compute_options + next + } + + abstract_page instproc fetch_entry_label {entry_label item_id} { + db_1row [my qn [self proc]] "select $entry_label from cr_items ci, cr_revisions cr + where cr.revision_id = ci.live_revision and ci.item_id = $item_id" + return [set $entry_label] + } + abstract_page instproc get_entry_label {value} { + set item_id [[my set package_id] lookup -parent_id [[my object] parent_id] -name $value] + if {$item_id} { + return [::xo::cc cache [list my fetch_entry_label [my entry_label] $item_id]] + } + return "" + } + + abstract_page instproc pretty_value {v} { + my instvar package_id + set object [my object] + set parent_id [$object parent_id] + my set options [my get_labels $v] + if {[my multiple]} { + foreach o [my set options] { + foreach {label value} $o break + set href [$package_id pretty_link -parent_id $parent_id $value] + set labels($value) "$label" + } + set hrefs [list] + foreach i $v { + if {![info exists labels($i)]} { + #my msg "can't determine label for value '$i' (values=$v, l=[array names labels])" + set labels($i) $i + } + set href [$package_id pretty_link -parent_id $parent_id $i] + lappend hrefs "$labels($i)" + } + if {[my multiple_style] eq "list"} { + return "\n" + } else { + return [join $hrefs {, }] + } + } else { + foreach o [my set options] { + foreach {label value} $o break + #my log "comparing '$value' with '$v'" + if {$value eq $v} { + if {[my as_box]} { + return [$object include [list $value -decoration rightbox]] + } + set href [$package_id pretty_link -parent_id $parent_id $value] + return "$label" + } + } + } + } + + abstract_page instproc render_input {} { + my compute_options + next + } + + ########################################################### + # + # ::xowiki::formfield::form_page + # + ########################################################### + Class form_page -superclass abstract_page -parameter { + {form} + {where} + {entry_label title} + } + + form_page instproc initialize {} { + my instvar form_object_item_ids package_id object + if {![my exists form]} { return } + next + set form_name [my form] + set package_id [$object package_id] + set form_objs [::xowiki::Weblog instantiate_forms \ + -parent_id [$object parent_id] \ + -default_lang [$object lang] \ + -forms $form_name -package_id $package_id] + + #set form_obj [[my object] resolve_included_page_name $form_name] + if {$form_objs eq ""} {error "Cannot lookup Form '$form_name'"} + + set form_object_item_ids [list] + foreach form_obj $form_objs {lappend form_object_item_ids [$form_obj item_id]} + } + form_page instproc compute_options {} { + my instvar form_object_item_ids where package_id + #my msg "[my name] compute_options [my exists form]" + if {![my exists form]} { + return + } + + array set wc {tcl true h "" vars "" sql ""} + if {[info exists where]} { + array set wc [::xowiki::FormPage filter_expression $where &&] + #my msg "where '$where' => wc=[array get wc]" + } + + set from_package_ids {} + set package_path [::$package_id package_path] + if {[llength $package_path] > 0} { + foreach p $package_path { + lappend from_package_ids [$p id] + } + } + set items [::xowiki::FormPage get_form_entries \ + -base_item_ids $form_object_item_ids \ + -form_fields [list] \ + -publish_status ready \ + -h_where [array get wc] \ + -package_id $package_id \ + -from_package_ids $from_package_ids] + + set options [list] + foreach i [$items children] { + # + # If the form_page has a different package_id, prepend the + # package_url to the name. TODO: We assume here, that the form_pages + # have no special parent_id. + # + set object_package_id [$i package_id] + if {$package_id != $object_package_id} { + set package_prefix /[$object_package_id package_url] + } else { + set package_prefix "" + } + + lappend options [list [$i title] $package_prefix[$i name]] + } + my options $options + } + + form_page instproc pretty_value {v} { + my options [my get_labels $v] + if {![my exists form_object_item_ids]} { + error "No forms specified for form_field '[my name]'" + } + my set package_id [[lindex [my set form_object_item_ids] 0] package_id] + next + } + + + ########################################################### + # + # ::xowiki::formfield::page + # + ########################################################### + Class page -superclass abstract_page -parameter { + {type ::xowiki::Page} + {with_subtypes false} + {glob} + {entry_label name} + } + + page instproc compute_options {} { + my instvar type with_subtypes glob + + set extra_where_clause "" + if {[my exists glob]} { + append extra_where_clause [::xowiki::Includelet glob_clause $glob] + } + + set package_id [[my object] package_id] + set options [list] + db_foreach [my qn instance_select] \ + [$type instance_select_query \ + -folder_id [$package_id folder_id] \ + -with_subtypes $with_subtypes \ + -select_attributes [list title] \ + -from_clause ", xowiki_page p" \ + -where_clause "p.page_id = bt.revision_id $extra_where_clause" \ + -orderby ci.name \ + ] { + lappend options [list [set [my entry_label]] $name] + } + my options $options + } + + page instproc pretty_value {v} { + my set package_id [[my object] package_id] + next + } + + + + ########################################################### + # + # ::xowiki::formfield::DD + # + ########################################################### + + Class DD -superclass select + 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 HH24 -superclass select + 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 MI -superclass select + 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] + } + } + } + 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 MM -superclass select + 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 mon -superclass select + 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 5 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 month -superclass select + 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 5 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 YYYY -superclass numeric -parameter { + {size 4} + {maxlength 4} + } -extend_slot validator YYYY + + YYYY instproc check=YYYY {value} { + if {$value ne ""} { + return [expr {[catch {clock scan "$value-01-01 00:00:00"}] == 0}] + } + return 1 + } + + ########################################################### + # + # ::xowiki::formfield::youtube_url + # + ########################################################### + Class youtube_url -superclass text + youtube_url set urlre {^http://www.youtube.com/watch[?]v=([^?]+)([?]?)} + + youtube_url instproc initialize {} { + next + if {[my help_text] eq ""} {my help_text "#xowiki.formfield-youtube_url-help_text#"} + } + youtube_url instproc pretty_value {v} { + if {$v eq ""} { + return "" + } elseif {[regexp [[self class] set urlre] $v _ name]} { + return " + + + +\n" + } else { + return "'$v' does not look like a youtube url" + } + } + + ########################################################### + # + # ::xowiki::formfield::image_url + # + ########################################################### + + Class image_url -superclass text \ + -extend_slot validator image_check \ + -parameter { + href cssclass + {float left} width height + padding {padding-right 10px} padding-left padding-top padding-bottom + margin margin-left margin-right margin-top margin-bottom + border border-width position top botton left right + } + image_url instproc initialize {} { + next + if {[my help_text] eq ""} {my help_text "#xowiki.formfield-image_url-help_text#"} + } + image_url instproc entry_name {value} { + set value [string map [list %2e .] $value] + if {![regexp -nocase {/([^/]+)[.](gif|jpg|jpeg|png)} $value _ name ext]} { + return "" + } + return file:$name.$ext + } + image_url instproc check=image_check {value} { + if {$value eq ""} {return 1} + set entry_name [my entry_name $value] + if {$entry_name eq ""} { + my log "--img '$value' does not appear to be an image" + # no image? + return 0 + } + set folder_id [[my object] set parent_id] + if {[::xo::db::CrClass lookup -name $entry_name -parent_id $folder_id]} { + my log "--img entry named $entry_name exists already" + # file exists already + return 1 + } + if {[regexp {^file://(.*)$} $value _ path]} { + set f [open $path r] + fconfigure $f translation binary + set img [read $f] + close $f + } elseif {[catch { + set r [::xo::HttpRequest new -url $value -volatile] + set img [$r set data] + } errorMsg]} { + # cannot transfer image + my log "--img cannot tranfer image '$value' ($errorMsg)" + return 0 + } + #my msg "guess mime_type of $entry_name = [::xowiki::guesstype $entry_name]" + set import_file [ns_tmpnam] + ::xowiki::write_file $import_file $img + set file_object [::xowiki::File new -destroy_on_cleanup \ + -title $entry_name \ + -name $entry_name \ + -parent_id $folder_id \ + -mime_type [::xowiki::guesstype $entry_name] \ + -package_id [[my object] package_id] \ + -creation_user [::xo::cc user_id] \ + ] + $file_object set import_file $import_file + $file_object save_new + return 1 + } + image_url instproc pretty_value {v} { + set entry_name [my entry_name $v] + return [my pretty_image -parent_id [[my object] parent_id] $entry_name] + } + + + ########################################################### + # + # ::xowiki::formfield::include + # + ########################################################### + + # note that the includelet "include" can be used for implementing symbolic links + # to other xowiki pages. + Class include -superclass text -parameter { + } + + include instproc pretty_value {v} { + if {$v eq ""} { return $v } + + my instvar object + set item_id [$object get_property_from_link_page item_id] + if {$item_id == 0} { + # Here, we could call "::xowiki::Link render" to offer the user means + # to create the entry like with [[..]], if he has sufficent permissions...; + # when $(package_id) is 0, the referenced package could not be + # resolved + return "Cannot resolve symbolic link '$v'" + } + set link_type [$object get_property_from_link_page link_type] + $object lappend references [list $item_id $link_type] + + # + # resetting esp. the item-id is dangerous. Therefore we reset it immediately after the rendering + # + $item_id set_resolve_context \ + -package_id [$object package_id] -parent_id [$object parent_id] \ + -item_id [$object item_id] + set html [$item_id render] + #my msg "reset resolve-context" + $item_id reset_resolve_context + + return $html + } + + ########################################################### + # + # ::xowiki::formfield::redirect + # + ########################################################### + + Class redirect -superclass text + redirect instproc pretty_value {v} { + #ad_returnredirect -allow_complete_url $v + #ad_script_abort + return [[[my object] package_id] returnredirect $v] + } + + ########################################################### + # + # ::xowiki::formfield::CompoundField + # + ########################################################### + + Class CompoundField -superclass FormField -parameter { + {components ""} + {CSSclass compound-field} + } -extend_slot validator compound + + CompoundField instproc check=compound {value} { + #my msg "check compound in [my components]" + foreach c [my components] { + set error [$c validate [self]] + if {$error ne ""} { + set msg "[$c label]: $error" + my uplevel [list set errorMsg $msg] + #util_user_message -message "Error in compound field [$c name]: $error" + return 0 + } + } + return 1 + } + + CompoundField instproc set_disabled {disable} { + #my msg "[my name] set disabled $disable" + if {$disable} { + my set disabled true + } else { + my unset -nocomplain disabled + } + foreach c [my components] { + $c set_disabled $disable + } + } + + CompoundField instproc value {args} { + if {[llength $args] == 0} { + set v [my get_compound_value] + #my msg "[my name]: reading compound value => '$v'" + return $v + } else { + #my msg "[my name]: setting compound value => '[lindex $args 0]'" + my set_compound_value [lindex $args 0] + } + } + + CompoundField instproc set_compound_value {value} { + if {[catch {array set {} $value} errorMsg]} { + # this branch could be taken, when the field was retyped + ns_log notice "CompoundField: error during setting compound value with $value: $errorMsg" + } + # set the value parts for each components + foreach c [my components] { + # Set only those parts, for which attribute values pairs are + # given. Components might have their own default values, which + # we do not want to overwrite ... + if {[info exists ([$c name])]} { + $c value $([$c name]) + } + } + } + + CompoundField instproc get_compound_value {} { + # Set the internal representation based on the components values. + set value [list] + foreach c [my components] { + #my msg "lappending [$c name] [$c value] " + lappend value [$c name] [$c value] + } + #my msg "[my name]: get_compound_value returns value=$value" + return $value + } + + CompoundField instproc create_components {spec_list} { + # + # Build a component structure based on a list of specs + # of the form {name spec}. + # + my set structure $spec_list + my set components [list] + foreach entry $spec_list { + foreach {name spec} $entry break + # + # create for each component a form field + # + set c [::xowiki::formfield::FormField create [self]::$name \ + -name [my name].$name -id [my id].$name \ + -locale [my locale] -object [my object] \ + -spec $spec] + my set component_index([my name].$name) $c + my lappend components $c + } + } + + CompoundField instproc get_component {component_name} { + set key component_index([my name].$component_name) + if {[my exists $key]} { + return [my set $key] + } + error "no component named $component_name of compound field [my name]" + } + + CompoundField instproc exists_named_sub_component args { + # Iterate along the argument list to check components of a deeply + # nested structure. For example, + # + # my check_named_sub_component a b + # + # returns 0 or one depending whether there exists a component "a" + # with a subcomponent "b". + set component_name [my name] + set sub [self] + foreach e $args { + append component_name .$e + if {![$sub exists component_index($component_name)]} { + return 0 + } + set sub [$sub set component_index($component_name)] + } + return 1 + } + + CompoundField instproc get_named_sub_component args { + # Iterate along the argument list to get components of a deeply + # nested structure. For example, + # + # my get_named_sub_component a b + # + # returns the object of the subcomponent "b" of component "a" + set component_name [my name] + set sub [self] + foreach e $args { + append component_name .$e + #my msg "check $sub set component_index($component_name)" + set sub [$sub set component_index($component_name)] + } + return $sub + } + + CompoundField instproc get_named_sub_component_value {{-default ""} args} { + if {[eval my exists_named_sub_component $args]} { + return [[eval my get_named_sub_component $args] value] + } else { + return $default + } + } + + CompoundField instproc generate_fieldnames {{-prefix "v-"} n} { + set names [list] + for {set i 1} {$i <= $n} {incr i} {lappend names $prefix$i} + return $names + } + + CompoundField instproc render_input {} { + # + # Render content within in a fieldset, but with labels etc. + # + html::fieldset [my get_attributes id {CSSclass class}] { + foreach c [my components] { $c render } + } + } + + CompoundField instproc has_instance_variable {var value} { + set r [next] + if {$r} {return 1} + foreach c [my components] { + set r [$c has_instance_variable $var $value] + if {$r} {return 1} + } + return 0 + } + + CompoundField instproc convert_to_internal {} { + foreach c [my components] { + $c convert_to_internal + } + } + + CompoundField instproc get_spec {} { + set component_specs [list] + foreach c [my components] { + lappend component_specs [$c get_spec] + } + my set style "margin: 0px; padding: 0px;" + set atts [my get_attributes id style] + return [list "fieldset" $atts $component_specs] + } + + + ########################################################### + # + # ::xowiki::formfield::label + # + ########################################################### + + Class label -superclass FormField -parameter { + {disableOutputEscaping false} + } + label instproc render_item {} { + # sanity check; required and label do not fit well together + if {[my required]} {my required false} + next + } + label instproc render_input {} { + if {[my disableOutputEscaping]} { + ::html::t -disableOutputEscaping [my value] + } else { + ::html::t [my value] + } + # Include labels as hidden fields to avoid surprises when + # switching field types to labels. + my set type hidden + next + } + + + ########################################################### + # + # ::xowiki::formfield::child_pages + # + ########################################################### + Class child_pages -superclass label -parameter { + {form} + {publish_status all} + } + child_pages instproc initialize {} { + next + # + # for now, we allow just FormPages as child_pages + # + if {![my exists form]} { return } + my instvar object + my set form_objs [::xowiki::Weblog instantiate_forms \ + -parent_id [$object parent_id] \ + -default_lang [$object lang] \ + -forms [my form] \ + -package_id [$object package_id]] + } + child_pages instproc pretty_value {v} { + if {[my exists form_objs]} { + my instvar object + set count 0 + foreach form [my set form_objs] { + incr count [$form count_usages \ + -package_id [$object package_id] \ + -parent_id [$object item_id] \ + -publish_status [my publish_status]] + } + return $count + } else { + return 0-NULL + } + } + + ########################################################### + # + # ::xowiki::formfield::date + # + ########################################################### + + Class date -superclass CompoundField -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 + + date instproc initialize {} { + #my msg "DATE has value [my value]//d=[my default] format=[my format] disabled?[my exists disabled]" + my set widget_type date + my set format [string map [list _ " "] [my format]] + my array set defaults {year 2000 month 01 day 01 hour 00 min 00 sec 00} + 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} + } + #my msg "[my name] initialize date, format=[my format] components=[my components]" + foreach c [my components] {$c destroy} + my components [list] + + foreach element [split [my format]] { + if {![my exists format_map($element)]} { + # + # We add undefined formats as literal texts in the edit form + # + set name $element + set c [::xowiki::formfield::label create [self]::$name \ + -name [my name].$name -id [my id].$name \ + -locale [my locale] -object [my object] \ + -value $element] + $c set_disabled [my exists disabled] + if {[lsearch [my components] $c] == -1} {my lappend components $c} + continue + } + foreach {class code trim_zeros} [my set format_map($element)] break + # + # create for each component a form field + # + set name $class + set c [::xowiki::formfield::$class create [self]::$name \ + -name [my name].$name -id [my id].$name \ + -locale [my locale] -object [my object]] + #my msg "creating [my name].$name" + $c set_disabled [my exists disabled] + $c set code $code + $c set trim_zeros $trim_zeros + if {[lsearch [my components] $c] == -1} {my lappend components $c} + } + } + + date instproc set_compound_value {value} { + #my msg "[my name] original value '[my value]' // passed='$value' disa?[my exists disabled]" + # if {$value eq ""} {return} + if { $value eq {} } { + # We need to reset component values so that + # instances of this class can be used as flyweight + # objects. Otherwise, we get side-effects when + # we render the input widget. + foreach c [my components] { + $c value "" + } + return + } + set value [::xo::db::tcl_date $value tz] + #my msg "transformed value '$value'" + if {$value ne ""} { + set ticks [clock scan [string map [list _ " "] $value]] + } else { + set ticks "" + } + my set defaults(year) [clock format $ticks -format %Y] + my set defaults(month) [clock format $ticks -format %m] + my set defaults(day) [clock format $ticks -format %e] + my set defaults(hour) [clock format $ticks -format %H] + my set defaults(min) [clock format $ticks -format %M] + #my set defaults(sec) [clock format $ticks -format %S] + + # set the value parts for each components + foreach c [my components] { + if {[$c istype ::xowiki::formfield::label]} continue + if {$ticks ne ""} { + set value_part [clock format $ticks -format [$c set code]] + if {[$c set trim_zeros]} { + set value_part [string trimleft $value_part 0] + if {$value_part eq ""} {set value_part 0} + } + } else { + set value_part "" + } + #my msg "ticks=$ticks $c value $value_part" + $c value $value_part + } + } + + 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 "" + } + # Validation happens after the value is retrieved. + # To avoid errors in "clock scan", fix the year if necessary + if {![string is integer $year]} {set year 0} + + foreach v [list year month day hour min sec] { + if {[set $v] eq ""} {set $v [my set defaults($v)]} + } + #my msg "$year-$month-$day ${hour}:${min}:${sec}" + if {[catch {set ticks [clock scan "$year-$month-$day ${hour}:${min}:${sec}"]}]} { + set ticks 0 ;# we assume that the validator flags these values + } + # TODO: TZ??? + #my msg "DATE [my name] get_compound_value returns [clock format $ticks -format {%Y-%m-%d %T}]" + return [clock format $ticks -format "%Y-%m-%d %T"] + } + + date instproc pretty_value {v} { + my instvar display_format + # + # Internally, we use the ansi date format. For displaying the date, + # use the specified display format and present the time localized. + # + # 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]]] + if {$display_format eq "pretty-age"} { + return [::xowiki::utility pretty_age -timestamp [clock scan $v] -locale [my locale]] + } else { + return [lc_time_fmt $v [string map [list _ " "] [my display_format]] [my locale]] + } + } + + date instproc render_input {} { + # + # render the content inline withing a fieldset, without labels etc. + # + my set style "margin: 0px; padding: 0px;" + html::fieldset [my get_attributes id style] { + foreach c [my components] { $c render_input } + } + } + + + ########################################################### + # + # ::xowiki::boolean + # + ########################################################### + + Class boolean -superclass radio -parameter { + {default t} + } + boolean instproc value_if_nothing_is_returned_from_form {default} { + if {[my exists disabled]} {return $default} else {return f} + } + boolean instproc initialize {} { + # should be with cvs head message catalogs: + my options {{#acs-kernel.common_Yes# t} {#acs-kernel.common_No# f}} + #my options {{No f} {#acs-kernel.common_Yes# t}} + next + } + + ########################################################### + # + # ::xowiki::boolean_image + # + ########################################################### + + Class create boolean_image -superclass FormField -parameter { + {default t} + {t_img_url /resources/xowiki/examples/check_richtig.png} + {f_img_url /resources/xowiki/examples/check_falsch.png} + {CSSclass img_boolean} + } + boolean_image instproc initialize {} { + my type hidden + my set widget_type boolean(hidden) + } + boolean_image instproc render_input {} { + my instvar t_img_url f_img_url CSSclass + set title [expr {[my exists __render_help_text_as_title_attr] ? [my set help_text] : ""}] + ::html::img \ + -title $title \ + -class $CSSclass \ + -src [expr {[my value] ? $t_img_url : $f_img_url}] \ + -onclick "toggle_img_boolean(this,'$t_img_url','$f_img_url')" + ::html::input -type hidden -name [my name] -value [my value] + + ::xo::Page requireJS { + function toggle_img_boolean (element,t_img_url,f_img_url) { + var input = $(element).next(); + var state = input.val()== "t"; + if (state) { + input.val('f'); + $(element).attr('src',f_img_url); + } else { + input.val('t'); + $(element).attr('src',t_img_url); + } + } + } + } + + ########################################################### + # + # ::xowiki::formfield::scale + # + ########################################################### + + Class scale -superclass radio -parameter {{n 5} {horizontal true}} + 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 + } + + + ########################################################### + # + # ::xowiki::formfield::form + # + ########################################################### + + Class form -superclass richtext -parameter { + {height 200} + } -extend_slot validator form + + form instproc check=form {value} { + set form $value + #my msg form=$form + dom parse -simple -html $form doc + $doc documentElement root + set rootNodeName "" + if {$root ne ""} {set rootNodeName [$root nodeName]} + return [expr {$rootNodeName eq "form"}] + } + + ########################################################### + # + # ::xowiki::formfield::form_constraints + # + ########################################################### + + Class form_constraints -superclass textarea -parameter { + {rows 5} + } -extend_slot validator form_constraints + # the form_constraints checker is defined already on the ::xowiki::Page level + + + ########################################################### + # + # ::xowiki::formfield::event + # + ########################################################### + + Class event -superclass CompoundField -parameter { + {multiday false} + } + + event instproc initialize {} { + #my msg "event initialize [my exists __initialized], multi=[my multiday] state=[my set __state]" + if {[my set __state] ne "after_specs"} return + my set widget_type event + if {[my multiday]} { + set dtend_format DD_MONTH_YYYY_#xowiki.event-hour_prefix#_HH24_MI + set dtend_display_format %Q_%X + } else { + set dtend_format HH24_MI + set dtend_display_format %X + } + my create_components [subst { + {summary {richtext,required,editor=wym,height=150px,label=#xowiki.event-title_of_event#}} + {dtstart {date,required,format=DD_MONTH_YYYY_#xowiki.event-hour_prefix#_HH24_MI, + default=now,label=#xowiki.event-start_of_event#,display_format=%Q_%X}} + {dtend date,format=$dtend_format,default=now,label=#xowiki.event-end_of_event#,display_format=$dtend_display_format} + {location text,label=#xowiki.event-location#} + }] + my set __initialized 1 + } + + event instproc get_compound_value {} { + if {![my exists __initialized]} { + return "" + } + set dtstart [my get_component dtstart] + set dtend [my get_component dtend] + if {![my multiday]} { + # If the event is not a multi-day-event, the end_day is not + # given by the dtend widget, but is taken from dtstart. + set end_day [lindex [$dtstart value] 0] + set end_time [lindex [$dtend value] 1] + $dtend value "$end_day $end_time" + #my msg "[$dtend name] set to '$end_day $end_time' ==> $dtend, [$dtend value]" + } + next + } + + event instproc pretty_value {v} { + array set {} [my value] + set dtstart [my get_component dtstart] + set dtstart_val [$dtstart value] + set dtstart_iso [::xo::ical clock_to_iso [clock scan $dtstart_val]] + + set dtend [my get_component dtend] + set dtend_val [$dtend value] + set dtend_txt "" + if {$dtend_val ne ""} { + set dtend_iso [::xo::ical clock_to_iso [clock scan $dtend_val]] + set dtend_txt " - [$dtend pretty_value $dtend_val]" + } + + set summary_txt "[[my get_component summary] value]" + set location [my get_component location] + set location_val [$location value] + set location_txt "" + if {$location_val ne ""} { + set location_label [$location label] + if {[regexp {^#(.+)#$} $location_label _ msg_key]} { + set location_label [lang::message::lookup [my locale] $msg_key] + } + set location_txt "$location_label: $location_val" + } + + append result \ + "
    " \ + $summary_txt " " \ + "[$dtstart pretty_value $dtstart_val]" \ + $dtend_txt
    \ + $location_txt \ + "
    " + return $result + } + + + ########################################################### + # + # ::xowiki::formfield::repeatable + # + ########################################################### + + Class repeatable -superclass enumeration -parameter { + {min_elements 2} + {max_elements ""} + {repeat_type "text"} + } -extend_slot validator repeatable_num_of_elements + + repeatable instproc initialize {} { + my set type text + my set repeat_type "[namespace tail [my info class]]" ;# ::xowiki::formfield::date -> repeat_type=date + next + } + + repeatable instproc convert_to_internal {} { + set value [my value] + set new_value [list] + set isCompoundField [llength [my procsearch components]] + foreach v $value { + if { $v eq {} } { continue } + if { $isCompoundField} { + my value [list $v] + } else { + my value $v + } + next + # + # Whatever the effect of next, we still need + # to take it into account. + # + set new_v [[my object] get_property -name [my name]] + if { $new_v ne $value } { + lappend new_value $new_v + } + } + if { $new_value ne {} } { + [my object] set_property -new 1 [my name] $new_value + } + } + + repeatable instproc convert_to_external {value} { + set new_value [list] + foreach v $value { + lappend new_value [next $v] + } + return $new_value + } + + repeatable instproc set_compound_value {value} { + set c "" + array set values [list] + foreach v $value { + next $v + foreach c [my components] { + lappend values($c) [$c value] + } + } + if { $c ne {} } { + foreach c [my components] { + $c value $values($c) + } + } } + repeatable instproc get_compound_value {} { + # Iterate over all values so that inherited + # class methods would work, for instance, + # date, can only process one value at a time. + + set c "" + array set values [list] + foreach c [my components] { + set values($c) [$c value] + } + + set result [list] + if { $c ne {} } { + + # treat compound values one at a time + set count [llength $values($c)] + for {set i 0} {$i < $count} {incr i} { + foreach c [my components] { + $c value [lindex $values($c) $i] + } + lappend result [next] + } + + # restore values + foreach c [my components] { + $c value $values($c) + } + + } + return $result + } + + repeatable instproc validation_check {validator_method value} { + if { [string match {check=repeatable_*} $validator_method] } { + return [next] + } else { + foreach v $value { + if { ![my $validator_method $v] } { + return 0 + } + } + return 1 + } + } + + repeatable instproc check=repeatable_num_of_elements {value} { + my instvar min_elements max_elements + + set num_elements [llength [lsearch -not -all $value ""]] + ns_log notice "name=[my name] value= $value (ensure num_elements=$num_elements between $min_elements and [util_coalesce $max_elements +inf])" + ns_log notice "" + if { $num_elements < $min_elements } { + return 0 + } elseif { $max_elements ne {} && $num_elements > $max_elements } { + return 0 + } + } + + repeatable instproc render_input {} { + + if { ![my exists disabled] } { + my set disabled false + } + + if { ![my disabled] } { + ::xo::Page requireJS "/resources/xowiki/wu-repeatable.js" + } + + my instvar min_elements repeat_type + # sample data: my set value "a b c" + #my set value "a" + + # Note that we have a spec parameter that refers to + # the form definition, and a get_spec proc that refers + # to the specification for generating html and json. + set flyweight [::xowiki::formfield::$repeat_type new \ + -name [my name] \ + -locale [my locale] \ + -object [my object] \ + -proc get_spec {} { + lassign [next] tag atts children + lappend atts rep 1 + return [list $tag $atts $children] + }] + + + set rep 0 + foreach v [my value] { + incr rep + ::html::div { + ::html::div -class "wu-repeatable-arrows" { + ::html::a -class wu-repeatable-action -href "#" -onclick "return wu.repeatable.moveUp(this)" + + $flyweight id [my id]:$rep + $flyweight value $v + $flyweight render_input + if { ![my disabled] } { + ::html::a -href "#" -onclick "return wu.repeatable.delChoice(this)" { html::t "\[x\]" } + } + } + } + } + + for {set i $rep} {$i < $min_elements} {incr i} { + incr rep + ::html::div { + ::html::div -class "wu-repeatable-arrows" { + ::html::a -class wu-repeatable-action -href "#" -onclick "return wu.repeatable.moveUp(this)" + + $flyweight id [my id]:$rep + $flyweight value "" + $flyweight render_input + + if { ![my disabled] } { + ::html::a -href "#" -onclick "return wu.repeatable.delChoice(this)" { html::t "\[x\]" } + } + } + } + } + + if { ![my disabled] } { + $flyweight value "" + set spec [$flyweight get_json] + html::a -spec $spec -href "#" -onclick "return wu.repeatable.addChoice(this);" { html::t "add another" } + } + } + +} + +::xo::library source_dependent Index: openacs-4/packages/xowiki/tcl/import-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/import-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/import-procs.tcl 13 Sep 2012 16:05:27 -0000 1.26 @@ -0,0 +1,503 @@ +::xo::library doc { + XoWiki - importer + + @creation-date 2008-04-25 + @author Gustaf Neumann + @cvs-id $Id: import-procs.tcl,v 1.26 2012/09/13 16:05:27 victorg Exp $ +} + + +namespace eval ::xowiki { + + Class Importer -parameter { + {added 0} {replaced 0} {updated 0} {inherited 0} + {package_id} {parent_id} {user_id} + } + Importer instproc init {} { + my set log "" + my destroy_on_cleanup + } + Importer instproc report_lines {} { + return "[my set log]
    " + } + Importer instproc report_line {obj operation} { + set href [$obj pretty_link] + set name [[$obj package_id] external_name -parent_id [$obj parent_id] [$obj name]] + my append log "$operation$name\n" + } + Importer instproc report {} { + my instvar added updated replaced inherited + return "$added objects newly inserted,\ + $updated objects updated, $replaced objects replaced, $inherited inherited (update ignored)

    \ + [my report_lines]" + } + + Importer instproc import {-object:required -replace -create_user_ids} { + # + # Import a single object. In essence, this method demarshalls a + # single object and inserts it (or updates it) in the database. It + # takes as well care about categories. + # + my instvar package_id user_id + + $object demarshall -parent_id [$object parent_id] -package_id $package_id \ + -creation_user $user_id -create_user_ids $create_user_ids + set item_id [::xo::db::CrClass lookup -name [$object name] -parent_id [$object parent_id]] + #my msg "lookup of [$object name] parent [$object parent_id] => $item_id" + if {$item_id != 0} { + if {$replace} { ;# we delete the original + ::xo::db::CrClass delete -item_id $item_id + set item_id 0 + my report_line $object replaced + my incr replaced + } else { + #my msg "$item_id update: [$object name]" + ::xo::db::CrClass get_instance_from_db -item_id $item_id + $item_id copy_content_vars -from_object $object + $item_id save -use_given_publish_date [$item_id exists publish_date] \ + -modifying_user [$object set modifying_user] + #my log "$item_id saved" + $object set item_id [$item_id item_id] + #my msg "$item_id updated: [$object name]" + my report_line $item_id updated + my incr updated + } + } + if {$item_id == 0} { + set n [$object save_new -use_given_publish_date [$object exists publish_date] \ + -creation_user [$object set modifying_user] ] + $object set item_id $n + set item_id $object + #my msg "$object added: [$object name]" + my report_line $object added + my incr added + } + # + # The method demarshall might set the mapped __category_ids in $object. + # Insert these into the category object map + # + if {[$object exists __category_ids]} { + #my msg "$item_id map_categories [object set __category_ids] // [$item_id item_id]" + $item_id map_categories [$object set __category_ids] + } + + $package_id flush_references -item_id [$object item_id] -name [$object name] + } + + Importer instproc import_all {-replace -objects:required {-create_user_ids 0} {-keep_inherited 1}} { + # + # Import a series of objects. This method takes care especially + # about dependencies of objects, which is reflected by the order + # of object-imports. + # + # + # Extact information from objects to be imported, that might be + # changed later in the objects. + # + foreach o $objects { + # + # Remember old item_ids and old_names for pages with + # item_ids. Only these can have parents (page_templates) or + # child_objects + # + if {[$o exists item_id]} { + set item_ids([$o item_id]) $o + set old_names([$o item_id]) [$o name] + } { + $o item_id "" + } + # Remember old parent_ids for name-mapping, names are + # significant per parent_id. + if {[$o exists parent_id]} { + set parent_ids([$o item_id]) [$o parent_id] + } { + $o parent_id "" + } + set todo($o) 1 + + # + # Handle import of categories in the first pass + # + if {[$o exists __map_command]} { + $o package_id [my package_id] + $o eval [$o set __map_command] + } + # FIXME remove? + #if {[$o exists __category_map]} { + # array set ::__category_map [$o set __category_map] + #} + } + #my msg "item_ids=[array names item_ids], parent_ids=[array names parent_ids]" + + # + # Make a fix-point iteration during import. Do only import, when + # all prerequirement pages are already loaded. + # + while {[llength [array names todo]] > 0} { + set new 0 + foreach o [array names todo] { + #my msg "work on $o [$o info class] [$o name]" + + set old_name [$o name] + set old_item_id [$o item_id] + set old_parent_id [$o parent_id] + + # page instances have references to page templates, add the templates first + if {[$o istype ::xowiki::PageInstance]} { + set old_template_id [$o page_template] + if {![info exists old_names($old_template_id)]} { + set new 0 + my msg "need name for $old_template_id. Maybe item_ids for PageTemplate missing?" + break + } + + set template_name_key $parent_ids($old_template_id)-$old_names($old_template_id) + if {![info exists name_map($template_name_key)]} { + #my msg "... delay import of $o (no object with name $template_name_key) imported" + continue + } + #my msg "we found entry for name_map($template_name_key) = $name_map($template_name_key)" + } + + if {[info exists item_ids($old_parent_id)]} { + # we have a child object + if {![info exists id_map($old_parent_id)]} { + #my msg "... delay import of $o (map of parent_id $old_parent_id missing)" + continue + } + } + + set need_to_import 1 + # + # If the page was implicitly added (due to being a + # page_template of an exported page), and a page (e.g. a form + # or a workflow) with the same name can be found in the + # target, don't materialize the inherited page. + # + if {$keep_inherited + && [$o exists __export_reason] + && [$o set __export_reason] eq "implicit_page_template"} { + $o unset __export_reason + set page [[my package_id] get_page_from_item_ref \ + -allow_cross_package_item_refs false \ + -use_package_path true \ + -use_site_wide_pages true \ + -use_prototype_pages false \ + [$o name] \ + ] + + # If we would like to restrict to just inherited pages in + # the target, we could extend the test below with a test like + # the following: + # set inherited [expr {[$page physical_parent_id] ne [$page parent_id]}] + + if {$page ne ""} { + #my msg "page [$o name] can ne found in folder [my parent_id]" + my incr inherited + unset todo($o) + set o $page + set need_to_import 0 + } + } + + if {$need_to_import} { + # Now, all requirements are met, parent-object and + # child-object conditions are fulfilled. We have to map + # page_template for PageInstances and parent_ids for child + # objects to new IDs. + # + if {[$o istype ::xowiki::PageInstance]} { + #my msg "importing [$o name] page_instance, map $template_name_key to $name_map($template_name_key)" + $o page_template $name_map($template_name_key) + #my msg "exists template? [my isobject [$o page_template]]" + if {![my isobject [$o page_template]]} { + ::xo::db::CrClass get_instance_from_db -item_id [$o page_template] + #my msg "[my isobject [$o page_template]] loaded" + } + } + + if {[info exists item_ids($old_parent_id)]} { + $o set parent_id $id_map($old_parent_id) + } else { + $o set parent_id [my parent_id] + } + + # Everything is mapped, we can now do the import. + + #my msg "start import for $o, name=[$o name]" + my import \ + -object $o \ + -replace $replace \ + -create_user_ids $create_user_ids + #my msg "import for $o done, name=[$o name]" + + unset todo($o) + } + + # + # Maintain the maps and iterate + # + if {$old_item_id ne ""} { + set id_map($old_item_id) [$o item_id] + } + set name_map($old_parent_id-$old_name) [$o item_id] + #my msg "setting name_map($old_parent_id-$old_name)=$name_map($old_parent_id-$old_name), o=$o, old_item_id=$old_item_id" + + set new 1 + } + if {$new == 0} { + my msg "could not import [array names todo]" + break + } + } + #my msg "final name_map=[array get name_map], id_map=[array get id_map]" + + # + # final cleanup + # + foreach o $objects {$o destroy} + + [my package_id] flush_page_fragment_cache + } + + # + # A small helper for exporting objects + # + + Object create exporter + exporter proc include_needed_objects {item_ids} { + # + # Load the objects + # + foreach item_id $item_ids { + if {[::xo::db::CrClass get_instance_from_db -item_id $item_id] eq ""} { + my log "Warning: cannot fetch item $item_id for exporting" + } else { + set items($item_id) 1 + } + } + + # + # In a second step, include the objects which should be exported implicitly + # + while {1} { + set new 0 + ns_log notice "--export works on [array names items]" + foreach item_id [array names items] { + # + # We flag the reason, why the implicitely included elements were + # included. If the target can resolve already such items + # (e.g. forms), we might not have to materialize these finally. + # + # For PageInstances (or its subtypes), include the parent-objects as well + # + if {[$item_id istype ::xowiki::PageInstance]} { + set template_id [$item_id page_template] + if {![info exists items($template_id)]} { + ns_log notice "--export including parent-object $template_id [$template_id name]" + set items($template_id) 1 + ::xo::db::CrClass get_instance_from_db -item_id $template_id + set new 1 + $template_id set __export_reason implicit_page_template + continue + } + } + # + # check for child objects of the item + # + set sql [::xowiki::Page instance_select_query -folder_id $item_id -with_subtypes true] + db_foreach instance_select $sql { + if {![info exists items($item_id)]} { + ::xo::db::CrClass get_instance_from_db -item_id $item_id + ns_log notice "--export including child $item_id [$item_id name]" + set items($item_id) 1 + set new 1 + $item_id set __export_reason implicit_child_page + } + } + } + if {!$new} break + } + return [array names items] + } + + exporter proc marshall_all {item_ids} { + set content "" + foreach item_id $item_ids { + if {[catch {set obj [$item_id marshall]} errorMsg]} { + ns_log error "Error while exporting $item_id [$item_id name]\n$errorMsg\n$::errorInfo" + } else { + append content $obj\n + } + } + return $content + } + + exporter proc export {item_ids} { + # + # include implictely needed objects, instantiate the objects. + # + set item_ids [my include_needed_objects $item_ids] + # + # stream the objects via ns_write + # + ns_set put [ns_conn outputheaders] "Content-Type" "text/plain" + ns_set put [ns_conn outputheaders] "Content-Disposition" "attachment;filename=export.xotcl" + ReturnHeaders + + foreach item_id $item_ids { + ns_log notice "--exporting $item_id [$item_id name]" + if {[catch {set obj [$item_id marshall]} errorMsg]} { + ns_log error "Error while exporting $item_id [$item_id name]\n$errorMsg\n$::errorInfo" + } else { + ns_write "$obj\n" + } + } + } + + + # + # Simple archive file manager + # + # The Archive manages supports importing .zip files and .tar.gz + # files as ::xowiki::File into xowiki folders. + # + ::xotcl::Class create ArchiveFile -parameter { + file + name + parent_id + {use_photo_form false} + } + ArchiveFile instproc init {} { + my destroy_on_cleanup + ::xo::db::CrClass get_instance_from_db -item_id [my parent_id] + my set tmpdir [ns_tmpnam] + file mkdir [my set tmpdir] + } + ArchiveFile instproc delete {} { + file delete -force [my set tmpdir] + next + } + ArchiveFile instproc unpack {} { + my instvar name file + set success 0 + #my log "::xowiki::guesstype '$name' => [::xowiki::guesstype $name]" + switch [::xowiki::guesstype $name] { + application/zip - + application/x-zip - + application/x-zip-compressed { + set zipcmd [::util::which unzip] + #my msg "zip = $zipcmd, tempdir = [my set tmpdir]" + exec $zipcmd $file -d [my set tmpdir] + my import -dir [my set tmpdir] -parent_id [my parent_id] + set success 1 + } + application/x-compressed { + if {[string match *tar.gz $name]} { + set cmd [::util::which tar] + exec $cmd -xzf $file -C [my set tmpdir] + my import -dir [my set tmpdir] -parent_id [my parent_id] + set success 1 + } else { + my msg "unknown compressed file type $name" + } + } + default {my msg "type [::xowiki::guesstype $name] of $name unknown"} + } + #my msg success=$success + return $success + } + ArchiveFile instproc import {-dir -parent_id} { + set package_id [$parent_id package_id] + + foreach tmpfile [glob -nocomplain -directory $dir *] { + #my msg "work on $tmpfile [::file isdirectory $tmpfile]" + set file_name [::file tail $tmpfile] + if {[::file isdirectory $tmpfile]} { + # ignore mac os x resource fork directories + if {[string match *__MACOSX $tmpfile]} continue + set folder_object [$package_id get_page_from_name -assume_folder true \ + -name $file_name -parent_id $parent_id] + if {$folder_object ne ""} { + # if the folder exists already, we have nothing to do + } else { + # we create a new folder ... + set folder_form_id [::xowiki::Weblog instantiate_forms -forms en:folder.form \ + -package_id $package_id] + set folder_object [FormPage new -destroy_on_cleanup \ + -title $file_name \ + -name $file_name \ + -package_id $package_id \ + -parent_id $parent_id \ + -nls_language en_US \ + -instance_attributes {} \ + -page_template $folder_form_id] + $folder_object save_new + # ..... and refetch it under its canonical name + ::xo::db::CrClass get_instance_from_db -item_id [$folder_object item_id] + } + my import -dir $tmpfile -parent_id [$folder_object item_id] + } else { + set mime_type [::xowiki::guesstype $file_name] + if {[string match image/* $mime_type] && [my use_photo_form]} { + set photo_object [$package_id get_page_from_name -name en:$file_name -parent_id $parent_id] + if {$photo_object ne ""} { + # photo entry exists already, create a new revision + my log "Photo $file_name exists already" + $photo_object set title $file_name + set f [::xowiki::formfield::file new -object $photo_object -name "image" -destroy_on_cleanup] + $f set value $file_name + $f content-type $mime_type + $f set tmpfile $tmpfile + $f convert_to_internal + $photo_object save + } else { + # create a new photo entry + my log "new Photo $file_name" + set photoFormObj [::xowiki::Weblog instantiate_forms \ + -parent_id $parent_id -forms en:photo.form -package_id $package_id] + set photo_object [$photoFormObj create_form_page_instance \ + -name en:$file_name \ + -nls_language en_US \ + -creation_user [::xo::cc user_id] \ + -parent_id $parent_id \ + -package_id $package_id \ + -instance_attributes [list image $file_name]] + $photo_object title $file_name + $photo_object publish_status "ready" + $photo_object save_new ;# to obtain item_id needed by the form-field + set f [::xowiki::formfield::file new -object $photo_object -name "image" -destroy_on_cleanup] + $f set value $file_name + $f content-type $mime_type + $f set tmpfile $tmpfile + $f convert_to_internal + #my log "after convert to internal $file_name" + } + } else { + set file_object [$package_id get_page_from_name -name file:$file_name -parent_id $parent_id] + if {$file_object ne ""} { + my msg "file $file_name exists already" + # file entry exists already, create a new revision + $file_object set import_file $tmpfile + $file_object set mime_type $mime_type + $file_object set title $file_name + $file_object save + } else { + my msg "file $file_name created new" + set file_object [::xowiki::File new -destroy_on_cleanup \ + -title $file_name \ + -name file:$file_name \ + -parent_id $parent_id \ + -mime_type $mime_type \ + -package_id $package_id \ + -creation_user [::xo::cc user_id] ] + $file_object set import_file $tmpfile + $file_object save_new + } + } + } + } + } +} +::xo::library source_dependent + Index: openacs-4/packages/xowiki/tcl/includelet-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/includelet-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/includelet-procs.tcl 13 Sep 2012 16:05:27 -0000 1.183 @@ -0,0 +1,4529 @@ +::xo::library doc { + XoWiki - define various kind of includelets + + @creation-date 2006-10-10 + @author Gustaf Neumann + @cvs-id $Id: includelet-procs.tcl,v 1.183 2012/09/13 16:05:27 victorg Exp $ +} +namespace eval ::xowiki::includelet { + # + # Define a meta-class for creating Includelet classes. + # We use a meta-class for making it easier to define properties + # on classes of includelets, which can be used without instantiating + # it. One can for example use the query from the page fragment + # cache the caching properties of the class. + # + Class create ::xowiki::IncludeletClass \ + -superclass ::xotcl::Class \ + -parameter { + {localized true} + {personalized true} + {cacheable false} + {aggregating false} + } + + # The general superclass for includelets + + Class create ::xowiki::Includelet \ + -superclass ::xo::Context \ + -parameter { + {name ""} + {title ""} + {__decoration "portlet"} + {parameter_declaration {}} + {id} + } +#2.8.0r4 + ::xowiki::Includelet proc require_YUI_CSS {{-version 2.7.0} {-ajaxhelper true} path} { + if {$ajaxhelper} { + ::xo::Page requireCSS "/resources/ajaxhelper/yui/$path" + } else { + ::xo::Page requireCSS "http://yui.yahooapis.com/$version/build/$path" + } + } + + ::xowiki::Includelet proc require_YUI_JS {{-version 2.7.0} {-ajaxhelper true} path} { + if {$ajaxhelper} { + ::xo::Page requireJS "/resources/ajaxhelper/yui/$path" + } else { + ::xo::Page requireJS "http://yui.yahooapis.com/$version/build/$path" + } + } + + ::xowiki::Includelet proc describe_includelets {includelet_classes} { + #my log "--plc=$includelet_classes " + foreach cl $includelet_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::Includelet proc available_includelets {} { + if {[my array exists html]} {my array unset html} + my describe_includelets [::xowiki::Includelet info subclass] + set result "

    " + return $result + } + + ::xowiki::Includelet proc html_to_text {string} { + return [string map [list "&" &] $string] + } + + ::xowiki::Includelet proc js_name {name} { + return [string map [list : _ # _] $name] + } + + ::xowiki::Includelet proc js_encode {string} { + string map [list \n \\n \" {\"} ' {\'}] $string + } + + ::xowiki::Includelet proc html_encode {string} { + # ' is not a known entity to some validators, so we use the + # numerical entity here for encoding "'" + return [string map [list & "&" < "<" > ">" \" """ ' "'"] $string] + } + + + ::xowiki::Includelet proc html_id {name} { + # Construct a valid HTML id or name. + # For details, see http://www.w3.org/TR/html4/types.html + # + # For XOTcl object names, strip first the colons + set name [string trimleft $name :] + + # make sure, the ID starts with characters + if {![regexp {^[A-Za-z]} $name]} { + set name id_$name + } + + # replace unwanted characters + regsub -all {[^A-Za-z0-9_:.-]} $name _ name + return $name + } + + ::xowiki::Includelet proc publish_status_clause {{-base_table ci} value} { + if {$value eq "all"} { + # legacy + set publish_status_clause "" + } else { + array set valid_state [list production 1 ready 1 live 1 expired 1] + set clauses [list] + foreach state [split $value |] { + if {![info exists valid_state($state)]} { + error "no such state: '$state'; valid states are: production, ready, live, expired" + } + lappend clauses "$base_table.publish_status='$state'" + } + set publish_status_clause " and ([join $clauses { or }])" + } + return $publish_status_clause + } + + ::xowiki::Includelet proc locale_clause { + -revisions + -items + 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 + } + #my msg "--L with_system_locale=$with_system_locale, locale=$locale, default_locale=$default_locale" + + set locale_clause "" + if {$locale ne ""} { + set locale_clause " and $revisions.nls_language = '$locale'" + if {$with_system_locale} { + set system_locale [lang::system::locale -package_id $package_id] + #my msg "system_locale=$system_locale, default_locale=$default_locale" + if {$system_locale ne $default_locale} { + set locale_clause " and ($revisions.nls_language = '$locale' + or $revisions.nls_language = '$system_locale' and not exists + (select 1 from cr_items i where i.name = '[string range $locale 0 1]:' || + substring($items.name,4) and i.parent_id = $items.parent_id))" + } + } + } + + #my msg "--locale $locale, def=$default_locale sys=$system_locale, cl=$locale_clause locale_clause=$locale_clause" + return [list $locale $locale_clause] + } + + ::xowiki::Includelet 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 = $item_ref 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::Includelet proc parent_id_clause { + {-base_table bt} + {-use_package_path true} + {-parent_id ""} + -base_package_id:required + } { + # + # Get the package path and from it, the folder_ids. The parent_id + # of the returned pages should be a direct child of the folder. + # + if {$parent_id eq ""} { + set parent_id [$base_package_id folder_id] + } + set packages [$base_package_id package_path] + if {$use_package_path && [llength $packages] > 0} { + set parent_ids [list $parent_id] + foreach p $packages {lappend parent_ids [$p folder_id]} + return "$base_table.parent_id in ([join $parent_ids ,])" + } else { + return "$base_table.parent_id = $parent_id" + } + } + + ::xowiki::Includelet proc glob_clause {{-base_table ci} {-attribute name} value} { + # Return a clause for name matching. + # value uses * for matching + set glob [string map [list * %] $value] + return " and $base_table.$attribute like '$glob'" + } + + # + # Other helpers + # + + ::xowiki::Includelet proc listing { + -package_id + {-count:boolean false} + {-folder_id} + {-parent_id ""} + {-page_size 20} + {-page_number ""} + {-orderby ""} + {-use_package_path true} + {-extra_where_clause ""} + {-glob ""} + } { + if {$count} { + set attribute_selection "count(*)" + set orderby "" ;# no need to order when we count + set page_number "" ;# no pagination when count is used + } else { + set attribute_selection "i.name, r.title, p.page_id, r.publish_date, \ + r.mime_type, i.parent_id, o.package_id, \ + to_char(r.publish_date,'YYYY-MM-DD HH24:MI:SS') as formatted_date" + } + if {$page_number ne ""} { + set limit $page_size + set offset [expr {$page_size*($page_number-1)}] + } else { + set limit "" + set offset "" + } + set parent_id_clause [::xowiki::Includelet parent_id_clause \ + -base_table i \ + -use_package_path $use_package_path \ + -parent_id $parent_id \ + -base_package_id $package_id] + + if {$glob ne ""} { + append extra_where_clause [::xowiki::Includelet glob_clause -base_table i $glob] + } + + set sql [::xo::db::sql select \ + -vars $attribute_selection \ + -from "cr_items i, cr_revisions r, xowiki_page p, acs_objects o" \ + -where "$parent_id_clause \ + and r.revision_id = i.live_revision \ + and i.item_id = o.object_id \ + and p.page_id = r.revision_id \ + and i.publish_status <> 'production' $extra_where_clause" \ + -orderby $orderby \ + -limit $limit -offset $offset] + + if {$count} { + return [db_string [my qn count_listing] $sql] + } else { + set s [::xowiki::Page instantiate_objects -sql $sql] + return $s + } + } + + + # + # inherited methods for all includelets + # + + ::xowiki::Includelet instproc resolve_page_name {page_name} { + return [[my set __including_page] resolve_included_page_name $page_name] + } + + ::xowiki::Includelet instproc get_page_order {-source -ordered_pages -pages} { + my instvar page_order ordered_pages + # + # first check, if we can load the page_order from the page + # denoted by source + # + if {[info exists source]} { + set p [my resolve_page_name $source] + if {$p ne ""} { + array set ia [$p set instance_attributes] + if {[info exists ia(pages)]} { + set pages $ia(pages) + } elseif {[info exists ia(ordered_pages)]} { + set ordered_pages $ia(ordered_pages) + } + } + } + + # 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]} + } + } + + ::xowiki::Includelet instproc include_head_entries {} { + # The purpose of this method is to contain all calls to include + # CSS files, javascript, etc. in the HTML Head. This kind of + # requirements could as well be included e.g. in render, but this + # won't work, if "render" is cached. This method is called before + # render to be executed even when render is not due to caching. + # It is intended to be overloaded by subclasses. + } + + ::xowiki::Includelet instproc initialize {} { + # This method is called at a time after init and before render. + # It can be used to alter specified parameter from the user, + # or to influence the rendering of a decoration (e.g. title etc.) + } + + ::xowiki::Includelet instproc js_name {} { + return [[self class] js_name [self]] + } + + ::xowiki::Includelet 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)}] + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + ::xowiki::IncludeletClass create available-includelets \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "The following includelets can be used in a page"} + } + + available-includelets instproc render {} { + my get_parameters + return [::xowiki::Includelet available_includelets] + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # Page Fragment Cache + # + # The following mixin-class implements page fragment caching in the + # xowiki-cache. Caching can be turned on for every + # ::xowiki::IncludeletClass instance. + # + # Fragment caching depends in the class variables + # - cacheable (the mixin is only registered, when cacheable is set to true) + # - aggregating (requires flusing when items are added/edited/deleted) + # - localized (dependency on locale) + # - personalized (dependency on userid) + # + Class create ::xowiki::includelet::page_fragment_cache -instproc render {} { + set c [my info class] + # + # Construct a key based on the class parameters and the + # actual parameters + # + set key "PF-[my package_id]-" + append key [expr {[$c aggregating] ? "agg" : "ind"}] + append key "-$c [my set __caller_parameters]" + if {[$c localized]} {append key -[my locale]} + if {[$c personalized]} {append key -[::xo::cc user_id]} + # + # Get the HTML from the rendered includelet by calling "next" + # + set HTML [ns_cache eval xowiki_cache $key next] + # + # Some side-effects might be necessary, even when the HTML output + # of the includelet is cached (e.g. some associative arrays, + # etc.). For this purpose, we provide here a means to cache + # additional some "includelet data", if the includelet provides + # it. + # + if {[catch {set data [ns_cache get xowiki_cache $key-data]}]} { + my cache_includelet_data $key-data + } else { + #my msg "eval $data" + eval $data + } + return $HTML + } -instproc cache_includelet_data {key} { + #my msg "data=[next]" + set data [next] + if {$data ne ""} {ns_cache set xowiki_cache $key $data} + } +} +namespace eval ::xowiki::includelet { + ############################################################################# + # dotlrn style includelet decoration for includelets + # + Class create ::xowiki::includelet::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 localized_title [::xo::localize $title] + set link [expr {[string match "*:*" $name] ? + "$localized_title" : + $localized_title}] + ::xo::render_localizer + 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 create ::xowiki::includelet::decoration=edit -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 localized_title [::xo::localize $title] + set edit_button [my include [list edit-item-button -book_mode true]] + set link [expr {[string match "*:*" $name] ? + "$localized_title" : + $localized_title}] + return [subst [[self class] set template]] + } -set template {
    +
    $edit_button
    +
    $html
    + } + + Class create ::xowiki::includelet::decoration=plain -instproc render {} { + set class [namespace tail [my info class]] + set id [expr {[my exists id] ? "id='[my id]'" : ""}] + return "
    [next]
    " + } + + Class create ::xowiki::includelet::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::includelet { + + ::xowiki::IncludeletClass create get \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-variable} + {-form_variable} + {-source ""} + }} + } -instproc render {} { + my get_parameters + if {![info exists variable] && ![info exists form_variable]} { + return "either -variable or -form_variable must be specified" + } + set page [my resolve_page_name $source] + + if {[info exists variable] && [$page exists $variable]} { + return [$page set $variable] + } + if {[info exists form_variable] && [$page exists instance_attributes]} { + array set __ia [$page set instance_attributes] + if {[info exists __ia($form_variable)]} { + return $__ia($form_variable) + } + } + if {[info exists variable]} { + return "no such variable $variable defined in page [$page set name]" + } + return "no such form_variable $form_variable defined in page [$page set name]" + } + + ::xowiki::IncludeletClass create creation-date \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-source ""} + {-format "%m-%d-%Y"} + }} + } -instproc render {} { + my get_parameters + set page [my resolve_page_name $source] + set time [$page set creation_date] + regexp {^([^.]+)[.]} $time _ time + return [lc_time_fmt [clock format [clock scan $time] -format "%Y-%m-%d %H:%M:%S"] $format [my locale]] + #return [clock format [clock scan $time] -format $format] + } + + ############################################################################# + # rss button + # + ::xowiki::IncludeletClass create rss-button \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-span "10d"} + {-name_filter} + {-entries_of} + {-title} + }} + } + + rss-button instproc render {} { + my get_parameters + set parent_ids [[my set __including_page] parent_id] + set href [export_vars -base [$package_id package_url] {{rss $span} parent_ids name_filter title entries_of}] + regsub -all & $href "&" href + ::xo::Page requireLink -rel alternate -type application/rss+xml -title RSS -href $href + return "RSS" + } + + ############################################################################# + # bookmarklet button + # + ::xowiki::IncludeletClass create bookmarklet-button \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-siteurl ""} + {-label ""} + }} + } + + bookmarklet-button instproc render {} { + my get_parameters + set parent_id [[my set __including_page] parent_id] + set url [$package_id pretty_link -absolute 1 -siteurl $siteurl -parent_id $parent_id news-item] + if {$label eq ""} {set label "Add to [$package_id instance_name]"} + set href [subst -nocommands -nobackslash { + javascript:d=document;w=window;t=''; + if(d.selection){t=d.selection.createRange().text} else + if(d.getSelection){t=d.getSelection()} else + if(w.getSelection){t=w.getSelection()} + void(open('$url?m=create-new&title='+escape(d.title)+ + '&detail_link='+escape(d.location.href)+'&text='+escape(t),'_blank', + 'scrollbars=yes,width=700,height=575,status=yes,resizable=yes,scrollbars=yes')) + }] + regsub -all {[\n ]+} $href " " href + regsub -all & $href "&" href + return "$label" + } + + ############################################################################# + # set-parameter "includelet" + # + ::xowiki::IncludeletClass create set-parameter \ + -superclass ::xowiki::Includelet \ + -parameter {{__decoration none}} + + 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::includelet { + ############################################################################# + # valid parameters for he categories includelet 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 + + ::xowiki::IncludeletClass create categories \ + -superclass ::xowiki::Includelet \ + -cacheable true -personalized false -aggregating true \ + -parameter { + {title "#xowiki.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"} + {-style "mktree"} + {-category_ids ""} + {-except_category_ids ""} + {-allow_edit false} + {-ordered_composite} + }} + } + + categories instproc initialize {} { + my get_parameters + if {!$tree_style} { + set style sections + } + my set style $style + } + + categories instproc include_head_entries {} { + ::xowiki::Tree include_head_entries -renderer [my set style] + } + + categories instproc category_tree_edit_button {-object_id:integer -locale {-allow_edit false} -tree_id:integer} { + set allow_p [::xo::cc permission -object_id $object_id -privilege admin -party_id [::xo::cc set untrusted_user_id]] + if {$allow_edit && $allow_p} { + if {[info exists tree_id]} { + # + # If a tree_id is given, edit directly the category tree ... + # + set href "[[my package_id] package_url]?edit-category-tree&object_id=$object_id&tree_id=$tree_id" + return [[my set __including_page] include \ + [list edit-item-button -link $href -title "Edit Category Tree" -target _blank]] + } else { + # + # ... otherwise, manage categories (allow defining new category trees, map/unmap, etc.) + # + set href "[[my package_id] package_url]?manage-categories&object_id=$object_id" + return [[my set __including_page] include \ + [list edit-item-button -link $href -title "Manage Categories" -target _blank]]] + } + } + return "" + } + categories instproc category_tree_missing {{-name ""} -edit_html} { + # todo i18n + if {$name eq ""} { + #set msg "No category tree found." + # maybe it is better to stay quiet in case, no category name was provided + set msg "" + } else { + set msg "No category tree with name '$name' found." + } + [my package_id] flush_page_fragment_cache -scope agg + set html "
    $msg
    " + if {$edit_html ne ""} { + return "$html Manage Categories? $edit_html" + } + return $html + } + + categories instproc render {} { + my get_parameters + + set content "" + set folder_id [$package_id folder_id] + set open_item_id [expr {$open_page ne "" ? + [::xo::db::CrClass lookup -name $open_page -parent_id $folder_id] : 0}] + + foreach {locale locale_clause} \ + [::xowiki::Includelet locale_clause -revisions r -items ci $package_id $locale] break + + set trees [::xowiki::Category get_mapped_trees -object_id $package_id -locale $locale \ + -names $tree_name \ + -output {tree_id tree_name}] + + #my msg "[llength $trees] == 0 && $tree_name" + if {[llength $trees] == 0 && $tree_name ne ""} { + # we have nothing left from mapped trees, maybe the tree_names are not mapped; + # try to get these + foreach name $tree_name { + #set tree_id [lindex [category_tree::get_id $tree_name $locale] 0] + set tree_id [lindex [category_tree::get_id $tree_name] 0] + if {$tree_id ne ""} { + lappend trees [list $tree_id $name] + } + } + } + + set edit_html [my category_tree_edit_button -object_id $package_id -allow_edit $allow_edit] + if {[llength $trees] == 0} { + return [my category_tree_missing -name $tree_name -edit_html $edit_html] + } + + if {![my exists id]} {my set id [::xowiki::Includelet html_id [self]]} + + foreach tree $trees { + foreach {tree_id my_tree_name ...} $tree {break} + + set edit_html [my category_tree_edit_button -object_id $package_id \ + -allow_edit $allow_edit -tree_id $tree_id] + #append content "
    $edit_html
    \n" + + if {!$no_tree_name} { + append content "

    $my_tree_name $edit_html

    " + } elseif {$edit_html ne ""} { + append content "$edit_html
    " + } + set categories [list] + set pos 0 + set cattree(0) [::xowiki::Tree new -volatile -orderby pos \ + -id [my id]-$my_tree_name -name $my_tree_name] + + set category_infos [::xowiki::Category get_category_infos \ + -locale $locale -tree_id $tree_id] + foreach category_info $category_infos { + foreach {cid category_label deprecated_p level} $category_info {break} + set c [::xowiki::TreeNode new -orderby pos \ + -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 + } + + if {[llength $categories] == 0} { + return $content + } + + if {[info exists ordered_composite]} { + set items [list] + foreach c [$ordered_composite children] {lappend items [$c item_id]} + + # If we have no item, provide a dummy one to avoid sql error + # later + if {[llength $items]<1} {set items -4711} + + if {$count} { + set sql "category_object_map c + where c.object_id in ([join $items ,]) " + } else { + # TODO: the non-count-part for the ordered_composite is not + # tested yet. Although "ordered compostite" can be used + # only programmatically for now, the code below should be + # tested. It would be as well possible to obtain titles and + # names etc. from the ordered composite, resulting in a + # faster SQL like above. + set sql "category_object_map c, cr_items ci, cr_revisions r + where c.object_id in ([join $items ,]) + and c.object_id = ci.item_id and + and r.revision_id = ci.live_revision + " + } + } else { + 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 c.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 -style [my set style]] + } else { + foreach {orderby direction} [split $order_items_by ,] break ;# e.g. "title,asc" + set increasing [expr {$direction ne "desc"}] + set order_column ", p.page_order" + + db_foreach [my qn get_pages] \ + "select ci.item_id, ci.name, ci.parent_id, 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]} + $itemobj set href [::$package_id pretty_link -parent_id $parent_id $name] + $cattree(0) add_item \ + -category $category($category_id) \ + -itemobj $itemobj \ + -orderby $orderby \ + -increasing $increasing \ + -open_item [expr {$item_id == $open_item_id}] + } + append content [$cattree(0) render -style [my set style]] + } + } + return $content + } +} + + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # 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 + + ::xowiki::IncludeletClass create categories-recent \ + -superclass ::xowiki::Includelet \ + -cacheable true -personalized false -aggregating true \ + -parameter { + {title "#xowiki.recently_changed_pages_by_categories#"} + {parameter_declaration { + {-max_entries:integer 10} + {-tree_name ""} + {-locale ""} + {-pretty_age "off"} + }} + } + + categories-recent instproc initialize {} { + my set style sections + # When pretty age is activated, this includedlet is not suited for + # caching (it could make sense e.g. when the age granularity is 1 + # minute or more). This measure here (turing off caching + # completely) is a little bit too much, but it is safe. + my get_parameters + if {[[my info class] cacheable] && $pretty_age ne "off"} { + [my info class] cacheable false + } + } + + categories-recent instproc include_head_entries {} { + ::xowiki::Tree include_head_entries -renderer [my set style] + } + + categories-recent instproc render {} { + my get_parameters + + if {![my exists id]} {my set id [::xowiki::Includelet html_id [self]]} + set cattree [::xowiki::Tree new -volatile -id [my id]] + + foreach {locale locale_clause} \ + [::xowiki::Includelet locale_clause -revisions r -items ci $package_id $locale] break + + set tree_ids [::xowiki::Category get_mapped_trees -object_id $package_id -locale $locale \ + -names $tree_name -output tree_id] + + if {$tree_ids ne ""} { + 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, ci.parent_id, 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 "" + set suffix "" + switch -- $pretty_age { + 1 {set suffix " ([::xowiki::utility pretty_age -timestamp [clock scan $formatted_date] -locale [my locale]])"} + 2 {set suffix "([::xowiki::utility pretty_age -timestamp [clock scan $formatted_date] -locale [my locale] -levels 2])"} + default {set prefix "$formatted_date "} + } + if {$prefix ne ""} {set prefix "$prefix";$itemobj set encoded(prefix) 1} + if {$suffix ne ""} {set suffix "$suffix";$itemobj set encoded(suffix) 1} + foreach var {name title prefix suffix} {$itemobj set $var [set $var]} + $itemobj set href [::$package_id pretty_link -parent_id $parent_id $name] + + if {![info exists categories($category_id)]} { + set categories($category_id) [::xowiki::TreeNode new \ + -label [category::get_name $category_id $locale] \ + -level 1] + $cattree add $categories($category_id) + } + $cattree add_item -category $categories($category_id) -itemobj $itemobj + } + return [$cattree render -style [my set style]] + } +} + + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # display recent entries + # + + ::xowiki::IncludeletClass create recent \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "#xowiki.recently_changed_pages#"} + {parameter_declaration { + {-max_entries:integer 10} + {-allow_edit:boolean false} + {-allow_delete:boolean false} + {-pretty_age off} + }} + } + + recent instproc render {} { + my get_parameters + ::xo::Page requireCSS "/resources/acs-templating/lists.css" + set admin_p [::xo::cc permission -object_id $package_id -privilege admin \ + -party_id [::xo::cc set untrusted_user_id]] + set show_heritage $admin_p + + TableWidget t1 -volatile \ + -set allow_edit $allow_edit \ + -set allow_delete $allow_delete \ + -set show_heritage $admin_p \ + -columns { + Field date -label [_ xowiki.Page-last_modified] + if {[[my info parent] set allow_edit]} { + AnchorField edit -CSSclass edit-item-button -label "" -html {style "padding-right: 2px;"} -richtext 1 + } + if {[[my info parent] set show_heritage]} { + AnchorField inherited -label "" -CSSclass inherited + } + AnchorField title -label [::xowiki::Page::slot::title set pretty_name] + if {[[my info parent] set allow_delete]} { + AnchorField delete -CSSclass delete-item-button -label "" -richtext 1 + } + } + + set listing [::xowiki::Includelet listing \ + -package_id $package_id -page_number 1 -page_size $max_entries \ + -orderby "publish_date desc"] + + foreach entry [$listing children] { + $entry instvar parent_id formatted_date page_id {title entry_title} {name entry_name} + set entry_package_id [$entry set package_id] + + set page_link [$entry_package_id pretty_link -parent_id $parent_id $entry_name] + switch -- $pretty_age { + 1 {set age [::xowiki::utility pretty_age -timestamp [clock scan $formatted_date] -locale [my locale]]} + 2 {set age [::xowiki::utility pretty_age -timestamp [clock scan $formatted_date] -locale [my locale] -levels 2]} + default {set age $formatted_date} + } + + t1 add \ + -title $entry_title \ + -title.href $page_link \ + -date $age + + if {$allow_edit} { + set p [::xo::db::CrClass get_instance_from_db -item_id 0 -revision_id $page_id] + set edit_link [$entry_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 + [t1 last_child] set edit " " + } + if {$allow_delete} { + if {![info exists p]} { + set p [::xo::db::CrClass get_instance_from_db -item_id 0 -revision_id $page_id] + } + set delete_link [$entry_package_id make_link -link $page_link $p delete return_url] + [t1 last_child] set delete.href $delete_link + [t1 last_child] set delete " " + } + if {$show_heritage} { + if {$entry_package_id == [my package_id]} { + set href "" + set title "" + set alt "" + set class "" + set label "" + } else { + # provide a link to the original + set href $page_link + set label [$entry_package_id instance_name] + set title [_ xowiki.view_in_context [list context $label]] + set alt $title + set class "inherited" + } + [t1 last_child] set inherited $label + [t1 last_child] set inherited.href $href + [t1 last_child] set inherited.title $title + [t1 last_child] set inherited.CSSclass $class + } + } + return [t1 asHTML] + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # display last visited entries + # + + ::xowiki::IncludeletClass create last-visited \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "#xowiki.last_visited_pages#"} + {parameter_declaration { + {-max_entries:integer 20} + }} + } + + last-visited instproc render {} { + my get_parameters + ::xo::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 "i.parent_id, 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 set untrusted_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 -parent_id $parent_id $name] + } + return [t1 asHTML] + } +} + + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # list the most popular pages + # + + ::xowiki::IncludeletClass create most-popular \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "#xowiki.most_popular_pages#"} + {parameter_declaration { + {-max_entries:integer "10"} + {-interval} + }} + } + + most-popular instproc render {} { + my get_parameters + ::xo::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, i.parent_id" \ + -from "xowiki_last_visited x, xowiki_page p, cr_items i, cr_revisions r" \ + -where "x.package_id = $package_id and x.page_id = i.item_id and \ + i.publish_status <> 'production' and i.live_revision = r.revision_id \ + and $since_condition" \ + -groupby "x.page_id, r.title, i.name, i.parent_id" \ + -orderby "nr_different_users desc" \ + -limit $max_entries ] { + t1 add \ + -title $title \ + -title.href [$package_id pretty_link -parent_id $parent_id $name] \ + -users $nr_different_users + } + } else { + + TableWidget t1 -volatile \ + -columns { + AnchorField title -label [::xowiki::Page::slot::title set pretty_name] + Field count -label [_ xowiki.includelets-visits] -html { align right } + Field users -label [_ xowiki.includelet-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, i.parent_id" \ + -from "xowiki_last_visited x, cr_items i, cr_revisions r" \ + -where "x.package_id = $package_id and x.page_id = i.item_id and \ + i.publish_status <> 'production' and i.live_revision = r.revision_id" \ + -groupby "x.page_id, r.title, i.name, i.parent_id" \ + -orderby "sum desc" \ + -limit $max_entries] { + t1 add \ + -title $title \ + -title.href [$package_id pretty_link -parent_id $parent_id $name] \ + -users $nr_different_users \ + -count $sum + } + } + return [t1 asHTML] + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # list the most frequent visitors + # + + ::xowiki::IncludeletClass create rss-client \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "#xowiki.rss_client#"} + {parameter_declaration { + {-url:required} + {-max_entries:integer "15"} + }} + } + + rss-client instproc initialize {} { + my instvar feed + my get_parameters + my set feed [::xowiki::RSS-client new -url $url -destroy_on_cleanup] + if {[info command [$feed channel]] ne ""} { + my title [ [$feed channel] title] + } + } + + rss-client instproc render {} { + my instvar feed + my get_parameters + if {[info command [$feed channel]] eq ""} { + set detail "" + if {[$feed exists errorMessage]} {set detail \n[$feed set errorMessage]} + return "No data available from $url
    $detail" + } else { + set channel [$feed channel] + #set html "

    [$channel title]

    " + set html "\n" + return $html + } + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # list the most frequent visitors + # + + ::xowiki::IncludeletClass create most-frequent-visitors \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "#xowiki.most_frequent_visitors#"} + {parameter_declaration { + {-max_entries:integer "15"} + }} + } + + most-frequent-visitors instproc render {} { + my get_parameters + ::xo::Page requireCSS "/resources/acs-templating/lists.css" + + TableWidget t1 -volatile \ + -columns { + Field user -label Visitors -html { align right } + Field count -label Visits -html { align right } + } + db_foreach [my qn get_pages] \ + [::xo::db::sql select \ + -vars "sum(count) as sum, user_id" \ + -from "xowiki_last_visited" \ + -where "package_id = $package_id" \ + -groupby "user_id" \ + -orderby "sum desc" \ + -limit $max_entries] { + t1 add \ + -user [::xo::get_user_name $user_id] \ + -count $sum + } + return [t1 asHTML] + } + +} + + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # 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?) + # + + ::xowiki::IncludeletClass create unread-items \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "#xowiki.unread_items#"} + {parameter_declaration { + {-max_entries:integer 20} + }} + } + + unread-items instproc render {} { + my get_parameters + ::xo::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 + and x.user_id = [::xo::cc user_id] + )" + + set or_clause "" + + db_foreach [my qn get_pages] \ + [::xo::db::sql select \ + -vars "a.title, i.name, i.parent_id" \ + -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 -parent_id $parent_id $name] + } + return [t1 asHTML] + } +} + + + + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # Show the tags + # + + ::xowiki::IncludeletClass create tags \ + -superclass ::xowiki::Includelet \ + -parameter { + {title "Tags"} + {parameter_declaration { + {-limit:integer 20} + {-summary:boolean 0} + {-popular:boolean 0} + {-page} + }} + } + + tags instproc render {} { + my get_parameters + ::xo::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 href [$package_id package_url]tag/ + db_foreach [my qn get_counts] $sql { + set q [list] + if {$summary} {lappend q "summary=$summary"} + if {$popular} {lappend q "popular=$popular"} + set link $href$tag?[join $q &] + #lappend entries "$tag ($nr)" + lappend entries "$tag " + } + return [expr {[llength $entries] > 0 ? + "

    $label

    [join $entries {, }]
    \n" : + ""}] + } + + ::xowiki::IncludeletClass create my-tags \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-summary 1} + }} + id + } + + my-tags instproc render {} { + my get_parameters + my instvar __including_page tags + ::xo::Page requireJS "/resources/xowiki/get-http-object.js" + + set p_link [$__including_page pretty_link] + 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&tag + + set entries [list] + + #foreach tag $tags {lappend entries "$tag"} + set href [$package_id package_url]/tag/ + foreach tag $tags {lappend entries ""} + set tags_with_links [join [lsort $entries] {, }] + + if {![my exists id]} {my set id [::xowiki::Includelet html_id [self]]} + set content [subst -nobackslashes { + #xowiki.your_tags_label#: $tags_with_links + (#xowiki.edit_link#, + #xowiki.popular_tags_link#) + +
    + }] + return $content + } + + + ::xowiki::IncludeletClass create my-categories \ + -superclass ::xowiki::Includelet \ + -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 "#xowiki.categories#: [join $entries {, }]" + } + return $content + } + + ::xowiki::IncludeletClass create my-general-comments \ + -superclass ::xowiki::Includelet \ + -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] + # Even, if general_comments is turned on, don't offer the + # link to add comments, unless the user is logged in. + # Otherwise, this attracts spammers and search bots + if {[::xo::cc user_id] != 0} { + set gc_link [general_comments_create_link \ + -object_name [$__including_page title] \ + $item_id $gc_return_url] + set gc_link

    $gc_link

    + } else { + set gc_link "" + } + set gc_comments [general_comments_get_comments $item_id $gc_return_url] + if {$gc_comments ne ""} { + return "

    #general-comments.Comments#

    $gc_link" + } else { + return "$gc_link" + } + } + + ::xowiki::IncludeletClass create digg \ + -superclass ::xowiki::Includelet \ + -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]"} + }] + regsub -all & $digg_link "&" digg_link + return "Digg!" + } + + ::xowiki::IncludeletClass create delicious \ + -superclass ::xowiki::Includelet \ + -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 + }] + regsub -all & $delicious_link "&" delicious_link + return "Add to your del.icio.usdel.icio.us" + } + + + ::xowiki::IncludeletClass create my-yahoo-publisher \ + -superclass ::xowiki::Includelet \ + -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 get_parameter PackageTitle [$package_id instance_name]]] + 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!" + } + + + # + # my-references lists the pages which are refering to the + # including page + # + ::xowiki::IncludeletClass create my-references \ + -superclass ::xowiki::Includelet \ + -parameter {{__decoration none}} + + my-references instproc render {} { + my get_parameters + my instvar __including_page + + set item_id [$__including_page item_id] + set refs [list] + # The same image might be linked both, as img or file on one page, + # so we need DISTINCT. + + db_foreach [my qn get_references] "SELECT DISTINCT page,ci.name,ci.parent_id,o.package_id as pid \ + from xowiki_references,cr_items ci,acs_objects o \ + where reference=$item_id and ci.item_id = page and ci.item_id = o.object_id" { + if {$pid eq ""} { + # in version less then oacs 5.2, this returns empty + set pid [db_string _ "select package_id from cr_folders where folder_id = :parent_id"] + } + if {$pid ne ""} { + ::xowiki::Package require $pid + 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 + } + + # + # my-refers lists the pages which are refered to by the + # including page + # + ::xowiki::IncludeletClass create my-refers \ + -superclass ::xowiki::Includelet \ + -parameter {{__decoration none}} + + my-refers instproc render {} { + my get_parameters + my instvar __including_page + + set item_id [$__including_page item_id] + set refs [list] + + db_foreach [my qn get_refers] "SELECT DISTINCT reference,ci.name,ci.parent_id,o.package_id as pid \ + from xowiki_references,cr_items ci,acs_objects o \ + where page=$item_id and ci.item_id = reference and ci.item_id = o.object_id" { + if {$pid eq ""} { + # in version less then oacs 5.2, this returns empty + set pid [db_string _ "select package_id from cr_folders where folder_id = :parent_id"] + } + if {$pid ne ""} { + ::xowiki::Package require $pid + 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_of_label# $references" + } + if {$lang(undefined) ne ""} { + append result "#xowiki.create_this_page_in_language# $lang(undefined)" + } + return $result + } + +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # presence + # + ::xowiki::IncludeletClass create presence \ + -superclass ::xowiki::Includelet \ + -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(distinct user_id) from xowiki_last_visited WHERE $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::includelet { + ############################################################################# + # includelets based on order + # + Class create PageReorderSupport + PageReorderSupport instproc page_reorder_check_allow {{-with_head_entries true} allow_reorder} { + if {$allow_reorder ne ""} { + my instvar package_id + set granted [$package_id check_permissions \ + -user_id [[$package_id context] user_id] \ + -package_id $package_id \ + $package_id change-page-order] + #my msg "granted=$granted" + if {$granted} { + if {$with_head_entries} { + set ajaxhelper 1 + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "utilities/utilities.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "selector/selector-min.js" + ::xo::Page requireJS "/resources/xowiki/yui-page-order-region.js" + } + } else { + # the user has not enough permissions, so disallow + set allow_reorder "" + } + } + return $allow_reorder + } + + PageReorderSupport instproc page_reorder_init_vars {-allow_reorder js_ last_level_ ID_ min_level_} { + my upvar $js_ js $last_level_ last_level $ID_ ID $min_level_ min_level + set js "YAHOO.xo_page_order_region.DDApp.package_url = '[[my package_id] package_url]';\n" + set last_level 0 + set ID [my js_name] + if {[string is integer -strict $allow_reorder]} { + set min_level $allow_reorder + } else { + set min_level 1 + } + } + PageReorderSupport instproc page_reorder_open_ul {-min_level -ID -prefix_js l} { + set l1 [expr {$l + 2}] + set id ${ID}__l${l1}_${prefix_js} + set css_class [expr {$l1 >= $min_level ? "page_order_region" : "page_order_region_no_target"}] + return "\n" } + for {set l $last_level} {$l < $level} {incr l} { + regsub -all {[.]} $prefix _ prefix_js + append output [my page_reorder_open_ul -min_level $min_level -ID $ID -prefix_js $prefix_js $l] + } + set last_level $level + set last_prefix $prefix + } + # Pass the page_order for the element to javascript and add + # the li element for the section. + set item_id [my page_reorder_item_id -ID $ID -prefix_js $prefix_js -page_order $page_order js] + append output "
  • " + } + + set p [::xo::db::CrClass get_instance_from_db -item_id 0 -revision_id $page_id] + + $p set unresolved_references 0 + #$p set render_adp 0 + switch [$p info class] { + ::xowiki::Form { + set content [$p render] + } + default { + set content [$p render -with_footer false] + #set content [string map [list "\{\{" "\\\{\{"] $content] + } + } + + append output [my render_item \ + -menu_buttons $menu_buttons \ + -content $content \ + -object $p \ + -level $level] + if {$with_footer} { + append output [$p htmlFooter -content $content] + } + } + + if {$allow_reorder ne ""} { + for {set l $last_level} {$l > 0} {incr l -1} {append output "\n" } + append output "\n" + } + return $output + } + + book instproc render_images {-addClass pages} { + # + # Return a list of the rendered images in HTML markup. The page + # content is reduced to a bare image. Note that this function + # does not return "pages" not containing images. + # + set imageList {} + foreach o [$pages children] { + set p [::xo::db::CrClass get_instance_from_db -item_id 0 -revision_id [$o set page_id]] + set html [$p render -with_footer false] + if {[regsub -nocase {^(.*)(]+>)(.*)$} $html {\2} html] < 1} continue + if {[info exists addClass]} { + regsub -nocase {class\s*=\s*'([^']+)'} $html "class='\\1 $addClass'" html + } + lappend imageList $html + } + return $imageList + } + + 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 allow_reorder [my page_reorder_check_allow $allow_reorder] + + set extra_where_clause "" + set cnames "" + if {[info exists category_id]} { + foreach {cnames extra_where_clause} [my category_clause $category_id] break + } + + foreach {locale locale_clause} \ + [::xowiki::Includelet locale_clause -revisions p -items p $package_id $locale] break + + if {$folder_mode} { + # TODO just needed for michael aram? + set parent_id [$__including_page item_id] + } else { + #set parent_id [$package_id folder_id] + set parent_id [$__including_page parent_id] + } + + 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 = $parent_id \ + and not page_order is NULL $extra_where_clause \ + $locale_clause \ + [::xowiki::Page container_already_rendered item_id]" ] + $pages mixin add ::xo::OrderedComposite::IndexCompare + $pages orderby page_order + + # + # filter range + # + if {$range ne ""} { + foreach {from to} [split $range -] break + foreach p [$pages children] { + if {[$pages __value_compare [$p set page_order] $from 0] == -1 + || [$pages __value_compare [$p set page_order] $to 0] > 0} { + $pages delete $p + } + } + } + + if {[llength [$pages children]] < 1} { + # + # Provide a hint why not pages were found + # + set p [::xo::db::CrClass get_instance_from_db -item_id $parent_id] + set output "

    No pages with parent object [$p name], page_order not NULL and an appropriate publish status found

    \n" + } else { + set output [my render_items \ + -menu_buttons $menu_buttons \ + -with_footer $with_footer \ + -pages $pages \ + -cnames $cnames \ + -allow_reorder $allow_reorder] + } + return $output + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # display a sequence of pages via W3C slidy + # + ::xowiki::IncludeletClass create slidy \ + -superclass ::xowiki::includelet::book + + slidy instproc render_items { + -pages:required + {-cnames ""} + {-allow_reorder ""} + -menu_buttons + {-with_footer "false"} + } { + my instvar __including_page + if {$cnames ne "" || $allow_reorder ne "" || $with_footer ne "false"} { + error "ignoring cnames, allow_reorder, and with_footer for the time being" + } + + set output "" + foreach o [$pages children] { + set p [::xo::db::CrClass get_instance_from_db -item_id 0 -revision_id [$o set page_id]] + append output "
    \n" [$p render -with_footer false] "\n
    \n" + } + + ns_return 200 text/html [subst { + + [$__including_page title] + + + + + +$output + + }] + ad_script_abort + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # display a sequence of pages via jQuery Carousel + # + ::xowiki::IncludeletClass create jquery-carousel \ + -superclass ::xowiki::includelet::book + + jquery-carousel instproc render_items { + -pages:required + {-cnames ""} + {-allow_reorder ""} + -menu_buttons + {-with_footer "false"} + } { + my instvar __including_page + if {$cnames ne "" || $allow_reorder ne "" || $with_footer ne "false"} { + error "ignoring cnames, allow_reorder, and with_footer for the time being" + } + + set id [my js_name] + append output \ + "
      \n" \ +
    • [join [my render_images $pages] "
    • \n
    • "]
    • \ + "
    \n" + + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" + ::xo::Page requireJS "/resources/xowiki/jquery.carousel.min.js" + ::xo::Page requireJS [subst -novariables { + $(function(){ + $("#[set id]").carousel( ); + }); + }] + return $output + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # Display a sequence of images via the jQuery plugin + # + # Infinite Carousel + # + # http://www.catchmyfame.com/2009/08/27/jquery-infinite-carousel-plugin-1-2-released/ + # + # This includelet works only with images + # + # Install: obtain jQuery plugin + # + # http://www.catchmyfame.com/jquery/jquery.infinitecarousel2.zip + # + # and install its files under packages/xowiki/resources/infiniteCarousel: + # + # infiniteCarousel/images/caption.gif + # infiniteCarousel/images/leftright.gif + # infiniteCarousel/images/playpause.gif + # infiniteCarousel/jquery.infinitecarousel2.js + # infiniteCarousel/jquery.infinitecarousel2.min.js + # + ::xowiki::IncludeletClass create jquery-infinite-carousel \ + -superclass ::xowiki::includelet::book + + jquery-infinite-carousel instproc render_items { + -pages:required + {-cnames ""} + {-allow_reorder ""} + -menu_buttons + {-with_footer "false"} + } { + my instvar __including_page + if {$cnames ne "" || $allow_reorder ne "" || $with_footer ne "false"} { + error "ignoring cnames, allow_reorder, and with_footer for the time being" + } + + set id [my js_name] + append output \ + "
      \n" \ +
    • [join [my render_images $pages] "
    • \n
    • "]
    • \ + "
    \n" + + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" + ::xo::Page requireJS "/resources/xowiki/infiniteCarousel/jquery.infinitecarousel2.min.js" + ::xo::Page requireJS [subst -novariables { + $(function(){ + $("#[set id]").infiniteCarousel({ + displayTime: 6000, + textholderHeight : .25, + imagePath: '/resources/xowiki/infiniteCarousel/images/', + }); + });}] + + return $output + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # Display a sequence of images via 3D Cloud Carousel + # + # This includelet works only with images. + # + # Install: get the jQuery plugins cloud-carousel and mousewheel from + # + # http://www.professorcloud.com/mainsite/carousel.htm + # https://github.com/brandonaaron/jquery-mousewheel/downloads + # + # and install these files under + # + # packages/xowiki/resources/cloud-carousel.1.0.5.min.js + # packages/xowiki/resources/jquery.mousewheel.min.js + # + # The following elements might be used in the page containing the includelet: + # + # + # + # + #

    + # + + ::xowiki::IncludeletClass create jquery-cloud-carousel \ + -superclass ::xowiki::includelet::book + + jquery-cloud-carousel instproc render_items { + -pages:required + {-cnames ""} + {-allow_reorder ""} + -menu_buttons + {-with_footer "false"} + } { + my instvar __including_page + if {$cnames ne "" || $allow_reorder ne "" || $with_footer ne "false"} { + error "ignoring cnames, allow_reorder, and with_footer for the time being" + } + + set id [my js_name] + append output \ + "
    " \ + [join [my render_images -addClass cloudcarousel $pages] "\n"] \ + "
    \n" + + ::xo::Page requireStyle "div.jquery-cloud-carousel div {width:650px; height:400px;background:#000;}" + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" + ::xo::Page requireJS "/resources/xowiki/jquery.mousewheel.min.js" + ::xo::Page requireJS "/resources/xowiki/cloud-carousel.1.0.5.min.js" + + ::xo::Page requireJS [subst -novariables { + $(function(){ + $("#[set id]").CloudCarousel( + { + xPos: 300, + yPos: 32, + buttonLeft: $("#left-but"), + buttonRight: $("#right-but"), + altBox: $("#alt-text"), + titleBox: $("#title-text"), + bringToFront: true, + mouseWheel:true + } + ); + }); + }] + return $output + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # Display a sequence of images via jQuery spacegallery + # + # This includelet works only with images + # + # Install: get the jQuery plugin spacegallery from + # http://www.eyecon.ro/spacegallery/ + # and install its files under packages/xowiki/resources/spacegallery: + # + # spacegallery/css/custom.css + # spacegallery/css/layout.css + # spacegallery/css/spacegallery.css + # spacegallery/images/ajax_small.gif + # spacegallery/images/blank.gif + # spacegallery/images/bw1.jpg + # spacegallery/images/bw2.jpg + # spacegallery/images/bw3.jpg + # spacegallery/images/lights1.jpg + # spacegallery/images/lights2.jpg + # spacegallery/images/lights3.jpg + # spacegallery/index.html + # spacegallery/js/eye.js + # spacegallery/js/jquery.js + # spacegallery/js/layout.js + # spacegallery/js/spacegallery.js + # spacegallery/js/utils.js + # spacegallery/spacegallery.css + # + # You might want to adapt spacegallery/spacegallery.css according to + # your needs. + + ::xowiki::IncludeletClass create jquery-spacegallery \ + -superclass ::xowiki::includelet::book + + jquery-spacegallery instproc render_items { + -pages:required + {-cnames ""} + {-allow_reorder ""} + -menu_buttons + {-with_footer "false"} + } { + my instvar __including_page + if {$cnames ne "" || $allow_reorder ne "" || $with_footer ne "false"} { + error "ignoring cnames, allow_reorder, and with_footer for the time being" + } + + set id [my js_name] + append output \ + "
    \n" \ + [join [my render_images $pages] "\n"] \ + "
    \n" + + ::xo::Page requireStyle "div.spacegallery {width:600px; height:450px;}" + ::xo::Page requireCSS "/resources/xowiki/spacegallery/spacegallery.css" + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" + ::xo::Page requireJS "/resources/xowiki/spacegallery/js/eye.js" + ::xo::Page requireJS "/resources/xowiki/spacegallery/js/utils.js" + ::xo::Page requireJS "/resources/xowiki/spacegallery/js/spacegallery.js" + ::xo::Page requireJS [subst -novariables { + $(function(){ + $("#[set id]").spacegallery({loadingClass: 'loading'}); + }); + }] + return $output + } +} + + +############################################################################# +# item-button +# +namespace eval ::xowiki::includelet { + ::xowiki::IncludeletClass create item-button \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {return_url ""} + } + + item-button instproc initialize {} { + if {[my return_url] eq "" } { my return_url [[my package_id] url]} + } + + item-button instproc render_button { + -page + -package_id + -method + -link + -alt + -title + -return_url + -page_order + -object_type + -source_item_id + {-target ""} + } { + set html "" + if {![info exists return_url] || $return_url eq ""} {set return_url [$package_id url]} + if {![info exists alt]} {set alt $method} + if {![info exists link] || $link eq ""} { + if {[$page istype ::xowiki::Package]} { + set link [$package_id make_link $package_id edit-new object_type \ + return_url page_order source_item_id] + } else { + set p_link [$page pretty_link] + set link [$package_id make_link -link $p_link $page $method \ + return_url page_order source_item_id] + } + } + if {$link ne ""} { + set button_class [namespace tail [my info class]] + set props "" + if {$alt ne ""} {append props "alt=\"$alt\" "} + if {$title ne ""} {append props "title=\"$title\" "} + if {$target ne ""} {append props "target=\"$target\" "} + set html " " + } + return $html + } + + ::xowiki::IncludeletClass create edit-item-button -superclass ::xowiki::includelet::item-button \ + -parameter { + {parameter_declaration { + {-page_id} + {-title "#xowiki.edit#"} + {-alt "edit"} + {-book_mode false} + {-link ""} + {-target ""} + }} + } + + edit-item-button instproc render {} { + my get_parameters + my instvar __including_page return_url + 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]" + } + + if {$book_mode} { + append return_url #[toc anchor [$page name]] + } + return [my render_button \ + -page $page -method edit -package_id $package_id -link $link \ + -title $title -alt $alt -return_url $return_url -target $target] + } + + ::xowiki::IncludeletClass create delete-item-button \ + -superclass ::xowiki::includelet::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 return_url + 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 $return_url] + } + + ::xowiki::IncludeletClass create view-item-button \ + -superclass ::xowiki::includelet::item-button \ + -parameter { + {__decoration none} + {parameter_declaration { + {-page_id} + {-title "#xowiki.view#"} + {-alt "view"} + {-link ""} + {-book_mode false} + }} + } + + view-item-button instproc render {} { + my get_parameters + my instvar __including_page return_url + set page [expr {[info exists page_id] ? $page_id : $__including_page}] + return [my render_button \ + -page $page -method view -package_id $package_id \ + -link $link -title $title -alt $alt \ + -return_url $return_url] + } + + + ::xowiki::IncludeletClass create create-item-button \ + -superclass ::xowiki::includelet::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 return_url + set page [expr {[info exists page_id] ? $page_id : $__including_page}] + set page_order [::xowiki::utility 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 $return_url] + } 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 $return_url \ + -object_type $object_type] + } + } + + ::xowiki::IncludeletClass create copy-item-button -superclass ::xowiki::includelet::item-button \ + -parameter { + {__decoration none} + {parameter_declaration { + {-page_id} + {-alt "copy"} + {-book_mode false} + }} + } + + copy-item-button instproc render {} { + my get_parameters + my instvar __including_page return_url + set page [expr {[info exists page_id] ? $page_id : $__including_page}] + + 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.copy_entry [list type [$template title]]] \ + -alt $alt -source_item_id [$page item_id] \ + -return_url $return_url] + } else { + set object_type [$__including_page info class] + return [my render_button \ + -page $package_id -method edit_new -package_id $package_id \ + -title [_ xowiki.copy_entry [list type $object_type]] \ + -alt $alt -source_item_id [$page item_id] \ + -return_url $return_url \ + -object_type $object_type] + } + } +} + + +namespace eval ::xowiki::includelet { + + ::xowiki::IncludeletClass create graph \ + -superclass ::xowiki::Includelet \ + -parameter {{__decoration plain}} + + graph instproc graphHTML {-edges -nodes -max_edges -cutoff -base {-attrib node_id}} { + + ::xo::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 + ::xo::Page requireJS "/resources/xowiki/excanvas.js" + } + ::xo::Page requireJS "/resources/xowiki/collab-graph.js" + ::xo::Page requireJS "/resources/ajaxhelper/yui/yahoo/yahoo.js" + ::xo::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::includelet { + ::xowiki::IncludeletClass create collab-graph \ + -superclass ::xowiki::includelet::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 + } + + + ::xowiki::IncludeletClass create activity-graph \ + -superclass ::xowiki::includelet::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 tmp_table_name XOWIKI_TMP_ACTIVITY + #my msg "tmp exists [::xo::db::require exists_table $tmp_table_name]" + set tt [::xo::db::temp_table new \ + -name $tmp_table_name \ + -query [::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 = [$package_id folder_id] \ + and o.object_id = revision_id" \ + -orderby "revision_id desc" \ + -limit $max_activities] \ + -vars "item_id, revision_id, creation_user"] + + set total 0 + db_foreach [my qn get_activities] " + select count(revision_id) as count, item_id, creation_user + from $tmp_table_name + 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])" + } + $tt destroy + + 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 + } + + ::xowiki::IncludeletClass create timeline \ + -superclass ::xowiki::Includelet \ + -parameter { + {parameter_declaration { + -user_id + {-data timeline-data} + {-interval1 DAY} + {-interval2 MONTH} + }} + } + + timeline instproc render {} { + my get_parameters + + ::xo::Page requireJS "/resources/ajaxhelper/yui/yahoo/yahoo.js" + ::xo::Page requireJS "/resources/ajaxhelper/yui/event/event.js" + ::xo::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 { +
    + + + }] + } + + ::xowiki::IncludeletClass 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::includelet { + ############################################################################# + Class create form-menu-button \ + -parameter { + form + method + link + package_id + parent_id + base + return_url + {label_suffix ""} + } + + form-menu-button instproc render {} { + my instvar package_id base form method return_url label_suffix link + if {![info exists link]} { + if {[my parent_id] != [$package_id folder_id]} { + set parent_id [my parent_id] + } + #my msg "[my info class] check-link-package_id=$package_id" + set link [$package_id make_link -link $base $form $method return_url parent_id] + } + if {$link eq ""} { + return "" + } + set msg_key [namespace tail [my info class]] + set label [_ xowiki.$msg_key [list form_name [$form name]]]$label_suffix + return "$label" + } + + Class form-menu-button-new -superclass form-menu-button -parameter { + {method create-new} + } + Class form-menu-button-answers -superclass form-menu-button -parameter { + {method list} + } + form-menu-button-answers instproc render {} { + array set "" [list publish_status all] + array set "" [::xowiki::PageInstance get_list_from_form_constraints \ + -name @table_properties \ + -form_constraints [[my form] get_form_constraints -trylocal true]] + set count [[my form] count_usages \ + -package_id [my package_id] -parent_id [my parent_id] \ + -publish_status $(publish_status)] + my label_suffix " ($count)" + next + } + + Class form-menu-button-form -superclass form-menu-button -parameter { + {method view} + } + + + ::xowiki::IncludeletClass create form-menu \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-form_item_id:integer} + {-parent_id} + {-form} + {-buttons {new answers}} + {-button_objs} + {-return_url} + }} + } + + form-menu instproc render {} { + my get_parameters + my instvar __including_page + if {![info exists form_item_id]} { + set form_item_id [::xowiki::Weblog instantiate_forms \ + -forms $form \ + -parent_id [$__including_page parent_id] \ + -package_id [$__including_page package_id]] + if {$form_item_id eq ""} { + # we could throw an error as well... + my msg "could not locate form '$form' for parent_id [$__including_page parent_id]" + return "" + } + } + if {[info exists parent_id]} { + if {$parent_id eq "self"} { + set parent_id [$__including_page item_id] + } + } else { + #set parent_id [$package_id folder_id] + set parent_id [$__including_page parent_id] + } + if {![info exists button_objs]} { + foreach b $buttons { + if {[llength $b]>1} { + foreach {button id} $b break + } else { + foreach {button id} [list $b $form_item_id] break + } + set form [::xo::db::CrClass get_instance_from_db -item_id $id] + # + # "Package require" is just a part of "Package initialize" creating + # the package object if needed + # + set form_package_id [$form package_id] + ::xowiki::Package require $form_package_id + set obj [form-menu-button-$button new -volatile -package_id $package_id \ + -base [$form pretty_link] \ + -form $form -parent_id $parent_id] + if {[info exists return_url]} {$obj return_url $return_url} + lappend button_objs $obj + } + } + set links [list] + foreach b $button_objs { lappend links [$b render] } + return "
    [join $links { · }]
    \n" + } + + ############################################################################# + ::xowiki::IncludeletClass create form-stats \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-form} + {-parent_id} + {-property _state} + {-orderby "count,desc"} + {-renderer "table"} + + }} + } + + form-stats instproc render {} { + my get_parameters + set o [my set __including_page] + if {![info exists parent_id]} {set parent_id [$o parent_id]} + set form_item_ids [::xowiki::Weblog instantiate_forms \ + -forms $form -package_id $package_id \ + -parent_id $parent_id] + if {[llength $form_item_ids] != 1} { + return "no such form $form
    \n" + } + set items [::xowiki::FormPage get_form_entries \ + -base_item_ids $form_item_ids -form_fields "" \ + -always_queried_attributes "*" -initialize false \ + -publish_status all -package_id $package_id] + + set sum 0 + foreach i [$items children] { + set value "" + if {[string match _* $property]} { + set varname [string range $property 1 end] + if {[$i exists $varname]} {set value [$i set $varname]} + } else { + array set __ia [$i set instance_attributes] + set varname __ia($property) + if {[info exists $varname]} {set value [set $varname]} + } + if {[info exists __count($value)]} {incr __count($value)} else {set __count($value) 1} + incr sum 1 + } + + if {$sum == 0} { + return "no data
    \n" + } + + if {$renderer eq "highcharts"} { + # + # experimental highcharts pie renderer + # + set percentages [list] + foreach {value count} [array get __count] { + lappend percentages $value [format %.2f [expr {$count*100.0/$sum}]] + } + set h [highcharts new -volatile -id [my js_name] \ + -title [::xowiki::Includelet js_encode \ + "$sum Answers for Survey '[$form_item_ids title]'"]] + return [$h pie [list value count] $percentages] + + } else { + # + # standard table encoder + # + TableWidget t1 -volatile \ + -columns { + Field value -orderby value -label value + Field count -orderby count -label count + } + + foreach {att order} [split $orderby ,] break + t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] $att + foreach {value count} [array get __count] { + t1 add -value $value -count $count + } + return [t1 asHTML] + } + } + + # + # To use highcharts, download it from http://www.highcharts.com/ + # and install it under the directory xowiki/www/resources/highcharts + # (you have to create the directory and unpack the zip file there). + # + ::xotcl::Class highcharts -parameter {title id} + highcharts instproc pie {names data} { + ::xo::Page requireJS "/resources/xowiki/jquery/jquery.min.js" + ::xo::Page requireJS "/resources/xowiki/highcharts/js/highcharts.js" + ::xo::Page requireJS "/resources/xowiki/highcharts/js/themes/gray.js" + set result "
    \n" + set title [my title] + set id [my id] + set values [list] + foreach {name value} $data { + lappend values "\['[::xowiki::Includelet js_encode $name]', $value\]" + } + set values [join $values ",\n"] + append result [subst -nocommands { + +}] + return $result + } + + + ############################################################################# + ::xowiki::IncludeletClass create form-usages \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration plain} + {parameter_declaration { + {-form_item_id:integer} + {-form} + {-parent_id} + {-package_ids ""} + {-orderby "_last_modified,desc"} + {-view_field _name} + {-publish_status "all"} + {-field_names} + {-hidden_field_names ""} + {-extra_form_constraints ""} + {-inherit_from_forms ""} + {-category_id} + {-unless} + {-where} + {-csv true} + {-voting_form} + {-voting_form_form ""} + {-voting_form_anon_instances "t"} + {-generate} + {-with_form_link true} + {-with_categories} + {-wf} + {-buttons "edit delete"} + {-renderer ""} + }} + } + +# {-renderer "YUIDataTableRenderer"} + form-usages instproc render {} { + my get_parameters + + my instvar __including_page + set o $__including_page + ::xo::Page requireCSS "/resources/acs-templating/lists.css" + set return_url [::xo::cc url]?[::xo::cc actual_query] + + if {[info exists parent_id]} { + if {$parent_id eq "self"} { + set parent_id [$__including_page item_id] + } + } else { + set parent_id [$o parent_id] + } + + if {![info exists form_item_id]} { + # Start for search for form in the directory of the including + # form. The provided package_id and parent_id refers to the + # form instances, not to the forms. + set form_item_ids [::xowiki::Weblog instantiate_forms -parent_id $parent_id \ + -parent_id [$o parent_id] \ + -default_lang [$o lang] \ + -forms $form -package_id [$o package_id]] + } else { + set form_item_ids [list $form_item_id] + } + + set form_constraints $extra_form_constraints\n + + if {$inherit_from_forms ne ""} { + foreach inherit_form $inherit_from_forms { + set inherit_form_id [::xowiki::Weblog instantiate_forms \ + -parent_id [$o parent_id] \ + -default_lang [$o lang] \ + -forms $inherit_form -package_id [$o package_id]] + if {$inherit_form_id ne ""} { + set p [$inherit_form_id property form_constraints] + append form_constraints $p\n + } + } + } + + foreach form_item $form_item_ids { + append form_constraints [$form_item get_form_constraints -trylocal true] \n + } + #my msg fc=$form_constraints + + # + # The internal variables (instance attributes, etc) are prefixed + # with an underscore. Therefore, we prefix here "orderby" as + # well. For the provided table properties, prefixing happens in + # the loop below. + # + set orderby _$orderby + + # load table properties; order_by won't work due to comma, but solve that later (TODO) + set table_properties [::xowiki::PageInstance get_list_from_form_constraints \ + -name @table_properties \ + -form_constraints $form_constraints] + foreach {attr value} $table_properties { + switch $attr { + orderby {set $attr _[::xowiki::formfield::FormField fc_decode $value]} + buttons - publish_status - category_id - unless - + where - with_categories - with_form_link - csv - view_field - + voting_form - voting_form_form - voting_form_anon_instances { + set $attr $value + #my msg " set $attr $value" + } + default {error "unknown table property '$attr' provided"} + } + } + + if {![info exists field_names]} { + set fn [::xowiki::PageInstance get_short_spec_from_form_constraints \ + -name @table \ + -form_constraints $form_constraints] + set raw_field_names [split $fn ,] + } elseif {[string match "*,*" $field_names] } { + set raw_field_names [split $field_names ,] + } else { + set raw_field_names $field_names + } + + foreach fn $hidden_field_names { + set __hidden($fn) 1 + lappend raw_field_names $fn + } + + if {$raw_field_names eq ""} { + set raw_field_names {_name _last_modified _creation_user} + } + + # finally, evaluate conditions if included + set field_names [list] + foreach f $raw_field_names { + set _ [string trim [::xowiki::formfield::FormField get_single_spec \ + -object $o -package_id $package_id $f]] + if {$_ ne ""} {lappend field_names $_} + } + + foreach form_item $form_item_ids { + set form_fields [::xowiki::FormPage get_table_form_fields \ + -base_item $form_item \ + -field_names $field_names \ + -form_constraints $form_constraints] + #$form_item show_fields $form_fields + foreach f $form_fields {set __ff([$f name]) $f} + } + # if {[info exists __ff(_creation_user)]} {$__ff(_creation_user) label "By User"} + + # TODO: wiki-substitution is just foced in here. Maybe it makes + # more sense to use it as a default for _text, but we have to + # check all the nested cases to avoid double-substitutions. + if {[info exists __ff(_text)]} {$__ff(_text) set wiki 1} + + foreach b $buttons {set use_button($b) 1} + + set cols "" + if {[info exists use_button(edit)]} { + append cols {AnchorField _edit -CSSclass edit-item-button -label "" \ + -html {style "padding: 2px;"} -no_csv 1 -richtext 1} \n + } + if {[info exists use_button(view)]} { + append cols {AnchorField _view -CSSclass view-item-button -label "" \ + -html {style "padding: 2px;"} -no_csv 1 -richtext 1} \n + } + foreach fn $field_names { + if {[info exists __hidden($fn)]} continue + append cols [list AnchorField _$fn \ + -label [$__ff($fn) label] \ + -richtext 1 \ + -orderby _$fn \ + ] \n + } + if {[info exists use_button(delete)]} { + #append cols [list ImageField_DeleteIcon _delete -label "" -no_csv 1] \n + append cols [list AnchorField _delete -CSSclass delete-item-button -label "" -no_csv 1 -richtext 1] \n + } + + set cmd [list TableWidget t1 -volatile -columns $cols] + if {$renderer ne ""} { + lappend cmd -renderer $renderer + } elseif {[info command ::xo::Table::YUIDataTableRenderer] ne ""} { + lappend cmd -renderer YUIDataTableRenderer + } + eval $cmd + + # + # Sorting is done for the time being in Tcl. This has the advantage + # that page_order 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 + } + #my msg "order=[expr {$order eq {asc} ? {increasing} : {decreasing}}] $att" + t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] $att + + # + # Compute filter clauses + # + set init_vars [list] + array set uc {tcl false h "" vars "" sql ""} + if {[info exists unless]} { + array set uc [::xowiki::FormPage filter_expression $unless ||] + set init_vars [concat $init_vars $uc(vars)] + } + array set wc {tcl true h "" vars "" sql ""} + if {[info exists where]} { + array set wc [::xowiki::FormPage filter_expression $where &&] + set init_vars [concat $init_vars $wc(vars)] + } + #my msg uc=[array get uc] + #my msg wc=[array get wc] + + # + # get an ordered composite of the base set (currently including extra_where clause) + # + #my log "exists category_id [info exists category_id]" + set extra_where_clause "" + if {[info exists category_id]} { + foreach {cnames extra_where_clause} [my category_clause $category_id bt.item_id] break + } + + set items [::xowiki::FormPage get_form_entries \ + -base_item_ids $form_item_ids \ + -parent_id $parent_id \ + -form_fields $form_fields \ + -publish_status $publish_status \ + -extra_where_clause $extra_where_clause \ + -h_where [array get wc] \ + -from_package_ids $package_ids \ + -package_id $package_id] + + if {[info exists with_categories]} { + if {$extra_where_clause eq ""} { + set base_items $items + } else { + # difference to variable items: just the extra_where_clause + set base_items [::xowiki::FormPage get_form_entries \ + -base_item_ids $form_item_ids \ + -parent_id $parent_id \ + -form_fields $form_fields \ + -publish_status $publish_status \ + -h_where [array get wc] \ + -from_package_ids $package_ids \ + -package_id $package_id] + } + } + #my log "queries done" + if {[info exists wf]} { + set wf_link [$package_id pretty_link -parent_id $parent_id $wf] + } + + foreach p [$items children] { + $p set package_id $package_id + array set __ia $init_vars + array set __ia [$p instance_attributes] + if {[expr $uc(tcl)]} continue + #if {![expr $wc(tcl)]} continue ;# already handled in get_form_entries + + set page_link [$p pretty_link] + + if {[info exists wf]} { + set view_link $wf_link?m=create-or-use&p.form=[$p name] + } else { + set view_link $page_link + } + t1 add + set __c [t1 last_child] + + if {[info exists use_button(edit)]} { + $__c set _edit " " + $__c set _edit.title #xowiki.edit# + #set template_file view-default + $__c set _edit.href [$package_id make_link -link $page_link $p edit return_url template_file] + } + if {[info exists use_button(delete)]} { + $__c set _delete " " + $__c set _delete.title #xowiki.delete# + $__c set _delete.href [$package_id make_link -link $page_link $p delete return_url] + } + if {[info exists use_button(view)]} { + $__c set _view " " + $__c set _view.title #xowiki.view# + $__c set _view.href $view_link + } elseif {![info exists use_button(no-view)]} { + # + # Set always a view link, if we have no view button ... + # + if {[info exists __ff($view_field)]} { + # .... on $view_field) (per default: _name) .... + $__c set _$view_field.href $view_link + } else { + # .... otherwise on the first form_field + $__c set _[lindex $field_names 0].href $view_link + } + } + + # set always last_modified for default sorting + $__c set __last_modified [$p set last_modified] + + + foreach __fn $field_names { + $__ff($__fn) object $p + $__c set _$__fn [$__ff($__fn) pretty_value [$p property $__fn]] + } + $__c set __name [$package_id external_name -parent_id [$p parent_id] [$p name]] + } + + # + # If there are multiple includelets on a single page, + # we have to identify the right one for e.g. producing the + # csv table. Therefore, we compute an includelet_key + # + my instvar name + set includelet_key "" + foreach var {name form_item_ids form publish_states field_names unless} { + if {[info exists $var]} {append includelet_key $var : [set $var] ,} + } + + if {[info exists voting_form]} { + # if the user provided a voting form name without a language prefix, + # add one. + if {![regexp {^..:} $voting_form]} { + set obj [my set __including_page] + set voting_form [$obj lang]:$voting_form + } + } + + set given_includelet_key [::xo::cc query_parameter includelet_key ""] + if {$given_includelet_key ne ""} { + if {$given_includelet_key eq $includelet_key && [info exists generate]} { + if {$generate eq "csv"} { + return [t1 write_csv] + } elseif {$generate eq "voting_form"} { + return [my generate_voting_form $voting_form $voting_form_form t1 $field_names $voting_form_anon_instances] + } + } + return "" + } + + set links [list] + set base [$form_item pretty_link] + set label [$form_item name] + + if {$with_form_link} { + append html [_ xowiki.entries_using_form [list form "$label"]] + } + append html [t1 asHTML] + + if {$csv} { + set csv_href "[::xo::cc url]?[::xo::cc actual_query]&includelet_key=[ns_urlencode $includelet_key]&generate=csv" + lappend links "csv" + } + if {[info exists voting_form]} { + set href "[::xo::cc url]?[::xo::cc actual_query]&includelet_key=[ns_urlencode $includelet_key]&generate=voting_form" + lappend links " Generate Voting Form $voting_form" + } + append html [join $links ,] + #my log "render done" + + if {[info exists with_categories]} { + set category_html [$o include [list categories -count 1 -tree_name $with_categories \ + -ordered_composite $base_items]] + return "
    $category_html
    $html\n" + } + return $html + } + + form-usages instproc generate_voting_form {form_name form_form t1 field_names voting_form_anon_instances} { + #my msg "generate_voting anon=$voting_form_anon_instances" + set form "
    How do you rate
    + + + + + + + \n" + + # We use here the table t1 to preserve sorting etc. + # The basic assumption is that every line of the table has an instance variable + # corresponding to the wanted field name. This is guaranteed by the construction + # in form-usages. + set count 0 + set table_field_names [list] + foreach t [$t1 children] { + incr count + lappend table_field_names $count + # In most situations, it seems useful to have just one field in + # the voting table. If there are multiple, we use a comma to + # separate the values (looks bettern than separate columns). + set field_contents [list] + foreach __fn $field_names { + lappend field_contents [$t set $__fn] + } + append form "\n" + } + + append form "
     very good
     very bad
    [join $field_contents {, }]@$count@
    \n" + lappend table_field_names _last_modified _creation_user + + # Check, of we have a form for editing the generated form. If yes, we will + # instantiate a form page from it. + set form_form_id 0 + if {$form_form ne ""} { + set form_form_id [::xo::db::CrClass lookup -name $form_form -parent_id [[my package_id] folder_id]] + } + # The normal form requires for rich-text the 2 element list as content + if {$form_form_id == 0} { set form [list $form text/html] } + + set item_id [::xo::db::CrClass lookup -name $form_name -parent_id [[my package_id] folder_id]] + if {$item_id == 0} { + + if {$form_form_id == 0} { + set f [::xowiki::Form new \ + -package_id [my package_id] \ + -parent_id [[my package_id] folder_id] \ + -name $form_name \ + -anon_instances $voting_form_anon_instances \ + -form $form \ + -form_constraints "@fields:scale,n=7,inline=true @cr_fields:hidden @categories:off\n\ + @table:[join $table_field_names ,]" \ + ] + } else { + set f [::xowiki::FormPage new \ + -page_template $form_form_id \ + -package_id [my package_id] \ + -parent_id [[my package_id] folder_id] \ + -name $form_name] + $f set_property anon_instances $voting_form_anon_instances + $f set_property form $form + $f set_property form_constraints "@fields:scale,n=7,inline=true @cr_fields:hidden @categories:off\n\ + @table:[join $table_field_names ,]" + } + $f save_new + set form_href [$f pretty_link] + $f destroy + set action created + } else { + ::xo::db::CrClass get_instance_from_db -item_id $item_id + if {$form_form_id == 0} { + $item_id form $form + } else { + $item_id set_property form $form + } + $item_id save + set form_href [$item_id pretty_link] + set action updated + } + return "#xowiki.form-$action# $form_name" + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # Show an iframe as includelet + # + ::xowiki::IncludeletClass create iframe \ + -superclass ::xowiki::Includelet \ + -parameter { + {parameter_declaration { + {-title ""} + {-url:required} + {-width "100%"} + {-height "500px"} + }} + } + + iframe instproc render {} { + my get_parameters + + if {$title eq ""} {set title $url} + set content "" + append content "

    $title

    " + return $content + } + +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # present images in an YUI carousel + # + ::xowiki::IncludeletClass create yui-carousel \ + -superclass ::xowiki::Includelet \ + -parameter { + {parameter_declaration { + {-title ""} + {-item_size 600x400} + {-image_size} + {-num_visible 1} + {-play_interval 0} + {-auto_size 0} + {-folder} + {-glob ""} + {-form ""} + }} + } + + yui-carousel instproc images {-package_id -parent_id {-glob ""} {-width ""} {-height ""}} { + set size_info "" + if {$width ne ""} {append size_info " width='$width'"} + if {$height ne ""} {append size_info " height='$height'"} + if {$width ne "" && $height ne ""} { + set geometry "?geometry=${width}x${height}" + } else { + set geometry "" + } + set listing [::xowiki::Includelet listing \ + -package_id $package_id \ + -parent_id $parent_id \ + -use_package_path false \ + -extra_where_clause " and mime_type like 'image/%'" \ + -orderby "name asc" \ + -glob $glob] + #my msg "parent-id=$parent_id, glob=$glob entries=[llength [$listing children]]" + + foreach entry [$listing children] { + $entry class ::xowiki::Page + $entry set html "

    [$entry title]

    " + } + return $listing + } + + yui-carousel instproc form_images { + -package_id + -parent_id + {-form "en:photo.form"} + {-glob ""} {-width ""} {-height ""} + } { + set form_item_ids [::xowiki::Weblog instantiate_forms -parent_id $parent_id -forms $form -package_id $package_id] + if {$form_item_ids eq ""} {error "could not find en:photo.form"} + set form_item_id [lindex $form_item_ids 0] + + set items [::xowiki::FormPage get_form_entries \ + -base_item_ids $form_item_ids -form_fields "" \ + -publish_status all \ + -always_queried_attributes * \ + -parent_id $parent_id \ + -package_id $package_id] + #my msg "parent-id=$parent_id, glob=$glob entries=[llength [$items children]]" + + foreach entry [$items children] { + # order? + set image_name [$entry property image] + if {$glob ne "" && ![string match $glob $image_name]} { + $items delete $entry + continue + } + if {![info exists entry_field_names]} { + set entry_field_names [$entry field_names] + set entry_form_fields [::xowiki::FormPage get_table_form_fields \ + -base_item $form_item_id -field_names $entry_field_names \ + -form_constraints [$form_item_id set form_constraints]] + foreach fn $entry_field_names f $entry_form_fields {set ff($fn) $f} + } + $entry load_values_into_form_fields $entry_form_fields + foreach f $entry_form_fields {$f object $entry} + if {[info exists ff(image)]} { + if {$width ne ""} {$ff(image) width $width} + if {$height ne ""} {$ff(image) height $height} + if {$width ne "" && $height ne ""} { + $ff(image) set geometry "${width}x${height}" + } + $ff(image) label [$entry property _title] + } + $entry set html [$entry render_content] + #my log html=[$entry set html] + } + return $items + } + + yui-carousel instproc render {} { + my get_parameters + + set ajaxhelper 1 + ::xowiki::Includelet require_YUI_CSS -ajaxhelper $ajaxhelper carousel/assets/skins/sam/carousel.css + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "yahoo-dom-event/yahoo-dom-event.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "connection/connection-min.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "animation/animation-min.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "element/element-min.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "carousel/carousel-min.js" + ::xo::Page set_property body class "yui-skin-sam " + + if {![regexp {^(.*)x(.*)$} $item_size _ item_width item_height]} { + error "invalid item size '$item_size'; use e.g. 300x240" + } + + if {[info exists image_size]} { + if {![regexp {^(.*)x(.*)$} $image_size _ width height]} { + error "invalid image size '$image_size'; use e.g. 300x240" + } + } elseif {$auto_size} { + set width $item_width + set height $item_height + } else { + set width "" + set height "" + } + + set ID container_[::xowiki::Includelet html_id [self]] + set play_interval [expr {int($play_interval * 1000)}] + + ::xo::Page requireJS [subst { + YAHOO.util.Event.onDOMReady(function (ev) { + var carousel = new YAHOO.widget.Carousel("$ID",{ + isCircular: true, numVisible: $num_visible, + autoPlayInterval: $play_interval, animation: {speed: 1.0} + }); + carousel.render(); // get ready for rendering the widget + carousel.show(); // display the widget + + }); + }] + + ::xo::Page requireStyle [subst { + + \#$ID { + margin: 0 auto; + } + + .yui-carousel-element .yui-carousel-item-selected { + opacity: 1; + } + + .yui-carousel-element li { + height: ${item_height}px; + width: ${item_width}px; + } + + .yui-skin-sam .yui-carousel-nav ul li { + margin: 0; + }}] + + set parent_id [[my set __including_page] parent_id] + if {[info exists folder]} { + set folder_page [$package_id get_page_from_item_ref -parent_id $parent_id $folder] + if {$folder_page eq ""} { + error "no such folder '$folder'" + } else { + set parent_id [$folder_page item_id] + } + } + + set content "
      \n" + if {$form ne ""} { + set images [my form_images -package_id $package_id -parent_id $parent_id \ + -form $form -glob $glob -width $width -height $height] + } else { + set images [my images -package_id $package_id -parent_id $parent_id \ + -glob $glob -width $width -height $height] + } + foreach entry [$images children] { + append content "
    1. [$entry set html]
    2. \n" + } + append content "
    \n
    \n" + #if {$title eq ""} {set title $url} + return $content + } +} + + +namespace eval ::xowiki::includelet { + ############################################################################# + # gravatar + # + # user image based on email address + # for details: see http://en.gravatar.com/ + # + ::xowiki::IncludeletClass create gravatar \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-email:required} + {-size 80} + }} + } + + gravatar proc url {-email {-size 80}} { + # reusable helper proc to compute an gravatar URL + package require md5 + set md5 [string tolower [md5::Hex [md5::md5 -- $email]]] + return http://www.gravatar.com/avatar/$md5?size=$size + } + + gravatar instproc render {} { + my get_parameters + return "$email" + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # random-form-page + # + ::xowiki::IncludeletClass create random-form-page \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + {-form:required} + {-publish_status "ready"} + {-expires 600} + }} + } + + random-form-page proc page_names {package_id form publish_status} { + # + # This is a cacheable method returing a list of the names from + # which the random page is selected. We use a class method and the + # argument list with util_memoize inability to provide a key for + # caching. + # + set form_item_ids [::xowiki::Weblog instantiate_forms -forms $form -package_id $package_id] + set form_fields [::xowiki::FormPage get_table_form_fields \ + -base_item [lindex $form_item_ids 0] -field_names _name \ + -form_constraints ""] + set items [::xowiki::FormPage get_form_entries \ + -base_item_ids $form_item_ids -form_fields $form_fields \ + -initialize false \ + -publish_status $publish_status \ + -package_id $package_id] + set result [list] + foreach item [$items children] { + lappend result [$item name] + } + return $result + } + + random-form-page instproc render {} { + my get_parameters + + set cmd [list ::xowiki::includelet::random-form-page page_names $package_id $form $publish_status] + if {[ns_info name] eq "NaviServer"} { + set names [ns_cache_eval -expires $expires xowiki_cache random-$package_id-$form $cmd] + } else { + set names [util_memoize $cmd] + } + set random_item [lindex $names [expr { int([llength $names] * rand()) }]] + if {$random_item eq ""} { + return "" + } { + return [[my set __including_page] include [list $random_item -decoration none]] + } + } +} + +namespace eval ::xowiki::includelet { + ############################################################################# + # flowplayer + # + # Get flowplayer from + # http://flowplayer.org/download/index.html + # Get pseudostreaming plugin from + # http://flowplayer.org/plugins/streaming/pseudostreaming.html#download + # + # install bowth under packages/xowiki/www/resources/flowplayer + # + ::xowiki::IncludeletClass create flowplayer \ + -superclass ::xowiki::Includelet \ + -parameter { + {__decoration none} + {parameter_declaration { + -mp4:required + }} + } + + flowplayer instproc include_head_entries {} { + ::xo::Page requireJS "/resources/xowiki/flowplayer/example/flowplayer-3.1.4.min.js" + } + + flowplayer instproc render {} { + my get_parameters + return " + " + } +} + + +namespace eval ::xowiki::includelet { + ############################################################################# + # + # Show the content of an html file in includelet + # + ::xowiki::IncludeletClass create html-file \ + -superclass ::xowiki::Includelet \ + -parameter { + {parameter_declaration { + {-title ""} + {-extra_css ""} + {-levels 0} + {-file:required} + }} + } + + # the two method "href" and "page_number" are copied from "toc" + html-file instproc href {book_mode name} { + my instvar package_id __including_page + if {$book_mode} { + set href [$package_id url]#[toc anchor $name] + } else { + set href [$package_id pretty_link -parent_id [$__including_page parent_id] $name] + } + return $href + } + + html-file instproc page_number {page_order remove_levels} { + #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 + } + #return $displayed_page_order + return "" + } + + html-file instproc render {} { + my get_parameters + + if {$title eq ""} {set title $file} + set parent_id [[my set __including_page] parent_id] + set page [$package_id get_page_from_item_ref -parent_id $parent_id $file] + if {$page eq ""} { + error "could not resolve page from item ref $file" + } + if {$extra_css ne ""} {foreach css $extra_css {::xo::Page requireCSS $css}} + return [$page html_content -add_sections_to_folder_tree $levels -owner [self]] + } + +} + + +::xo::library source_dependent + 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 13 Sep 2012 16:05:27 -0000 1.4 @@ -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 13 Sep 2012 16:05:28 -0000 1.90 @@ -0,0 +1,525 @@ +::xo::library doc { + XoWiki - definition of link types and their renderers + + @creation-date 2006-04-15 + @author Gustaf Neumann + @cvs-id $Id: link-procs.tcl,v 1.90 2012/09/13 16:05:28 victorg Exp $ +} + +namespace eval ::xowiki { + # + # generic links + # + Class create BaseLink -parameter { + cssclass cssid href label title target extra_query_parameter + {anchor ""} {query ""} + } + + BaseLink instproc mk_css_class {{-additional ""} {-default ""}} { + set cls [expr {[my exists cssclass] ? [my cssclass] : $default}] + if {$additional ne ""} { + if {$cls eq ""} {set cls $additional} else {append cls " " $additional} + } + if {$cls ne ""} {set cls "class='$cls'"} + return $cls + } + + BaseLink instproc mk_css_class_and_id {{-additional ""} {-default ""}} { + if {[my exists cssid]} {set id "id='[my cssid]'"} else {set id ""} + set cls [my mk_css_class -additional $additional -default $default] + return [string trim "$cls $id"] + } + + # + # external links + # + Class create ExternalLink -superclass BaseLink + ExternalLink instproc render {} { + my instvar href label title target + set title_att "" + if {[info exists title]} {append title_att " title='[string map [list ' {'}] $title]'"} + if {[info exists target]} {append title_att " target='$target'"} + set css_atts [my mk_css_class_and_id -additional external] + return "$label " + } + + # + # internal links + # + Class create Link -superclass BaseLink -parameter { + {type link} name lang stripped_name page + parent_id package_id item_id {form ""} revision_id + } + Link instproc atts {} { + set atts "" + if {[my exists title]} {append atts " title='[string map [list ' {'}] [my title]]'"} + if {[my exists target]} {append atts " target='[my target]'"} + } + Link instproc init {} { + my instvar page name + set class [self class]::[my type] + if {[my isclass $class]} {my class $class} + if {![my exists name]} { + set name [string trimleft [my lang]:[my stripped_name] :] + } elseif {![my exists stripped_name]} { + # set stripped name and lang from provided name or to the default + my instvar stripped_name lang + if {![regexp {^(..):(.*)$} $name _ lang stripped_name]} { + set stripped_name $name; set lang "" + } + } + if {![my exists label]} {my label $name} + if {![my exists parent_id]} {my parent_id [$page parent_id]} + if {![my exists package_id]} {my package_id [$page package_id]} + #my msg "--L link has class [my info class] // $class // [my type] // [my parent_id]" + } + Link instproc link_name {-lang -stripped_name} { + return $lang:$stripped_name + } + Link instproc resolve {} { + return [my item_id] + } + Link instproc render_found {href label} { + return "$label" + } + Link instproc render_not_found {href label} { + if {$href eq ""} { + return \[$label\] + } else { + return " $label" + } + } + Link instproc pretty_link {item_id} { + my instvar package_id + return [::$package_id pretty_link -parent_id [my parent_id] -lang [my lang] \ + -anchor [my anchor] -query [my query] [my name]] + } + Link instproc new_link {} { + my instvar package_id form + set page [my page] + set nls_language [$page get_nls_language_from_lang [my lang]] + if {$form ne ""} { + return [$package_id make_form_link -form $form \ + -parent_id [my parent_id] \ + -name [my name] \ + -nls_language $nls_language] + } + if {[$page exists __unresolved_object_type]} { + # get the desired object_type for unresoved entries + set object_type [$page set __unresolved_object_type] + } else { + set object_type [[$page info class] set object_type] + if {$object_type ne "::xowiki::Page" && $object_type ne "::xowiki::PlainPage"} { + # TODO: this is a temporary solution. we should find a way to + # pass similar to file or image entries the type of this + # entry. Maybe we can get the type as well from a kind of + # blackboard, where the type of the "edit" wiki-menu-entry is + # stored as well. + set object_type ::xowiki::Page + } + } + return [$page new_link -name [my name] -title [my label] -parent_id [my parent_id] \ + -nls_language $nls_language $package_id] + } + + Link instproc render {} { + my instvar package_id + set page [my page] + set item_id [my resolve] + if {$item_id} { + $page lappend references [list $item_id [my type]] + ::xowiki::Package require $package_id + my render_found [my pretty_link $item_id] [my label] + } else { + $page incr unresolved_references + set new_link [my new_link] + set html [my render_not_found $new_link [my label]] + $page lappend __unresolved_references $html + return $html + } + } + + 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 + } + + # + # folder links + # + Class create ::xowiki::Link::folder -superclass ::xowiki::Link + ::xowiki::Link::folder instproc link_name {-lang -stripped_name} { + return $stripped_name + } + ::xowiki::Link::folder instproc pretty_link {item_id} { + my instvar package_id + return [::$package_id pretty_link \ + -anchor [my anchor] -parent_id [my parent_id] -query [my query] [my name] ] + } + ::xowiki::Link::folder instproc new_link {} { + my instvar package_id + return [$package_id make_link -with_entities 0 \ + $package_id \ + edit-new \ + [list object_type ::xo::db::CrFolder] \ + [list name [my name]] \ + [list parent_id [my parent_id]] \ + [list return_url [::xo::cc url]] \ + autoname] + } + + # + # 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 image_css_class "found" + set link [$package_id pretty_link -lang $lang -parent_id [my parent_id] [my stripped_name]] + } else { + set image_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 $image_css_class} { + set link "" + } + if {$link ne ""} { + $page lappend lang_links($image_css_class) \ + "$lang" + } + return "" + } + + # + # image links + # + + Class create ::xowiki::Link::image -superclass ::xowiki::Link \ + -parameter { + href + center 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 [$package_id pretty_link -download true -query [my query] \ + -absolute [$page absolute_links] -parent_id [my parent_id] $name] + #my log "--l fully quali [$page absolute_links], base=$base" + $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 object_type ::xowiki::File + set link [$package_id make_link $package_id edit-new object_type \ + [list parent_id [my parent_id]] \ + [list title $label] \ + [list return_url [::xo::cc url]] \ + autoname name last_page_id] + set html [my render_not_found $link $label] + return $html + } + } + ::xowiki::Link::image instproc render_found {link label} { + set style ""; set pre ""; set post "" + foreach a { + float width height center + 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]} { + if {$a eq "center"} {set pre "
    "; set post "
    "; continue} + append style "$a: [my set $a];" + } + } + if {$style ne ""} {set style "style='$style'"} + if {[my exists geometry]} {append link "?geometry=[my set geometry]"} + set label [string map [list ' "'"] $label] + set cls [my mk_css_class_and_id -default image] + if {[my exists href]} { + set href [my set href] + if {[string match "java*" $href]} {set href .} + if {[my exists revision_id]} {append href ?revision_id=[my revision_id]} + return "$pre$label$post" + } else { + if {[my exists revision_id]} {append link ?revision_id=[my revision_id]} + return "$pre$label$post" + } + } + + + # + # localimage link + # + + Class create ::xowiki::Link::localimage -superclass ::xowiki::Link::image + ::xowiki::Link::localimage instproc render {} { + my render_found [my href] [my label] + } + + # + # file link + # + + Class create ::xowiki::Link::file -superclass ::xowiki::Link::image -parameter { + width height align pluginspage pluginurl hidden href + autostart loop volume controls controller mastersound starttime endtime + } + + ::xowiki::Link::file instproc render_found {internal_href label} { + foreach f { + width height align pluginspage pluginurl hidden href + autostart loop volume controls controller mastersound starttime endtime + } { + if {[my exists $f]} { + append embed_options "$f = '[my set $f]' " + } + } + if {[my exists extra_query_parameter]} { + set pairs {} + foreach {pair} [my extra_query_parameter] { + lappend pairs [lindex $pair 0]=[ns_urlencode [lindex $pair 1]] + } + append internal_href ?[string map [list ' "'"] [join $pairs &]] + if {[my exists revision_id]} {append internal_href &revision_id=[my revision_id]} + } else { + if {[my exists revision_id]} {append internal_href ?revision_id=[my revision_id]} + } + if {![info exists embed_options]} { + return "$label " + } else { + set internal_href [string map [list %2e .] $internal_href] + return "" + } + } + + # + # css link + # + + Class create ::xowiki::Link::css -superclass ::xowiki::Link::file -parameter { + order + } + ::xowiki::Link::css instproc render_found {href label} { + if {[my exists order]} { + ::xo::Page requireCSS -order [my order] $href + } else { + ::xo::Page requireCSS $href + } + return "" + } + + # + # js link + # + Class create ::xowiki::Link::js -superclass ::xowiki::Link::file -parameter { + } + ::xowiki::Link::js instproc render_found {href label} { + ::xo::Page requireJS $href + return "" + } + + # + # swf link + # + 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 render_found {href label} { + ::xo::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::Includelet 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
    + + " + } + + # + # plugin link + # +# Class create ::xowiki::Link::plugin -superclass ::xowiki::Link::file -parameter { +# classid width height autostart params +# } + +# ::xowiki::Link::plugin instproc render_found {href label} { +# my instvar package_id name + +# foreach {width height autostart} {320 240 true} break +# foreach a {classid width height autostart} {if {[my exists $a]} {set $a [my set $a]}} +# set arguments [list width height autostart] + +# set object_params "" +# if {[my exists params]} { +# set paramlist [split [my set params] ,] +# foreach p $paramlist { +# set pair [split $p =] +# set param([lindex $pair 0]) [lindex $pair 1] +# } +# } + +# #my msg [my name]-guess-type=[::xowiki::guesstype [my name]] +# set mime [::xowiki::guesstype [my name]] + +# switch $mime { +# video/x-ms-wmv { +# # TODO: using classid will stop firefox loading plugin, +# # without classid IE asks user to allow addon +# # also possible: application/x-mplayer2 +# if {![my exists classid]} {set classid "CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"} +# foreach f $arguments {if {[info exists $f]} {append object_params ""}} +# set objectElement \ +# "\n\ +# \n$object_params\n\ +# " +# } +# video/quicktime { +# if {![my exists classid]} {set classid "CLSID:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"} +# foreach f $arguments {if {[info exists $f]} {append object_params ""}} +# set objectElement \ +# " \n\ +# \n\ +# \n\ +# $object_params \n\ +# \n\n" +# } +# application/x-shockwave-flash { +# if {![my exists classid]} {set classid "CLSID:D27CDB6E-AE6D-11cf-96B8-444553540000"} +# set embed_options "" +# set app_params "?" +# foreach f $arguments {if {[info exists $f]} { append embed_options "$f = '[set $f]' " }} +# foreach {att value} [array get param] {append app_params "$att=$value&"} ;# replace with export_vars +# set objectElement \ +# " \n\ +# \n\ +# \n\ +# \n" +# } +# application/java { +# if {![my exists classid]} {set classid "clsid:CAFEEFAC-0015-0000-0000-ABCDEFFEDCBA"} +# if {![info exists param(code)]} {set param(code) [my stripped_name]} +# if {![info exists codebase]} {set codebase [$package_id pretty_link -lang [my lang] -download true ""]} + +# foreach {att value} [array get param] {append object_params "\n"} +# set objectElement \ +# "\n\ +# \n\ +# $object_params \n\ +# No Java Support. \n\ +# \n\ +# $object_params \n\ +# \n" +# } +# default { +# my msg "unknown mime type '$mime' for plugin" +# #set mime "application/x-oleobject" +# } +# } + +# return "$objectElement +#
    $label ([my name])
    +# " +# } + + + + # + # 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 [::xo::db::CrClass lookup -name [my name] -parent_id [$id set parent_id]] + } + #my log "--LINK no page found [my name], [my lang], type=[my type]." + return 0 + } + ::xowiki::Link::glossary instproc render_found {href label} { + ::xo::Page requireJS "/resources/xowiki/get-http-object.js" + ::xo::Page requireJS "/resources/xowiki/popup-handler.js" + ::xo::Page requireJS "/resources/xowiki/overlib/overlib.js" + return "$label" + } + + # + # link cache + # + +# Class LinkCache +# LinkCache instproc resolve {} { +# set key link-[my type]-[my name]-[my parent_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 +} +::xo::library source_dependent + Index: openacs-4/packages/xowiki/tcl/menu-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/menu-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/menu-procs.tcl 13 Sep 2012 16:05:28 -0000 1.6 @@ -0,0 +1,494 @@ +::xo::library doc { + + Basic classes for Menues (context menu, menu bar, menu item). The + design is influenced by the YUI2 classes, but we tried to keep the + implmentation generic. The original version was developed by Michael + Aram in his Master Thesis. Over the time it was simplified, + downstripped and refactored by Gustaf Neumann. The currently + prefered interface is the class + + @author Michael Aram + @author Gustaf Neumann +} + +namespace eval ::xowiki { + + # + # MenuComponent + # + ::xo::tdom::Class create MenuComponent \ + -superclass ::xo::tdom::Object + + MenuComponent instproc js_name {} { + return [::xowiki::Includelet js_name [self]] + } + MenuComponent instproc html_id {} { + return [::xowiki::Includelet html_id [self]] + } + + # + # Menu + # + ::xo::tdom::Class create Menu \ + -superclass MenuComponent \ + -parameter { + {id "[my html_id]"} + CSSclass + } + + Menu ad_instproc render {} {doku} { + html::ul [my get_attributes id {CSSclass class}] { + foreach menuitem [my children] {$menuitem render} + } + } + + # + # MenuItem + # + ::xo::tdom::Class create MenuItem \ + -superclass MenuComponent \ + -parameter { + text + href + title + {id "[my html_id]"} + CSSclass + style + linkclass + target + {group ""} + } + + + MenuItem ad_instproc init args {doku} { + next + # Use computed default values when not specified + if {![my exists title]} { + # set the mouseover-title to the "MenuItem-Label" + # TODO: Do we really want "text" to be required ? + my title [my text] + } + if {![my exists CSSclass]} { + # set the CSS class to e.g. "yuimenuitem" + my CSSclass [string tolower [namespace tail [my info class]]] + } + + if {![my exists href] || [my href] eq ""} { + my append CSSclass " " [string tolower [namespace tail [my info class]]]-disabled + } + if {![my exists linkclass]} { + # set the CSS class to e.g. "yuimenuitemlabel" + my set linkclass [string tolower [namespace tail [my info class]]]label + } + } + + MenuItem ad_instproc render {} {doku} { + html::li [my get_attributes id {CSSclass class}] { + html::a [my get_attributes title href target] { + html::t [my text] + } + } + } + + + ::xo::tdom::Class YUIMenuItemList \ + -superclass Menu \ + -parameter { + header + } + + YUIMenuItemList ad_instproc render {} {} { + if {[my exists header]} { + html::h6 { + html::t [my header] + } + } + next + } + + ################################################### + # + # YUIMenu + # + ::xo::tdom::Class create YUIMenu \ + -superclass Menu \ + -parameter { + header + footer + shadow + {autorender false} + {configuration {{}}} + } + + YUIMenu instproc init {} { + ::xowiki::Includelet require_YUI_CSS -ajaxhelper 1 "menu/assets/skins/sam/menu.css" + ::xowiki::Includelet require_YUI_JS -ajaxhelper 1 "yahoo-dom-event/yahoo-dom-event.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper 1 "container/container_core-min.js" + ::xowiki::Includelet require_YUI_JS -ajaxhelper 1 "menu/menu-min.js" + next + } + + YUIMenu instproc split_menu_groups {list} { + # + # split the list of entries into groups, which will be separated + # with lines in the rendering + # + set result [list] + if {[llength $list] < 1} {return $result} + set group_name [[lindex $list 0] group] + set group_list [list] + foreach e $list { + set gn [$e group] + if {$gn ne $group_name} { + lappend result $group_list + set group_name $gn + set group_list [list] + } + lappend group_list $e + } + lappend result $group_list + return $result + } + + YUIMenu ad_instproc render {} { + http://developer.yahoo.com/yui/menu/ + } { + my append CSSclass " yuimenu" + + # I want the menu to show up when JS is disabled + # This gets overridden by JS, so its only relevant for the non-JS version + #my set style "visibility: visible; position: relative;" + + html::div [my get_attributes {CSSclass class} id style] { + # Header + html::t \n + if {[my exists header]} { + html::div -class "hd" { + html::t [my header] + } + } + # Body + html::t \n + html::div -class "bd" { + foreach group [my split_menu_groups [my children]] { + html::ul { + foreach menuitemlist $group {$menuitemlist render} + } + } + } + # Footer + if {[my exists footer]} { + html::div -class "ft" { + html::t [my footer] + } + } + # Shadow + if {[my exists shadow]} { + html::div -class "yui-menu-shadow" {} + } + # JavaScript + # only "root-level" menus need JS + # TODO: is this parent-check sufficient / future-safe? + if {![my exists __parent]} { + html::script -type "text/javascript" { + html::t "var [my js_name] = new YAHOO.widget.Menu(\"[my id]\", [my set configuration]);" + html::t " + [my js_name].render(); + [my js_name].show(); + " + } + } + } + } + + # + # YUIMenuItem + # + ::xo::tdom::Class create YUIMenuItem \ + -superclass MenuItem \ + -parameter { + {href "#"} + helptext + } + + YUIMenuItem ad_instproc render {} {doku} { + html::li [my get_attributes id {CSSclass class} style] { + # if we have no href, mark entry as disabled + if {![my exists href] || [my href] eq ""} {my append linkclass " disabled"} + html::a [my get_attributes target href {linkclass class} title] { + html::t [my text] + if {[my exists helptext]} { + html::em { + html::t [my helptext] + } + } + } + foreach menu [my children] {$menu render} + } + html::t \n + } + + + # + # YUIMenuBar + # + ::xo::tdom::Class create YUIMenuBar \ + -superclass YUIMenu \ + -parameter { + {navbar true} + } + + YUIMenuBar ad_instproc render {} { + http://developer.yahoo.com/yui/menu/#menubar + MenuBar looks best without a header and with one MenuItemList only + } { + my append CSSclass " yuimenubar" + if {[my navbar]} {my append CSSclass " yuimenubarnav"} + html::div [my get_attributes id {CSSclass class}] { + html::div -class "bd" { + html::t \n + html::ul -class "first-of-type" { + foreach li [my children] {$li render} + } + html::t \n + } + html::t \n + ::xo::Page set_property body class "yui-skin-sam" + ::xo::Page requireJS "YAHOO.util.Event.onDOMReady(function () { + var [my js_name] = new YAHOO.widget.MenuBar('[my id]', [my set configuration]); + [my js_name].render(); + });" + } + } + + # + # YUIMenuBarItem + # + ::xo::tdom::Class create YUIMenuBarItem \ + -superclass YUIMenuItem + + YUIMenuBarItem ad_instproc init {} {} { + #goto YUIMenuItem and set all those nice defaults + next + my append CSSclass " first-of-type" + if {![my exists href]} { + # If not set to #, the title of the menubaritems wont expand the submenu (only the arrow) + my set href "#" + } + } + + + # + # YUIContextMenu + # + + # TODO: Support for Multiple Element IDs/Refs as Trigger + + ::xo::tdom::Class YUIContextMenu \ + -superclass YUIMenu \ + -parameter { + {trigger "document"} + {triggertype "reference"} + } + + YUIContextMenu ad_instproc render {} { + http://developer.yahoo.com/yui/menu/#contextmenu + } { + my append CSSclass " yuimenu" + html::div [my get_attributes id {CSSclass class}] { + html::div -class "bd" { + html::ul { + foreach li [my children] {$li render} + } + } + html::script -type "text/javascript" { + html::t "var [my js_name] = new YAHOO.widget.ContextMenu('[my id]', { trigger: '[my set trigger]' } );" + html::t "[my js_name].render(document.body);" + } + } + } + + # + # YUIContextMenuItem + # + ::xo::tdom::Class YUIContextMenuItem \ + -superclass YUIMenuItem + + + # + # Simple Generic MenuBar + # + # Class for creating and updating Menubars in an incremental + # fashion. Menu handling works as following: + # + # 1) Create an ::xowiki::MenuBar instance + # + # 2) Create menus via the "add_menu" method. The order of the + # creation commands determine the order of the menu buttons. + # + # 3) Add/update menuentries via the "add_menu_item" method. The + # provided name determines the menu to which the entry is + # added. The following example adds a menu entry "StartPage" to + # the menu "Package": + # + # $mb add_menu_item -name Package.Startpage \ + # -item [list text #xowiki.index# url $index_link] + # + # 4) After all updates are performed, use "render-yui" to obtain + # the HTML rendering of the menu. + # + # Follow the following nameing conventions: + # 1) All menu names must start with a capital letter + # 2) All menu entry names must start with a capital letter + # 3) All menu entry names should be named after the menu name + # + # Notice: the current implementation uses interally dicts. Since the + # code should as well work with tcl 8.4 instances, we provide a + # compatibility layer. Maybe it would be better to base the code on + # an ordered composite. Ideally, the interface should stay mostly + # compatible. + # + # Gustaf Neumann, May 31, 2010 + + Class create ::xowiki::MenuBar -parameter { + id + } + + if {[info command ::dict] ne ""} { + ::xowiki::MenuBar instproc get_prop {dict key {default ""}} { + if {![dict exists $dict $key]} { + return $default + } + return [dict get $dict $key] + } + } else { + ::xowiki::MenuBar instproc get_prop {dict key {default ""}} { + array set "" $dict + if {![info exists ($key)]} { + return $default + } + return [set ($key)] + } + } + + ::xowiki::MenuBar instproc init {} { + my set Menues [list] + my destroy_on_cleanup + } + + ::xowiki::MenuBar instproc add_menu {-name {-label ""}} { + my instvar Menues + if {[lsearch -exact $Menues $name] > -1} { + error "menu $name exists already" + } + if {[string match {[a-z]*} $name]} { + error "names must start with uppercase, provided name '$name'" + } + my lappend Menues $name + if {$label eq ""} {set label $name} + my set Menu($name) [list text $label] + #my log "menues: $Menues" + } + + ::xowiki::MenuBar instproc additional_sub_menu {-kind:required -pages:required -owner:required} { + my set submenu_pages($kind) $pages + my set submenu_owner($kind) $owner + } + + ::xowiki::MenuBar instproc clear_menu {-menu:required} { + array set "" [my set Menu($menu)] + my set Menu($menu) [list text $(text)] + } + + ::xowiki::MenuBar instproc add_menu_item {-name:required -item:required} { + # + # The provided items are of the form of attribute-value pairs + # containing at least attributes "text" and "url" + # (e.g. "text .... url ...."). + # + my instvar Menues + set full_name $name + if {![regexp {^([^.]+)[.](.+)$} $name _ menu name]} { + error "menu item name '$name' not of the form Menu.Name" + } + if {[lsearch -exact $Menues $menu] == -1} { + error "menu $menu does not exist" + } + if {[string match {[a-z]*} $name]} { + error "names must start with uppercase, provided name '$name'" + } + + # + # get group name (syntax: Menu.Group.Item) + # + set group_name "" + regexp {^[^.]+[.]([^.]+)[.].*} $full_name _ group_name + # + # provide a default label + # + regsub -all {[.]} $full_name - full_name + array set "" [list text "#xowiki.menu-$full_name#" group $group_name] + array set "" $item + set item [array get ""] + + # + # If an entry with the given name exists, update it. Otherwise add + # such an entry. + # + set updated 0 + set newitems [list] + foreach {n i} [my set Menu($menu)] { + if {$n eq $name} { + lappend newitems $name $item + set updated 1 + } else { + lappend newitems $n $i + } + } + if {$updated} { + my set Menu($menu) $newitems + } else { + my lappend Menu($menu) $name $item + } + } + + ::xowiki::MenuBar instproc content {} { + set result [list id [my id]] + foreach m [my set Menues] { + lappend result $m [my set Menu($m)] + } + return $result + } + + ::xowiki::MenuBar instproc render-yui {} { + set M [my content] + set mb [::xowiki::YUIMenuBar -id [my get_prop $M id] -configuration { + {autosubmenudisplay: false, keepopen: true, lazyload: false} + } { + foreach {menu_att menu} $M { + if {$menu_att eq "id"} continue + ::xowiki::YUIMenuBarItem -text [my get_prop $menu text] { + ::xowiki::YUIMenu { + foreach {item_att item} $menu { + if {[string match {[a-z]*} $item_att]} continue + set text [my get_prop $item text] + set url [my get_prop $item url] + set group [my get_prop $item group] + #my msg "ia=$item_att group '$group' // t=$text item=$item" + ::xowiki::YUIMenuItem -text $text -href $url -group $group {} + } + } + } + } + }] + return [$mb asHTML] + } + + namespace export Menu + namespace export YUIMenuBar YUIMenuBarItem + namespace export YUIMenu YUIMenuItem YUIMenuItemList + namespace export YUIContextMenu YUIContextMenuItem +# end of namespace +} +::xo::library source_dependent + 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 13 Sep 2012 16:05:28 -0000 1.18 @@ -0,0 +1,177 @@ +::xo::library doc { + XoWiki - Notification procs + + @creation-date 2006-08-08 + @author Gustaf Neumann + @cvs-id $Id: notification-procs.tcl,v 1.18 2012/09/13 16:05:28 victorg 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 {id} { + if {[db_0or1row is_package_id "select 1 from apm_packages where package_id = $id"]} { + # + # the specified id is an package_id + # + set node_id [db_string get_node_id "select node_id from site_nodes where object_id = $id"] + set url [site_node::get_url -node_id $node_id] + return $url + } + if {[category::get_name $id] ne ""} { + # + # the specified id is a category_id + # + # if we would know the package_id here, we could return something like + # /xowiki/weblog-portlet?summary=1&category_id=8380 + # however, since we have only a category_id, which might be mapped to + # multiple xowiki instances, we give up here. + return /categories + } + # id is an revision_id + return [::xowiki::url $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 [$page pretty_link -absolute 1] + 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] + + set notif_user_id [expr {[$page exists modifying_user] ? [$page set modifying_user] : [$page set creation_user]}] + + #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 $notif_user_id + + #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 [::xowiki::Category get_category_infos -tree_id $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 $notif_user_id + } + } + } + + + 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" + } +} +::xo::library source_dependent + 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 13 Sep 2012 16:05:28 -0000 1.261 @@ -0,0 +1,2422 @@ +::xo::library doc { + XoWiki - package specific methods + + @creation-date 2006-10-10 + @author Gustaf Neumann + @cvs-id $Id: package-procs.tcl,v 1.261 2012/09/13 16:05:28 victorg Exp $ +} + +namespace eval ::xowiki { + + ::xo::PackageMgr create ::xowiki::Package \ + -superclass ::xo::Package \ + -pretty_name "XoWiki" \ + -package_key xowiki \ + -parameter { + {folder_id 0} + {force_refresh_login false} + } + # {folder_id "[::xo::cc query_parameter folder_id 0]"} + + if {[apm_version_names_compare [ad_acs_version] 5.2] <= -1} { + error "We require at least OpenACS Version 5.2; current version is [ad_acs_version]" + } + + Package ad_proc get_package_id_from_page_id { + {-revision_id 0} + {-item_id 0} + } { + Obtain the package_id from either the item_id or the revision_id of a page + } { + if {$revision_id} { + set object_id $revision_id + } elseif {$item_id} { + set object_id $item_id + } else { + error "Either item_id or revision_id must be provided" + } + return [db_string [my qn get_pid] "select package_id from acs_objects where object_id = :object_id"] + } + + 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). This call is convenient + when testing e.g. from the developer shell + } { + set package_id [my get_package_id_from_page_id \ + -item_id $item_id \ + -revision_id $revision_id] + ::xo::Package initialize \ + -export_vars false \ + -package_id $package_id \ + -init_url false -actual_query "" \ + -parameter $parameter \ + -user_id $user_id + set page [::xo::db::CrClass get_instance_from_db -item_id $item_id -revision_id $revision_id] + ::$package_id set_url -url [$page pretty_link] + return $page + } + + 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] + return [::[$page package_id] url] + } + + # + # URL and naming management + # + Package instproc normalize_name {string} { + set string [string trim $string] + regsub -all {[\#/\\]} $string _ string + # if subst_blank_in_name is turned on, turn spaces into _ + if {[my get_parameter subst_blank_in_name 1]} { + regsub -all { +} $string "_" string + } + #my log "normalize name '$string' // [my get_parameter subst_blank_in_name 1]" + #return [ns_urldecode $string] + return $string + } + + Package instproc default_locale {} { + if {[my get_parameter use_connection_locale 0]} { + # we return the connection locale (if not connected the system locale) + set locale [::xo::cc 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 + view-book 1 view-book-no-ajax 1 view-oacs-docs 1 + download 1 + } + + Package instproc get_lang_and_name {-path -name {-default_lang ""} vlang vlocal_name} { + my upvar $vlang lang $vlocal_name local_name + if {[info exists path]} { + # + # Determine lang and name from a path with slashes + # + if {[regexp {^pages/(..)/(.*)$} $path _ lang local_name]} { + } elseif {[regexp {^([a-z][a-z])/(.*)$} $path _ lang local_name]} { + + # TODO we should be able to get rid of this by using a canonical /folder/ in + # case of potential conflicts, like for file.... + + # check if we have a LANG - FOLDER "conflict" + set item_id [::xo::db::CrClass lookup -name $lang -parent_id [my folder_id]] + if {$item_id} { + my msg "We have a lang-folder 'conflict' (or a two-char folder) with folder: $lang" + set local_name $path + if {$default_lang eq ""} {set default_lang [my default_language]} + set lang $default_lang + } + + } elseif {[regexp {^(file|image|swf|download/file|download/..|tag)/(.*)$} $path _ lang local_name]} { + } else { + set local_name $path + if {$default_lang eq ""} {set default_lang [my default_language]} + set lang $default_lang + } + } elseif {[info exists name]} { + # + # Determine lang and name from a names as it stored in the database + # + if {![regexp {^(..):(.*)$} $name _ lang local_name]} { + if {![regexp {^(file|image|swf):(.*)$} $name _ lang local_name]} { + set local_name $name + if {$default_lang eq ""} {set default_lang [my default_language]} + set lang $default_lang + } + } + } + } + + Package instproc get_page_from_super {-folder_id:required name} { + set package [self] + set inherit_folders [FormPage get_super_folders $package $folder_id] + + foreach item_ref $inherit_folders { + set folder [::xo::cc cache [list $package get_page_from_item_ref $item_ref]] + if {$folder eq ""} { + my log "Error: Could not resolve parameter folder page '$item_ref' of FormPage [self]." + } else { + set item_id [::xo::db::CrClass lookup -name $name -parent_id [$folder item_id]] + if { $item_id != 0 } { + return $item_id + } + } + } + return 0 + } + + + Package instproc get_parent_and_name {-path:required -lang:required -parent_id:required vparent vlocal_name} { + my upvar $vparent parent $vlocal_name local_name + if {[regexp {^([^/]+)/(.+)$} $path _ parent local_name]} { + + # try without a prefix + set p [my lookup -name $parent -parent_id $parent_id] + + if {$p == 0} { + # check if page is inherited + set p2 [my get_page_from_super -folder_id $parent_id $parent] + if { $p2 != 0 } { + set p $p2 + } + + } + + if {$p == 0} { + # pages are stored with a lang prefix + set p [my lookup -name ${lang}:$parent -parent_id $parent_id] + #my log "check with prefix '${lang}:$parent' returned $p" + + if {$p == 0 && $lang ne "en"} { + # try again with prefix "en" + set p [my lookup -name en:$parent -parent_id $parent_id] + #my log "check with en 'en:$parent' returned $p" + } + } + + if {$p != 0} { + if {[regexp {^([^/]+)/(.+)$} $local_name _ parent2 local_name2]} { + set p2 [my get_parent_and_name -path $local_name -lang $lang -parent_id $p parent local_name] + #my log "recursive call for '$local_name' parent_id=$p returned $p2" + if {$p2 != 0} { + set p $p2 + } + } + } + + if {$p != 0} { + return $p + } + } + set parent "" + # a trailing slash indicates a directory, remove it from the path + set local_name [string trimright $path /] + return $parent_id + } + + Package instproc get_page_from_name {{-parent_id ""} {-assume_folder false} -name:required} { + # Check if an instance with this name exists in the current package. + if {$assume_folder} { + set lookup_name $name + } else { + my get_lang_and_name -name $name lang stripped_name + set lookup_name $lang:$stripped_name + } + set item_id [my lookup -parent_id $parent_id -name $lookup_name] + if {$item_id != 0} { + return [::xo::db::CrClass get_instance_from_db -item_id $item_id] + } + return "" + } + + Package instproc folder_path {{-parent_id ""} {-context_url ""} {-folder_ids ""}} { + # + # handle different parent_ids + # + if {$parent_id eq "" || $parent_id == [my folder_id]} { + return "" + } + # + # The item might be in a folder along the folder path. so it + # will be found by the object resolver. For the time being, we + # do nothing more about this. + # + # + if { $context_url ne {} } { + set parts [split $context_url /] + set index [expr {[llength $parts]-1}] + } + + if { $context_url ne {} } { + set context_id [my get_parent_and_name -path $context_url -lang "" -parent_id $parent_id parent local_name] + #my msg "context_url $context_url folder_ids $folder_ids context_id $context_id" + } + + set path "" + while {1} { + set fo [::xo::db::CrClass get_instance_from_db -item_id $parent_id] + if { $context_url ne {} } { + set context_name [lindex $parts $index] + if {1 && $parent_id in $folder_ids} { + #my msg "---- parent $parent_id in $folder_ids" + set context_id [$context_id item_id] + set fo [::xo::db::CrClass get_instance_from_db -item_id $context_id] + } else { + #my msg "context_url $context_url, parts $parts, context_name $context_name // parts $parts // index $index / folder $fo" + + if { [$fo name] ne $context_name } { + set context_folder [my get_page_from_name -parent_id $parent_id -assume_folder true -name $context_name] + if {$context_folder eq ""} { + my msg "my get_page_from_name -parent_id $parent_id -assume_folder true -name $context_name ==> EMPTY" + my msg "Cannot lookup '$context_name' in package folder $parent_id [$parent_id name]" + + set new_path [join [lrange $parts 0 $index] /] + set p2 [my get_parent_and_name -path [join [lrange $parts 0 $index] /] -lang "" -parent_id $parent_id parent local_name] + my msg "p2=$p2 new_path=$new_path '$local_name' ex=[nsf::object::exists $p2] [$p2 name]" + + } + my msg "context_name [$context_folder serialize]" + set context_id [$context_folder item_id] + set fo [::xo::db::CrClass get_instance_from_db -item_id $context_id] + } + incr index -1 + } + } + + #my get_lang_and_name -name [$fo name] lang stripped_name + #set path $stripped_name/$path + set path [$fo name]/$path + if {[my folder_id] == [$fo parent_id]} break + if {[$fo parent_id] < 0} break + set parent_id [$fo parent_id] + } + return $path + } + + + Package ad_instproc external_name { + {-parent_id ""} + name + } { + Generate a name with a potentially inserted parent name + + @param parent_id parent_id (for now just for download) + @param name name of the wiki page + } { + set folder [my folder_path -parent_id $parent_id] + if {$folder ne ""} { + # Return the stripped name for sub-items, the parent has already + # the language prefix + #my get_lang_and_name -name $name lang stripped_name + return $folder$name + } + return $name + + } + + Package ad_instproc pretty_link { + {-anchor ""} + {-query ""} + {-absolute:boolean false} + {-siteurl ""} + {-lang ""} + {-parent_id ""} + {-download false} + {-context_url ""} + {-folder_ids ""} + 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 parent_id parent_id (for now just for download) + @param name name of the wiki page + } { + #my msg "input name=$name, lang=$lang" + set default_lang [my default_language] + + my get_lang_and_name -default_lang $lang -name $name lang name + + set host [expr {$absolute ? ($siteurl ne "" ? $siteurl : [ad_url]) : ""}] + if {$anchor ne ""} {set anchor \#$anchor} + if {$query ne ""} {set query ?$query} + #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, default_lang=$default_lang, name=$name, parent_id=$parent_id, package_prefix=$package_prefix" + + if {$parent_id eq -100} { + return ${host}${package_prefix}$query$anchor + } + + if {[ns_info name] eq "NaviServer"} { + set encoded_name [ns_urlencode -part path -- $name] + } else { + set encoded_name [::xowiki::utility urlencode $name] + } + + #set encoded_name [string map [list %2d - %5f _ %2e .] [ns_urlencode $name]] + set folder [my folder_path -parent_id $parent_id -context_url $context_url -folder_ids $folder_ids] + #my msg "folder_path = $folder, default_lang [my default_language]" + + # if {$folder ne ""} { + # # if folder has a different language than the content, we have to provide a prefix.... + # regexp {^(..):} $folder _ default_lang + # } + + #my log "h=${host}, prefix=${package_prefix}, folder=$folder, name=$encoded_name anchor=$anchor download=$download" + #my msg folder=$folder,lang=$lang,default_lang=$default_lang + if {$download} { + # + # use the special download (file) syntax + # + set url ${host}${package_prefix}download/file/$folder$encoded_name$query$anchor + } elseif {$lang ne $default_lang || [[self class] exists www-file($name)]} { + # + # If files are physical files in the www directory, add the + # language prefix + # + set url ${host}${package_prefix}${lang}/$folder$encoded_name$query$anchor + } else { + # + # Use the short notation without language prefix + # + set url ${host}${package_prefix}$folder$encoded_name$query$anchor + } + #my msg "final url=$url" + return $url + } + + Package instproc init {} { + #my log "--R creating + folder_object" + next + my require_folder_object + my set policy [my get_parameter -check_query_parameter false security_policy ::xowiki::policy1] + #my proc destroy {} {my log "--P "; next} + } + + Package ad_instproc get_parameter {{-check_query_parameter true} {-type ""} attribute {default ""}} { + resolves configurable parameters according to the following precedence: + (1) values specifically set per page {{set-parameter ...}} + (2) query parameter + (3) form fields from the parameter_page FormPage + (4) standard OpenACS package parameter + } { + set value [::xo::cc get_parameter $attribute] + if {$check_query_parameter && $value eq ""} {set value [string trim [my query_parameter $attribute]]} + if {$value eq "" && $attribute ne "parameter_page"} { + # + # Try to get the parameter from the parameter_page. We have to + # be very cautious here to avoid recursive calls (e.g. when + # resolve_page_name needs as well parameters such as + # use_connection_locale or subst_blank_in_name, etc.). + # + set pp [my get_parameter parameter_page ""] + if {$pp ne ""} { + if {![regexp {/?..:} $pp]} { + my log "Error: Name of parameter page '$pp' of package [my id] must contain a language prefix" + } else { + set page [::xo::cc cache [list [self] get_page_from_item_ref $pp]] + if {$page eq ""} { + my log "Error: Could not resolve parameter page '$pp' of package [my id]." + } + #my msg pp=$pp,page=$page-att=$attribute + + if {$page ne "" && [$page exists instance_attributes]} { + array set __ia [$page set instance_attributes] + if {[info exists __ia($attribute)]} { + set value $__ia($attribute) + #my log "got value='$value'" + } + } + } + } + } + #if {$value eq ""} {set value [::[my folder_id] get_payload $attribute]} + if {$value eq ""} {set value [next $attribute $default]} + if {$type ne ""} { + # to be extended and generalized + switch $type { + word {if {[regexp {\W} $value]} {error "value '$value' contains invalid character"}} + default {error "requested type unknown: $type"} + } + } + #my log " $attribute returns '$value'" + return $value + } + + Package instproc resolve_package_path {path name_var} { + # + # In case, we can resolve the path against an xowiki instance, + # require the package, set the provided name of the object and + # return the package_id. If we cannot resolve the name, turn 0. + # + my upvar $name_var name + + # Set output variable always to some value + set name $path + + if {[regexp {^/(/.*)$} $path _ path]} { + array set "" [site_node::get_from_url -url $path] + if {$(package_key) eq "acs-subsite"} { + # the main site + return 0 + } + set package_id $(package_id) + set package_class [::xo::PackageMgr get_package_class_from_package_key $(package_key)] + if {$package_class ne ""} { + # we found an xo::Package, but is it an xowiki package? + set classes [concat $package_class [$package_class info heritage]] + if {[lsearch $classes ::xowiki::Package] > -1} { + # yes, it is an xowiki::package, compute the name and return the package_id + ::xowiki::Package require $package_id + set name [string range $path [string length $(url)] end] + return $package_id + } + } + } elseif {!([string match "http*://*" $path] || [string match "ftp://*" $path])} { + return [my id] + } + + return 0 + } + + Package instproc get_package_id_from_page_name {{-default_lang ""} page_name} { + # + # Return package id + remaining page name + # + set package_id [my id] + if {[regexp {^/(/[^/]+/)(.*)$} $page_name _ url page_name]} { + set provided_name $page_name + array set "" [site_node::get_from_url -url $url] + if {$(package_id) eq ""} {return ""} + if {$(name) ne ""} {set package_id $(package_id)} + ::xowiki::Package require $package_id + my get_lang_and_name -default_lang $default_lang -path $page_name lang stripped_name + set page_name $lang:$stripped_name + set url $(url) + set search 0 + } else { + set url [my url]/ + set provided_name $page_name + set search 1 + } + #my msg [self args]->[list package_id $package_id page_name $page_name url $url provided_name $provided_name search $search] + return [list package_id $package_id page_name $page_name url $url provided_name $provided_name search $search] + } + + Package instproc resolve_page_name {{-default_lang ""} page_name} { + # + # This is a very simple version for resolving page names in an + # package instance. It can be called either with a full page + # name with a language prefix (as stored in the CR) for the + # current package, or with a path (starting with a //) pointing to + # an xowiki instance followed by the page name. + # + # Examples + # ... resolve_page_name en:index + # ... resolve_page_name //xowiki/en:somepage + # + # The method returns either the page object or empty (""). + # + return [my get_page_from_item_ref -allow_cross_package_item_refs true -default_lang $default_lang $page_name] + #array set "" [my get_package_id_from_page_name $page_name] + } + + Package instproc resolve_page_name_and_init_context {{-lang} page_name} { + # todo: currently only used from + # Page->resolve_included_page_name. maybe, it could be replaced by + # get_page_from_name or get_page_from_item_ref + set page "" + # + # take a local copy of the package_id, since it is possible + # that the variable package_id might changed to another instance. + # + set package_id [my id] + array set "" [my get_package_id_from_page_name $page_name] + if {$(package_id) != $package_id} { + # + # Handle cross package resolve requests + # + # Note, that package::initialize might change the package id. + # Preserving the package-url is just necessary, if for some + # reason the same package is initialized here with a different + # url. This could be done probably with a flag to initialize, + # but we get below the object name from the package_id... + # + #my log "cross package request $page_name" + # + set last_package_id $package_id + set last_url [my url] + # + # TODO: We assume here that the package is an xowiki package. + # The package might be as well a subclass of xowiki... + # For now, we fixed the problem to perform reclassing in + # ::xo::Package init and calling a per-package instance + # method "initialize" + # + ::xowiki::Package initialize -parameter {{-m view}} -url $(url)$(provided_name) \ + -actual_query "" + #my log "url=$url=>[$package_id serialize]" + + if {$package_id != 0} { + # + # 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 {[$package_id exists context] ? [$package_id context] : "::xo::cc"}] + $package_id context [::xo::Context new -volatile] + set object_name [$package_id set object] + #my log "cross package request got object=$object_name" + # + # A user might force the language by preceding the + # name with a language prefix. + # + #my log "check '$object_name' for lang prefix" + if {![regexp {^..:} $object_name]} { + if {![info exists lang]} { + set lang [my default_language] + } + set object_name ${lang}:$object_name + } + set page [$package_id resolve_page -simple true $object_name __m] + $package_id context $last_context + } + $last_package_id set_url -url $last_url + + } else { + # It is not a cross package request + set last_context [expr {[$package_id exists context] ? [$package_id context] : "::xo::cc"}] + $package_id context [::xo::Context new -volatile] + set page [$package_id resolve_page -use_package_path $(search) $(page_name) __m] + $package_id context $last_context + } + #my log "returning $page" + return $page + } + + + Package instproc show_page_order {} { + return [my get_parameter display_page_order 1] + } + + # + # conditional links + # + Package ad_instproc make_link {{-with_entities 0} -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 "" + #my msg "obj=$object, [$object info class]" + 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] + #my msg "base = '[my url]'" + } + lappend args [list m $method] + set computed_link [uplevel export_vars -base [list $base] [list $args]] + #my msg "computed_link = '$computed_link'" + } + if {$with_entities} { + regsub -all & $computed_link "&" computed_link + } + + # provide links based in untrusted_user_id + set party_id [::xo::cc set untrusted_user_id] + if {[info exists privilege]} { + #my log "-- checking priv $privilege for [self args] from id $id" + set granted [expr {$privilege eq "public" ? 1 : + [::xo::cc permission -object_id $id -privilege $privilege -party_id $party_id] }] + } else { + # determine privilege from policy + #my msg "-- check permissions from $id of object $object $method" + if {[catch { + set granted [my check_permissions \ + -user_id $party_id \ + -package_id $id \ + -link $computed_link $object $method] + } errorMsg ]} { + my log "error in check_permissions: $errorMsg" + set granted 0 + } + #my msg "--p $id check_permissions $object $method ==> $granted" + } + #my log "granted=$granted $computed_link" + if {$granted} { + return $computed_link + } + return "" + } + + Package instproc make_form_link {-form {-parent_id ""} -name -nls_language -return_url} { + my instvar id + # use the same instantiate_forms as everywhere; TODO: will go to a different namespace + set form_id [lindex [::xowiki::Weblog instantiate_forms \ + -parent_id $parent_id \ + -forms $form \ + -package_id $id] 0] + #my log "instantiate_forms -parent_id $parent_id -forms $form => $form_id " + if {$form_id ne ""} { + if {$parent_id eq ""} {unset parent_id} + set form_link [$form_id pretty_link] + #my msg "$form -> $form_id -> $form_link -> [my make_link -with_entities 0 -link $form_link $form_id \ + # create-new return_url title parent_id name nls_language]" + return [my make_link -with_entities 0 -link $form_link $form_id \ + create-new return_url title parent_id name nls_language] + } + } + + Package instproc create_new_snippet { + {-object_type ::xowiki::Page} + provided_name + } { + my get_lang_and_name -path $provided_name lang local_name + set name ${lang}:$local_name + set new_link [my make_link [my id] edit-new object_type return_url name] + if {$new_link ne ""} { + return "

    Do you want to create page $name new?" + } else { + return "" + } + } + Package array set delegate_link_to_target { + csv-dump 1 download 1 list 1 + } + Package instproc invoke {-method {-error_template error-template} {-batch_mode 0}} { + set page_or_package [my resolve_page [my set object] method] + #my log "--r resolve_page => $page_or_package" + if {$page_or_package ne ""} { + if {[$page_or_package istype ::xowiki::FormPage] + && [$page_or_package is_link_page] + && [[self class] exists delegate_link_to_target($method)]} { + # if the target is a link, we may want to call the method on the target + set target [$page_or_package get_target_from_link_page] + #my msg "delegate $method from $page_or_package [$page_or_package name] to $target [$target name]" + if {$target ne ""} {set page_or_package $target} + } + if {[$page_or_package procsearch $method] eq ""} { + return [my error_msg "Method '$method' is not defined for this object"] + } else { + #my msg "--invoke [my set object] id=$page_or_package method=$method ([my id] batch_mode $batch_mode)" + if {$batch_mode} {[my id] set __batch_mode 1} + set r [my call $page_or_package $method ""] + if {$batch_mode} {[my id] unset __batch_mode} + return $r + } + } else { + # the requested page was not found, provide an error message and + # an optional link for creating the page + set path [::xowiki::Includelet html_encode [my set object]] + set edit_snippet [my create_new_snippet $path] + return [my error_msg -status_code 404 -template_file $error_template \ + "Page '$path' is not available. $edit_snippet"] + } + } + + Package instproc error_msg {{-template_file error-template} {-status_code 200} error_msg} { + my instvar id + if {![regexp {^[./]} $template_file]} { + set template_file /packages/xowiki/www/$template_file + } + set context [list [$id instance_name]] + set title Error + set header_stuff [::xo::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} + set top_includelets ""; set content $error_msg + ::xo::cc set status_code $status_code + $id return_page -adp $template_file -variables { + context title index_link back_link header_stuff error_msg + top_includelets content + } + } + + Package instproc get_page_from_item_or_revision_id {item_id} { + 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" + return [::xo::db::CrClass get_instance_from_db -item_id $item_id -revision_id $revision_id] + } + + Package instproc resolve_page {{-use_package_path true} {-simple false} -lang object method_var} { + # + # Try to resolve from object (path) and query parameter the called + # object (might be a packge or page) and the method to be called. + # + # @return instantiated object (Page or Package) or empty + # + upvar $method_var method + my instvar id + + # get the default language if not specified + if {![info exists lang]} { + set lang [my default_language] + } + #my msg "resolve_page '$object', default-lang $lang" + + # + # First, resolve package level methods, + # having the syntax PACKAGE_URL?METHOD&.... + # + + if {$object eq ""} { + # + # We allow only to call methods defined by the policy + # + set exported [[my set policy] defined_methods Package] + foreach m $exported { + #my log "--QP my exists_query_parameter $m = [my exists_query_parameter $m] || [my exists_form_parameter $m]" + if {[my exists_query_parameter $m] || [my exists_form_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"] + #my log "--o object is now '$object'" + } + # + # second, resolve object level + # + #my msg "call item_info_from url" + array set "" [my item_info_from_url -with_package_prefix false -default_lang $lang $object] + + if {$(item_id) ne 0} { + if {$(method) ne ""} { set method $(method) } + return [my get_page_from_item_or_revision_id $(item_id)] + } + if {$simple} { return ""} + #my msg "NOT found object=$object" + + # try standard page + set standard_page [$id get_parameter $(stripped_name)_page] + if {$standard_page ne ""} { + # + # allow for now mapped standard pages just on the toplevel + # + set page [my get_page_from_item_ref \ + -allow_cross_package_item_refs false \ + -use_package_path true \ + -use_site_wide_pages true \ + -use_prototype_pages true \ + -default_lang $lang \ + -parent_id [my folder_id] \ + $standard_page] + #my log "--o resolving standard_page '$standard_page' returns $page" + if {$page ne ""} { + return $page + } + # Maybe we are calling from a different language, but the + # standard page with en: was already instantiated. + #set standard_page "en:$stripped_object" + #set page [my resolve_request -default_lang en -path $standard_page method] + #my msg "resolve -default_lang en -path $standard_page returns --> $page" + #if {$page ne ""} { + # return $page + #} + } + + # Maybe, a prototype page was imported with language en:, but the current language is different + #if {$lang ne "en"} { + # set page [my resolve_request -default_lang en -path $stripped_object method] + # #my msg "resolve -default_lang en -path $stripped_object returns --> $page" + # if {$page ne ""} { + # return $page + # } + #} + + if {$use_package_path} { + # Check for this page along the package path + #my msg "check along package path" + foreach package [my package_path] { + set page [$package resolve_page -simple true -lang $lang $object method] + if {$page ne ""} { + #my msg "set_resolve_context inherited -package_id [my id] -parent_id [my folder_id]" + $page set_resolve_context -package_id [my id] -parent_id [my folder_id] + return $page + } + } + #my msg "package path done [array get {}]" + } + + set page [::xowiki::Package get_site_wide_page -name en:$(stripped_name)] + #my msg "get_site_wide_page for en:'$(stripped_name)' returned '$page' (stripped name)" + if {$page ne ""} { + #my msg "set_resolve_context site-wide -package_id [my id] -parent_id [my folder_id]" + $page set_resolve_context -package_id [my id] -parent_id [my folder_id] + return $page + } + + #my msg "we have to try to import a prototype page for $stripped_object" + set page [my import-prototype-page $(stripped_name)] + if {$page ne ""} { + return $page + } + my log "no prototype for '$object' found" + return $page + } + + Package instproc package_path {} { + # + # Compute a list fo package objects which should be used for + # resolving ("inheritance of objects from other instances"). + # + set packages [list] + set package_url [string trimright [my package_url] /] + set package_path [my get_parameter PackagePath] + # + # To avoid recursions, remove the current package from the list of + # packages if was accidentally included. Get the package objects + # from the remaining URLs. + # + foreach package_instance_url $package_path { + #my msg "compare $package_instance_url eq $package_url" + if {$package_instance_url eq $package_url} continue + lappend packages ::[::xowiki::Package initialize \ + -url $package_instance_url/[my set object] \ + -keep_cc true -init_url false] + } + # final sanity check, in case package->initialize is broken + set p [lsearch $packages ::[my id]] + if {$p > -1} {set packages [lreplace $packages $p $p]} + + #my msg "[my id] packages=$packages, p=$p" + return $packages + } + + Package instproc prefixed_lookup {{-default_lang ""} -lang:required -stripped_name:required -parent_id:required} { + # todo unify with package->lookup + # + # This method tries a direct lookup of stripped_name under + # parent_id followed by a prefixed lookup. The direct lookup is + # only performed, when $default-lang == $lang. The prefixed lookup + # might change lang in the result set. + # + # @return item-ref info + # + + set item_id 0 + if {$lang eq $default_lang || [string match *:* $stripped_name]} { + # try a direct lookup; ($lang eq "file" needed for links to files) + set item_id [::xo::db::CrClass lookup -name $stripped_name -parent_id $parent_id] + if {$item_id != 0} { + set name $stripped_name + regexp {^(..):(.+)$} $name _ lang stripped_name + #my log "direct $stripped_name" + } + } + + # TODO + #my log ">>>>>>>> HERE HERE item_id=$item_id" + if { $item_id == 0 } { + set item_id [my get_page_from_super -folder_id $parent_id $stripped_name] + if { $item_id != 0 } { + set name $stripped_name + } + } + + if {$item_id == 0} { + set name ${lang}:$stripped_name + set item_id [::xo::db::CrClass lookup -name $name -parent_id $parent_id] + #my log "comp $name" + } + return [list item_id $item_id parent_id $parent_id \ + lang $lang stripped_name $stripped_name name $name ] + } + + Package instproc lookup { + {-use_package_path true} + {-use_site_wide_pages false} + {-default_lang ""} + -name:required + {-parent_id ""} + } { + # Lookup name (with maybe cross-package references) from a + # given parent_id or from the list of configured instances + # (obtained via package_path). + # + array set "" [my get_package_id_from_page_name -default_lang $default_lang $name] + #my msg "result = [array get {}]" + if {![info exists (package_id)]} { + return 0 + } + + if {$parent_id eq ""} {set parent_id [$(package_id) folder_id]} + set item_id [::xo::db::CrClass lookup -name $(page_name) -parent_id $parent_id] + #my log "lookup $(page_name) $parent_id in package $(package_id) returns $item_id, parent_id $parent_id" + + # Test for "0" is only needed when we want to create the first root folder + if {$item_id == 0 && $parent_id ne "0"} { + # + # Page not found so far. Is the parent-page a regular page and a folder-link? + # If so, de-reference the link. + # + set p [::xo::db::CrClass get_instance_from_db -item_id $parent_id] + if {[$p istype ::xowiki::FormPage] && [$p is_link_page] && [$p is_folder_page]} { + set target [$p get_target_from_link_page] + #my log "LINK LOOKUP from target-package [$target package_id] source package $(package_id)" + return [[$target package_id] lookup \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -default_lang $default_lang \ + -name $name \ + -parent_id [$target item_id]] + } + } + + if {$item_id == 0 && $use_package_path} { + # + # Page not found so far. Is the page inherited along the package + # path? + # + foreach package [my package_path] { + set item_id [$package lookup -name $name] + #my msg "lookup from package $package $name returns $item_id" + if {$item_id != 0} break + } + } + + if {$item_id == 0 && $use_site_wide_pages} { + # + # Page not found so far. Is the page a site_wide page? + # + set item_id [::xowiki::Package lookup_side_wide_page -name $name] + } + + return $item_id + } + + # + # Resolving item refs + # (symbolic references to content items and content folders) + # + + Package ad_instproc item_ref { + {-use_package_path false} + {-use_site_wide_pages false} + {-normalize_name true} + -default_lang:required + -parent_id:required + link + } { + + An item_ref refers to an item (existing or nonexisting) in the + content repository relative to some parent_id. The item might be + either a folder or some kind of "page" (e.g. a file). An item_ref + might be complex, i.e. consist of a path of simple_item_refs, + separated by "/". An item_ref stops at the first unknown part in + the path and returns item_id == 0 and the appropriate parent_id + (and name etc.) for insertion. + + @return item info containing link_type form prefix stripped_name item_id parent_id + + } { + # A trailing slash says that the last element is a folder. We + # substitute it to allow easy iteration over the slash separated + # segments. + if {[string match */ $link]} { + set llink [string trimright $link /]\0 + } else { + set llink $link + } + + set elements [split $llink /] + # Get start-page, if path is empty + if {[llength $elements] == 0} { + set link [my get_parameter index_page "index"] + set elements [list $link] + } + + # Iterate until the first unknown element appears in the path + # (we can handle only one unknown at a time). + set nr_elements [llength $elements] + set n 0 + set ref_ids {} + foreach element $elements { + set (last_parent_id) $parent_id + lappend ref_ids $parent_id + array set "" [my simple_item_ref \ + -normalize_name $normalize_name \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -default_lang $default_lang \ + -parent_id $parent_id \ + -assume_folder [expr {[incr n] < $nr_elements}] \ + $element] + #my log "$element => [array get {}]" + if {$(item_id) == 0} { + set parent_id $(parent_id) + break + } else { + set parent_id $(item_id) + } + } + + return [list link $link link_type $(link_type) form $(form) \ + prefix $(prefix) stripped_name $(stripped_name) \ + item_id $(item_id) parent_id $(parent_id) ref_ids $ref_ids] + } + + Package instproc simple_item_ref { + -default_lang:required + -parent_id:required + {-use_package_path true} + {-use_site_wide_pages false} + {-normalize_name true} + {-assume_folder:required false} + element + } { + if {$normalize_name} { + set element [my normalize_name $element] + } + #my log el=[string map [list \0 MARKER] $element]-assume_folder=$assume_folder,parent_id=$parent_id + set (form) "" + set use_default_lang 0 + + if {[regexp {^(file|image|js|css|swf):(.+)$} $element _ (link_type) (stripped_name)]} { + # (typed) file links + set (prefix) file + set name file:$(stripped_name) + } elseif {[regexp {^folder:(.+)$} $element _ (stripped_name)]} { + # (typed) file links + array set "" [list prefix "" link_type link form "en:folder.form"] + set name $(stripped_name) + } elseif {[regexp {^(..):([^:]{3,}?):(..):(.+)$} $element _ form_lang form (prefix) (stripped_name)]} { + array set "" [list link_type "link" form "$form_lang:$form.form"] + set name $(prefix):$(stripped_name) + #my msg "FIRST case name=$name, form=$form_lang:$form" + } elseif {[regexp {^(..):([^:]{3,}?):(.+)$} $element _ form_lang form (stripped_name)]} { + array set "" [list link_type "link" form "$form_lang:$form.form" prefix $default_lang] + set name $default_lang:$(stripped_name) + set use_default_lang 1 + #my msg "SECOND case name=$name, form=$form_lang:$form" + } elseif {[regexp {^([^:]{3,}?):(..):(.+)$} $element _ form (prefix) (stripped_name)]} { + array set "" [list link_type "link" form "$default_lang:$form.form"] + set name $(prefix):$(stripped_name) + #my msg "THIRD case name=$name, form=$default_lang:$form" + } elseif {[regexp {^([^:]{3,}?):(.+)$} $element _ form (stripped_name)]} { + array set "" [list link_type "link" form "$default_lang:$form.form" prefix $default_lang] + set name $default_lang:$(stripped_name) + set use_default_lang 1 + #my msg "FOURTH case name=$name, form=$default_lang:$form" + } elseif {[regexp {^(..):(.+)$} $element _ (prefix) (stripped_name)]} { + array set "" [list link_type "link"] + set name $(prefix):$(stripped_name) + } elseif {[regexp {^(.+)\0$} $element _ (stripped_name)]} { + array set "" [list link_type "link" form "en:folder.form" prefix ""] + set name $(stripped_name) + } elseif {$assume_folder} { + array set "" [list link_type "link" form "en:folder.form" prefix "" stripped_name $element] + set name $element + } else { + array set "" [list link_type "link" prefix $default_lang stripped_name $element] + set name $default_lang:$element + set use_default_lang 1 + } + + if {$use_default_lang && $default_lang eq ""} { + my log "WARNING: Trying to use empty default lang on link '$element' => $name" + } + + set name [string trimright $name \0] + set (stripped_name) [string trimright $(stripped_name) \0] + + if {$element eq "" || $element eq "\0"} { + set folder_id [my folder_id] + array set "" [my item_info_from_id $folder_id] + set item_id $folder_id + set parent_id $(parent_id) + #my msg "SETTING item_id $item_id parent_id $parent_id // [array get {}]" + } elseif {$element eq "." || $element eq ".\0"} { + array set "" [my item_info_from_id $parent_id] + set item_id $parent_id + set parent_id $(parent_id) + } elseif {$element eq ".." || $element eq "..\0"} { + set id [::xo::db::CrClass get_parent_id -item_id $parent_id] + if {$id > 0} { + # refuse to traverse past root folder + set parent_id $id + } + array set "" [my item_info_from_id $parent_id] + set item_id $parent_id + set parent_id $(parent_id) + } else { + # with the following construct we need in most cases just 1 lookup + + set item_id [my lookup \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -name $name -parent_id $parent_id] + #my log "[my id] lookup -use_package_path $use_package_path -name $name -parent_id $parent_id => $item_id" + + if {$item_id == 0} { + # + # The first lookup was not successful, so we try again. + # + if {$(link_type) eq "link" && $element eq $(stripped_name)} { + # + # try a direct lookup, in case it is a folder + # + set item_id [my lookup \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -name $(stripped_name) -parent_id $parent_id] + #my msg "try again direct lookup, parent_id $parent_id $(stripped_name) => $item_id" + if {$item_id > 0} {array set "" [list prefix ""]} + } + + if {$item_id == 0 && $(link_type) eq "link" && $assume_folder && $(prefix) eq ""} { + set item_id [my lookup \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -name $default_lang:$element -parent_id $parent_id] + if {$item_id > 0} {array set "" [list link_type "link" prefix $default_lang stripped_name $element] + } + } + + if {$item_id == 0 && $(link_type) eq "link" && $use_default_lang && $(prefix) ne "en"} { + # + # If the name was not specified explicitely (we are using + # $default_lang), try again with language "en" try again, + # maybe element is folder in a different language + # + set item_id [my lookup \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -name en:$(stripped_name) -parent_id $parent_id] + #my msg "try again in en en:$(stripped_name) => $item_id" + if {$item_id > 0} {array set "" [list link_type "link" prefix en]} + } + + # If the item is still unknown, try filename-based lookup, + # when the entry looks like a filename with an extension. + if {$item_id == 0 && [string match *.* $element] && ![regexp {[.](form|wf)$} $element]} { + # + # Get the mime type to distinguish between images, flash + # files and ordinary files. + # + set mime_type [::xowiki::guesstype $name] + set (prefix) file + switch -glob $mime_type { + "image/*" { + set name file:$(stripped_name) + set (link_type) image + } + application/x-shockwave-flash { + set name file:$(stripped_name) + set (link_type) swf + } + default { + set name file:$(stripped_name) + if {![info exists (link_type)]} {set (link_type) file} + } + } + set item_id [my lookup \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -name file:$(stripped_name) -parent_id $parent_id] + } + } + } + + #my msg "return link_type $(link_type) prefix $(prefix) stripped_name $(stripped_name) form $(form) parent_id $parent_id item_id $item_id" + return [list link_type $(link_type) prefix $(prefix) stripped_name $(stripped_name) \ + form $(form) parent_id $parent_id item_id $item_id ] + } + + Package instproc item_info_from_id { + item_id + } { + # + # Obtain (partial) item info from id. It does not handle + # e.g. special link_types as for e.g file|image|js|css|swf, etc. + # + ::xo::db::CrClass get_instance_from_db -item_id $item_id + set name [$item_id name] + set parent_id [$item_id parent_id] + if {[$item_id is_folder_page]} { + return [list link_type "folder" prefix "" stripped_name $name parent_id $parent_id] + } + regexp {^(.+):(.+)$} $name _ prefix stripped_name + return [list link_type "link" prefix $prefix stripped_name $stripped_name parent_id $parent_id] + } + + Package instproc item_info_from_url {{-with_package_prefix true} {-default_lang ""} url} { + # + # Obtain item info (item_id parent_id lang stripped_name) from the + # specified url. Search starts always at the root. + # + # @parm with_package_prefix flag, if provided url contains package-url + # @return item ref data (parent_id lang stripped_name method) + # + if {$with_package_prefix && [string match /* $url]} { + set url [string range $url [string length [my package_url]] end] + } + if {$default_lang eq ""} {set default_lang [my default_language]} + my get_lang_and_name -default_lang $default_lang -path $url (lang) stripped_url + set (parent_id) [my get_parent_and_name \ + -lang $(lang) -path $stripped_url \ + -parent_id [my folder_id] \ + parent (stripped_name)] + + #my msg "get_parent_and_name '$stripped_url' returns [array get {}]" + + if {![regexp {^(download)/(.+)$} $(lang) _ (method) (lang)]} { + set (method) "" + # The lang value "tag" is used for allowing tag-urls without + # parameters, since several tag harvester assume such a syntax + # and don't process arguments. We rewrite in such cases simply + # the url and query parameters and update the connection + # context. + if {$(lang) eq "tag"} { + # todo: missing: tag links to subdirectories, also on url generation + set tag $stripped_url + set summary [::xo::cc query_parameter summary 0] + set popular [::xo::cc query_parameter popular 0] + set tag_kind [expr {$popular ? "ptag" :"tag"}] + set weblog_page [my get_parameter weblog_page] + my get_lang_and_name -default_lang $default_lang -name $weblog_page (lang) (stripped_name) + #set name $(lang):$(stripped_name) + my set object $weblog_page + ::xo::cc set actual_query $tag_kind=$tag&summary=$summary + } + } + array set "" [my prefixed_lookup -parent_id $(parent_id) \ + -default_lang $default_lang -lang $(lang) -stripped_name $(stripped_name)] + #my msg "prefixed_lookup '$(stripped_name)' returns [array get {}]" + + if {$(item_id) == 0} { + # check link (todo should happen in package->lookup?) + ::xo::db::CrClass get_instance_from_db -item_id $(parent_id) + if {[$(parent_id) is_link_page] && [$(parent_id) is_folder_page]} { + set target [$(parent_id) get_target_from_link_page] + #$target set_resolve_context -package_id [my id] -parent_id $(parent_id) + #my msg "LINK prefixed LOOKUP from target-package [$target package_id] source package [my id]" + array set "" [[$target package_id] prefixed_lookup -parent_id [$target item_id] \ + -default_lang $default_lang -lang $(lang) -stripped_name $(stripped_name)] + #my msg "-lang $(lang) -stripped_name $(stripped_name) => got=$(item_id)" + } + } + return [array get ""] + } + + Package instproc get_page_from_item_ref { + {-allow_cross_package_item_refs true} + {-use_package_path false} + {-use_site_wide_pages true} + {-use_prototype_pages false} + {-default_lang ""} + {-parent_id ""} + link + } { + # + # Get page from an item ref name (either with language prefix or + # not). First it try to resolve the item_ref from the actual + # package. If not successful, it checks optionally along the + # package_path and on the side-wide pages. + # + # @return page object or empty (""). + # + #my log "get_page_from_item_ref [self args]" + + if {$allow_cross_package_item_refs && [string match //* $link]} { + + # todo check: get_package_id_from_page_name uses a different lookup based on site nodes + + set referenced_package_id [my resolve_package_path $link rest_link] + #my log "get_page_from_item_ref $link recursive rl?[info exists rest_link] in $referenced_package_id" + if {$referenced_package_id != 0 && $referenced_package_id != [my id]} { + # TODO: we have still to check, whether or not we want + # site-wide-pages etc. in cross package links, and if, under + # which parent we would like to create newly importage pages. + # + # For now, we do not want to create pages this way, we pass + # the root folder of the referenced package as start + # parent_page for the search and turn off all page creation + # facilities. + + #my log cross-package + return [$referenced_package_id get_page_from_item_ref \ + -allow_cross_package_item_refs false \ + -use_package_path false \ + -use_site_wide_pages false \ + -use_prototype_pages false \ + -default_lang $default_lang \ + -parent_id [$referenced_package_id folder_id] \ + $rest_link] + } else { + # it is a link to the same package, we start search for page at top. + set link $rest_link + set search_parent_id "" + } + } else { + set search_parent_id $parent_id + } + + #my log "my folder [my folder_id]" + + if {$search_parent_id eq ""} { + set search_parent_id [my folder_id] + } + if {$parent_id eq ""} { + set parent_id [my folder_id] + } + #my log call-item_ref-on:$link-parent_id=$parent_id,search_parent_id=$search_parent_id + array set "" [my item_ref -normalize_name false \ + -use_package_path $use_package_path \ + -use_site_wide_pages $use_site_wide_pages \ + -default_lang $default_lang \ + -parent_id $search_parent_id \ + $link] + + #my msg "[my instance_name] (root [my folder_id]) item-ref for '$link' search parent $search_parent_id, parent $parent_id, returns\n[array get {}]" + if {$(item_id)} { + set page [::xo::db::CrClass get_instance_from_db -item_id $(item_id)] + if {[$page package_id] ne [my id] || [$page parent_id] != $(parent_id)} { + #my msg "set_resolve_context site_wide_pages [my id] and -parent_id $parent_id" + $page set_resolve_context -package_id [my id] -parent_id $parent_id + } + return $page + } + + if {!$(item_id) && $use_prototype_pages} { + array set "" [my item_ref \ + -normalize_name false \ + -default_lang $default_lang \ + -parent_id $parent_id \ + $link] + set page [::xowiki::Package import_prototype_page \ + -package_key [my package_key] \ + -name $(stripped_name) \ + -parent_id $(parent_id) \ + -package_id [my id] ] + #my msg "import_prototype_page for '$(stripped_name)' => '$page'" + if {$page ne ""} { + # we want to be able to address the page via ::$item_id + set page [::xo::db::CrClass get_instance_from_db -item_id [$page item_id]] + } + return $page + } + + return "" + } + + # + # import for prototype pages + # + + 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 page [::xowiki::Package import_prototype_page \ + -package_key [my package_key] \ + -name $prototype_name \ + -parent_id [my folder_id] \ + -package_id [my id] ] + + if {[info exists via_url] && [my exists_query_parameter "return_url"]} { + my returnredirect [my query_parameter "return_url" [my package_url]] + } + return $page + } + + Package proc import_prototype_page { + -package_key:required + -name:required + -parent_id:required + -package_id:required + } { + set page "" + set fn [get_server_root]/packages/$package_key/www/prototypes/$name.page + my log "--W check $fn" + if {[file readable $fn]} { + my instvar id + # We have the file of the prototype page. We try to create + # either a new item or a revision from definition in the file + # system. + if {[regexp {^(..):(.*)$} $name _ lang local_name]} { + set fullName $name + } else { + set fullName en:$name + } + my log "--sourcing page definition $fn, using name '$fullName'" + set page [source $fn] + $page configure -name $fullName \ + -parent_id $parent_id -package_id $package_id + # xowiki::File has a different interface for build-name to + # derive the "name" from a file-name. This is not important for + # prototype pages, so we skip it + if {![$page istype ::xowiki::File]} { + $page name [$page build_name] + } + 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 p [$package_id get_page_from_name -name $fullName -parent_id $parent_id] + if {$p eq ""} { + # We have to create the page new. The page is completed with + # missing vars on save_new. + $page save_new + } else { + # An old page exists already, make a revision. Update the + # existing page with all scalar variables from the prototype + # page (which is just partial) + foreach v [$page info vars] { + if {[$page array exists $v]} continue ;# don't copy arrays + $p set $v [$page set $v] + } + $p save + set page $p + } + if {$page ne ""} { + # we want to be able to address the page via the canonical name ::$item_id + set page [::xo::db::CrClass get_instance_from_db -item_id [$page item_id]] + } + } + return $page + } + + Package proc require_site_wide_pages { + {-refetch:boolean false} + } { + set parent_id -100 + set package_id [::xowiki::Package first_instance] + ::xowiki::Package require $package_id + #::xowiki::Package initialize -package_id $package_id -init_url false -keep_cc true + set package_key "xowiki" + + foreach n {folder.form link.form page.form import-archive.form photo.form} { + set item_id [::xo::db::CrClass lookup -name en:$n -parent_id $parent_id] + #my ds "lookup en:$n => $item_id" + if {!$item_id || $refetch} { + set page [::xowiki::Package import_prototype_page \ + -name $n \ + -package_key $package_key \ + -parent_id $parent_id \ + -package_id $package_id ] + my log "Page en:$n loaded as '$page'" + } + } + } + + Package proc lookup_side_wide_page {-name:required} { + return [::xo::db::CrClass lookup -name $name -parent_id -100] + } + + Package proc get_site_wide_page {-name:required} { + set item_id [my lookup_side_wide_page -name $name] + #my ds "lookup from base objects $name => $item_id" + if {$item_id} { + set page [::xo::db::CrClass get_instance_from_db -item_id $item_id] + ::xo::Package require [$page package_id] + return $page + } + return "" + } + + Package instproc call {object method options} { + my instvar policy id + set allowed [$policy enforce_permissions \ + -package_id $id -user_id [::xo::cc user_id] \ + $object $method] + if {$allowed} { + #my log "--p calling $object ([$object name] [$object info class]) '$method'" + eval $object $method $options + } else { + my log "not allowed to call $object $method" + } + } + Package instforward check_permissions {%my set policy} %proc + + Package ad_instproc require_root_folder { + {-parent_id -100} + {-content_types {}} + -name:required + } { + Make sure, the root folder for the given package exists. If not, + create it and register all allowed content types. + + @return folder_id + } { + my instvar id + + set folder_id [ns_cache eval xotcl_object_type_cache root_folder-$id { + + set folder_id [::xo::db::CrClass lookup -name $name -parent_id $parent_id] + if {$folder_id == 0} { + ::xowiki::Package require_site_wide_pages + set form_id [::xowiki::Weblog instantiate_forms -forms en:folder.form -package_id $id] + set f [FormPage new -destroy_on_cleanup \ + -name $name \ + -text "" \ + -package_id $id \ + -parent_id $parent_id \ + -nls_language en_US \ + -publish_status ready \ + -instance_attributes {} \ + -page_template $form_id] + $f save_new + set folder_id [$f item_id] + + ::xo::db::sql::acs_object set_attribute -object_id_in $folder_id \ + -attribute_name_in context_id -value_in $id + + my log "CREATED folder '$name' and parent $parent_id ==> $folder_id" + } + + # register all specified content types + #::xo::db::CrFolder register_content_types \ + # -folder_id $folder_id \ + # -content_types $content_types + #my log "returning from cache folder_id $folder_id" + return $folder_id + }] + #my log "returning from require folder_id $folder_id" + return $folder_id + } + + Package instproc require_folder_object { } { + set folder_id [my require_root_folder -name "xowiki: [my id]" \ + -content_types ::xowiki::Page* ] + ::xo::db::CrClass get_instance_from_db -item_id $folder_id + my set folder_id $folder_id + } + + + ############################################################### + # + # user callable methods on package level + # + + Package ad_instproc refresh-login {} { + Force a refresh of a login and do a redict. Intended for use from ajax. + } { + set return_url [my query_parameter return_url] + if {[::xo::cc user_id] == 0} { + set url [subsite::get_url]register + ad_returnredirect [export_vars -base $url return_url] + } else { + ad_returnredirect $return_url + } + } + + # + # reindex (for site wide search) + # + + Package ad_instproc reindex {} { + reindex all items of this package + } { + my instvar folder_id id + set pages [db_list [my qn get_pages] { + select page_id,package_id from xowiki_page, cr_revisions r, cr_items ci, acs_objects o + where page_id = r.revision_id and ci.item_id = r.item_id and ci.live_revision = page_id + and publish_status = 'ready' + and page_id = o.object_id and o.package_id = :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 + } + ad_returnredirect . + } + + # + # change-page-order (normally called via ajax POSTs) + # + Package ad_instproc change-page-order {} { + Change Page Order for pages by renumbering and filling gaps. + } { + my instvar folder_id + set to [string trim [my form_parameter to ""]] + set from [string trim [my form_parameter from ""]] + set clean [string trim [my form_parameter clean ""]] ;# only for inserts + + #set from {1.2 1.3 1.4}; set to {1.3 1.4 1.2}; set clean {...} + #set from {1.2 1.3 1.4}; set to {1.3 1.4 2.1 1.2}; set clean {2.1} + #set from {1 2}; set to {1 1.2 2}; set clean {1.2 1.3 1.4} + + if {$from eq "" || $to eq "" || [llength $to]-[llength $from] >1 || [llength $to]-[llength $from]<0} { + my log "unreasonable request from='$from', to='$to'" + return + } + my log "--cpo from=$from, to=$to, clean=$clean" + set gap_renames [list] + # + # We distinguish two cases: + # - pure reordering: length(to) == length(from) + # - insert from another section: length(to) == length(from)+1 + # + if {[llength $to] == [llength $from]} { + my log "--cpo reorder" + } elseif {[llength $clean] > 1} { + my log "--cpo insert" + # + # We have to fill the gap. First, find the newly inserted + # element in $to. + # + foreach e $to { + if {[lsearch -exact $from $e] == -1} { + set inserted $e + break + } + } + if {![info exists inserted]} {error "invalid 'to' list (no inserted element detected)"} + # + # compute the remaining list + # + set remaining [list] + foreach e $clean {if {$e ne $inserted} {lappend remaining $e}} + # + # compute rename rename commands for it + # + set gap_renames [::xowiki::utility page_order_renames -parent_id $folder_id \ + -start [lindex $clean 0] -from $remaining -to $remaining] + foreach {page_id item_id name old_page_order new_page_order} $gap_renames { + my log "--cpo gap $page_id (name) rename $old_page_order to $new_page_order" + } + } + # + # Compute the rename commands for the drop target + # + set drop_renames [::xowiki::utility page_order_renames -parent_id $folder_id \ + -start [lindex $from 0] -from $from -to $to] + #my log "--cpo drops l=[llength $drop_renames]" + foreach {page_id item_id name old_page_order new_page_order} $drop_renames { + my log "--cpo drop $page_id ($name) rename $old_page_order to $new_page_order" + } + + # + # Perform the actual renames + # + set temp_obj [::xowiki::Page new -name dummy -volatile] + set slot [$temp_obj find_slot page_order] + db_transaction { + foreach {page_id item_id name old_page_order new_page_order} [concat $drop_renames $gap_renames] { + #my log "--cpo UPDATE $page_id new_page_order $new_page_order" + $temp_obj item_id $item_id + $temp_obj update_attribute_from_slot -revision_id $page_id $slot $new_page_order + ::xo::clusterwide ns_cache flush xotcl_object_cache ::$item_id + ::xo::clusterwide ns_cache flush xotcl_object_cache ::$page_id + } + } + # + # Flush the page fragement caches (page fragments based on page_order might be sufficient) + my flush_page_fragment_cache -scope agg + ns_return 200 text/plain ok + } + + + + # + # 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 name_filter]} { + set name_filter [my get_parameter -type word name_filter ""] + } + if {![info exists entries_of]} { + set entries_of [my get_parameter entries_of ""] + } + if {![info exists title]} { + set title [my get_parameter PackageTitle [my instance_name]] + } + set description [my get_parameter PackageDescription ""] + + 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] \ + -parent_ids [my query_parameter parent_ids ""] \ + -name_filter $name_filter \ + -entries_of $entries_of \ + -title $title \ + -description $description \ + -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 "ci.parent_id, 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 -parent_id $parent_id $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] { + if {![::xo::parameter get -package_id $package_id \ + -parameter include_in_google_sitemap_index -default 1]} { + continue + } + 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)sitemap.xml \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] + } + + # + # Create new pages + # + + 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 parent_id [$id query_parameter parent_id ""] + if {$parent_id eq ""} {set parent_id [$id form_parameter folder_id $folder_id]} + set page [$object_type new -volatile -parent_id $parent_id -package_id $id] + #my ds "parent_id of $page = [$page parent_id], cl=[$page info class] parent_id=$parent_id\n[$page serialize]" + if {$object_type eq "::xowiki::PageInstance"} { + # + # If we create a PageInstance via the ad_form based + # PageInstanceForm, we have to provide the page_template here to + # be able to validate the name, where "build_name" needs + # access to the ::xowiki::PageTemplate of the + # ::xowiki::PageInstance. + # + $page set page_template [my form_parameter page_template] + } + + set source_item_id [$id query_parameter source_item_id ""] + if {$source_item_id ne ""} { + set source [$object_type get_instance_from_db -item_id $source_item_id] + $page copy_content_vars -from_object $source + set name "[::xowiki::autoname new -parent_id $source_item_id -name [$source name]]" + #my get_lang_and_name -name $name lang name + $page set name $name + #my msg nls=[$page nls_language],source-nls=[$source nls_language],page=$page,name=$name + } else { + $page set name "" + } + + return [$page edit -new true -autoname $autoname] + } + + # + # manage categories + # + + Package instproc manage-categories {} { + set object_id [my query_parameter object_id] + if {![string is integer -strict $object_id]} { return [my error_msg "No valid object_id provided!"] } + + # flush could be made more precise in the future + my flush_page_fragment_cache -scope agg + + my returnredirect [site_node::get_package_url -package_key categories]cadmin/object-map?ctx_id=$object_id&object_id=$object_id + } + + # + # edit a single category tree + # + + Package instproc edit-category-tree {} { + set object_id [my query_parameter object_id] + if {![string is integer -strict $object_id]} { return [my error_msg "No valid object_id provided!"] } + set tree_id [my query_parameter tree_id] + if {![string is integer -strict $tree_id]} { return [my error_msg "No valid tree_id provided!"] } + + # flush could be made more precise in the future + my flush_page_fragment_cache -scope agg + my returnredirect [site_node::get_package_url -package_key categories]cadmin/tree-view?tree_id=$tree_id&ctx_id=$object_id&object_id=$object_id + } + + + # + # Package import + # + + Package ad_instproc import {-user_id {-parent_id 0} {-replace 0} -objects {-create_user_ids 0}} { + import the specified pages into the xowiki instance + } { + if {$parent_id == 0} {set parent_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 importer [Importer new -package_id [my id] -parent_id $parent_id -user_id $user_id] + $importer import_all -replace $replace -objects $objects -create_user_ids $create_user_ids + append msg [$importer report] + } + + Package instproc flush_references {-item_id:integer,required -name -parent_id} { + my instvar id folder_id + if {![info exists parent_id]} { + set parent_id [::xo::db::CrClass get_parent_id -item_id $item_id] + } + if {![info exists name]} { + set name [::xo::db::CrClass get_name -item_id $item_id] + } + my flush_name_cache -name $name -parent_id $parent_id + } + + Package instproc flush_name_cache {-name:required -parent_id:required} { + # Different machines in the cluster might have different entries in their caches. + # Since we use wild-cards to find these, it has to be done on every machine + ::xo::clusterwide xo::cache_flush_all xowiki_cache link-*-$name-$parent_id + ::xo::clusterwide ns_cache flush xotcl_object_type_cache $parent_id-$name + } + + Package instproc delete_revision {-revision_id:required -item_id:required} { + ::xo::clusterwide ns_cache flush xotcl_object_cache ::$item_id + ::xo::clusterwide ns_cache flush xotcl_object_cache ::$revision_id + ::xo::db::sql::content_revision del -revision_id $revision_id + } + + Package instproc delete {-item_id -name -parent_id} { + # + # 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 log "--D delete [self args]" + # + my instvar id + # + # if no item_id given, take it from the query parameter + # + if {![info exists item_id]} { + set item_id [my query_parameter item_id] + #my log "--D item_id from query parameter $item_id" + } + # + # if no name is given, take it from the query parameter + # + if {![info exists name]} { + set name [my query_parameter name] + } + + if {$item_id eq ""} { + array set "" [my item_info_from_url -with_package_prefix false $name] + if {$(item_id) == 0} { + ns_log notice "lookup of '$name' with parent_id $parent_id failed" + } else { + set parent_id $(parent_id) + set item_id $(item_id) + set name $(name) + } + } else { + set name [::xo::db::CrClass get_name -item_id $item_id] + if {![info exists parent_id]} { + set parent_id [::xo::db::CrClass get_parent_id -item_id $item_id] + } + } + #my msg item_id=$item_id/name=$name + + if {$item_id ne ""} { + my log "--D trying to delete $item_id $name" + set object_type [::xo::db::CrClass 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 -publish_status all] + if {$count > 0} { + return [$id error_msg \ + [_ xowiki.error-delete_entries_first [list count $count]]] + } + } + if {[my get_parameter "with_general_comments" 0]} { + # + # We have general comments. In a first step, we have to delete + # these, before we are able to delete the item. + # + set comment_ids [db_list [my qn get_comments] \ + "select comment_id from general_comments where object_id = $item_id"] + foreach comment_id $comment_ids { + my log "-- deleting comment $comment_id" + ::xo::db::sql::content_item del -item_id $comment_id + } + } + foreach child_item_id [::xo::db::CrClass get_child_item_ids -item_id $item_id] { + my flush_references -item_id $child_item_id + } + $object_type delete -item_id $item_id + my flush_references -item_id $item_id -name $name -parent_id $parent_id + my flush_page_fragment_cache -scope agg + } else { + my log "--D nothing to delete!" + } + my returnredirect [my query_parameter "return_url" [$id package_url]] + } + + Package instproc flush_page_fragment_cache {{-scope agg}} { + switch -- $scope { + agg {set key PF-[my id]-agg-*} + all {set key PF-[my id]-*} + default {error "unknown scope for flushing page fragment cache"} + } + foreach entry [ns_cache names xowiki_cache $key] { + ns_log notice "::xo::clusterwide ns_cache flush xowiki_cache $entry" + ::xo::clusterwide ns_cache flush xowiki_cache $entry + } + } + + # + # Perform per connection parameter caching. Using the + # per-connection cache speeds later lookups up by a factor of 15. + # Repeated parameter lookups are quite likely + # + + Class ParameterCache + ParameterCache instproc get_parameter {{-check_query_parameter true} {-type ""} attribute {default ""}} { + set key [list [my id] [self proc] $attribute] + if {[info command "::xo::cc"] ne ""} { + if {[::xo::cc cache_exists $key]} { + return [::xo::cc cache_get $key] + } + return [::xo::cc cache_set $key [next]] + } else { + # in case, we have no ::xo::cc (e.g. during bootstrap). + ns_log notice "warning: no ::xo::cc available, returning default for parameter $attribute" + return $default + } + } + Package instmixin add ParameterCache + + + # + # policy management + # + + Package instproc condition=has_class {query_context value} { + return [expr {[$query_context query_parameter object_type ""] eq $value}] + } + Package instproc condition=has_name {query_context value} { + return [regexp $value [$query_context query_parameter name ""]] + } + + Class create Policy -superclass ::xo::Policy + + Policy policy1 -contains { + + Class Package -array set require_permission { + reindex swa + change-page-order {{id admin}} + import-prototype-page swa + refresh-login none + rss none + google-sitemap none + google-sitemapindex none + manage-categories {{id admin}} + edit-category-tree {{id admin}} + delete {{id admin}} + edit-new { + {{has_class ::xowiki::Object} swa} + {{has_class ::xowiki::FormPage} nobody} + {{has_name {[.](js|css)$}} id admin} + {id create} + } + } + + Class Page -array set require_permission { + view none + revisions {{package_id write}} + diff {{package_id write}} + edit { + {{regexp {name {(weblog|index)$}}} package_id admin} + {package_id write} + } + save-form-data {{package_id write}} + save-attributes {{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 {{parent_id create}} + create-or-use {{parent_id create}} + } -set default_permission {{package_id write}} + + Class Object -array set require_permission { + edit swa + } + Class File -array set require_permission { + download none + } + Class Form -array set require_permission { + list {{package_id read}} + edit admin + view admin + } + Class CrFolder -array set require_permission { + view none + delete {{package_id admin}} + edit-new {{item_id write}} + } + } + + Policy policy2 -contains { + # + # we require side wide admin rights for deletions and code + # + + Class Package -array set require_permission { + reindex {{id admin}} + rss none + refresh-login none + google-sitemap none + google-sitemapindex none + change-page-order {{id admin}} + manage-categories {{id admin}} + edit-category-tree {{id admin}} + delete swa + edit-new { + {{has_class ::xowiki::Object} swa} + {{has_class ::xowiki::FormPage} nobody} + {{has_name {[.](js|css)$}} swa} + {id create} + } + } + + Class Page -array set require_permission { + view {{package_id read}} + revisions {{package_id write}} + diff {{package_id write}} + edit { + {{regexp {name {(weblog|index)$}}} package_id admin} + {package_id write} + } + save-attributes {{package_id write}} + make-live-revision {{package_id write}} + delete-revision swa + delete swa + save-tags login + popular-tags login + create-new {{parent_id create}} + create-or-use {{parent_id create}} + } + + Class Object -array set require_permission { + edit swa + } + Class File -array set require_permission { + download {{package_id read}} + } + Class Form -array set require_permission { + view admin + edit admin + list {{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 + refresh-login none + google-sitemap none + google-sitemapindex none + change-page-order {{id admin}} + manage-categories {{id admin}} + edit-category-tree {{id admin}} + delete swa + edit-new { + {{has_class ::xowiki::Object} swa} + {{has_class ::xowiki::FormPage} nobody} + {{has_name {[.](js|css)$}} 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}} + save-attributes {{package_id write}} + delete-revision swa + delete swa + save-tags login + popular-tags login + create-new {{parent_id create}} + create-or-use {{parent_id create}} + } + + Class Object -array set require_permission { + edit swa + } + Class File -array set require_permission { + download {{package_id read}} + } + Class Form -array set require_permission { + view admin + edit admin + list {{item_id read}} + } +# Class FormPage -array set require_permission { +# view { +# {{is_true {_creation_user = @current_user@}} item_id read} +# swa +# } +# } + } + + #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]" + + # + # an example with in_state condition... + # + Policy policy5 -contains { + + Class Package -array set require_permission { + reindex {{id admin}} + rss none + refresh-login none + google-sitemap none + google-sitemapindex none + change-page-order {{id admin}} + manage-categories {{id admin}} + edit-category-tree {{id admin}} + delete swa + edit-new { + {{has_class ::xowiki::Object} swa} + {{has_class ::xowiki::FormPage} nobody} + {{has_name {[.](js|css)$}} 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}} + save-attributes {{item_id write}} + make-live-revision {{item_id write}} + delete-revision swa + delete swa + save-tags login + popular-tags login + create-new {{parent_id create}} + create-or-use {{parent_id create}} + } + + Class Object -array set require_permission { + edit swa + } + Class File -array set require_permission { + download {{package_id read}} + } + Class FormPage -array set require_permission { + view creator + edit { + {{in_state initial|suspended|working} creator} admin + } + } + Class Form -array set require_permission { + view admin + edit admin + list admin + } + } + +} + +::xo::library source_dependent + + + 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 13 Sep 2012 16:05:28 -0000 1.40 @@ -0,0 +1,569 @@ +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 create RSS -superclass XMLSyndication -parameter { + maxentries + {parent_ids ""} + {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.publish_date "$days days"] + } + if {$entries_of ne ""} { + if {[regexp {^[0-9 ]+$} $entries_of]} { + # form item_ids were provided as a filter + set form_items $entries_of + } else { + set form_items [::xowiki::Weblog instantiate_forms \ + -forms $entries_of \ + -package_id $package_id] + } + + if {[llength $form_items] == 0} { + # In case, we have no form_items to select on, let the query fail + # without causing a SQL error. + set form_items [list -1] + } + 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 + + if {[my parent_ids] ne ""} { + set folder_ids [my parent_ids] + } else { + set folder_ids [::$package_id folder_id] + } + + my set link $siteurl[lindex [site_node::get_url_from_object_id -object_id $package_id] 0] + + 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, s.rss_xml_frag, p.name, p.creator, p.title, p.page_id, instance_attributes, \ + p.object_type as content_type, p.publish_date, p.description" \ + -from "syndication s, cr_items ci, $base_table p $extra_from" \ + -where "ci.parent_id in ([join $folder_ids ,]) \ + and ci.live_revision = s.object_id \ + and ci.publish_status <> 'production' \ + and s.object_id = p.page_id \ + $extra_where_clause"\ + -orderby "p.publish_date desc" \ + -limit [my limit]] + + set content [my head] + db_foreach [my qn get_pages] $sql { + if {[string match "::*" $name]} continue + if {$content_type eq "::xowiki::PageTemplate" || $content_type eq "::xowiki::Form"} continue + append content $rss_xml_frag + } + 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_ids [::$package_id folder_id] + if {$summary eq ""} {set summary $description} + if {$subtitle eq ""} {set subtitle $title} + + my set link $siteurl[lindex [site_node::get_url_from_object_id -object_id $package_id] 0] + + 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 in ([join $folder_ids ,]) 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 [my qn 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 \ + -parent_id $parent_id $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_ids [::$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, ci.parent_id, o.creation_user, cr.publish_date, o2.creation_date, \ + cr.item_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 in ([join $folder_ids ,]) and o.creation_user is not null + $where_clause" \ + -orderby "revision_id desc" \ + -limit $limit] + db_foreach [my qn 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 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 \ + -parent_id [$i set parent_id] \ + [$i set name]]] \ + event $event] \n + } + append result \n + return $result + } +} + +namespace eval ::xowiki { + # This is the class representing an RSS client + Class create RSS-client -parameter url + + # Constructor for a given URI + RSS-client instproc init {} { + set XML [my load] + if {$XML ne ""} { + my parse $XML + } + } + + RSS-client instproc load { } { + set r [::xo::HttpRequest new -url [my url] -volatile] + #my msg "statuscode = [$r set status_code], content_type=[$r set content_type]" + #set f [open /tmp/feed w]; fconfigure $f -translation binary; puts $f [$r set data]; close $f + if {[$r exists status] && [$r set status] eq "canceled"} { + my set errorMessage [$r set cancel_message] + } + return [$r set data] + # the following does not appear to be necessary due to changes in http-client-procs. + #set charset utf-8 + #regexp {^<\?xml\s+version\s*=\s*\S+\s+encoding\s*=\s*[\"'](\S+)[\"']} $xml _ charset + #ns_log notice "charse=$charset,xml=$xml" + #return [encoding convertfrom [string tolower $charset] $xml] + } + + RSS-client instproc parse {data} { + set doc [ dom parse $data ] + set root [ $doc documentElement ] + + switch [RSS-client getRSSVersion $doc] { + 0.91 - 0.92 - 0.93 - 2.0 { + my array set xpath { + title {/rss/channel/title/text()} + link {/rss/channel/link/text()} + imgNode {/rss/channel/image/title} + imgTitle {/rss/channel/image/title/text()} + imgLink {/rss/channel/image/url/text()} + imgWidth {/rss/channel/image/width/text()} + imgHeight {/rss/channel/image/height/text()} + stories {/rss/channel/item} + itemTitle {title/text()} + itemLink {link/text()} + itemPubDate {pubDate/text()} + itemDesc {description/text()} + } + } + 1.0 { + my array set xpath { + title {/rdf:RDF/*[local-name()='channel']/*[local-name()='title']/text()} + link {/rdf:RDF/*[local-name()='channel']/*[local-name()='link']/text()} + imgNode {/rdf:RDF/*[local-name()='image']} + imgTitle {/rdf:RDF/*[local-name()='image']/*[local-name()='title']/text()} + imgLink {/rdf:RDF/*[local-name()='image']/*[local-name()='url']/text()} + imgWidth {/rdf:RDF/*[local-name()='image']/*[local-name()='width']/text()} + imgHeight {/rdf:RDF/*[local-name()='image']/*[local-name()='height']/text()} + stories {/rdf:RDF/*[local-name()='item']} + itemTitle {*[local-name()='title']/text()} + itemLink {*[local-name()='link']/text()} + itemPubDate {*[local-name()='pubDate']/text()} + itemDesc {*[local-name()='description']/text()} + } + + } + default { + my set errorMessage "Unsupported RSS schema [RSS-client getRSSVersion $doc]" + return + #error "Unsupported schema [RSS-client getRSSVersion $doc]" + } + } + + # Channel + set cN [ $root child 1 channel ] + set channel [::xowiki::RSS-client::channel create [self]::channel -root $cN] + + # Items + my set items {} + set stories [$root selectNodes [my set xpath(stories)] ] + foreach iN $stories { + my lappend items [::xowiki::RSS-client::item new -childof [self] -node $iN ] + } + } + + # returns the XPath Query for a given type + RSS-client instproc xpath { key } { + return [my set xpath($key)] + } + + # returns the channel object + RSS-client instproc channel {} { + return [self]::channel + } + + # returns a list of items + RSS-client instproc items {} { + return [my set items] + } + + # detects the RSS version of the document + RSS-client proc getRSSVersion {doc} { + set root [$doc documentElement] + switch [$root nodeName] { + rss { + if {[$root hasAttribute version]} { + return [$root getAttribute version] + } + # Best guess as most stuff is optional... + return 0.92 + } + rdf:RDF { + return 1.0 + } + default { + return 0 + } + } + } + + # this namespace contains some utility methods + RSS-client proc node_uri {node xpath} { + set n [$node selectNode $xpath] + if {$n ne ""} { + # Only if there is a lonely &, quote it back to an entity. + return [string map { & %26 } [$n nodeValue]] + } else { + return "" + } + } + + RSS-client proc node_text {node xpath} { + set n [$node selectNode $xpath] + if {$n ne ""} { + return [$n nodeValue] + } else { + return "" + } + } + + # this class is used to contain rss items + Class create RSS-client::item -parameter node + RSS-client::item instforward xpath {%my info parent} %proc + + # get the title + RSS-client::item instproc title { } { + return [::xowiki::RSS-client node_text [my node] [my xpath itemTitle]] + } + + # get the link + RSS-client::item instproc link {} { + return [::xowiki::RSS-client node_uri [my node] [my xpath itemLink]] + } + + # get the description + RSS-client::item instproc description {} { + return [::xowiki::RSS-client node_text [my node] [my xpath itemDesc]] + } + + # return the publication date as string + RSS-client::item instproc pubDate {} { + return [::xowiki::RSS-client node_text [my node] [my xpath itemPubDate]] + } + + + # this class contains information on the channel + Class create RSS-client::channel -parameter root + RSS-client::channel instforward xpath {%my info parent} %proc + + # get the title + RSS-client::channel instproc title { } { + return [::xowiki::RSS-client node_text [my root] [my xpath title]] + } + + # get the image link + RSS-client::channel instproc imgLink {} { + return [::xowiki::RSS-client node_uri [my root] [my xpath imgLink]] + } + + # get the image title + RSS-client::channel instproc imgTitle {} { + return [::xowiki::RSS-client node_text [my root] [my xpath imgTitle]] + } + + # get the image width + RSS-client::channel instproc imgWidth {} { + return [::xowiki::RSS-client node_text [my root] [my xpath imgWidth]] + } + # get the image height + RSS-client::channel instproc imgHeight {} { + return [::xowiki::RSS-client node_text [my root] [my xpath imgHeight]] + } + + +} + +::xo::library source_dependent + 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 13 Sep 2012 16:05:28 -0000 1.4 @@ -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/tree-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/tree-procs.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/tcl/tree-procs.tcl 13 Sep 2012 16:05:28 -0000 1.10 @@ -0,0 +1,406 @@ +::xo::library doc { + Classes for creating, manageing and rendering trees + + @creation-date 2009-05-29 + @author Gustaf Neumann + @cvs-id $Id: tree-procs.tcl,v 1.10 2012/09/13 16:05:28 victorg Exp $ +} + +namespace eval ::xowiki { + # + # ::xowiki::Tree + # + # This class manages the creation and rendering of the nodes of the + # tree. It provides a name and id for rending in HTML. + + Class Tree \ + -superclass ::xo::OrderedComposite \ + -parameter { + {name ""} + id + } + + # + # Class methods + # + Tree proc renderer {style} { + set renderer TreeRenderer=$style + if {![my isclass $renderer]} { + error "No such renderer $renderer (avalialble [info commands ::xowiki::TreeRenderer=*]" + } + return $renderer + } + + Tree proc include_head_entries {{-renderer mktree} args} { + eval [my renderer $renderer] include_head_entries $args + } + + # + # Instance methods + # + Tree instproc init {} { + # If there is no id specified, use the name as id. + if {![my exists id]} {my id [my name]} + } + + Tree instproc add_item { + -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 + } + } + Tree instproc open_tree {} {;} + Tree instproc render {{-style mktree} {-js ""} {-context ""}} { + set renderer [[self class] renderer $style] + $renderer set context $context + $renderer set js $js + TreeNode instmixin $renderer + set content [$renderer render [self]] + TreeNode instmixin "" + if {[$renderer set js] ne ""} { + append content "\n\n" + } + return $content + } + + Tree instproc add_pages { + {-full false} + {-remove_levels 0} + {-book_mode false} + {-open_page ""} + {-expand_all false} + -owner + pages + } { + my instvar package_id + set tree(-1) [self] + my set open_node($tree(-1)) 1 + set pos 0 + foreach o [$pages children] { + $o instvar page_order title name + if {![regexp {^(.*)[.]([^.]+)} $page_order _ parent]} {set parent ""} + set page_number [$owner page_number $page_order $remove_levels] + + set level [regsub -all {[.]} [$o set page_order] _ page_order_js] + if {$full || [my exists open_node($parent)] || [my exists open_node($page_order)]} { + set href [$owner href $book_mode $name] + set is_current [expr {$open_page eq $name}] + set is_open [expr {$is_current || $expand_all}] + set c [::xowiki::TreeNode new -orderby pos -pos [incr pos] -level $level \ + -object $o -owner [self] \ + -label $title -prefix $page_number -href $href \ + -highlight $is_current \ + -expanded $is_open \ + -open_requests 1] + set tree($level) $c + for {set l [expr {$level - 1}]} {![info exists tree($l)]} {incr l -1} {} + $tree($l) add $c + if {$is_open} {$c open_tree} + } + } + return $tree(-1) + } + + # + # ::xowiki::TreeNode + # + # The TreeNode represents an n-ary node storing its child nodes in + # an ordered composite. In addition to its children, every node may + # have items associated. For example, a tree of categories can have + # associated categorized items, which can be added via the method + # "add_item". + # + Class TreeNode -superclass Tree -parameter { + level label pos {open_requests 0} count {href ""} + object owner li_id ul_id ul_class + {prefix ""} {expanded false} {highlight false} + } + + TreeNode instproc open_tree {} { + my open_requests 1 + my expanded true + if {[my exists __parent]} {[my set __parent] open_tree} + } + + TreeNode 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 + } + + TreeNode instproc render {} { + set content "" + if {[my isobject [self]::items]} { + foreach i [[self]::items children] { + append cat_content [my render_item -highlight [$i exists open_item] $i ] + } + foreach c [my children] {append cat_content [$c render] \n} + append content [my render_node -open [expr {[my 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_node -open true $cat_content] + + } + return $content + } + + # + # The rendering of trees is performed via rendering classes. All + # renderers are created and configured via the meta-class + # TreeRenderer. This meta-class defines the common attributes and + # behavior of all TreeRenders. + # + # In particular, the TreeRenders are defined to work with xowiki's + # page fragment caching. Via page fragment caching, the result of + # the rendering of includedlets is cached. However, the renderer + # might require additional CSS or JavaScript code, which has to be + # included for the cached HTML fragment as well. Therefore, the + # method "include_head_entries" is provided, which is called + # independently from HTML generation. + # + # + + Class create TreeRenderer -superclass Class \ + -parameter { + {subtree_wrapper_class} + {li_expanded_atts ""} + {highlight_atts {"style = 'font-weight:bold;'"}} + } + TreeRenderer instproc include_head_entries {args} { + # to be overloaded + } + TreeRenderer instproc render {tree} { + set content "" + foreach c [$tree children] {append content [$c render] \n} + return $content + } + + # + # The renderers should provide the following methods as procs + # + # - include_head_entries {args} + # - render {tree} + # + # (both are optional) and the following methods as instprocs + # + # - render_node {{-open:boolean false} cat_content} + # - render_item {{-highlight:boolean false} item} + # + # The last two methods are required. + + # Below are the currently defined tree renderers. We use as naming + # convention TreeRenderer= + + + + @header_stuff;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 13 Sep 2012 16:05:29 -0000 1.6 @@ -0,0 +1,24 @@ + + @edit_form_page_title;noquote@ + property_doc + @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 13 Sep 2012 16:05:29 -0000 1.5 @@ -0,0 +1,25 @@ + + @title;noquote@ + @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 13 Sep 2012 16:05:29 -0000 1.10 @@ -0,0 +1,25 @@ +# -*- 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.10 2012/09/13 16:05:29 victorg 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 13 Sep 2012 16:05:30 -0000 1.65 @@ -0,0 +1,93 @@ + + + @title;noquote@ + @context;noquote@ + @item_id@ + property_body + property_doc + + + + + + @header_stuff;noquote@ + + + + + + + + @header_stuff;noquote@ + + + + +
    + +
    +
    + +
    +
    +@top_includelets;noquote@ +

    @title@ (@page_context@)

    +

    @title@

    + @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 13 Sep 2012 16:05:30 -0000 1.44 @@ -0,0 +1,125 @@ + + + @title;noquote@ + @context;noquote@ + @item_id@ + property_body + property_doc + + + + + + + @header_stuff;noquote@ + + + + + + + + + @header_stuff;noquote@ + + + + +
    + +
    +
    + +
    +
    + +
    +@top_includelets;noquote@ +

    @title@ (@page_context@)

    +

    @title@

    + @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 13 Sep 2012 16:05:30 -0000 1.39 @@ -0,0 +1,133 @@ + + + @title;noquote@ + @context;noquote@ + @item_id@ + property_body + property_doc + + + + + + + + @header_stuff;noquote@ + + + + + + + + + + @header_stuff;noquote@ + + + + +
    + + +
    +
    +@top_includelets;noquote@ +

    @title@ (@page_context@)

    +

    @title@

    + @content;noquote@ +
    +
    + +
    +
    +
    + + + +
    + +
    +Contributors +
    +
    + +
    +
    + +
    +
    + + +@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 13 Sep 2012 16:05:30 -0000 1.3 @@ -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 13 Sep 2012 16:05:30 -0000 1.5 @@ -0,0 +1,8 @@ +# like portlet, except with background loading via ajax +# gustaf neumann, fecit may 2006 +::xo::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 [lindex [site_node::get_url_from_object_id -object_id $package_id] 0]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 13 Sep 2012 16:05:30 -0000 1.3 @@ -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 13 Sep 2012 16:05:30 -0000 1.4 @@ -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 13 Sep 2012 16:05:30 -0000 1.5 @@ -0,0 +1,16 @@ + +@title;noquote@ +property_doc +@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-no-ajax.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-book-no-ajax.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-book-no-ajax.adp 13 Sep 2012 16:05:30 -0000 1.21 @@ -0,0 +1,123 @@ + + + @title;noquote@ + @context;noquote@ + @item_id@ + property_body + property_doc + + + + @header_stuff;noquote@ + + + + + + @header_stuff;noquote@ + + + + +
    + +
    +
    +@toc;noquote@ +
    +
    + +
    + + + + + + + + + + +
    + + + Previous + + + + No Previous + + + + + + + +
    @book_relpos@
    +
    +
    + + + Next + + + + No Next + +
    +
    +
    + +
    + +
    +
    + +@footer;noquote@ +
    Index: openacs-4/packages/xowiki/www/view-book-no-ajax.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-book-no-ajax.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-book-no-ajax.tcl 13 Sep 2012 16:05:30 -0000 1.8 @@ -0,0 +1,22 @@ +set title [$package_id get_parameter PackageTitle [$package_id instance_name]] +#set toc [$page include [list toc -ajax 0 -open_page $name -decoration plain -remove_levels 0]] +set toc [$page include [list toc -style list -open_page $name -expand_all 1 -decoration plain]] +set i [$page set __last_includelet] +#$package_id log "--last includelet = $i, class=[$i info class] [$page exists __is_book_page]" + +# prevent recursive books +if {$i ne "" && ![$page exists __is_book_page]} { + set p [$i position] + set count [$i count] + + if {$count > 0} { + set book_relpos [format %.2f%% [expr {100.0 * $p / $count}]] + if {$p>1} {set book_prev_link [$package_id pretty_link -parent_id [$i parent_id] [$i page_name [expr {$p - 1}]]]} + if {$p<$count} {set book_next_link [$package_id pretty_link -parent_id [$i parent_id] [$i page_name [expr {$p + 1}]]]} + set page_title "

    [$i current] $title

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

    $title

    " + } +} +set header_stuff [::xo::Page header_stuff] 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 13 Sep 2012 16:05:30 -0000 1.32 @@ -0,0 +1,123 @@ + + + @title;noquote@ + @context;noquote@ + @item_id@ + property_body + property_doc + + + + @header_stuff;noquote@ + + + + + + @header_stuff;noquote@ + + + + +
    + +
    +
    +@toc;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 13 Sep 2012 16:05:30 -0000 1.13 @@ -0,0 +1,21 @@ +set title [$package_id get_parameter PackageTitle [$package_id instance_name]] +set toc [$page include [list toc -open_page $name -decoration plain -remove_levels 1]] +set i [$page set __last_includelet] +#$package_id log "--last includelet = $i, class=[$i info class] [$page exists __is_book_page]" + +# prevent recursive books +if {$i ne "" && ![$page exists __is_book_page]} { + set p [$i position] + set count [$i count] + + if {$count > 0} { + set book_relpos [format %.2f%% [expr {100.0 * $p / $count}]] + if {$p>1} {set book_prev_link [$package_id pretty_link -parent_id [$i parent_id] [$i page_name [expr {$p - 1}]]]} + if {$p<$count} {set book_next_link [$package_id pretty_link -parent_id [$i parent_id] [$i page_name [expr {$p + 1}]]]} + set page_title "

    [$i current] $title

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

    $title

    " + } +} +set header_stuff [::xo::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 13 Sep 2012 16:05:31 -0000 1.61 @@ -0,0 +1,75 @@ + + + @title;noquote@ + @context;noquote@ + @item_id@ + property_body + property_doc + + + @header_stuff;noquote@ + + + + + @header_stuff;noquote@ + + + + +
    + +@top_includelets;noquote@ +

    @title@ (@page_context@)

    +

    @title@

    + @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 13 Sep 2012 16:05:31 -0000 1.51 @@ -0,0 +1,25 @@ + + + +
    + +@top_includelets;noquote@ +

    @title@ (@page_context@)

    +

    @title@

    + @content;noquote@ + +
    Index: openacs-4/packages/xowiki/www/view-mobile.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/view-mobile.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/view-mobile.adp 13 Sep 2012 16:05:31 -0000 1.3 @@ -0,0 +1,9 @@ + + +@header_stuff;noquote@ + + +
    + @content;noquote@ +
    + \ No newline at end of file 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 13 Sep 2012 16:05:31 -0000 1.9 @@ -0,0 +1,25 @@ +
    + + +@top_includelets;noquote@ + +

    @page_title@

    +
    +@content;noquote@ +
    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 13 Sep 2012 16:05:31 -0000 1.3 @@ -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 13 Sep 2012 16:05:31 -0000 1.47 @@ -0,0 +1,11 @@ + + + +
    + +@top_includelets;noquote@ +

    @title@ (@page_context@)

    +

    @title@

    + @content;noquote@ + +
    Index: openacs-4/packages/xowiki/www/admin/bulk-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/admin/bulk-delete.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/admin/bulk-delete.tcl 13 Sep 2012 16:05:31 -0000 1.3 @@ -0,0 +1,18 @@ +::xowiki::Package initialize -ad_doc { + this file is called by the bulk action of admin/list + + @author Gustaf Neumann (gustaf.neumann@wu-wien.ac.at) + @creation-date Nov 11, 2007 + @cvs-id $Id: bulk-delete.tcl,v 1.3 2012/09/13 16:05:31 victorg Exp $ + + @param object_type +} -parameter { + {-objects ""} +} + +foreach o $objects { + ns_log notice "DELETE $o" + $package_id delete -name $o +} + +ad_returnredirect "./list" 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 13 Sep 2012 16:05:32 -0000 1.12 @@ -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.12 2012/09/13 16:05:32 victorg 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 + $package_id delete -item_id $item_id -name $name +} + +# 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 13 Sep 2012 16:05:32 -0000 1.19 @@ -0,0 +1,40 @@ +::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.19 2012/09/13 16:05:32 victorg Exp $ + + @param object_type +} -parameter { + {-object_type ::xowiki::Page} + {-objects ""} +} + +set folder_id [::$package_id folder_id] + +# +# In a first step, get the items_ids of the objects which are explicitly exported +# +if {$objects eq ""} { + set sql [$object_type instance_select_query -folder_id $folder_id -with_subtypes true] + db_foreach instance_select $sql { set items($item_id) 1 } +} else { + foreach o $objects { + $package_id get_lang_and_name -default_lang [::xo::cc lang] -path $o lang stripped_name + set parent_id [$package_id get_parent_and_name -lang $lang \ + -path $stripped_name -parent_id $folder_id \ + parent local_name] + #ns_log notice "lookup of $o in $folder_id returns [::xo::db::CrClass lookup -name $o -parent_id $parent_id]" + if {[set item_id [::xo::db::CrClass lookup -name $local_name -parent_id $parent_id]] != 0} { + set items($item_id) 1 + } + } +} + +# +# The exporter exports the specified objects together with implicitely +# needed objects. +# +::xowiki::::exporter export [array names items] + 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 13 Sep 2012 16:05:32 -0000 1.8 @@ -0,0 +1,11 @@ + + @title;noquote@ + @title;noquote@ + @context;noquote@ + + + + +@msg;noquote@ +
    back + 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 13 Sep 2012 16:05:32 -0000 1.22 @@ -0,0 +1,78 @@ +::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.22 2012/09/13 16:05:32 victorg Exp $ +} -parameter { + {create_user_ids 0} + {replace 0} +} + +set msg "" +ad_form \ + -name upload_form \ + -mode edit \ + -export {parent_id return_url} \ + -html { enctype multipart/form-data } \ + -form { + {upload_file:file(file) {html {size 30}} {label "[_ xowiki.import_upload_file]"}} + {create_user_ids:integer(radio),optional {options {{#acs-admin.Yes# 1} {#acs-admin.No# 0}}} {value 0} + {label "[_ xowiki.import_create_user_ids]"} + {help_text "[_ xowiki.import_create_user_ids_helptxt]"} + } + {replace:integer(radio),optional {options {{#acs-admin.Yes# 1} {#acs-admin.No# 0}}} {value 0} + {label "[_ xowiki.import_replace]"} + {help_text "[_ xowiki.import_replace_helptxt]"} + } + {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]; + # if we do not set translation binary, + # backslashes at the end of the lines might be lost + fconfigure $f -translation binary -encoding utf-8 + set content [read $f]; close $f + + foreach o [::xowiki::Page allinstances] { + set preexists($o) 1 + } + if {[catch {namespace eval ::xo::import $content} error]} { + #my msg "Error: $::errorInfo" + set msg "Error: $error\n$::errorInfo" + } else { + set objects [list] + foreach o [::xowiki::Page allinstances] { + if {![info exists preexists($o)]} {lappend objects $o} + } + ns_log notice "objects to import: $objects" + set parent_id [ns_queryget parent_id 0] + #::xotcl::Object msg parent_id=$parent_id + if {[catch { + set msg [$package_id import -replace $replace -create_user_ids $create_user_ids \ + -parent_id $parent_id -objects $objects] + } errMsg]} { + ns_log notice "Error during import: $errMsg\nErrInfo: $::errorInfo" + ::xotcl::Object msg "Error during import: $errMsg\nErrInfo: $::errorInfo" + foreach o $objects {$o destroy} + error $errMsg + } + foreach o $objects {if {[::xotcl::Object isobject $o]} {$o destroy}} + } + namespace delete ::xo::import + } + + +set return_url [ns_queryget return_url ../] +set title [_ xowiki.import_title] +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 13 Sep 2012 16:05:32 -0000 1.6 @@ -0,0 +1,8 @@ + + @title;noquote@ + @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 13 Sep 2012 16:05:32 -0000 1.10 @@ -0,0 +1,44 @@ + + @title;noquote@ + @title;noquote@ + @context;noquote@ + + + + + + + + +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 13 Sep 2012 16:05:32 -0000 1.28 @@ -0,0 +1,70 @@ +::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.28 2012/09/13 16:05:32 victorg Exp $ + +} -parameter { + {-object_type ::xowiki::Page} +} + +set context [list] +set pretty_plural [$object_type set pretty_plural] +set title #xowiki.admin_all_title# + +set object_types [$object_type object_types] +set return_url [ns_conn url] +set category_url [export_vars -base [$package_id package_url] { {manage-categories 1} {object_id $package_id}}] + +lang::message::lookup "" xowiki.admin " " +TableWidget t1 -volatile \ + -actions [subst { + Action new -label #xowiki.All_pages# -url list + Action new -label "[lang::message::lookup {} categories.Categories Categories]" \ + -url $category_url + Action new -label [_ acs-subsite.Parameters] -url \ + [export_vars -base /shared/parameters {package_id return_url}] + Action new -label [_ xowiki.export] -url export + Action new -label [_ xowiki.import] -url import + Action new -label [_ acs-subsite.Permissions] -url [export_vars -base permissions {package_id}] + }] \ + -columns { + Field object_type -label [_ xowiki.page_type] + AnchorField instances -label [_ xowiki.instances] -html {align center} + AnchorField edit -CSSclass add-item-button -label [_ xowiki.add] -html {align center} + AnchorField delete -CSSclass delete-item-button -label [_ xowiki.delete_all] \ + -html {align center onClick "return(confirm('#xowiki.delete_all_confirm#'));"} + } + +set base [::$package_id package_url] +foreach object_type $object_types { + set return_url [export_vars -base ${base}admin {object_type}] + set add_title "" + set add_href "" + set pretty_plural [$object_type pretty_plural] + 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 delete_title [_ xowiki.delete_all_items] + } else { + set add_title [_ xotcl-core.add [list type [$object_type pretty_name]]] + set add_href [$package_id make_link -with_entities 0 $package_id edit-new object_type return_url autoname] + set delete_title [_ xowiki.delete_all_instances] + } + t1 add \ + -object_type $object_type \ + -instances $n \ + -instances.href [export_vars -base ./list {object_type}] \ + -edit "" \ + -edit.href $add_href \ + -edit.title $add_title \ + -delete "" \ + -delete.href [export_vars -base delete-type {object_type}] \ + -delete.title $delete_title +} + +set t1 [t1 asHTML] + 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 13 Sep 2012 16:05:32 -0000 1.6 @@ -0,0 +1,43 @@ + + @title;noquote@ + @title;noquote@ + @context;noquote@ + + + + + + + + +
    +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 13 Sep 2012 16:05:32 -0000 1.34 @@ -0,0 +1,157 @@ +::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.34 2012/09/13 16:05:32 victorg 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 pretty_plural [$supertype set pretty_plural] + set page_title [_ xowiki.listing_title_all] + set with_subtypes true + set object_type $supertype + set with_children true +} else { + set per_type 1 + set object_types [list $object_type] + set pretty_plural [$object_type set pretty_plural] + set page_title [_ xowiki.listing_title] + set with_subtypes false + set with_children true +} + +set return_url [expr {$per_type ? [export_vars -base [::$package_id url] object_type] : + [::$package_id url]}] + +set category_url [export_vars -base [$package_id package_url] { {manage-categories 1} {object_id $package_id}}] + +set actions [subst { + Action new -label "[lang::message::lookup {} categories.Categories Categories]" \ + -url $category_url +}] +foreach type $object_types { + set link [$package_id make_link -with_entities 0 \ + $package_id edit-new {object_type $type} return_url autoname] + if {$link eq ""} continue + append actions [subst { + Action new \ + -label "[_ xotcl-core.add [list type [$type pretty_name]]]" \ + -url "$link" \ + -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 [_ xowiki.export] -tooltip [_ xowiki.export] -url export + Action new -label [_ xowiki.delete] -tooltip [_ xowiki.delete] -url bulk-delete + } + AnchorField edit -CSSclass edit-item-button -label "" -html {style "padding: 0px;"} + 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 -orderby publish_status.src -src "" \ + -width 8 -height 8 -border 0 -title "Toggle Publish Status" \ + -alt "publish status" -label [_ xowiki.publish_status] -html {style "padding: 2px;text-align: center;"} + } + Field syndicated -label "RSS" -html {style "padding: 2px; text-align: center;"} + AnchorField page_order -label [_ xowiki.Page-page_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 [_ xowiki.Size] -orderby size -html {align right style "padding: 2px;"} + Field last_modified -label [_ xowiki.Page-last_modified] -orderby last_modified + Field mod_user -label [_ xowiki.By_user] -orderby mod_user + AnchorField delete -CSSclass delete-item-button -label "" ;#-html {onClick "return(confirm('#xowiki.delete_confirm#'));"} + } + +foreach {att order} [split $orderby ,] break +t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] $att + +# -page_size 10 +# -page_number 1 + +# for content_length, we need cr_revision and cannot use the base table +set attributes [list revision_id content_length creation_user title page_order parent_id \ + "to_char(last_modified,'YYYY-MM-DD HH24:MI:SS') as last_modified" ] + +set folder_id [::$package_id folder_id] +foreach i [db_list get_syndicated { + select s.object_id from syndication s, cr_items ci + where s.object_id = ci.live_revision and ci.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 = bt.revision_id" \ + -with_children $with_children \ + -select_attributes $attributes \ + -orderby ci.name \ + ] { + set page_link [::$package_id pretty_link -parent_id $parent_id $name] + set name [::$package_id external_name -parent_id $parent_id $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 "" \ + -edit.href [export_vars -base $page_link {{m edit} return_url}] \ + -edit.title #xowiki.edit# \ + -mod_user [::xo::get_user_name $creation_user] \ + -delete "" \ + -delete.href [export_vars -base [$package_id package_url] {{delete 1} item_id name return_url}] \ + -delete.title #xowiki.delete# + 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}] + } + [t1 last_child] set page_order $page_order + } + +set t1 [t1 asHTML] +# db_foreach clobbers title, so re-establish it +set title $page_title 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 13 Sep 2012 16:05:33 -0000 1.6 @@ -0,0 +1,6 @@ + + @page_title@ + @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 13 Sep 2012 16:05:33 -0000 1.6 @@ -0,0 +1,29 @@ +::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.6 2012/09/13 16:05:33 victorg Exp $ + +} -parameter { + {-item_id:optional} +} + +if {[info exists item_id]} { + set page [::xo::db::CrClass get_instance_from_db -item_id $item_id] + $page volatile + set object_id $item_id + set page_name [$page name] + set page_title [_ xowiki.permissions_manage_page] + set return_url [$package_id query_parameter return_url [$package_id package_url]admin/list] +} else { + set object_id $package_id + set package_name [apm_instance_name_from_id $package_id] + set package_name [$package_id get_parameter PackageTitle $package_name] + set page_title [_ xowiki.permissions_manage_package] + 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 13 Sep 2012 16:05:33 -0000 1.14 @@ -0,0 +1,67 @@ +::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.14 2012/09/13 16:05:33 victorg Exp $ + + @param object_type show objects of this class and its subclasses +} -parameter { + {-portal_id:required} + {-page_name:required} + {-referer .} +} + +set page [$package_id get_page_from_item_ref $page_name] + +if {$page eq ""} { + # + # If a page with the given name does not exist, return an error. + # + ad_return_error \ + [_ xowiki.portlet_page_does_not_exist_error_short] \ + [_ xowiki.portlet_page_does_not_exist_error_long $page_name] + +} else { + # + # The page exists, get the title of the page... + # + set page_title [$page 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]} { + # + # The name of the portal element is not unique. + # + ad_return_error \ + [_ xowiki.portlet_title_exists_error_short] \ + [_ xowiki.portlet_title_exists_error_long $page_title] + } else { + # + # everything ok, add the portal element + # + db_transaction { + set element_id [portal::add_element \ + -portal_id $portal_id \ + -portlet_name [xowiki_portlet 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 + # in case, someone wants language-specific includelets + #regexp {^..:(.*)$} $page_name _ page_name + portal::set_element_param $element_id page_name $page_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 13 Sep 2012 16:05:33 -0000 1.3 @@ -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.3 2012/09/13 16:05:33 victorg 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 13 Sep 2012 16:05:33 -0000 1.9 @@ -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.9 2012/09/13 16:05:33 victorg 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 13 Sep 2012 16:05:33 -0000 1.34 @@ -0,0 +1,1436 @@ +# regression test for xowiki +# $Id: test.tcl,v 1.34 2012/09/13 16:05:33 victorg 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 subsubsection msg {ns_write "
    $msg
    "} +test proc errmsg msg {my code "ERROR: [string map [list < {<} > {>}] $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 { + #ns_log notice "queryget $key => [::xo::cc form_parameter $key {}]"; + ::xo::cc form_parameter $key "" + } + proc ::ns_querygetall key { + #ns_log notice "querygetall $key => [list [::xo::cc form_parameter $key {}]]" + list [::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 \n   '$r' ne \n   '$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.5}} 0 "XOTcl Version $::xotcl::version >= 1.5" + +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]} { + test hint "we have an existing instance named /$instance_name, we delete it..." + # 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) + # remove the package instance + apm_package_instance_delete $info(object_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 /] +#test code [array get node] + +site_node::instantiate_and_mount \ + -parent_node_id $node(node_id) \ + -node_name $instance_name \ + -package_name $instance_name \ + -package_key xowiki + +? {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] +#test code [array get info] + +? {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" +? {::$folder_id name} "xowiki: $package_id" "name of folder object is 'xowiki: $package_id'" +? {::$folder_id parent_id} -100 "parent_id of folder object is -100" +? {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"} 0 \ + "folder contains no objects" + +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"} 1 \ + "folder contains 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" +? {::$folder_id name} "xowiki: $package_id" "name of folder object is 'xowiki: $package_id'" +? {::$folder_id parent_id} -100 "parent_id of folder object is -100" +? {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 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" +#test hint $content + +? {db_string count "select count(*) from cr_items where parent_id = $folder_id"} 3 \ + "folder contains: index and weblog page (+1 includelet)" + +::xo::at_cleanup + + +######################################################################## +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" +? {string first file:image $content} -1 "page contains no error" +? {expr {[string first "Index Page" $content] == -1}} 0 \ + "weblog contains Index Page" + +set full_weblog_content_length $content_length + +::xo::at_cleanup + +######################################################################## +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 ($content_length) is shorter than full weblog $full_weblog_content_length" + +#test hint $content +::xo::at_cleanup +#return + +######################################################################## +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]"} 3 \ + "folder contains: index and weblog page (+1 includelet)" +::xo::at_cleanup + +######################################################################## +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]"} 2 \ + "folder contains: index and weblog page (+0 includelet)" + +test subsection "Create a test page named hello with package_id $package_id" + +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 +? {$page set package_id} $package_id "package_id $package_id not modified" +? {db_string count "select count(*) from cr_items where parent_id=[$package_id folder_id]"} 3 \ + "folder contains: index and weblog, hello page (+0 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]"} 3 \ + "still 3 pages" +? {expr {[$page revision_id]>$revision_id1}} 1 "revision_id > old revision_id" +? {expr {[$page item_id] == $item_id1}} 1 "item id the same" + +::xo::at_cleanup + + + +######################################################################## +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]"} 4 \ + "again, 4 pages" + +::xo::at_cleanup + +######################################################################## +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" + +::xo::at_cleanup + + +######################################################################## +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] + +? {set title} {Hello World- V.2} +? {set text} {Hello [[Wiki]] World.} + +::xo::at_cleanup + +######################################################################## +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 - saved}} + 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" + +::xo::at_cleanup + +######################################################################## +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] + +set p [::xowiki::Page info instances] +? {llength $p} 1 "expect only one page instance" + +if {[llength $p] == 1} { + ? {$p set title} {Hello World- V.2 - saved} "saved title is ok" + ? {lindex [$p set text] 0} {Hello [[Wiki]] World. ... just testing ..
    } "saved text is ok" +} else { + test code [::xowiki::Page info instances] + foreach p [::xowiki::Page info instances] {test code "$p [$p serialize]"} +} + +? {string first Error $content} -1 "page contains no error" +? {expr {[string first 3: $content]>-1}} 1 "page contains three revisions" + +# keep the page for the following test +#::xo::at_cleanup + +######################################################################## +test section "Small tests" + +test subsection "Link resolver" +set p [::xowiki::Page info instances] +? {llength $p} 1 "expect only one page instance" + +proc xowiki-test-links {p tests} { + foreach {link result external} $tests { + set l [$p create_link $link] + switch [$l info class] { + ::xowiki::Link { ? {expr {[$l resolve] > 0}} $result "Can resolve link $link" } + ::xowiki::ExternalLink { ? {expr {$external == 1}} $result "found external link" } + } + $l destroy + } +} +test subsubsection "Testing links on English page" +xowiki-test-links $p { + hello 1 0 + en:hello 1 0 + de:hello 0 0 + xxx 0 0 + //XOWIKI-TEST/hello 1 0 + //XOWIKI-TEST/en:hello 1 0 + //XOWIKI-TEST/de:hello 0 0 + //XOWIKI-TEST/en/hello 0 0 + //forums 1 1 + //XOWIKI-TEST/weblog?m=create-new&p.exercise_form=en:l1 1 0 + //XOWIKI-TEST/en:weblog?m=create-new&p.exercise_form=en:l1 1 0 +} + +# make page a german page +$p nls_language de_DE +test subsubsection "Testing links on German page" +xowiki-test-links $p { + hello 1 0 + en:hello 1 0 + de:hello 0 0 + xxx 0 0 + //XOWIKI-TEST/hello 1 0 + //XOWIKI-TEST/en:hello 1 0 + //XOWIKI-TEST/de:hello 0 0 + //XOWIKI-TEST/en/hello 0 0 + //forums 1 1 + //XOWIKI-TEST/weblog?m=create-new&p.exercise_form=en:l1 1 0 + //XOWIKI-TEST/en:weblog?m=create-new&p.exercise_form=en:l1 1 0 +} + + + +######################################################################## +test subsection "Filter expressions" + +? {::xowiki::FormPage filter_expression \ + "_state=created|accepted|approved|tested|developed|deployed&&_assignee=123" &&} \ + {tcl {[lsearch -exact {created accepted approved tested developed deployed} [my property _state]] > -1&&[my property _assignee] eq {123}} h {} vars {} sql {{state in ('created','accepted','approved','tested','developed','deployed')} {assignee = '123'}}} filter_expr_where_1 + +? {::xowiki::FormPage filter_expression \ + "_assignee<=123 && y>=123" &&} \ + {tcl {[my property _assignee] <= {123}&&$__ia(y) >= {123}} h {} vars {y {}} sql {{assignee <= '123'}}} \ + filter_expr_where_2 + +? {::xowiki::FormPage filter_expression \ + "betreuer contains en:person1" &&} \ + {tcl {[lsearch $__ia(betreuer) {en:person1}] > -1} h {} vars {betreuer {}} sql {{instance_attributes like '%en:person1%'}}} \ + filter_expr_where_3 + +? {::xowiki::FormPage filter_expression \ + "_state=closed" ||} \ + {tcl {[my property _state] eq {closed}} h {} vars {} sql {{state = 'closed'}}} \ + filter_expr_unless_1 + +? {::xowiki::FormPage filter_expression \ + "_state= closed|accepted || x = 1" ||} \ + {tcl {[lsearch -exact {closed accepted} [my property _state]] > -1||$__ia(x) eq {1}} h x=>1 vars {x {}} sql {{state in ('closed','accepted')}}} \ + filter_expr_unless_1 + + + +######################################################################## +test section "Item refs" +# +# Testing item refs and wiki links (between [[ .... ]]) +# +# Still missing: +# - test reverse mappings from urls generated from item-refs back to item_ids +# - syntax Person:de:p1 (if de:p1 does not exist, create an instance of Person name de:p1) +# - typed links (glossary app)... important? +# - interaction between PackagePath and folders (would be nice to inherit from folders, not packages) +# +# Save this file in openacs-4/www/item-ref-test.tcl and run it via +# http://..../item-ref-test +# +# + + # "require_folder" and "require_page" are here just for testing + proc require_folder {name parent_id package_id} { + set item_id [::xo::db::CrClass lookup -name $name -parent_id $parent_id] + + if {$item_id == 0} { + set form_id [::xowiki::Weblog instantiate_forms -forms en:folder.form -package_id $package_id] + set f [$form_id create_form_page_instance \ + -name $name \ + -nls_language en_US \ + -default_variables [list title "Folder $name" parent_id $parent_id package_id $package_id]] + $f save_new + set item_id [$f item_id] + } + test hint " $name => $item_id\n" + return $item_id + } + + proc require_link {name parent_id package_id target_id} { + set item_id [::xo::db::CrClass lookup -name $name -parent_id $parent_id] + + if {$item_id == 0} { + set form_id [::xowiki::Weblog instantiate_forms -forms en:link.form -package_id $package_id] + set target [::xo::db::CrClass get_instance_from_db -item_id $target_id] + set item_ref [[$target package_id] external_name -parent_id [$target parent_id] [$target name]] + + set f [$form_id create_form_page_instance \ + -name $name \ + -nls_language en_US \ + -instance_attributes [list link $item_ref] \ + -default_variables [list title "Link $name" parent_id $parent_id package_id $package_id]] + $f save_new + set item_id [$f item_id] + } + test hint " $name => $item_id\n" + return $item_id + } + + proc require_page {name parent_id package_id {file_content ""}} { + set item_id [::xo::db::CrClass lookup -name $name -parent_id $parent_id] + if {$item_id == 0} { + if {$file_content eq ""} { + set f [::xowiki::Page new -name $name -description "" \ + -parent_id $parent_id -package_id $package_id -text [list "Content of $name" text/html]] + } else { + set mime_type [::xowiki::guesstype $name] + set f [::xowiki::File new -name $name -description "" \ + -parent_id $parent_id -package_id $package_id -mime_type $mime_type] + set import_file [ns_tmpnam] + ::xowiki::write_file $import_file [::base64::decode $file_content] + $f set import_file $import_file + } + $f save_new + set item_id [$f item_id] + $f destroy_on_cleanup + } + ns_log notice "Page $name => $item_id" + test hint " $name => $item_id\n" + return $item_id + } + proc label {intro case ref} {return "$intro '$ref' -- $case"} + + #some test cases + ::xowiki::Package initialize -url /$instance_name/ + ::xowiki::Page create p -package_id $package_id -nls_language de_DE -parent_id [$package_id folder_id] + p set unresolved_references 0 + + test subsection "Ingredients:" + set folder_id [$package_id folder_id] + test hint "folder_id => $folder_id" + + set folder_id [$package_id folder_id] + + # make sure, we have folder "f1" with subfolder "f3" with subfolder "subf3" + set f1_id [require_folder "f1" $folder_id $package_id] + set f3_id [require_folder "f3" $f1_id $package_id] + set subf3_id [require_folder "subf3" $f3_id $package_id] + + # make sure, we have the test pages + set parentpage_id [require_page de:parentpage $folder_id $package_id] + set enpage_id [require_page en:page $folder_id $package_id] + set testpage_id [require_page de:testpage $f1_id $package_id] + set f3page_id [require_page en:page $f3_id $package_id] + + set childfolder_id [require_folder "childfolder" $parentpage_id $package_id] + set childpage_id [require_page "de:childpage" $parentpage_id $package_id] + + set base64 "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAAxJREFUCNdj\n+P//PwAF/gL+3MxZ5wAAAABJRU5ErkJggg==" + set image_id [require_page file:image.png $folder_id $package_id $base64] + set subimage_id [require_page file:image2.png $f1_id $package_id $base64] + set childimage_id [require_page file:image3.png $parentpage_id $package_id $base64] + + set pagelink_id [require_link link1 $folder_id $package_id $parentpage_id] + set folderlink_id [require_link link2 $folder_id $package_id $f1_id] + set subpagelink_id [require_link link3 $folder_id $package_id $testpage_id] + set subfolderlink_id [require_link link4 $folder_id $package_id $f3_id] + set subimagelink_id [require_link link5 $folder_id $package_id $subimage_id] + ################################ + + + test subsection "Toplevel Tests:" + + set l "folder:f1" + set test [label "item_ref" "existing topfolder" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(form) eq "en:folder.form" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "de:parentpage" + set test [label "item_ref" "existing page in root_folder" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "parentpage" + && $(parent_id) eq $folder_id && $(item_id) == $parentpage_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/" + set test [label "item_ref" "existing topfolder short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1";# this works, since "f1" exists + set test [label "item_ref" "existing topfolder short + lookup" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "page1";# last item per default page + set test [label "item_ref" "not existing page short" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "page1" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "parentpage" + set test [label "item_ref" "existing page short (without language prefix)" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "parentpage" + && $(parent_id) eq $folder_id && $(item_id) == $parentpage_id}} 1 "\n$test:\n [array get {}]\n " + + set l "image:img1" + set test [label "item_ref" "not existing image" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "image" && $(prefix) eq "file" && $(stripped_name) eq "img1" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "image:image.png" + set test [label "item_ref" "existing image" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "image" && $(prefix) eq "file" && $(stripped_name) eq "image.png" + && $(parent_id) eq $folder_id && $(item_id) == $image_id}} 1 "\n$test:\n [array get {}]\n " + + set l "file:file1" + set test [label "item_ref" "not existing file" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "file" && $(prefix) eq "file" && $(stripped_name) eq "file1" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "file:image.png" + set test [label "item_ref" "existing file" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "file" && $(prefix) eq "file" && $(stripped_name) eq "image.png" + && $(parent_id) eq $folder_id && $(item_id) == $image_id}} 1 "\n$test:\n [array get {}]\n " + + set l "image.png" + set test [label "item_ref" "existing image short" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "image" && $(prefix) eq "file" && $(stripped_name) eq "image.png" + && $(parent_id) eq $folder_id && $(item_id) == $image_id}} 1 "\n$test:\n [array get {}]\n " + + set l "image1.png" + set test [label "item_ref" "not existing image short" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "image" && $(prefix) eq "file" && $(stripped_name) eq "image1.png" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "flashfile.swf" + set test [label "item_ref" "not existing flash file short" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "swf" && $(prefix) eq "file" && $(stripped_name) eq "flashfile.swf" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + ################################ + test subsection "Absolute to toplevel:" + + set l "/f1" + set test [label "item_ref" "absolute existing topfolder short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "/f1/" + set test [label "item_ref" "absolute existing topfolder short slash" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "/" ;# stripped name will be the name of the root folder + set test [label "item_ref" "just slash" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" + && $(parent_id) == -100 && $(item_id) == $folder_id}} 1 "\n$test:\n [array get {}]\n " + + + ################################ + test subsection "Relative to current folder:" + + set l "./parentpage" + set test [label "item_ref" "existing page short (without prefixuage prefix), relative" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "parentpage" + && $(parent_id) eq $folder_id && $(item_id) == $parentpage_id}} 1 "\n$test:\n [array get {}]\n " + + set l "./de:parentpage" + set test [label "item_ref" "existing page in root_folder, relative" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "parentpage" + && $(parent_id) eq $folder_id && $(item_id) == $parentpage_id}} 1 "\n$test:\n [array get {}]\n " + + set l "./f1/" + set test [label "item_ref" "existing topfolder short, relative" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "./f1";# this works, since "f1" exists + set test [label "item_ref" "existing topfolder short + lookup, relative" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "./page1";# last item per default page + set test [label "item_ref" "not existing page short, relative" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "page1" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "./parentpage/" + set test [label "item_ref" "not existing folder (with same name of existing page) in root_folder, relative" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "parentpage" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "./" ;# stripped name will be the name of the root folder + set test [label "item_ref" "dot with slash, relative" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" + && $(parent_id) == -100 && $(item_id) == $folder_id}} 1 "\n$test:\n [array get {}]\n " + + ################################ + test subsection "Ending with dot:" + + set l "." ;# stripped name will be the name of the root folder, omit from test + set test [label "item_ref" "dot with slash, relative" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" + && $(parent_id) eq -100 && $(item_id) == $folder_id}} 1 "\n$test:\n [array get {}]\n " + + set l "./f1/." + set test [label "item_ref" "existing topfolder short, relative" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "./parentpage/." + set test [label "item_ref" "existing page short (without language prefix), relative" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "parentpage" + && $(parent_id) eq $folder_id && $(item_id) == $parentpage_id}} 1 "\n$test:\n [array get {}]\n " + + ################################ + test subsection "Under folder:" + + set l "folder:f1/folder:f3" + set test [label "item_ref" "existing subfolder" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f3" + && $(parent_id) eq $f1_id && $(item_id) == $f3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "folder:f1/f3/" + set test [label "item_ref" "existing subfolder short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f3" + && $(parent_id) eq $f1_id && $(item_id) == $f3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "./folder:f1/folder:f3/" + set test [label "item_ref" "existing subfolder with prefix and trailing slash" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f3" + && $(parent_id) eq $f1_id && $(item_id) == $f3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/f3/" + set test [label "item_ref" "existing subfolder short short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f3" + && $(parent_id) eq $f1_id && $(item_id) == $f3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "folder:f11/folder:f3" + set test [label "item_ref" "not existing folder with subfolder" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f11" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "f11/folder/" + set test [label "item_ref" "not existing folder with subfolder short short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f11" + && $(parent_id) eq $folder_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/folder1/" + set test [label "item_ref" "existing folder with not existing subfolder short short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "folder1" + && $(parent_id) eq $f1_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/page1" + set test [label "item_ref" "existing folder with not existing page short short" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "page1" + && $(parent_id) eq $f1_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "folder:f1/folder:f3/folder:subf3" + set test [label "item_ref" "existing subsubfolder" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "subf3" + && $(parent_id) eq $f3_id && $(item_id) == $subf3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/f3/subf3" + set test [label "item_ref" "existing subsubfolder short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "subf3" + && $(parent_id) eq $f3_id && $(item_id) == $subf3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/f3/subf3/." + set test [label "item_ref" "existing subsubfolder short" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" && $(stripped_name) eq "subf3" + && $(parent_id) eq $f3_id && $(item_id) == $subf3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "folder:f1/folder:f99" + set test [label "item_ref" "not existing folder in folder" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "f99" + && $(parent_id) eq $f1_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "folder:f1/de:testpage" + set test [label "item_ref" "existing page in folder" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "testpage" + && $(parent_id) eq $f1_id && $(item_id) == $testpage_id}} 1 "\n$test:\n [array get {}]\n " + + set l "folder:f1/de:entry" + set test [label "item_ref" "not existing page in folder" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "entry" + && $(parent_id) eq $f1_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/image:image.png" + set test [label "item_ref" "not existing image" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "image" && $(prefix) eq "file" && $(stripped_name) eq "image.png" + && $(parent_id) eq $f1_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/image.png" + set test [label "item_ref" "not existing image short" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "image" && $(prefix) eq "file" && $(stripped_name) eq "image.png" + && $(parent_id) eq $f1_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + ################################ + test subsection "Under page:" + + set l "de:parentpage/folder:childfolder" + set test [label "item_ref" "existing folder under page" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "childfolder" + && $(parent_id) eq $parentpage_id && $(item_id) == $childfolder_id}} 1 "\n$test:\n [array get {}]\n " + + set l "de:parentpage/folder:childfolder/" + set test [label "item_ref" "existing folder under page with prefix and trailing slash" $l] + array set "" [p item_ref -default_lang en -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "childfolder" + && $(parent_id) eq $parentpage_id && $(item_id) == $childfolder_id}} 1 "\n$test:\n [array get {}]\n " + + set l "de:parentpage/folder:childfolder1" + set test [label "item_ref" "not existing folder under page" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "childfolder1" + && $(parent_id) eq $parentpage_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "de:parentpage/folder:childfolder1/" + set test [label "item_ref" "not existing folder under page with prefix and trailing slash" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "" && $(stripped_name) eq "childfolder1" + && $(parent_id) eq $parentpage_id && $(item_id) == 0}} 1 "\n$test:\n [array get {}]\n " + + set l "de:parentpage/de:childpage" + set test [label "item_ref" "existing page under page" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "childpage" + && $(parent_id) eq $parentpage_id && $(item_id) == $childpage_id}} 1 "\n$test:\n [array get {}]\n " + + set l "parentpage/childpage" + set test [label "item_ref" "existing page under page short" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "childpage" + && $(parent_id) eq $parentpage_id && $(item_id) == $childpage_id}} 1 "\n$test:\n [array get {}]\n " + + ################################ + test subsection "Ending with /.." + + set l ".." + set test [label "item_ref" "dot dot (don't traverse beyond root folder)" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" + && $(parent_id) == -100 && $(item_id) == $folder_id}} 1 "\n$test:\n [array get {}]\n " + + set l ".." + set test [label "item_ref" "dot dot slash dot dot (don't traverse beyond root folder)" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" + && $(parent_id) == -100 && $(item_id) == $folder_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/f3/subf3/.." + set test [label "item_ref" "existing subsubfolder dot dot" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" && $(stripped_name) eq "f3" + && $(parent_id) eq $f1_id && $(item_id) == $f3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/f3/subf3/../" + set test [label "item_ref" "existing subsubfolder dot dot slash" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" && $(stripped_name) eq "f3" + && $(parent_id) eq $f1_id && $(item_id) == $f3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/f3/subf3/../." + set test [label "item_ref" "existing subsubfolder dot dot slash dot" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" && $(stripped_name) eq "f3" + && $(parent_id) eq $f1_id && $(item_id) == $f3_id}} 1 "\n$test:\n [array get {}]\n " + + set l "f1/f3/subf3/../.." + set test [label "item_ref" "existing subsubfolder dot dot slash dot dot" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "folder" && $(prefix) eq "" && $(stripped_name) eq "f1" + && $(parent_id) eq $folder_id && $(item_id) == $f1_id}} 1 "\n$test:\n [array get {}]\n " + + set l "parentpage/childpage/.." + set test [label "item_ref" "existing page und page dot dot" $l] + array set "" [p item_ref -default_lang de -parent_id $folder_id $l] + ? {expr {$(link_type) eq "link" && $(prefix) eq "de" && $(stripped_name) eq "parentpage" + && $(parent_id) eq $folder_id && $(item_id) == $parentpage_id}} 1 "\n$test:\n [array get {}]\n " + + + test subsection "Links:" + + set l "parentpage" + set test [label "link" "existing simple page" $l] + set link [p create_link $l] + ? {$link render} "parentpage" "\n$test\n " + + set l "parentpage1" + set test [label "link" "not existing simple page" $l] + set link [p create_link $l] +? {$link render} [subst -nocommands { parentpage1}] "\n$test\n " + + set l "parentpage#a" + set test [label "link" "existing simple with anchor" $l] + set link [p create_link $l] +? {$link render} [subst -nocommands {parentpage}] "\n$test\n " + + set l "image:image.png" + set test [label "link" "existing image" $l] + set link [p create_link $l] +? {$link render} [subst -nocommands {image:image.png}] "\n$test\n " + + set l "image.png" + set test [label "link" "existing image short" $l] + set link [p create_link $l] +? {$link render} [subst -nocommands {image.png}] "\n$test\n " + + set l ":de:parentpage" + set test [label "link" "existing language link" $l] + p array unset lang_links + set link [p create_link $l] + ? {$link render} {} "\n$test\n " +? {p array get lang_links} [subst -nocommands {found {{de}}}] "\n$test links\n " + + p destroy +############################################ + + test section "page properties" + + set f1 [::xo::db::CrClass get_instance_from_db -item_id $f1_id] + set f2 [::xo::db::CrClass get_instance_from_db -item_id $f3_id] + set f3 [::xo::db::CrClass get_instance_from_db -item_id $subf3_id] + + set p1 [::xo::db::CrClass get_instance_from_db -item_id $parentpage_id] + set p2 [::xo::db::CrClass get_instance_from_db -item_id $testpage_id] + set p3 [::xo::db::CrClass get_instance_from_db -item_id $childpage_id] + set p4 [::xo::db::CrClass get_instance_from_db -item_id $enpage_id] + set p5 [::xo::db::CrClass get_instance_from_db -item_id $f3page_id] + + set i1 [::xo::db::CrClass get_instance_from_db -item_id $image_id] + set i2 [::xo::db::CrClass get_instance_from_db -item_id $subimage_id] + set i3 [::xo::db::CrClass get_instance_from_db -item_id $childimage_id] + + set l1 [::xo::db::CrClass get_instance_from_db -item_id $pagelink_id] + set l2 [::xo::db::CrClass get_instance_from_db -item_id $folderlink_id] + set l3 [::xo::db::CrClass get_instance_from_db -item_id $subpagelink_id] + set l4 [::xo::db::CrClass get_instance_from_db -item_id $subfolderlink_id] + set l5 [::xo::db::CrClass get_instance_from_db -item_id $subimagelink_id] + + ? {$f1 is_folder_page} 1 + ? {$f2 is_folder_page} 1 + ? {$f3 is_folder_page} 1 + + ? {$p1 is_folder_page} 0 + + ? {$l1 is_folder_page} 0 + ? {$l2 is_folder_page} 1 + ? {$l3 is_folder_page} 0 + ? {$l4 is_folder_page} 1 + ? {$l5 is_folder_page} 0 + + + + test section "pretty links" + + ? {$f1 pretty_link} "/XOWIKI-TEST/f1" + ? {$f2 pretty_link} "/XOWIKI-TEST/f1/f3" + ? {$f3 pretty_link} "/XOWIKI-TEST/f1/f3/subf3" + + ? {$p1 pretty_link} "/XOWIKI-TEST/de/parentpage" + ? {$p2 pretty_link} "/XOWIKI-TEST/de/f1/testpage" + ? {$p3 pretty_link} "/XOWIKI-TEST/de/de:parentpage/childpage" + ? {$p4 pretty_link} "/XOWIKI-TEST/page" + ? {$p5 pretty_link} "/XOWIKI-TEST/f1/f3/page" + + ? {$i1 pretty_link} "/XOWIKI-TEST/file/image.png" + ? {$i2 pretty_link} "/XOWIKI-TEST/file/f1/image2.png" + ? {$i3 pretty_link} "/XOWIKI-TEST/file/de:parentpage/image3.png" + + ? {$l1 pretty_link} "/XOWIKI-TEST/link1" + ? {$l2 pretty_link} "/XOWIKI-TEST/link2" + ? {$l3 pretty_link} "/XOWIKI-TEST/link3" + ? {$l4 pretty_link} "/XOWIKI-TEST/link4" + ? {$l5 pretty_link} "/XOWIKI-TEST/link5" + ? {$l5 pretty_link -download true} "/XOWIKI-TEST/download/file/link5" + + test section "item info from pretty links" + + set l [$f1 pretty_link] + set test [label "url" "topfolder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $f1_id && $(stripped_name) eq "f1"}} 1 "\n$test:\n [array get {}]\n " + + set l [$f2 pretty_link] + set test [label "url" "folder under topfolder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $f3_id && $(stripped_name) eq "f3"}} 1 "\n$test:\n [array get {}]\n " + + set l [$f3 pretty_link] + set test [label "url" "subsubfolder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $subf3_id && $(stripped_name) eq "subf3"}} 1 "\n$test:\n [array get {}]\n " + + set l [$p1 pretty_link] + set test [label "url" "toppage" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $parentpage_id && $(stripped_name) eq "parentpage"}} 1 "\n$test:\n [array get {}]\n " + + set l [$p2 pretty_link] + set test [label "url" "page in folder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $testpage_id && $(stripped_name) eq "testpage"}} 1 "\n$test:\n [array get {}]\n " + + set l [$p3 pretty_link] + set test [label "url" "page under page" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $childpage_id && $(stripped_name) eq "childpage"}} 1 "\n$test:\n [array get {}]\n " + + set l [$p4 pretty_link] + set test [label "url" "toplevel en page" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $enpage_id && $(stripped_name) eq "page" + && $(name) eq "en:page"}} 1 "\n$test:\n [array get {}]\n " + + set l [$p5 pretty_link] + set test [label "url" "en page under subfolder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $f3page_id && $(stripped_name) eq "page" + && $(name) eq "en:page"}} 1 "\n$test:\n [array get {}]\n " + + # image links + + set l [$i1 pretty_link] + set test [label "url" "toplevel image" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $image_id && $(stripped_name) eq "image.png" + && $(name) eq "file:image.png"}} 1 "\n$test:\n [array get {}]\n " + + set l [$i2 pretty_link] + set test [label "url" "toplevel image" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $subimage_id && $(stripped_name) eq "image2.png" + && $(name) eq "file:image2.png"}} 1 "\n$test:\n [array get {}]\n " + + set l [$i3 pretty_link] + set test [label "url" "toplevel image" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $childimage_id && $(stripped_name) eq "image3.png" + && $(name) eq "file:image3.png" && $(method) eq ""}} 1 "\n$test:\n [array get {}]\n " + + + # links + + set l [$l1 pretty_link] + set test [label "url" "toplevel link to page" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $pagelink_id && $(stripped_name) eq "link1" + && $(name) eq "link1" && $(method) eq ""}} 1 "\n$test:\n [array get {}]\n " + + set l [$l2 pretty_link] + set test [label "url" "toplevel link to folder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $folderlink_id && $(stripped_name) eq "link2" + && $(name) eq "link2" && $(method) eq ""}} 1 "\n$test:\n [array get {}]\n " + + set l [$l3 pretty_link] + set test [label "url" "toplevel link to page under folder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $subpagelink_id && $(stripped_name) eq "link3" + && $(name) eq "link3" && $(method) eq ""}} 1 "\n$test:\n [array get {}]\n " + + set l [$l4 pretty_link] + set test [label "url" "toplevel link to folder under folder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $subfolderlink_id && $(stripped_name) eq "link4" + && $(name) eq "link4" && $(method) eq ""}} 1 "\n$test:\n [array get {}]\n " + + set l [$l5 pretty_link] + set test [label "url" "toplevel link to image under folder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $subimagelink_id && $(stripped_name) eq "link5" + && $(name) eq "link5" && $(method) eq ""}} 1 "\n$test:\n [array get {}]\n " + + + test section "item info from variations of pretty links" + + # download + set l /XOWIKI-TEST/download/file/image.png + set test [label "url" "toplevel image download" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $image_id && $(stripped_name) eq "image.png" + && $(name) eq "file:image.png" && $(method) eq "download"}} 1 "\n$test:\n [array get {}]\n " + + # download via link + set l /XOWIKI-TEST/download/file/link5 + set test [label "url" "toplevel image download" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $subimagelink_id && $(stripped_name) eq "link5" + && $(name) eq "link5" && $(method) eq "download"}} 1 "\n$test:\n [array get {}]\n " + + # tag link + set l /XOWIKI-TEST/tag/a + set test [label "url" "tag query" $l] + array set "" [$package_id item_info_from_url -default_lang de $l] + ? {expr {$(item_id) != 0 && $(stripped_name) eq "weblog" + && $(name) eq "en:weblog" && $(method) eq ""}} 1 "\n$test:\n [array get {}]\n" + # missing: tag links to subdirectories + + # url without default lang + set l /XOWIKI-TEST/parentpage + set test [label "url" "toppage w/o de" $l] + array set "" [$package_id item_info_from_url -default_lang de $l] + ? {expr {$(item_id) == $parentpage_id && $(stripped_name) eq "parentpage"}} 1 "\n$test:\n [array get {}]\n " + + # prefixed name + set l /XOWIKI-TEST/de:parentpage + set test [label "url" "toppage prefixed eq default_lang" $l] + array set "" [$package_id item_info_from_url -default_lang de $l] + ? {expr {$(item_id) == $parentpage_id && $(stripped_name) eq "parentpage"}} 1 "\n$test:\n [array get {}]\n " + + set l /XOWIKI-TEST/de:parentpage + set test [label "url" "toppage prefixed ne default_lang" $l] + array set "" [$package_id item_info_from_url -default_lang en $l] + ? {expr {$(item_id) == $parentpage_id && $(stripped_name) eq "parentpage"}} 1 "\n$test:\n [array get {}]\n " + + + test section "item info via links to folders" + # reference pages over links to folders + + set l /XOWIKI-TEST/link2/testpage + set test [label "url" "reference page over links to folder default-lang" $l] + array set "" [$package_id item_info_from_url -default_lang de $l] + ? {expr {$(item_id) == $testpage_id && $(stripped_name) eq "testpage" + && $(name) eq "de:testpage"}} 1 "\n$test:\n [array get {}]\n " + + set l /XOWIKI-TEST/link2/de:testpage + set test [label "url" "reference page over links to folder direct name" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $testpage_id && $(stripped_name) eq "testpage" + && $(name) eq "de:testpage"}} 1 "\n$test:\n [array get {}]\n " + + set l /XOWIKI-TEST/download/file/link2/image2.png + set test [label "url" "reference download image over links to folder" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $subimage_id && $(stripped_name) eq "image2.png" + && $(name) eq "file:image2.png"}} 1 "\n$test:\n [array get {}]\n " + + set l /XOWIKI-TEST/link2/f3/page + set test [label "url" "path contains link and references finally page" $l] + array set "" [$package_id item_info_from_url $l] + ? {expr {$(item_id) == $f3page_id && $(stripped_name) eq "page" + && $(name) eq "en:page"}} 1 "\n$test:\n [array get {}]\n " + + + #test section "inherited pages" + + # link to site-wide page + + #set l /XOWIKI-TEST/en/folder.form + #set test [label "url" "site-wide-page top" $l] + #array set "" [$package_id item_info_from_url -default_lang de $l] + #? {expr {$(item_id) == $parentpage_id && $(stripped_name) eq "parentpage"}} 1 "\n$test:\n [array get {}]\n " + + # link to page in other package + # link to dir in other package + + +test section "Form Fields" + +# Create dummy object with a minimal setup to be used like a page +set o [::xotcl::Object new -destroy_on_cleanup] +$o mixin ::xowiki::Page +$o name dummy +$o nls_language en_US +$o package_id $info(package_id) + +set f0 [$o create_raw_form_field -name test -slot ::xowiki::Page::slot::name] +? {$f0 asWidgetSpec} \ + {text,optional {label {#xowiki.Page-name#}} {html {maxlength 400 id F.dummy.test size 80 }} {help_text {Shortname to identify an entry within a folder, typically lowercase characters}}} \ + "name with help_text" + +set f0 [$o create_raw_form_field -name test \ + -slot ::xowiki::Page::slot::name -spec inform] +? {$f0 asWidgetSpec} \ + {text(inform),optional {label {#xowiki.Page-name#}} {html {id F.dummy.test }} {help_text {Shortname to identify an entry within a folder, typically lowercase characters}}} \ + "name with help_text + inform" + +set f0 [$o create_raw_form_field -name test \ + -slot ::xowiki::Page::slot::name -spec optional] +? {$f0 asWidgetSpec} \ + {text,optional {label {#xowiki.Page-name#}} {html {maxlength 400 id F.dummy.test size 80 }} {help_text {Shortname to identify an entry within a folder, typically lowercase characters}}} \ + "name with help_text + optional" + +set f1 [$o create_raw_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 id F.dummy.test rows 2 }} } \ + "textarea,cols=80,rows=2" + + set f2 [$o create_raw_form_field -name test \ + -slot ::xowiki::Page::slot::nls_language \ + -spec {select,options={{de_DE de_DE} {en_US en_US} {pt_BR pt_BR} {es_ES es_ES}}}] +? {$f2 asWidgetSpec} \ + {text(select),optional {label {#xowiki.Page-nls_language#}} {html {id F.dummy.test }} {options {{{de_DE de_DE} {en_US en_US} {pt_BR pt_BR} {es_ES es_ES}}}} } \ + {select,options=[xowiki::locales]} + +$o mixin ::xowiki::PodcastItem +set f3 [$o create_raw_form_field -name test \ + -slot ::xowiki::PodcastItem::slot::pub_date] +? {$f3 asWidgetSpec} \ + {date,optional {label {#xowiki.PodcastItem-pub_date#}} {html {id F.dummy.test }} {format {YYYY MM DD HH24 MI}} } \ + {date with format} + + + +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 13 Sep 2012 16:05:33 -0000 1.6 @@ -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 13 Sep 2012 16:05:33 -0000 1.6 @@ -0,0 +1,78 @@ +// simple javascript support for polling ajax based chat interface +// $Id: chat.js,v 1.6 2012/09/13 16:05:33 victorg 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 13 Sep 2012 16:05:34 -0000 1.7 @@ -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.7 2012/09/13 16:05:34 victorg Exp $ +} -query { + m + id + s + msg:optional + {mode ""} +} + +#ns_log notice "--chat 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 " + + + +$_
    + +" 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 13 Sep 2012 16:05:34 -0000 1.3 @@ -0,0 +1,73 @@ +// simple javascript support for streaming ajax based chat interface +// $Id: scripted-streaming-chat.js,v 1.3 2012/09/13 16:05:34 victorg 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;i + + + + + + +#xowiki.attached_images#: +
    +
    +
    +
    + +
    +
    +
    + +
    + +
    +
    + + + + +
    +
    +
    + + + + + + + + + + + + + +
    URL: + + + + +
    Alternativtext: + +
    +
    + + + \ No newline at end of file Index: openacs-4/packages/xowiki/www/ckeditor-images/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/index.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/index.tcl 13 Sep 2012 16:05:34 -0000 1.4 @@ -0,0 +1,13 @@ +ad_page_contract { + +} { + parent_id:notnull,integer + {bild_url ""} +} +set package_url [ad_conn package_url] +set image_browser_url $package_url/ckeditor-images +set fs_package_id $parent_id +set CKEditorFuncNum 0 +set item_id $fs_package_id +#::xo::db::CrClass get_instance_from_db -item_id $fs_package_id + Index: openacs-4/packages/xowiki/www/ckeditor-images/preview.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/preview.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/preview.adp 13 Sep 2012 16:05:34 -0000 1.3 @@ -0,0 +1,7 @@ + +
    + In neuem Fenster öffnen (fullsize) +
    +
    +
    +
    Index: openacs-4/packages/xowiki/www/ckeditor-images/preview.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/preview.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/preview.tcl 13 Sep 2012 16:05:34 -0000 1.3 @@ -0,0 +1,7 @@ +ad_page_contract { + +} { + revision:notnull,integer +} + + Index: openacs-4/packages/xowiki/www/ckeditor-images/thumb-view.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/thumb-view.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/thumb-view.adp 13 Sep 2012 16:05:34 -0000 1.4 @@ -0,0 +1,25 @@ + + + + + + + +
    +
    + + + + +
    @sub_files.date@
    Löschen +
    +
    +
    +
    + + \ No newline at end of file Index: openacs-4/packages/xowiki/www/ckeditor-images/thumb-view.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/thumb-view.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/thumb-view.tcl 13 Sep 2012 16:05:34 -0000 1.4 @@ -0,0 +1,27 @@ +ad_page_contract { + +} { + {parent_id ""} +} -validate { + parent_id_exists -requires {parent_id} { + if {[db_0or1row object_exists "select item_id from cr_items where item_id =:parent_id"] == 0} { + #ad_complain "Das angegebene Objekt existiert nicht." + } + } +} + +set output "" +set return_url [ns_urlencode "[ad_conn url]?parent_id=$parent_id"] +db_multirow -extend url sub_files get_children " +select package_id,name,cr.item_id ,revision_id,mime_type, to_char(publish_date, 'yyyy-mm-dd, HH:MM') as date +from cr_items ci inner join cr_revisions cr on (ci.item_id = cr.item_id) +join acs_objects o on o.object_id=cr.item_id + where parent_id = :parent_id and revision_id = ci.live_revision + AND cr.mime_type LIKE 'image/%' + ORDER BY publish_date DESC" { + ::xowiki::Package initialize -package_id $package_id + set item [::xowiki::File get_instance_from_db -item_id $item_id] + set url "[$item pretty_link]" + } + +set server_url "" Index: openacs-4/packages/xowiki/www/ckeditor-images/upload_image.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/upload_image.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/upload_image.adp 13 Sep 2012 16:05:34 -0000 1.3 @@ -0,0 +1,58 @@ + + + + + + + +
    + + + + + + + + + + + +
    +#xowiki.choose_image#: +
    #xowiki.width#: #xowiki.height#:
    +#xowiki.image_width_hint# +
    + + +
    +
    + + + + \ No newline at end of file Index: openacs-4/packages/xowiki/www/ckeditor-images/upload_image.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/upload_image.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/upload_image.tcl 13 Sep 2012 16:05:35 -0000 1.4 @@ -0,0 +1,62 @@ +ad_page_contract { + +} { + parent_id:notnull,integer + {bild_url ""} +} +set js_update "" +ad_form -name upload_form \ + -export { parent_id CKEditorFuncNum } \ + -html { enctype multipart/form-data } \ + -mode edit \ + -form { + {upload_file:file(file),optional {label "Bild zum Hochladen ausw�hlen"}} + {width:text(text),optional {label "Breite in Pixel"}} + {height:text(text),optional {label "H�he in Pixel"}} + } -on_submit { + set width [template::element::get_values upload_form width] + set height [template::element::get_values upload_form height] + set size "" + if {$width ne ""} {append size $width} + if {$height ne ""} {append size x$height} + + 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] + set tmp_size [file size $upload_tmpfile] + ds_comment $upload_tmpfile + if {$size!=""} {exec convert -resize $size $upload_tmpfile $upload_tmpfile} + ds_comment $mime_type + ds_comment [template::element::get_values upload_form upload_file] + + if {![regexp {image/+} $mime_type]} { + template::form::set_error "upload_image" "upload_file" "[_ tlf-resource-integrator.HTMLArea_SelectImageUploadNoImage]" + break + } + + #set parent_id [db_string _ "select parent_id from cr_items where item_id=:fs_package_id"] + set title $file_name + + set existing_filenames [db_list _ "select name from cr_items where parent_id = :parent_id" ] + ns_log notice "util_text_to_url -text ${title} -existing_urls \"$existing_filenames\" -replacement \"_\"" + set filename [util_text_to_url -text "${title}" -existing_urls "$existing_filenames" -replacement "_"] + set package_id [db_string _ "select package_id from acs_objects where object_id=:parent_id"] + ::xowiki::Package initialize -package_id $package_id + set file_object [::xowiki::File new -destroy_on_cleanup \ + -title $title \ + -name file:$filename \ + -parent_id $parent_id \ + -package_id $package_id \ + -mime_type [::xowiki::guesstype $title] \ + -creation_user [ad_conn user_id]] + ns_log notice "file_object $file_object" + $file_object set import_file $upload_tmpfile + $file_object save_new + set revision_id [$file_object set revision_id] + + #ad_returnredirect "." + ds_comment $revision_id + set bild_url "[$file_object pretty_link]?m=download" + set image_browser_url [ad_conn package_url]/ckeditor-images + set js_update "parent.frames\['thumbs'\].location='$image_browser_url/thumb-view?parent_id=${parent_id}';" + } Index: openacs-4/packages/xowiki/www/ckeditor-images/view.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ckeditor-images/view.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ckeditor-images/view.tcl 13 Sep 2012 16:05:35 -0000 1.3 @@ -0,0 +1,8 @@ +ad_page_contract { + +} { + revision:notnull,integer +} + + +cr_write_content -revision_id $revision \ No newline at end of file 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 13 Sep 2012 16:05:35 -0000 1.3 @@ -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 13 Sep 2012 16:05:35 -0000 1.5 @@ -0,0 +1,8 @@ +# +::xo::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 13 Sep 2012 16:05:35 -0000 1.3 @@ -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 13 Sep 2012 16:05:35 -0000 1.3 @@ -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 13 Sep 2012 16:05:35 -0000 1.8 @@ -0,0 +1,4 @@ +#ns_log notice "--including_page= $__including_page, portlet=$portlet" +set content [$__including_page include $portlet] +set header_stuff [::xo::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 13 Sep 2012 16:05:35 -0000 1.3 @@ -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 13 Sep 2012 16:05:35 -0000 1.3 @@ -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 13 Sep 2012 16:05:35 -0000 1.5 @@ -0,0 +1,53 @@ + + + + + + + + +
    + + + + + + +
    + + #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 13 Sep 2012 16:05:36 -0000 1.17 @@ -0,0 +1,169 @@ + +::xo::Page requireCSS "/resources/calendar/calendar.css" +set package_id [::xo::cc package_id] +set parent_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 -parent_id $parent_id $page] +} + +set date [ns_queryget date] +if {![exists_and_not_null date]} { + set date [dt_sysdate] +} + +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 prev_mon [clock scan "1 month ago" -base $now] +set next_mon [clock scan "1 month" -base $now] + +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 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}]] +} + +set innersql "from xowiki_pagei p, cr_items ci \ + where ci.parent_id = $parent_id \ + and ci.item_id = p.item_id and ci.live_revision = p.page_id \ + and ci.content_type not in ('::xowiki::PageTemplate', '::xowiki::Form') \ + and ci.item_id != $including_item_id \ + and ci.publish_status <> 'production' " + +db_foreach entries_this_month "select count(ci.item_id) as c, + [::xo::db::sql date_trunc day p.publish_date] as d \ + $innersql + 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 + } + +# +# The following time range specifies the dates between the navigation +# arrows of the weblog mini calendar should be. Without a limitation, +# crawler will iterate over this pages until they reach infinite past +# or infinite future. +# +#set earliest_date "2006-01-1" +#set latest_date "1 year" +# +# Compute the available time range +# +set dates [db_list_of_lists get_dates "select min([::xo::db::sql date_trunc day p.publish_date]),max([::xo::db::sql date_trunc day p.publish_date]) $innersql"] +set earliest_date [::xo::db::tcl_date [lindex $dates 0 0] _] +set latest_date [::xo::db::::tcl_date [lindex $dates 0 end] _] + +if {$prev_mon < [clock scan $earliest_date]} { + set prev_month_url "" +} else { + set prev_month [clock format $prev_mon -format "%Y-%m-%d"] + set prev_month_url [export_vars -base $base_url {{date $prev_month} page_num summary}] +} +if {$next_mon > [clock scan $latest_date]} { + set next_month_url "" +} else { + set next_month [clock format $next_mon -format "%Y-%m-%d"] + set next_month_url [export_vars -base $base_url {{date $next_month} page_num summary}] +} + + +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 == 1} { + 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] && $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 13 Sep 2012 16:05:36 -0000 1.3 @@ -0,0 +1,11 @@ +# -*- tcl-*- +# $Id: CGI.page,v 1.3 2012/09/13 16:05:36 victorg 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 13 Sep 2012 16:05:36 -0000 1.4 @@ -0,0 +1,22 @@ +# -*- tcl-*- +# $Id: CGI2.page,v 1.4 2012/09/13 16:05:36 victorg 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 13 Sep 2012 16:05:36 -0000 1.4 @@ -0,0 +1,40 @@ +# -*- tcl-*- +# $Id: CGI3.page,v 1.4 2012/09/13 16:05:36 victorg 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 13 Sep 2012 16:05:36 -0000 1.3 @@ -0,0 +1,13 @@ +# -*- tcl-*- +# $Id: ajax-chat.page,v 1.3 2012/09/13 16:05:36 victorg 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/announcement-talk.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/announcement-talk.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/announcement-talk.form.page 13 Sep 2012 16:05:36 -0000 1.3 @@ -0,0 +1,22 @@ +# -*- tcl-*- +# $Id: announcement-talk.form.page,v 1.3 2012/09/13 16:05:36 victorg Exp $ +::xowiki::Form new \ + -set name en:announcement-talk.form \ + -title "Talk Announcement" \ + -set creator "Gustaf Neumann" \ + -set anon_instances t \ + -set form {{
    @_title@ @detail_link@ @event@ @_text@ @_description@ @_publish_date@ @_nls_language@ @_publish_status@
    } text/html} \ + -set text {
    @event@
    +

    Abstract: @_text@
    @detail_link@

    } \ + -set form_constraints { + _title:text,label=#xowiki.title_of_event# + _text:richtext,editor=wym,label=#xowiki.abstract# + {event:event,label=#xowiki.event#} + {detail_link:detail_link,label=#xowiki.details#} + {_publish_status:radio,options={live ready} {draft production},label=#xowiki.publish_status#} + {_description:textarea,rows=3,label=#xowiki.news-teaser#} + _page_order:hidden _creator:hidden + } + + + Index: openacs-4/packages/xowiki/www/prototypes/announcement-workshop.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/announcement-workshop.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/announcement-workshop.form.page 13 Sep 2012 16:05:36 -0000 1.3 @@ -0,0 +1,22 @@ +# -*- tcl-*- +# $Id: announcement-workshop.form.page,v 1.3 2012/09/13 16:05:36 victorg Exp $ +::xowiki::Form new \ + -set name en:announcement-workshop.form \ + -title "Workshop Announcement" \ + -set creator "Gustaf Neumann" \ + -set anon_instances t \ + -set form {{
    @_title@ @detail_link@ @event@ @_text@ @_description@ @_publish_date@ @_nls_language@ @_publish_status@
    } text/html} \ + -set text {
    @event@
    +

    Abstract: @_text@
    @detail_link@

    } \ + -set form_constraints { + _title:text,label=#xowiki.title_of_event# + _text:richtext,editor=wym,label=#xowiki.abstract# + {event:event,label=#xowiki.event#,multiday=true} + {detail_link:detail_link,label=#xowiki.details#} + {_publish_status:radio,options={live ready} {draft production},label=#xowiki.publish_status#} + {_description:textarea,rows=3,label=#xowiki.news-teaser#} + _page_order:hidden _creator:hidden + } + + + 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 13 Sep 2012 16:05:36 -0000 1.5 @@ -0,0 +1,103 @@ +# -*- tcl -*- +# $Id: bib.page,v 1.5 2012/09/13 16:05:36 victorg 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 {} { + if {[my exists instance_attributes]} { + 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 " $prev $next" + } + + my proc content {} { + my get_parameters + set page [my info parent] + + if {$entries_of eq ""} {return ""} + + 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-print.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/book-print.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/book-print.page 13 Sep 2012 16:05:36 -0000 1.3 @@ -0,0 +1,44 @@ +::xowiki::Page new -title "Book (print version)" -text { +{{set-parameter template_file view-plain}} +{{set-parameter master 0}} + + +@title@ + + + + + +Alex logo + +

    @title@

    +
    + + + + + + + + + + + + + +
    Creator: @creator@
    Version: 5.4
    Date:{{creation-date -format "%B %d, %Y"}} +
    +
    +

    Table of Contents: +

    +

    {{toc -style list -decoration plain -book_mode 1 -expand_all 1}} +

    +
    +

    {{book -menu_buttons ""}} +

    + +} 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 13 Sep 2012 16:05:37 -0000 1.7 @@ -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 -menu_buttons "edit copy create delete"}} +>><< + +} 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 13 Sep 2012 16:05:37 -0000 1.7 @@ -0,0 +1,114 @@ +# -*- tcl-*- +# $Id: categories-portlet.page,v 1.7 2012/09/13 16:05:37 victorg 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 "" ? + [::xo::db::CrClass lookup -name $open_page -parent_id $folder_id] : 0}] + + set content "" + + set tree_ids [::xowiki::Category get_mapped_trees -object_id $package_id \ + -names $tree_name -output {tree_id tree_name}] + + foreach tree $tree_ids { + foreach {tree_id my_tree_name ...} $tree {break} + if {!$no_tree_name} { + append content "

    $my_tree_name

    " + } + set categories [list] + set pos 0 + set cattree(0) [::xowiki::Tree new -volatile -orderby pos -name $my_tree_name] + foreach category_info [::xowiki::Category get_category_infos -tree_id $tree_id] { + foreach {cid category_label deprecated_p level} $category_info {break} + set c [::xowiki::TreeNode 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 13 Sep 2012 16:05:37 -0000 1.6 @@ -0,0 +1,34 @@ +# -*- tcl-*- +# $Id: contributors.page,v 1.6 2012/09/13 16:05:37 victorg 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 + } + [my info parent] render_adp 1 + return "The following users have contributed to this xowiki instance:

    [t1 asHTML]

    " + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/folder.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/folder.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/folder.form.page 13 Sep 2012 16:05:37 -0000 1.11 @@ -0,0 +1,11 @@ +# -*- tcl-*- +::xowiki::Form new \ + -set name en:folder.form \ + -title "Folder Form" \ + -set anon_instances t \ + -set text {{{child-resources}}} \ + -set form {
    @extra_menu_entries@ @index@ @ParameterPages@ @viewers@ @inherit_folders@
    } \ + -set form_constraints {extra_menu_entries:menuentries _nls_language:omit _name:required} + + + Index: openacs-4/packages/xowiki/www/prototypes/ical.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/ical.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/ical.page 13 Sep 2012 16:05:37 -0000 1.7 @@ -0,0 +1,89 @@ +# -*- tcl-*- +# $Id: ical.page,v 1.7 2012/09/13 16:05:37 victorg Exp $ +::xowiki::Object new -title "News" -text { + # + # A sample News object. + # + my initialize -parameter { + {-page_size:integer 100} + {-page_number:integer 1} + {-summary:boolean 0} + {-date ""} + {-tag ""} + {-ptag ""} + {-entries_of en:announcement-talk|en:announcement-workshop} + } + + # + # The following definition is the default rendering per + # news entry. This is executed in the context of every displayed page. + # + Class create IcalEntryRenderer -instproc render {} { + array set {} [my instance_attributes] + array set event $(event) + #my msg [my instance_attributes] + set dtstart [::xo::ical clock_to_utc [clock scan $event(event.dtstart)]] + set dtend [::xo::ical clock_to_utc [clock scan $event(event.dtend)]] + set body "SUMMARY:[::xo::ical text_to_ical -remove_tags true $event(event.summary)]" + foreach f {location} { + set key event(event.$f) + if {[info exists $key] && [set $key] ne ""} { + append body \n[string toupper $f]:[::xo::ical text_to_ical -remove_tags true [set $key]] + } + } + + return [subst {BEGIN:VEVENT +DTSTART:$dtstart +DTEND:$dtend +$body +URL:[my pretty_link -absolute true] +END:VEVENT +}] + } + + # + # The following definition is the renderer for the aggregated content. + # This is executed in the context of the whole weblog object + # + Class create IcalRenderer -instproc render {} { + return [subst {BEGIN:VCALENDAR +VERSION:2.0 +[next]END:VCALENDAR +}] +} + + my proc content {} { + my get_parameters + # + # this is not a HTML page, decativate master and provide content-type + # + ::xo::cc set_parameter master 0 + ::xo::cc set_parameter content-type text/plain + + # use the above defined custom renderers + set renderer [self]::IcalRenderer + set entry_renderer [self]::IcalEntryRenderer + + 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_renderer $entry_renderer \ + -entry_flag __no_form_page_footer \ + -entries_of $entries_of \ + ] + + $w set __page [my info parent] + $w mixin add $renderer + return [$w render] + } + +} + + + Index: openacs-4/packages/xowiki/www/prototypes/import-archive.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/import-archive.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/import-archive.form.page 13 Sep 2012 16:05:37 -0000 1.3 @@ -0,0 +1,14 @@ +# -*- tcl-*- +::xowiki::Form new \ + -set name en:import-archive.form \ + -title "Import Archive Form" \ + -set anon_instances t \ + -set text {@archive@} \ + -set form {
    @archive@
    } \ + -set form_constraints { + archive:import_archive,cleanup=true,label=#xowiki.formfield-import_archive-label# + _name:hidden _nls_language:hidden _page_order:omit _title:omit _creator:omit _description:omit + } + + + 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 13 Sep 2012 16:05:37 -0000 1.5 @@ -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/link.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/link.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/link.form.page 13 Sep 2012 16:05:37 -0000 1.5 @@ -0,0 +1,10 @@ +# -*- tcl-*- +::xowiki::Form new \ + -set name en:link.form \ + -title "Symbolic Link" \ + -set anon_instances t \ + -set text {@link@} \ + -set form {} \ + -set form_constraints {link:include _nls_language:omit} + + Index: openacs-4/packages/xowiki/www/prototypes/link.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/link.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/link.page 13 Sep 2012 16:05:38 -0000 1.3 @@ -0,0 +1,13 @@ +# -*- tcl-*- +::xowiki::Form new \ + -set name en:link \ + -title "Symbolic Link" \ + -set anon_instances t \ + -set text {@link@} \ + -set form {} \ + -set form_constraints { + link:include + } + + + Index: openacs-4/packages/xowiki/www/prototypes/news-item.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/news-item.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/news-item.form.page 13 Sep 2012 16:05:38 -0000 1.3 @@ -0,0 +1,21 @@ +# -*- tcl-*- +# $Id: news-item.form.page,v 1.3 2012/09/13 16:05:38 victorg Exp $ +::xowiki::Form new \ + -set name en:news-item.form \ + -title "News Item" \ + -set anon_instances t \ + -set text {@image_url@ @_text@
    @detail_link@} \ + -set form {{
    @_title@ @detail_link@ @_text@ @image_url@ @_description@ @_publish_date@ @_nls_language@ @_publish_status@
    } text/html} \ + -set form_constraints { + _page_order:hidden + _creator:hidden + _title:text,label=#acs-kernel.common_Title# + {detail_link:detail_link,label=#xowiki.news-source#} + _publish_date:date + image_url:image_url,float=left,width=100px + {_publish_status:radio,options={live ready} {draft production},label=#xowiki.publish_status#} + {_description:textarea,rows=3,label=#xowiki.news-teaser#} + } + + + 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 13 Sep 2012 16:05:38 -0000 1.19 @@ -0,0 +1,161 @@ +# -*- tcl-*- +# $Id: news.page,v 1.19 2012/09/13 16:05:38 victorg 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.form|en:announcement-talk.form|en:announcement-workshop.form} + } + + my get_parameters + # + # Don't add the footer (with tags, general comments, etc.) to the + # aggregated page, since this can be confusing.. + # + [my info parent] set __no_footer 1 + + # + # get current folder + # + set folder_form_id [::xowiki::Weblog instantiate_forms -forms en:folder.form -package_id $package_id] + set current_folder [[my info parent] get_folder -folder_form_ids $folder_form_id] + my set current_folder_id [$current_folder item_id] + + # Provide a tailored link for creating new pages in the wiki menu + # + set forms [::xowiki::Weblog instantiate_forms -parent_id [my set current_folder_id] \ + -forms $entries_of \ + -package_id $package_id] + set template_id [lindex $forms 0] + if {$template_id ne ""} { + set form_link [$template_id pretty_link] + set new_link [$package_id make_link -link $form_link $template_id create-new return_url] + } else { + ns_log notice "Warning: could not resolve $entries_of with -parent_id [my set current_folder_id]" + set form_link "" + set new_link "" + } + + [my info parent] set __link(new) $new_link + + # + # 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 [my detail_link] + regsub -all & $link "&" link + 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] + + set edit_button [my include [list edit-item-button -book_mode true]] + if {$edit_button ne ""} {set edit_button "
    $edit_button
    "} + append content "
    " $edit_button \ + "

    [ad_quotehtml $title]

    " \ + " ($day)
    \n" \ + $description $more $my_footer \n\ + "
    " + } + + # + # The following definition is the renderer for the aggregated content. + # 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 package_id + + 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" + } + # + # Include the RSS Button + # + set page [my set __page] + set rss [$page include "rss-button -title {[$page title]} -entries_of [my entries_of] -decoration none"] + # + # If the user has creation rights (on the first form), include the RSS Bookmarklet button + # + if {[my exists form_ids] && [my set form_ids] ne ""} { + set can_create_news_item [$package_id make_link [lindex [my set form_ids] 0] create-new return_url] + if {$can_create_news_item ne ""} { + append rss "Bookmarklet: " [$page include "bookmarklet-button -label {[$page title]}"] + } + } + + 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 \ + -parent_id [my set current_folder_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/page.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/page.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/page.form.page 13 Sep 2012 16:05:38 -0000 1.4 @@ -0,0 +1,11 @@ +# -*- tcl-*- +::xowiki::Form new \ + -set name en:page.form \ + -title "Wiki" \ + -set anon_instances f \ + -set text {@_text@} \ + -set form {
    @_name@ @_page_order@ @_title@ @_creator@ @_text@ @_description@ @_nls_language@
    } \ + -set form_constraints {} + + + Index: openacs-4/packages/xowiki/www/prototypes/photo.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/prototypes/photo.form.page,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/prototypes/photo.form.page 13 Sep 2012 16:05:38 -0000 1.3 @@ -0,0 +1,8 @@ +# -*- tcl-*- +::xowiki::Form new \ + -set name en:photo.form \ + -title "Photo" \ + -set anon_instances t \ + -set text {

    @_title@

    @image@

    } \ + -set form {} \ + -set form_constraints {image:image} 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 13 Sep 2012 16:05:38 -0000 1.6 @@ -0,0 +1,31 @@ +# -*- tcl-*- +# $Id: podcast.page,v 1.6 2012/09/13 16:05:38 victorg 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 13 Sep 2012 16:05:38 -0000 1.3 @@ -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 13 Sep 2012 16:05:39 -0000 1.3 @@ -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 13 Sep 2012 16:05:39 -0000 1.20 @@ -0,0 +1,123 @@ +# -*- tcl-*- +# $Id: weblog-portlet.page,v 1.20 2012/09/13 16:05:39 victorg 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} + {-category_id ""} + {-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 log "--W entry [self] [my name] package_id $package_id" + [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) + set link [my detail_link] + 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\ + "
    " + #my log "--W entry done [self] [my info class] subst=[my do_substitutions] [my name]" + return $content + } + + # + # 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 + my log "--get_parameters returned package_id=$package_id" + set page [my info parent] + + if {[$page exists __including_page]} { + set i [$page set __including_page] + #my log "--W including page $i" + set exclude_item_ids [$i item_id] + $i set render_adp 0 ;# no double adp substitutions + $i do_substitutions 0;# no double substitutions in parent + } else { + #my log "--W NO including page" + set exclude_item_ids [$page item_id] + $page set __no_footer 1 + } + $page do_substitutions 0; # no double substitutions in page + + # 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 $category_id \ + -tag $tag \ + -ptag $ptag \ + -entries_of $entries_of \ + -exclude_item_ids $exclude_item_ids \ + -entry_renderer $entry_renderer \ + ] + + $w mixin add $renderer + set html [$w render] + $page do_substitutions 1; # reset to default + return $html + } + +} 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 13 Sep 2012 16:05:39 -0000 1.9 @@ -0,0 +1,16 @@ +::xowiki::Page new -title "Weblog Page" -set publish_status production -text { + +>>content<< +{{weblog-portlet -decoration plain}} +>><< +>>sidebar<< +{{adp portlets/weblog-mini-calendar}} +{{tags -decoration plain}} +{{tags -popular 1 -limit 30 -decoration plain}} +{{categories -count 1 -decoration plain}} +>><< + +} + + + 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 13 Sep 2012 16:05:39 -0000 1.6 @@ -0,0 +1,41 @@ +/* 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/ck_config.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ck_config.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ck_config.js 13 Sep 2012 16:05:39 -0000 1.3 @@ -0,0 +1,70 @@ + +CKEDITOR.editorConfig = function( config ) +{ + config.width = '95%'; + + config.autoParagraph = false; + config.toolbar_Page = + [ + ['Cut','Copy','Paste','PasteText','PasteFromWord'], + ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], + ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], + ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['Timestamp', 'xowikiImage','Table','HorizontalRule'], + ['Link','Unlink','Anchor'], + ['Styles','Format','TextColor','BGColor'], + ['Maximize', 'ShowBlocks','Source'] + ]; + config.toolbar_GapText = + [ + ['Gap'], + ['Cut','Copy','Paste','PasteText','PasteFromWord'], + ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], + ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], + ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['xowikiImage','Table','HorizontalRule'], + ['Link','Unlink','Anchor'], + ['Styles','Format','TextColor','BGColor'], + ['Maximize', 'ShowBlocks','Source','About'] + ]; + config.toolbar_Xoqt = + [ + ['interactions'], + ['Cut','Copy','Paste','PasteText','PasteFromWord'], + ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], + ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], + ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['xowikiImage','Table','HorizontalRule'], + ['Link','Unlink','Anchor'], + ['Styles','Format','TextColor','BGColor'], + ['Maximize', 'ShowBlocks','Source','About'] + ]; + config.toolbar_Basic = + [ + ['Source'], + ['Bold'], + ['Italic'], + ]; + config.toolbar_Full = + [ + ['Source','-','Save','NewPage','Preview','-','Templates'], + ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], + ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], + ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], + '/', + ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], + ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['BidiLtr', 'BidiRtl'], + ['Link','Unlink','Anchor'], + ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], + '/', + ['Styles','Format','Font','FontSize'], + ['TextColor','BGColor'], + ['Maximize', 'ShowBlocks','-','About'] + ]; + +}; Index: openacs-4/packages/xowiki/www/resources/ck_contents.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ck_contents.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ck_contents.css 13 Sep 2012 16:05:39 -0000 1.3 @@ -0,0 +1,20 @@ +.xoqt-interaction { + border: 2px solid green; + padding: 5px; +} +.gap { + border: 2px solid red; + padding 5px; +} + +.sortable { list-style-type: none; margin: 0; padding: 0; } +.sortable li { + background: url("http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png") repeat-x scroll 50% 50% #E6E6E6; + border: 1px solid #D3D3D3; + color: #555555; + font-weight: normal; + float:left; clear:left; +} +.sortable li span { position: absolute; margin-left: -1.3em; } +.associate-t {color: green;} +.associate-f {color: red;} Index: openacs-4/packages/xowiki/www/resources/ck_templates.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ck_templates.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ck_templates.js 13 Sep 2012 16:05:39 -0000 1.3 @@ -0,0 +1,141 @@ +/* +Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +// Register a templates definition set named "default". +CKEDITOR.addTemplates( 'default', +{ + // The name of sub folder which hold the shortcut preview images of the + // templates. + imagesPath : CKEDITOR.getUrl( CKEDITOR.plugins.getPath( 'templates' ) + 'templates/images/' ), + + // The templates definitions. + templates : + [ + { + title: 'Image and Title', + image: 'template1.gif', + description: 'One main image with a title and text that surround the image.', + html: + '

    ' + + '' + + 'Type the title here'+ + '

    ' + + '

    ' + + 'Type the text here' + + '

    ' + }, + { + title: 'Strange Template', + image: 'template2.gif', + description: 'A template that defines two colums, each one with a title, and some text.', + html: + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
    ' + + '

    Title 1

    ' + + '
    ' + + '

    Title 2

    ' + + '
    ' + + 'Text 1' + + '' + + 'Text 2' + + '
    ' + + '

    ' + + 'More text goes here.' + + '

    ' + }, + { + title: 'Text and Table', + image: 'template3.gif', + description: 'A title with some text and a table.', + html: + '
    ' + + '

    ' + + 'Title goes here' + + '

    ' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
    ' + + 'Table title' + + '
       
       
       
    ' + + '

    ' + + 'Type the text here' + + '

    ' + + '
    ' + } + ] +}); + + +// Register a templates definition set named "interactions". +CKEDITOR.addTemplates( 'interactions', +{ + // The name of sub folder which hold the shortcut preview images of the + // templates. + imagesPath : CKEDITOR.getUrl( '/resources/xowiki/images/' ), + + // The templates definitions. + templates : + [ + { + title: 'Simple Open Text Question', + image: '1answer.png', + description: 'Question with a text and a single answer field.', + html: + '
    Schreiben Sie den Angabetext hier...' + + '
    (10 Minuten)
    ' + + '
    ' + }, + { + title: 'Open Text question consisting of three parts', + image: '2answers.png', + description: 'Question with a introductory text and three subquestions.', + html: + '

    Schreiben Sie den allgemeinen Angabetext hier' + + '

      ' + + '
    1. Angabetext für die erste Teilaufgabe' + + '
      (10 Minuten)
      ' + + '
      ' + + + '
    2. Angabetext für die zweite Teilaufgabe' + + '
      (10 Minuten)
      ' + + '
      ' + + + '
    3. Angabetext für die dritte Teilaufgabe' + + '
      (10 Minuten)
      ' + + '
      ' + + '
    ' + + } + ] +}); \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/ckeip.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ckeip.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ckeip.js 13 Sep 2012 16:05:40 -0000 1.4 @@ -0,0 +1,141 @@ +/* + +# CKEDITOR Edit-In Place jQuery Plugin. + +# Created By Dave Earley. +# www.Dave-Earley.com +# Adapted by Michael Totschnig + +*/ + +$.fn.ckeip = function (callback,options) { + + function load_ck (u_id) { + var name = 'ckeip_e_' + u_id; + var textarea = $('#' + name); + textarea.ckeditor(callback,settings.ckeditor_config); + CKEDITOR.instances[name].on('instanceReady',function(e) {settings.ckeditor_config.ready_callback}); + textarea.show(); + textarea.bind('destroy.ckeditor',settings.ckeditor_config.destroy_callback); + $('#buttons_ckeip_' + u_id + '').show(); + } + + var defaults = { + name: 'text', + e_height: '1', + data: {}, + e_hover_color: '#eeeeee', + ckeditor_config: '', + e_width: '50' + }; + + var settings = $.extend({}, defaults, options); + + return this.each(function () { + var using_wrapper = false; + var timeout; + var delay = 500; + var eip_html = $(this).html(); + if (eip_html == ' ') { eip_html = ''} + var u_id = this.id; + var div = $(this); + div.addClass('ckeip'); + div.data('editing',false); + var wrapper; + if (settings.wrapper_class != '') { + wrapper = div.closest('.'+settings.wrapper_class); + if (wrapper.length == 0) { + wrapper = div; + } else { + using_wrapper = true; + } + } else { + wrapper = div; + } + + $(this).before("
    "); + + wrapper.bind("click focusin", function () { + //we provide for the possibility that the element has been cloned + //and changed id after having been initialized + var div; + var wrapper = this; + if (using_wrapper) { + div = $(wrapper).find('div.ckeip'); + } else { + div = $(wrapper); + } + if (div.data('editing')) {return false} + var u_id = div.attr('id'); + var textarea = $('#ckeip_e_' + u_id + ''); + if (!timeout) { + timeout = setTimeout(function() { + div.hide(); + div.data('editing',true); + if (div.html().match(/<.+>/)!=null) { + load_ck(u_id); + } else { + textarea.show();; + textarea.focus(); + textarea.bind("focusout", function(ev) { + var ckeip_html = textarea.val(); + if (ckeip_html == '') { ckeip_html = ' '} + div.html(ckeip_html); + textarea.hide(); + textarea.unbind('focusout'); + div.show(); + div.data('editing',false); + return false; + }); + } + timeout = null; + }, delay); + } + }); + wrapper.bind("dblclick", function () { + if (timeout) { + // Clear the timeout since this is a double-click and we don't want + // the 'click-only' code to run. + clearTimeout(timeout); + timeout = null; + } + var div; + var wrapper = this; + if (using_wrapper) { + div = $(wrapper).find('div.ckeip'); + } else { + div = $(wrapper); + } + if (div.data('editing')) {return false} + var u_id = div.attr('id'); + div.hide(); + div.data('editing',true); + load_ck(u_id); + }); + + wrapper.hover(function () { + $(this).css({ + backgroundColor: settings.e_hover_color + }); + }, function () { + $(this).css({ + backgroundColor: '' + }); + }); + $("#close_ckeip_" + u_id + "").click(function () { + var wrapper; + var u_id = this.id.substring(12); + var textarea = $('#ckeip_e_' + u_id + ''); + var div = $('#' + u_id); + var ckeip_html = textarea.val(); + if (ckeip_html == '') { ckeip_html = ' '} + div.html(ckeip_html); + textarea.ckeditorGet().destroy(); + textarea.hide(); + $('#buttons_ckeip_' + u_id + '').hide(); + div.show(); + div.data('editing',false); + return false; + }); + }); +}; \ No newline at end of file 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 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/collab-graph.js 13 Sep 2012 16:05:40 -0000 1.6 @@ -0,0 +1,295 @@ +/* Graph JavaScript framework, version 0.0.1 + * (c) 2006 Aslak Hellesoy + * (c) 2006 Dave Hoover + * + * Ported from Graph::Layouter::Spring in + * http://search.cpan.org/~pasky/Graph-Layderer-0.02/ + * 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 + * +/*--------------------------------------------------------------------------*/ + +var Graph = Class.create(); +Graph.prototype = { + initialize: function() { + this.nodeSet = {}; + this.nodes = []; + this.edges = []; + }, + + addNode: function(value) { + if(typeof value == 'string') { + // Create a new div + var key = value; + var element = document.createElement('div'); + element.innerHTML = value; + // THIS DOESN'T WORK!! NEED AN OTHER CONTAINER. + document.appendChild(element); + } else { + // Assuming it's a DOM node *with* and id. + var key = value.id; + var element = value; + } + + var node = this.nodeSet[key]; + if(node == undefined) { + node = new Graph.Node(element); + this.nodeSet[key] = node; + this.nodes.push(node); + } + return node; + }, + + // Uniqueness must be ensured by caller + addEdge: function(source, target, w, a, l) { + var s = this.addNode(source); + var t = this.addNode(target); + if (w == undefined) {w = 1;} + if (a == undefined) {a = 1;} + if (l == undefined) {l = 1.0;} + var edge = {source: s, target: t, weight: w, arrow: a, linewidth: l}; + this.edges.push(edge); + } +}; + +Graph.Node = Class.create(); +Graph.Node.prototype = { + initialize: function(value) { + this.value = value; + } +}; + +Graph.Renderer = {}; +Graph.Renderer.Basic = Class.create(); +Graph.Renderer.Basic.prototype = { + initialize: function(element, graph) { + this.element = element; + this.graph = graph; + + this.ctx = element.getContext("2d"); + this.radius = 5; + this.arrowAngle = Math.PI/10; + this.scale = 0.9; + this.offset = 0.1*((1-this.scale)*element.width); + this.factorX = this.scale*(element.width - 2 * this.radius) / (graph.layoutMaxX - graph.layoutMinX); + this.factorY = this.scale*(element.height - 2 * this.radius) / (graph.layoutMaxY - graph.layoutMinY); + }, + + translate: function(point) { + return [ + this.offset+(point[0] - this.graph.layoutMinX) * this.factorX + this.radius, + this.offset+(point[1] - this.graph.layoutMinY) * this.factorY + this.radius + ]; + }, + + rotate: function(point, length, angle) { + var dx = length * Math.cos(angle); + var dy = length * Math.sin(angle); + return [point[0]+dx, point[1]+dy]; + }, + + draw: function() { + for (var i = 0; i < this.graph.nodes.length; i++) { + this.drawNode(this.graph.nodes[i]); + } + for (var i = 0; i < this.graph.edges.length; i++) { + this.drawEdge(this.graph.edges[i]); + } + }, + + drawNode: function(node) { + var point = this.translate([node.layoutPosX, node.layoutPosY]); + + node.value.style.position = 'absolute'; + 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); + this.ctx.closePath(); + this.ctx.stroke(); + }, + + drawEdge: function(edge) { + var source = this.translate([edge.source.layoutPosX, edge.source.layoutPosY]); + var target = this.translate([edge.target.layoutPosX, edge.target.layoutPosY]); + + var tan = (target[1] - source[1]) / (target[0] - source[0]); + var theta = Math.atan(tan); + if(source[0] <= target[0]) {theta = Math.PI+theta} + source = this.rotate(source, -this.radius, theta); + target = this.rotate(target, this.radius, theta); + + // draw the edge + this.ctx.strokeStyle = 'grey'; + this.ctx.fillStyle = 'grey'; + this.ctx.lineWidth = edge.linewidth; + this.ctx.beginPath(); + this.ctx.moveTo(source[0], source[1]); + this.ctx.lineTo(target[0], target[1]); + this.ctx.stroke(); + if (this.arrow) { + this.drawArrowHead(20, this.arrowAngle, theta, source[0], source[1], target[0], target[1]); + } + }, + + drawArrowHead: function(length, alpha, theta, startx, starty, endx, endy) { + var top = this.rotate([endx, endy], length, theta + alpha); + var bottom = this.rotate([endx, endy], length, theta - alpha); + this.ctx.beginPath(); + this.ctx.moveTo(endx, endy); + this.ctx.lineTo(top[0], top[1]); + this.ctx.lineTo(bottom[0], bottom[1]); + this.ctx.fill(); + } +}; + +Graph.Layout = {}; +Graph.Layout.Spring = Class.create(); +Graph.Layout.Spring.prototype = { + initialize: function(graph) { + this.graph = graph; + this.iterations = 500; + this.maxRepulsiveForceDistance = 6; + this.k = 2; + this.c = 0.01; + this.maxVertexMovement = 0.5; + }, + + layout: function() { + this.layoutPrepare(); + for (var i = 0; i < this.iterations; i++) { + this.layoutIteration(); + } + this.layoutCalcBounds(); + }, + + layoutPrepare: function() { + for (var i = 0; i < this.graph.nodes.length; i++) { + var node = this.graph.nodes[i]; + node.layoutPosX = 0; + node.layoutPosY = 0; + node.layoutForceX = 0; + node.layoutForceY = 0; + } + }, + + layoutCalcBounds: function() { + var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity; + + for (var i = 0; i < this.graph.nodes.length; i++) { + var x = this.graph.nodes[i].layoutPosX; + var y = this.graph.nodes[i].layoutPosY; + + if(x > maxx) maxx = x; + if(x < minx) minx = x; + if(y > maxy) maxy = y; + if(y < miny) miny = y; + } + + this.graph.layoutMinX = minx; + this.graph.layoutMaxX = maxx; + this.graph.layoutMinY = miny; + this.graph.layoutMaxY = maxy; + }, + + layoutIteration: function() { + // Forces on nodes due to node-node repulsions + for (var i = 0; i < this.graph.nodes.length; i++) { + var node1 = this.graph.nodes[i]; + for (var j = i + 1; j < this.graph.nodes.length; j++) { + var node2 = this.graph.nodes[j]; + this.layoutRepulsive(node1, node2); + } + } + // Forces on nodes due to edge attractions + for (var i = 0; i < this.graph.edges.length; i++) { + var edge = this.graph.edges[i]; + this.layoutAttractive(edge); + } + + // Move by the given force + for (var i = 0; i < this.graph.nodes.length; i++) { + var node = this.graph.nodes[i]; + var xmove = this.c * node.layoutForceX; + var ymove = this.c * node.layoutForceY; + + var max = this.maxVertexMovement; + if(xmove > max) xmove = max; + if(xmove < -max) xmove = -max; + if(ymove > max) ymove = max; + if(ymove < -max) ymove = -max; + + node.layoutPosX += xmove; + node.layoutPosY += ymove; + node.layoutForceX = 0; + node.layoutForceY = 0; + } + }, + + layoutRepulsive: function(node1, node2) { + var dx = node2.layoutPosX - node1.layoutPosX; + var dy = node2.layoutPosY - node1.layoutPosY; + var d2 = dx * dx + dy * dy; + if(d2 < 0.01) { + dx = 0.1 * Math.random() + 0.1; + dy = 0.1 * Math.random() + 0.1; + var d2 = dx * dx + dy * dy; + } + var d = Math.sqrt(d2); + if(d < this.maxRepulsiveForceDistance) { + var repulsiveForce = this.k * this.k / d; + node2.layoutForceX += repulsiveForce * dx / d; + node2.layoutForceY += repulsiveForce * dy / d; + node1.layoutForceX -= repulsiveForce * dx / d; + node1.layoutForceY -= repulsiveForce * dy / d; + } + }, + + layoutAttractive: function(edge) { + var node1 = edge.source; + var node2 = edge.target; + + var dx = node2.layoutPosX - node1.layoutPosX; + var dy = node2.layoutPosY - node1.layoutPosY; + var d2 = dx * dx + dy * dy; + if(d2 < 0.01) { + dx = 0.1 * Math.random() + 0.1; + dy = 0.1 * Math.random() + 0.1; + var d2 = dx * dx + dy * dy; + } + var d = Math.sqrt(d2); + if(d > this.maxRepulsiveForceDistance) { + d = this.maxRepulsiveForceDistance; + d2 = d * d; + } + var attractiveForce = (d2 - this.k * this.k) / this.k; + if(edge.weight == undefined || edge.weight < 1) edge.weight = 1; + //console.log(edge.weight); + attractiveForce *= Math.log(edge.weight) * 0.5 + 1; + //console.log(attractiveForce); + node2.layoutForceX -= attractiveForce * dx / d; + node2.layoutForceY -= attractiveForce * dy / d; + node1.layoutForceX += attractiveForce * dx / d; + node1.layoutForceY += attractiveForce * dy / d; + } +}; 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 13 Sep 2012 16:05:40 -0000 1.4 @@ -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/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 13 Sep 2012 16:05:40 -0000 1.3 @@ -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/jquery-ui-1.8.17.custom.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/jquery-ui-1.8.17.custom.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/jquery-ui-1.8.17.custom.css 13 Sep 2012 16:05:41 -0000 1.3 @@ -0,0 +1,565 @@ +/* + * jQuery UI CSS Framework 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* + * jQuery UI Resizable 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.17 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/jquery-ui-1.8.17.custom.min.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/jquery-ui-1.8.17.custom.min.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/jquery-ui-1.8.17.custom.min.js 13 Sep 2012 16:05:41 -0000 1.3 @@ -0,0 +1,356 @@ +/*! + * jQuery UI 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */(function(a,b){function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;if(!b.href||!g||f.nodeName.toLowerCase()!=="map")return!1;h=a("img[usemap=#"+g+"]")[0];return!!h&&d(h)}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}a.ui=a.ui||{};a.ui.version||(a.extend(a.ui,{version:"1.8.17",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)});return c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){if(c===b)return g["inner"+d].call(this);return this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){if(typeof b!="number")return g["outer"+d].call(this,b);return this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);/* + * jQuery UI Position 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Position + */(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1];return this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]!==e){var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0}},top:function(b,c){if(c.at[1]!==e){var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];if(!c||!c.ownerDocument)return null;if(b)return this.each(function(){a.offset.setOffset(this,b)});return h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&jQuery.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);/* + * jQuery UI Draggable 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Draggables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!!this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy();return this}},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle"))return!1;this.handle=this._getHandle(b);if(!this.handle)return!1;c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('
    ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")});return!0},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment();if(this._trigger("start",b)===!1){this._clear();return!1}this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.helper.addClass("ui-draggable-dragging"),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b);return!0},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1){this._mouseUp({});return!1}this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,b);return!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",b)!==!1&&d._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b);return a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)});return c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute");return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.lefth[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.toph[3]?j-this.offset.click.toph[2]?k-this.offset.click.left=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f=k&&g<=l||h>=k&&h<=l||gl)&&(e>=i&&e<=j||f>=i&&f<=j||ej);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();droppablesLoop:for(var g=0;g').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e');/sw|se|ne|nw/.test(f)&&h.css({zIndex:++c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){c.disabled||(a(this).removeClass("ui-resizable-autohide"),b._handles.show())},function(){c.disabled||b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement);return this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),a.browser.opera&&/relative/.test(f.css("position"))&&f.css({position:"relative",top:"auto",left:"auto"}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b);return!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui());return!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),ea.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null);return a},_proportionallyResize:function(){var b=this.options;if(!!this._proportionallyResizeElements.length){var c=this.helper||this.element;for(var d=0;d');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.17"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10),position:b.css("position")})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,e){a(b).each(function(){var b=a(this),f=a(this).data("resizable-alsoresize"),g={},i=e&&e.length?e:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(i,function(a,b){var c=(f[b]||0)+(h[b]||0);c&&c>=0&&(g[b]=c||null)}),a.browser.opera&&/relative/.test(b.css("position"))&&(d._revertToRelativePosition=!0,b.css({position:"absolute",top:"auto",left:"auto"})),b.css(g)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};d._revertToRelativePosition&&(d._revertToRelativePosition=!1,typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)),a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!!i){e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/e.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*e.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);/* + * jQuery UI Selectable 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("
    ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy();return this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(!this.options.disabled){var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element});return!1}})}},_mouseDrag:function(b){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!!i&&i.element!=c.element[0]){var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.righth||i.bottome&&i.rightf&&i.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f){e=a(this);return!1}});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}this.currentItem=e,this._removeCurrentsFromItems();return!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(b,c){if(!!b){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"=");return d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")});return d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+jf&&b+ka[this.floating?"width":"height"]?l:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a),this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];e||(b.style.visibility="hidden");return b},update:function(a,b){if(!e||!!d.forcePlaceholderSize)b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!!c)if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.topthis.containment[3]?h-this.offset.click.topthis.containment[2]?i-this.offset.click.left=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");(b.autoHeight||b.fillHeight)&&c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(!(this.options.disabled||b.altKey||b.ctrlKey)){var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}if(f){a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus();return!1}return!0}},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];this._clickHandler({target:b},b);return this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(!d.disabled){if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return}},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!!g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}}),a.extend(a.ui.accordion,{version:"1.8.17",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size())b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);else{if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})}},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})})(jQuery);/* + * jQuery UI Autocomplete 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!b.options.disabled&&!b.element.propAttr("readOnly")){d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._move("previous",c),c.preventDefault();break;case e.DOWN:b._move("next",c),c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){b.options.disabled||(b.selectedItem=null,b.previous=b.element.val())}).bind("blur.autocomplete",function(a){b.options.disabled||(clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150))}),this._initSource(),this.response=function(){return b._response.apply(b,arguments)},this.menu=a("
      ").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",autocompleteRequest:++c,success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length").data("item.autocomplete",c).append(a("").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend(""),d.secondary&&b.append(""),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})})(jQuery);/* + * jQuery UI Dialog 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js + */(function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||" ",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("
      ")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){b.close(a);return!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1!==c._trigger("beforeClose",b)){c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d);return c}},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;if(e.modal&&!b||!e.stack&&!e.modal)return d._trigger("focus",c);e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c);return d},open:function(){if(!this._isOpen){var b=this,c=b.options,d=b.uiDialog;b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey){d.focus(1);return!1}if(b.target===d[0]&&b.shiftKey){e.focus(1);return!1}}}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open");return b}},_createButtons:function(b){var c=this,d=!1,e=a("
      ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("
      ").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){a!=="click"&&(a in f?e[a](b):e.attr(a,b))}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||" "))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.17",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");b||(this.uuid+=1,b=this.uuid);return"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&c.bgiframe(),this.instances.push(c);return c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;if(a.browser.msie&&a.browser.version<7){b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return b").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;ic&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i);if(j===!1)return!1;this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0;return!0},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);this._slide(a,this._handleIndex,c);return!1},_mouseStop:function(a){this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1;return!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e;return this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values());return this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c1)this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);else{if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;Math.abs(c)*2>=b&&(d+=c>0?b:-b);return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.17"})})(jQuery);/* + * jQuery UI Tabs 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */(function(a,b){function f(){return++d}function e(){return++c}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
      ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
    • #{label}
    • "},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash){e.selected=a;return!1}}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1){this.blur();return!1}e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected")){e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur();return!1}if(!f.length){e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur();return!1}}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$="+a+"]")));return a},destroy:function(){var b=this.options;this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie);return this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0]));return this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a])));return this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;this.anchors.eq(a).trigger(this.options.event+".tabs");return this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup();return this},url:function(a,b){this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.17"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a'))}$.extend($.ui,{datepicker:{version:"1.8.17"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('
      ')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);c.hasClass(this.markerClassName)||(this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a))},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$(''+c+""),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('').addClass(this._triggerClass).html(g==""?f:$("").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){$.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._showDatepicker(a[0]);return!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;db&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);c.hasClass(this.markerClassName)||(c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block"))},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$(''),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f);return this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(a){$.datepicker.log(a)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if(!$.datepicker._isDisabledDatepicker(a)&&$.datepicker._lastInput!=a){var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){e|=$(this).css("position")=="fixed";return!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0);return b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=$.data(a,PROP_NAME))&&this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=this,f=function(){$.datepicker._tidyDialog(b),e._curInst=null};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,f):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,f),c||f(),this._datepickerShowing=!1;var g=this._get(b,"onClose");g&&g.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!!$.datepicker._curInst){var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);this._isDisabledDatepicker(d[0])||(this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e))},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if(!$(d).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(e[0])){var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();b.setMonth(0),b.setDate(1);return Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1-1){j=1,k=l;for(;;){var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+112?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&pp)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?''+q+"":e?"":''+q+"",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?''+s+"":e?"":''+s+"",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'",x=d?'
      '+(c?w:"")+(this._isInRange(a,v)?'":"")+(c?"":w)+"
      ":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='
      '+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'
      '+"";var R=z?'":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="=5?' class="ui-datepicker-week-end"':"")+">"+''+C[T]+""}Q+=R+"";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z";var _=z?'":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Ym;_+='",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+""}n++,n>11&&(n=0,o++),Q+="
      '+this._get(a,"weekHeader")+"
      '+this._get(a,"calculateWeek")(Y)+""+(bb&&!G?" ":bc?''+Y.getDate()+"":''+Y.getDate()+"")+"
      "+(j?""+(g[0]>0&&N==g[1]-1?'
      ':""):""),M+=Q}K+=M}K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'':""),a._keyEvent=!1;return K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this +._get(a,"showMonthAfterYear"),l='
      ',m="";if(f||!i)m+=''+g[b]+"";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='"}k||(l+=m+(f||!i||!j?" ":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+=''+c+"";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='",l+=a.yearshtml,a.yearshtml=null}}l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?" ":"")+m),l+="
      ";return l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&bd?d:e;return e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth()));return this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));return this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)})},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.17",window["DP_jQuery_"+dpuuid]=$})(jQuery);/* + * jQuery UI Progressbar 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */(function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("
      ").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===b)return this._value();this._setOption("value",a);return this},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;typeof a!="number"&&(a=0);return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.17"})})(jQuery);/* + * jQuery UI Effects 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */jQuery.effects||function(a,b){function l(b){if(!b||typeof b=="number"||a.fx.speeds[b])return!0;if(typeof b=="string"&&!a.effects[b])return!0;return!1}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete;return[b,c,d,e]}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function d(b,d){var e;do{e=a.curCSS(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function c(b){var c;if(b&&b.constructor==Array&&b.length==3)return b;if(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];if(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))return[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55];if(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];if(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];if(c=/rgba\(0, 0, 0, 0\)/.exec(b))return e.transparent;return e[a.trim(b).toLowerCase()]}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){a.isFunction(d)&&(e=d,d=null);return this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class");a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.17",save:function(a,b){for(var c=0;c").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"}));return d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;if(b.parent().is(".ui-effects-wrapper")){c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus();return c}return b},setTransition:function(b,c,d,e){e=e||{},a.each(c,function(a,c){unit=b.cssUnit(c),unit[0]>0&&(e[c]=unit[0]*d+unit[1])});return e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];if(a.fx.off||!i)return h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)});return i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="show";return this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="hide";return this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);c[1].mode="toggle";return this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])});return d}}),a.easing.jswing=a.easing.swing,a.extend(a.easing,{def:"easeOutQuad",swing:function(b,c,d,e,f){return a.easing[a.easing.def](b,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b+c;return-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b+c;return d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b+c;return-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b*b+c;return d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return b==0?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){if(b==0)return c;if(b==e)return c+d;if((b/=e/2)<1)return d/2*Math.pow(2,10*(b-1))+c;return d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){if((b/=e/2)<1)return-d/2*(Math.sqrt(1-b*b)-1)+c;return d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);/* + * jQuery UI Effects Fade 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */(function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/* + * jQuery UI Effects Fold 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */(function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);/* + * jQuery UI Effects Highlight 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */(function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/* + * jQuery UI Effects Pulsate 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */(function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show");times=(b.options.times||5)*2-1,duration=b.duration?b.duration/2:a.fx.speeds._default/2,isVisible=c.is(":visible"),animateTo=0,isVisible||(c.css("opacity",0).show(),animateTo=1),(d=="hide"&&isVisible||d=="show"&&!isVisible)&×--;for(var e=0;e').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery); \ No newline at end of file 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 13 Sep 2012 16:05:41 -0000 1.3 @@ -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/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 13 Sep 2012 16:05:41 -0000 1.3 @@ -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/weblog.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/weblog.css,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/weblog.css 13 Sep 2012 16:05:41 -0000 1.5 @@ -0,0 +1,34 @@ +.filter { + float: right; + font-size: 85%; + color: #9a9a9b; +} +div.post { + clear: both; + background: #f8f8f8; +} +.post p.auth { + padding: 0 0 0 12px; + font-size: 85%; + margin-left: 10px; + font-weight: bold; + color: #9a9a9b; + background: url(/resources/xowiki/bracket.gif) no-repeat; +} + +.post .more { + color: #9a9a9b; +} + +.post h2 { + font: normal 140%/1.3em Arial, Verdana, Helvetica, sans-serif; +} + +.post h2 a { + text-decoration: none; + border: none; +} + +.post { + font-size: 90%; +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/wu-repeatable.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/wu-repeatable.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/wu-repeatable.js 13 Sep 2012 16:05:41 -0000 1.3 @@ -0,0 +1,136 @@ +// wu-base.js + +var wu = wu || {}; + +wu.log = function(o) { + if (window.console && o) { + window.console.log(o); + } +}; + +wu.setStyle = setStyle = function(el, property, val) { + el.style[property] = val; +}; + +wu.applyStyles = function(el, styles){ + if(styles){ + if(typeof styles == "string"){ + var re = /\s?([a-z\-]*)\:\s?([^;]*);?/gi; + var matches; + while ((matches = re.exec(styles)) != null){ + wu.setStyle(el,matches[1], matches[2]); + } + }else if (typeof styles == "object"){ + for (var style in styles){ + wu.setStyle(el,style, styles[style]); + } + }else if (typeof styles == "function"){ + wu.applyStyles(el, styles.call()); + } + } +} + +function isArray(v){ + return v && typeof v.length == 'number' && typeof v.splice == 'function'; +} +function createDom(o, parentNode){ + var el; + if (isArray(o)) { // Allow Arrays of siblings to be inserted + el = document.createDocumentFragment(); // in one shot using a DocumentFragment + for(var i = 0, l = o.length; i < l; i++) + { + createDom(o[i], el); + } + } else if (typeof o == "string") { // Allow a string as a child spec. + el = document.createTextNode(o); + } else { + el = document.createElement(o['tag']||'div'); + var useSet = !!el.setAttribute; // In IE some elements don't have setAttribute + for(var attr in o){ + if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || attr == "style" || typeof o[attr] == "function") continue; + if(attr=="cls"){ + el.className = o["cls"]; + }else{ + if(useSet) el.setAttribute(attr, o[attr]); + else el[attr] = o[attr]; + } + } + wu.applyStyles(el, o['style']); + var cn = o['children'] || o['cn']; + if(cn){ + createDom(cn, el); + } else if(o['html']){ + el.innerHTML = o['html']; + } + } + if(parentNode){ + parentNode.appendChild(el); + } + return el; +}; + +// Mozilla 1.8 has support for indexOf, lastIndexOf, forEach, filter, map, some, every +// http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:lastIndexOf +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function (obj, fromIndex) { + if (fromIndex == null) { + fromIndex = 0; + } else if (fromIndex < 0) { + fromIndex = Math.max(0, this.length + fromIndex); + } + for (var i = fromIndex; i < this.length; i++) { + if (this[i] === obj) + return i; + } + return -1; + }; +} + +String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g,""); +} + +// wu-repeatable.js + +wu.repeatable = { + counter:0 +}; + +wu.repeatable.addChoice = function(e) { + + wu.log(e); + wu.repeatable.counter++; + + // TODO: get the spec attribute, generate name, and create dom + // render_input ensures that SPEC["text"] is included + // (via a call to ::xo::formfield::text->require_spec or some such) + // Example of spec attribute: + // {'tag':'input','cls':'wu-repeatable-choice','type':'text','name':'some_id:'}; + var json = e.getAttribute('spec'); + var spec = eval("(" + json + ')'); + + // use negative count for ids to avoid conflicts with + // code generated on the server-side + spec['id'] = spec['name'] + ':-' + wu.repeatable.counter; + + var d = document; + var el = e.parentNode; + var newNode=createDom({'tag':'div', + 'children':[{'tag':'div','cls':'wu-repeatable-arrows', + 'children':[{'tag':'a','cls':'wu-repeatable-action','href':'#','onclick':'return wu.repeatable.moveUp(this)','html':''}]}, + spec, + {'tag':'a','cls':'fl','href':'#','onclick':'return wu.repeatable.delChoice(this)','html':'[x]'} + ]}); + + el.insertBefore(newNode,e); + return false; +}; + +wu.repeatable.delChoice = function(e) { + var el = e.parentNode.parentNode; + el.removeChild(e.parentNode); + wu.repeatable.update(); + return false; +}; + +wu.repeatable.update = function() {} \ No newline at end of file Index: openacs-4/packages/xowiki/www/resources/xinha-inplace.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/xinha-inplace.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/xinha-inplace.js 13 Sep 2012 16:05:42 -0000 1.4 @@ -0,0 +1,171 @@ +/* + * A simple inplace editor vor xinha to be used within OpenACS + * (providing the basic configuration). The inplace editor is to be + * used within forms to edit elements with the style 'xinha' and pass + * the content via a hidden variable back to the application. The + * editor was desinged to be used with xowiki and xowiki content flow. + * + * Gustaf Neumann + */ + +// provide a namespace 'xinha' +if (!window.xinha) { + window.xinha = {}; +} + +xinha.inplace = { + hoverColor : '#BBffBB', + saveButtonLabel : 'Save', + cancelButtonLabel : 'Cancel', + backgroundColor : null, + xinha_editors : [] +}; + +/* + * Initialize the inplace editor. This means essentially to setup all + * handlers for elemets of CSS class 'xinha' and 'xinhaupdate'. + */ +xinha.inplace.init = function() { + var editElements = []; + + // In case the iteration over all nodes turns out to be a problem, + // we should switch to YUI to do so.... + + var elements = document.getElementsByTagName('*'); + var nrElements = elements.length; + + for (i = 0, j = 0; i < nrElements; i++) { + if (elements[i].className == 'xinha') { + // For all nodes of CSS class 'xinha', we register the event + // handlers. + editElements.push(this.setEventHandler(elements[i])); + } else if (elements[i].className == 'xinhaupdate') { + // For all nodes of CSS class 'xinhaupdate' (usually only a + // single button) we register the finish handler to copy the + // content to the hidden fields. + elements[i].onclick = function() { + xinha.inplace.finish(); + } + } + } +}; + +/* + * Iterate over all nodes and copy the content of the elements of + * class 'xinha' to the corresponding hidden fields in the form; the + * correspondance happens via a naming convention of IDs. + * + */ +xinha.inplace.finish = function() { +// nothing to do for now +}; + +/* + * Define standard handlers (for 'xinha' elements) + * - onmouseover + * - onmouseout + * - ondblclick + */ +xinha.inplace.setEventHandler = function(element) { + element.onmouseover = function() { + xinha.inplace.backgroundColor = this.style.backgroundColor; + this.style.backgroundColor = xinha.inplace.hoverColor; + } + element.onmouseout = function() {this.style.backgroundColor = xinha.inplace.backgroundColor;} + element.ondblclick = function() {xinha.inplace.openEditor(this.id);} + return element; +}; + + +/* + * openEditor function: we define an inplace form with a textarea and a save + * and cancel button. The content of the textarea will be set to the + * content of the given element. On a save operation, this content of + * the element will be replaced by the content of the textarea. + */ +xinha.inplace.openEditor = function(editId) { + // Use id rather then element to make it easier to call this + // function for other contexts. + var element = document.getElementById(editId); + + // Use three IDs to locate later the editForm, the textArea and the + // content: + var editFormId = element.id + '__FORM__'; + var textAreaId = element.id + '__TEXTAREA__'; + var contentId = element.id + '__CONTENT__'; + + // Create editForm and form elements + var editForm = document.createElement('form'); + var textArea = document.createElement('textarea'); + var saveButton = document.createElement('input'); + var cancelButton = document.createElement('input'); + + var content = document.getElementById(contentId); + + // configure textArea, editForm and buttons + textArea.id = textAreaId; + textArea.value = content.innerHTML; + textArea.style.width = element.style.width ? element.style.width : element.offsetWidth + 'px'; + textArea.style.height = element.style.height ? element.style.height : (element.offsetHeight + 25) + 'px'; + textArea.focus(); + + editForm.id = editFormId; + editForm.onsubmit = function() { + xinha.inplace.closeEditor(this.id, element, 1, this.getElementsByTagName('textarea')[0].value); + return false; + }; + + saveButton.type = 'submit'; + saveButton.value = this.saveButtonLabel; + + cancelButton.type = 'button'; + cancelButton.value = this.cancelButtonLabel; + cancelButton.onclick = function() { + xinha.inplace.closeEditor(editFormId, element, 0, ''); + return false; + }; + + // insert the created nodes + editForm.appendChild(textArea); + editForm.appendChild(saveButton); + editForm.appendChild(cancelButton); + element.parentNode.insertBefore(editForm,element); + + // make the original element invisible + element.style.display = 'none'; + + // configure xinha + + // use globally provided xinha_config, provided by OpenACS, and configure a few parameter + xinha_config.statusBar = false; + xinha_config.height = 'auto'; //textArea.style.height; + xinha_config.sizeIncludesBars = false; + xinha_config.sizeIncludesPanels = false; + + // start xinha + this.xinha_editors.push(textAreaId); + this.xinha_editors = Xinha.makeEditors(this.xinha_editors, xinha_config, xinha_plugins); + Xinha.startEditors(this.xinha_editors); + this.xinha_editors = []; +}; + +/* + * closeEditor is the inverse function of openEditor: it updates + * optionally the base element and removes the inplace editor + */ +xinha.inplace.closeEditor = function(id, element, replace, htmlText) { + var editForm = document.getElementById(id); + // update text of the div, + if (replace) { + var contentId = element.id + "__CONTENT__"; + var hiddenId = element.id + "__HIDDEN__"; + var content = document.getElementById(contentId); + var hidden = document.getElementById(hiddenId); + content.innerHTML = htmlText; + hidden.value = htmlText; + } + // make div visible and remove editor + element.style.display = 'block'; + this.setEventHandler(element); + editForm.parentNode.removeChild(editForm); +}; 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 13 Sep 2012 16:05:42 -0000 1.59 @@ -0,0 +1,515 @@ +/* for mini-calendar in weblog */ +#at-a-glance td.inactive {color: #999999; background:#FFF;} +/*#at-a-glance :active {background: #999999;}*/ +/*#at-a-glance td.active {color: #003b53;}*/ +/*#at-a-glance td.today {color: #003b53;}*/ + +/* minimize damage of yui-skin-sam */ +#breadcrumbs, #alert-message {clear: both !important; text-align: left !important;} + +/* useful helper */ +.visual-clear {clear: both; display: block;} + +/* menues and such */ +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; +} + +div.xowiki-content { + font: 10pt Verdana, Arial, Helvetica, sans-serif; +} + +/* appearance of link types */ +div.xowiki-content span.external { + background: transparent url(/resources/xowiki/sprite16.png) -4px -264px no-repeat; + padding-right: 10px; + text-decoration: none; /* added here for   required in IE */ +} +div.xowiki-content span.file { + background: transparent url(/resources/xowiki/sprite16.png) -4px -286px no-repeat; + padding-right: 10px; + text-decoration: none; +} +div.xowiki-content a.glossary { + background: url(/resources/xowiki/glossary.gif) right center no-repeat; + padding-right: 14px; +} + +/* appearance of item-buttons */ +/* +div.xowiki-content a.edit-item-button { + background: url(/resources/acs-subsite/Edit16.gif) right center no-repeat; + padding-right: 16px; +} +div.xowiki-content a.delete-item-button { + background: url(/resources/acs-subsite/Delete16.gif) right center no-repeat; + padding-right: 16px; +} +div.xowiki-content a.view-item-button { + background: url(/resources/acs-subsite/Zoom16.gif) right center no-repeat; + padding-right: 16px; +} +div.xowiki-content a.create-item-button { + background: url( /resources/acs-subsite/Add16.gif) right center no-repeat; + padding-right: 16px; +} +div.xowiki-content a.copy-item-button { + background: url(/resources/acs-subsite/Copy16.gif) right center no-repeat; + padding-right: 16px; +} +div.xowiki-content a.copy-item-button { + background: url(/resources/acs-subsite/Copy16.gif) right center no-repeat; + padding-right: 16px; +} +*/ +/* positions + Add16 -2,-1 + Copy16 -2,-22 + Delete16 -2,-44 + Edit16 -2,-66 + New16 -2,-88 + Open16 -2,-110 + Preferences16 -2,-132 + Properties16 -2,-154 + Zoom16 -2,-176 + ZoomIn16 -2,-198 + ZoomOut16 -2,-220 + email.png -2,-242 + external.png -2,-264 + file.png -2,-286 + transparent.png -1,-308 +*/ +div.xowiki-content a.edit-item-button { + background: transparent url(/resources/xowiki/sprite16.png) -2px -66px no-repeat; + padding-right: 16px; + text-decoration: none; +} +div.xowiki-content a.delete-item-button { + background: transparent url(/resources/xowiki/sprite16.png) -2px -44px no-repeat; + padding-right: 16px; + text-decoration: none; +} +div.xowiki-content a.view-item-button { + background: transparent url(/resources/xowiki/sprite16.png) -2px -176px no-repeat; + padding-right: 16px; + text-decoration: none; +} +div.xowiki-content a.create-item-button { + background: transparent url(/resources/xowiki/sprite16.png) -2px -1px no-repeat; + padding-right: 16px; + text-decoration: none; +} +div.xowiki-content a.copy-item-button { + background: transparent url(/resources/xowiki/sprite16.png) -2px -22px no-repeat; + padding-right: 16px; + text-decoration: none; + width: 16px; height: 16px; +} +div.xowiki-content a.add-item-button { + background: transparent url(/resources/xowiki/sprite16.png) -2px -1px no-repeat; + padding-right: 16px; + text-decoration: none; +} +div.xowiki-content a.notification-image-button { + background: transparent url(/resources/xowiki/sprite16.png) -4px -248px no-repeat; /* 6px more */ + padding-right: 16px; + text-decoration: none; +} + +/* headings */ +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 {background: #FFF; color: red; font-weight: bold;} +div.xowiki-content .hr { + height: 1px; border: none; + background-color: silver; +} + +/* region handling */ +#main div.column {text-align: left; margin-bottom: 1em;} +#content {float: left; width: 70%;} + +#bookNavBar { top: 0px; height: 2px; overflow:hidden; background-color: #859db8;float:left;} + +#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: #717171;} +#messages .user {font-size: 80%; font-weight: bold; color: #717171;} +#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;background: #F60;} +a:visited.rss {color: #FFF;background: #F60;} +a:link.rss {color: #FFF;background: #F60;} + +div.rightbox {float:right; right: 1em; clear: right; font-size: 75%; padding: 5px; + border:dotted; border-width:1px;background: #f8f8f8; +} +div.presence div.title {font-size: 90%; margin-bottom: 0px; + border-bottom: solid silver 1px; color: #222222; +} + +div.xowiki-content a.missing { + color: red; + text-decoration: none; +} +div.xowiki-content a.missing:hover { + text-decoration: underline; + background: none; +} + +div.xowiki-content pre, .code { + font-family: "Courier", monospace; +} + +.string { + color: #7D615B; +} +div.xowiki-content pre, div.code { + font-size: 80%; + 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%;} + + +div.news-item {clear: both; border: 1px solid #a9a9a9; padding: 15px 15px; margin: 10px 10px; background: #f8f8f8;} +div.news-item .item-header {margin-bottom: 12px;} +div.news-item h2 {display: inline; font-weight: bolder;} +/*div.xowiki-content div.news-item .item-footer {margin-left: 20px; margin-right: 20px;}*/ + +div.xowiki-content .item-footer { + clear: both; + text-align: left; font-size: 85%; + margin-left: 10px; margin-right: 10px; margin-top: 5px; + padding-top: 5px; + border-top: 1px solid; border-color: #c8c8c8; + color: #555555; +} +div.xowiki-content .content-chunk-footer {clear: both;} +div.xowiki-content .image-button img {border: 0px;} + +div.book-navigation img {border: 0px;} + +/* Make help_text nicer. Would like to make the font-sizer smaller as well, + but this does not fit together with the openacs form styles, using + magin-left as 17em +*/ +div.xowiki-content .margin-form .form-button, .margin-form div.form-help-text { + color: #7A7A78; +} + +/* Make the weblog-mini-calendar slightly nicer by alignig its columns + and extending the width as it was with styles before zen. +*/ +.weblog-mini-calendar {width: 100%;} +.weblog-mini-calendar table {width: 100%;} +/* header of the calendar */ +.weblog-mini-calendar .back { text-align: left; } +.weblog-mini-calendar .current_view { text-align: center; } +.weblog-mini-calendar .forward { text-align: right; } +.weblog-mini-calendar .forward, .weblog-mini-calendar .back { + width: 20px; +} +/* the body-part of the calendar */ +.weblog-mini-calendar #at-a-glance td { text-align: right; padding-right: 3px;} +.weblog-mini-calendar #at-a-glance td.active:hover { text-align: right; } + +/* includelet "recent" */ +div.recent div.portlet .list-table td.list { + padding: 8px 4px; +} + +/* includelet "categories-recent" */ +div.categories-recent .date { + font-size: 85%; + font-weight: bold; + color: #9a9a9b; +} + +/* inherited markup */ +div.xowiki-content a.inherited { + background: url(/resources/acs-subsite/arrow-down.gif) right center no-repeat; + padding-right: 14px; + font-size: 65%; +} + + +div.xowiki-content fieldset.compound-field { + margin: 0px; padding: 0px; +} + +/* for yui dnd stuff */ +div.xowiki-content div.workarea { padding-right: 10px; float:left; } +div.xowiki-content div.workarea h3 { margin-top: 0px; margin-bottom: 0.5ex;} + +div.xowiki-content ul.region { + border: 1px solid gray; + position: relative; + width: 300px; + list-style: none; + margin:0; + padding:0; + /* + The bottom padding provides the cushion that makes the empty + list targetable. Alternatively, we could leave the padding + off by default, adding it when we detect that the list is empty. + */ + padding-bottom:3ex; +} + +div.xowiki-content ul.region li { + margin: 1px; + cursor: move; +} + +div.xowiki-content li.candidates { + background-color: #D1E6EC; + border:1px solid #7EA6B2; +} + +div.xowiki-content li.selection { + background-color: #D8D4E2; + border:1px solid #6B4C86; +} + +div.xowiki-content div.book ul.page_order_region { + border: 0px solid gray; + width: 100%; + list-style: none; + margin: 10px; + padding:0; + /* + The bottom padding provides the cushion that makes the empty + list targetable. Alternatively, we could leave the padding + off by default, adding it when we detect that the list is empty. + */ + padding-bottom:3ex; +} +div.xowiki-content div.book ul.page_order_region_no_target { + border: 0px solid gray; + width: 100%; + list-style: none; + margin: 10px; + padding: 0; +} + +div.xowiki-content div.toc ul.page_order_region_no_target { + list-style: none; + margin: 0px 1em; + padding: 0; +} +div.xowiki-content div.toc ul.page_order_region { + list-style: none; + margin: 0px 1em; + padding:0; + /* + The bottom padding provides the cushion that makes the empty + list targetable. Alternatively, we could leave the padding + off by default, adding it when we detect that the list is empty. + */ + padding-bottom:3ex; +} + +/* + Handling hidden field-sets: + + child selectors are apparently not supported by IE 5 and 6, + but the content is usable in IE anyhow; maybe we have to use the + parent-node hack + + background-color: expression(/currentpage/.test(this.parentNode.className)? "#eff" : "#ef0"); + + or the nesting hack + + div * { margin-left: 20px; } + div * * { margin-left: 0} + + as well... +*/ +div.xowiki-content div.hidden-field-set > div.form-label { + display: none; +} +div.xowiki-content div.hidden-field-set > div.form-widget { + margin-left: 0px; +} +div.xowiki-content div.hidden-field-set > div.form-widget > .compound-field { + border: 0px; +} + + +div.xowiki-content .margin-form fieldset .form-item-wrapper { + padding: 0px 0px 0px 0px; +} + +/* folder menu placement */ + +div.xowiki-content div.folders { + float:left; width: 200px; + font-size: 90%; +} +div.xowiki-content .content-with-folders { + float: left; width: 70%; +} +div.xowiki-content .content-with-folders div.form-label { + width: 9em; +} +div.xowiki-content .content-with-folders div.form-widget, +div.xowiki-content .content-with-folders .form-help-text, +div.xowiki-content .content-with-folders .form-button, +div.xowiki-content .content-with-folders .form-widget-error, +div.xowiki-content .content-with-folders .form-error { + margin-left: 10em; +} + +div.xowiki-content #menubar a.disabled { + color: #A0A0A0; + /* or maybe display none */ +} + + +/* mc stuff */ +div.xowiki-content table.mchoice td.selection { + width: 25px; + padding: 0px 5px 0px 25px; +} +div.xowiki-content form.feedback td.selection { + width: 25px; + padding: 0px 5px 0px 25px; +} + +/* linear forum stuff */ +div.xowiki-content { + text-align: left; +} +div.xowiki-content .forum .question { +} +div.xowiki-content .forum .responses { +} + +div.xowiki-content .forum .cite.photo { + float: left; + width: 190px; +} +div.xowiki-content .forum .cite { + float: left; + width: 100px; +} +div.xowiki-content .forum .question-text { + margin-left: 200px; +} +div.xowiki-content .forum .question-text.nophoto { + margin-left: 110px; +} +div.xowiki-content .forum .cite .photo { + float: right; + margin-left: 4px; +} +div.xowiki-content .forum .cite p.author { + margin-bottom: 0px; + text-align: right; +} +div.xowiki-content .forum .cite p.date { + text-align: right; + font-size: 85%; + color: #777777; + +} Index: openacs-4/packages/xowiki/www/resources/yui-form-field-validate.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/yui-form-field-validate.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/yui-form-field-validate.js 13 Sep 2012 16:05:42 -0000 1.4 @@ -0,0 +1,109 @@ +/* + * A simple form field validator based on YUI + * + * Gustaf Neumann fecit Nov 2009 + */ + +YAHOO.namespace('xo_form_field_validate'); + +YAHOO.xo_form_field_validate = { + current_url: "", + currentID: "", + ids: new Array(), + + init: function() { + // console.log("init"); + var ids = YAHOO.xo_form_field_validate.ids; + for (var i=0; i 10) { + // there must have happened a redirect + console.info(o); + alert("Refresh your login and redo update"); + //window.location.href = this.package_url + // + "?refresh-login&return_url=" + // + escape(this.current_url); + } else { + var inputID = this.currentID; + var errorEl = YAHOO.util.Dom.get(inputID + "-error"); + var inputEl = YAHOO.util.Dom.get(inputID); + if (errorEl != undefined) { + errorEl.parentNode.removeChild(errorEl); + } + if (YAHOO.util.Dom.hasClass(inputEl.parentNode,"form-widget-error") && + inputEl.parentNode.class != "form-widget-error") { + YAHOO.util.Dom.replaceClass(inputEl.parentNode,"form-widget-error","form-widget"); + } else { + YAHOO.util.Dom.removeClass(inputEl.parentNode,"form-widget-error"); + } + } + }, + + scope: YAHOO.xo_form_field_validate + } + + var url = window.location.href.replace(/[?].*/,"") + '?m=validate-attribute'; + var post_query = e.target.name + '=' + escape(e.target.value); + YAHOO.xo_form_field_validate.current_url = url + '&' + post_query; + YAHOO.xo_form_field_validate.currentID = e.target.id; + //console.log(url); + //console.log(post_query); + YAHOO.util.Connect.asyncRequest('POST', url, this.callback, post_query); + return 1; + } + +}; + +YAHOO.util.Event.onDOMReady(YAHOO.xo_form_field_validate.init); + Index: openacs-4/packages/xowiki/www/resources/yui-page-order-region.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/yui-page-order-region.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/yui-page-order-region.js 13 Sep 2012 16:05:42 -0000 1.6 @@ -0,0 +1,298 @@ +/* + * A simple drag and drop handler based on YUI for lists to be used + * e.g. with the book includelet. + * + * The handler knows about the two CSS + * classes page_order_region and page_order_region_no_target, where + * page_order_regions are used for drag and drop. The handler + * maintains client data (cd) associated with the list items, which + * has to be initialized by the application. + * + * Note: it might not be a good idea to use this with large list + * structures asi it is, since the drag-proxy might be quite large. + * + * Example usage with the book includelet: + * + * {{book -menu_buttons "edit create delete" -allow_reorder 2}} + * + * which means: only support drag&drop starting with the 2nd level + * + * Gustaf Neumann fecit April 2009 + */ + +YAHOO.namespace('xo_page_order_region'); + +YAHOO.xo_page_order_region.DragnDrop = function() { + + var Dom = YAHOO.util.Dom; + var Event = YAHOO.util.Event; + var DDM = YAHOO.util.DragDropMgr; + +YAHOO.xo_page_order_region.DDApp = { + with_DDTarget: 1, + + package_url: "", + cd: new Array(), + source_region: new Array(), + level: new Array(), + highest_level: 0, + highest_region: 0, + + init: function() { + // Ok, now we use standard drag and drop, modeled around the + // example from YUI dnd. We have now two HTML lists to be + // handled as regions for drag and drop. + //var regions = YAHOO.util.Selector.query('ul.page_order_region'); + //var regions = YAHOO.util.Selector.query('ul.page_order_region, ul.page_order_region_no_target'); + var regions = YAHOO.util.Selector.query('ul.page_order_region'); + for (var i = 0; i < regions.length; i++) { + + if (this.with_DDTarget) { + new YAHOO.util.DDTarget(regions[i].id); + } + + // compute the order of items per region + var order = ""; + var items = regions[i].childNodes; + + for (var j = 0; j < items.length; j++) { + if (items[j].nodeName != 'LI') {continue;} + var iid = items[j].id; + // add the DDList only for list items in UL with class + // "page_order_region" + if (YAHOO.util.Dom.hasClass(regions[i],"page_order_region")) { + new YAHOO.xo_page_order_region.DDList(iid); + } + + // console.log(iid + " => " + this.cd[iid] ); + order += this.cd[iid] + " "; + // Keep as well the source regions + this.source_region[iid] = regions[i]; + } + // finally, remeber the level and store the original order + this.level[regions[i].id] = this.cd[iid].split(/[.]/g).length; + this.cd[regions[i].id] = order; + //console.log("initial region: " + regions[i].id + " => " + order); + } + }, + + report_level: function(id, e) { + if (this.level[id] != undefined) { + // Keep the highest level in case we drop on nested targets + if (this.highest_level < this.level[id]) { + this.highest_level = this.level[id]; + this.highest_region = id; + } + } + }, + + finish: function(e) { + + //console.log("finish " + this.highest_region); + + // if we have no highest_region, the drop was not on a drop target + if (this.highest_region == 0) { + // get the ul via the provided element. This might not be the + // list you are expecting, if there are nested lists. + var ul = document.getElementById(e.id).parentNode; + //console.info(ul); + } else { + // The variable highest_region is only used, if ul's are + // defined as DDTargets + var ul = document.getElementById(this.highest_region); + } + + // console.log(this.cd[e.id] + " landed in region "+ ul.id + " => " + this.cd[ul.id]); + + // Process childNodes of the ul simply to avoid to include + // nested items + var order = ""; + var items = ul.childNodes; + + for (var j = 0; j < items.length; j++) { + if (items[j].nodeName != 'LI') {continue;} + var iid = items[j].id; + order += this.cd[iid] + " "; + //console.log(iid + " => " + this.cd[iid]); + } + + // console.log(this.cd[ul.id] + " => " + order + " => " + this.cd[this.source_region[e.id].id]); + + if (this.package_url != '' && order != '') { + this.callback = { + success: function(o) { + //console.info(o); There seems no way to handle redirects + // (301 or 302) in the asyncrequest. Since we know valid + // results (just the "OK"), everything else must be a + // redirect. We could be brutal and display the returned + // page, but not sure, if this would be desireable either. + if (o.getResponseHeader["Content-Length"] > 10) { + // there must have happened a redirect + alert("Refresh your login and redo update"); + window.location.href = this.package_url + + "?refresh-login&return_url=" + + escape(window.location.href); + } else { + window.location.reload(); + } + + }, + scope: this + } + //return; + YAHOO.util.Connect.asyncRequest('POST', this.package_url, this.callback, + 'change-page-order=1' + + '&from=' + escape(this.cd[ul.id]) + + '&to=' + escape(order) + + '&clean=' + escape(this.cd[this.source_region[e.id].id])); + } + } + +}; + +///////////////////////////////////////////////////////////////////////////// +// custom drag and drop implementation +////////////////////////////////////////////////////////////////////////////// + +YAHOO.xo_page_order_region.DDList = function(id, sGroup, config) { + + YAHOO.xo_page_order_region.DDList.superclass.constructor.call(this, id, sGroup, config); + + var el = this.getDragEl(); + Dom.setStyle(el, "opacity", 0.67); // The proxy is slightly transparent + + this.goingUp = false; + this.lastY = 0; +}; + +YAHOO.extend(YAHOO.xo_page_order_region.DDList, YAHOO.util.DDProxy, { + + startDrag: function(x, y) { + + // make the proxy look like the source element + var dragEl = this.getDragEl(); + var clickEl = this.getEl(); + + Dom.setStyle(clickEl, "visibility", "hidden"); + dragEl.innerHTML = clickEl.innerHTML; + + Dom.setStyle(dragEl, "color", Dom.getStyle(clickEl, "color")); + Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor")); + Dom.setStyle(dragEl, "border", "2px solid gray"); + + // make sure, this is always initialized + YAHOO.xo_page_order_region.DDApp.highest_region = 0; + }, + + endDrag: function(e) { + //console.log("endDrag"); + var srcEl = this.getEl(); + var proxy = this.getDragEl(); + + // Show the proxy element and animate it to the src element's location + Dom.setStyle(proxy, "visibility", ""); + var a = new YAHOO.util.Motion( + proxy, { + points: { + to: Dom.getXY(srcEl) + } + }, + 0.2, + YAHOO.util.Easing.easeOut + ) + var proxyid = proxy.id; + var thisid = this.id; + + // Hide the proxy and show the source element when finished with the animation + a.onComplete.subscribe(function() { + Dom.setStyle(proxyid, "visibility", "hidden"); + Dom.setStyle(thisid, "visibility", ""); + }); + a.animate(); + YAHOO.xo_page_order_region.DDApp.finish(this); + }, + + onDragDrop: function(e, id) { + //console.log("onDragDrop"); + // If there is one drop interaction, the li was dropped either on the list, + // or it was dropped on the current location of the source element. + if (DDM.interactionInfo.drop.length === 1) { + + // The position of the cursor at the time of the drop (YAHOO.util.Point) + var pt = DDM.interactionInfo.point; + + // The region occupied by the source element at the time of the drop + var region = DDM.interactionInfo.sourceRegion; + + // Check to see if we are over the source element's location. We will + // append to the bottom of the list once we are sure it was a drop in + // the negative space (the area of the list without any list items) + if (!region.intersect(pt)) { + var destEl = Dom.get(id); + var destDD = DDM.getDDById(id); + destEl.appendChild(this.getEl()); + destDD.isEmpty = false; + DDM.refreshCache(); + //console.log('no intersect'); + } else { + // console.log('intersect'); + } + } else { + // console.log('interactions l=' + DDM.interactionInfo.drop.length); + } + YAHOO.xo_page_order_region.DDApp.report_level(id, this); + }, + + onDrag: function(e) { + + // Keep track of the direction of the drag for use during onDragOver + var y = Event.getPageY(e); + + if (y < this.lastY) { + this.goingUp = true; + } else if (y > this.lastY) { + this.goingUp = false; + } + + this.lastY = y; + }, + + onDragEnter: function(e, id) { + var destEl = Dom.get(id); + var p = destEl.parentNode; + Dom.setStyle(p, "border", "1px dotted green"); + }, + + onDragOut: function(e, id) { + var destEl = Dom.get(id); + var p = destEl.parentNode; + Dom.setStyle(p, "border", "0px"); + }, + + onDragOver: function(e, id) { + + var srcEl = this.getEl(); + var destEl = Dom.get(id); + + // We are only concerned with list items, we ignore the dragover + // notifications for the list. + if (destEl.nodeName.toLowerCase() == "li") { + var orig_p = srcEl.parentNode; + var p = destEl.parentNode; + + if (this.goingUp) { + p.insertBefore(srcEl, destEl); // insert above + } else { + p.insertBefore(srcEl, destEl.nextSibling); // insert below + } + + DDM.refreshCache(); + } + } +}); + +Event.onDOMReady(YAHOO.xo_page_order_region.DDApp.init, YAHOO.xo_page_order_region.DDApp, true); +}; + +YAHOO.xo_page_order_region.DragnDrop(); + Index: openacs-4/packages/xowiki/www/resources/yui-selection-area.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/yui-selection-area.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/yui-selection-area.js 13 Sep 2012 16:05:42 -0000 1.3 @@ -0,0 +1,237 @@ +/* + * A simple drag and drop handler based on YUI for lists to be used + * e.g. with the the form-fields of type abstract_page (e.g. form_page + * or page) with mutliple entries. + * + * The handler knows about the CSS class textarea.selection, makes it + * invisible and replaces it by a list (selected items). It handles + * actually ULs of class region which are treated as candidates. The + * candidates list is build by the application. On drag and drop, this code + * maintains the entries in textarea. + * + * + * Gustaf Neumann fecit April 2009 + */ +YAHOO.namespace('xo_sel_area'); + +YAHOO.xo_sel_area.DragnDrop = function() { + + var Dom = YAHOO.util.Dom; + var Event = YAHOO.util.Event; + var DDM = YAHOO.util.DragDropMgr; + +YAHOO.xo_sel_area.DDApp = { + dict: new Array(), + values: new Array(), + + init: function() { + // console.log("init called"); + // console.info(this); + // + // Find all textareas which class selection (maybe further restrict in the future) + var textareas = YAHOO.util.Selector.query('textarea.selection'); + for (var i = 0; i < textareas.length; i++) { + var textarea = textareas[i]; + // We found such an textarea. The lines of the textarea are + // treated as the selected values (internal representations). + var items = textarea.value.split(/\n/g); + var selected_LIs = ""; + // For all these items, build an HTML list with the labels + // (external representations). + for (var j = 0; j < items.length; j++) { + var o = items[j]; + if (o == "") continue; + selected_LIs += "
    • " + this.dict[o] + "
    • \n"; + } + + // Map in the candidates the internal representation to an + // external one. + var candidates = document.getElementById(textarea.id + "_candidates"); + var items = candidates.getElementsByTagName("li"); + for (var j = 0; j < items.length; j++) { + items[j].innerHTML = this.dict[items[j].innerHTML]; + } + + // Insert the generated HTML list and hide the textarea + var html = "
        \n" + selected_LIs + "
      \n"; + textarea.style.display = "none"; + var div = document.createElement('div'); + div.innerHTML = html; + Dom.insertBefore(div,textarea); + //console.log(html); + } + + // Ok, now we use standard drag and drop, modeled around the + // example from YUI dnd. We have now two HTML lists to be + // handled as regions for drag and drop. + var regions = YAHOO.util.Selector.query('ul.region'); + for (var i = 0; i < regions.length; i++) { + new YAHOO.util.DDTarget(regions[i].id); + var items = regions[i].getElementsByTagName("li"); + for (var j = 0; j < items.length; j++) { + var id = regions[i].id + '__' + j; + // setting the ids (note: will overwrite prexising ids on dnd items) + items[j].id = id; + new YAHOO.xo_sel_area.DDList(id); + } + } + }, + + build_selection: function(id) { + // We get called with the id of the drop target (the list) + var selection_id; + if (id.match(/_selection$/)) { + selection_id = id.replace(/_selection$/,""); + } else { + selection_id = id.replace(/_candidates$/,""); + } + // console.log("selection_id " + selection_id); + + var textarea = document.getElementById(selection_id); + var selection_list = document.getElementById(selection_id + "_selection"); + var items = selection_list.getElementsByTagName("li"); + var values = ""; + for (var j = 0; j < items.length; j++) { + var item = items[j]; + if (this.values[item.innerHTML] == undefined ) { + console.log(" undefined : "+ item.innerHTML); + console.info(this); + console.info(YAHOO.xo_sel_area.DDApp); + for (var i = 0; i < this.values.length; i++) { + console.log(" defined : "+ this.values[i]); + } + } else { + values += this.values[item.innerHTML] + "\n"; + } + } + textarea.value = values; + }, + +}; + +///////////////////////////////////////////////////////////////////////////// +// custom drag and drop implementation +////////////////////////////////////////////////////////////////////////////// + +YAHOO.xo_sel_area.DDList = function(id, sGroup, config) { + + YAHOO.xo_sel_area.DDList.superclass.constructor.call(this, id, sGroup, config); + + var el = this.getDragEl(); + Dom.setStyle(el, "opacity", 0.67); // The proxy is slightly transparent + + this.goingUp = false; + this.lastY = 0; +}; + +YAHOO.extend(YAHOO.xo_sel_area.DDList, YAHOO.util.DDProxy, { + + startDrag: function(x, y) { + + // make the proxy look like the source element + var dragEl = this.getDragEl(); + var clickEl = this.getEl(); + Dom.setStyle(clickEl, "visibility", "hidden"); + + dragEl.innerHTML = clickEl.innerHTML; + + Dom.setStyle(dragEl, "color", Dom.getStyle(clickEl, "color")); + Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor")); + Dom.setStyle(dragEl, "border", "2px solid gray"); + }, + + endDrag: function(e) { + + var srcEl = this.getEl(); + var proxy = this.getDragEl(); + + // Show the proxy element and animate it to the src element's location + Dom.setStyle(proxy, "visibility", ""); + var a = new YAHOO.util.Motion( + proxy, { + points: { + to: Dom.getXY(srcEl) + } + }, + 0.2, + YAHOO.util.Easing.easeOut + ) + var proxyid = proxy.id; + var thisid = this.id; + + // Hide the proxy and show the source element when finished with the animation + a.onComplete.subscribe(function() { + Dom.setStyle(proxyid, "visibility", "hidden"); + Dom.setStyle(thisid, "visibility", ""); + }); + a.animate(); + }, + + onDragDrop: function(e, id) { + + // If there is one drop interaction, the li was dropped either on the list, + // or it was dropped on the current location of the source element. + if (DDM.interactionInfo.drop.length === 1) { + + // The position of the cursor at the time of the drop (YAHOO.util.Point) + var pt = DDM.interactionInfo.point; + + // The region occupied by the source element at the time of the drop + var region = DDM.interactionInfo.sourceRegion; + + // Check to see if we are over the source element's location. We will + // append to the bottom of the list once we are sure it was a drop in + // the negative space (the area of the list without any list items) + if (!region.intersect(pt)) { + var destEl = Dom.get(id); + var destDD = DDM.getDDById(id); + destEl.appendChild(this.getEl()); + destDD.isEmpty = false; + DDM.refreshCache(); + } + + } + YAHOO.xo_sel_area.DDApp.build_selection(id); + }, + + onDrag: function(e) { + + // Keep track of the direction of the drag for use during onDragOver + var y = Event.getPageY(e); + + if (y < this.lastY) { + this.goingUp = true; + } else if (y > this.lastY) { + this.goingUp = false; + } + + this.lastY = y; + }, + + onDragOver: function(e, id) { + + var srcEl = this.getEl(); + var destEl = Dom.get(id); + + // We are only concerned with list items, we ignore the dragover + // notifications for the list. + if (destEl.nodeName.toLowerCase() == "li") { + var orig_p = srcEl.parentNode; + var p = destEl.parentNode; + + if (this.goingUp) { + p.insertBefore(srcEl, destEl); // insert above + } else { + p.insertBefore(srcEl, destEl.nextSibling); // insert below + } + + DDM.refreshCache(); + } + } +}); + +Event.onDOMReady(YAHOO.xo_sel_area.DDApp.init, YAHOO.xo_sel_area.DDApp, true); +}; + +YAHOO.xo_sel_area.DragnDrop(); + 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 13 Sep 2012 16:05:42 -0000 1.3 @@ -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/ckeditor/CHANGES.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ckeditor/CHANGES.html,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ckeditor/CHANGES.html 13 Sep 2012 16:05:42 -0000 1.3 @@ -0,0 +1,1433 @@ + + + + + Changelog — CKEditor + + + + +

      + CKEditor Changelog +

      +

      + CKEditor 3.6.2

      +

      + New features:

      +
        +
      • #6089 : The editor is now enabled on iOS 5 (iPad and iPhone).
      • +
      • #7354 : It is now possible to exit from blockquotes by using the Enter key on empty paragraphs.
      • +
      • #7931 : The mode event now carries the previous editor mode.
      • +
      • #6161 : New autoGrow_onStartup configuration option.
      • +
      • #8052 : autogrow is now available as an editor command.
      • +
      • #3457 : It is now possible to edit the contents of <textarea> elements through the dialog window.
      • +
      • #8242 : The "»" character is now added to the Special Character dialog window.
      • +
      +

      + Fixed issues:

      +
        +
      • #8171, #8172 : Updated links to WebSpellChecker.net.
      • +
      • #8155 : Tooltips in the Special Character dialog window corrected.
      • +
      • #8163 : The name of the filebrowserWindowFeatures configuration setting corrected to match the documented name.
      • +
      • #8124 : The Style fields in Advanced dialog window tabs are now validated according to CSS style attribute syntax.
      • +
      • #8025 : The checkboxes in the Find and Replace dialog window are now part of a fieldset.
      • +
      • #7943 : CSS conflict no longer appears when the page styles set the float property of label elements.
      • +
      • #8016 : [WebKit] Flash content is not visible when previewing content.
      • +
      • #6908 : Text color should always be applied to the linked text.
      • +
      • #7619 : [IE] IFrame shim now consolidates the editor dialog window to avoid having it masked by embedded objects.
      • +
      • #7900 : [FF] Copy/Paste operations for table cells no longer break the Table Properties dialog window.
      • +
      • #7243 : Inline JavaScript events may become corrupted.
      • +
      • #7448 : List creation in RTL blocks is wrongly merged with the above LTR block.
      • +
      • #6957 : Highlighting of searched terms does not reach read-only blocks.
      • +
      • #7948 : Tooltips with information about correct length units are now displayed for the Width/Height fields of the Table Properties dialog window.
      • +
      • #6212 : [WebKit] Editor resize may scroll the host page.
      • +
      • #6540 : [Safari] Editor loses focus on resizing.
      • +
      • #7908 : [IE] Unlink command is sometimes missing from the context menu of a link.
      • +
      • #8159 : Editor fails to load if the browser has no default language set.
      • +
      • #7490 : [IE] Block format leaks to the next unselected line when enterMode is set to BR.
      • +
      • #8087 : Indenting list items may add redundant text direction attributes.
      • +
      • #6200 : Add styling for certain dialog window element types that miss focus outline (like checkbox).
      • +
      • #7894 : Fault tolerance when parsing a malformed link.
      • +
      • #8049 : Bullets/Numbers are invisible for list items with LTR text direction.
      • +
      • #8222 : [IE] Incorrect selection locking after opening a dialog window in some cases.
      • +
      • #7002 : [IE] Undo operation when a table is selected results in an error.
      • +
      • #8232 : [IE] Unable to apply inline style that starts at the end of a link text.
      • +
      • #7153 : Fail to load the source version of the editor after the window is loaded.
      • +
      • #8246 : Bad editing performance on certain document contents.
      • +
      • #7912 : Cursor trapped in an invisible element after pressing the Enter key.
      • +
      • #7645 : Full list or table deletion with the Backspace/Delete key.
      • +
      • #8050 : AutoGrow feature better fits the content styles.
      • +
      • #8349 : [IE9] Larger toolbar top offset on HTML5 pages.
      • +
      • #8352 : [IE9] Toolbar wrapping is incorrect.
      • +
      • #8080 : JavaScript error when inserting a new table row.
      • +
      • Updated the following language files:
          +
        • #8263 : Dutch;
        • +
        • #8238 : Estonian;
        • +
        • #8193 : Finnish;
        • +
        • German;
        • +
        • Hebrew;
        • +
        • #8179 : Hungarian;
        • +
        • #8128 : Italian;
        • +
        • #8371 : Lithuanian;
        • +
        • #8126, #8256 : Norwegian (Bokmal and Nynorsk);
        • +
        • #8356 : Persian;
        • +
        • Polish;
        • +
        • Portuguese (Brazil);
        • +
        • #8151, #8298 : Russian;
        • +
        • Spanish;
        • +
      • +
      +

      + CKEditor 3.6.1

      +

      + New features:

      +
        +
      • #4556 : Initial support for HTML5 elements.
      • +
      • #6492 : The Find/Replace dialog window will now be populated with text selected in the editor.
      • +
      • #7323 : New align property in dialog window UI elements for field alignment.
      • +
      • #6462 : A wider range of CSS length units (like pt and percentage) are now supported in related dialog window fields.
      • +
      • #7911 : New Remove Anchor option is now available in the context menu.
      • +
      • #7387 : Allow styleDefinition to be applied to a set of elements.
      • +
      • #4345 : A new langLoaded event added to CKEDITOR.editor in order to make it possible to perform "by code" language updates.
      • +
      • #7959 : The cursor will now blink in the first cell after a table is inserted.
      • +
      • #7885 : New editor::removeMenuItem API for removing plugin context menu items introduced.
      • +
      • #7991 : Introduce the controlStyle and inputStyle definitions to allow fine-grained controlling of dialog window element styles.
      • +
      +

      + Fixed issues:

      +
        +
      • #7914 : ATTENTION! The signature for the setReadOnly() function has been changed, reversing the meaning of the parameter to be passed to it. Please make sure to update your code when upgrading.
      • +
      • #7657 : Wrong margin mirroring when creating a list from RTL paragraphs.
      • +
      • #7620 : A glitch in list pasting from Microsoft Word caused by broken child references when filtering.
      • +
      • #7811 : [IE] Deleting table row throws a JavaScript error.
      • +
      • #6962 : Changed the CKEDITOR.CTRL, CKEDITOR.SHIFT and CKEDITOR.ALT constant values to avoid collision with any possible Unicode character.
      • +
      • #6263 : Some table cell context menu options may be incorrectly disabled.
      • +
      • #6247 : Focus is not restored properly after a drop-down menu is closed.
      • +
      • #7334 : [IE7] Indentation style does not apply to RTL lists.
      • +
      • #6845 : Spaces inside the URL field in the Link dialog window will now be removed.
      • +
      • #7840 : [IE] Opening the Table Properties dialog window via the context menu causes a JavaScript error.
      • +
      • #7733 : Flash movies inserted with the Flash Properties dialog window are not displaying properly when injected into the page.
      • +
      • #7837 : [IE<8] Inserting a page break results in an error.
      • +
      • #7804 : The HTML5 wbr tag is now recognized by the editor.
      • +
      • #7867 : The file browser for the background image in the Document Properties plugin dialog window does not work.
      • +
      • #7130 : The column resizer gripping area is invading adjacent table cells.
      • +
      • #7844 : [FF] Calling setData() on a hidden editor caused editor not to display.
      • +
      • #7860 : The BBCode plugin was stripping BBCode tags that were not implemented in the plugin, but from now on they will be handled as simple text.
      • +
      • #7321 : [IE6] Contents inside the RTL fields in dialog windows are overflowing.
      • +
      • #7323 : [IE Quirks] Some fields are not centered in the dialog window.
      • +
      • #5955 : Editor accessibility issue with JAWS when a drop-down menu is placed as the first item in the toolbar.
      • +
      • #6671 : [FF] Selection of an item from the Styles drop-down list is not refreshed after the style is removed.
      • +
      • #7879 : The Style and Height/Width fields of the Table Properties dialog window are not synchronized.
      • +
      • #7581 : [IE] The Enter key pressed at the end of a list item containing the start attribute crashes the browser.
      • +
      • #7266 : Dialog window fields that did not pass validation are now ARIA-compatible with aria-invalid.
      • +
      • #7742 : [WebKit] Indentation, alignment, and language direction are not applied on an empty document without the editor being in focus.
      • +
      • #7801 : [Opera] Pasted paragraphs now split partially selected blocks.
      • +
      • #6663 : Table caption that contains rich text is corrupted after an edit done with the Table Properties dialog window.
      • +
      • #7893 : [WebKit, Opera, IE<8] It is impossible to link to anchors in the document.
      • +
      • #7637 : Cursor position might in some cases cause problems after inserting a page break.
      • +
      • #5314 : The aria-selected attribute is not removed when toolbar drop-down menu items are deselected.
      • +
      • #7749 : Small check introduced to avoid issues with custom data processors and the insertHtml function.
      • +
      • #7269 : [WebKit] Paste from Word is including the full file:// URL path for anchor links.
      • +
      • #7584 : Start number of the List dialog window now works with numbered list items.
      • +
      • #6975 : [IE6, IE7] A definition list crashes Internet Explorer on HTML output.
      • +
      • #7841 : Deleting a column with a cell deleted in one of the rows does not work.
      • +
      • #7944 : The Enter key should not split or create new paragraphs inside caption elements.
      • +
      • #7639 : [IE9] Browser might crash when an object is selected in the document.
      • +
      • #7847 : [IE8] Inserting an image with non-secure source in a HTTPS page breaks the dialog window.
      • +
      • #7953 : [IE] Text selection lost after the browser context menu is opened.
      • +
      • #5239 : Inconsistent focus behavior after closing a toolbar drop-down menu.
      • +
      • #6470 : The Start attribute of a Numbered List is rendered incorrectly if the field is left empty.
      • +
      • #7324 : [IE6 Quirks] Context menus are not displayed correctly.
      • +
      • #7566 : BiDi: Increasing indentation of a list item changes the language direction.
      • +
      • #7839 : [IE] Pasting multi-level numbered lists from Microsoft Word does not work properly.
      • +
      • #188 : [IE] Object selection was making the toolbar inactive in some situations.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.6

      +

      + New features:

      +
        +
      • #7044 : New BBCode sample plugin that makes the editor output (one dialect of) BBCode format.
      • +
      • #5647 : Accessibility enhancements to the structure of the toolbar.
      • +
      • #5647 : The Kama skin now presents separators for the toolbar items, making it easier to group buttons and have a cleaner layout.
      • +
      • #5647 : Usability enhancements to keyboard navigation on the toolbar. The Tab key is now used to jump between toolbar groups, while the Arrow keys can be used to cycle within the group. The new toolbarGroupCycling setting can be used to change the Arrow keys behavior.
      • +
      • #1376 : It is now possible to put the editor in the "read-only" state, so that the users would not be able to introduce changes to the contents. Check out the new CKEDITOR.editor::setReadOnly method, the CKEDITOR.editor::readOnly property, the CKEDITOR.editor::readOnly event, and the readOnly setting.
      • +
      • #3582 : New presentation of anchor elements in the WYSIWYG mode.
      • +
      • #6737 : The Format drop-down list will now display the preview of its contents exactly as defined in their style configurations.
      • +
      • #6654 : A new autoParagraph configuration setting is added to disable the auto paragraphing feature.
      • +
      • #901 : New Stylesheet Parser (stylesheetparser) plugin that fills the Styles drop-down list based on the CSS classes available for the content. Check the new sample to learn how to use it.
      • +
      • #2988 : New Document Properties (docprops) plugin that sets the metadata of the page in the Full Page mode.
      • +
      • #7240 : New Developer Tools (devtools) plugin that shows information about dialog window UI elements to allow for easier customization.
      • +
      • #6841 : Pressing the Enter key at the end of a pre-formatted block will now exit from it.
      • +
      • #6850 : The About CKEditor dialog window now contains a link to CKEditor User's Guide.
      • +
      • #5745 : Extra configuration options for the iframeDialog can now be passed.
      • +
      • #6589 : The onDialogEvent function will now be used automatically in the iframeDialog contents if no callback is used on creation.
      • +
      • #7757 : Georgian localization added.
      • +
      +

      + Fixed issues:

      +
        +
      • #6774 : Internal styles are not included in the contents.css sample.
      • +
      • #6521 : Added sample for the TableResize plugin.
      • +
      • #6664 : Page break is sometimes merged into block-level elements.
      • +
      • #7594 : Toolbar keyboard navigation is not possible after recreating the editor.
      • +
      • #6657 : Allow to style the entire dialog window field when the input element is disabled.
      • +
      • Updated the following language files:
          +
        • Hebrew;
        • +
        • Polish;
        • +
      • +
      +

      + CKEditor 3.5.4

      +

      + Fixed issues:

      +
        +
      • Added protection against XSS attacks in PHP samples when displaying element names.
      • +
      • #7347 : The Enter key will no longer be caught by the dialog window covering the editor.
      • +
      • #6718 : Paste from Word command overrides the Force Paste as Plain Text configuration.
      • +
      • #6629 : Padding body is no longer needed when the last block is pre-formatted.
      • +
      • #4844 : [IE] Dialog windows fail to load if there are too many editor instances on the page.
      • +
      • #5788 : HTML parser trims empty spaces following <br> elements.
      • +
      • #7513 : Invalid markup could cause the editor to hang.
      • +
      • #6109 : Paste and Paste as Plain Text dialog windows now use the standard commitContent and setupContent methods.
      • +
      • #7588 : The editor code now has a protection system to avoid issues when including ckeditor.js more than once in the page.
      • +
      • #7322 : Text font plugin now recognizes font family names that contain quotes.
      • +
      • #7540 : Paste from Word introduces wrong spaces.
      • +
      • #7697 : Successive calls of the replace() method did not work after SCAYT context menu initialization.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.5.3

      +

      + New features:

      +
        +
      • #4890 : Added the possibility to edit the rel attribute for links.
      • +
      • #7004 : Allow loading plugin translations even if they are not present in the plugin definition.
      • +
      • #7315 : Firing the resize event on dialog window instances is now possible.
      • +
      • #7259 : Dialog window definition allows to specify initial width and height values.
      • +
      • #7131 : List item numbering is now supported on pasting from Microsoft Word.
      • +
      +

      + Fixed issues:

      +
        +
      • #1272 : [WebKit] It is now possible to apply styles to collapsed selections in Safari and Chrome.
      • +
      • #7054 : The tooltips for special characters are now lowercased, making them more readable.
      • +
      • #7102 : "Replace DIV" sample did not work when double-clicking inside the formatted text.
      • +
      • #7088 : Loading of plugins failed on new instances of the editor after the Insert Special Character dialog window was used.
      • +
      • #6215 : Removal of inline styles now also removes overrides.
      • +
      • #6144 : Rich text drop-down lists have wrong height when toolbar is wrapped.
      • +
      • #6387 : AutoGrow may cause an error when editor instance is destroyed too quickly after a height change.
      • +
      • #6901 : Mixed direction content was not properly respected in a shared toolbar setting.
      • +
      • #4809 : Table-related tags are output in wrong order.
      • +
      • #7092 : Corrupted toolbar button state for inline style after switching to Source.
      • +
      • #6921 : Pasted text marked by SCAYT in one language is not re-checked if another spellchecking language is selected in the editor.
      • +
      • #6614 : Enhancement of the resize handle in RTL.
      • +
      • #5924 : Flash plugin now recognizes Flash content without an embed tag.
      • +
      • #4475 : Protected source in attributes and inline CSS text is not handled correctly.
      • +
      • #6984 : [FF] Trailing line breaks are lost in ENTER_BR.
      • +
      • #6987 : [IE] Text selection lost when calling editor::insertHtml from a dialog window in some situations.
      • +
      • #6865 : BiDi mirroring does not work when a text direction change is done through a dialog window.
      • +
      • #6966 : [IE] Unintended paragraph is created in an empty document in enterMode set for BR and DIV.
      • +
      • #7084 : SCAYT dialog window is now working properly with more than one editor instance in a page.
      • +
      • #6662 : [FF] List structure pasting error caused by a regression from FF3.5.x is now fixed.
      • +
      • #7300 : Link dialog window now loads numeric values correctly.
      • +
      • #7330 : New list items no longer inherit the value attribute from their sibling.
      • +
      • #7293 : The "Automatic" color button is now presented correctly without focus inside the editor.
      • +
      • #7018 : [IE] Toolbar drop-down lists did not have a border around them.
      • +
      • #7073 : Image dialog window no longer allows zero height and width value to be entered.
      • +
      • #7316 : [FF] Clicking on "Paste" button incorrectly breaks the line at the cursor position.
      • +
      • #6751 : Inline whitespaces are incorrectly stripped when pasting from Word.
      • +
      • #6236 : [IE] Fixing malformed nested list structure which was introduced by the Backspace key.
      • +
      • #6649 : [IE] Selection of the full table sometimes does not work.
      • +
      • #6946 : HTML parser is now able to fix orphan list items.
      • +
      • #6861 : Indenting a list item should retain the text direction.
      • +
      • #6938 : Outdenting a list item should retain the text direction.
      • +
      • #6849 : Correct Enter key behavior on list item.
      • +
      • #7113 : [WebKit] Undesired document scroll on click after scrolling.
      • +
      • #6491 : Undesired Image dialog window dimension lock reset on URL change.
      • +
      • #7284 : [FF Quirks] Maximize now works correctly.
      • +
      • #6609 : [IE9] Browser in high contrast mode is not properly detected.
      • +
      • #7222 : [WebKit] Impossible to apply a single style to a collapsed selection without giving the editor focus.
      • +
      • #7180 : [IE9] When using Kama skin and RTL layout dialog window buttons were not being displayed correctly.
      • +
      • #7182 : [IE9] When using Office2003/v2 skin and RTL layout dialog window shadows were corrupted.
      • +
      • #6913 : Invalid escape sequence (\b) was used in the PHP integration.
      • +
      • #5757 : [IE6] Text was not wrapping in the accessibility instructions dialog window.
      • +
      • [6604] : Xml.js and Ajax.js are now available as plugins ('xml' and 'ajax').
      • +
      • #7304 : Microsoft Word cleanup function is not always invoked when clicking on the "Paste From Word" button.
      • +
      • #6658 : [IE] Pasting text from Microsoft Word with one or more tabs between list items was failing.
      • +
      • #7433 : [IE9] ENTER_BR at the end of a block breaks due to an IE9 regression.
      • +
      • #7432 : [WebKit] Unable to create a new list in an empty document.
      • +
      • #4880 : CKEditor changes tag style inside HTML comment with cke_protected.
      • +
      • #7023 : [IE] JavaScript error when a Selection Field is inserted into a page.
      • +
      • #7034 : Inserting special characters into styled text.
      • +
      • #7132 : Paste toolbar buttons are becoming disabled.
      • +
      • #7138 : The api.html sample in Opera does not work as expected.
      • +
      • #7160 : Cannot paste the form element on top of the page.
      • +
      • #7171 : Double-clicking an image in non-editable content opens the editing dialog window.
      • +
      • #7455 : Extra line break is added automatically to the preformatted element.
      • +
      • #7467 : [Firefox] Extra br element is added in a nested list.
      • +
      • Updated the following language files:
          +
        • #7124 : Czech;
        • +
        • #7126 : French;
        • +
        • #7140 : Catalan;
        • +
        • #7215 : Faroese;
        • +
        • #7177 : Finnish;
        • +
        • #7163 : Norwegian (no and nb);
        • +
        • #7219 : Swedish;
        • +
        • #7183 : Afrikaans;
        • +
        • Hebrew;
        • +
        • Spanish;
        • +
        • Polish;
        • +
        • German;
        • +
      • +
      +

      + CKEditor 3.5.2

      +

      + Fixed issues:

      +
        +
      • #7168 : [IE9] Destroying an editor instance throws an error.
      • +
      • #7169 : [IE9] Menu item has incorrect height.
      • +
      • #7178 : [IE9] Read-only attributes do not work in IE9.
      • +
      • #7181 : [IE9] Toolbar items are not aligned in v2 and Office2003 skins.
      • +
      • #7174 : [IE9] Elements path does not load correctly when the editor is switched back from Source to WYSIWYG.
      • +
      +

      + CKEditor 3.5.1

      +

      + New features:

      +
        +
      • #6107 : It is now possible to remove block styles using Styles and Paragraph Format drop-down lists.
      • +
      • #5590 : Remove Format command works in collapsed selections.
      • +
      • #5755 : The dialog_buttonsOrder option now works in Internet Explorer.
      • +
      • #6869 : The data-cke-nostyle attribute (which was introduced for escaping the element from been influenced by the style system since 3.5) is deprecated in favor of the new data-nostyle attribute.
      • +
      • Revised sample pages with code examples and clarifications.
      • +
      +

      + Fixed issues:

      +
        +
      • #5855 : Updating a link multiple times generates wrong href attribute.
      • +
      • #6166 : Error on Maximize command, when the toolbar button is not shown.
      • +
      • #6607 : Table cell "merge down" and "merge right" commands work only once.
      • +
      • #6228 : Merge down does not work, throwing a JavasSript error.
      • +
      • #6625 : BIDI: Mixed LTR/RTL direction causes incorrect behavior.
      • +
      • #6881 : IFrame capitalization is now consistent throughout labels.
      • +
      • #6686 : BIDI: [FF] When we apply explicit language direction to a numbered/bulleted list, the corresponding language direction toolbar icon is not highlighted.
      • +
      • #6566 : It is now possible to exit a blockquote using ENTER_BR.
      • +
      • #6868 : Partial (invalid) list structure crashes the editor on load.
      • +
      • #6804 : Buggy behavior when editing the legend element inside a fieldset.
      • +
      • #6724 : [IE7] Nested list display bug on empty list item.
      • +
      • #6715 : List items do not create paragraphs after the list placed in a table cell is removed.
      • +
      • #6695 : [Webkit] Display bug after the editor is restored from the full screen mode.
      • +
      • #6661 : [IE] Pre-formatted style does not preserve applied text direction.
      • +
      • #6655 : Using the editor resize grip causes small visual offsets.
      • +
      • #6604 : The div element should be used as a formatting block in ENTER_BR.
      • +
      • #6249 : BIDI: List item bullets are off viewport with RTL text direction.
      • +
      • #6610 : BIDI: ENTER_BR change direction in one line out of multiple.
      • +
      • #6872 : [IE] Link target field is not populated properly when no target is set.
      • +
      • #6880 : Samples: Added a user-friendly message for users on servers without PHP support.
      • +
      • #6628 : Setting config.enterMode from PHP fails.
      • +
      • #6278 : Comments were moved above the br tags.
      • +
      • #6687 : Empty tag should be removed in inline-style format.
      • +
      • #6645 : Allow to configure whether " (double quotes) characters should be encoded in the contents.
      • +
      • #6336 : IE: (double)clicking an input type="submit" button submitted the form.
      • +
      • #6646 : Context menu was not working for text inputs present in the initial content.
      • +
      • #6641 : Copying and pasting links inside the editor was not working.
      • +
      • #4208 : The disableObjectResizing setting now works in IE.
      • +
      • #6242 : [IE] Editing existing links with href of a relative path mangles containing text.
      • +
      • #5930 : [IE] Style definitions are no longer lowercased.
      • +
      • #5361 : Preview window's title should reflect the title tag in full page mode.
      • +
      • #5522 : [IE] In versions < 8 or compatibility mode, type="text" was missing in text fields.
      • +
      • #6126 : [IE] Avoid problems if there are two buttons named "submit".
      • +
      • #6791 : [IE7] Editor did not show up when the name of a replaced textarea matched the name of a meta tag in the page.
      • +
      • #5684 : [FF] When forcePasteAsPlainText is used, the cursor disappears after paste.
      • +
      • #6390 : Prevent toolbar dialog window buttons from being clicked twice.
      • +
      • #6684 : [Webkit] Toolbar buttons are not wrapping correctly when the editor is displayed inside a table.
      • +
      • #6703 : [IE] editor focus event not fired in an instance, when a dialog window closes.
      • +
      • #6873 : Difficult to drag the resize grip of the spell checker dialog window.
      • +
      • #6896 : [Webkit] Unable to paste into source area when the editor is maximized.
      • +
      • #6020 : The state of the Cut, Copy, and Paste toolbar now matches the state of the context menu buttons.
      • +
      • #5256 : JavaScript error thrown when percent (%) sign is used in image URL.
      • +
      • #6577 : [FF] Selection error when an element containing the editor instance is hidden.
      • +
      • #5500 : [IE] value attribute of text input dialog window field was missing.
      • +
      • #6665 : [IE] name field of Link dialog window was missing.
      • +
      • #6639 : Line-breaks inside pasted list item from Microsoft Word break the list structure.
      • +
      • #6909 : [IE] GIF icons of toolbar button from custom plugins are not diplayed in zoom level 100%.
      • +
      • #6860 : [FF] Double-clicking the placeholder element in order to open a Placeholder dialog window throws a JavaScript error.
      • +
      • #6630 : Empty pre elements are output differently in various browsers.
      • +
      • #6568 : Insert table row/column does not work with spanning.
      • +
      • #6735 : Inaccurate read-only selection detection.
      • +
      • #6728 : BIDI: Change direction does not work with list nested inside a blockquote.
      • +
      • #6432 : Inserting a table in place of a fully selected list results in a JavaScript error.
      • +
      • #6438 : [IE] Performance enhancement when typing inside an element with many child nodes.
      • +
      • #6970 : [IE] Dialog window shadows were presented inaccurately.
      • +
      • #6672 : [IE] Unnecessary br element is no longer inserted after a form.
      • +
      • #7087 : [FF] Sometimes it was not possible to move cursor out of link at the end of block.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.5

      +

      + New features:

      +
        +
      • #4090 : Full Adobe AIR support.
      • +
      • #5084 : Dialog windows are now resizable with a grip located in the footer.
      • +
      • #5755 : Introduced the dialog_buttonsOrder setting, making it possible to control the buttons order.
      • +
      • #4648 : Added the new iFrame plugin.
      • +
      • #6010 : The Automatic option of the font/background color panel now represents the real color.
      • +
      • #5654 : New "placeholder" plugin.
      • +
      • #6334 : CKEditor now uses HTML5's data-* attributes for its internal attributes.
      • +
      • #6103 : It's now possible to control the styling of inline read-only elements with the disableReadonlyStyling setting. It's also possible to avoid inline-styling any element by setting its "data-cke-nostyle" attribute to "1".
      • +
      • #5404 : fillEmptyBlocks configuration option of v2 is now available.
      • +
      • #5367 : New CKEDITOR.editor#insertText method (check api.html sample page for usages) is now provided to insert plain text into editor.
      • +
      • #5915 : New removeDialogTabs configuration option to hide certain dialog tabs.
      • +
      +

      + Fixed issues:

      +
        +
      • #4821 : Icons in the toolbar were distorted with IE and zoom != 100%.
      • +
      • #5587 : Visual improvements in dialogs, reinforce field label on separate line.
      • +
      • #4652 : Now it's able to disable editor context menu by simply removing the "contextmenu" plugin.
      • +
      • #5599 : Labels of "specialchar" dialog are now translated.
      • +
      • #6419 : [IE] List creation by merging problem.
      • +
      • #6502 : Removed IE6 image preloading, which was used to defect the duplicate request of background images.
      • +
      • #6822 : Added labels to fake objects.
      • +
      • #6898 : [IE6] Toolbar icons becomes invisible in RTL.
      • +
      • Updated the following language files:
          +
        • Hebrew
        • +
      • +
      +

      + CKEditor 3.4.3

      +

      + Fixed issues:

      +
        +
      • #6554 : [Webkit] cannot type after inserting Page Break.
      • +
      • #6569 : Indentation now complies with text direction of the only item.
      • +
      • #6579 : The jQuery adapter was not working properly and was turned on in incompatible environments.
      • +
      • #6644 : Restrict onmousedown handler to the toolbar area.
      • +
      • #6656 : Panelbutton's buttons became active when clicking on Source.
      • +
      • #6248 : Whitespaces (nbsp elements) were incorrectly added into empty table cells and list items.
      • +
      • #6575 : Tabs disappearing in Link dialog window after a specific sequence of actions.
      • +
      • #6510 : Margin mirroring does not respect style configuration.
      • +
      • #6471 : BIDI: Pressing Decrease Indent in an RTL bulleted list causes incorrect behaviour.
      • +
      • #6479 : BIDI: Language direction is not being preserved when pressing Enter after a Paragraph Format was applied.
      • +
      • #6670 : BIDI: Indent & List icons are not reversed when we apply RTL direction to a paragraph with any of Paragraph Formatting options.
      • +
      • #6640 : Floating panels are now being closed when switching modes.
      • +
      • #4790 : Remove list with multiple items in enterBr doesnot preserve line breaks.
      • +
      • #6297 : Floated inline elements are not taking part in behavior of blocks anymore.
      • +
      • #6171 : [Firefox] Opening rich content drop-down list scrolls host page to the top when editor has a vertical scrollbar.
      • +
      • #6330 : List markers from MS Word with Roman numbering are not preserved.
      • +
      • #6720 : Attribute protection might detect wrong elements.
      • +
      • #6580 : [IE9] Flash dialog window does not get filled up.
      • +
      • #6447 : Decreasing indentation of a list with indentClasses config does not work.
      • +
      • #5894 : Adding custom buttons at the bottom of a dialog window does not cause it to expand to include its contents.
      • +
      • #6513 : Wrong ARIA attributes created on list options of Styles drop-down list.
      • +
      • #6150 : [Safari] Color dialog window was broken.
      • +
      • #6747 : Full screen layout issue caused by page element focus outside editor.
      • +
      • #6779 : Clicking the body element on elements path turns the selection on and off immediately.
      • +
      • #6781 : [IE7] Dialog windows are broken with RTL, Office 2003 and v2 skins.
      • +
      • #6798 : [IE7] Dialog window buttons disappearing in RTL after dragging.
      • +
      • #6806 : [IE7] Dialog window buttons invisible on focus.
      • +
      • #6588 : Copy and paste adds <span> if SCAYT is enabled.
      • +
      • #6673 : IE Target combo for Image Link shown as blank even when we select <not set> as an option.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.4.2

      +

      + New features:

      +
        +
      • #5024 : Added a sample that shows how to output HTML that is valid for Flash.
      • +
      +

      + Fixed issues:

      +
        +
      • #5237 : English text in dialogs' title was flipped when using RTL language (office2003 and v2 skins).
      • +
      • #6289 : Deleting nested table removed the parent cell.
      • +
      • #6341 : The editor contents now have the text cursor.
      • +
      • #6153 : Chrome: tab focus is wrong.
      • +
      • #6261 : Focus and infinite loop between multiple editors.
      • +
      • #6170 : Dedicated class names are removed from floating panels when opening another panel.
      • +
      • #6339 : Autogrow plugin now doesn't work on maximized editors.
      • +
      • #6237 : BIDI: Applying same language direction to all paragraphs not working.
      • +
      • #6353 : [IE] Resize was broken with office2003 and v2 skins.
      • +
      • #6375 : Avoiding errors when hiding the editor after the blur event.
      • +
      • #6133 : Styled paragraphs result on buggy list creation.
      • +
      • #5074 : Link target is not removed when changing to popup.
      • +
      • #6408 : [IE] Autogrow now works correctly on Quirks.
      • +
      • #6420 : [IE] The table properties dialog now correctly retrieves the caption text.
      • +
      • #6141 : It was impossible to outdent a list when indentOffset was set to 0.
      • +
      • #6377 : FF width and height are not shown for smiley in Image properties dialog.
      • +
      • #5399 : Lists pasted from Word do not maintain their nesting.
      • +
      • #6225 : [FF] Cannot transform several lines to list with enterMode BR.
      • +
      • #6467 : [FF] It is now possible to disable the plugin command on "mode" event.
      • +
      • #6461 : Attributes are now being kept when changing block formatting.
      • +
      • #6226 : BIDI: Language direction applied to a Paragraph is removed when we apply one of Paragraph formatting options.
      • +
      • #5395 : [Opera] Native context menu incorrectly opened after Opera 10.2.
      • +
      • #6444 : [Opera] Close panels and dialogs don't return focus to wysiwyg frame.
      • +
      • #6332 : IE: V2 skin bottom dialog's border broken.
      • +
      • #5646 : Parser incorrectly removes inline element when there's only one comment node enclosed.
      • +
      • #6189 : Minor code size reduction.
      • +
      • #5045 : uiColor behaved wrong if multiple editors were used with period in their names.
      • +
      • #5766 : Config entry "ignoreEmptyParagraph" should only remove one single empty paragraph in document.
      • +
      • #5931 : Unable to apply inline style because of nested elements with same style name.
      • +
      • #6083 : Dialog close sometimes cause collapsed editor selection before the insertion.
      • +
      • #6253 : BIDI: creating a Numbered/Bulleted list causing improper behavior on bidi.
      • +
      • #4023 : [Opera] Maximize plugin.
      • +
      • #6403 : [Opera] Font name options are not correctly marked in dropdown list.
      • +
      • #4534 : [Opera] Arrow key to navigate through combo list has side effects of window scrolling.
      • +
      • #6534 : [Opera] Menu key brings up both CKEditor and browser context menu.
      • +
      • #6534 : [Opera] Menu key brings up both CKEditor and browser context menu.
      • +
      • #6416 : [IE9] Unable to make text selection with mouse in source area.
      • +
      • #6417 : [IE9] Context menu opens at the upper-left corner always.
      • +
      • #6501 : [IE9] Context menu item layout is broken.
      • +
      • #6099 : BIDI: when we apply explicit language direction to Numbered/Bulleted List the corresponding BIDI Tool bar icon is not highlighted in the Toolbar.
      • +
      • #6100 : BIDI: when we change Table language direction indentation of text in Table cells is not applied correctly.
      • +
      • #6376 : BIDI: buttons should not toggle the base language direction.
      • +
      • #6235 : BIDI: Applying direction to multi-paragraph selection within a div.
      • +
      • #6187 : [IE6] Multi-instance loading produces 404s on background images.
      • +
      • #5446 : Setting config.filebrowserImageBrowseUrl results in displaying also Browser Server on links.
      • +
      • #5626 : CKeditor 3.2.1 : html content attached makes ckeditor crash the browser FF/IE.
      • +
      • #6508 : BiDi: Margin mirroring logic doesn't honor CSS direction.
      • +
      • #6043 : BIDI: When we apply RTL direction to a right aligned Paragraph, Paragraph is not moved to the left & Alignment of Paragraph is not changed.
      • +
      • #6485 : BIDI: When direction is applied on partial selected list, the style is been incorrectly applied to the entire list.
      • +
      • #6087 : Cursor of input fields in dialog isn't visible in RTL.
      • +
      • #5595 : Extra leading spaces added in preformatted block.
      • +
      • #6094 : Match full word option doesn't stop on block boundaries.
      • +
      • #5730 : [Safari] Continual pastes (holding paste key) breaks document contents.
      • +
      • #5850 : [IE] Inline style misbehaviors at the beginning of numbered/bulleted list.
      • +
      • Updated the following language files:
          +
        • #6427 : Ukrainian;
        • +
        • #6464 : Finnish;
        • +
        • Hebrew;
        • +
      • +
      +

      + CKEditor 3.4.1

      +

      + New features:

      + +

      + Fixed issues:

      +
        +
      • #6027 : Modifying Table Properties by selecting more than one cell caused issues.
      • +
      • #6146 : IE: Floating panels were being opened in the wrong place in RTL pages with horizontal scrollbars.
      • +
      • #6055 : The timestamp is now added only once to each loaded file.
      • +
      • #6097 : The bookmarks now use the right name.
      • +
      • #5717 : Removed the scayt_contextMenuOntop setting and the SCAYT context menu options are always on top.
      • +
      • #5956 : [FF] It was impossible to create an editor inside an hidden container.
      • +
      • #5753 : It was impossible to have a default value for the name field in the select dialog.
      • +
      • #6041 : BIDI: Direction of Increase Indent & Decrease Indent icons are not reversed after changing Lang direction to RTL.
      • +
      • #6138 : List indentation is not working.
      • +
      • #5649 : Image dialog too wide when many styles are set.
      • +
      • #5715 : Cell color picker dialog returns focus to document.
      • +
      • #6108 : Fixed div style.
      • +
      • #5336 : Remove object style.
      • +
      • #6155 : [[FF]] Modifying Table Header Properties by selecting first Row, causing several issues.
      • +
      • #6163 : Focus not going to Tabs in Image dialog when we went to Edit the Image.
      • +
      • #6177 : IE we can't start Numbered/Bulleted list on a Empty page.
      • +
      • #6034 : Horizontal Alignment applied to Table cell is not updated correctly in the Toolbar.
      • +
      • #6112 : BIDI: Alignment set to text in Table cell is not shown in the Tool bar when we press Enter to start a new Paragraph.
      • +
      • #6117 : BIDI: Language direction is changing when we come out of Numbered/Bulleted list.
      • +
      • #6182 : Language Direction field on the Advanced tab of Table Properties dialog has a fixed pixel width.
      • +
      • #5487 : Fullpage writer problem with line-break.
      • +
      • #6197 : The CKEDITOR.loader base path auto-detection was not working with the _source folder.
      • +
      • #6240 : Font Names & Font Sizes should be shown Left Align even for RTL Languages.
      • +
      • #5975 : Page-break should have proper Alt Text instead of Unknown object. so that JAWS reads it properly.
      • +
      • #6255 : Inserting a page break as the first node triggered an error.
      • +
      • #6188 : [IE7] Automatic color button had the wrong cursor.
      • +
      • #6129 : The show blocks' labels are now shown in the right for RTL languages.
      • +
      • #5421 : &shy; entity not converted when config.entities=false.
      • +
      • #5769 : xhtml code generation problem &nbsp; instead of &#160; (htmlentities, entities,entities_additional,..., configuration).
      • +
      • #4472 : [FF3] Browser window scrolls to loaded CKEditor.
      • +
      • #6230 : Fixed invalid parameter count for setTimeout function call.
      • +
      • #5335 : Several lines' formatted data will be merged to one line when we apply Numbers/Bullets.
      • +
      • #5353 : wrong width of editor after resize() called in Firefox 3.6.
      • +
      • #5778 : [IE] Unwanted scroll on first mouse right-click.
      • +
      • #5218 : [FF] Copy/paste of an image from same domain changed URL to relative URL.
      • +
      • #6265 : Popup window properties were visible in the link dialog's target tab when nothing was selected.
      • +
      • #6075 : [FF] Newly created links didn't fill in information on edit.
      • +
      • #6183 : The toolbar panels options sometimes had the contents' link color.
      • +
      • #6192 : [WebKit] Inserting smileys was not working because of editor focus issues.
      • +
      • #6178 : [WebKit] Inserting elements by code was failing if the editor didn't receive the focus first.
      • +
      • #6179 : [WebKit] The Image dialog was not working if the editor didn't receive the focus first.
      • +
      • #4657 : [Opera] Styles where not working with collapsed selections.
      • +
      • #5839 : "Insert row after" was removing the ids of the elements from the clicked row.
      • +
      • #6315 : DIV plugin TT #2885 regression.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.4

      +

      + Fixed issues:

      +
        +
      • #6118 : Initial focus is now set to the tabs in the table properties dialog.
      • +
      • #6135 : The dialogadvtab plugin now uses the correct label.
      • +
      • #6125 : Focus was lost after applying commands in Opera.
      • +
      • #6137 : The table dialog was missing the default width value on second opening.
      • +
      +

      + CKEditor 3.4 Beta

      +

      + New features:

      +
        +
      • #5909 : New BiDi feature, making it possible to switch the base language direction of block elements.
      • +
      • #5268 : Introducing the "tableresize" plugin, which makes it possible to resize tables columns by mouse drag. It's not enabled by default, so it must be enabled in the configurations file.
      • +
      • #979 : New enableTabKeyTools configuration to allow using the TAB key to navigate through table cells.
      • +
      • #4606 : Introduce the "autogrow" plugin, which makes the editor resize automatically, based on the contents size.
      • +
      • #5737 : Added support for the HTML5 contenteditable attribute, making it possible to define read only regions into the editor contents.
      • +
      • #5418 : New "Advanced" tab introduced on the Table Properties dialog. It's based on the new dialogadvtab plugin.
      • +
      • #6082 : Introduced the useComputedState setting, making it possible to control whether toolbar features, like alignment and direction, should reflect the "computed" selection states, even when the effective feature value is not applied.
      • +
      +

      + Fixed issues:

      +
        +
      • #5911 : BiDi: List items should support and retain correct base language direction
      • +
      • #5689 : Make it possible to run CKEditor inside of Firefox chrome.
      • +
      • #6042 : It wasn't possible to align a paragraph with the dir attribute to the opposite direction.
      • +
      • #6058 : Fixed a small style glitch with file upload fields in IE+Quirks.
      • +
      +

      + CKEditor 3.3.2

      +

      + New features:

      +
        +
      • #5882 : Introduce the dialog#selectPage event, replicating the OnDialogTabChange feature available in FCKeditor 2.
      • +
      • #5927 : The native controls in ui.dialog.elements can be styled with the controlStyle definition.
      • +
      +

      + Fixed issues:

      +
        +
      • #1644 : Removed references to cursor:hand in the stylesheets.
      • +
      • #5411 : Anchor, hidden fields and Page-Break objects can no longer be resized.
      • +
      • #5456 : Initial focus incorect in api_dialog sample page.
      • +
      • #5628 : Incorrect <pre> siblings merging.
      • +
      • #5829 : Adding validation for start number field in list style dialog.
      • +
      • #5845 : Context menu on empty list item loses selection.
      • +
      • #5860 : [IE] > in attribute values are incorrectly escaped.
      • +
      • #5905 : SCAYT is not any more enabled by default.
      • +
      • #5736 : Improved the text generated for mailto: links if no text was selected.
      • +
      • #4779 : Adjust resize_minWidth and resize_minHeight if smaller than actual dimensions.
      • +
      • #5687 : Navigation through colors is now compatible with RTL.
      • +
      • #4615 : [IE] Text fields are no longer disrupted in dialog with RTL.
      • +
      • #5887 : The number of columns in the smileys table is now configurable via the smiley_columns setting.
      • +
      • #5100 : It was possible to drag&drop some elements like context menu items or dropdown entries.
      • +
      • #5933 : Text color and background color panels don't have scrollbars anymore under office2003 and v2 skins.
      • +
      • #5943 : An error is no longer generated when using percent or pixel values in the image dialog.
      • +
      • #5951 : Avoid problems with security systems due to the usage of UniversalXPConnect.
      • +
      • #5441 : Avoid errors if the editor instance is removed from the DOM before calling its destroy() method.
      • +
      • #4997 : Provide better access to the native input in the ui.dialog.file element.
      • +
      • #5914 : Modified the Smileys dialog to make active only the images and not their borders.
      • +
      • #5565 : The scrollbar does not behaves erratically when opening a rich combo in RTL page.
      • +
      • #5843 : In CKEditor 3.3: When we set the focus in the 'instanceReady' event, FF3.6 is giving js error.
      • +
      • #5902 : paste and pastetext dialogs cannot be skinned easily.
      • +
      • #5959 : Dialog auto focus does not check for hidden tabs.
      • +
      • #5415 : Undo not working when we change the Table Properties for the table on a saved page.
      • +
      • #5435 : IE: we can't start Numbered/Bulleted list in Tables by Clicking on Insert/Remove Numbers/Bullets Icon.
      • +
      • #5832 : The JQuery adapter sample is not working properly with SSL.
      • +
      • #5728 : Text field & Upload Button in Upload Tab of Image Properties dialog are not shown Properly in Arabic.
      • +
      • #5436 : IE: Cursor goes to next Table Cell after we insert a Smiley in the Table Cell.
      • +
      • #5580 : Maximize does not work properly in the Office 2003 and V2 skins.
      • +
      • #5495 : The link dialog was breaking the undo system on some situations.
      • +
      • #5775 : Required field's label to contain a CSS class to allow it to be styled differently.
      • +
      • #5999 : Table dialog rows and columns fields are now marked as required.
      • +
      • #5693 : baseHref detection in the flash dialog now works correctly.
      • +
      • #5690 : Table cell's width attribute is now respected properly.
      • +
      • #5819 : Introducing the new removeFormatCleanup event and making sure remove format doesn't break the showborder plugin.
      • +
      • #5558 : After pasting on WebKit based browsers the editor now scrolls to the end of the pasted content.
      • +
      • #5799 : Correct plugin dependencies for the liststyle plugin with contextMenu and dialog.
      • +
      • #5436 : IE: The cursor was moving to the wrong position when inserting inline elements at the end of cells on tables.
      • +
      • #5984 : Firefox: CTRL+HOME was creating an unwanted empty paragraph at the start of the document.
      • +
      • #5634 : IE: It was needed to click twice in the editor to make it editable on some situations.
      • +
      • #5338 : Pasting from Open Office could lead on error.
      • +
      • #5224 : Some invalid markup could break the editor.
      • +
      • #5455 : It was not possible to remove formatting from pasted content on specific cases.
      • +
      • #5735 : IE: The editor was having focus issues when the previous selection got hidden by scroll operations.
      • +
      • #5563 : Firefox: The disableObjectResizing and disableNativeTableHandles settings stopped working.
      • +
      • #5781 : Firefox: Editing was not possible in an empty document.
      • +
      • #5293 : Firefox: Unwanted BR tags were being left in the editor output when it should be empty.
      • +
      • #5280 : IE: Scrollbars where reacting improperly when clicking in the bar space.
      • +
      • #5840 : Some dialog access keys are conflicting with "Ctrl + A", select all text behavior on text input.
      • +
      • #6059 : Changing list type didn't preserve the list's attributes.
      • +
      • #5193 : In Firefox, the element path options had the text cursor instead of the arrow.
      • +
      • #6073 : The list context menu was showing the wrong option when in a mixed list hierarchy.
      • +
      • #6074 : The Insert Table Column command was duplicating the selected column cells ids.
      • +
      • #6066 : The toolbar combos had the text cursor instead of the arrow.
      • +
      • #6062 : The toolbar buttons had the text cursor instead of the arrow.
      • +
      • #6068 : [IE7] A few labels were hidden in a RTL language.
      • +
      • #6000 : Safari and Chrome where scrolling the contents to the top when moving the focus to the editor.
      • +
      • #6090 : IE: Textarea with selection inside causes Link dialog issues.
      • +
      • #5079 : Page break in lists move to above the list when you switch from WYSIWYG to HTML mode and back.
      • +
      • Updated the following language files:
          +
        • Chinese Simplified;
        • +
        • Hebrew;
        • +
        • #5962 : German;
        • +
        • #5645 : Portuguese;
        • +
        • #5797 : Turkish;
        • +
      • +
      +

      + CKEditor 3.3.1

      +

      + Fixed issues:

      +
        +
      • #5780 : Text selection lost when opening some of the dialogs.
      • +
      • #5787 : Liststyle plugin wasn't packaged into the core (CKEDITOR.resourceManager.load exception).
      • +
      • #5637 : Fix wrong nesting that generated "<head> must be a child of <html>" warning in Webkit.
      • +
      • #5790 : Internal only attributes output on fullpage <html> tag.
      • +
      • #5761 : [IE] Color dialog matrix buttons are barely clickable in quirks mode.
      • +
      • #5759 : [IE] Clicking on the scrollbar and then on the host page causes error.
      • +
      • #5772 : List style dialog is missing tab page ids.
      • +
      • #5782 : [FF] Wysiwyg mode is broken by 'display' style changes on editor's parent DOM tree.
      • +
      • #5801 : [IE] contentEditable="false" doesn't apply in effect on inline-elements.
      • +
      • #5794 : Empty find matching twice results in JavaScript error.
      • +
      • #5732 : If it isn't possible to connect to the SCAYT servers the dialogs might hang in Firefox. Fix for Firefox>=3.6.
      • +
      • #5807 : [FF2] New page command results in uneditable document.
      • +
      • #5807 : [FF2] SCAYT plugin is disabled in Firefox2 due to selection interference.
      • +
      • #5772 : [IE] Some numbered list style types are not supported by IE6/7 and causes JavaScript error.
      • +
      +

      + CKEditor 3.3

      +

      + New features:

      +
        +
      • #635 : The properties dialog will now open when double clicking on objects.
      • +
      • #3893 : It's now possible to indent/outdent lists when selecting the first list item.
      • +
      • #4968 : The contentsLangDirection setting now has a default value 'ui' which inherit language direction from the editor UI language.
      • +
      • #4649 : The color picker dialog is now accessible.
      • +
      • #3593 : The editing area is now enabled by contentEditable="true" instead of designMode="on" to allow creating uneditable content elements in all browsers.
      • +
      • #4056 : Hidden fields will now be displayed as fake element just like in FCKeditor 2.
      • +
      +

      + CKEditor 3.2.2

      +

      + New features:

      +
        +
      • The SCAYT spell checker is now enabled by default through the autoStartup setting.
      • +
      • #5631 : The SCAYT context menu options can now be reorganized through the scayt_contextMenuItemsOrder setting.
      • +
      • #4231 : Introducing the resize_dir setting, to be able to restrict manual resizing of the editor to only one direction (horizontal/vertical).
      • +
      • #5479 : Introducing the classic ASP integration files and samples.
      • +
      • #5024 : Added samples (HTML and XHTML) to show how to output HTML using fonts and other attributes instead of styles.
      • +
      • #4358 : Introduced the List Properties dialog.
      • +
      • #5485 : Adding the contentsLanguage configuration option to be able to set the language for the editor contents.
      • +
      +

      + Fixed issues:

      +
        +
      • #5330 : Corrected detection of CTRL and META keys in Macs for the context menu.
      • +
      • #5434 : Fixed access denied issues with IE when accessing web sites through IPv6 IP addresses.
      • +
      • #4476 : [IE] Inaccessible empty list item contains sub list.
      • +
      • #4881 : [IE] Selection range broken because of cutting a single control type element from it.
      • +
      • #5505 : Image dialog throw JavaScript error when click close dialog before preview area is loading.
      • +
      • #5144 : [Chrome] Paste in Webkit sometimes leaves extra 'div' element.
      • +
      • #5021 : [Firefox] Typing in empty document start from second line when enterMode = CKEDITOR.ENTER_BR.
      • +
      • #5416 : [IE] Delete table throws a error when enterMode = CKEDITOR.ENTER_BR.
      • +
      • #4459 : [IE] Select element is penetrating the maximized editor in IE6.
      • +
      • #5559 : [IE] The first call to setData is affected by iframe cache when loading the wysiwyg mode.
      • +
      • #5567 : [IE] Remove inline styles in some case doesn't join identical siblings.
      • +
      • #5450 : [FireFox] Press ENTER on 'replace' button result wrong.
      • +
      • #5121 : Recognizes the <br /> tag as a separator when apply block styles and enterMode = CKEDITOR.ENTER_BR.
      • +
      • #5575 : CKEDITOR.replaceAll should consider all kind of white spaces between class names.
      • +
      • #5582 : Prevent the default behavior when click the 'x' button to close dialog box.
      • +
      • #5584 : ENTER key with forceEnterMode turns on doesn't inherit current block attributes.
      • +
      • #4797 : [Opera] Press ENTER key in dialog fields to close throws JavaScript error.
      • +
      • #5578 : Add flash fake element align property when switch mode (source to wysiwyg).
      • +
      • #5577 : Update delete column behavior when choose multiple cells in the same column.
      • +
      • #5512 : Open context menu with SHIFT+F10 doesn't get correct editor selection.
      • +
      • #5433 : English protocol text directions in Link dialog are not incorrect in 'rtl' UI languages.
      • +
      • #5553 : Paste dialog clipboard area text direction is incorrect for 'rtl' content languages.
      • +
      • #4734 : Font size resets when font name is changed in an empty numbered list.
      • +
      • #5237 : English text in dialogs' title is flipped when using RTL language.
      • +
      • #3257 : Create list doesn't keep blocks as headings.
      • +
      • #5111 : [Firefox] JAWS doesn't respect PC cursor mode (application role) on toolbar.
      • +
      • #5530 : Page break for printing can't be removed with undo.
      • +
      • #5381 : Unable to place cursor between two paragraphs in body.
      • +
      • #5568 : [IE6/7] Selecting a entire table cell changes the original range.
      • +
      • #5623 : [Firefox] Apply style that edges another inline style result incorrect.
      • +
      • #5586 : [Firefox] Maximize the second editor ruins full screen mode.
      • +
      • #5617 : HTML filter system does not allow two 'text' filter rules.
      • +
      • #5663 : General memory clean up after destroying last instance.
      • +
      • #5461 : [IE] Fix Paste from Word dialog doesn't accept imput problem.
      • +
      • #5676 : Make color buttons use RRGGBB instead of RGB for better compatibility with IE.
      • +
      • #4948 : [Safari] Select the first/last cell of table to open context menu may lead to undetected table.
      • +
      • #5591 : [Firefox] Select a list item makes selected element broken.
      • +
      • #5667 : Pasting in a RTL page content causes shows up the horizontal scrollbar.
      • +
      • #5688 : Duplicate ids are used in dialog definition.
      • +
      • #5719 : [IE] 'change' dialog event should not be triggered when dialog is already closed.
      • +
      • #5747 : [IE] Error thrown when IE input field editing mode is turned on.
      • +
      • #5516 : IE8: Toolbar buttons have higher bottom padding.
      • +
      • #5402 : SHIFT-ENTER could now be used to exit from preformat block.
      • +
      • SCAYT plugin related:
          +
        • #4836 : Using SCAYT result in fragile elements when applying inline styles.
        • +
        • #5425 : [Opera] Disable SCAYT plugin for Opera browser.
        • +
        • #5632 : SCAYT word marker is not visible on text with background-color set.
        • +
        • #4125 : Remove Format command incorrectly removes SCAYT word markers.
        • +
        • #5671 : SCAYT bootstrap script could be added multiple times unnecessarily.
        • +
        • #5573 : SCAYT move cursor position after insert element into marked word text.
        • +
        • #5546 : SCAYT interferes with undo/redo commands.
        • +
        • #5570 : [IE] First enabling SCAYT blind cursor in editor.
        • +
        • #5741 : Enable SCAYT cause error in multiple editor instances.
        • +
        • #5744 : Remove editor with SCAYT enabled in source mode throws error.
        • +
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.2.1

      +

      + New features:

      +
        +
      • #4478 : Enable the SelectAll command in source mode.
      • +
      • #5150 : Allow names in the CKEDITOR.config.colorButton_colors setting.
      • +
      • #4810 : Adding configuration option for image dialog preview area filling text.
      • +
      • #536 : Object style now could be applied on any parent element of current selection.
      • +
      • #5290 : Unified stylesSet loading removing dependencies from the styles combo. + Now the configuration entry is named 'config.stylesSet' instead of config.stylesCombo_stylesSet and the default location + is under the 'styles' plugin instead of 'stylescombo'.
      • +
      • #5352 : Allow to define the stylesSet array in the config object for the editor.
      • +
      • #5302 : Adding config option "forceEnterMode".
      • +
      • #5216 : Extend CKEDITOR.appendTo to allow a data parameter for the initial value.
      • +
      • #5024 : Added sample to show how to output XHTML and avoid deprecated tags.
      • +
      +

      + Fixed issues:

      +
        +
      • #5152 : Indentation using class attribute doesn't work properly.
      • +
      • #4682 : It wasn't possible to edit block elements in IE that had styles like width, height or float.
      • +
      • #4750 : Correcting default order of buttons layout in dialogs on Mac.
      • +
      • #4932 : Fixed collapse button not clickable on simple toolbar.
      • +
      • #5228 : Link dialog is automatically changes protocol when URLs that starts with '?'.
      • +
      • #4877 : Fixed CKEditor displays source code in one long line (IE quirks mode + office2003 skin).
      • +
      • #5132 : Apply inline style leaks into sibling words which are seperated spaces.
      • +
      • #3599 : Background color style on sized text displayed as narrow band behind.
      • +
      • #4661 : Translation missing in link dialog.
      • +
      • #5240 : Flash alignment property is not presented visually on fake element.
      • +
      • #4910 : Pasting in IE scrolls document to the end.
      • +
      • #5041 : Table summary attribute can't be removed with dialog.
      • +
      • #5124 : All inline styles cannot be applied on empty spaces.
      • +
      • #3570 : SCAYT marker shouldn't appear inside elements path bar.
      • +
      • #4553 : Dirty check result incorrect when editor document is empty.
      • +
      • #4555 : Unreleased memory when editor is created and destroyed.
      • +
      • #5118 : Arrow keys navigation in RTL languages is incorrect.
      • +
      • #4721 : Remove attribute 'value' of checkbox in IE.
      • +
      • #5278 : IE: Add validation to check for bad window names of popup window.
      • +
      • #5171 : Dialogs contains lists don't have proper voice labels.
      • +
      • #4791 : Can't place cursor inside a form that end with a checkbox/radio.
      • +
      • #4479 : StylesCombo doesn't reflect the selection state until it's first opened.
      • +
      • #4717 : 'Unlink' and 'Outdent' command buttons should be disabled on editor startup.
      • +
      • #5119 : Disabled command buttons are not being properly styled when focused.
      • +
      • #5307 : Hide dialog page cause problem when there's two tab pages remain.
      • +
      • #5343 : Active list item ARIA role is wrongly placed.
      • +
      • #3599 : Background color style applying to text with font size style has been narrowly rendered.
      • +
      • #4711 : Line break character inside preformatted text makes it unable to type text at the end of previous line.
      • +
      • #4829 : [IE] Apply style from combo has wrong result on manually created selection.
      • +
      • #4830 : Retrieving selected element isn't always right, especially selecting using keyboard (SHIFT+ARROW).
      • +
      • #5128 : Element attribute inside preformatted text is corrupted when converting to other blocks.
      • +
      • #5190 : Template list entry shouldn't gain initial focus open templates list dialog opens.
      • +
      • #5238 : Menu button doesn't display arrow icon in high-contrast mode.
      • +
      • #3576 : Non-attributed element of the same name with the applied style is incorrectly removed.
      • +
      • #5221 : Insert table into empty document cause JavaScript error thrown.
      • +
      • #5242 : Apply 'automatic' color option of text color incorrectly removes background-color style.
      • +
      • #4719 : IE does not escape attribute values properly.
      • +
      • #5170 : Firefox does not insert text into styled element properly.
      • +
      • #4026 : Office2003 skin has no toolbar button borders in High Contrast in IE7.
      • +
      • #4348 : There should have exception thrown when 'CKEDITOR_BASEPATH' couldn't be figured out automatically.
      • +
      • #5364 : Focus may not be put into dialog correctly when dialog skin file is loading slow.
      • +
      • #4016 : Justify the layout of forms select dialog in Chrome and IE7.
      • +
      • #5373 : Variable 'pathBlockElements' defines wrong items in CKEDITOR.dom.elementPath.
      • +
      • #5082 : Ctrl key should be described as Cmd key on Mac.
      • +
      • #5182 : Context menu is not been announced correctly by ATs.
      • +
      • #4898 : Can't navigate outside table under the last paragraph of document.
      • +
      • #4950 : List commands could compromise list item attribute and styles.
      • +
      • #5018 : Find result highlighting remove normal font color styles unintentionally.
      • +
      • #5376 : Unable to exit list from within a empty block under list item.
      • +
      • #5145 : Various SCAYT fixes.
      • +
      • #5319 : Match whole word doesn't work anymore after replacement has happened.
      • +
      • #5363 : 'title' attribute now presents on all editor iframes.
      • +
      • #5374 : Unable to toggle inline style when the selection starts at the linefeed of the previous paragraph.
      • +
      • #4513 : Selected link element is not always correctly detected when using keyboard arrows to perform such selection.
      • +
      • #5372 : Newly created sub list should inherit nothing from the original (parent) list, except the list type.
      • +
      • #5274 : [IE6] Templates preview image is displayed in wrong size.
      • +
      • #5292 : Preview in font size and family doesn't work with custom styles.
      • +
      • #5396 : Selection is lost when use cell properties dialog to change cell type to header.
      • +
      • #4082 : [IE+Quirks] Preview text in the image dialog is not wrapping.
      • +
      • #4197 : Fixing format combo don't hide when editor blur on Safari.
      • +
      • #5401 : The context menu break layout with Office2003 and V2 skin on IE quirks mode.
      • +
      • #4825 : Fixing browser context menu is opened when clicking right mouse button twice.
      • +
      • #5356 : The SCAYT dialog had issues with Prototype enabled pages.
      • +
      • #5266 : SCAYT was disturbing the rendering of TH elements.
      • +
      • #4688 : SCAYT was interfering on checkDirty.
      • +
      • #5429 : High Contrast mode was being mistakenly detected when loading the editor through Dojo's xhrGet.
      • +
      • #5221 : Range is mangled when making collapsed selection in an empty paragraph.
      • +
      • #5261 : Config option 'scayt_autoStartup' slow down editor loading.
      • +
      • #3846 : Google Chrome - No Img properties after inserting.
      • +
      • #5465 : ShiftEnter=DIV doesn't respect list item when pressing ENTER at end of list item.
      • +
      • #5454 : After replaced success, the popup window couldn't be closed and a js error occured.
      • +
      • #4784 : Incorrect cursor position after delete table cells.
      • +
      • #5149 : [FF] Cursor disappears after maximize when the editor has focus.
      • +
      • #5220 : DTD now shows tolerance to <style> appear inside content.
      • +
      • #5440 : Mobile browsers (iPhone, Android...) are marked as incompatible as they don't support editing features.
      • +
      • #5504 : [IE6/7] 'Paste' dialog will always get opened even when user allows the clipboard access dialog when using 'Paste' button.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.2

      +

      + New features:

      +
        +
      • Several accessibility enhancements:
          +
        • #4502 : The editor accessibility is now totally based on WAI-ARIA.
        • +
        • #5015 : Adding accessibility help dialog plugin.
        • +
        • #5014 : Keyboard navigation compliance with screen reader suggested keys.
        • +
        • #4595 : Better accessibility in the Templates dialog.
        • +
        • #3389 : Esc/Arrow Key now works for closing sub menu.
        • +
      • +
      • #4973 : The Style field in the Div Container dialog is now loading the styles defined in the default styleset used by the Styles toolbar combo.
      • +
      +

      + Fixed issues:

      +
        +
      • #5049 : Form Field list command in JAWS incorrectly lists extra fields.
      • +
      • #5008 : Lock/Unlock ratio buttons in the Image dialog was poorly designed in High Contrast mode.
      • +
      • #3980 : All labels in dialogs now use <label> instead of <div>.
      • +
      • #5213 : Reorganization of some entries in the language files to make it more consistent.
      • +
      • #5199 : In IE, single row toolbars didn't have the bottom padding.
      • +
      +

      + CKEditor 3.1.1

      +

      + New features:

      +
        +
      • #4399 : Improved support for external file browsers by allowing executing a callback function.
      • +
      • #4612 : The text of links is now updated if it matches the URL to which it points to.
      • +
      • #4936 : New localization support for the Welsh language.
      • +
      +

      + Fixed issues:

      +
        +
      • #4272 : Kama skin toolbar was broken in IE+Quirks+RTL.
      • +
      • #4987 : Changed the url which is called by the Browser Server button in the Link tab of Image Properties dialog.
      • +
      • #5030 : The CKEDITOR.timestamp wasn't been appended to the skin.js file.
      • +
      • #4993 : Removed the float style from images when the user selects 'not set' for alignment.
      • +
      • #4944 : Fixed a bug where nested list structures with inconsequent levels were not being pasted correctly from MS Word.
      • +
      • #4637 : Table cells' 'nowrap' attribute was not being loaded by the cell property dialog. Thanks to pomu0325.
      • +
      • #4724 : Using the mouse to insert a link in IE might create incorrect results.
      • +
      • #4640 : Small optimizations for the fileBrowser plugin.
      • +
      • #4583 : The "Target Frame Name" field is now visible when target is set to 'frame' only.
      • +
      • #4863 : Fixing iframedialog's height doesn't stretch to 100% (except IE Quirks).
      • +
      • #4964 : The BACKSPACE key positioning was not correct in some cases with Firefox.
      • +
      • #4980 : Setting border, vspace and hspace of images to zero was not working.
      • +
      • #4773 : The fileBrowser plugin was overwriting onClick functions eventually defined on fileButton elements.
      • +
      • #4731 : The clipboard plugin was missing a reference to the dialog plugin.
      • +
      • #5051 : The about plugin was missing a reference to the dialog plugin.
      • +
      • #5146 : The wsc plugin was missing a reference to the dialog plugin.
      • +
      • #4632 : The print command will now properly break on the insertion point of page break for printing.
      • +
      • #4862 : The English (United Kingdom) language file has been renamed to en-gb.js.
      • +
      • #4618 : Selecting an emoticon or the lock and reset buttons in the image dialog fired the onBeforeUnload event in IE.
      • +
      • #4678 : It was not possible to set tables' width to empty value.
      • +
      • #5012 : Fixed dependency issues with the menu plugin.
      • +
      • #5040 : The editor will not properly ignore font related settings that have extra item separators (semi-colons).
      • +
      • #4046 : Justify should respect config.enterMode = CKEDITOR.ENTER_BR.
      • +
      • #4622 : Inserting tables multiple times was corrupting the undo system.
      • +
      • #4647 : [IE] Selection on an element within positioned container is lost after open context-menu then click one menu item.
      • +
      • #4683 : Double-quote character in attribute values was not escaped in the editor output.
      • +
      • #4762 : [IE] Unexpected vertical-scrolling behavior happens whenever focus is moving out of editor in source mode.
      • +
      • #4772 : Text color was not being applied properly on links.
      • +
      • #4795 : [IE] Press 'Del' key on horizontal line or table result in error.
      • +
      • #4824 : [IE] <br/> at the very first table cell breaks the editor selection.
      • +
      • #4851 : [IE] Delete table rows with context-menu may cause error.
      • +
      • #4951 : Replacing text with empty string was throwing errors.
      • +
      • #4963 : Link dialog was not opening properly for e-mail type links.
      • +
      • #5043 : Removed the possibility of having an unwanted script tag being outputted with the editor contents.
      • +
      • #3678 : There were issues when editing links inside floating divs with IE.
      • +
      • #4763 : Pressing ENTER key with text selected was not deleting the text in some situations.
      • +
      • #5096 : Simple ampersand attribute value doesn't work for more than one occurrence.
      • +
      • #3494 : Context menu is too narrow in some translations.
      • +
      • #5005 : Fixed HTML errors in PHP samples.
      • +
      • #5123 : Fixed broken XHTML in User Interface Languages sample.
      • +
      • #4893 : Editor now understands table cell inline styles.
      • +
      • #4611 : Selection around <select> in editor doesn't cause error anymore.
      • +
      • #4886 : Extra BR tags were being created in the output HTML.
      • +
      • #4933 : Empty tags with BR were being left in the DOM.
      • +
      • #5127 : There were errors when removing dialog definition pages through code.
      • +
      • #4767 : CKEditor was not working when ckeditor_source.js is loaded in the <body> .
      • +
      • #5062 : Avoided security warning message when loading the wysiwyg area in IE6 under HTTPS.
      • +
      • #5135 : The TAB key will now behave properly when in Source mode.
      • +
      • #4988 : It wasn't possible to use forcePasteAsPlainText with Safari on Mac.
      • +
      • #5095 : Safari on Mac deleted the current selection in the editor when Edit menu was clicked.
      • +
      • #5140 : In High Contrast mode, arrows were now been displayed for menus with submenus.
      • +
      • #5163 : The undo system was not working on some specific cases.
      • +
      • #5162 : The ajax sample was throwing errors when loading data.
      • +
      • #4999 : The Template dialog was not generating an undo snapshot.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.1

      +

      + New features:

      +
        +
      • #4067 : Introduced the full page editing support (from <html> to </html>).
      • +
      • #4228 : Introduced the Shared Spaces feature.
      • +
      • #4379 : Introduced the new powerful pasting system and word cleanup procedure, including enhancements to the paste as plain text feature.
      • +
      • #2872 : Introduced the new native PHP API, the first standardized server side support.
      • +
      • #4210 : Added CKEditor plugin for jQuery.
      • +
      • #2885 : Added 'div' dialog and corresponding context menu options.
      • +
      • #4574 : Added the table merging tools and corresponding context menu options.
      • +
      • #4340 : Added the email protection option for link dialog.
      • +
      • #4463 : Added inline CSS support in all places where custom stylesheet could apply.
      • +
      • #3881 : Added color dialog for 'more color' option in color buttons.
      • +
      • #4341 : Added the 'showborder' plugin.
      • +
      • #4549 : Make the anti-cache query string configurable.
      • +
      • #4708 : Added the 'htmlEncodeOutput' config option.
      • +
      • #4342 : Introduced the bodyId and bodyClass settings to specify the id and class. to be used in the editing area at runtime.
      • +
      • #3401 : Introduced the baseHref setting so it's possible to set the URL to be used to resolve absolute and relative URLs in the contents.
      • +
      • #4729 : Added support to fake elements for comments.
      • +
      +

      + Fixed issues:

      +
        +
      • #4707 : Fixed invalid link is requested in image preview.
      • +
      • #4461 : Fixed toolbar separator line along side combo enlarging the toolbar height.
      • +
      • #4596 : Fixed image re-size lock buttons aren't accessible in high-contrast mode.
      • +
      • #4676 : Fixed editing tables using table properties dialog overwrites original style values.
      • +
      • #4714 : Fixed IE6 JavaScript error when editing flash by commit 'Flash' dialog.
      • +
      • #3905 : Fixed 'wysiwyg' mode causes unauthenticated content warnings over SSL in FF 3.5.
      • +
      • #4768 : Fixed open context menu in IE throws js error when focus is not inside document.
      • +
      • #4822 : Fixed applying 'Headers' to existing table does not work in IE.
      • +
      • #4855 : Fixed toolbar doesn't wrap well for 'v2' skin in all browsers.
      • +
      • #4882 : Fixed auto detect paste from MS-Word is not working for Safari.
      • +
      • #4882 : Fixed unexpected margin style left behind on content cleaning up from MS-Word.
      • +
      • #4896 : Fixed paste nested list from MS-Word with measurement units set to cm is broken.
      • +
      • #4899 : Fixed unable to undo pre-formatted style.
      • +
      • #4900 : Fixed ratio-lock inconsistent between browsers.
      • +
      • #4901 : Fixed unable to edit any link with popup window's features in Firefox.
      • +
      • #4904 : Fixed when paste happen from dialog, it always throw JavaScript error.
      • +
      • #4905 : Fixed paste plain text result incorrect when content from dialog.
      • +
      • #4889 : Fixed unable to undo 'New Page' command after typing inside editor.
      • +
      • #4892 : Fixed table alignment style is not properly represented by the wrapping div.
      • +
      • #4918 : Fixed switching mode when maximized is showing background page contents.
      • +
      +

      + CKEditor 3.0.2

      +

      + New features:

      +
        +
      • #4343 : Added the configuration option 'browserContextMenuOnCtrl' so it's possible to enable the default browser context menu by holding the CTRL key.
      • +
      +

      + Fixed issues:

      +
        +
      • #4552 : Fixed float panel doesn't show up since editor instanced been destroyed once.
      • +
      • #3918 : Fixed fake object is editable with Image dialog.
      • +
      • #4053 : Fixed 'Form Properties' missing from context menu when selection collapsed inside form.
      • +
      • #4401 : Fixed customized by removing 'upload' tab page from 'Link dialog' cause JavaScript error.
      • +
      • #4477 : Adding missing tag names in object style elements.
      • +
      • #4567 : Fixed IE throw error when pressing BACKSPACE in source mode.
      • +
      • #4573 : Fixed 'IgnoreEmptyPargraph' config doesn't work with the config 'entities' is set to 'false'.
      • +
      • #4614 : Fixed attribute protection fails because of line-break.
      • +
      • #4546 : Fixed UIColor plugin doesn't work when editor id contains CSS selector preserved keywords.
      • +
      • #4609 : Fixed flash object is lost when loading data from outside editor.
      • +
      • #4625 : Fixed editor stays visible in a div with style 'visibility:hidden'.
      • +
      • #4621 : Fixed clicking below table caused an empty table been generated.
      • +
      • #3373 : Fixed empty context menu when there's no menu item at all.
      • +
      • #4473 : Fixed setting rules on the same element tag name throws error.
      • +
      • #4514 : Fixed press 'Back' button breaks wysiwyg editing mode is Firefox.
      • +
      • #4542 : Fixed unable to access buttons using tab key in Safari and Opera.
      • +
      • #4577 : Fixed relative link url is broken after opening 'Link' dialog.
      • +
      • #4597 : Fixed custom style with same attribute name but different attribute value doesn't work.
      • +
      • #4651 : Fixed 'Deleted' and 'Inserted' text style is not rendering in wysiwyg mode and is wrong is source mode.
      • +
      • #4654 : Fixed 'CKEDITOR.config.font_defaultLabel(fontSize_defaultLabel)' is not working.
      • +
      • #3950 : Fixed table column insertion incorrect when selecting empty cell area.
      • +
      • #3912 : Fixed UIColor not working in IE when page has more than 30+ editors.
      • +
      • #4031 : Fixed mouse cursor on toolbar combo has more than 3 shapes.
      • +
      • #4041 : Fixed open context menu on multiple cells to remove them result in only one removed.
      • +
      • #4185 : Fixed resize handler effect doesn't affect flash object on output.
      • +
      • #4196 : Fixed 'Remove Numbered/Bulleted List' on nested list doesn't work well on nested list.
      • +
      • #4200 : Fixed unable to insert 'password' type filed with attributes.
      • +
      • #4530 : Fixed context menu couldn't open in Opera.
      • +
      • #4536 : Fixed keyboard navigation doesn't work at all in IE quirks mode.
      • +
      • #4584 : Fixed updated link Target field is not updating when updating to certain values.
      • +
      • #4603 : Fixed unable to disable submenu items in contextmenu.
      • +
      • #4672 : Fixed unable to redo the insertion of horizontal line.
      • +
      • #4677 : Fixed 'Tab' key is trapped by hidden dialog elements.
      • +
      • #4073 : Fixed insert template with replace option could result in empty document.
      • +
      • #4455 : Fixed unable to start editing when image inside document not loaded.
      • +
      • #4517 : Fixed 'dialog_backgroundCoverColor' doesn't work on IE6.
      • +
      • #3165 : Fixed enter key in empty list item before nested one result in collapsed line.
      • +
      • #4527 : Fixed checkbox generate invalid 'checked' attribute.
      • +
      • #1659 : Fixed unable to click below content to start editing in IE with 'config.docType' setting to standard compliant.
      • +
      • #3933 : Fixed extra <br> left at the end of document when the last element is a table.
      • +
      • #4736 : Fixed PAGE UP and PAGE DOWN keys in standards mode are not working.
      • +
      • #4725 : Fixed hitting 'enter' before html comment node produces a JavaScript error.
      • +
      • #4522 : Fixed unable to redo when typing after insert an image with relative url.
      • +
      • #4594 : Fixed context menu goes off-screen when mouse is at right had side of screen.
      • +
      • #4673 : Fixed undo not available straight away if shift key is used to enter first character.
      • +
      • #4690 : Fixed the parsing of nested inline elements.
      • +
      • #4450 : Fixed selecting multiple table cells before apply justify commands generates spurious paragraph in Firefox.
      • +
      • #4733 : Fixed dialog opening sometimes hang up Firefox and Safari.
      • +
      • #4498 : Fixed toolbar collapse button missing tooltip.
      • +
      • #4738 : Fixed inserting table inside bold/italic/underline generates error on ENTER_BR mode.
      • +
      • #4246 : Fixed avoid XHTML deprecated attributes for image styling.
      • +
      • #4543 : Fixed unable to move cursor between table and hr.
      • +
      • #4764 : Fixed wrong exception message when CKEDITOR.editor.append() to non-existing elements.
      • +
      • #4521 : Fixed dialog layout in IE6/7 may have scroll-bar and other weird effects.
      • +
      • #4709 : Fixed inconsistent scroll-bar behavior on IE.
      • +
      • #4776 : Fixed preview page failed to open when relative URl contains in document.
      • +
      • #4812 : Fixed 'Esc' key not working on dialogs in Opera.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.0.1

      +

      + New features:

      +
        +
      • #4219 : Added fallback mechanism for config.language.
      • +
      • #4194 : Added support for using multiple css style sheets within the editor.
      • +
      +

      + Fixed issues:

      +
        +
      • #3898 : Added validation for URL value in Image dialog.
      • +
      • #3528 : Fixed Context Menu issue when triggered using Shift+F10.
      • +
      • #4028 : Maximize control's tool tip was wrong once it is maximized.
      • +
      • #4237 : Toolbar is chopped off in Safari browser 3.x.
      • +
      • #4241 : Float panels are left on screen while editor is destroyed.
      • +
      • #4274 : Double click event is incorrect handled in 'divreplace' sample.
      • +
      • #4354 : Fixed TAB key on toolbar to not focus disabled buttons.
      • +
      • #3856 : Fixed focus and blur events in source view mode.
      • +
      • #3438 : Floating panels are off by (-1px, 0px) in RTL mode.
      • +
      • #3370 : Refactored use of CKEDITOR.env.isCustomDomain().
      • +
      • #4230 : HC detection caused js error.
      • +
      • #3978 : Fixed setStyle float on IE7 strict.
      • +
      • #4262 : Tab and Shift+Tab was not working to cycle through CTRL+SHIFT+F10 context menu in IE.
      • +
      • #3633 : Default context menu isn't disabled in toolbar, status bar, panels...
      • +
      • #3897 : Now there is no image previews when the URL is empty in image dialog.
      • +
      • #4048 : Context submenu was lacking uiColor.
      • +
      • #3568 : Dialogs now select all text when tabbing to text inputs.
      • +
      • #3727 : Cell Properties dialog was missing color selection option.
      • +
      • #3517 : Fixed "Match cyclic" field in Find & Replace dialog.
      • +
      • #4368 : borderColor table cell attribute haven't worked for none-IE
      • +
      • #4203 : In IE quirks mode + toolbar collapsed + source mode editing block height was incorrect.
      • +
      • #4387 : Fixed: right clicking in Kama skin can lead to a javascript error.
      • +
      • #4397 : Wysiwyg mode caused the host page scroll.
      • +
      • #4385 : Fixed editor's auto adjusting on DOM structure were confusing the dirty checking mechanism.
      • +
      • #4397 : Fixed regression of [3816] where turn on design mode was causing Firefox3 to scroll the host page.
      • +
      • #4254 : Added basic API sample.
      • +
      • #4107 : Normalize css font-family style text for correct comparision.
      • +
      • #3664 : Insert block element in empty editor document should not create new paragraph.
      • +
      • #4037 : 'id' attribute is missing with Flash dialog advanced page.
      • +
      • #4047 : Delete selected control type element when 'Backspace' is pressed on it.
      • +
      • #4191 : Fixed: dialog changes confirmation on image dialog appeared even when no changes have been made.
      • +
      • #4351 : Dash and dot could appear in attribute names.
      • +
      • #4355 : 'maximize' and 'showblock' commands shouldn't take editor focus.
      • +
      • #4504 : Fixed 'Enter'/'Esc' key is not working on dialog button.
      • +
      • #4245 : 'Strange Template' now come with a style attribute for width.
      • +
      • #4512 : Fixed styles plugin incorrectly adding semicolons to style text.
      • +
      • #3855 : Fixed loading unminified _source files when ckeditor_source.js is used.
      • +
      • #3717 : Dialog settings defaults can now be overridden in-page through the CKEDITOR.config object.
      • +
      • #4481 : The 'stylesCombo_stylesSet' configuration entry didn't work for full URLs.
      • +
      • #4480 : Fixed scope attribute in th.
      • +
      • #4467 : Fixed bug to use custom icon in context menus. Thanks to george.
      • +
      • #4190 : Fixed select field dialog layout in Safari.
      • +
      • #4518 : Fixed unable to open dialog without editor focus in IE.
      • +
      • #4519 : Fixed maximize without editor focus throw error in IE.
      • +
      • Updated the following language files:
      • +
      +

      + CKEditor 3.0

      +

      + New features:

      +
        +
      • #3188 : Introduce + <pre> formatting feature when converting from other blocks.
      • +
      • #4445 : editor::setData now support an optional callback parameter.
      • +
      +

      + Fixed issues:

      +
        +
      • #2856 : Fixed problem with inches in Paste From Word plugin.
      • +
      • #3929 : Using Paste dialog, + the text is pasted into current selection
      • +
      • #3920 : Mouse cursor over characters in + Special Character dialog now is correct
      • +
      • #3882 : Fixed an issue + with PasteFromWord dialog in which default values was ignored
      • +
      • #3859 : Fixed Flash dialog layout in Webkit
      • +
      • #3852 : Disabled textarea resizing in dialogs
      • +
      • #3831 : The attempt to remove the contextmenu plugin + will not anymore break the editor
      • +
      • #3781 : Colorbutton is now disabled in 'source' mode
      • +
      • #3848 : Fixed an issue with Webkit in witch + elements in the Image and Link dialogs had wrong dimensions.
      • +
      • #3808 : Fixed UI Color Picker dialog size in example page.
      • +
      • #3658 : Editor had horizontal scrollbar in IE6.
      • +
      • #3819 : The cursor was not visible + when applying style to collapsed selections in Firefox 2.
      • +
      • #3809 : Fixed beam cursor + when mouse cursor is over text-only buttons in IE.
      • +
      • #3815 : Fixed an issue + with the form dialog in which the "enctype" attribute is outputted as "encoding".
      • +
      • #3785 : Fixed an issue + in CKEDITOR.tools.htmlEncode() which incorrectly outputs &nbsp; in IE8.
      • +
      • #3820 : Fixed an issue in + bullet list command in which a list created at the bottom of another gets merged to the top. +
      • +
      • #3830 : Table cell properties dialog + doesn't apply to all selected cells.
      • +
      • #3835 : Element path is not refreshed + after click on 'newpage'; and safari is not putting focus on document also. +
      • +
      • #3821 : Fixed an issue with JAWS in which + toolbar items are read inconsistently between virtual cursor modes.
      • +
      • #3789 : The "src" attribute + was getting duplicated in some situations.
      • +
      • #3591 : Protecting flash related elements + including '<object>', '<embed>' and '<param>'. +
      • +
      • #3759 : Fixed CKEDITOR.dom.element::scrollIntoView + logic bug which scroll even element is inside viewport. +
      • +
      • #3773 : Fixed remove list will merge lines. +
      • +
      • #3829 : Fixed remove empty link on output data.
      • +
      • #3730 : Indent is performing on the whole + block instead of selected lines in enterMode = BR.
      • +
      • #3844 : Fixed UndoManager register keydown on obsoleted document
      • +
      • #3805 : Enabled SCAYT plugin for IE.
      • +
      • #3834 : Context menu on table caption was incorrect.
      • +
      • #3812 : Fixed an issue in which the editor + may show up empty or uneditable in IE7, 8 and Firefox 3.
      • +
      • #3825 : Fixed JS error when opening spellingcheck.
      • +
      • #3862 : Fixed html parser infinite loop on certain malformed + source code.
      • +
      • #3639 : Button size was inconsistent.
      • +
      • #3874 : Paste as plain text in Safari loosing lines.
      • +
      • #3849 : Fixed IE8 crashes when applying lists and indenting.
      • +
      • #3876 : Changed dialog checkbox and radio labels to explicit labels.
      • +
      • #3843 : Fixed context submenu position in IE 6 & 7 RTL.
      • +
      • #3864 : [FF]Document is not editable after inserting element on a fresh page.
      • +
      • #3883 : Fixed removing inline style logic incorrect on Firefox2.
      • +
      • #3884 : Empty "href" attribute was duplicated on output data.
      • +
      • #3858 : Fixed the issue where toolbars + break up in IE6 and IE7 after the browser is resized.
      • +
      • #3868 : [chrome] SCAYT toolbar options was in reversed order.
      • +
      • #3875 : Fixed an issue in Safari where + table row/column/cell menus are not useable when table cells are selected.
      • +
      • #3896 : The editing area was + flashing when switching forth and back to source view.
      • +
      • #3894 : Fixed an issue where editor failed to initialize when using the on-demand loading way.
      • +
      • #3903 : Color button plugin doesn't read config entry from editor instance correctly.
      • +
      • #3801 : Comments at the start of the document was lost in IE.
      • +
      • #3871 : Unable to redo when undos to the front of snapshots stack.
      • +
      • #3909 : Move focus from editor into a text input control is broken.
      • +
      • #3870 : The empty paragraph + desappears when hitting ENTER after "New Page".
      • +
      • #3887 : Fixed an issue in which the create + list command may leak outside of a selected table cell and into the rest of document.
      • +
      • #3916 : Fixed maximize does not enlarge editor width when width is set.
      • +
      • #3879 : [webkit] Color button panel had incorrect size on first open.
      • +
      • #3839 : Update Scayt plugin to reflect the latest change from SpellChecker.net.
      • +
      • #3742 : Fixed wrong dialog layout for dialogs without tab bar in IE RTL mode .
      • +
      • #3671 : Fixed body fixing should be applied to the real type under fake elements.
      • +
      • #3836 : Fixed remove list in enterMode=BR will merge sibling text to one line.
      • +
      • #3949 : Fixed enterKey within pre-formatted text introduce wrong line-break.
      • +
      • #3878 : Whenever possible, + dialogs will not present scrollbars if the content is too big for its standard + size.
      • +
      • #3782 : Remove empty list in table cell result in collapsed cell.
      • +
      • Updated the following language files:
      • +
      • #3984 : [IE]The pre-formatted style is generating error.
      • +
      • #3946 : Fixed unable to hide contextmenu.
      • +
      • #3956 : Fixed About dialog in Source Mode for IE.
      • +
      • #3953 : Fixed keystroke for close Paste dialog.
      • +
      • #3951 : Reset size and lock ratio options were not accessible in Image dialog.
      • +
      • #3921 : Fixed Container scroll issue on IE7.
      • +
      • #3940 : Fixed list operation doesn't stop at table.
      • +
      • #3891 : [IE] Fixed 'automatic' font color doesn't work.
      • +
      • #3972 : Fixed unable to remove a single empty list in document in Firefox with enterMode=BR.
      • +
      • #3973 : Fixed list creation error at the end of document.
      • +
      • #3959 : Pasting styled text from word result in content lost.
      • +
      • #3793 : Combined images into sprites.
      • +
      • #3783 : Fixed indenting command in table cells create collapsed paragraph.
      • +
      • #3968 : About dialog layout was broken with IE+Standards+RTL.
      • +
      • #3991 : In IE quirks, text was not visible in v2 and office2003 skins.
      • +
      • #3983 : In IE, we'll now + silently ignore wrong toolbar definition settings which have extra commas being + left around.
      • +
      • Fixed the following test cases:
          +
        • #3992 : core/ckeditor2.html
        • +
        • #4138 : core/plugins.html
        • +
        • #3801 : plugins/htmldataprocessor/htmldataprocessor.html
        • +
      • +
      • #3989 : Host page horizontal scrolling a lot when on having righ-to-left direction.
      • +
      • #4001 : Create link around existing image result incorrect.
      • +
      • #3988 : Destroy editor on form submit event cause error.
      • +
      • #3994 : Insert horizontal line at end of document cause error.
      • +
      • #4074 : Indent error with 'indentClasses' config specified.
      • +
      • #4057 : Fixed anchor is lost after switch between editing modes.
      • +
      • #3644 : Image dialog was missin radio lock.
      • +
      • #4014 : Firefox2 had no dialog button backgrounds.
      • +
      • #4018 : Firefox2 had no richcombo text visible.
      • +
      • #4035 : [IE6] Paste dialog size was too small.
      • +
      • #4049 : Kama skin was too wide with config.width.
      • +
      • The following released files now doesn't require the _source folder
          +
        • #4086 : _samples/ui_languages.html
        • +
        • #4093 : _tests/core/dom/document.html
        • +
        • #4094 : Smiley plugin file
        • +
        • #4097 : No undo/redo support for fontColor and backgroundColor buttons.
        • +
      • +
      • #4085 : Paste and Paste from Word dialogs were not well styled in IE+RTL.
      • +
      • #3982 : Fixed enterKey on empty list item result in weird dom structure.
      • +
      • #4101 : Now it is possible to close dialog before gets focus.
      • +
      • #4075 : [IE6/7]Fixed apply custom inline style with "class" attribute failed.
      • +
      • #4087 : [Firefox]Fixed extra blocks created on create list when full document selected.
      • +
      • #4097 : No undo/redo support for fontColor and backgroundColor buttons.
      • +
      • #4111 : Fixed apply block style after inline style applied on full document error.
      • +
      • #3622 : Fixed shift enter with selection not deleting highlighted text.
      • +
      • #4092 : [IE6] Close button was missing for dialog without multiple tabs.
      • +
      • #4003 : Markup on the image dialog was disrupted when removing the border input.
      • +
      • #4096 : Editor content area was pushed down in IE RTL quirks.
      • +
      • #4112 : [FF] Paste dialog had scrollbars in quirks.
      • +
      • #4118 : Dialog dragging was + occasionally behaving strangely .
      • +
      • #4077 : The toolbar combos + were rendering incorrectly in some languages, like Chinese.
      • +
      • #3622 : The toolbar in the v2 + skin was wrapping improperly in some languages.
      • +
      • #4119 : Unable to edit image link with image dialog.
      • +
      • #4117 : Fixed dialog error when transforming image into button.
      • +
      • #4058 : [FF] wysiwyg mode is sometimes not been activated.
      • +
      • #4114 : [IE] RTE + IE6/IE7 Quirks = dialog mispositoned.
      • +
      • #4123 : Some dialog buttons were broken in IE7 quirks.
      • +
      • #4122 : [IE] The image dialog + was being rendered improperly when loading an image with long URL.
      • +
      • #4144 : Fixed the white-spaces at the end of <pre> is incorrectly removed.
      • +
      • #4143 : Fixed element id is lost when extracting contents from the range.
      • +
      • #4007 : [IE] Source area overflow from editor chrome.
      • +
      • #4145 : Fixed the on demand + ("basic") loading model of the editor.
      • +
      • #4139 : Fixed list plugin regression of [3903].
      • +
      • #4147 : Unify style text normalization logic when comparing styles.
      • +
      • #4150 : Fixed enlarge list result incorrect at the inner boundary of block.
      • +
      • #4164 : Now it is possible to paste text + in Source mode even if forcePasteAsPlainText = true.
      • +
      • #4129 : [FF]Unable to remove list with Ctrl-A.
      • +
      • #4172 : [Safari] The trailing + <br> was not been always added to blank lines ending with &nbsp;.
      • +
      • #4178 : It's now possible to + copy and paste Flash content among different editor instances.
      • +
      • #4193 : Automatic font color produced empty span on Firefox 3.5.
      • +
      • #4186 : [FF] Fixed First open float panel cause host page scrollbar blinking.
      • +
      • #4227 : Fixed destroy editor instance created on textarea which is not within form cause error.
      • +
      • #4240 : Fixed editor name containing hyphen break editor completely.
      • +
      • #3828 : Malformed nested list is now corrected by the parser.
      • +
      +

      + CKEditor 3.0 RC

      +

      + Changelog starts at this release.

      + + + Index: openacs-4/packages/xowiki/www/resources/ckeditor/INSTALL.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ckeditor/INSTALL.html,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ckeditor/INSTALL.html 13 Sep 2012 16:05:42 -0000 1.3 @@ -0,0 +1,92 @@ + + + + + Installation Guide - CKEditor + + + + +

      + CKEditor Installation Guide

      +

      + What's CKEditor?

      +

      + CKEditor is a text editor to be used inside web pages. It's not a replacement + for desktop text editors like Word or OpenOffice, but a component to be used as + part of web applications and web sites.

      +

      + Installation

      +

      + Installing CKEditor is an easy task. Just follow these simple steps:

      +
        +
      1. Download the latest version of the editor from our web site: http://ckeditor.com. You should have already completed + this step, but be sure you have the very latest version.
      2. +
      3. Extract (decompress) the downloaded file into the root of your + web site.
      4. +
      +

      + Note: CKEditor is by default installed in the "ckeditor" + folder. You can place the files in whichever you want though.

      +

      + Checking Your Installation +

      +

      + The editor comes with a few sample pages that can be used to verify that installation + proceeded properly. Take a look at the _samples directory.

      +

      + To test your installation, just call the following page at your web site:

      +
      +http://<your site>/<CKEditor installation path>/_samples/index.html
      +
      +For example:
      +http://www.example.com/ckeditor/_samples/index.html
      +

      + Documentation

      +

      + The full editor documentation is available online at the following address:
      + http://docs.cksource.com/ckeditor

      + + + Index: openacs-4/packages/xowiki/www/resources/ckeditor/LICENSE.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ckeditor/LICENSE.html,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ckeditor/LICENSE.html 13 Sep 2012 16:05:42 -0000 1.3 @@ -0,0 +1,1327 @@ + + + + + License - CKEditor + + +

      + Software License Agreement +

      +

      + CKEditor™ - The text editor for Internet™ - + http://ckeditor.com
      + Copyright © 2003-2011, CKSource - Frederico Knabben. All rights reserved. +

      +

      + Licensed under the terms of any of the following licenses at your choice: +

      + +

      + You are not required to, but if you want to explicitly declare the license you have + chosen to be bound to when using, reproducing, modifying and distributing this software, + just include a text file titled "LEGAL" in your version of this software, indicating + your license choice. In any case, your choice will not restrict any recipient of + your version of this software to use, reproduce, modify and distribute this software + under any of the above licenses. +

      +

      + Sources of Intellectual Property Included in CKEditor +

      +

      + Where not otherwise indicated, all CKEditor content is authored by CKSource engineers + and consists of CKSource-owned intellectual property. In some specific instances, + CKEditor will incorporate work done by developers outside of CKSource with their + express permission. +

      +

      + YUI Test: At _source/tests/yuitest.js + can be found part of the source code of YUI, which is licensed under the terms of + the BSD License. YUI is + Copyright © 2008, Yahoo! Inc. +

      +

      + Trademarks +

      +

      + CKEditor is a trademark of CKSource - Frederico Knabben. All other brand and product + names are trademarks, registered trademarks or service marks of their respective + holders. +

      + + Index: openacs-4/packages/xowiki/www/resources/ckeditor/ckeditor.asp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ckeditor/ckeditor.asp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ckeditor/ckeditor.asp 13 Sep 2012 16:05:42 -0000 1.3 @@ -0,0 +1,955 @@ +<% + ' + ' Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. + ' For licensing, see LICENSE.html or http://ckeditor.com/license + +' Shared variable for all instances ("static") +dim CKEDITOR_initComplete +dim CKEDITOR_returnedEvents + + '' + ' \brief CKEditor class that can be used to create editor + ' instances in ASP pages on server side. + ' @see http://ckeditor.com + ' + ' Sample usage: + ' @code + ' editor = new CKEditor + ' editor.editor "editor1", "

      Initial value.

      ", empty, empty + ' @endcode + +Class CKEditor + + '' + ' The version of %CKEditor. + private version + + '' + ' A constant string unique for each release of %CKEditor. + private mTimeStamp + + '' + ' URL to the %CKEditor installation directory (absolute or relative to document root). + ' If not set, CKEditor will try to guess it's path. + ' + ' Example usage: + ' @code + ' editor.basePath = "/ckeditor/" + ' @endcode + Public basePath + + '' + ' A boolean variable indicating whether CKEditor has been initialized. + ' Set it to true only if you have already included + ' <script> tag loading ckeditor.js in your website. + Public initialized + + '' + ' Boolean variable indicating whether created code should be printed out or returned by a function. + ' + ' Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function. + ' @code + ' editor = new CKEditor + ' editor.returnOutput = true + ' code = editor.editor("editor1", "

      Initial value.

      ", empty, empty) + ' response.write "

      Editor 1:

      " + ' response.write code + ' @endcode + Public returnOutput + + '' + ' A Dictionary with textarea attributes. + ' + ' When %CKEditor is created with the editor() method, a HTML <textarea> element is created, + ' it will be displayed to anyone with JavaScript disabled or with incompatible browser. + public textareaAttributes + + '' + ' A string indicating the creation date of %CKEditor. + ' Do not change it unless you want to force browsers to not use previously cached version of %CKEditor. + public timestamp + + '' + ' A dictionary that holds the instance configuration. + private oInstanceConfig + + '' + ' A dictionary that holds the configuration for all the instances. + private oAllInstancesConfig + + '' + ' A dictionary that holds event listeners for the instance. + private oInstanceEvents + + '' + ' A dictionary that holds event listeners for all the instances. + private oAllInstancesEvents + + '' + ' A Dictionary that holds global event listeners (CKEDITOR object) + private oGlobalEvents + + + Private Sub Class_Initialize() + version = "3.6.2" + timeStamp = "B8DJ5M3" + mTimeStamp = "B8DJ5M3" + + Set oInstanceConfig = CreateObject("Scripting.Dictionary") + Set oAllInstancesConfig = CreateObject("Scripting.Dictionary") + + Set oInstanceEvents = CreateObject("Scripting.Dictionary") + Set oAllInstancesEvents = CreateObject("Scripting.Dictionary") + Set oGlobalEvents = CreateObject("Scripting.Dictionary") + + Set textareaAttributes = CreateObject("Scripting.Dictionary") + textareaAttributes.Add "rows", 8 + textareaAttributes.Add "cols", 60 + End Sub + + '' + ' Creates a %CKEditor instance. + ' In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element. + ' + ' @param name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element). + ' @param value (string) Initial value. + ' + ' Example usage: + ' @code + ' set editor = New CKEditor + ' editor.editor "field1", "

      Initial value.

      " + ' @endcode + ' + ' Advanced example: + ' @code + ' set editor = new CKEditor + ' set config = CreateObject("Scripting.Dictionary") + ' config.Add "toolbar", Array( _ + ' Array( "Source", "-", "Bold", "Italic", "Underline", "Strike" ), _ + ' Array( "Image", "Link", "Unlink", "Anchor" ) _ + ' ) + ' set events = CreateObject("Scripting.Dictionary") + ' events.Add "instanceReady", "function (evt) { alert('Loaded second editor: ' + evt.editor.name );}" + + ' editor.editor "field1", "

      Initial value.

      ", config, events + ' @endcode + ' + public function editor(name, value) + dim attr, out, js, customConfig, extraConfig + dim attribute + + attr = "" + + for each attribute in textareaAttributes + attr = attr & " " & attribute & "=""" & replace( textareaAttributes( attribute ), """", """ ) & """" + next + + out = "" & vbcrlf + + if not(initialized) then + out = out & init() + end if + + set customConfig = configSettings() + js = returnGlobalEvents() + + extraConfig = (new JSON)( empty, customConfig, false ) + if extraConfig<>"" then extraConfig = ", " & extraConfig + js = js & "CKEDITOR.replace('" & name & "'" & extraConfig & ");" + + out = out & script(js) + + if not(returnOutput) then + response.write out + out = "" + end if + + editor = out + + oInstanceConfig.RemoveAll + oInstanceEvents.RemoveAll + end function + + '' + ' Replaces a <textarea> with a %CKEditor instance. + ' + ' @param id (string) The id or name of textarea element. + ' + ' Example 1: adding %CKEditor to <textarea name="article"></textarea> element: + ' @code + ' set editor = New CKEditor + ' editor.replace "article" + ' @endcode + ' + public function replaceInstance(id) + dim out, js, customConfig, extraConfig + + out = "" + if not(initialized) then + out = out & init() + end if + + set customConfig = configSettings() + js = returnGlobalEvents() + + extraConfig = (new JSON)( empty, customConfig, false ) + if extraConfig<>"" then extraConfig = ", " & extraConfig + js = js & "CKEDITOR.replace('" & id & "'" & extraConfig & ");" + + out = out & script(js) + + if not(returnOutput) then + response.write out + out = "" + end if + + replaceInstance = out + + oInstanceConfig.RemoveAll + oInstanceEvents.RemoveAll + end function + + '' + ' Replace all <textarea> elements available in the document with editor instances. + ' + ' @param className (string) If set, replace all textareas with class className in the page. + ' + ' Example 1: replace all <textarea> elements in the page. + ' @code + ' editor = new CKEditor + ' editor.replaceAll empty + ' @endcode + ' + ' Example 2: replace all <textarea class="myClassName"> elements in the page. + ' @code + ' editor = new CKEditor + ' editor.replaceAll 'myClassName' + ' @endcode + ' + function replaceAll(className) + dim out, js, customConfig + + out = "" + if not(initialized) then + out = out & init() + end if + + set customConfig = configSettings() + js = returnGlobalEvents() + + if (customConfig.Count=0) then + if (isEmpty(className)) then + js = js & "CKEDITOR.replaceAll();" + else + js = js & "CKEDITOR.replaceAll('" & className & "');" + end if + else + js = js & "CKEDITOR.replaceAll( function(textarea, config) {\n" + if not(isEmpty(className)) then + js = js & " var classRegex = new RegExp('(?:^| )' + '" & className & "' + '(?:$| )');\n" + js = js & " if (!classRegex.test(textarea.className))\n" + js = js & " return false;\n" + end if + js = js & " CKEDITOR.tools.extend(config, " & (new JSON)( empty, customConfig, false ) & ", true);" + js = js & "} );" + end if + + out = out & script(js) + + if not(returnOutput) then + response.write out + out = "" + end if + + replaceAll = out + + oInstanceConfig.RemoveAll + oInstanceEvents.RemoveAll + end function + + + '' + ' A Dictionary that holds the %CKEditor configuration for all instances + ' For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html + ' + ' Example usage: + ' @code + ' editor.config("height") = 400 + ' // Use @@ at the beggining of a string to ouput it without surrounding quotes. + ' editor.config("width") = "@@screen.width * 0.8" + ' @endcode + Public Property Let Config( configKey, configValue ) + oAllInstancesConfig.Add configKey, configValue + End Property + + '' + ' Configuration options for the next instance + ' + Public Property Let instanceConfig( configKey, configValue ) + oInstanceConfig.Add configKey, configValue + End Property + + '' + ' Adds event listener. + ' Events are fired by %CKEditor in various situations. + ' + ' @param eventName (string) Event name. + ' @param javascriptCode (string) Javascript anonymous function or function name. + ' + ' Example usage: + ' @code + ' editor.addEventHandler "instanceReady", "function (ev) { " & _ + ' " alert('Loaded: ' + ev.editor.name); " & _ + ' "}" + ' @endcode + ' + public sub addEventHandler(eventName, javascriptCode) + if not(oAllInstancesEvents.Exists( eventName ) ) then + oAllInstancesEvents.Add eventName, Array() + end if + + dim listeners, size + listeners = oAllInstancesEvents( eventName ) + size = ubound(listeners) + 1 + redim preserve listeners(size) + listeners(size) = javascriptCode + + oAllInstancesEvents( eventName ) = listeners +' '' Avoid duplicates. fixme... +' if (!in_array($javascriptCode, $this->_events[$event])) { +' $this->_events[$event][] = $javascriptCode; +' } + end sub + + '' + ' Clear registered event handlers. + ' Note: this function will have no effect on already created editor instances. + ' + ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed. + ' + public sub clearEventHandlers( eventName ) + if not(isEmpty( eventName )) then + oAllInstancesEvents.Remove eventName + else + oAllInstancesEvents.RemoveAll + end if + end sub + + + '' + ' Adds event listener only for the next instance. + ' Events are fired by %CKEditor in various situations. + ' + ' @param eventName (string) Event name. + ' @param javascriptCode (string) Javascript anonymous function or function name. + ' + ' Example usage: + ' @code + ' editor.addInstanceEventHandler "instanceReady", "function (ev) { " & _ + ' " alert('Loaded: ' + ev.editor.name); " & _ + ' "}" + ' @endcode + ' + public sub addInstanceEventHandler(eventName, javascriptCode) + if not(oInstanceEvents.Exists( eventName ) ) then + oInstanceEvents.Add eventName, Array() + end if + + dim listeners, size + listeners = oInstanceEvents( eventName ) + size = ubound(listeners) + 1 + redim preserve listeners(size) + listeners(size) = javascriptCode + + oInstanceEvents( eventName ) = listeners +' '' Avoid duplicates. fixme... +' if (!in_array($javascriptCode, $this->_events[$event])) { +' $this->_events[$event][] = $javascriptCode; +' } + end sub + + '' + ' Clear registered event handlers. + ' Note: this function will have no effect on already created editor instances. + ' + ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed. + ' + public sub clearInstanceEventHandlers( eventName ) + if not(isEmpty( eventName )) then + oInstanceEvents.Remove eventName + else + oInstanceEvents.RemoveAll + end if + end sub + + '' + ' Adds global event listener. + ' + ' @param event (string) Event name. + ' @param javascriptCode (string) Javascript anonymous function or function name. + ' + ' Example usage: + ' @code + ' editor.addGlobalEventHandler "dialogDefinition", "function (ev) { " & _ + ' " alert('Loading dialog: ' + ev.data.name); " & _ + ' "}" + ' @endcode + ' + public sub addGlobalEventHandler( eventName, javascriptCode) + if not(oGlobalEvents.Exists( eventName ) ) then + oGlobalEvents.Add eventName, Array() + end if + + dim listeners, size + listeners = oGlobalEvents( eventName ) + size = ubound(listeners) + 1 + redim preserve listeners(size) + listeners(size) = javascriptCode + + oGlobalEvents( eventName ) = listeners + +' // Avoid duplicates. +' if (!in_array($javascriptCode, $this->_globalEvents[$event])) { +' $this->_globalEvents[$event][] = $javascriptCode; +' } + end sub + + '' + ' Clear registered global event handlers. + ' Note: this function will have no effect if the event handler has been already printed/returned. + ' + ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed . + ' + public sub clearGlobalEventHandlers( eventName ) + if not(isEmpty( eventName )) then + oGlobalEvents.Remove eventName + else + oGlobalEvents.RemoveAll + end if + end sub + + '' + ' Prints javascript code. + ' + ' @param string js + ' + private function script(js) + script = "" & vbcrlf + end function + + '' + ' Returns the configuration array (global and instance specific settings are merged into one array). + ' + ' @param instanceConfig (Dictionary) The specific configurations to apply to editor instance. + ' @param instanceEvents (Dictionary) Event listeners for editor instance. + ' + private function configSettings() + dim mergedConfig, mergedEvents + set mergedConfig = cloneDictionary(oAllInstancesConfig) + set mergedEvents = cloneDictionary(oAllInstancesEvents) + + if not(isEmpty(oInstanceConfig)) then + set mergedConfig = mergeDictionary(mergedConfig, oInstanceConfig) + end if + + if not(isEmpty(oInstanceEvents)) then + for each eventName in oInstanceEvents + code = oInstanceEvents( eventName ) + + if not(mergedEvents.Exists( eventName)) then + mergedEvents.Add eventName, code + else + + dim listeners, size + listeners = mergedEvents( eventName ) + size = ubound(listeners) + if isArray( code ) then + addedCount = ubound(code) + redim preserve listeners( size + addedCount + 1 ) + for i = 0 to addedCount + listeners(size + i + 1) = code (i) + next + else + size = size + 1 + redim preserve listeners(size) + listeners(size) = code + end if + + mergedEvents( eventName ) = listeners + end if + next + + end if + + dim i, eventName, handlers, configON, ub, code + + if mergedEvents.Count>0 then + if mergedConfig.Exists( "on" ) then + set configON = mergedConfig.items( "on" ) + else + set configON = CreateObject("Scripting.Dictionary") + mergedConfig.Add "on", configOn + end if + + for each eventName in mergedEvents + handlers = mergedEvents( eventName ) + code = "" + + if isArray(handlers) then + uB = ubound(handlers) + if (uB = 0) then + code = handlers(0) + else + code = "function (ev) {" + for i=0 to uB + code = code & "(" & handlers(i) & ")(ev);" + next + code = code & "}" + end if + else + code = handlers + end if + ' Using @@ at the beggining to signal JSON that we don't want this quoted. + configON.Add eventName, "@@" & code + next + +' set mergedConfig.Item("on") = configOn + end if + + set configSettings = mergedConfig + end function + + '' + ' Returns a copy of a scripting.dictionary object + ' + private function cloneDictionary( base ) + dim newOne, tmpKey + + Set newOne = CreateObject("Scripting.Dictionary") + for each tmpKey in base + newOne.Add tmpKey , base( tmpKey ) + next + + set cloneDictionary = newOne + end function + + '' + ' Combines two scripting.dictionary objects + ' The base object isn't modified, and extra gets all the properties in base + ' + private function mergeDictionary(base, extra) + dim newOne, tmpKey + + for each tmpKey in base + if not(extra.Exists( tmpKey )) then + extra.Add tmpKey, base( tmpKey ) + end if + next + + set mergeDictionary = extra + end function + + '' + ' Return global event handlers. + ' + private function returnGlobalEvents() + dim out, eventName, handlers + dim handlersForEvent, handler, code, i + out = "" + + if (isempty(CKEDITOR_returnedEvents)) then + set CKEDITOR_returnedEvents = CreateObject("Scripting.Dictionary") + end if + + for each eventName in oGlobalEvents + handlers = oGlobalEvents( eventName ) + + if not(CKEDITOR_returnedEvents.Exists(eventName)) then + CKEDITOR_returnedEvents.Add eventName, CreateObject("Scripting.Dictionary") + end if + + set handlersForEvent = CKEDITOR_returnedEvents.Item( eventName ) + + ' handlersForEvent is another dictionary + ' and handlers is an array + + for i = 0 to ubound(handlers) + code = handlers( i ) + + ' Return only new events + if not(handlersForEvent.Exists( code )) then + if (out <> "") then out = out & vbcrlf + out = out & "CKEDITOR.on('" & eventName & "', " & code & ");" + handlersForEvent.Add code, code + end if + next + next + + returnGlobalEvents = out + end function + + '' + ' Initializes CKEditor (executed only once). + ' + private function init() + dim out, args, path, extraCode, file + out = "" + + if (CKEDITOR_initComplete) then + init = "" + exit function + end if + + if (initialized) then + CKEDITOR_initComplete = true + init = "" + exit function + end if + + args = "" + path = ckeditorPath() + + if (timestamp <> "") and (timestamp <> "%" & "TIMESTAMP%") then + args = "?t=" & timestamp + end if + + ' Skip relative paths... + if (instr(path, "..") <> 0) then + out = out & script("window.CKEDITOR_BASEPATH='" & path & "';") + end if + + out = out & "" & vbcrlf + + extraCode = "" + if (timestamp <> mTimeStamp) then + extraCode = extraCode & "CKEDITOR.timestamp = '" & timestamp & "';" + end if + if (extraCode <> "") then + out = out & script(extraCode) + end if + + CKEDITOR_initComplete = true + initialized = true + + init = out + end function + + private function ckeditorFileName() + ckeditorFileName = "ckeditor.js" + end function + + '' + ' Return path to ckeditor.js. + ' + private function ckeditorPath() + if (basePath <> "") then + ckeditorPath = basePath + else + ' In classic ASP we can't get the location of this included script + ckeditorPath = "/ckeditor/" + end if + + ' Try to check if that folder contains the CKEditor files: + ' If it's a full URL avoid checking it as it might point to an external server. + if (instr(ckeditorPath, "://") <> 0) then exit function + + dim filename, oFSO, exists + filename = server.mapPath(basePath & ckeditorFileName()) + set oFSO = Server.CreateObject("Scripting.FileSystemObject") + exists = oFSO.FileExists(filename) + set oFSO = nothing + + if not(exists) then + response.clear + response.write "

      CKEditor path validation failed

      " + response.write "

      The path "" & ckeditorPath & "" doesn't include the CKEditor main file (" & ckeditorFileName() & ")

      " + response.write "

      Please, verify that you have set it correctly and/or adjust the 'basePath' property

      " + response.write "

      Checked for physical file: "" & filename & ""

      " + response.end + end if + end function + +End Class + + + +' URL: http://www.webdevbros.net/2007/04/26/generate-json-from-asp-datatypes/ +'************************************************************************************************************** +'' @CLASSTITLE: JSON +'' @CREATOR: Michal Gabrukiewicz (gabru at grafix.at), Michael Rebec +'' @CONTRIBUTORS: - Cliff Pruitt (opensource at crayoncowboy.com) +'' - Sylvain Lafontaine +'' - Jef Housein +'' - Jeremy Brown +'' @CREATEDON: 2007-04-26 12:46 +'' @CDESCRIPTION: Comes up with functionality for JSON (http://json.org) to use within ASP. +'' Correct escaping of characters, generating JSON Grammer out of ASP datatypes and structures +'' Some examples (all use the toJSON() method but as it is the class' default method it can be left out): +'' +'' <% +'' 'simple number +'' output = (new JSON)("myNum", 2, false) +'' 'generates {"myNum": 2} +'' +'' 'array with different datatypes +'' output = (new JSON)("anArray", array(2, "x", null), true) +'' 'generates "anArray": [2, "x", null] +'' '(note: the last parameter was true, thus no surrounding brackets in the result) +'' % > +'' +'' @REQUIRES: - +'' @OPTIONEXPLICIT: yes +'' @VERSION: 1.5.1 + +'************************************************************************************************************** +class JSON + + 'private members + private output, innerCall + + '********************************************************************************************************** + '* constructor + '********************************************************************************************************** + public sub class_initialize() + newGeneration() + end sub + + '****************************************************************************************** + '' @SDESCRIPTION: STATIC! takes a given string and makes it JSON valid + '' @DESCRIPTION: all characters which needs to be escaped are beeing replaced by their + '' unicode representation according to the + '' RFC4627#2.5 - http://www.ietf.org/rfc/rfc4627.txt?number=4627 + '' @PARAM: val [string]: value which should be escaped + '' @RETURN: [string] JSON valid string + '****************************************************************************************** + public function escape(val) + dim cDoubleQuote, cRevSolidus, cSolidus + cDoubleQuote = &h22 + cRevSolidus = &h5C + cSolidus = &h2F + dim i, currentDigit + for i = 1 to (len(val)) + currentDigit = mid(val, i, 1) + if ascw(currentDigit) > &h00 and ascw(currentDigit) < &h1F then + currentDigit = escapequence(currentDigit) + elseif ascw(currentDigit) >= &hC280 and ascw(currentDigit) <= &hC2BF then + currentDigit = "\u00" + right(padLeft(hex(ascw(currentDigit) - &hC200), 2, 0), 2) + elseif ascw(currentDigit) >= &hC380 and ascw(currentDigit) <= &hC3BF then + currentDigit = "\u00" + right(padLeft(hex(ascw(currentDigit) - &hC2C0), 2, 0), 2) + else + select case ascw(currentDigit) + case cDoubleQuote: currentDigit = escapequence(currentDigit) + case cRevSolidus: currentDigit = escapequence(currentDigit) + case cSolidus: currentDigit = escapequence(currentDigit) + end select + end if + escape = escape & currentDigit + next + end function + + '****************************************************************************************************************** + '' @SDESCRIPTION: generates a representation of a name value pair in JSON grammer + '' @DESCRIPTION: It generates a name value pair which is represented as {"name": value} in JSON. + '' the generation is fully recursive. Thus the value can also be a complex datatype (array in dictionary, etc.) e.g. + '' + '' <% + '' set j = new JSON + '' j.toJSON "n", array(RS, dict, false), false + '' j.toJSON "n", array(array(), 2, true), false + '' % > + '' + '' @PARAM: name [string]: name of the value (accessible with javascript afterwards). leave empty to get just the value + '' @PARAM: val [variant], [int], [float], [array], [object], [dictionary]: value which needs + '' to be generated. Conversation of the data types is as follows:
      + '' - ASP datatype -> JavaScript datatype + '' - NOTHING, NULL -> null + '' - INT, DOUBLE -> number + '' - STRING -> string + '' - BOOLEAN -> bool + '' - ARRAY -> array + '' - DICTIONARY -> Represents it as name value pairs. Each key is accessible as property afterwards. json will look like "name": {"key1": "some value", "key2": "other value"} + '' - multidimensional array -> Generates a 1-dimensional array (flat) with all values of the multidimensional array + '' - request object -> every property and collection (cookies, form, querystring, etc) of the asp request object is exposed as an item of a dictionary. Property names are lowercase. e.g. servervariables. + '' - OBJECT -> name of the type (if unknown type) or all its properties (if class implements reflect() method) + '' Implement a reflect() function if you want your custom classes to be recognized. The function must return + '' a dictionary where the key holds the property name and the value its value. Example of a reflect function within a User class which has firstname and lastname properties + '' + '' <% + '' function reflect() + '' . set reflect = server.createObject("scripting.dictionary") + '' . reflect.add "firstname", firstname + '' . reflect.add "lastname", lastname + '' end function + '' % > + '' + '' Example of how to generate a JSON representation of the asp request object and access the HTTP_HOST server variable in JavaScript: + '' + '' + '' + '' @PARAM: nested [bool]: indicates if the name value pair is already nested within another? if yes then the {} are left out. + '' @RETURN: [string] returns a JSON representation of the given name value pair + '****************************************************************************************************************** + public default function toJSON(name, val, nested) + if not nested and not isEmpty(name) then write("{") + if not isEmpty(name) then write("""" & escape(name) & """: ") + generateValue(val) + if not nested and not isEmpty(name) then write("}") + toJSON = output + + if innerCall = 0 then newGeneration() + end function + + '****************************************************************************************************************** + '* generate + '****************************************************************************************************************** + private function generateValue(val) + if isNull(val) then + write("null") + elseif isArray(val) then + generateArray(val) + elseif isObject(val) then + dim tName : tName = typename(val) + if val is nothing then + write("null") + elseif tName = "Dictionary" or tName = "IRequestDictionary" then + generateDictionary(val) + elseif tName = "IRequest" then + set req = server.createObject("scripting.dictionary") + req.add "clientcertificate", val.ClientCertificate + req.add "cookies", val.cookies + req.add "form", val.form + req.add "querystring", val.queryString + req.add "servervariables", val.serverVariables + req.add "totalbytes", val.totalBytes + generateDictionary(req) + elseif tName = "IStringList" then + if val.count = 1 then + toJSON empty, val(1), true + else + generateArray(val) + end if + else + generateObject(val) + end if + else + 'bool + dim varTyp + varTyp = varType(val) + if varTyp = 11 then + if val then write("true") else write("false") + 'int, long, byte + elseif varTyp = 2 or varTyp = 3 or varTyp = 17 or varTyp = 19 then + write(cLng(val)) + 'single, double, currency + elseif varTyp = 4 or varTyp = 5 or varTyp = 6 or varTyp = 14 then + write(replace(cDbl(val), ",", ".")) + else + ' Using @@ at the beggining to signal JSON that we don't want this quoted. + if left(val, 2) = "@@" then + write( mid( val, 3 ) ) + else + write("""" & escape(val & "") & """") + end if + end if + end if + generateValue = output + end function + + '****************************************************************************************************************** + '* generateArray + '****************************************************************************************************************** + private sub generateArray(val) + dim item, i + write("[") + i = 0 + 'the for each allows us to support also multi dimensional arrays + for each item in val + if i > 0 then write(",") + generateValue(item) + i = i + 1 + next + write("]") + end sub + + '****************************************************************************************************************** + '* generateDictionary + '****************************************************************************************************************** + private sub generateDictionary(val) + innerCall = innerCall + 1 + if val.count = 0 then + toJSON empty, null, true + exit sub + end if + dim key, i + write("{") + i = 0 + for each key in val + if i > 0 then write(",") + toJSON key, val(key), true + i = i + 1 + next + write("}") + innerCall = innerCall - 1 + end sub + + '****************************************************************************************************************** + '* generateObject + '****************************************************************************************************************** + private sub generateObject(val) + dim props + on error resume next + set props = val.reflect() + if err = 0 then + on error goto 0 + innerCall = innerCall + 1 + toJSON empty, props, true + innerCall = innerCall - 1 + else + on error goto 0 + write("""" & escape(typename(val)) & """") + end if + end sub + + '****************************************************************************************************************** + '* newGeneration + '****************************************************************************************************************** + private sub newGeneration() + output = empty + innerCall = 0 + end sub + + '****************************************************************************************** + '* JsonEscapeSquence + '****************************************************************************************** + private function escapequence(digit) + escapequence = "\u00" + right(padLeft(hex(ascw(digit)), 2, 0), 2) + end function + + '****************************************************************************************** + '* padLeft + '****************************************************************************************** + private function padLeft(value, totalLength, paddingChar) + padLeft = right(clone(paddingChar, totalLength) & value, totalLength) + end function + + '****************************************************************************************** + '* clone + '****************************************************************************************** + private function clone(byVal str, n) + dim i + for i = 1 to n : clone = clone & str : next + end function + + '****************************************************************************************** + '* write + '****************************************************************************************** + private sub write(val) + output = output & val + end sub + +end class +%> Index: openacs-4/packages/xowiki/www/resources/ckeditor/ckeditor.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/ckeditor/ckeditor.js,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/resources/ckeditor/ckeditor.js 13 Sep 2012 16:05:42 -0000 1.3 @@ -0,0 +1,149 @@ +/* +Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +(function(){if(window.CKEDITOR&&window.CKEDITOR.dom)return;if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'B8DJ5M3',version:'3.6.2',revision:'7275',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f=0?'&':'?')+'t='+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();var a=CKEDITOR;if(!a.event){a.event=function(){};a.event.implementOn=function(b){var c=a.event.prototype;for(var d in c){if(b[d]==undefined)b[d]=c[d];}};a.event.prototype=(function(){var b=function(d){var e=d.getPrivate&&d.getPrivate()||d._||(d._={});return e.events||(e.events={});},c=function(d){this.name=d;this.listeners=[];};c.prototype={getListenerIndex:function(d){for(var e=0,f=this.listeners;e=0;n--){if(k[n].priority<=h){k.splice(n+1,0,m);return;}}k.unshift(m);}},fire:(function(){var d=false,e=function(){d=true;},f=false,g=function(){f=true;};return function(h,i,j){var k=b(this)[h],l=d,m=f;d=f=false;if(k){var n=k.listeners;if(n.length){n=n.slice(0);for(var o=0;o=0)f.listeners.splice(g,1); +}},hasListeners:function(d){var e=b(this)[d];return e&&e.listeners.length>0;}};})();}if(!a.editor){a.ELEMENT_MODE_NONE=0;a.ELEMENT_MODE_REPLACE=1;a.ELEMENT_MODE_APPENDTO=2;a.editor=function(b,c,d,e){var f=this;f._={instanceConfig:b,element:c,data:e};f.elementMode=d||0;a.event.call(f);f._init();};a.editor.replace=function(b,c){var d=b;if(typeof d!='object'){d=document.getElementById(b);if(d&&d.tagName.toLowerCase() in {style:1,script:1,base:1,link:1,meta:1,title:1})d=null;if(!d){var e=0,f=document.getElementsByName(b);while((d=f[e++])&&d.tagName.toLowerCase()!='textarea'){}}if(!d)throw '[CKEDITOR.editor.replace] The element with id or name "'+b+'" was not found.';}d.style.visibility='hidden';return new a.editor(c,d,1);};a.editor.appendTo=function(b,c,d){var e=b;if(typeof e!='object'){e=document.getElementById(b);if(!e)throw '[CKEDITOR.editor.appendTo] The element with id "'+b+'" was not found.';}return new a.editor(c,e,2,d);};a.editor.prototype={_init:function(){var b=a.editor._pending||(a.editor._pending=[]);b.push(this);},fire:function(b,c){return a.event.prototype.fire.call(this,b,c,this);},fireOnce:function(b,c){return a.event.prototype.fireOnce.call(this,b,c,this);}};a.event.implementOn(a.editor.prototype,true);}if(!a.env)a.env=(function(){var b=navigator.userAgent.toLowerCase(),c=window.opera,d={ie:/*@cc_on!@*/false,opera:!!c&&c.version,webkit:b.indexOf(' applewebkit/')>-1,air:b.indexOf(' adobeair/')>-1,mac:b.indexOf('macintosh')>-1,quirks:document.compatMode=='BackCompat',mobile:b.indexOf('mobile')>-1,iOS:/(ipad|iphone|ipod)/.test(b),isCustomDomain:function(){if(!this.ie)return false;var g=document.domain,h=window.location.hostname;return g!=h&&g!='['+h+']';},secure:location.protocol=='https:'};d.gecko=navigator.product=='Gecko'&&!d.webkit&&!d.opera;var e=0;if(d.ie){e=parseFloat(b.match(/msie (\d+)/)[1]);d.ie8=!!document.documentMode;d.ie8Compat=document.documentMode==8;d.ie9Compat=document.documentMode==9;d.ie7Compat=e==7&&!document.documentMode||document.documentMode==7;d.ie6Compat=e<7||d.quirks;}if(d.gecko){var f=b.match(/rv:([\d\.]+)/);if(f){f=f[1].split('.');e=f[0]*10000+(f[1]||0)*100+ +(f[2]||0);}}if(d.opera)e=parseFloat(c.version());if(d.air)e=parseFloat(b.match(/ adobeair\/(\d+)/)[1]);if(d.webkit)e=parseFloat(b.match(/ applewebkit\/(\d+)/)[1]);d.version=e;d.isCompatible=d.iOS&&e>=534||!d.mobile&&(d.ie&&e>=6||d.gecko&&e>=10801||d.opera&&e>=9.5||d.air&&e>=1||d.webkit&&e>=522||false);d.cssClass='cke_browser_'+(d.ie?'ie':d.gecko?'gecko':d.opera?'opera':d.webkit?'webkit':'unknown'); +if(d.quirks)d.cssClass+=' cke_browser_quirks';if(d.ie){d.cssClass+=' cke_browser_ie'+(d.version<7?'6':d.version>=8?document.documentMode:'7');if(d.quirks)d.cssClass+=' cke_browser_iequirks';}if(d.gecko&&e<10900)d.cssClass+=' cke_browser_gecko18';if(d.air)d.cssClass+=' cke_browser_air';return d;})();var b=a.env;var c=b.ie;if(a.status=='unloaded')(function(){a.event.implementOn(a);a.loadFullCore=function(){if(a.status!='basic_ready'){a.loadFullCore._load=1;return;}delete a.loadFullCore;var e=document.createElement('script');e.type='text/javascript';e.src=a.basePath+'ckeditor.js';document.getElementsByTagName('head')[0].appendChild(e);};a.loadFullCoreTimeout=0;a.replaceClass='ckeditor';a.replaceByClassEnabled=1;var d=function(e,f,g,h){if(b.isCompatible){if(a.loadFullCore)a.loadFullCore();var i=g(e,f,h);a.add(i);return i;}return null;};a.replace=function(e,f){return d(e,f,a.editor.replace);};a.appendTo=function(e,f,g){return d(e,f,a.editor.appendTo,g);};a.add=function(e){var f=this._.pending||(this._.pending=[]);f.push(e);};a.replaceAll=function(){var e=document.getElementsByTagName('textarea');for(var f=0;f'+g+'');else h.push('');}return h.join('');},htmlEncode:function(f){var g=function(k){var l=new d.element('span');l.setText(k);return l.getHtml();},h=g('\n').toLowerCase()=='
      '?function(k){return g(k).replace(/
      /gi,'\n');}:g,i=g('>')=='>'?function(k){return h(k).replace(/>/g,'>');}:h,j=g(' ')=='  '?function(k){return i(k).replace(/ /g,' ');}:i;this.htmlEncode=j;return this.htmlEncode(f);},htmlEncodeAttr:function(f){return f.replace(/"/g,'"').replace(//g,'>');},getNextNumber:(function(){var f=0;return function(){return++f;};})(),getNextId:function(){return 'cke_'+this.getNextNumber();},override:function(f,g){return g(f);},setTimeout:function(f,g,h,i,j){if(!j)j=window;if(!h)h=j;return j.setTimeout(function(){if(i)f.apply(h,[].concat(i));else f.apply(h);},g||0);},trim:(function(){var f=/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g;return function(g){return g.replace(f,'');};})(),ltrim:(function(){var f=/^[ \t\n\r]+/g;return function(g){return g.replace(f,'');};})(),rtrim:(function(){var f=/[ \t\n\r]+$/g;return function(g){return g.replace(f,'');};})(),indexOf:Array.prototype.indexOf?function(f,g){return f.indexOf(g);}:function(f,g){for(var h=0,i=f.length;h',a.document);a.document.getBody().append(f);}if(!/%$/.test(g)){f.setStyle('width',g);return f.$.clientWidth;}return g;};})(),repeat:function(f,g){return new Array(g+1).join(f);},tryThese:function(){var f;for(var g=0,h=arguments.length;g8))&&i)h=i+':'+h;return new d.nodeList(this.$.getElementsByTagName(h));},getHead:function(){var h=this.$.getElementsByTagName('head')[0];if(!h)h=this.getDocumentElement().append(new d.element('head'),true);else h=new d.element(h);return(this.getHead=function(){return h;})();},getBody:function(){var h=new d.element(this.$.body);return(this.getBody=function(){return h;})();},getDocumentElement:function(){var h=new d.element(this.$.documentElement);return(this.getDocumentElement=function(){return h;})();},getWindow:function(){var h=new d.window(this.$.parentWindow||this.$.defaultView);return(this.getWindow=function(){return h;})();},write:function(h){var i=this;i.$.open('text/html','replace');b.isCustomDomain()&&(i.$.domain=document.domain);i.$.write(h);i.$.close();}});d.node=function(h){if(h){switch(h.nodeType){case 9:return new g(h);case 1:return new d.element(h);case 3:return new d.text(h);}d.domObject.call(this,h);}return this;};d.node.prototype=new d.domObject();a.NODE_ELEMENT=1;a.NODE_DOCUMENT=9;a.NODE_TEXT=3;a.NODE_COMMENT=8;a.NODE_DOCUMENT_FRAGMENT=11;a.POSITION_IDENTICAL=0;a.POSITION_DISCONNECTED=1;a.POSITION_FOLLOWING=2; +a.POSITION_PRECEDING=4;a.POSITION_IS_CONTAINED=8;a.POSITION_CONTAINS=16;e.extend(d.node.prototype,{appendTo:function(h,i){h.append(this,i);return h;},clone:function(h,i){var j=this.$.cloneNode(h),k=function(l){if(l.nodeType!=1)return;if(!i)l.removeAttribute('id',false);l.removeAttribute('data-cke-expando',false);if(h){var m=l.childNodes;for(var n=0;n]*>/g,''):i;},getOuterHtml:function(){var j=this;if(j.$.outerHTML)return j.$.outerHTML.replace(/<\?[^>]*>/,'');var i=j.$.ownerDocument.createElement('div');i.appendChild(j.$.cloneNode(true));return i.innerHTML;},setHtml:function(i){return this.$.innerHTML=i;},setText:function(i){h.prototype.setText=this.$.innerText!=undefined?function(j){return this.$.innerText=j;}:function(j){return this.$.textContent=j;};return this.setText(i);},getAttribute:(function(){var i=function(j){return this.$.getAttribute(j,2);};if(c&&(b.ie7Compat||b.ie6Compat))return function(j){var n=this;switch(j){case 'class':j='className';break;case 'http-equiv':j='httpEquiv';break;case 'name':return n.$.name;case 'tabindex':var k=i.call(n,j);if(k!==0&&n.$.tabIndex===0)k=null;return k;break;case 'checked':var l=n.$.attributes.getNamedItem(j),m=l.specified?l.nodeValue:n.$.checked;return m?'checked':null;case 'hspace':case 'value':return n.$[j];case 'style':return n.$.style.cssText;}return i.call(n,j);};else return i;})(),getChildren:function(){return new d.nodeList(this.$.childNodes);},getComputedStyle:c?function(i){return this.$.currentStyle[e.cssStyleToDomStyle(i)];}:function(i){return this.getWindow().$.getComputedStyle(this.$,'').getPropertyValue(i);},getDtd:function(){var i=f[this.getName()];this.getDtd=function(){return i;};return i;},getElementsByTag:g.prototype.getElementsByTag,getTabIndex:c?function(){var i=this.$.tabIndex;if(i===0&&!f.$tabIndex[this.getName()]&&parseInt(this.getAttribute('tabindex'),10)!==0)i=-1;return i;}:b.webkit?function(){var i=this.$.tabIndex;if(i==undefined){i=parseInt(this.getAttribute('tabindex'),10);if(isNaN(i))i=-1;}return i;}:function(){return this.$.tabIndex;},getText:function(){return this.$.textContent||this.$.innerText||'';},getWindow:function(){return this.getDocument().getWindow();},getId:function(){return this.$.id||null;},getNameAtt:function(){return this.$.name||null;},getName:function(){var i=this.$.nodeName.toLowerCase();if(c&&!(document.documentMode>8)){var j=this.$.scopeName;if(j!='HTML')i=j.toLowerCase()+':'+i;}return(this.getName=function(){return i;})();},getValue:function(){return this.$.value;},getFirst:function(i){var j=this.$.firstChild,k=j&&new d.node(j);if(k&&i&&!i(k))k=k.getNext(i);return k;},getLast:function(i){var j=this.$.lastChild,k=j&&new d.node(j);if(k&&i&&!i(k))k=k.getPrevious(i);return k;},getStyle:function(i){return this.$.style[e.cssStyleToDomStyle(i)]; +},is:function(){var i=this.getName();for(var j=0;j0&&(j>2||!k[i[0].nodeName]||j==2&&!k[i[1].nodeName]);},hasAttribute:(function(){function i(j){var k=this.$.attributes.getNamedItem(j);return!!(k&&k.specified);};return c&&b.version<8?function(j){if(j=='name')return!!this.$.name;return i.call(this,j);}:i;})(),hide:function(){this.setStyle('display','none');},moveChildren:function(i,j){var k=this.$;i=i.$;if(k==i)return;var l;if(j)while(l=k.lastChild)i.insertBefore(k.removeChild(l),i.firstChild);else while(l=k.firstChild)i.appendChild(k.removeChild(l));},mergeSiblings:(function(){function i(j,k,l){if(k&&k.type==1){var m=[];while(k.data('cke-bookmark')||k.isEmptyInlineRemoveable()){m.push(k);k=l?k.getNext():k.getPrevious();if(!k||k.type!=1)return;}if(j.isIdentical(k)){var n=l?j.getLast():j.getFirst(); +while(m.length)m.shift().move(j,!l);k.moveChildren(j,!l);k.remove();if(n&&n.type==1)n.mergeSiblings();}}};return function(j){var k=this;if(!(j===false||f.$removeEmpty[k.getName()]||k.is('a')))return;i(k,k.getNext(),true);i(k,k.getPrevious());};})(),show:function(){this.setStyles({display:'',visibility:''});},setAttribute:(function(){var i=function(j,k){this.$.setAttribute(j,k);return this;};if(c&&(b.ie7Compat||b.ie6Compat))return function(j,k){var l=this;if(j=='class')l.$.className=k;else if(j=='style')l.$.style.cssText=k;else if(j=='tabindex')l.$.tabIndex=k;else if(j=='checked')l.$.checked=k;else i.apply(l,arguments);return l;};else if(b.ie8Compat&&b.secure)return function(j,k){if(j=='src'&&k.match(/^http:\/\//))try{i.apply(this,arguments);}catch(l){}else i.apply(this,arguments);return this;};else return i;})(),setAttributes:function(i){for(var j in i)this.setAttribute(j,i[j]);return this;},setValue:function(i){this.$.value=i;return this;},removeAttribute:(function(){var i=function(j){this.$.removeAttribute(j);};if(c&&(b.ie7Compat||b.ie6Compat))return function(j){if(j=='class')j='className';else if(j=='tabindex')j='tabIndex';i.call(this,j);};else return i;})(),removeAttributes:function(i){if(e.isArray(i))for(var j=0;j=100?'':'progid:DXImageTransform.Microsoft.Alpha(opacity='+i+')');}else this.setStyle('opacity',i);},unselectable:b.gecko?function(){this.$.style.MozUserSelect='none';this.on('dragstart',function(i){i.data.preventDefault();});}:b.webkit?function(){this.$.style.KhtmlUserSelect='none';this.on('dragstart',function(i){i.data.preventDefault();});}:function(){if(c||b.opera){var i=this.$,j,k=0;i.unselectable='on';while(j=i.all[k++])switch(j.tagName.toLowerCase()){case 'iframe':case 'textarea':case 'input':case 'select':break;default:j.unselectable='on';}}},getPositionedAncestor:function(){var i=this;while(i.getName()!='html'){if(i.getComputedStyle('position')!='static')return i;i=i.getParent();}return null;},getDocumentPosition:function(i){var D=this; +var j=0,k=0,l=D.getDocument(),m=l.getBody(),n=l.$.compatMode=='BackCompat';if(document.documentElement.getBoundingClientRect){var o=D.$.getBoundingClientRect(),p=l.$,q=p.documentElement,r=q.clientTop||m.$.clientTop||0,s=q.clientLeft||m.$.clientLeft||0,t=true;if(c){var u=l.getDocumentElement().contains(D),v=l.getBody().contains(D);t=n&&v||!n&&u;}if(t){j=o.left+(!n&&q.scrollLeft||m.$.scrollLeft);j-=s;k=o.top+(!n&&q.scrollTop||m.$.scrollTop);k-=r;}}else{var w=D,x=null,y;while(w&&!(w.getName()=='body'||w.getName()=='html')){j+=w.$.offsetLeft-w.$.scrollLeft;k+=w.$.offsetTop-w.$.scrollTop;if(!w.equals(D)){j+=w.$.clientLeft||0;k+=w.$.clientTop||0;}var z=x;while(z&&!z.equals(w)){j-=z.$.scrollLeft;k-=z.$.scrollTop;z=z.getParent();}x=w;w=(y=w.$.offsetParent)?new h(y):null;}}if(i){var A=D.getWindow(),B=i.getWindow();if(!A.equals(B)&&A.$.frameElement){var C=new h(A.$.frameElement).getDocumentPosition(i);j+=C.x;k+=C.y;}}if(!document.documentElement.getBoundingClientRect)if(b.gecko&&!n){j+=D.$.clientLeft?1:0;k+=D.$.clientTop?1:0;}return{x:j,y:k};},scrollIntoView:function(i){var o=this;var j=o.getWindow(),k=j.getViewPaneSize().height,l=k*-1;if(i)l+=k;else{l+=o.$.offsetHeight||0;l+=parseInt(o.getComputedStyle('marginBottom')||0,10)||0;}var m=o.getDocumentPosition();l+=m.y;l=l<0?0:l;var n=j.getScrollPosition().y;if(l>n||lwindow.setTimeout(function(){window.close();},50);")');}return i&&new g(i.contentWindow.document);},copyAttributes:function(i,j){var p=this;var k=p.$.attributes;j=j||{};for(var l=0;l0&&j)j=j.childNodes[i.shift()];return j?new d.node(j):null;},getChildCount:function(){return this.$.childNodes.length;},disableContextMenu:function(){this.on('contextmenu',function(i){if(!i.data.getTarget().hasClass('cke_enable_context_menu'))i.data.preventDefault();});},getDirection:function(i){var j=this;return i?j.getComputedStyle('direction')||j.getDirection()||j.getDocument().$.dir||j.getDocument().getBody().getDirection(1):j.getStyle('direction')||j.getAttribute('dir');},data:function(i,j){i='data-'+i;if(j===undefined)return this.getAttribute(i);else if(j===false)this.removeAttribute(i);else this.setAttribute(i,j);return null;}});(function(){var i={width:['border-left-width','border-right-width','padding-left','padding-right'],height:['border-top-width','border-bottom-width','padding-top','padding-bottom']};function j(k){var l=0;for(var m=0,n=i[k].length;m',bodyId:'',bodyClass:'',fullPage:false,height:200,plugins:'about,a11yhelp,basicstyles,bidi,blockquote,button,clipboard,colorbutton,colordialog,contextmenu,dialogadvtab,div,elementspath,enterkey,entities,filebrowser,find,flash,font,format,forms,horizontalrule,htmldataprocessor,iframe,image,indent,justify,keystrokes,link,list,liststyle,maximize,newpage,pagebreak,pastefromword,pastetext,popup,preview,print,removeformat,resize,save,scayt,smiley,showblocks,showborders,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,toolbar,undo,wysiwygarea,wsc',extraPlugins:'',removePlugins:'',protectedSource:[],tabIndex:0,theme:'default',skin:'kama',width:'',baseFloatZIndex:10000}; +var i=a.config;a.focusManager=function(j){if(j.focusManager)return j.focusManager;this.hasFocus=false;this._={editor:j};return this;};a.focusManager.prototype={focus:function(){var k=this;if(k._.timer)clearTimeout(k._.timer);if(!k.hasFocus){if(a.currentInstance)a.currentInstance.focusManager.forceBlur();var j=k._.editor;j.container.getChild(1).addClass('cke_focus');k.hasFocus=true;j.fire('focus');}},blur:function(){var j=this;if(j._.timer)clearTimeout(j._.timer);j._.timer=setTimeout(function(){delete j._.timer;j.forceBlur();},100);},forceBlur:function(){if(this.hasFocus){var j=this._.editor;j.container.getChild(1).removeClass('cke_focus');this.hasFocus=false;j.fire('blur');}}};(function(){var j={};a.lang={languages:{af:1,ar:1,bg:1,bn:1,bs:1,ca:1,cs:1,cy:1,da:1,de:1,el:1,'en-au':1,'en-ca':1,'en-gb':1,en:1,eo:1,es:1,et:1,eu:1,fa:1,fi:1,fo:1,'fr-ca':1,fr:1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,is:1,it:1,ja:1,ka:1,km:1,ko:1,lt:1,lv:1,mn:1,ms:1,nb:1,nl:1,no:1,pl:1,'pt-br':1,pt:1,ro:1,ru:1,sk:1,sl:1,'sr-latn':1,sr:1,sv:1,th:1,tr:1,uk:1,vi:1,'zh-cn':1,zh:1},load:function(k,l,m){if(!k||!a.lang.languages[k])k=this.detect(l,k);if(!this[k])a.scriptLoader.load(a.getUrl('lang/'+k+'.js'),function(){m(k,this[k]);},this);else m(k,this[k]);},detect:function(k,l){var m=this.languages;l=l||navigator.userLanguage||navigator.language||k;var n=l.toLowerCase().match(/([a-z]+)(?:-([a-z]+))?/),o=n[1],p=n[2];if(m[o+'-'+p])o=o+'-'+p;else if(!m[o])o=null;a.lang.detect=o?function(){return o;}:function(q){return q;};return o||k;}};})();a.scriptLoader=(function(){var j={},k={};return{load:function(l,m,n,o){var p=typeof l=='string';if(p)l=[l];if(!n)n=a;var q=l.length,r=[],s=[],t=function(y){if(m)if(p)m.call(n,y);else m.call(n,r,s);};if(q===0){t(true);return;}var u=function(y,z){(z?r:s).push(y);if(--q<=0){o&&a.document.getDocumentElement().removeStyle('cursor');t(z);}},v=function(y,z){j[y]=1;var A=k[y];delete k[y];for(var B=0;B1)return;var A=new h('script');A.setAttributes({type:'text/javascript',src:y});if(m)if(c)A.$.onreadystatechange=function(){if(A.$.readyState=='loaded'||A.$.readyState=='complete'){A.$.onreadystatechange=null;v(y,true);}};else{A.$.onload=function(){setTimeout(function(){v(y,true);},0);};A.$.onerror=function(){v(y,false);};}A.appendTo(a.document.getHead());};o&&a.document.getDocumentElement().setStyle('cursor','wait');for(var x=0;x1)return;var w=!p.css||!p.css.length,x=!p.js||!p.js.length,y=function(){if(w&&x){p._isLoaded=1;for(var B=0;B=0?x.langCode:J[0];if(!I.langEntries||!I.langEntries[L])G.push(a.getUrl(K+'lang/'+L+'.js'));else{e.extend(x.lang,I.langEntries[L]);L=null;}}F.push(L);E.push(I);}a.scriptLoader.load(G,function(){var M=['beforeInit','init','afterInit'];for(var N=0;N]+)>)|(?:!--([\\S|\\s]*?)-->)|(?:([^\\s>]+)\\s*((?:(?:\"[^\"]*\")|(?:'[^']*')|[^\"'>])*)\\/?>))",'g')};};(function(){var l=/([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,m={checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1};a.htmlParser.prototype={onTagOpen:function(){},onTagClose:function(){},onText:function(){},onCDATA:function(){},onComment:function(){},parse:function(n){var A=this;var o,p,q=0,r;while(o=A._.htmlPartsRegex.exec(n)){var s=o.index;if(s>q){var t=n.substring(q,s);if(r)r.push(t);else A.onText(t);}q=A._.htmlPartsRegex.lastIndex;if(p=o[1]){p=p.toLowerCase();if(r&&f.$cdata[p]){A.onCDATA(r.join(''));r=null;}if(!r){A.onTagClose(p);continue;}}if(r){r.push(o[0]);continue;}if(p=o[3]){p=p.toLowerCase();if(/="/.test(p))continue; +var u={},v,w=o[4],x=!!(w&&w.charAt(w.length-1)=='/');if(w)while(v=l.exec(w)){var y=v[1].toLowerCase(),z=v[2]||v[3]||v[4]||'';if(!z&&m[y])u[y]=y;else u[y]=z;}A.onTagOpen(p,u,x);if(!r&&f.$cdata[p])r=[];continue;}if(p=o[2])A.onComment(p);}if(n.length>q)A.onText(n.substring(q,n.length));}};})();a.htmlParser.comment=function(l){this.value=l;this._={isBlockLike:false};};a.htmlParser.comment.prototype={type:8,writeHtml:function(l,m){var n=this.value;if(m){if(!(n=m.onComment(n,this)))return;if(typeof n!='string'){n.parent=this.parent;n.writeHtml(l,m);return;}}l.comment(n);}};(function(){a.htmlParser.text=function(l){this.value=l;this._={isBlockLike:false};};a.htmlParser.text.prototype={type:3,writeHtml:function(l,m){var n=this.value;if(m&&!(n=m.onText(n,this)))return;l.text(n);}};})();(function(){a.htmlParser.cdata=function(l){this.value=l;};a.htmlParser.cdata.prototype={type:3,writeHtml:function(l){l.write(this.value);}};})();a.htmlParser.fragment=function(){this.children=[];this.parent=null;this._={isBlockLike:true,hasInlineStarted:false};};(function(){var l=e.extend({table:1,ul:1,ol:1,dl:1},f.table,f.ul,f.ol,f.dl),m=c&&b.version<8?{dd:1,dt:1}:{},n={ol:1,ul:1},o=e.extend({},{html:1},f.html,f.body,f.head,{style:1,script:1});function p(q){return q.name=='a'&&q.attributes.href||f.$removeEmpty[q.name];};a.htmlParser.fragment.fromHtml=function(q,r,s){var t=new a.htmlParser(),u=s||new a.htmlParser.fragment(),v=[],w=[],x=u,y=false,z=false;function A(D){var E;if(v.length>0)for(var F=0;F=0;E--){if(D==v[E].name){v.splice(E,1);return;}}var F=[],G=[],H=x;while(H!=u&&H.name!=D){if(!H._.isBlockLike)G.unshift(H);F.push(H);H=H.returnPoint||H.parent;}if(H!=u){for(E=0;E0?t.children[r-1]:null;if(s){if(q._.isBlockLike&&s.type==3){s.value=e.rtrim(s.value);if(s.value.length===0){t.children.pop();t.add(q);return;}}s.next=q;}q.previous=s;q.parent=t;t.children.splice(r,0,q);t._.hasInlineStarted=q.type==3||q.type==1&&!q._.isBlockLike;},writeHtml:function(q,r){var s;this.filterChildren=function(){var t=new a.htmlParser.basicWriter();this.writeChildrenHtml.call(this,t,r,true);var u=t.getHtml();this.children=new a.htmlParser.fragment.fromHtml(u).children;s=1;};!this.name&&r&&r.onFragment(this);this.writeChildrenHtml(q,s?null:r);},writeChildrenHtml:function(q,r){for(var s=0;sn?1:0;};a.htmlParser.element.prototype={type:1,add:a.htmlParser.fragment.prototype.add,clone:function(){return new a.htmlParser.element(this.name,this.attributes);},writeHtml:function(m,n){var o=this.attributes,p=this,q=p.name,r,s,t,u;p.filterChildren=function(){if(!u){var B=new a.htmlParser.basicWriter();a.htmlParser.fragment.prototype.writeChildrenHtml.call(p,B,n);p.children=new a.htmlParser.fragment.fromHtml(B.getHtml(),0,p.clone()).children;u=1;}};if(n){for(;;){if(!(q=n.onElementName(q)))return;p.name=q;if(!(p=n.onElement(p)))return;p.parent=this.parent;if(p.name==q)break;if(p.type!=1){p.writeHtml(m,n);return;}q=p.name;if(!q){for(var v=0,w=this.children.length;v=0;u--){var x=r[u];if(x){x.pri=s;q.splice(t,0,x);}}}};function n(q,r,s){if(r)for(var t in r){var u=q[t];q[t]=o(u,r[t],s);if(!u)q.$length++;}};function o(q,r,s){if(r){r.pri=s;if(q){if(!q.splice){if(q.pri>s)q=[r,q];else q=[q,r];q.filter=p;}else m(q,r,s);return q;}else{r.filter=r;return r;}}};function p(q){var r=q.type||q instanceof a.htmlParser.fragment;for(var s=0;s');else this._.output.push('>');},attribute:function(l,m){if(typeof m=='string')m=e.htmlEncodeAttr(m);this._.output.push(' ',l,'="',m,'"');},closeTag:function(l){this._.output.push('');},text:function(l){this._.output.push(l);},comment:function(l){this._.output.push('');},write:function(l){this._.output.push(l);},reset:function(){this._.output=[];this._.indent=false;},getHtml:function(l){var m=this._.output.join('');if(l)this.reset();return m;}}});delete a.loadFullCore;a.instances={};a.document=new g(document);a.add=function(l){a.instances[l.name]=l; +l.on('focus',function(){if(a.currentInstance!=l){a.currentInstance=l;a.fire('currentInstance');}});l.on('blur',function(){if(a.currentInstance==l){a.currentInstance=null;a.fire('currentInstance');}});};a.remove=function(l){delete a.instances[l.name];};a.on('instanceDestroyed',function(){if(e.isEmpty(this.instances))a.fire('reset');});a.TRISTATE_ON=1;a.TRISTATE_OFF=2;a.TRISTATE_DISABLED=0;d.comment=e.createClass({base:d.node,$:function(l,m){if(typeof l=='string')l=(m?m.$:document).createComment(l);this.base(l);},proto:{type:8,getOuterHtml:function(){return '';}}});(function(){var l={address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,li:1,dt:1,dd:1,legend:1,caption:1},m={body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,form:1,fieldset:1},n=function(o){var p=o.getChildren();for(var q=0,r=p.count();q0&&C.getChild(v.startOffset-1);this._.guardRTL=function(F,G){return(!G||!C.equals(F))&&(!D||!F.equals(D))&&(F.type!=1||!G||F.getName()!='body');};}var E=s?this._.guardRTL:this._.guardLTR;if(x)w=function(F,G){if(E(F,G)===false)return false;return x(F,G);};else w=E;if(this.current)u=this.current[z](false,y,w);else if(s){u=v.endContainer;if(v.endOffset>0){u=u.getChild(v.endOffset-1);if(w(u)===false)u=null;}else u=w(u,true)===false?null:u.getPreviousSourceNode(true,y,w);}else{u=v.startContainer;u=u.getChild(v.startOffset);if(u){if(w(u)===false)u=null;}else u=w(v.startContainer,true)===false?null:v.startContainer.getNextSourceNode(true,y,w);}while(u&&!this._.end){this.current=u;if(!this.evaluator||this.evaluator(u)!==false){if(!t)return u;}else if(t&&this.evaluator)return false;u=u[z](false,y,w);}this.end();return this.current=null;};function m(s){var t,u=null;while(t=l.call(this,s))u=t;return u;};d.walker=e.createClass({$:function(s){this.range=s;this._={};},proto:{end:function(){this._.end=1;},next:function(){return l.call(this);},previous:function(){return l.call(this,1);},checkForward:function(){return l.call(this,0,1)!==false;},checkBackward:function(){return l.call(this,1,1)!==false;},lastForward:function(){return m.call(this);},lastBackward:function(){return m.call(this,1);},reset:function(){delete this.current;this._={};}}});var n={block:1,'list-item':1,table:1,'table-row-group':1,'table-header-group':1,'table-footer-group':1,'table-row':1,'table-column-group':1,'table-column':1,'table-cell':1,'table-caption':1};h.prototype.isBlockBoundary=function(s){var t=s?e.extend({},f.$block,s||{}):f.$block;return this.getComputedStyle('float')=='none'&&n[this.getComputedStyle('display')]||t[this.getName()];};d.walker.blockBoundary=function(s){return function(t,u){return!(t.type==1&&t.isBlockBoundary(s)); +};};d.walker.listItemBoundary=function(){return this.blockBoundary({br:1});};d.walker.bookmark=function(s,t){function u(v){return v&&v.getName&&v.getName()=='span'&&v.data('cke-bookmark');};return function(v){var w,x;w=v&&!v.getName&&(x=v.getParent())&&u(x);w=s?w:w||u(v);return!!(t^w);};};d.walker.whitespaces=function(s){return function(t){var u=t&&t.type==3&&!e.trim(t.getText());return!!(s^u);};};d.walker.invisible=function(s){var t=d.walker.whitespaces();return function(u){var v=t(u)||u.is&&!u.$.offsetHeight;return!!(s^v);};};d.walker.nodeType=function(s,t){return function(u){return!!(t^u.type==s);};};var o=/^[\t\r\n ]*(?: |\xa0)$/,p=d.walker.whitespaces(),q=d.walker.bookmark(),r=function(s){return q(s)||p(s)||s.type==1&&s.getName() in f.$inline&&!(s.getName() in f.$empty);};h.prototype.getBogus=function(){var s=this;do s=s.getPreviousSourceNode();while(r(s));if(s&&(!c?s.is&&s.is('br'):s.getText&&o.test(s.getText())))return s;return false;};})();d.range=function(l){var m=this;m.startContainer=null;m.startOffset=null;m.endContainer=null;m.endOffset=null;m.collapsed=true;m.document=l;};(function(){var l=function(t){t.collapsed=t.startContainer&&t.endContainer&&t.startContainer.equals(t.endContainer)&&t.startOffset==t.endOffset;},m=function(t,u,v,w){t.optimizeBookmark();var x=t.startContainer,y=t.endContainer,z=t.startOffset,A=t.endOffset,B,C;if(y.type==3)y=y.split(A);else if(y.getChildCount()>0)if(A>=y.getChildCount()){y=y.append(t.document.createText(''));C=true;}else y=y.getChild(A);if(x.type==3){x.split(z);if(x.equals(y))y=x.getNext();}else if(!z){x=x.getFirst().insertBeforeMe(t.document.createText(''));B=true;}else if(z>=x.getChildCount()){x=x.append(t.document.createText(''));B=true;}else x=x.getChild(z).getPrevious();var D=x.getParents(),E=y.getParents(),F,G,H;for(F=0;F0&&!J.equals(y))K=I.append(J.clone());if(!D[O]||J.$.parentNode!=D[O].$.parentNode){L=J.getPrevious();while(L){if(L.equals(D[O])||L.equals(x))break;M=L.getPrevious();if(u==2)I.$.insertBefore(L.$.cloneNode(true),I.$.firstChild);else{L.remove();if(u==1)I.$.insertBefore(L.$,I.$.firstChild);}L=M;}}if(I)I=K;}if(u==2){var P=t.startContainer;if(P.type==3){P.$.data+=P.$.nextSibling.data; +P.$.parentNode.removeChild(P.$.nextSibling);}var Q=t.endContainer;if(Q.type==3&&Q.$.nextSibling){Q.$.data+=Q.$.nextSibling.data;Q.$.parentNode.removeChild(Q.$.nextSibling);}}else{if(G&&H&&(x.$.parentNode!=G.$.parentNode||y.$.parentNode!=H.$.parentNode)){var R=H.getIndex();if(B&&H.$.parentNode==x.$.parentNode)R--;if(w&&G.type==1){var S=h.createFromHtml(' ',t.document);S.insertAfter(G);G.mergeSiblings(false);t.moveToBookmark({startNode:S});}else t.setStart(H.getParent(),R);}t.collapse(true);}if(B)x.remove();if(C&&y.$.parentNode)y.remove();},n={abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1};function o(t){var u=false,v=d.walker.bookmark(true);return function(w){if(v(w))return true;if(w.type==3){if(w.hasAscendant('pre')||e.trim(w.getText()).length)return false;}else if(w.type==1)if(!n[w.getName()])if(!t&&!c&&w.getName()=='br'&&!u)u=true;else return false;return true;};};function p(t){return t.type!=3&&t.getName() in f.$removeEmpty||!e.trim(t.getText())||!!t.getParent().data('cke-bookmark');};var q=new d.walker.whitespaces(),r=new d.walker.bookmark();function s(t){return!q(t)&&!r(t);};d.range.prototype={clone:function(){var u=this;var t=new d.range(u.document);t.startContainer=u.startContainer;t.startOffset=u.startOffset;t.endContainer=u.endContainer;t.endOffset=u.endOffset;t.collapsed=u.collapsed;return t;},collapse:function(t){var u=this;if(t){u.endContainer=u.startContainer;u.endOffset=u.startOffset;}else{u.startContainer=u.endContainer;u.startOffset=u.endOffset;}u.collapsed=true;},cloneContents:function(){var t=new d.documentFragment(this.document);if(!this.collapsed)m(this,2,t);return t;},deleteContents:function(t){if(this.collapsed)return;m(this,0,null,t);},extractContents:function(t){var u=new d.documentFragment(this.document);if(!this.collapsed)m(this,1,u,t);return u;},createBookmark:function(t){var z=this;var u,v,w,x,y=z.collapsed;u=z.document.createElement('span');u.data('cke-bookmark',1);u.setStyle('display','none');u.setHtml(' ');if(t){w='cke_bm_'+e.getNextNumber();u.setAttribute('id',w+'S');}if(!y){v=u.clone();v.setHtml(' ');if(t)v.setAttribute('id',w+'E');x=z.clone();x.collapse();x.insertNode(v);}x=z.clone();x.collapse(true);x.insertNode(u);if(v){z.setStartAfter(u);z.setEndBefore(v);}else z.moveToPosition(u,4);return{startNode:t?w+'S':u,endNode:t?w+'E':v,serializable:t,collapsed:y}; +},createBookmark2:function(t){var B=this;var u=B.startContainer,v=B.endContainer,w=B.startOffset,x=B.endOffset,y=B.collapsed,z,A;if(!u||!v)return{start:0,end:0};if(t){if(u.type==1){z=u.getChild(w);if(z&&z.type==3&&w>0&&z.getPrevious().type==3){u=z;w=0;}if(z&&z.type==1)w=z.getIndex(1);}while(u.type==3&&(A=u.getPrevious())&&A.type==3){u=A;w+=A.getLength();}if(!y){if(v.type==1){z=v.getChild(x);if(z&&z.type==3&&x>0&&z.getPrevious().type==3){v=z;x=0;}if(z&&z.type==1)x=z.getIndex(1);}while(v.type==3&&(A=v.getPrevious())&&A.type==3){v=A;x+=A.getLength();}}}return{start:u.getAddress(t),end:y?null:v.getAddress(t),startOffset:w,endOffset:x,normalized:t,collapsed:y,is2:true};},moveToBookmark:function(t){var B=this;if(t.is2){var u=B.document.getByAddress(t.start,t.normalized),v=t.startOffset,w=t.end&&B.document.getByAddress(t.end,t.normalized),x=t.endOffset;B.setStart(u,v);if(w)B.setEnd(w,x);else B.collapse(true);}else{var y=t.serializable,z=y?B.document.getById(t.startNode):t.startNode,A=y?B.document.getById(t.endNode):t.endNode;B.setStartBefore(z);z.remove();if(A){B.setEndBefore(A);A.remove();}else B.collapse(true);}},getBoundaryNodes:function(){var y=this;var t=y.startContainer,u=y.endContainer,v=y.startOffset,w=y.endOffset,x;if(t.type==1){x=t.getChildCount();if(x>v)t=t.getChild(v);else if(x<1)t=t.getPreviousSourceNode();else{t=t.$;while(t.lastChild)t=t.lastChild;t=new d.node(t);t=t.getNextSourceNode()||t;}}if(u.type==1){x=u.getChildCount();if(x>w)u=u.getChild(w).getPreviousSourceNode(true);else if(x<1)u=u.getPreviousSourceNode();else{u=u.$;while(u.lastChild)u=u.lastChild;u=new d.node(u);}}if(t.getPosition(u)&2)t=u;return{startNode:t,endNode:u};},getCommonAncestor:function(t,u){var y=this;var v=y.startContainer,w=y.endContainer,x;if(v.equals(w)){if(t&&v.type==1&&y.startOffset==y.endOffset-1)x=v.getChild(y.startOffset);else x=v;}else x=v.getCommonAncestor(w);return u&&!x.is?x.getParent():x;},optimize:function(){var v=this;var t=v.startContainer,u=v.startOffset;if(t.type!=1)if(!u)v.setStartBefore(t);else if(u>=t.getLength())v.setStartAfter(t);t=v.endContainer;u=v.endOffset;if(t.type!=1)if(!u)v.setEndBefore(t);else if(u>=t.getLength())v.setEndAfter(t);},optimizeBookmark:function(){var v=this;var t=v.startContainer,u=v.endContainer;if(t.is&&t.is('span')&&t.data('cke-bookmark'))v.setStartAt(t,3);if(u&&u.is&&u.is('span')&&u.data('cke-bookmark'))v.setEndAt(u,4);},trim:function(t,u){var B=this;var v=B.startContainer,w=B.startOffset,x=B.collapsed;if((!t||x)&&v&&v.type==3){if(!w){w=v.getIndex(); +v=v.getParent();}else if(w>=v.getLength()){w=v.getIndex()+1;v=v.getParent();}else{var y=v.split(w);w=v.getIndex()+1;v=v.getParent();if(B.startContainer.equals(B.endContainer))B.setEnd(y,B.endOffset-B.startOffset);else if(v.equals(B.endContainer))B.endOffset+=1;}B.setStart(v,w);if(x){B.collapse(true);return;}}var z=B.endContainer,A=B.endOffset;if(!(u||x)&&z&&z.type==3){if(!A){A=z.getIndex();z=z.getParent();}else if(A>=z.getLength()){A=z.getIndex()+1;z=z.getParent();}else{z.split(A);A=z.getIndex()+1;z=z.getParent();}B.setEnd(z,A);}},enlarge:function(t,u){switch(t){case 1:if(this.collapsed)return;var v=this.getCommonAncestor(),w=this.document.getBody(),x,y,z,A,B,C=false,D,E,F=this.startContainer,G=this.startOffset;if(F.type==3){if(G){F=!e.trim(F.substring(0,G)).length&&F;C=!!F;}if(F)if(!(A=F.getPrevious()))z=F.getParent();}else{if(G)A=F.getChild(G-1)||F.getLast();if(!A)z=F;}while(z||A){if(z&&!A){if(!B&&z.equals(v))B=true;if(!w.contains(z))break;if(!C||z.getComputedStyle('display')!='inline'){C=false;if(B)x=z;else this.setStartBefore(z);}A=z.getPrevious();}while(A){D=false;if(A.type==3){E=A.getText();if(/[^\s\ufeff]/.test(E))A=null;D=/[\s\ufeff]$/.test(E);}else if((A.$.offsetWidth>0||u&&A.is('br'))&&!A.data('cke-bookmark'))if(C&&f.$removeEmpty[A.getName()]){E=A.getText();if(/[^\s\ufeff]/.test(E))A=null;else{var H=A.$.all||A.$.getElementsByTagName('*');for(var I=0,J;J=H[I++];){if(!f.$removeEmpty[J.nodeName.toLowerCase()]){A=null;break;}}}if(A)D=!!E.length;}else A=null;if(D)if(C){if(B)x=z;else if(z)this.setStartBefore(z);}else C=true;if(A){var K=A.getPrevious();if(!z&&!K){z=A;A=null;break;}A=K;}else z=null;}if(z)z=z.getParent();}F=this.endContainer;G=this.endOffset;z=A=null;B=C=false;if(F.type==3){F=!e.trim(F.substring(G)).length&&F;C=!(F&&F.getLength());if(F)if(!(A=F.getNext()))z=F.getParent();}else{A=F.getChild(G);if(!A)z=F;}while(z||A){if(z&&!A){if(!B&&z.equals(v))B=true;if(!w.contains(z))break;if(!C||z.getComputedStyle('display')!='inline'){C=false;if(B)y=z;else if(z)this.setEndAfter(z);}A=z.getNext();}while(A){D=false;if(A.type==3){E=A.getText();if(/[^\s\ufeff]/.test(E))A=null;D=/^[\s\ufeff]/.test(E);}else if((A.$.offsetWidth>0||u&&A.is('br'))&&!A.data('cke-bookmark'))if(C&&f.$removeEmpty[A.getName()]){E=A.getText();if(/[^\s\ufeff]/.test(E))A=null;else{H=A.$.all||A.$.getElementsByTagName('*');for(I=0;J=H[I++];){if(!f.$removeEmpty[J.nodeName.toLowerCase()]){A=null;break;}}}if(A)D=!!E.length;}else A=null;if(D)if(C)if(B)y=z;else this.setEndAfter(z);if(A){K=A.getNext(); +if(!z&&!K){z=A;A=null;break;}A=K;}else z=null;}if(z)z=z.getParent();}if(x&&y){v=x.contains(y)?y:x;this.setStartBefore(v);this.setEndAfter(v);}break;case 2:case 3:var L=new d.range(this.document);w=this.document.getBody();L.setStartAt(w,1);L.setEnd(this.startContainer,this.startOffset);var M=new d.walker(L),N,O,P=d.walker.blockBoundary(t==3?{br:1}:null),Q=function(W){var X=P(W);if(!X)N=W;return X;},R=function(W){var X=Q(W);if(!X&&W.is&&W.is('br'))O=W;return X;};M.guard=Q;z=M.lastBackward();N=N||w;this.setStartAt(N,!N.is('br')&&(!z&&this.checkStartOfBlock()||z&&N.contains(z))?1:4);if(t==3){var S=this.clone();M=new d.walker(S);var T=d.walker.whitespaces(),U=d.walker.bookmark();M.evaluator=function(W){return!T(W)&&!U(W);};var V=M.previous();if(V&&V.type==1&&V.is('br'))return;}L=this.clone();L.collapse();L.setEndAt(w,2);M=new d.walker(L);M.guard=t==3?R:Q;N=null;z=M.lastForward();N=N||w;this.setEndAt(N,!z&&this.checkEndOfBlock()||z&&N.contains(z)?2:3);if(O)this.setEndAfter(O);}},shrink:function(t,u){if(!this.collapsed){t=t||2;var v=this.clone(),w=this.startContainer,x=this.endContainer,y=this.startOffset,z=this.endOffset,A=this.collapsed,B=1,C=1;if(w&&w.type==3)if(!y)v.setStartBefore(w);else if(y>=w.getLength())v.setStartAfter(w);else{v.setStartBefore(w);B=0;}if(x&&x.type==3)if(!z)v.setEndBefore(x);else if(z>=x.getLength())v.setEndAfter(x);else{v.setEndAfter(x);C=0;}var D=new d.walker(v),E=d.walker.bookmark();D.evaluator=function(I){return I.type==(t==1?1:3);};var F;D.guard=function(I,J){if(E(I))return true;if(t==1&&I.type==3)return false;if(J&&I.equals(F))return false;if(!J&&I.type==1)F=I;return true;};if(B){var G=D[t==1?'lastForward':'next']();G&&this.setStartAt(G,u?1:3);}if(C){D.reset();var H=D[t==1?'lastBackward':'previous']();H&&this.setEndAt(H,u?2:4);}return!!(B||C);}},insertNode:function(t){var x=this;x.optimizeBookmark();x.trim(false,true);var u=x.startContainer,v=x.startOffset,w=u.getChild(v);if(w)t.insertBefore(w);else u.append(t);if(t.getParent().equals(x.endContainer))x.endOffset++;x.setStartBefore(t);},moveToPosition:function(t,u){this.setStartAt(t,u);this.collapse(true);},selectNodeContents:function(t){this.setStart(t,0);this.setEnd(t,t.type==3?t.getLength():t.getChildCount());},setStart:function(t,u){var v=this;if(t.type==1&&f.$empty[t.getName()])u=t.getIndex(),t=t.getParent();v.startContainer=t;v.startOffset=u;if(!v.endContainer){v.endContainer=t;v.endOffset=u;}l(v);},setEnd:function(t,u){var v=this;if(t.type==1&&f.$empty[t.getName()])u=t.getIndex()+1,t=t.getParent(); +v.endContainer=t;v.endOffset=u;if(!v.startContainer){v.startContainer=t;v.startOffset=u;}l(v);},setStartAfter:function(t){this.setStart(t.getParent(),t.getIndex()+1);},setStartBefore:function(t){this.setStart(t.getParent(),t.getIndex());},setEndAfter:function(t){this.setEnd(t.getParent(),t.getIndex()+1);},setEndBefore:function(t){this.setEnd(t.getParent(),t.getIndex());},setStartAt:function(t,u){var v=this;switch(u){case 1:v.setStart(t,0);break;case 2:if(t.type==3)v.setStart(t,t.getLength());else v.setStart(t,t.getChildCount());break;case 3:v.setStartBefore(t);break;case 4:v.setStartAfter(t);}l(v);},setEndAt:function(t,u){var v=this;switch(u){case 1:v.setEnd(t,0);break;case 2:if(t.type==3)v.setEnd(t,t.getLength());else v.setEnd(t,t.getChildCount());break;case 3:v.setEndBefore(t);break;case 4:v.setEndAfter(t);}l(v);},fixBlock:function(t,u){var x=this;var v=x.createBookmark(),w=x.document.createElement(u);x.collapse(t);x.enlarge(2);x.extractContents().appendTo(w);w.trim();if(!c)w.appendBogus();x.insertNode(w);x.moveToBookmark(v);return w;},splitBlock:function(t){var D=this;var u=new d.elementPath(D.startContainer),v=new d.elementPath(D.endContainer),w=u.blockLimit,x=v.blockLimit,y=u.block,z=v.block,A=null;if(!w.equals(x))return null;if(t!='br'){if(!y){y=D.fixBlock(true,t);z=new d.elementPath(D.endContainer).block;}if(!z)z=D.fixBlock(false,t);}var B=y&&D.checkStartOfBlock(),C=z&&D.checkEndOfBlock();D.deleteContents();if(y&&y.equals(z))if(C){A=new d.elementPath(D.startContainer);D.moveToPosition(z,4);z=null;}else if(B){A=new d.elementPath(D.startContainer);D.moveToPosition(y,3);y=null;}else{z=D.splitElement(y);if(!c&&!y.is('ul','ol'))y.appendBogus();}return{previousBlock:y,nextBlock:z,wasStartOfBlock:B,wasEndOfBlock:C,elementPath:A};},splitElement:function(t){var w=this;if(!w.collapsed)return null;w.setEndAt(t,2);var u=w.extractContents(),v=t.clone(false);u.appendTo(v);v.insertAfter(t);w.moveToPosition(t,4);return v;},checkBoundaryOfElement:function(t,u){var v=u==1,w=this.clone();w.collapse(v);w[v?'setStartAt':'setEndAt'](t,v?1:2);var x=new d.walker(w);x.evaluator=p;return x[v?'checkBackward':'checkForward']();},checkStartOfBlock:function(){var z=this;var t=z.startContainer,u=z.startOffset;if(u&&t.type==3){var v=e.ltrim(t.substring(0,u));if(v.length)return false;}z.trim();var w=new d.elementPath(z.startContainer),x=z.clone();x.collapse(true);x.setStartAt(w.block||w.blockLimit,1);var y=new d.walker(x);y.evaluator=o(true);return y.checkBackward();},checkEndOfBlock:function(){var z=this; +var t=z.endContainer,u=z.endOffset;if(t.type==3){var v=e.rtrim(t.substring(u));if(v.length)return false;}z.trim();var w=new d.elementPath(z.endContainer),x=z.clone();x.collapse(false);x.setEndAt(w.block||w.blockLimit,2);var y=new d.walker(x);y.evaluator=o(false);return y.checkForward();},checkReadOnly:(function(){function t(u,v){while(u){if(u.type==1)if(u.getAttribute('contentEditable')=='false'&&!u.data('cke-editable'))return 0;else if(u.is('html')||u.getAttribute('contentEditable')=='true'&&(u.contains(v)||u.equals(v)))break;u=u.getParent();}return 1;};return function(){var u=this.startContainer,v=this.endContainer;return!(t(u,v)&&t(v,u));};})(),moveToElementEditablePosition:function(t,u){function v(x,y){var z;if(x.type==1&&x.isEditable(false)&&!f.$nonEditable[x.getName()])z=x[u?'getLast':'getFirst'](s);if(!y&&!z)z=x[u?'getPrevious':'getNext'](s);return z;};var w=0;while(t){if(t.type==3){this.moveToPosition(t,u?4:3);w=1;break;}if(t.type==1)if(t.isEditable()){this.moveToPosition(t,u?2:1);w=1;}t=v(t,w);}return!!w;},moveToElementEditStart:function(t){return this.moveToElementEditablePosition(t);},moveToElementEditEnd:function(t){return this.moveToElementEditablePosition(t,true);},getEnclosedNode:function(){var t=this.clone();t.optimize();if(t.startContainer.type!=1||t.endContainer.type!=1)return null;var u=new d.walker(t),v=d.walker.bookmark(true),w=d.walker.whitespaces(true),x=function(z){return w(z)&&v(z);};t.evaluator=x;var y=u.next();u.reset();return y&&y.equals(u.previous())?y:null;},getTouchedStartNode:function(){var t=this.startContainer;if(this.collapsed||t.type!=1)return t;return t.getChild(this.startOffset)||t;},getTouchedEndNode:function(){var t=this.endContainer;if(this.collapsed||t.type!=1)return t;return t.getChild(this.endOffset-1)||t;}};})();a.POSITION_AFTER_START=1;a.POSITION_BEFORE_END=2;a.POSITION_BEFORE_START=3;a.POSITION_AFTER_END=4;a.ENLARGE_ELEMENT=1;a.ENLARGE_BLOCK_CONTENTS=2;a.ENLARGE_LIST_ITEM_CONTENTS=3;a.START=1;a.END=2;a.STARTEND=3;a.SHRINK_ELEMENT=1;a.SHRINK_TEXT=2;(function(){d.rangeList=function(n){if(n instanceof d.rangeList)return n;if(!n)n=[];else if(n instanceof d.range)n=[n];return e.extend(n,l);};var l={createIterator:function(){var n=this,o=d.walker.bookmark(),p=function(s){return!(s.is&&s.is('tr'));},q=[],r;return{getNextRange:function(s){r=r==undefined?0:r+1;var t=n[r];if(t&&n.length>1){if(!r)for(var u=n.length-1;u>=0;u--)q.unshift(n[u].createBookmark(true));if(s){var v=0;while(n[r+v+1]){var w=t.document,x=0,y=w.getById(q[v].endNode),z=w.getById(q[v+1].startNode),A; +while(1){A=y.getNextSourceNode(false);if(!z.equals(A)){if(o(A)||A.type==1&&A.isBlockBoundary()){y=A;continue;}}else x=1;break;}if(!x)break;v++;}}t.moveToBookmark(q.shift());while(v--){A=n[++r];A.moveToBookmark(q.shift());t.setEnd(A.endContainer,A.endOffset);}}return t;}};},createBookmarks:function(n){var s=this;var o=[],p;for(var q=0;q',a.document);l.appendTo(a.document.getHead());try{b.hc=l.getComputedStyle('border-top-color')==l.getComputedStyle('border-right-color');}catch(m){b.hc=false;}if(b.hc)b.cssClass+=' cke_hc';l.remove();})();j.load(i.corePlugins.split(','),function(){a.status='loaded';a.fire('loaded');var l=a._.pending;if(l){delete a._.pending;for(var m=0;m0){z=A.shift();while(!z.getParent().equals(D))z=z.getParent();if(!z.equals(H))E.push(z);H=z;}while(E.length>0){z=E.shift();if(z.getName()=='blockquote'){var I=new d.documentFragment(q.document);while(z.getFirst()){I.append(z.getFirst().remove());A.push(I.getLast());}I.replace(z);}else A.push(z);}var J=q.document.createElement('blockquote');J.insertBefore(A[0]);while(A.length>0){z=A.shift();J.append(z);}}else if(r==1){var K=[],L={};while(z=y.getNextParagraph()){var M=null,N=null;while(z.getParent()){if(z.getParent().getName()=='blockquote'){M=z.getParent();N=z;break;}z=z.getParent();}if(M&&N&&!N.getCustomData('blockquote_moveout')){K.push(N);h.setMarker(L,N,'blockquote_moveout',true);}}h.clearAllMarkers(L);var O=[],P=[];L={};while(K.length>0){var Q=K.shift();J=Q.getParent();if(!Q.getPrevious())Q.remove().insertBefore(J);else if(!Q.getNext())Q.remove().insertAfter(J);else{Q.breakParent(Q.getParent());P.push(Q.getNext());}if(!J.getCustomData('blockquote_processed')){P.push(J);h.setMarker(L,J,'blockquote_processed',true);}O.push(Q);}h.clearAllMarkers(L);for(F=P.length-1;F>=0;F--){J=P[F];if(o(J))J.remove();}if(q.config.enterMode==2){var R=true;while(O.length){Q=O.shift();if(Q.getName()=='div'){I=new d.documentFragment(q.document);var S=R&&Q.getPrevious()&&!(Q.getPrevious().type==1&&Q.getPrevious().isBlockBoundary());if(S)I.append(q.document.createElement('br'));var T=Q.getNext()&&!(Q.getNext().type==1&&Q.getNext().isBlockBoundary());while(Q.getFirst())Q.getFirst().remove().appendTo(I);if(T)I.append(q.document.createElement('br'));I.replace(Q);R=false;}}}}s.selectBookmarks(u);q.focus();}};j.add('blockquote',{init:function(q){q.addCommand('blockquote',p);q.ui.addButton('Blockquote',{label:q.lang.blockquote,command:'blockquote'});q.on('selectionChange',n);},requires:['domiterator']});})();j.add('button',{beforeInit:function(m){m.ui.addHandler('button',k.button.handler);}});a.UI_BUTTON='button';k.button=function(m){e.extend(this,m,{title:m.label,className:m.className||m.command&&'cke_button_'+m.command||'',click:m.click||(function(n){n.execCommand(m.command); +})});this._={};};k.button.handler={create:function(m){return new k.button(m);}};(function(){k.button.prototype={render:function(m,n){var o=b,p=this._.id=e.getNextId(),q='',r=this.command,s;this._.editor=m;var t={id:p,button:this,editor:m,focus:function(){var z=a.document.getById(p);z.focus();},execute:function(){if(c&&b.version<7)e.setTimeout(function(){this.button.click(m);},0,this);else this.button.click(m);}},u=e.addFunction(function(z){if(t.onkey){z=new d.event(z);return t.onkey(t,z.getKeystroke())!==false;}}),v=e.addFunction(function(z){var A;if(t.onfocus)A=t.onfocus(t,new d.event(z))!==false;if(b.gecko&&b.version<10900)z.preventBubble();return A;});t.clickFn=s=e.addFunction(t.execute,t);if(this.modes){var w={};function x(){var z=m.mode;if(z){var A=this.modes[z]?w[z]!=undefined?w[z]:2:0;this.setState(m.readOnly&&!this.readOnly?0:A);}};m.on('beforeModeUnload',function(){if(m.mode&&this._.state!=0)w[m.mode]=this._.state;},this);m.on('mode',x,this);!this.readOnly&&m.on('readOnly',x,this);}else if(r){r=m.getCommand(r);if(r){r.on('state',function(){this.setState(r.state);},this);q+='cke_'+(r.state==1?'on':r.state==0?'disabled':'off');}}if(!r)q+='cke_off';if(this.className)q+=' '+this.className;n.push('','=10900&&!o.hc?'':'" href="javascript:void(\''+(this.title||'').replace("'",'')+"')\"",' title="',this.title,'" tabindex="-1" hidefocus="true" role="button" aria-labelledby="'+p+'_label"'+(this.hasArrow?' aria-haspopup="true"':''));if(o.opera||o.gecko&&o.mac)n.push(' onkeypress="return false;"');if(o.gecko)n.push(' onblur="this.style.cssText = this.style.cssText;"');n.push(' onkeydown="return CKEDITOR.tools.callFunction(',u,', event);" onfocus="return CKEDITOR.tools.callFunction(',v,', event);" '+(c?'onclick="return false;" onmouseup':'onclick')+'="CKEDITOR.tools.callFunction(',s,', this); return false;"> ',this.label,'');if(this.hasArrow)n.push(''+(b.hc?'▼':' ')+'');n.push('','');if(this.onRender)this.onRender();return t;},setState:function(m){if(this._.state==m)return false;this._.state=m;var n=a.document.getById(this._.id);if(n){n.setState(m); +m==0?n.setAttribute('aria-disabled',true):n.removeAttribute('aria-disabled');m==1?n.setAttribute('aria-pressed',true):n.removeAttribute('aria-pressed');return true;}else return false;}};})();k.prototype.addButton=function(m,n){this.add(m,'button',n);};(function(){var m=function(y,z){var A=y.document,B=A.getBody(),C=0,D=function(){C=1;};B.on(z,D);(b.version>7?A.$:A.$.selection.createRange()).execCommand(z);B.removeListener(z,D);return C;},n=c?function(y,z){return m(y,z);}:function(y,z){try{return y.document.$.execCommand(z,false,null);}catch(A){return false;}},o=function(y){var z=this;z.type=y;z.canUndo=z.type=='cut';z.startDisabled=true;};o.prototype={exec:function(y,z){this.type=='cut'&&t(y);var A=n(y,this.type);if(!A)alert(y.lang.clipboard[this.type+'Error']);return A;}};var p={canUndo:false,exec:c?function(y){y.focus();if(!y.document.getBody().fire('beforepaste')&&!m(y,'paste')){y.fire('pasteDialog');return false;}}:function(y){try{if(!y.document.getBody().fire('beforepaste')&&!y.document.$.execCommand('Paste',false,null))throw 0;}catch(z){setTimeout(function(){y.fire('pasteDialog');},0);return false;}}},q=function(y){if(this.mode!='wysiwyg')return;switch(y.data.keyCode){case 1114112+86:case 2228224+45:var z=this.document.getBody();if(!c&&z.fire('beforepaste'))y.cancel();else if(b.opera||b.gecko&&b.version<10900)z.fire('paste');return;case 1114112+88:case 2228224+46:var A=this;this.fire('saveSnapshot');setTimeout(function(){A.fire('saveSnapshot');},0);}};function r(y){y.cancel();};function s(y,z,A){var B=this.document;if(B.getById('cke_pastebin'))return;if(z=='text'&&y.data&&y.data.$.clipboardData){var C=y.data.$.clipboardData.getData('text/plain');if(C){y.data.preventDefault();A(C);return;}}var D=this.getSelection(),E=new d.range(B),F=new h(z=='text'?'textarea':b.webkit?'body':'div',B);F.setAttribute('id','cke_pastebin');b.webkit&&F.append(B.createText('\xa0'));B.getBody().append(F);F.setStyles({position:'absolute',top:D.getStartElement().getDocumentPosition().y+'px',width:'1px',height:'1px',overflow:'hidden'});F.setStyle(this.config.contentsLangDirection=='ltr'?'left':'right','-1000px');var G=D.createBookmarks();this.on('selectionChange',r,null,null,0);if(z=='text')F.$.focus();else{E.setStartAt(F,1);E.setEndAt(F,2);E.select(true);}var H=this;window.setTimeout(function(){z=='text'&&b.gecko&&H.focusGrabber.focus();F.remove();H.removeListener('selectionChange',r);var I;F=b.webkit&&(I=F.getFirst())&&I.is&&I.hasClass('Apple-style-span')?I:F;D.selectBookmarks(G); +A(F['get'+(z=='text'?'Value':'Html')]());},0);};function t(y){if(!c||b.quirks)return;var z=y.getSelection(),A;if(z.getType()==3&&(A=z.getSelectedElement())){var B=z.getRanges()[0],C=y.document.createText('');C.insertBefore(A);B.setStartBefore(C);B.setEndAfter(A);z.selectRanges([B]);setTimeout(function(){if(A.getParent()){C.remove();z.selectElement(A);}},0);}};var u;function v(y,z){c&&(u=1);var A=2;try{A=z.document.$.queryCommandEnabled(y)?2:0;}catch(B){}u=0;return A;};var w;function x(){var z=this;if(z.mode!='wysiwyg')return;z.getCommand('cut').setState(w?0:v('Cut',z));z.getCommand('copy').setState(v('Copy',z));var y=w?0:b.webkit?2:v('Paste',z);z.fire('pasteState',y);};j.add('clipboard',{requires:['dialog','htmldataprocessor'],init:function(y){y.on('paste',function(A){var B=A.data;if(B.html)y.insertHtml(B.html);else if(B.text)y.insertText(B.text);setTimeout(function(){y.fire('afterPaste');},0);},null,null,1000);y.on('pasteDialog',function(A){setTimeout(function(){y.openDialog('paste');},0);});y.on('pasteState',function(A){y.getCommand('paste').setState(A.data);});function z(A,B,C,D){var E=y.lang[B];y.addCommand(B,C);y.ui.addButton(A,{label:E,command:B});if(y.addMenuItems)y.addMenuItem(B,{label:E,command:B,group:'clipboard',order:D});};z('Cut','cut',new o('cut'),1);z('Copy','copy',new o('copy'),4);z('Paste','paste',p,8);a.dialog.add('paste',a.getUrl(this.path+'dialogs/paste.js'));y.on('key',q,y);y.on('contentDom',function(){var A=y.document.getBody();A.on(b.webkit?'paste':'beforepaste',function(B){if(u)return;var C={mode:'html'};y.fire('beforePaste',C);s.call(y,B,C.mode,function(D){if(!(D=e.trim(D.replace(/]+data-cke-bookmark[^<]*?<\/span>/ig,''))))return;var E={};E[C.mode]=D;y.fire('paste',E);});});A.on('contextmenu',function(){u=1;setTimeout(function(){u=0;},10);});A.on('beforecut',function(){!u&&t(y);});A.on('mouseup',function(){setTimeout(function(){x.call(y);},0);},y);A.on('keyup',x,y);});y.on('selectionChange',function(A){w=A.data.selection.getRanges()[0].checkReadOnly();x.call(y);});if(y.contextMenu)y.contextMenu.addListener(function(A,B){var C=B.getRanges()[0].checkReadOnly();return{cut:!C&&v('Cut',y),copy:v('Copy',y),paste:!C&&(b.webkit?2:v('Paste',y))};});}});})();j.add('colorbutton',{requires:['panelbutton','floatpanel','styles'],init:function(m){var n=m.config,o=m.lang.colorButton,p;if(!b.hc){q('TextColor','fore',o.textColorTitle);q('BGColor','back',o.bgColorTitle);}function q(t,u,v){var w=e.getNextId()+'_colorBox';m.ui.add(t,'panelbutton',{label:v,title:v,className:'cke_button_'+t.toLowerCase(),modes:{wysiwyg:1},panel:{css:m.skin.editor.css,attributes:{role:'listbox','aria-label':o.panelTitle}},onBlock:function(x,y){y.autoSize=true; +y.element.addClass('cke_colorblock');y.element.setHtml(r(x,u,w));y.element.getDocument().getBody().setStyle('overflow','hidden');k.fire('ready',this);var z=y.keys,A=m.lang.dir=='rtl';z[A?37:39]='next';z[40]='next';z[9]='next';z[A?39:37]='prev';z[38]='prev';z[2228224+9]='prev';z[32]='click';},onOpen:function(){var x=m.getSelection(),y=x&&x.getStartElement(),z=new d.elementPath(y),A;y=z.block||z.blockLimit||m.document.getBody();do A=y&&y.getComputedStyle(u=='back'?'background-color':'color')||'transparent';while(u=='back'&&A=='transparent'&&y&&(y=y.getParent()));if(!A||A=='transparent')A='#ffffff';this._.panel._.iframe.getFrameDocument().getById(w).setStyle('background-color',A);}});};function r(t,u,v){var w=[],x=n.colorButton_colors.split(','),y=x.length+(n.colorButton_enableMore?2:1),z=e.addFunction(function(F,G){if(F=='?'){var H=arguments.callee;function I(K){this.removeListener('ok',I);this.removeListener('cancel',I);K.name=='ok'&&H(this.getContentElement('picker','selectedColor').getValue(),G);};m.openDialog('colordialog',function(){this.on('ok',I);this.on('cancel',I);});return;}m.focus();t.hide(false);m.fire('saveSnapshot');new a.style(n['colorButton_'+G+'Style'],{color:'inherit'}).remove(m.document);if(F){var J=n['colorButton_'+G+'Style'];J.childRule=G=='back'?function(K){return s(K);}:function(K){return!(K.is('a')||K.getElementsByTag('a').count())||s(K);};new a.style(J,{color:F}).apply(m.document);}m.fire('saveSnapshot');});w.push('
      ',o.auto,'
      ');for(var A=0;A');var B=x[A].split('/'),C=B[0],D=B[1]||C;if(!B[1])C='#'+C.replace(/^(.)(.)(.)$/,'$1$1$2$2$3$3');var E=m.lang.colors[D]||D;w.push('');}if(n.colorButton_enableMore===undefined||n.colorButton_enableMore)w.push(''); +w.push('
      ',o.more,'
      ');return w.join('');};function s(t){return t.getAttribute('contentEditable')=='false'||t.getAttribute('data-nostyle');};}});i.colorButton_colors='000,800000,8B4513,2F4F4F,008080,000080,4B0082,696969,B22222,A52A2A,DAA520,006400,40E0D0,0000CD,800080,808080,F00,FF8C00,FFD700,008000,0FF,00F,EE82EE,A9A9A9,FFA07A,FFA500,FFFF00,00FF00,AFEEEE,ADD8E6,DDA0DD,D3D3D3,FFF0F5,FAEBD7,FFFFE0,F0FFF0,F0FFFF,F0F8FF,E6E6FA,FFF';i.colorButton_foreStyle={element:'span',styles:{color:'#(color)'},overrides:[{element:'font',attributes:{color:null}}]};i.colorButton_backStyle={element:'span',styles:{'background-color':'#(color)'}};j.colordialog={init:function(m){m.addCommand('colordialog',new a.dialogCommand('colordialog'));a.dialog.add('colordialog',this.path+'dialogs/colordialog.js');}};j.add('colordialog',j.colordialog);j.add('contextmenu',{requires:['menu'],onLoad:function(){j.contextMenu=e.createClass({base:a.menu,$:function(m){this.base.call(this,m,{panel:{className:m.skinClass+' cke_contextmenu',attributes:{'aria-label':m.lang.contextmenu.options}}});},proto:{addTarget:function(m,n){if(b.opera&&!('oncontextmenu' in document.body)){var o;m.on('mousedown',function(s){s=s.data;if(s.$.button!=2){if(s.getKeystroke()==1114112+1)m.fire('contextmenu',s);return;}if(n&&(b.mac?s.$.metaKey:s.$.ctrlKey))return;var t=s.getTarget();if(!o){var u=t.getDocument();o=u.createElement('input');o.$.type='button';u.getBody().append(o);}o.setAttribute('style','position:absolute;top:'+(s.$.clientY-2)+'px;left:'+(s.$.clientX-2)+'px;width:5px;height:5px;opacity:0.01');});m.on('mouseup',function(s){if(o){o.remove();o=undefined;m.fire('contextmenu',s.data);}});}m.on('contextmenu',function(s){var t=s.data;if(n&&(b.webkit?p:b.mac?t.$.metaKey:t.$.ctrlKey))return;t.preventDefault();var u=t.getTarget().getDocument().getDocumentElement(),v=t.$.clientX,w=t.$.clientY;e.setTimeout(function(){this.open(u,null,v,w);},c?200:0,this);},this);if(b.opera)m.on('keypress',function(s){var t=s.data;if(t.$.keyCode===0)t.preventDefault();});if(b.webkit){var p,q=function(s){p=b.mac?s.data.$.metaKey:s.data.$.ctrlKey;},r=function(){p=0;};m.on('keydown',q);m.on('keyup',r);m.on('contextmenu',r);}},open:function(m,n,o,p){this.editor.focus();m=m||a.document.getDocumentElement();this.show(m,n,o,p);}}});},beforeInit:function(m){m.contextMenu=new j.contextMenu(m);m.addCommand('contextMenu',{exec:function(){m.contextMenu.open(m.document.getBody());}});}});(function(){function m(o){var p=this.att,q=o&&o.hasAttribute(p)&&o.getAttribute(p)||''; +if(q!==undefined)this.setValue(q);};function n(){var o;for(var p=0;p ';j.add('elementspath',{requires:['selection'],init:function(o){var p='cke_path_'+o.name,q,r=function(){if(!q)q=a.document.getById(p);return q;},s='cke_elementspath_'+e.getNextNumber()+'_';o._.elementsPath={idBase:s,filters:[]};o.on('themeSpace',function(x){if(x.data.space=='bottom')x.data.html+=''+o.lang.elementsPath.eleLabel+''+'
      '+n+'
      ';});function t(x){o.focus();var y=o._.elementsPath.list[x];if(y.is('body')){var z=new d.range(o.document);z.selectNodeContents(y);z.select();}else o.getSelection().selectElement(y);};var u=e.addFunction(t),v=e.addFunction(function(x,y){var z=o._.elementsPath.idBase,A;y=new d.event(y);var B=o.lang.dir=='rtl';switch(y.getKeystroke()){case B?39:37:case 9:A=a.document.getById(z+(x+1));if(!A)A=a.document.getById(z+'0');A.focus();return false;case B?37:39:case 2228224+9:A=a.document.getById(z+(x-1));if(!A)A=a.document.getById(z+(o._.elementsPath.list.length-1));A.focus();return false;case 27:o.focus();return false;case 13:case 32:t(x);return false;}return true;});o.on('selectionChange',function(x){var y=b,z=x.data.selection,A=z.getStartElement(),B=[],C=x.editor,D=C._.elementsPath.list=[],E=C._.elementsPath.filters;while(A){var F=0,G;if(A.data('cke-display-name'))G=A.data('cke-display-name');else if(A.data('cke-real-element-type'))G=A.data('cke-real-element-type');else G=A.getName();for(var H=0;H',G,''+L+'',''); +}if(G=='body')break;A=A.getParent();}var M=r();M.setHtml(B.join('')+n);C.fire('elementsPathUpdate',{space:M});});function w(){q&&q.setHtml(n);delete o._.elementsPath.list;};o.on('readOnly',w);o.on('contentDomUnload',w);o.addCommand('elementsPathFocus',m.toolbarFocus);}});})();(function(){j.add('enterkey',{requires:['keystrokes','indent'],init:function(t){t.addCommand('enter',{modes:{wysiwyg:1},editorFocus:false,exec:function(v){r(v);}});t.addCommand('shiftEnter',{modes:{wysiwyg:1},editorFocus:false,exec:function(v){q(v);}});var u=t.keystrokeHandler.keystrokes;u[13]='enter';u[2228224+13]='shiftEnter';}});j.enterkey={enterBlock:function(t,u,v,w){v=v||s(t);if(!v)return;var x=v.document,y=v.checkStartOfBlock(),z=v.checkEndOfBlock(),A=new d.elementPath(v.startContainer),B=A.block;if(y&&z){if(B&&(B.is('li')||B.getParent().is('li'))){t.execCommand('outdent');return;}if(B&&B.getParent().is('blockquote')){B.breakParent(B.getParent());if(!B.getPrevious().getFirst(d.walker.invisible(1)))B.getPrevious().remove();if(!B.getNext().getFirst(d.walker.invisible(1)))B.getNext().remove();v.moveToElementEditStart(B);v.select();return;}}else if(B&&B.is('pre')){if(!z){n(t,u,v,w);return;}}else if(B&&f.$captionBlock[B.getName()]){n(t,u,v,w);return;}var C=u==3?'div':'p',D=v.splitBlock(C);if(!D)return;var E=D.previousBlock,F=D.nextBlock,G=D.wasStartOfBlock,H=D.wasEndOfBlock,I;if(F){I=F.getParent();if(I.is('li')){F.breakParent(I);F.move(F.getNext(),1);}}else if(E&&(I=E.getParent())&&I.is('li')){E.breakParent(I);I=E.getNext();v.moveToElementEditStart(I);E.move(E.getPrevious());}if(!G&&!H){if(F.is('li')&&(I=F.getFirst(d.walker.invisible(true)))&&I.is&&I.is('ul','ol'))(c?x.createText('\xa0'):x.createElement('br')).insertBefore(I);if(F)v.moveToElementEditStart(F);}else{var J,K;if(E){if(E.is('li')||!(p.test(E.getName())||E.is('pre')))J=E.clone();}else if(F)J=F.clone();if(!J){if(I&&I.is('li'))J=I;else{J=x.createElement(C);if(E&&(K=E.getDirection()))J.setAttribute('dir',K);}}else if(w&&!J.is('li'))J.renameNode(C);var L=D.elementPath;if(L)for(var M=0,N=L.elements.length;M0;v--)u[v].deleteContents();return u[0];};})();(function(){var m='nbsp,gt,lt,amp',n='quot,iexcl,cent,pound,curren,yen,brvbar,sect,uml,copy,ordf,laquo,not,shy,reg,macr,deg,plusmn,sup2,sup3,acute,micro,para,middot,cedil,sup1,ordm,raquo,frac14,frac12,frac34,iquest,times,divide,fnof,bull,hellip,prime,Prime,oline,frasl,weierp,image,real,trade,alefsym,larr,uarr,rarr,darr,harr,crarr,lArr,uArr,rArr,dArr,hArr,forall,part,exist,empty,nabla,isin,notin,ni,prod,sum,minus,lowast,radic,prop,infin,ang,and,or,cap,cup,int,there4,sim,cong,asymp,ne,equiv,le,ge,sub,sup,nsub,sube,supe,oplus,otimes,perp,sdot,lceil,rceil,lfloor,rfloor,lang,rang,loz,spades,clubs,hearts,diams,circ,tilde,ensp,emsp,thinsp,zwnj,zwj,lrm,rlm,ndash,mdash,lsquo,rsquo,sbquo,ldquo,rdquo,bdquo,dagger,Dagger,permil,lsaquo,rsaquo,euro',o='Agrave,Aacute,Acirc,Atilde,Auml,Aring,AElig,Ccedil,Egrave,Eacute,Ecirc,Euml,Igrave,Iacute,Icirc,Iuml,ETH,Ntilde,Ograve,Oacute,Ocirc,Otilde,Ouml,Oslash,Ugrave,Uacute,Ucirc,Uuml,Yacute,THORN,szlig,agrave,aacute,acirc,atilde,auml,aring,aelig,ccedil,egrave,eacute,ecirc,euml,igrave,iacute,icirc,iuml,eth,ntilde,ograve,oacute,ocirc,otilde,ouml,oslash,ugrave,uacute,ucirc,uuml,yacute,thorn,yuml,OElig,oelig,Scaron,scaron,Yuml',p='Alpha,Beta,Gamma,Delta,Epsilon,Zeta,Eta,Theta,Iota,Kappa,Lambda,Mu,Nu,Xi,Omicron,Pi,Rho,Sigma,Tau,Upsilon,Phi,Chi,Psi,Omega,alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota,kappa,lambda,mu,nu,xi,omicron,pi,rho,sigmaf,sigma,tau,upsilon,phi,chi,psi,omega,thetasym,upsih,piv'; +function q(r,s){var t={},u=[],v={nbsp:'\xa0',shy:'­',gt:'>',lt:'<',amp:'&'};r=r.replace(/\b(nbsp|shy|gt|lt|amp)(?:,|$)/g,function(A,B){var C=s?'&'+B+';':v[B],D=s?v[B]:'&'+B+';';t[C]=D;u.push(C);return '';});if(!s&&r){r=r.split(',');var w=document.createElement('div'),x;w.innerHTML='&'+r.join(';&')+';';x=w.innerHTML;w=null;for(var y=0;y0;case 'checked':return!!q.$.checked;case 'value':var p=q.getAttribute('type');return p=='checkbox'||p=='radio'?q.$.value!='on':q.$.value;}return m.apply(q,arguments);};});(function(){var m={canUndo:false,exec:function(o){var p=o.document.createElement('hr'),q=new d.range(o.document);o.insertElement(p);q.moveToPosition(p,4);var r=p.getNext();if(!r||r.type==1&&!r.isEditable())q.fixBlock(true,o.config.enterMode==3?'div':'p');q.select();}},n='horizontalrule';j.add(n,{init:function(o){o.addCommand(n,m);o.ui.addButton('HorizontalRule',{label:o.lang.horizontalrule,command:n});}});})();(function(){var m=/^[\t\r\n ]*(?: |\xa0)$/,n='{cke_protected}';function o(T){var U=T.children.length,V=T.children[U-1];while(V&&V.type==3&&!e.trim(V.value))V=T.children[--U];return V;};function p(T,U){var V=T.children,W=o(T);if(W){if((U||!c)&&W.type==1&&W.name=='br')V.pop();if(W.type==3&&m.test(W.value))V.pop();}};function q(T,U,V){if(!U&&(!V||typeof V=='function'&&V(T)===false))return false;if(U&&c&&(document.documentMode>7||T.name in f.tr||T.name in f.$listItem))return false;var W=o(T);return!W||W&&(W.type==1&&W.name=='br'||T.name=='form'&&W.name=='input');};function r(T,U){return function(V){p(V,!T);if(q(V,!T,U))if(T||c)V.add(new a.htmlParser.text('\xa0'));else V.add(new a.htmlParser.element('br',{}));};};var s=f,t=['caption','colgroup','col','thead','tfoot','tbody'],u=e.extend({},s.$block,s.$listItem,s.$tableContent);for(var v in u){if(!('br' in s[v]))delete u[v];}delete u.pre;var w={elements:{},attributeNames:[[/^on/,'data-cke-pa-on']]},x={elements:{}};for(v in u)x.elements[v]=r();var y={elementNames:[[/^cke:/,''],[/^\?xml:namespace$/,'']],attributeNames:[[/^data-cke-(saved|pa)-/,''],[/^data-cke-.*/,''],['hidefocus','']],elements:{$:function(T){var U=T.attributes; +if(U){if(U['data-cke-temp'])return false;var V=['name','href','src'],W;for(var X=0;Xe.indexOf(t,W.name)?1:-1:0;});},embed:function(T){var U=T.parent;if(U&&U.name=='object'){var V=U.attributes.width,W=U.attributes.height;V&&(T.attributes.width=V);W&&(T.attributes.height=W);}},param:function(T){T.children=[];T.isEmpty=true;return T;},a:function(T){if(!(T.children.length||T.attributes.name||T.attributes['data-cke-saved-name']))return false;},span:function(T){if(T.attributes['class']=='Apple-style-span')delete T.name;},pre:function(T){c&&p(T);},html:function(T){delete T.attributes.contenteditable;delete T.attributes['class'];},body:function(T){delete T.attributes.spellcheck;delete T.attributes.contenteditable;},style:function(T){var U=T.children[0];U&&U.value&&(U.value=e.trim(U.value));if(!T.attributes.type)T.attributes.type='text/css';},title:function(T){var U=T.children[0];U&&(U.value=T.attributes['data-cke-title']||'');}},attributes:{'class':function(T,U){return e.ltrim(T.replace(/(?:^|\s+)cke_[^\s]*/g,''))||false;}}};if(c)y.attributes.style=function(T,U){return T.replace(/(^|;)([^\:]+)/g,function(V){return V.toLowerCase();});};function z(T){var U=T.attributes;if(U.contenteditable!='false')U['data-cke-editable']=U.contenteditable?'true':1;U.contenteditable='false';};function A(T){var U=T.attributes;switch(U['data-cke-editable']){case 'true':U.contenteditable='true';break;case '1':delete U.contenteditable;break;}};for(v in {input:1,textarea:1}){w.elements[v]=z;y.elements[v]=A;}var B=/<(a|area|img|input)\b([^>]*)>/gi,C=/\b(on\w+|href|src|name)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi,D=/(?:])[^>]*>[\s\S]*<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi,E=/([^<]*)<\/cke:encoded>/gi,F=/(<\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi,G=/(<\/?)cke:((?:html|body|head|title)[^>]*>)/gi,H=/]*?)\/?>(?!\s*<\/cke:\1)/gi;function I(T){return T.replace(B,function(U,V,W){return '<'+V+W.replace(C,function(X,Y){if(!/^on/.test(Y)&&W.indexOf('data-cke-saved-'+Y)==-1)return ' data-cke-saved-'+X+' '+X;return X;})+'>';});};function J(T){return T.replace(D,function(U){return ''+encodeURIComponent(U)+'';});};function K(T){return T.replace(E,function(U,V){return decodeURIComponent(V);});};function L(T){return T.replace(F,'$1cke:$2'); +};function M(T){return T.replace(G,'$1$2');};function N(T){return T.replace(H,'');};function O(T){return T.replace(/(]*>)(\r\n|\n)/g,'$1$2$2');};function P(T){return T.replace(//g,function(U){return '';});};function Q(T){return T.replace(//g,function(U,V){return decodeURIComponent(V);});};function R(T,U){var V=U._.dataStore;return T.replace(//g,function(W,X){return decodeURIComponent(X);}).replace(/\{cke_protected_(\d+)\}/g,function(W,X){return V&&V[X]||'';});};function S(T,U){var V=[],W=U.config.protectedSource,X=U._.dataStore||(U._.dataStore={id:1}),Y=/<\!--\{cke_temp(comment)?\}(\d*?)-->/g,Z=[//gi,//gi].concat(W);T=T.replace(//g,function(ab){return '';});for(var aa=0;aa';});T=T.replace(Y,function(ab,ac,ad){return '';});return T.replace(/(['"]).*?\1/g,function(ab){return ab.replace(//g,function(ac,ad){X[X.id]=decodeURIComponent(ad);return '{cke_protected_'+X.id++ +'}';});});};j.add('htmldataprocessor',{requires:['htmlwriter'],init:function(T){var U=T.dataProcessor=new a.htmlDataProcessor(T);U.writer.forceSimpleAmpersand=T.config.forceSimpleAmpersand;U.dataFilter.addRules(w);U.dataFilter.addRules(x);U.htmlFilter.addRules(y);var V={elements:{}};for(v in u)V.elements[v]=r(true,T.config.fillEmptyBlocks);U.htmlFilter.addRules(V);},onLoad:function(){!('fillEmptyBlocks' in i)&&(i.fillEmptyBlocks=1);}});a.htmlDataProcessor=function(T){var U=this;U.editor=T;U.writer=new a.htmlWriter();U.dataFilter=new a.htmlParser.filter();U.htmlFilter=new a.htmlParser.filter();};a.htmlDataProcessor.prototype={toHtml:function(T,U){T=S(T,this.editor);T=I(T);T=J(T);T=L(T);T=N(T);T=O(T);var V=new h('div');V.setHtml('a'+T);T=V.getHtml().substr(1);T=M(T);T=K(T);T=Q(T);var W=a.htmlParser.fragment.fromHtml(T,U),X=new a.htmlParser.basicWriter();W.writeHtml(X,this.dataFilter);T=X.getHtml(true);T=P(T);return T;},toDataFormat:function(T,U){var V=this.writer,W=a.htmlParser.fragment.fromHtml(T,U);V.reset();W.writeHtml(V,this.htmlFilter); +var X=V.getHtml(true);X=Q(X);X=R(X,this.editor);return X;}};})();(function(){j.add('iframe',{requires:['dialog','fakeobjects'],init:function(m){var n='iframe',o=m.lang.iframe;a.dialog.add(n,this.path+'dialogs/iframe.js');m.addCommand(n,new a.dialogCommand(n));m.addCss('img.cke_iframe{background-image: url('+a.getUrl(this.path+'images/placeholder.png')+');'+'background-position: center center;'+'background-repeat: no-repeat;'+'border: 1px solid #a9a9a9;'+'width: 80px;'+'height: 80px;'+'}');m.ui.addButton('Iframe',{label:o.toolbar,command:n});m.on('doubleclick',function(p){var q=p.data.element;if(q.is('img')&&q.data('cke-real-element-type')=='iframe')p.data.dialog='iframe';});if(m.addMenuItems)m.addMenuItems({iframe:{label:o.title,command:'iframe',group:'image'}});if(m.contextMenu)m.contextMenu.addListener(function(p,q){if(p&&p.is('img')&&p.data('cke-real-element-type')=='iframe')return{iframe:2};});},afterInit:function(m){var n=m.dataProcessor,o=n&&n.dataFilter;if(o)o.addRules({elements:{iframe:function(p){return m.createFakeParserElement(p,'cke_iframe','iframe',true);}}});}});})();j.add('image',{init:function(m){var n='image';a.dialog.add(n,this.path+'dialogs/image.js');m.addCommand(n,new a.dialogCommand(n));m.ui.addButton('Image',{label:m.lang.common.image,command:n});m.on('doubleclick',function(o){var p=o.data.element;if(p.is('img')&&!p.data('cke-realelement')&&!p.isReadOnly())o.data.dialog='image';});if(m.addMenuItems)m.addMenuItems({image:{label:m.lang.image.menu,command:'image',group:'image'}});if(m.contextMenu)m.contextMenu.addListener(function(o,p){if(!o||!o.is('img')||o.data('cke-realelement')||o.isReadOnly())return null;return{image:2};});}});i.image_removeLinkByEmptyURL=true;(function(){var m={ol:1,ul:1},n=d.walker.whitespaces(true),o=d.walker.bookmark(false,true);function p(t){var B=this;if(t.editor.readOnly)return null;var u=t.editor,v=t.data.path,w=v&&v.contains(m),x=v.block||v.blockLimit;if(w)return B.setState(2);if(!B.useIndentClasses&&B.name=='indent')return B.setState(2);if(!x)return B.setState(0);if(B.useIndentClasses){var y=x.$.className.match(B.classNameRegex),z=0;if(y){y=y[1];z=B.indentClassMap[y];}if(B.name=='outdent'&&!z||B.name=='indent'&&z==u.config.indentClasses.length)return B.setState(0);return B.setState(2);}else{var A=parseInt(x.getStyle(r(x)),10);if(isNaN(A))A=0;if(A<=0)return B.setState(0);return B.setState(2);}};function q(t,u){var w=this;w.name=u;w.useIndentClasses=t.config.indentClasses&&t.config.indentClasses.length>0;if(w.useIndentClasses){w.classNameRegex=new RegExp('(?:^|\\s+)('+t.config.indentClasses.join('|')+')(?=$|\\s)'); +w.indentClassMap={};for(var v=0;vY;T++)X[T].indent+=U;var aa=j.list.arrayToList(X,v,null,t.config.enterMode,M.getDirection());if(u.name=='outdent'){var ab;if((ab=M.getParent())&&ab.is('li')){var ac=aa.listNode.getChildren(),ad=[],ae=ac.count(),af;for(T=ae-1;T>=0;T--){if((af=ac.getItem(T))&&af.is&&af.is('li'))ad.push(af);}}}if(aa)aa.listNode.replace(M);if(ad&&ad.length)for(T=0;T0)M.addClass(t.config.indentClasses[P-1]);}else{var Q=r(M,N),R=parseInt(M.getStyle(Q),10);if(isNaN(R))R=0;var S=t.config.indentOffset||40;R+=(u.name=='indent'?1:-1)*S;if(R<0)return false;R=Math.max(R,0);R=Math.ceil(R/S)*S;M.setStyle(Q,R?R+(t.config.indentUnit||'px'):'');if(M.getAttribute('style')==='')M.removeAttribute('style');}h.setMarker(v,M,'indent_processed',1); +return true;};var z=t.getSelection(),A=z.createBookmarks(1),B=z&&z.getRanges(1),C,D=B.createIterator();while(C=D.getNextRange()){var E=C.getCommonAncestor(),F=E;while(F&&!(F.type==1&&m[F.getName()]))F=F.getParent();if(!F){var G=C.getEnclosedNode();if(G&&G.type==1&&G.getName() in m){C.setStartAt(G,1);C.setEndAt(G,2);F=G;}}if(F&&C.startContainer.type==1&&C.startContainer.getName() in m){var H=new d.walker(C);H.evaluator=s;C.startContainer=H.next();}if(F&&C.endContainer.type==1&&C.endContainer.getName() in m){H=new d.walker(C);H.evaluator=s;C.endContainer=H.previous();}if(F){var I=F.getFirst(s),J=!!I.getNext(s),K=C.startContainer,L=I.equals(K)||I.contains(K);if(!(L&&(u.name=='indent'||u.useIndentClasses||parseInt(F.getStyle(r(F)),10))&&y(F,!J&&I.getDirection())))w(F);}else x();}h.clearAllMarkers(v);t.forceNextSelectionCheck();z.selectBookmarks(A);}};j.add('indent',{init:function(t){var u=t.addCommand('indent',new q(t,'indent')),v=t.addCommand('outdent',new q(t,'outdent'));t.ui.addButton('Indent',{label:t.lang.indent,command:'indent'});t.ui.addButton('Outdent',{label:t.lang.outdent,command:'outdent'});t.on('selectionChange',e.bind(p,u));t.on('selectionChange',e.bind(p,v));if(b.ie6Compat||b.ie7Compat)t.addCss('ul,ol{\tmargin-left: 0px;\tpadding-left: 40px;}');t.on('dirChanged',function(w){var x=new d.range(t.document);x.setStartBefore(w.data.node);x.setEndAfter(w.data.node);var y=new d.walker(x),z;while(z=y.next()){if(z.type==1){if(!z.equals(w.data.node)&&z.getDirection()){x.setStartAfter(z);y=new d.walker(x);continue;}var A=t.config.indentClasses;if(A){var B=w.data.dir=='ltr'?['_rtl','']:['','_rtl'];for(var C=0;C=0;A--){x=v[A].createIterator();x.enlargeBr=t!=2;while(y=x.getNextParagraph(t==1?'p':'div')){y.removeAttribute('align');y.removeStyle('text-align');var B=w&&(y.$.className=e.ltrim(y.$.className.replace(D.cssClassRegex,''))),C=D.state==2&&(!z||n(y,true)!=D.value);if(w){if(C)y.addClass(w);else if(!B)y.removeAttribute('class');}else if(C)y.setStyle('text-align',D.value);}}r.focus();r.forceNextSelectionCheck();s.selectBookmarks(u);}};j.add('justify',{init:function(r){var s=new p(r,'justifyleft','left'),t=new p(r,'justifycenter','center'),u=new p(r,'justifyright','right'),v=new p(r,'justifyblock','justify');r.addCommand('justifyleft',s);r.addCommand('justifycenter',t);r.addCommand('justifyright',u);r.addCommand('justifyblock',v);r.ui.addButton('JustifyLeft',{label:r.lang.justify.left,command:'justifyleft'});r.ui.addButton('JustifyCenter',{label:r.lang.justify.center,command:'justifycenter'});r.ui.addButton('JustifyRight',{label:r.lang.justify.right,command:'justifyright'});r.ui.addButton('JustifyBlock',{label:r.lang.justify.block,command:'justifyblock'});r.on('selectionChange',e.bind(o,s));r.on('selectionChange',e.bind(o,u));r.on('selectionChange',e.bind(o,t));r.on('selectionChange',e.bind(o,v));r.on('dirChanged',q);},requires:['domiterator']});})();j.add('keystrokes',{beforeInit:function(m){m.keystrokeHandler=new a.keystrokeHandler(m); +m.specialKeys={};},init:function(m){var n=m.config.keystrokes,o=m.config.blockedKeystrokes,p=m.keystrokeHandler.keystrokes,q=m.keystrokeHandler.blockedKeystrokes;for(var r=0;r7))Q.append(L.createText('\xa0'));Q.append(W.listNode);O=W.nextIndex;}else if(T.indent==-1&&!I&&T.grandparent){if(m[T.grandparent.getName()])Q=T.element.clone(false,true); +else if(K||T.element.hasAttributes()||J!=2){Q=L.createElement(S);T.element.copyAttributes(Q,{type:1,value:1});if(!K&&J==2&&!Q.hasAttributes())Q=new d.documentFragment(L);}else Q=new d.documentFragment(L);if(Q.type==1)if(T.grandparent.getDirection(1)!=R)Q.setAttribute('dir',R);for(U=0;UJ[L-1].indent+1){var P=J[L-1].indent+1-J[L].indent,Q=J[L].indent;while(J[L]&&J[L].indent>=Q){J[L].indent+=P;L++;}L--;}}var R=j.list.arrayToList(J,I,null,G.config.enterMode,H.root.getAttribute('dir')),S=R.listNode,T,U;function V(W){if((T=S[W?'getFirst':'getLast']())&&!(T.is&&T.isBlockBoundary())&&(U=H.root[W?'getPrevious':'getNext'](d.walker.whitespaces(true)))&&!(U.is&&U.isBlockBoundary({br:1})))G.document.createElement('br')[W?'insertBefore':'insertAfter'](T);};V(true);V();S.replace(H.root);};function x(G,H){this.name=G;this.type=H;};function y(G){var H=G.getDirection();if(H){for(var I=0,J=G.getChildren(),K;K=J.getItem(I),I=0&&(ae=Z[af]); +af--){if(m[ae.getName()]&&ad.contains(ae)){ad.removeCustomData('list_group_object_'+S);var ag=ae.getCustomData('list_group_object');if(ag)ag.contents.push(X);else{ag={root:ae,contents:[X]};P.push(ag);h.setMarker(Q,ae,'list_group_object',ag);}ac=1;break;}}if(ac)continue;var ah=ad;if(ah.getCustomData('list_group_object_'+S))ah.getCustomData('list_group_object_'+S).contents.push(X);else{ag={root:ah,contents:[X]};h.setMarker(Q,ah,'list_group_object_'+S,ag);P.push(ag);}}}var ai=[];while(P.length>0){ag=P.shift();if(this.state==2){if(m[ag.root.getName()])t.call(this,G,ag,Q,ai);else v.call(this,G,ag,ai);}else if(this.state==1&&m[ag.root.getName()])w.call(this,G,ag,Q);}for(af=0;af0)for(var u=t.length-1;u>=0;u--){var v=t[u][0],w=t[u][1];if(w)v.insertBefore(w);else v.appendTo(s);}};function o(s,t){var u=m(s),v={},w=s.$;if(!t){v['class']=w.className||'';w.className='';}v.inline=w.style.cssText||'';if(!t)w.style.cssText='position: static; overflow: visible';n(u);return v;};function p(s,t){var u=m(s),v=s.$;if('class' in t)v.className=t['class'];if('inline' in t)v.style.cssText=t.inline;n(u);};function q(s){var t=a.instances;for(var u in t){var v=t[u];if(v.mode=='wysiwyg'&&!v.readOnly){var w=v.document.getBody();w.setAttribute('contentEditable',false);w.setAttribute('contentEditable',true);}}if(s.focusManager.hasFocus){s.toolbox.focus();s.focus();}};function r(s){if(!c||b.version>6)return null;var t=h.createFromHtml('');return s.append(t,true);};j.add('maximize',{init:function(s){var t=s.lang,u=a.document,v=u.getWindow(),w,x,y,z;function A(){var C=v.getViewPaneSize();z&&z.setStyles({width:C.width+'px',height:C.height+'px'});s.resize(C.width,C.height,null,true);};var B=2;s.addCommand('maximize',{modes:{wysiwyg:!b.iOS,source:!b.iOS},readOnly:1,editorFocus:false,exec:function(){var C=s.container.getChild(1),D=s.getThemeSpace('contents');if(s.mode=='wysiwyg'){var E=s.getSelection();w=E&&E.getRanges();x=v.getScrollPosition();}else{var F=s.textarea.$;w=!c&&[F.selectionStart,F.selectionEnd];x=[F.scrollLeft,F.scrollTop];}if(this.state==2){v.on('resize',A); +y=v.getScrollPosition();var G=s.container;while(G=G.getParent()){G.setCustomData('maximize_saved_styles',o(G));G.setStyle('z-index',s.config.baseFloatZIndex-1);}D.setCustomData('maximize_saved_styles',o(D,true));C.setCustomData('maximize_saved_styles',o(C,true));var H={overflow:b.webkit?'':'hidden',width:0,height:0};u.getDocumentElement().setStyles(H);!b.gecko&&u.getDocumentElement().setStyle('position','fixed');!(b.gecko&&b.quirks)&&u.getBody().setStyles(H);c?setTimeout(function(){v.$.scrollTo(0,0);},0):v.$.scrollTo(0,0);C.setStyle('position',b.gecko&&b.quirks?'fixed':'absolute');C.$.offsetLeft;C.setStyles({'z-index':s.config.baseFloatZIndex-1,left:'0px',top:'0px'});z=r(C);C.addClass('cke_maximized');A();var I=C.getDocumentPosition();C.setStyles({left:-1*I.x+'px',top:-1*I.y+'px'});b.gecko&&q(s);}else if(this.state==1){v.removeListener('resize',A);var J=[D,C];for(var K=0;K ');s.children.length=0;s.add(u);var v=s.attributes;delete v['aria-label'];delete v.contenteditable;delete v.title;}return t;}}},5);if(p)p.addRules({elements:{div:function(r){var s=r.attributes,t=s&&s.style,u=t&&r.children.length==1&&r.children[0],v=u&&u.name=='span'&&u.attributes.style;if(v&&/page-break-after\s*:\s*always/i.test(t)&&/display\s*:\s*none/i.test(v)){s.contenteditable='false';s['class']='cke_pagebreak';s['data-cke-display-name']='pagebreak';s['aria-label']=n;s.title=n;r.children.length=0;}}}});},requires:['fakeobjects']});j.pagebreakCmd={exec:function(m){var n=m.lang.pagebreakAlt,o=h.createFromHtml('
      '+'
      ',m.document),p=m.getSelection().getRanges(true);m.fire('saveSnapshot');for(var q,r=p.length-1;r>=0;r--){q=p[r];if(r1&&n.substr(n.length-1,1)=='%')n=parseInt(window.screen.width*parseInt(n,10)/100,10);if(typeof o=='string'&&o.length>1&&o.substr(o.length-1,1)=='%')o=parseInt(window.screen.height*parseInt(o,10)/100,10);if(n<640)n=640;if(o<420)o=420;var q=parseInt((window.screen.height-o)/2,10),r=parseInt((window.screen.width-n)/2,10);p=(p||'location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes')+',width='+n+',height='+o+',top='+q+',left='+r;var s=window.open('',null,p,true);if(!s)return false;try{s.moveTo(r,q);s.resizeTo(n,o);s.focus();s.location.href=m;}catch(t){s=window.open(m,null,p,true);}return true;}});(function(){var m={modes:{wysiwyg:1,source:1},canUndo:false,readOnly:1,exec:function(o){var p,q=o.config,r=q.baseHref?'':'',s=b.isCustomDomain();if(q.fullPage)p=o.getData().replace(//,'$&'+r).replace(/[^>]*(?=<\/title>)/,'$& — '+o.lang.preview); +else{var t=''+''+r+''+o.lang.preview+''+e.buildStyleHtml(o.config.contentsCss)+''+t+o.getData()+'';}var v=640,w=420,x=80;try{var y=window.screen;v=Math.round(y.width*0.8);w=Math.round(y.height*0.7);x=Math.round(y.width*0.1);}catch(C){}var z='';if(s){window._cke_htmlToLoad=p;z='javascript:void( (function(){document.open();document.domain="'+document.domain+'";'+'document.write( window.opener._cke_htmlToLoad );'+'document.close();'+'window.opener._cke_htmlToLoad = null;'+'})() )';}var A=window.open(z,null,'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width='+v+',height='+w+',left='+x);if(!s){var B=A.document;B.open();B.write(p);B.close();b.webkit&&setTimeout(function(){B.body.innerHTML+='';},0);}}},n='preview';j.add(n,{init:function(o){o.addCommand(n,m);o.ui.addButton('Preview',{label:o.lang.preview,command:n});}});})();j.add('print',{init:function(m){var n='print',o=m.addCommand(n,j.print);m.ui.addButton('Print',{label:m.lang.print,command:n});}});j.print={exec:function(m){if(b.opera)return;else if(b.gecko)m.window.$.print();else m.document.$.execCommand('Print');},canUndo:false,readOnly:1,modes:{wysiwyg:!b.opera}};j.add('removeformat',{requires:['selection'],init:function(m){m.addCommand('removeFormat',j.removeformat.commands.removeformat);m.ui.addButton('RemoveFormat',{label:m.lang.removeFormat,command:'removeFormat'});m._.removeFormat={filters:[]};}});j.removeformat={commands:{removeformat:{exec:function(m){var n=m._.removeFormatRegex||(m._.removeFormatRegex=new RegExp('^(?:'+m.config.removeFormatTags.replace(/,/g,'|')+')$','i')),o=m._.removeAttributes||(m._.removeAttributes=m.config.removeFormatAttributes.split(',')),p=j.removeformat.filter,q=m.getSelection().getRanges(1),r=q.createIterator(),s;while(s=r.getNextRange()){if(!s.collapsed)s.enlarge(1);var t=s.createBookmark(),u=t.startNode,v=t.endNode,w,x=function(z){var A=new d.elementPath(z),B=A.elements;for(var C=1,D;D=B[C];C++){if(D.equals(A.block)||D.equals(A.blockLimit))break;if(n.test(D.getName())&&p(m,D))z.breakParent(D);}};x(u);if(v){x(v);w=u.getNextSourceNode(true,1);while(w){if(w.equals(v))break;var y=w.getNextSourceNode(false,1);if(!(w.getName()=='img'&&w.data('cke-realelement'))&&p(m,w))if(n.test(w.getName()))w.remove(1); +else{w.removeAttributes(o);m.fire('removeFormatCleanup',w);}w=y;}}s.moveToBookmark(t);}m.getSelection().selectRanges(q);}}},filter:function(m,n){var o=m._.removeFormat.filters;for(var p=0;pr.width&&(n.resize_minWidth=r.width);n.resize_minHeight>r.height&&(n.resize_minHeight=r.height);a.document.on('mousemove',u);a.document.on('mouseup',v);if(m.document){m.document.on('mousemove',u);m.document.on('mouseup',v);}});m.on('destroy',function(){e.removeFunction(w);});m.on('themeSpace',function(x){if(x.data.space=='bottom'){var y='';if(s&&!t)y=' cke_resizer_horizontal';if(!s&&t)y=' cke_resizer_vertical';var z='
      ';o=='ltr'&&y=='ltr'?x.data.html+=z:x.data.html=z+x.data.html;}},m,null,100);}}});(function(){var m={modes:{wysiwyg:1,source:1},readOnly:1,exec:function(o){var p=o.element.$.form;if(p)try{p.submit();}catch(q){if(p.submit.click)p.submit.click(); +}}},n='save';j.add(n,{init:function(o){var p=o.addCommand(n,m);p.modes={wysiwyg:!!o.element.$.form};o.ui.addButton('Save',{label:o.lang.save,command:n});}});})();(function(){var m='scaytcheck',n='';function o(t,u){var v=0,w;for(w in u){if(u[w]==t){v=1;break;}}return v;};var p=function(){var t=this,u=function(){var y=t.config,z={};z.srcNodeRef=t.document.getWindow().$.frameElement;z.assocApp='CKEDITOR.'+a.version+'@'+a.revision;z.customerid=y.scayt_customerid||'1:WvF0D4-UtPqN1-43nkD4-NKvUm2-daQqk3-LmNiI-z7Ysb4-mwry24-T8YrS3-Q2tpq2';z.customDictionaryIds=y.scayt_customDictionaryIds||'';z.userDictionaryName=y.scayt_userDictionaryName||'';z.sLang=y.scayt_sLang||'en_US';z.onLoad=function(){if(!(c&&b.version<8))this.addStyle(this.selectorCss(),'padding-bottom: 2px !important;');if(t.focusManager.hasFocus&&!q.isControlRestored(t))this.focus();};z.onBeforeChange=function(){if(q.getScayt(t)&&!t.checkDirty())setTimeout(function(){t.resetDirty();},0);};var A=window.scayt_custom_params;if(typeof A=='object')for(var B in A)z[B]=A[B];if(q.getControlId(t))z.id=q.getControlId(t);var C=new window.scayt(z);C.afterMarkupRemove.push(function(E){new h(E,C.document).mergeSiblings();});var D=q.instances[t.name];if(D){C.sLang=D.sLang;C.option(D.option());C.paused=D.paused;}q.instances[t.name]=C;try{C.setDisabled(q.isPaused(t)===false);}catch(E){}t.fire('showScaytState');};t.on('contentDom',u);t.on('contentDomUnload',function(){var y=a.document.getElementsByTag('script'),z=/^dojoIoScript(\d+)$/i,A=/^https?:\/\/svc\.webspellchecker\.net\/spellcheck\/script\/ssrv\.cgi/i;for(var B=0;B=0){this.setState(0);q.loadEngine(t);}}};j.add('scayt',{requires:['menubutton'],beforeInit:function(t){var u=t.config.scayt_contextMenuItemsOrder||'suggest|moresuggest|control',v='';u=u.split('|');if(u&&u.length)for(var w=0;w tr > td, .%1 table.%2 > tr > th,','.%1 table.%2 > tbody > tr > td, .%1 table.%2 > tbody > tr > th,','.%1 table.%2 > thead > tr > td, .%1 table.%2 > thead > tr > th,','.%1 table.%2 > tfoot > tr > td, .%1 table.%2 > tfoot > tr > th','{','border : #d3d3d3 1px dotted','}']).join('');n=o.replace(/%2/g,m).replace(/%1/g,'cke_show_borders ');var p={preserveState:true,editorFocus:false,readOnly:1,exec:function(q){this.toggleState();this.refresh(q); +},refresh:function(q){if(q.document){var r=this.state==1?'addClass':'removeClass';q.document.getBody()[r]('cke_show_borders');}}};j.add('showborders',{requires:['wysiwygarea'],modes:{wysiwyg:1},init:function(q){var r=q.addCommand('showborders',p);r.canUndo=false;if(q.config.startupShowBorders!==false)r.setState(1);q.addCss(n);q.on('mode',function(){if(r.state!=0)r.refresh(q);},null,null,100);q.on('contentDom',function(){if(r.state!=0)r.refresh(q);});q.on('removeFormatCleanup',function(s){var t=s.data;if(q.getCommand('showborders').state==1&&t.is('table')&&(!t.hasAttribute('border')||parseInt(t.getAttribute('border'),10)<=0))t.addClass(m);});},afterInit:function(q){var r=q.dataProcessor,s=r&&r.dataFilter,t=r&&r.htmlFilter;if(s)s.addRules({elements:{table:function(u){var v=u.attributes,w=v['class'],x=parseInt(v.border,10);if((!x||x<=0)&&(!w||w.indexOf(m)==-1))v['class']=(w||'')+' '+m;}}});if(t)t.addRules({elements:{table:function(u){var v=u.attributes,w=v['class'];w&&(v['class']=w.replace(m,'').replace(/\s{2}/,' ').replace(/^\s+|\s+$/,''));}}});}});a.on('dialogDefinition',function(q){var r=q.data.name;if(r=='table'||r=='tableProperties'){var s=q.data.definition,t=s.getContents('info'),u=t.get('txtBorder'),v=u.commit;u.commit=e.override(v,function(y){return function(z,A){y.apply(this,arguments);var B=parseInt(this.getValue(),10);A[!B||B<=0?'addClass':'removeClass'](m);};});var w=s.getContents('advanced'),x=w&&w.get('advCSSClasses');if(x){x.setup=e.override(x.setup,function(y){return function(){y.apply(this,arguments);this.setValue(this.getValue().replace(/cke_show_border/,''));};});x.commit=e.override(x.commit,function(y){return function(z,A){y.apply(this,arguments);if(!parseInt(A.getAttribute('border'),10))A.addClass('cke_show_border');};});}}});})();j.add('sourcearea',{requires:['editingblock'],init:function(m){var n=j.sourcearea,o=a.document.getWindow();m.on('editingBlockReady',function(){var p,q;m.addMode('source',{load:function(r,s){if(c&&b.version<8)r.setStyle('position','relative');m.textarea=p=new h('textarea');p.setAttributes({dir:'ltr',tabIndex:b.webkit?-1:m.tabIndex,role:'textbox','aria-label':m.lang.editorTitle.replace('%1',m.name)});p.addClass('cke_source');p.addClass('cke_enable_context_menu');m.readOnly&&p.setAttribute('readOnly','readonly');var t={width:b.ie7Compat?'99%':'100%',height:'100%',resize:'none',outline:'none','text-align':'left'};if(c){q=function(){p.hide();p.setStyle('height',r.$.clientHeight+'px');p.setStyle('width',r.$.clientWidth+'px'); +p.show();};m.on('resize',q);o.on('resize',q);setTimeout(q,0);}r.setHtml('');r.append(p);p.setStyles(t);m.fire('ariaWidget',p);p.on('blur',function(){m.focusManager.blur();});p.on('focus',function(){m.focusManager.focus();});m.mayBeDirty=true;this.loadData(s);var u=m.keystrokeHandler;if(u)u.attach(p);setTimeout(function(){m.mode='source';m.fire('mode',{previousMode:m._.previousMode});},b.gecko||b.webkit?100:0);},loadData:function(r){p.setValue(r);m.fire('dataReady');},getData:function(){return p.getValue();},getSnapshotData:function(){return p.getValue();},unload:function(r){p.clearCustomData();m.textarea=p=null;if(q){m.removeListener('resize',q);o.removeListener('resize',q);}if(c&&b.version<8)r.removeStyle('position');},focus:function(){p.focus();}});});m.on('readOnly',function(){if(m.mode=='source')if(m.readOnly)m.textarea.setAttribute('readOnly','readonly');else m.textarea.removeAttribute('readOnly');});m.addCommand('source',n.commands.source);if(m.ui.addButton)m.ui.addButton('Source',{label:m.lang.source,command:'source'});m.on('mode',function(){m.getCommand('source').setState(m.mode=='source'?1:2);});}});j.sourcearea={commands:{source:{modes:{wysiwyg:1,source:1},editorFocus:false,readOnly:1,exec:function(m){if(m.mode=='wysiwyg')m.fire('saveSnapshot');m.getCommand('source').setState(0);m.setMode(m.mode=='source'?'wysiwyg':'source');},canUndo:false}}};(function(){j.add('stylescombo',{requires:['richcombo','styles'],init:function(n){var o=n.config,p=n.lang.stylesCombo,q={},r=[],s;function t(u){n.getStylesSet(function(v){if(!r.length){var w,x;for(var y=0,z=v.length;y0)return;if(T.type==1&&m.test(T.getName())&&!T.getCustomData('selected_cell')){h.setMarker(K,T,'selected_cell',true);J.push(T);}};for(var M=0;M1&&V&&U[Y]==V[Y]){Z=U[Y];Z.rowSpan+=1;}else{Z=new h(U[Y]).clone();Z.removeAttribute('rowSpan');!c&&Z.appendBogus();X.append(Z);Z=Z.$;}Y+=Z.colSpan-1;}H?X.insertBefore(S):X.insertAfter(S);};function q(G){if(G instanceof d.selection){var H=n(G),I=H[0],J=I.getAscendant('table'),K=e.buildTableMap(J),L=H[0].getParent(),M=L.$.rowIndex,N=H[H.length-1],O=N.getParent().$.rowIndex+N.$.rowSpan-1,P=[];for(var Q=M;Q<=O;Q++){var R=K[Q],S=new h(J.$.rows[Q]);for(var T=0;T0?X[M-1]:null)||J.$.parentNode);for(Q=P.length;Q>=0;Q--)q(P[Q]);return Y;}else if(G instanceof h){J=G.getAscendant('table');if(J.$.rows.length==1)J.remove();else G.remove();}return null;};function r(G,H){var I=G.getParent(),J=I.$.cells,K=0;for(var L=0;LI)I=K;}return I;};function t(G,H){var I=n(G),J=I[0],K=J.getAscendant('table'),L=s(I,1),M=s(I),N=H?L:M,O=e.buildTableMap(K),P=[],Q=[],R=O.length;for(var S=0;S1&&Q.length&&Q[S]==P[S]){U=P[S];U.colSpan+=1;}else{U=new h(P[S]).clone();U.removeAttribute('colSpan');!c&&U.appendBogus();U[H?'insertBefore':'insertAfter'].call(U,new h(P[S]));U=U.$;}S+=U.rowSpan-1;}};function u(G){var H=n(G),I=H[0],J=H[H.length-1],K=I.getAscendant('table'),L=e.buildTableMap(K),M,N,O=[];for(var P=0,Q=L.length;P1){L=H[J-1]+1;break;}}if(!L)L=H[0]>0?H[0]-1:H[H.length-1]+1;var N=I.$.rows;for(J=0,K=N.length;J=0;K--)x(H[K]);if(J)z(J,true);else if(I)I.remove();}else if(G instanceof h){var L=G.getParent();if(L.getChildCount()==1)L.remove();else G.remove();}};function y(G){var H=G.getBogus();H&&H.remove();G.trim();};function z(G,H){var I=new d.range(G.getDocument());if(!I['moveToElementEdit'+(H?'End':'Start')](G)){I.selectNodeContents(G);I.collapse(H?false:true);}I.select(true);};function A(G,H,I){var J=G[H];if(typeof I=='undefined')return J;for(var K=0;J&&K=Q)M.removeAttribute('rowSpan');else M.$.rowSpan=Y;if(Y>=P)M.removeAttribute('colSpan');else M.$.colSpan=Z;var ak=new d.nodeList(N.$.rows),al=ak.count();for(ac=al-1;ac>=0;ac--){var am=ak.getItem(ac);if(!am.$.cells.length){am.remove();al++;continue;}}return M;}else return Y*Z==ab;};function D(G,H){var I=n(G);if(I.length>1)return false;else if(H)return true;var J=I[0],K=J.getParent(),L=K.getAscendant('table'),M=e.buildTableMap(L),N=K.$.rowIndex,O=A(M,N,J),P=J.$.rowSpan,Q,R,S,T;if(P>1){R=Math.ceil(P/2);S=Math.floor(P/2);T=N+R;var U=new h(L.$.rows[T]),V=A(M,T),W;Q=J.clone();for(var X=0;XO){Q.insertBefore(new h(W));break;}else W=null;}if(!W)U.append(Q,true);}else{S=R=1;U=K.clone();U.insertAfter(K);U.append(Q=J.clone());var Y=A(M,N);for(var Z=0;Z1)return false;else if(H)return true;var J=I[0],K=J.getParent(),L=K.getAscendant('table'),M=e.buildTableMap(L),N=K.$.rowIndex,O=A(M,N,J),P=J.$.colSpan,Q,R,S;if(P>1){R=Math.ceil(P/2);S=Math.floor(P/2);}else{S=R=1;var T=B(M,O);for(var U=0;U0?2:0};}},tablecell_insertBefore:{label:H.cell.insertBefore,group:'tablecell',command:'cellInsertBefore',order:5},tablecell_insertAfter:{label:H.cell.insertAfter,group:'tablecell',command:'cellInsertAfter',order:10},tablecell_delete:{label:H.cell.deleteCell,group:'tablecell',command:'cellDelete',order:15},tablecell_merge:{label:H.cell.merge,group:'tablecell',command:'cellMerge',order:16},tablecell_merge_right:{label:H.cell.mergeRight,group:'tablecell',command:'cellMergeRight',order:17},tablecell_merge_down:{label:H.cell.mergeDown,group:'tablecell',command:'cellMergeDown',order:18},tablecell_split_horizontal:{label:H.cell.splitHorizontal,group:'tablecell',command:'cellHorizontalSplit',order:19},tablecell_split_vertical:{label:H.cell.splitVertical,group:'tablecell',command:'cellVerticalSplit',order:20},tablecell_properties:{label:H.cell.title,group:'tablecellproperties',command:'cellProperties',order:21},tablerow:{label:H.row.menu,group:'tablerow',order:1,getItems:function(){return{tablerow_insertBefore:2,tablerow_insertAfter:2,tablerow_delete:2};}},tablerow_insertBefore:{label:H.row.insertBefore,group:'tablerow',command:'rowInsertBefore',order:5},tablerow_insertAfter:{label:H.row.insertAfter,group:'tablerow',command:'rowInsertAfter',order:10},tablerow_delete:{label:H.row.deleteRow,group:'tablerow',command:'rowDelete',order:15},tablecolumn:{label:H.column.menu,group:'tablecolumn',order:1,getItems:function(){return{tablecolumn_insertBefore:2,tablecolumn_insertAfter:2,tablecolumn_delete:2}; +}},tablecolumn_insertBefore:{label:H.column.insertBefore,group:'tablecolumn',command:'columnInsertBefore',order:5},tablecolumn_insertAfter:{label:H.column.insertAfter,group:'tablecolumn',command:'columnInsertAfter',order:10},tablecolumn_delete:{label:H.column.deleteColumn,group:'tablecolumn',command:'columnDelete',order:15}});if(G.contextMenu)G.contextMenu.addListener(function(I,J){if(!I||I.isReadOnly())return null;while(I){if(I.getName() in F)return{tablecell:2,tablerow:2,tablecolumn:2};I=I.getParent();}return null;});},getSelectedCells:n};j.add('tabletools',j.tabletools);})();e.buildTableMap=function(m){var n=m.$.rows,o=-1,p=[];for(var q=0;qp&&(!s||!t||vt){s=v;t=u;}}else{if(q&&u==p){s=v;break;}if(ut)){s=v;t=u;}}}if(s)s.focus();};(function(){j.add('templates',{requires:['dialog'],init:function(o){a.dialog.add('templates',a.getUrl(this.path+'dialogs/templates.js'));o.addCommand('templates',new a.dialogCommand('templates'));o.ui.addButton('Templates',{label:o.lang.templates.button,command:'templates'});}});var m={},n={};a.addTemplates=function(o,p){m[o]=p;};a.getTemplates=function(o){return m[o];};a.loadTemplates=function(o,p){var q=[];for(var r=0,s=o.length;r':' style="display:none">');t.push('',o.lang.toolbars,'');var w=o.toolbox.toolbars,x=o.config.toolbar instanceof Array?o.config.toolbar:o.config['toolbar_'+o.config.toolbar];for(var y=0;y');v=0;}if(C==='/'){t.push('
      ');continue;}D=C.items||C;for(var E=0;E');B&&t.push('',B,'');t.push('');var I=w.push(A)-1;if(I>0){A.previous=w[I-1];A.previous.next=A;}}if(H){if(!v){t.push('');v=1;}}else if(v){t.push('');v=0;}var J=F.render(o,t);I=A.items.push(J)-1;if(I>0){J.previous=A.items[I-1];J.previous.next=J;}J.toolbar=A;J.onkey=q;J.onfocus=function(){if(!o.toolbox.focusCommandExecuted)o.focus();};}}if(v){t.push('');v=0;}if(A)t.push('');}t.push('');if(o.config.toolbarCanCollapse){var K=e.addFunction(function(){o.execCommand('toolbarCollapse');});o.on('destroy',function(){e.removeFunction(K);});var L=e.getNextId();o.addCommand('toolbarCollapse',{readOnly:1,exec:function(M){var N=a.document.getById(L),O=N.getPrevious(),P=M.getThemeSpace('contents'),Q=O.getParent(),R=parseInt(P.$.style.height,10),S=Q.$.offsetHeight,T=!O.isVisible();if(!T){O.hide();N.addClass('cke_toolbox_collapser_min');N.setAttribute('title',M.lang.toolbarExpand);}else{O.show();N.removeClass('cke_toolbox_collapser_min');N.setAttribute('title',M.lang.toolbarCollapse);}N.getFirst().setText(T?'▲':'◀');var U=Q.$.offsetHeight-S;P.setStyle('height',R-U+'px');M.fire('resize');},modes:{wysiwyg:1,source:1}});t.push('','','');}r.data.html+=t.join('');}});o.on('destroy',function(){var r,s=0,t,u,v;r=this.toolbox.toolbars;for(;s');return{};}};}});}});})();a.UI_SEPARATOR='separator';i.toolbarLocation='top';i.toolbar_Basic=[['Bold','Italic','-','NumberedList','BulletedList','-','Link','Unlink','-','About']];i.toolbar_Full=[{name:'document',items:['Source','-','Save','NewPage','DocProps','Preview','Print','-','Templates']},{name:'clipboard',items:['Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo']},{name:'editing',items:['Find','Replace','-','SelectAll','-','SpellChecker','Scayt']},{name:'forms',items:['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenField']},'/',{name:'basicstyles',items:['Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat']},{name:'paragraph',items:['NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl']},{name:'links',items:['Link','Unlink','Anchor']},{name:'insert',items:['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe']},'/',{name:'styles',items:['Styles','Format','Font','FontSize']},{name:'colors',items:['TextColor','BGColor']},{name:'tools',items:['Maximize','ShowBlocks','-','About']}];i.toolbar='Full';i.toolbarCanCollapse=true;(function(){j.add('undo',{requires:['selection','wysiwygarea'],init:function(s){var t=new o(s),u=s.addCommand('undo',{exec:function(){if(t.undo()){s.selectionChange();this.fire('afterUndo');}},state:0,canUndo:false}),v=s.addCommand('redo',{exec:function(){if(t.redo()){s.selectionChange();this.fire('afterRedo');}},state:0,canUndo:false});t.onChange=function(){u.setState(t.undoable()?2:0);v.setState(t.redoable()?2:0);};function w(x){if(t.enabled&&x.data.command.canUndo!==false)t.save();};s.on('beforeCommandExec',w);s.on('afterCommandExec',w);s.on('saveSnapshot',function(x){t.save(x.data&&x.data.contentOnly);});s.on('contentDom',function(){s.document.on('keydown',function(x){if(!x.data.$.ctrlKey&&!x.data.$.metaKey)t.type(x);});});s.on('beforeModeUnload',function(){s.mode=='wysiwyg'&&t.save(true);});s.on('mode',function(){t.enabled=s.readOnly?false:s.mode=='wysiwyg';t.onChange();});s.ui.addButton('Undo',{label:s.lang.undo,command:'undo'});s.ui.addButton('Redo',{label:s.lang.redo,command:'redo'}); +s.resetUndo=function(){t.reset();s.fire('saveSnapshot');};s.on('updateSnapshot',function(){if(t.currentImage)t.update();});}});j.undo={};var m=j.undo.Image=function(s){this.editor=s;s.fire('beforeUndoImage');var t=s.getSnapshot(),u=t&&s.getSelection();c&&t&&(t=t.replace(/\s+data-cke-expando=".*?"/g,''));this.contents=t;this.bookmarks=u&&u.createBookmarks2(true);s.fire('afterUndoImage');},n=/\b(?:href|src|name)="[^"]*?"/gi;m.prototype={equals:function(s,t){var u=this.contents,v=s.contents;if(c&&(b.ie7Compat||b.ie6Compat)){u=u.replace(n,'');v=v.replace(n,'');}if(u!=v)return false;if(t)return true;var w=this.bookmarks,x=s.bookmarks;if(w||x){if(!w||!x||w.length!=x.length)return false;for(var y=0;y25){this.save(false,null,false);this.modifiersCount=1;}}else if(!y){this.modifiersCount=0;this.typesCount++;if(this.typesCount>25){this.save(false,null,false);this.typesCount=1;}}},reset:function(){var s=this;s.lastKeystroke=0;s.snapshots=[];s.index=-1;s.limit=s.editor.config.undoStackSize||20;s.currentImage=null;s.hasUndo=false;s.hasRedo=false;s.resetType();},resetType:function(){var s=this;s.typing=false;delete s.lastKeystroke;s.typesCount=0;s.modifiersCount=0;},fireChange:function(){var s=this;s.hasUndo=!!s.getNextImage(true);s.hasRedo=!!s.getNextImage(false);s.resetType();s.onChange();},save:function(s,t,u){var w=this;var v=w.snapshots;if(!t)t=new m(w.editor);if(t.contents===false)return false;if(w.currentImage&&t.equals(w.currentImage,s))return false;v.splice(w.index+1,v.length-w.index-1);if(v.length==w.limit)v.shift();w.index=v.push(t)-1;w.currentImage=t; +if(u!==false)w.fireChange();return true;},restoreImage:function(s){var u=this;u.editor.loadSnapshot(s.contents);if(s.bookmarks)u.editor.getSelection().selectBookmarks(s.bookmarks);else if(c){var t=u.editor.document.getBody().$.createTextRange();t.collapse(true);t.select();}u.index=s.index;u.update();u.fireChange();},getNextImage:function(s){var x=this;var t=x.snapshots,u=x.currentImage,v,w;if(u)if(s)for(w=x.index-1;w>=0;w--){v=t[w];if(!u.equals(v,true)){v.index=w;return v;}}else for(w=x.index+1;w]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:]*>| |\u00A0| )?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi,n=d.walker.whitespaces(true);function o(C){return C.isBlockBoundary()&&f.$empty[C.getName()];};function p(C){return function(D){if(this.mode=='wysiwyg'){this.focus();this.fire('saveSnapshot');C.call(this,D.data);e.setTimeout(function(){this.fire('saveSnapshot');},0,this);}};};function q(C){var M=this;if(M.dataProcessor)C=M.dataProcessor.toHtml(C);if(!C)return;var D=M.getSelection(),E=D.getRanges()[0];if(E.checkReadOnly())return;if(b.opera){var F=new d.elementPath(E.startContainer);if(F.block){var G=a.htmlParser.fragment.fromHtml(C,false).children;for(var H=0,I=G.length;H'+O+'';});G=G.replace(/\n/g,'
      ');if(!(F||c))G=G.replace(new RegExp('
      (?=)'),function(M){return e.repeat(M,2);});if(b.gecko||b.webkit){var I=new d.elementPath(D.getStartElement()),J=[];for(var K=0;K/));else if(L in f.$block)break;}G=J.join('')+G;}q.call(this,G);};function s(C){var D=this.getSelection(),E=D.getRanges(),F=C.getName(),G=f.$block[F],H=D.isLocked;if(H)D.unlock();var I,J,K,L;for(var M=E.length-1;M>=0;M--){I=E[M];if(!I.checkReadOnly()){I.deleteContents(1);J=!M&&C||C.clone(1);var N,O;if(G)while((N=I.getCommonAncestor(0,1))&&(O=f[N.getName()])&&!(O&&O[F])){if(N.getName() in f.span)I.splitElement(N);else if(I.checkStartOfBlock()&&I.checkEndOfBlock()){I.setStartBefore(N);I.collapse(true);N.remove();}else I.splitBlock();}I.insertNode(J);if(!K)K=J;}}if(K){I.moveToPosition(K,4);if(G){var P=K.getNext(n),Q=P&&P.type==1&&P.getName();if(Q&&f.$block[Q]&&f[Q]['#'])I.moveToElementEditStart(P);}}D.selectRanges([I]);if(H)this.getSelection().lock();};function t(C){if(!C.checkDirty())setTimeout(function(){C.resetDirty();},0);};var u=d.walker.whitespaces(true),v=d.walker.bookmark(false,true);function w(C){return u(C)&&v(C);};function x(C){return C.type==3&&e.trim(C.getText()).match(/^(?: |\xa0)$/);};function y(C){if(C.isLocked){C.unlock();setTimeout(function(){C.lock();},0);}};function z(C){return C.getOuterHtml().match(m);};u=d.walker.whitespaces(true);function A(C){var D=C.window,E=C.document,F=C.document.getBody(),G=F.getFirst(),H=F.getChildren().count();if(!H||H==1&&G.type==1&&G.hasAttribute('_moz_editor_bogus_node')){t(C);var I=C.element.getDocument(),J=I.getDocumentElement(),K=J.$.scrollTop,L=J.$.scrollLeft,M=E.$.createEvent('KeyEvents');M.initKeyEvent('keypress',true,true,D.$,false,false,false,false,0,32);E.$.dispatchEvent(M);if(K!=J.$.scrollTop||L!=J.$.scrollLeft)I.getWindow().$.scrollTo(L,K);H&&F.getFirst().remove();E.getBody().appendBogus();var N=new d.range(E);N.setStartAt(F,1);N.select();}};function B(C){var D=C.editor,E=C.data.path,F=E.blockLimit,G=C.data.selection,H=G.getRanges()[0],I=D.document.getBody(),J=D.config.enterMode; +if(b.gecko){A(D);var K=E.block||E.blockLimit,L=K&&K.getLast(w);if(K&&K.isBlockBoundary()&&!(L&&L.type==1&&L.isBlockBoundary())&&!K.is('pre')&&!K.getBogus())K.appendBogus();}if(D.config.autoParagraph!==false&&J!=2&&H.collapsed&&F.getName()=='body'&&!E.block){var M=H.fixBlock(true,D.config.enterMode==3?'div':'p');if(c){var N=M.getFirst(w);N&&x(N)&&N.remove();}if(z(M)){var O=M.getNext(u);if(O&&O.type==1&&!o(O)){H.moveToElementEditStart(O);M.remove();}else{O=M.getPrevious(u);if(O&&O.type==1&&!o(O)){H.moveToElementEditEnd(O);M.remove();}}}H.select();C.cancel();}var P=new d.range(D.document);P.moveToElementEditEnd(D.document.getBody());var Q=new d.elementPath(P.startContainer);if(!Q.blockLimit.is('body')){var R;if(J!=2)R=I.append(D.document.createElement(J==1?'p':'div'));else R=I;if(!c)R.appendBogus();}};j.add('wysiwygarea',{requires:['editingblock'],init:function(C){var D=C.config.enterMode!=2&&C.config.autoParagraph!==false?C.config.enterMode==3?'div':'p':false,E=C.lang.editorTitle.replace('%1',C.name),F;C.on('editingBlockReady',function(){var L,M,N,O,P,Q,R=b.isCustomDomain(),S=function(V){if(M)M.remove();var W='document.open();'+(R?'document.domain="'+document.domain+'";':'')+'document.close();';W=b.air?'javascript:void(0)':c?'javascript:void(function(){'+encodeURIComponent(W)+'}())':'';M=h.createFromHtml('');if(document.location.protocol=='chrome:')a.event.useCapture=true;M.on('load',function(X){P=1;X.removeListener();var Y=M.getFrameDocument();Y.write(V);b.air&&U(Y.getWindow().$);});if(document.location.protocol=='chrome:')a.event.useCapture=false;L.append(M);};F=e.addFunction(U);var T='';function U(V){if(!P)return;P=0;C.fire('ariaWidget',M);var W=V.document,X=W.body,Y=W.getElementById('cke_actscrpt');Y&&Y.parentNode.removeChild(Y);X.spellcheck=!C.config.disableNativeSpellChecker;var Z=!C.readOnly;if(c){X.hideFocus=true;X.disabled=true;X.contentEditable=Z;X.removeAttribute('disabled');}else setTimeout(function(){if(b.gecko&&b.version>=10900||b.opera)W.$.body.contentEditable=Z;else if(b.webkit)W.$.body.parentNode.contentEditable=Z;else W.$.designMode=Z?'off':'on';},0);Z&&b.gecko&&e.setTimeout(A,0,null,C);V=C.window=new d.window(V); +W=C.document=new g(W);Z&&W.on('dblclick',function(af){var ag=af.data.getTarget(),ah={element:ag,dialog:''};C.fire('doubleclick',ah);ah.dialog&&C.openDialog(ah.dialog);});c&&W.on('click',function(af){var ag=af.data.getTarget();if(ag.is('input')){var ah=ag.getAttribute('type');if(ah=='submit'||ah=='reset')af.data.preventDefault();}});if(!(c||b.opera))W.on('mousedown',function(af){var ag=af.data.getTarget();if(ag.is('img','hr','input','textarea','select'))C.getSelection().selectElement(ag);});if(b.gecko)W.on('mouseup',function(af){if(af.data.$.button==2){var ag=af.data.getTarget();if(!ag.getOuterHtml().replace(m,'')){var ah=new d.range(W);ah.moveToElementEditStart(ag);ah.select(true);}}});W.on('click',function(af){af=af.data;if(af.getTarget().is('a')&&af.$.button!=2)af.preventDefault();});if(b.webkit){W.on('mousedown',function(){ac=1;});W.on('click',function(af){if(af.data.getTarget().is('input','select'))af.data.preventDefault();});W.on('mouseup',function(af){if(af.data.getTarget().is('input','textarea'))af.data.preventDefault();});}if(Z&&c&&W.$.compatMode=='CSS1Compat'||b.gecko||b.opera){var aa=W.getDocumentElement();aa.on('mousedown',function(af){if(af.data.getTarget().equals(aa)){if(b.gecko&&b.version>=10900)J();K.focus();}});}var ab=c?M:V;ab.on('blur',function(){C.focusManager.blur();});var ac;ab.on('focus',function(){var af=C.document;if(Z&&b.gecko&&b.version>=10900)J();else if(b.opera)af.getBody().focus();else if(b.webkit)if(!ac){C.document.getDocumentElement().focus();ac=1;}C.focusManager.focus();});var ad=C.keystrokeHandler;ad.blockedKeystrokes[8]=!Z;ad.attach(W);W.getDocumentElement().addClass(W.$.compatMode);Z&&W.on('keydown',function(af){var ag=af.data.getKeystroke();if(ag in {8:1,46:1}){var ah=C.getSelection(),ai=ah.getSelectedElement(),aj=ah.getRanges()[0];if(ai){C.fire('saveSnapshot');aj.moveToPosition(ai,3);ai.remove();aj.select();C.fire('saveSnapshot');af.data.preventDefault();return;}}});if(c&&W.$.compatMode=='CSS1Compat'){var ae={33:1,34:1};W.on('keydown',function(af){if(af.data.getKeystroke() in ae)setTimeout(function(){C.getSelection().scrollIntoView();},0);});}if(c&&C.config.enterMode!=1)W.on('selectionchange',function(){var af=W.getBody(),ag=C.getSelection().getRanges()[0];if(af.getHtml().match(/^

       <\/p>$/i)&&ag.startContainer.equals(af))setTimeout(function(){ag=C.getSelection().getRanges()[0];if(!ag.startContainer.equals('body')){af.getFirst().remove(1);ag.moveToElementEditEnd(af);ag.select(1);}},0);});if(C.contextMenu)C.contextMenu.addTarget(W,C.config.browserContextMenuOnCtrl!==false); +setTimeout(function(){C.fire('contentDom');if(Q){C.mode='wysiwyg';C.fire('mode',{previousMode:C._.previousMode});Q=false;}N=false;if(O){C.focus();O=false;}setTimeout(function(){C.fire('dataReady');},0);try{C.document.$.execCommand('enableInlineTableEditing',false,!C.config.disableNativeTableHandles);}catch(af){}if(C.config.disableObjectResizing)try{C.document.$.execCommand('enableObjectResizing',false,false);}catch(ag){C.document.getBody().on(c?'resizestart':'resize',function(ah){ah.data.preventDefault();});}if(c)setTimeout(function(){if(C.document){var ah=C.document.$.body;ah.runtimeStyle.marginBottom='0px';ah.runtimeStyle.marginBottom='';}},1000);},0);};C.addMode('wysiwyg',{load:function(V,W,X){L=V;if(c&&b.quirks)V.setStyle('position','relative');C.mayBeDirty=true;Q=true;if(X)this.loadSnapshotData(W);else this.loadData(W);},loadData:function(V){N=true;C._.dataStore={id:1};var W=C.config,X=W.fullPage,Y=W.docType,Z='';!X&&(Z=e.buildStyleHtml(C.config.contentsCss)+Z);var aa=W.baseHref?'':'';if(X)V=V.replace(/]*>/i,function(ab){C.docType=Y=ab;return '';}).replace(/<\?xml\s[^\?]*\?>/i,function(ab){C.xmlDeclaration=ab;return '';});if(C.dataProcessor)V=C.dataProcessor.toHtml(V,D);if(X){if(!/]/.test(V))V=''+V;if(!/]/.test(V))V=''+V+'';if(!/]/.test(V))V=V.replace(/]*>/,'$&');else if(!/]/.test(V))V=V.replace(/]*>/,'$&');aa&&(V=V.replace(//,'$&'+aa));V=V.replace(/<\/head\s*>/,Z+'$&');V=Y+V;}else V=W.docType+''+''+''+E+''+aa+Z+''+''+V+'';if(b.gecko)V=V.replace(/
      (?=\s*<\/(:?html|body)>)/,'$&
      ');V+=T;this.onDispose();S(V);},getData:function(){var V=C.config,W=V.fullPage,X=W&&C.docType,Y=W&&C.xmlDeclaration,Z=M.getFrameDocument(),aa=W?Z.getDocumentElement().getOuterHtml():Z.getBody().getHtml();if(b.gecko)aa=aa.replace(/
      (?=\s*(:?$|<\/body>))/,'');if(C.dataProcessor)aa=C.dataProcessor.toDataFormat(aa,D);if(V.ignoreEmptyParagraph)aa=aa.replace(m,function(ab,ac){return ac;});if(Y)aa=Y+'\n'+aa;if(X)aa=X+'\n'+aa;return aa;},getSnapshotData:function(){return M.getFrameDocument().getBody().getHtml(); +},loadSnapshotData:function(V){M.getFrameDocument().getBody().setHtml(V);},onDispose:function(){if(!C.document)return;C.document.getDocumentElement().clearCustomData();C.document.getBody().clearCustomData();C.window.clearCustomData();C.document.clearCustomData();M.clearCustomData();M.remove();},unload:function(V){this.onDispose();C.window=C.document=M=L=O=null;C.fire('contentDomUnload');},focus:function(){var V=C.window;if(N)O=true;else if(V){b.air?setTimeout(function(){V.focus();},0):V.focus();C.selectionChange();}}});C.on('insertHtml',p(q),null,null,20);C.on('insertElement',p(s),null,null,20);C.on('insertText',p(r),null,null,20);C.on('selectionChange',function(V){if(C.readOnly)return;var W=C.getSelection();if(W&&!W.isLocked){var X=C.checkDirty();C.fire('saveSnapshot',{contentOnly:1});B.call(this,V);C.fire('updateSnapshot');!X&&C.resetDirty();}},null,null,1);});var G;C.on('contentDom',function(){var L=C.document.getElementsByTag('title').getItem(0);L.data('cke-title',C.document.$.title);C.document.$.title=E;});C.on('readOnly',function(){if(C.mode=='wysiwyg'){var L=C.getMode();L.loadData(L.getData());}});if(a.document.$.documentMode>=8){C.addCss('html.CSS1Compat [contenteditable=false]{ min-height:0 !important;}');var H=[];for(var I in f.$removeEmpty)H.push('html.CSS1Compat '+I+'[contenteditable=false]');C.addCss(H.join(',')+'{ display:inline-block;}');}else if(b.gecko){C.addCss('html { height: 100% !important; }');C.addCss('img:-moz-broken { -moz-force-broken-image-icon : 1;\twidth : 24px; height : 24px; }');}C.addCss('html {\t_overflow-y: scroll; cursor: text;\t*cursor:auto;}');C.addCss('img, input, textarea { cursor: default;}');function J(L){if(C.readOnly)return;e.tryThese(function(){C.document.$.designMode='on';setTimeout(function(){C.document.$.designMode='off';if(a.currentInstance==C)C.document.getBody().focus();},50);},function(){C.document.$.designMode='off';var M=C.document.getBody();M.setAttribute('contentEditable',false);M.setAttribute('contentEditable',true);!L&&J(1);});};if(b.gecko||c||b.opera){var K;C.on('uiReady',function(){K=C.container.append(h.createFromHtml(''));K.on('focus',function(){C.focus();});C.focusGrabber=K;});C.on('destroy',function(){e.removeFunction(F);K.clearCustomData();delete C.focusGrabber;});}C.on('insertElement',function(L){var M=L.data;if(M.type==1&&(M.is('input')||M.is('textarea'))){var N=M.getAttribute('contenteditable')=='false';if(!N){M.data('cke-editable',M.hasAttribute('contenteditable')?'true':'1'); +M.setAttribute('contenteditable',false);}}});}});if(b.gecko)(function(){var C=document.body;if(!C)window.addEventListener('load',arguments.callee,false);else{var D=C.getAttribute('onpageshow');C.setAttribute('onpageshow',(D?D+';':'')+'event.persisted && (function(){'+'var allInstances = CKEDITOR.instances, editor, doc;'+'for ( var i in allInstances )'+'{'+'\teditor = allInstances[ i ];'+'\tdoc = editor.document;'+'\tif ( doc )'+'\t{'+'\t\tdoc.$.designMode = "off";'+'\t\tdoc.$.designMode = "on";'+'\t}'+'}'+'})();');}})();})();i.disableObjectResizing=false;i.disableNativeTableHandles=true;i.disableNativeSpellChecker=true;i.ignoreEmptyParagraph=true;j.add('wsc',{requires:['dialog'],init:function(m){var n='checkspell',o=m.addCommand(n,new a.dialogCommand(n));o.modes={wysiwyg:!b.opera&&!b.air&&document.domain==window.location.hostname};m.ui.addButton('SpellChecker',{label:m.lang.spellCheck.toolbar,command:n});a.dialog.add(n,this.path+'dialogs/wsc.js');}});i.wsc_customerId=i.wsc_customerId||'1:ua3xw1-2XyGJ3-GWruD3-6OFNT1-oXcuB1-nR6Bp4-hgQHc-EcYng3-sdRXG3-NOfFk';i.wsc_customLoaderScript=i.wsc_customLoaderScript||null;a.DIALOG_RESIZE_NONE=0;a.DIALOG_RESIZE_WIDTH=1;a.DIALOG_RESIZE_HEIGHT=2;a.DIALOG_RESIZE_BOTH=3;(function(){var m=e.cssLength;function n(S){return!!this._.tabs[S][0].$.offsetHeight;};function o(){var W=this;var S=W._.currentTabId,T=W._.tabIdList.length,U=e.indexOf(W._.tabIdList,S)+T;for(var V=U-1;V>U-T;V--){if(n.call(W,W._.tabIdList[V%T]))return W._.tabIdList[V%T];}return null;};function p(){var W=this;var S=W._.currentTabId,T=W._.tabIdList.length,U=e.indexOf(W._.tabIdList,S);for(var V=U+1;V1){af._.tabBarMode=true;af._.tabs[af._.currentTabId][0].focus();aj=1;}else if((as==37||as==39)&&af._.tabBarMode){av=as==(at?39:37)?o.call(af):p.call(af);af.selectPage(av);af._.tabs[av][0].focus();aj=1;}else if((as==13||as==32)&&af._.tabBarMode){aw.selectPage(aw._.currentTabId);aw._.tabBarMode=false;aw._.currentFocusIndex=-1;ai(true);aj=1;}if(aj){ar.stop();ar.data.preventDefault();}};function al(ar){aj&&ar.data.preventDefault();};var am=this._.element;this.on('show',function(){am.on('keydown',ak,this,null,0);if(b.opera||b.gecko&&b.mac)am.on('keypress',al,this);});this.on('hide',function(){am.removeListener('keydown',ak);if(b.opera||b.gecko&&b.mac)am.removeListener('keypress',al);ag(function(ar){s.apply(ar);});});this.on('iframeAdded',function(ar){var as=new g(ar.data.iframe.$.contentWindow.document);as.on('keydown',ak,this,null,0);});this.on('show',function(){var av=this;ah();if(S.config.dialog_startupFocusTab&&af._.pageCount>1){af._.tabBarMode=true;af._.tabs[af._.currentTabId][0].focus();}else if(!av._.hasFocus){av._.currentFocusIndex=-1;if(U.onFocus){var ar=U.onFocus.call(av);ar&&ar.focus();}else ai(true);if(av._.editor.mode=='wysiwyg'&&c){var as=S.document.$.selection,at=as.createRange();if(at)if(at.parentElement&&at.parentElement().ownerDocument==S.document.$||at.item&&at.item(0).ownerDocument==S.document.$){var au=document.body.createTextRange();au.moveToElementText(av.getElement().getFirst().$);au.collapse(true);au.select();}}}},this,null,4294967295);if(b.ie6Compat)this.on('load',function(ar){var as=this.getElement(),at=as.getFirst();at.remove();at.appendTo(as);},this);A(this);B(this);new d.text(U.title,a.document).appendTo(this.parts.title);for(var an=0;an0?U:0)+'px'};ab[X?'right':'left']=(T>0?T:0)+'px';W.setStyles(ab);V&&(ac._.moved=1);};})(),getPosition:function(){return e.extend({},this._.position);},show:function(){var S=this._.element,T=this.definition;if(!(S.getParent()&&S.getParent().equals(a.document.getBody())))S.appendTo(a.document.getBody());else S.setStyle('display','block');if(b.gecko&&b.version<10900){var U=this.parts.dialog;U.setStyle('position','absolute');setTimeout(function(){U.setStyle('position','fixed');},0);}this.resize(this._.contentSize&&this._.contentSize.width||T.width||T.minWidth,this._.contentSize&&this._.contentSize.height||T.height||T.minHeight);this.reset(); +this.selectPage(this.definition.contents[0].id);if(a.dialog._.currentZIndex===null)a.dialog._.currentZIndex=this._.editor.config.baseFloatZIndex;this._.element.getFirst().setStyle('z-index',a.dialog._.currentZIndex+=10);if(a.dialog._.currentTop===null){a.dialog._.currentTop=this;this._.parentDialog=null;G(this._.editor);S.on('keydown',K);S.on(b.opera?'keypress':'keyup',L);for(var V in {keyup:1,keydown:1,keypress:1})S.on(V,R);}else{this._.parentDialog=a.dialog._.currentTop;var W=this._.parentDialog.getElement().getFirst();W.$.style.zIndex-=Math.floor(this._.editor.config.baseFloatZIndex/2);a.dialog._.currentTop=this;}M(this,this,'\x1b',null,function(){this.getButton('cancel')&&this.getButton('cancel').click();});this._.hasFocus=false;e.setTimeout(function(){this.layout();this.parts.dialog.setStyle('visibility','');this.fireOnce('load',{});k.fire('ready',this);this.fire('show',{});this._.editor.fire('dialogShow',this);this.foreach(function(X){X.setInitValue&&X.setInitValue();});},100,this);},layout:function(){var U=this;var S=a.document.getWindow().getViewPaneSize(),T=U.getSize();U.move(U._.moved?U._.position.x:(S.width-T.width)/2,U._.moved?U._.position.y:(S.height-T.height)/2);},foreach:function(S){var V=this;for(var T in V._.contents)for(var U in V._.contents[T])S.call(V,V._.contents[T][U]);return V;},reset:(function(){var S=function(T){if(T.reset)T.reset(1);};return function(){this.foreach(S);return this;};})(),setupContent:function(){var S=arguments;this.foreach(function(T){if(T.setup)T.setup.apply(T,S);});},commitContent:function(){var S=arguments;this.foreach(function(T){if(c&&this._.currentFocusIndex==T.focusIndex)T.getInputElement().$.blur();if(T.commit)T.commit.apply(T,S);});},hide:function(){if(!this.parts.dialog.isVisible())return;this.fire('hide',{});this._.editor.fire('dialogHide',this);var S=this._.element;S.setStyle('display','none');this.parts.dialog.setStyle('visibility','hidden');N(this);while(a.dialog._.currentTop!=this)a.dialog._.currentTop.hide();if(!this._.parentDialog)H();else{var T=this._.parentDialog.getElement().getFirst();T.setStyle('z-index',parseInt(T.$.style.zIndex,10)+Math.floor(this._.editor.config.baseFloatZIndex/2));}a.dialog._.currentTop=this._.parentDialog;if(!this._.parentDialog){a.dialog._.currentZIndex=null;S.removeListener('keydown',K);S.removeListener(b.opera?'keypress':'keyup',L);for(var U in {keyup:1,keydown:1,keypress:1})S.removeListener(U,R);var V=this._.editor;V.focus();if(V.mode=='wysiwyg'&&c){var W=V.getSelection(); +W&&W.unlock(true);}}else a.dialog._.currentZIndex-=10;delete this._.parentDialog;this.foreach(function(X){X.resetInitValue&&X.resetInitValue();});},addPage:function(S){var ae=this;var T=[],U=S.label?' title="'+e.htmlEncode(S.label)+'"':'',V=S.elements,W=a.dialog._.uiElementBuilders.vbox.build(ae,{type:'vbox',className:'cke_dialog_page_contents',children:S.elements,expand:!!S.expand,padding:S.padding,style:S.style||'width: 100%;height:100%'},T),X=h.createFromHtml(T.join(''));X.setAttribute('role','tabpanel');var Y=b,Z='cke_'+S.id+'_'+e.getNextNumber(),aa=h.createFromHtml(['0?' cke_last':'cke_first',U,!!S.hidden?' style="display:none"':'',' id="',Z,'"',Y.gecko&&Y.version>=10900&&!Y.hc?'':' href="javascript:void(0)"',' tabIndex="-1"',' hidefocus="true"',' role="tab">',S.label,''].join(''));X.setAttribute('aria-labelledby',Z);ae._.tabs[S.id]=[aa,X];ae._.tabIdList.push(S.id);!S.hidden&&ae._.pageCount++;ae._.lastTab=aa;ae.updateStyle();var ab=ae._.contents[S.id]={},ac,ad=W.getChild();while(ac=ad.shift()){ab[ac.id]=ac;if(typeof ac.getChild=='function')ad.push.apply(ad,ac.getChild());}X.setAttribute('name',S.id);X.appendTo(ae.parts.contents);aa.unselectable();ae.parts.tabs.append(aa);if(S.accessKey){M(ae,ae,'CTRL+'+S.accessKey,P,O);ae._.accessKeyMap['CTRL+'+S.accessKey]=S.id;}},selectPage:function(S){if(this._.currentTabId==S)return;if(this.fire('selectPage',{page:S,currentPage:this._.currentTabId})===true)return;for(var T in this._.tabs){var U=this._.tabs[T][0],V=this._.tabs[T][1];if(T!=S){U.removeClass('cke_dialog_tab_selected');V.hide();}V.setAttribute('aria-hidden',T!=S);}var W=this._.tabs[S];W[0].addClass('cke_dialog_tab_selected');if(b.ie6Compat||b.ie7Compat){q(W[1]);W[1].show();setTimeout(function(){q(W[1],1);},0);}else W[1].show();this._.currentTabId=S;this._.currentTabIndex=e.indexOf(this._.tabIdList,S);},updateStyle:function(){this.parts.dialog[(this._.pageCount===1?'add':'remove')+'Class']('cke_single_page');},hidePage:function(S){var U=this;var T=U._.tabs[S]&&U._.tabs[S][0];if(!T||U._.pageCount==1||!T.isVisible())return;else if(S==U._.currentTabId)U.selectPage(o.call(U));T.hide();U._.pageCount--;U.updateStyle();},showPage:function(S){var U=this;var T=U._.tabs[S]&&U._.tabs[S][0];if(!T)return;T.show();U._.pageCount++;U.updateStyle();},getElement:function(){return this._.element;},getName:function(){return this._.name;},getContentElement:function(S,T){var U=this._.contents[S];return U&&U[T];},getValueOf:function(S,T){return this.getContentElement(S,T).getValue(); +},setValueOf:function(S,T,U){return this.getContentElement(S,T).setValue(U);},getButton:function(S){return this._.buttons[S];},click:function(S){return this._.buttons[S].click();},disableButton:function(S){return this._.buttons[S].disable();},enableButton:function(S){return this._.buttons[S].enable();},getPageCount:function(){return this._.pageCount;},getParentEditor:function(){return this._.editor;},getSelectedElement:function(){return this.getParentEditor().getSelection().getSelectedElement();},addFocusable:function(S,T){var V=this;if(typeof T=='undefined'){T=V._.focusList.length;V._.focusList.push(new t(V,S,T));}else{V._.focusList.splice(T,0,new t(V,S,T));for(var U=T+1;Uad.width-ac.width-X)ai=ad.width-ac.width+(W.lang.dir=='rtl'?0:Y[1]);else ai=U.x;if(U.y+Y[0]ad.height-ac.height-X)aj=ad.height-ac.height+Y[2];else aj=U.y;S.move(ai,aj,1);ab.data.preventDefault();};function aa(ab){a.document.removeListener('mousemove',Z);a.document.removeListener('mouseup',aa);if(b.ie6Compat){var ac=E.getChild(0).getFrameDocument();ac.removeListener('mousemove',Z);ac.removeListener('mouseup',aa);}};S.parts.title.on('mousedown',function(ab){T={x:ab.data.$.screenX,y:ab.data.$.screenY};a.document.on('mousemove',Z);a.document.on('mouseup',aa);U=S.getPosition();if(b.ie6Compat){var ac=E.getChild(0).getFrameDocument();ac.on('mousemove',Z);ac.on('mouseup',aa);}ab.data.preventDefault();},S);};function B(S){var T=S.definition,U=T.resizable;if(U==0)return;var V=S.getParentEditor(),W,X,Y,Z,aa,ab,ac=e.addFunction(function(af){aa=S.getSize();var ag=S.parts.contents,ah=ag.$.getElementsByTagName('iframe').length;if(ah){ab=h.createFromHtml('

      ');ag.append(ab);}X=aa.height-S.parts.contents.getSize('height',!(b.gecko||b.opera||c&&b.quirks));W=aa.width-S.parts.contents.getSize('width',1);Z={x:af.screenX,y:af.screenY};Y=a.document.getWindow().getViewPaneSize();a.document.on('mousemove',ad);a.document.on('mouseup',ae);if(b.ie6Compat){var ai=E.getChild(0).getFrameDocument();ai.on('mousemove',ad);ai.on('mouseup',ae);}af.preventDefault&&af.preventDefault(); +});S.on('load',function(){var af='';if(U==1)af=' cke_resizer_horizontal';else if(U==2)af=' cke_resizer_vertical';var ag=h.createFromHtml('
      ');S.parts.footer.append(ag,1);});V.on('destroy',function(){e.removeFunction(ac);});function ad(af){var ag=V.lang.dir=='rtl',ah=(af.data.$.screenX-Z.x)*(ag?-1:1),ai=af.data.$.screenY-Z.y,aj=aa.width,ak=aa.height,al=aj+ah*(S._.moved?1:2),am=ak+ai*(S._.moved?1:2),an=S._.element.getFirst(),ao=ag&&an.getComputedStyle('right'),ap=S.getPosition();if(ap.y+am>Y.height)am=Y.height-ap.y;if((ag?ao:ap.x)+al>Y.width)al=Y.width-(ag?ao:ap.x);if(U==1||U==3)aj=Math.max(T.minWidth||0,al-W);if(U==2||U==3)ak=Math.max(T.minHeight||0,am-X);S.resize(aj,ak);if(!S._.moved)S.layout();af.data.preventDefault();};function ae(){a.document.removeListener('mouseup',ae);a.document.removeListener('mousemove',ad);if(ab){ab.remove();ab=null;}if(b.ie6Compat){var af=E.getChild(0).getFrameDocument();af.removeListener('mouseup',ae);af.removeListener('mousemove',ad);}};};var C,D={},E;function F(S){S.data.preventDefault(1);};function G(S){var T=a.document.getWindow(),U=S.config,V=U.dialog_backgroundCoverColor||'white',W=U.dialog_backgroundCoverOpacity,X=U.baseFloatZIndex,Y=e.genKey(V,W,X),Z=D[Y];if(!Z){var aa=['
      '];if(b.ie6Compat){var ab=b.isCustomDomain(),ac="";aa.push('');}aa.push('
      ');Z=h.createFromHtml(aa.join(''));Z.setOpacity(W!=undefined?W:0.5);Z.on('keydown',F);Z.on('keypress',F);Z.on('keyup',F);Z.appendTo(a.document.getBody());D[Y]=Z;}else Z.show();E=Z;var ad=function(){var ag=T.getViewPaneSize();Z.setStyles({width:ag.width+'px',height:ag.height+'px'});},ae=function(){var ag=T.getScrollPosition(),ah=a.dialog._.currentTop;Z.setStyles({left:ag.x+'px',top:ag.y+'px'});if(ah)do{var ai=ah.getPosition(); +ah.move(ai.x,ai.y);}while(ah=ah._.parentDialog)};C=ad;T.on('resize',ad);ad();if(!(b.mac&&b.webkit))Z.focus();if(b.ie6Compat){var af=function(){ae();arguments.callee.prevScrollHandler.apply(this,arguments);};T.$.setTimeout(function(){af.prevScrollHandler=window.onscroll||(function(){});window.onscroll=af;},0);ae();}};function H(){if(!E)return;var S=a.document.getWindow();E.hide();S.removeListener('resize',C);if(b.ie6Compat)S.$.setTimeout(function(){var T=window.onscroll&&window.onscroll.prevScrollHandler;window.onscroll=T||null;},0);C=null;};function I(){for(var S in D)D[S].remove();D={};};var J={},K=function(S){var T=S.data.$.ctrlKey||S.data.$.metaKey,U=S.data.$.altKey,V=S.data.$.shiftKey,W=String.fromCharCode(S.data.$.keyCode),X=J[(T?'CTRL+':'')+(U?'ALT+':'')+(V?'SHIFT+':'')+W];if(!X||!X.length)return;X=X[X.length-1];X.keydown&&X.keydown.call(X.uiElement,X.dialog,X.key);S.data.preventDefault();},L=function(S){var T=S.data.$.ctrlKey||S.data.$.metaKey,U=S.data.$.altKey,V=S.data.$.shiftKey,W=String.fromCharCode(S.data.$.keyCode),X=J[(T?'CTRL+':'')+(U?'ALT+':'')+(V?'SHIFT+':'')+W];if(!X||!X.length)return;X=X[X.length-1];if(X.keyup){X.keyup.call(X.uiElement,X.dialog,X.key);S.data.preventDefault();}},M=function(S,T,U,V,W){var X=J[U]||(J[U]=[]);X.push({uiElement:S,dialog:T,key:U,keyup:W||S.accessKeyUp,keydown:V||S.accessKeyDown});},N=function(S){for(var T in J){var U=J[T];for(var V=U.length-1;V>=0;V--){if(U[V].dialog==S||U[V].uiElement==S)U.splice(V,1);}if(U.length===0)delete J[T];}},O=function(S,T){if(S._.accessKeyMap[T])S.selectPage(S._.accessKeyMap[T]);},P=function(S,T){},Q={27:1,13:1},R=function(S){if(S.data.getKeystroke() in Q)S.data.stopPropagation();};(function(){k.dialog={uiElement:function(S,T,U,V,W,X,Y){if(arguments.length<4)return;var Z=(V.call?V(T):V)||'div',aa=['<',Z,' '],ab=(W&&W.call?W(T):W)||{},ac=(X&&X.call?X(T):X)||{},ad=(Y&&Y.call?Y.call(this,S,T):Y)||'',ae=this.domId=ac.id||e.getNextId()+'_uiElement',af=this.id=T.id,ag;ac.id=ae;var ah={};if(T.type)ah['cke_dialog_ui_'+T.type]=1;if(T.className)ah[T.className]=1;if(T.disabled)ah.cke_disabled=1;var ai=ac['class']&&ac['class'].split?ac['class'].split(' '):[];for(ag=0;ag=0;ag--){if(ak[ag]==='')ak.splice(ag,1);}if(ak.length>0)ac.style=(ac.style?ac.style+'; ':'')+ak.join('; ');for(ag in ac)aa.push(ag+'="'+e.htmlEncode(ac[ag])+'" ');aa.push('>',ad,'');U.push(aa.join(''));(this._||(this._={})).dialog=S;if(typeof T.isChanged=='boolean')this.isChanged=function(){return T.isChanged;};if(typeof T.isChanged=='function')this.isChanged=T.isChanged;if(typeof T.setValue=='function')this.setValue=e.override(this.setValue,function(an){return function(ao){an.call(this,T.setValue.call(this,ao));};});if(typeof T.getValue=='function')this.getValue=e.override(this.getValue,function(an){return function(){return T.getValue.call(this,an.call(this));};});a.event.implementOn(this);this.registerEvents(T);if(this.accessKeyUp&&this.accessKeyDown&&T.accessKey)M(this,S,'CTRL+'+T.accessKey);var am=this;S.on('load',function(){var an=am.getInputElement();if(an){var ao=am.type in {checkbox:1,ratio:1}&&c&&b.version<8?'cke_dialog_ui_focused':'';an.on('focus',function(){S._.tabBarMode=false;S._.hasFocus=true;am.fire('focus');ao&&this.addClass(ao);});an.on('blur',function(){am.fire('blur');ao&&this.removeClass(ao);});}});if(this.keyboardFocusable){this.tabIndex=T.tabIndex||0;this.focusIndex=S._.focusList.push(this)-1;this.on('focus',function(){S._.currentFocusIndex=am.focusIndex;});}e.extend(this,T);},hbox:function(S,T,U,V,W){if(arguments.length<4)return;this._||(this._={});var X=this._.children=T,Y=W&&W.widths||null,Z=W&&W.height||null,aa={},ab,ac=function(){var ae=[''];for(ab=0;ab0)ae.push('style="'+ag.join('; ')+'" ');ae.push('>',U[ab],'');}ae.push('');return ae.join('');},ad={role:'presentation'};W&&W.align&&(ad.align=W.align);k.dialog.uiElement.call(this,S,W||{type:'hbox'},V,'table',aa,ad,ac);},vbox:function(S,T,U,V,W){if(arguments.length<3)return;this._||(this._={});var X=this._.children=T,Y=W&&W.width||null,Z=W&&W.heights||null,aa=function(){var ab=['');for(var ac=0;ac');}ab.push('
      0)ab.push('style="',ad.join('; '),'" ');ab.push(' class="cke_dialog_ui_vbox_child">',U[ac],'
      ');return ab.join('');};k.dialog.uiElement.call(this,S,W||{type:'vbox'},V,'div',null,{role:'presentation'},aa);}};})();k.dialog.uiElement.prototype={getElement:function(){return a.document.getById(this.domId);},getInputElement:function(){return this.getElement();},getDialog:function(){return this._.dialog;},setValue:function(S,T){this.getInputElement().setValue(S);!T&&this.fire('change',{value:S});return this;},getValue:function(){return this.getInputElement().getValue();},isChanged:function(){return false;},selectParentTab:function(){var V=this;var S=V.getInputElement(),T=S,U;while((T=T.getParent())&&T.$.className.search('cke_dialog_page_contents')==-1){}if(!T)return V;U=T.getAttribute('name');if(V._.dialog._.currentTabId!=U)V._.dialog.selectPage(U);return V;},focus:function(){this.selectParentTab().getInputElement().focus();return this;},registerEvents:function(S){var T=/^on([A-Z]\w+)/,U,V=function(X,Y,Z,aa){Y.on('load',function(){X.getInputElement().on(Z,aa,X);});};for(var W in S){if(!(U=W.match(T)))continue;if(this.eventProcessors[W])this.eventProcessors[W].call(this,this._.dialog,S[W]);else V(this,this._.dialog,U[1].toLowerCase(),S[W]);}return this;},eventProcessors:{onLoad:function(S,T){S.on('load',T,this);},onShow:function(S,T){S.on('show',T,this);},onHide:function(S,T){S.on('hide',T,this);}},accessKeyDown:function(S,T){this.focus();},accessKeyUp:function(S,T){},disable:function(){var S=this.getElement(),T=this.getInputElement();T.setAttribute('disabled','true');S.addClass('cke_disabled');},enable:function(){var S=this.getElement(),T=this.getInputElement();T.removeAttribute('disabled');S.removeClass('cke_disabled');},isEnabled:function(){return!this.getElement().hasClass('cke_disabled');},isVisible:function(){return this.getInputElement().isVisible();},isFocusable:function(){if(!this.isEnabled()||!this.isVisible())return false; +return true;}};k.dialog.hbox.prototype=e.extend(new k.dialog.uiElement(),{getChild:function(S){var T=this;if(arguments.length<1)return T._.children.concat();if(!S.splice)S=[S];if(S.length<2)return T._.children[S[0]];else return T._.children[S[0]]&&T._.children[S[0]].getChild?T._.children[S[0]].getChild(S.slice(1,S.length)):null;}},true);k.dialog.vbox.prototype=new k.dialog.hbox();(function(){var S={build:function(T,U,V){var W=U.children,X,Y=[],Z=[];for(var aa=0;aa',T||U.name,'');return V.join('');}};a.style.getStyleText=function(T){var U=T._ST;if(U)return U;U=T.styles;var V=T.attributes&&T.attributes.style||'',W='';if(V.length)V=V.replace(o,';');for(var X in U){var Y=U[X],Z=(X+':'+Y).replace(o,';');if(Y=='inherit')W+=Z;else V+=Z;}if(V.length)V=P(V);V+=W;return T._ST=V;};function s(T){var U,V;while(T=T.getParent()){if(T.getName()=='body')break;if(T.getAttribute('data-nostyle'))U=T;else if(!V){var W=T.getAttribute('contentEditable');if(W=='false')U=T;else if(W=='true')V=1;}}return U;};function t(T){var ay=this;var U=T.document;if(T.collapsed){var V=J(ay,U);T.insertNode(V);T.moveToPosition(V,2);return;}var W=ay.element,X=ay._.definition,Y,Z=X.ignoreReadonly,aa=Z||X.includeReadonly;if(aa==undefined)aa=U.getCustomData('cke_includeReadonly');var ab=f[W]||(Y=true,f.span);T.enlarge(1,1);T.trim();var ac=T.createBookmark(),ad=ac.startNode,ae=ac.endNode,af=ad,ag;if(!Z){var ah=s(ad),ai=s(ae);if(ah)af=ah.getNextSourceNode(true);if(ai)ae=ai;}if(af.getPosition(ae)==2)af=0;while(af){var aj=false;if(af.equals(ae)){af=null;aj=true;}else{var ak=af.type,al=ak==1?af.getName():null,am=al&&af.getAttribute('contentEditable')=='false',an=al&&af.getAttribute('data-nostyle'); +if(al&&af.data('cke-bookmark')){af=af.getNextSourceNode(true);continue;}if(!al||ab[al]&&!an&&(!am||aa)&&(af.getPosition(ae)|4|0|8)==4+0+8&&(!X.childRule||X.childRule(af))){var ao=af.getParent();if(ao&&((ao.getDtd()||f.span)[W]||Y)&&(!X.parentRule||X.parentRule(ao))){if(!ag&&(!al||!f.$removeEmpty[al]||(af.getPosition(ae)|4|0|8)==4+0+8)){ag=new d.range(U);ag.setStartBefore(af);}if(ak==3||am||ak==1&&!af.getChildCount()){var ap=af,aq;while((aj=!ap.getNext(q))&&(aq=ap.getParent(),ab[aq.getName()])&&(aq.getPosition(ad)|2|0|8)==2+0+8&&(!X.childRule||X.childRule(aq)))ap=aq;ag.setEndAfter(ap);}}else aj=true;}else aj=true;af=af.getNextSourceNode(an||am);}if(aj&&ag&&!ag.collapsed){var ar=J(ay,U),as=ar.hasAttributes(),at=ag.getCommonAncestor(),au={styles:{},attrs:{},blockedStyles:{},blockedAttrs:{}},av,aw,ax;while(ar&&at){if(at.getName()==W){for(av in X.attributes){if(au.blockedAttrs[av]||!(ax=at.getAttribute(aw)))continue;if(ar.getAttribute(av)==ax)au.attrs[av]=1;else au.blockedAttrs[av]=1;}for(aw in X.styles){if(au.blockedStyles[aw]||!(ax=at.getStyle(aw)))continue;if(ar.getStyle(aw)==ax)au.styles[aw]=1;else au.blockedStyles[aw]=1;}}at=at.getParent();}for(av in au.attrs)ar.removeAttribute(av);for(aw in au.styles)ar.removeStyle(aw);if(as&&!ar.hasAttributes())ar=null;if(ar){ag.extractContents().appendTo(ar);G(ay,ar);ag.insertNode(ar);ar.mergeSiblings();if(!c)ar.$.normalize();}else{ar=new h('span');ag.extractContents().appendTo(ar);ag.insertNode(ar);G(ay,ar);ar.remove(true);}ag=null;}}T.moveToBookmark(ac);T.shrink(2);};function u(T){T.enlarge(1,1);var U=T.createBookmark(),V=U.startNode;if(T.collapsed){var W=new d.elementPath(V.getParent()),X;for(var Y=0,Z;Y'+V+'';else T.setHtml(V);U.remove();};function B(T){var U=/(\S\s*)\n(?:\s|(]+data-cke-bookmark.*?\/span>))*\n(?!$)/gi,V=T.getName(),W=C(T.getOuterHtml(),U,function(Y,Z,aa){return Z+''+aa+'
      ';}),X=[];W.replace(/([\s\S]*?)<\/pre>/gi,function(Y,Z){X.push(Z);});return X;};function C(T,U,V){var W='',X='';T=T.replace(/(^]+data-cke-bookmark.*?\/span>)|(]+data-cke-bookmark.*?\/span>$)/gi,function(Y,Z,aa){Z&&(W=Z);aa&&(X=aa);return '';});return W+T.replace(U,V)+X;};function D(T,U){var V;if(T.length>1)V=new d.documentFragment(U.getDocument());for(var W=0;W');X=X.replace(/[ \t]{2,}/g,function(Z){return e.repeat(' ',Z.length-1)+' ';});if(V){var Y=U.clone();Y.setHtml(X);V.append(Y);}else U.setHtml(X);}return V||U;};function E(T,U){var V=T.getBogus();V&&V.remove();var W=T.getHtml();W=C(W,/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g,'');W=W.replace(/[ \t\r\n]*(]*>)[ \t\r\n]*/gi,'$1');W=W.replace(/([ \t\n\r]+| )/g,' ');W=W.replace(/]*>/gi,'\n');if(c){var X=T.getDocument().createElement('div');X.append(U);U.$.outerHTML='
      '+W+'
      ';U.copyAttributes(X.getFirst());U=X.getFirst().remove();}else U.setHtml(W);return U;};function F(T,U){var V=T._.definition,W=e.extend({},V.attributes,N(T)[U.getName()]),X=V.styles,Y=e.isEmpty(W)&&e.isEmpty(X);for(var Z in W){if((Z=='class'||T._.definition.fullMatch)&&U.getAttribute(Z)!=O(Z,W[Z]))continue;Y=U.hasAttribute(Z);U.removeAttribute(Z);}for(var aa in X){if(T._.definition.fullMatch&&U.getStyle(aa)!=O(aa,X[aa],true))continue;Y=Y||!!U.getStyle(aa);U.removeStyle(aa);}if(Y)!f.$block[U.getName()]||T._.enterMode==2&&!U.hasAttributes()?I(U):U.renameNode(T._.enterMode==1?'p':'div');};function G(T,U){var V=T._.definition,W=V.attributes,X=V.styles,Y=N(T),Z=U.getElementsByTag(T.element);for(var aa=Z.count();--aa>=0;)F(T,Z.getItem(aa));for(var ab in Y){if(ab!=T.element){Z=U.getElementsByTag(ab);for(aa=Z.count()-1;aa>=0;aa--){var ac=Z.getItem(aa);H(ac,Y[ab]);}}}};function H(T,U){var V=U&&U.attributes;if(V)for(var W=0;W0)H+=(F.$.offsetWidth||0)-(F.$.clientWidth||0)+3;H+=4;F.setStyle('width',H+'px');v.element.addClass('cke_frameLoaded');var I=v.element.$.scrollHeight;if(c&&b.quirks&&I>0)I+=(F.$.offsetHeight||0)-(F.$.clientHeight||0)+3;F.setStyle('height',I+'px');u._.currentBlock.element.setStyle('display','none').removeStyle('display');}else F.removeStyle('height');var J=u.element,K=J.getWindow(),L=K.getScrollPosition(),M=K.getViewPaneSize(),N={height:J.$.offsetHeight,width:J.$.offsetWidth};if(A?B<0:B+N.width>M.width+L.x)B+=N.width*(A?1:-1); +if(C+N.height>M.height+L.y)C-=N.height;if(c){var O=new h(w.$.offsetParent),P=O;if(P.getName()=='html')P=P.getDocument().getBody();if(P.getComputedStyle('direction')=='rtl')if(b.ie8Compat)B-=w.getDocument().getDocumentElement().$.scrollLeft*2;else B-=O.$.scrollWidth-O.$.clientWidth;}var Q=w.getFirst(),R;if(R=Q.getCustomData('activePanel'))R.onHide&&R.onHide.call(this,1);Q.setCustomData('activePanel',this);w.setStyles({top:C+'px',left:B+'px'});w.setOpacity(1);},this);u.isLoaded?E():u.onLoad=E;e.setTimeout(function(){x.$.contentWindow.focus();this.allowBlur(true);},0,this);},b.air?200:0,this);this.visible=1;if(this.onShow)this.onShow.call(this);n=0;},hide:function(p){var r=this;if(r.visible&&(!r.onHide||r.onHide.call(r)!==true)){r.hideChild();b.gecko&&r._.iframe.getFrameDocument().$.activeElement.blur();r.element.setStyle('display','none');r.visible=0;r.element.getFirst().removeCustomData('activePanel');var q=p!==false&&r._.returnFocus;if(q){if(b.webkit&&q.type)q.getWindow().$.focus();q.focus();}}},allowBlur:function(p){var q=this._.panel;if(p!=undefined)q.allowBlur=p;return q.allowBlur;},showAsChild:function(p,q,r,s,t,u){if(this._.activeChild==p&&p._.panel._.offsetParentId==r.getId())return;this.hideChild();p.onHide=e.bind(function(){e.setTimeout(function(){if(!this._.focused)this.hide();},0,this);},this);this._.activeChild=p;this._.focused=false;p.showBlock(q,r,s,t,u);if(b.ie7Compat||b.ie8&&b.ie6Compat)setTimeout(function(){p.element.getChild(0).$.style.cssText+='';},100);},hideChild:function(){var p=this._.activeChild;if(p){delete p.onHide;delete p._.returnFocus;delete this._.activeChild;p.hide();}}}});a.on('instanceDestroyed',function(){var p=e.isEmpty(a.instances);for(var q in m){var r=m[q];if(p)r.destroy();else r.element.hide();}p&&(m={});});})();j.add('menu',{beforeInit:function(m){var n=m.config.menu_groups.split(','),o=m._.menuGroups={},p=m._.menuItems={};for(var q=0;q'],B=r.length,C=B&&r[0].group;for(var D=0;D');C=E.group;}E.render(this,D,A);}A.push('');u.setHtml(A.join(''));k.fire('ready',this);if(this.parent)this.parent._.panel.showAsChild(t,this.id,n,o,p,q);else t.showBlock(this.id,n,o,p,q);s.fire('menuShow',[t]);},addListener:function(n){this._.listeners.push(n);},hide:function(n){var o=this;o._.onHide&&o._.onHide();o._.panel&&o._.panel.hide(n);}}});function m(n){n.sort(function(o,p){if(o.groupp.group)return 1;return o.orderp.order?1:0;});};a.menuItem=e.createClass({$:function(n,o,p){var q=this;e.extend(q,p,{order:0,className:'cke_button_'+o});q.group=n._.menuGroups[q.group];q.editor=n;q.name=o;},proto:{render:function(n,o,p){var w=this;var q=n.id+String(o),r=typeof w.state=='undefined'?2:w.state,s=' cke_'+(r==1?'on':r==0?'disabled':'off'),t=w.label;if(w.className)s+=' '+w.className;var u=w.getItems;p.push(''+''+'');if(u)p.push('','&#',w.editor.lang.dir=='rtl'?'9668':'9658',';','');p.push(t,'');}}});})();i.menu_groups='clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,div'; +(function(){var m;j.add('editingblock',{init:function(n){if(!n.config.editingBlock)return;n.on('themeSpace',function(o){if(o.data.space=='contents')o.data.html+='
      ';});n.on('themeLoaded',function(){n.fireOnce('editingBlockReady');});n.on('uiReady',function(){n.setMode(n.config.startupMode);});n.on('afterSetData',function(){if(!m){function o(){m=true;n.getMode().loadData(n.getData());m=false;};if(n.mode)o();else n.on('mode',function(){if(n.mode){o();n.removeListener('mode',arguments.callee);}});}});n.on('beforeGetData',function(){if(!m&&n.mode){m=true;n.setData(n.getMode().getData(),null,1);m=false;}});n.on('getSnapshot',function(o){if(n.mode)o.data=n.getMode().getSnapshotData();});n.on('loadSnapshot',function(o){if(n.mode)n.getMode().loadSnapshotData(o.data);});n.on('mode',function(o){o.removeListener();b.webkit&&n.container.on('focus',function(){n.focus();});if(n.config.startupFocus)n.focus();setTimeout(function(){n.fireOnce('instanceReady');a.fire('instanceReady',null,n);},0);});n.on('destroy',function(){var o=this;if(o.mode)o._.modes[o.mode].unload(o.getThemeSpace('contents'));});}});a.editor.prototype.mode='';a.editor.prototype.addMode=function(n,o){o.name=n;(this._.modes||(this._.modes={}))[n]=o;};a.editor.prototype.setMode=function(n){this.fire('beforeSetMode',{newMode:n});var o,p=this.getThemeSpace('contents'),q=this.checkDirty();if(this.mode){if(n==this.mode)return;this._.previousMode=this.mode;this.fire('beforeModeUnload');var r=this.getMode();o=r.getData();r.unload(p);this.mode='';}p.setHtml('');var s=this.getMode(n);if(!s)throw '[CKEDITOR.editor.setMode] Unknown mode "'+n+'".';if(!q)this.on('mode',function(){this.resetDirty();this.removeListener('mode',arguments.callee);});s.load(p,typeof o!='string'?this.getData():o);};a.editor.prototype.getMode=function(n){return this._.modes&&this._.modes[n||this.mode];};a.editor.prototype.focus=function(){this.forceNextSelectionCheck();var n=this.getMode();if(n)n.focus();};})();i.startupMode='wysiwyg';i.editingBlock=true;(function(){function m(){var B=this;try{var y=B.getSelection();if(!y||!y.document.getWindow().$)return;var z=y.getStartElement(),A=new d.elementPath(z);if(!A.compare(B._.selectionPreviousPath)){B._.selectionPreviousPath=A;B.fire('selectionChange',{selection:y,path:A,element:z});}}catch(C){}};var n,o;function p(){o=true;if(n)return;q.call(this);n=e.setTimeout(q,200,this);};function q(){n=null;if(o){e.setTimeout(m,0,this);o=false;}};function r(y){function z(D){return D&&D.type==1&&D.getName() in f.$removeEmpty; +};function A(D){var E=y.document.getBody();return!D.is('body')&&E.getChildCount()==1;};var B=y.startContainer,C=y.startOffset;if(B.type==3)return false;return!e.trim(B.getHtml())?z(B)||A(B):z(B.getChild(C-1))||z(B.getChild(C));};var s={modes:{wysiwyg:1,source:1},readOnly:c||b.webkit,exec:function(y){switch(y.mode){case 'wysiwyg':y.document.$.execCommand('SelectAll',false,null);y.forceNextSelectionCheck();y.selectionChange();break;case 'source':var z=y.textarea.$;if(c)z.createTextRange().execCommand('SelectAll');else{z.selectionStart=0;z.selectionEnd=z.value.length;}z.focus();}},canUndo:false};function t(y){w(y);var z=y.createText('​');y.setCustomData('cke-fillingChar',z);return z;};function u(y){return y&&y.getCustomData('cke-fillingChar');};function v(y){var z=y&&u(y);if(z)if(z.getCustomData('ready'))w(y);else z.setCustomData('ready',1);};function w(y){var z=y&&y.removeCustomData('cke-fillingChar');if(z){z.setText(z.getText().replace(/\u200B/g,''));z=0;}};j.add('selection',{init:function(y){if(b.webkit){y.on('selectionChange',function(){v(y.document);});y.on('beforeSetMode',function(){w(y.document);});y.on('key',function(D){switch(D.data.keyCode){case 13:case 2228224+13:case 37:case 39:case 8:w(y.document);}},null,null,10);var z,A;function B(){var D=y.document,E=u(D);if(E){var F=D.$.defaultView.getSelection();if(F.type=='Caret'&&F.anchorNode==E.$)A=1;z=E.getText();E.setText(z.replace(/\u200B/g,''));}};function C(){var D=y.document,E=u(D);if(E){E.setText(z);if(A){D.$.defaultView.getSelection().setPosition(E.$,E.getLength());A=0;}}};y.on('beforeUndoImage',B);y.on('afterUndoImage',C);y.on('beforeGetData',B,null,null,0);y.on('getData',C);}y.on('contentDom',function(){var D=y.document,E=D.getBody(),F=D.getDocumentElement();if(c){var G,H,I=1;E.on('focusin',function(M){if(M.data.$.srcElement.nodeName!='BODY')return;if(G){if(I){try{G.select();}catch(O){}var N=D.getCustomData('cke_locked_selection');if(N){N.unlock();N.lock();}}G=null;}});E.on('focus',function(){H=1;L();});E.on('beforedeactivate',function(M){if(M.data.$.toElement)return;H=0;I=1;});if(c&&b.version<8)y.on('blur',function(M){try{y.document&&y.document.$.selection.empty();}catch(N){}});F.on('mousedown',function(){I=0;});F.on('mouseup',function(){I=1;});if(c&&(b.ie7Compat||b.version<8||b.quirks))F.on('click',function(M){if(M.data.getTarget().getName()=='html')y.getSelection().getRanges()[0].select();});var J;E.on('mousedown',function(M){if(M.data.$.button==2){var N=y.document.$.selection;if(N.type=='None')J=y.window.getScrollPosition(); +}K();});E.on('mouseup',function(M){if(M.data.$.button==2&&J){y.document.$.documentElement.scrollLeft=J.x;y.document.$.documentElement.scrollTop=J.y;}J=null;H=1;setTimeout(function(){L(true);},0);});E.on('keydown',K);E.on('keyup',function(){H=1;L();});D.on('selectionchange',L);function K(){H=0;};function L(M){if(H){var N=y.document,O=y.getSelection(),P=O&&O.getNative();if(M&&P&&P.type=='None')if(!N.$.queryCommandEnabled('InsertImage')){e.setTimeout(L,50,this,true);return;}var Q;if(P&&P.type&&P.type!='Control'&&(Q=P.createRange())&&(Q=Q.parentElement())&&(Q=Q.nodeName)&&Q.toLowerCase() in {input:1,textarea:1})return;G=P&&O.getRanges()[0];p.call(y);}};}else{D.on('mouseup',p,y);D.on('keyup',p,y);D.on('selectionchange',p,y);}});y.on('contentDomUnload',y.forceNextSelectionCheck,y);y.addCommand('selectAll',s);y.ui.addButton('SelectAll',{label:y.lang.selectAll,command:'selectAll'});y.selectionChange=p;b.ie9Compat&&y.on('destroy',function(){var D=y.getSelection();D&&D.getNative().clear();},null,null,9);}});a.editor.prototype.getSelection=function(){return this.document&&this.document.getSelection();};a.editor.prototype.forceNextSelectionCheck=function(){delete this._.selectionPreviousPath;};g.prototype.getSelection=function(){var y=new d.selection(this);return!y||y.isInvalid?null:y;};a.SELECTION_NONE=1;a.SELECTION_TEXT=2;a.SELECTION_ELEMENT=3;d.selection=function(y){var B=this;var z=y.getCustomData('cke_locked_selection');if(z)return z;B.document=y;B.isLocked=0;B._={cache:{}};if(c){var A=B.getNative().createRange();if(!A||A.item&&A.item(0).ownerDocument!=B.document.$||A.parentElement&&A.parentElement().ownerDocument!=B.document.$)B.isInvalid=true;}return B;};var x={img:1,hr:1,li:1,table:1,tr:1,td:1,th:1,embed:1,object:1,ol:1,ul:1,a:1,input:1,form:1,select:1,textarea:1,button:1,fieldset:1,thead:1,tfoot:1};d.selection.prototype={getNative:c?function(){return this._.cache.nativeSel||(this._.cache.nativeSel=this.document.$.selection);}:function(){return this._.cache.nativeSel||(this._.cache.nativeSel=this.document.getWindow().$.getSelection());},getType:c?function(){var y=this._.cache;if(y.type)return y.type;var z=1;try{var A=this.getNative(),B=A.type;if(B=='Text')z=2;if(B=='Control')z=3;if(A.createRange().parentElement)z=2;}catch(C){}return y.type=z;}:function(){var y=this._.cache;if(y.type)return y.type;var z=2,A=this.getNative();if(!A)z=1;else if(A.rangeCount==1){var B=A.getRangeAt(0),C=B.startContainer;if(C==B.endContainer&&C.nodeType==1&&B.endOffset-B.startOffset==1&&x[C.childNodes[B.startOffset].nodeName.toLowerCase()])z=3; +}return y.type=z;},getRanges:(function(){var y=c?(function(){function z(B){return new d.node(B).getIndex();};var A=function(B,C){B=B.duplicate();B.collapse(C);var D=B.parentElement(),E=D.ownerDocument;if(!D.hasChildNodes())return{container:D,offset:0};var F=D.children,G,H,I=B.duplicate(),J=0,K=F.length-1,L=-1,M,N;while(J<=K){L=Math.floor((J+K)/2);G=F[L];I.moveToElementText(G);M=I.compareEndPoints('StartToStart',B);if(M>0)K=L-1;else if(M<0)J=L+1;else if(b.ie9Compat&&G.tagName=='BR'){var O='cke_range_marker';B.execCommand('CreateBookmark',false,O);G=E.getElementsByName(O)[0];var P=z(G);D.removeChild(G);return{container:D,offset:P};}else return{container:D,offset:z(G)};}if(L==-1||L==F.length-1&&M<0){I.moveToElementText(D);I.setEndPoint('StartToStart',B);N=I.text.replace(/(\r\n|\r)/g,'\n').length;F=D.childNodes;if(!N){G=F[F.length-1];if(G.nodeType==1)return{container:D,offset:F.length};else return{container:G,offset:G.nodeValue.length};}var Q=F.length;while(N>0)N-=F[--Q].nodeValue.length;return{container:F[Q],offset:-N};}else{I.collapse(M>0?true:false);I.setEndPoint(M>0?'StartToStart':'EndToStart',B);N=I.text.replace(/(\r\n|\r)/g,'\n').length;if(!N)return{container:D,offset:z(G)+(M>0?0:1)};while(N>0)try{H=G[M>0?'previousSibling':'nextSibling'];N-=H.nodeValue.length;G=H;}catch(R){return{container:D,offset:z(G)};}return{container:G,offset:M>0?-N:G.nodeValue.length+N};}};return function(){var L=this;var B=L.getNative(),C=B&&B.createRange(),D=L.getType(),E;if(!B)return[];if(D==2){E=new d.range(L.document);var F=A(C,true);E.setStart(new d.node(F.container),F.offset);F=A(C);E.setEnd(new d.node(F.container),F.offset);if(E.endContainer.getPosition(E.startContainer)&4&&E.endOffset<=E.startContainer.getIndex())E.collapse();return[E];}else if(D==3){var G=[];for(var H=0;H=G.getLength())K.setStartAfter(G);else K.setStartBefore(G);if(H&&H.type==3)if(!J)K.setEndBefore(H);else K.setEndAfter(H);var L=new d.walker(K);L.evaluator=function(M){if(M.type==1&&M.isReadOnly()){var N=D.clone();D.setEndBefore(M);if(D.collapsed)B.splice(C--,1);if(!(M.getPosition(K.endContainer)&16)){N.setStartAfter(M);if(!N.collapsed)B.splice(C+1,0,N);}return true;}return false;};L.next();}}return A.ranges;};})(),getStartElement:function(){var F=this;var y=F._.cache;if(y.startElement!==undefined)return y.startElement;var z,A=F.getNative();switch(F.getType()){case 3:return F.getSelectedElement();case 2:var B=F.getRanges()[0];if(B){if(!B.collapsed){B.optimize();while(1){var C=B.startContainer,D=B.startOffset;if(D==(C.getChildCount?C.getChildCount():C.getLength())&&!C.isBlockBoundary())B.setStartAfter(C);else break;}z=B.startContainer;if(z.type!=1)return z.getParent();z=z.getChild(B.startOffset);if(!z||z.type!=1)z=B.startContainer;else{var E=z.getFirst();while(E&&E.type==1){z=E;E=E.getFirst();}}}else{z=B.startContainer;if(z.type!=1)z=z.getParent();}z=z.$;}}return y.startElement=z?new h(z):null;},getSelectedElement:function(){var y=this._.cache;if(y.selectedElement!==undefined)return y.selectedElement;var z=this,A=e.tryThese(function(){return z.getNative().createRange().item(0);},function(){var B,C,D=z.getRanges()[0],E=D.getCommonAncestor(1,1),F={table:1,ul:1,ol:1,dl:1};for(var G in F){if(B=E.getAscendant(G,1))break;}if(B){var H=new d.range(this.document);H.setStartAt(B,1);H.setEnd(D.startContainer,D.startOffset);var I=e.extend(F,f.$listItem,f.$tableContent),J=new d.walker(H),K=function(L,M){return function(N,O){if(N.type==3&&(!e.trim(N.getText())||N.getParent().data('cke-bookmark')))return true;var P;if(N.type==1){P=N.getName();if(P=='br'&&M&&N.equals(N.getParent().getBogus()))return true;if(O&&P in I||P in f.$removeEmpty)return true;}L.halted=1;return false;};};J.guard=K(J);if(J.checkBackward()&&!J.halted){J=new d.walker(H);H.setStart(D.endContainer,D.endOffset);H.setEndAt(B,2);J.guard=K(J,1);if(J.checkForward()&&!J.halted)C=B.$;}}if(!C)throw 0; +return C;},function(){var B=z.getRanges()[0],C,D;for(var E=2;E&&!((C=B.getEnclosedNode())&&C.type==1&&x[C.getName()]&&(D=C));E--)B.shrink(1);return D.$;});return y.selectedElement=A?new h(A):null;},getSelectedText:function(){var y=this._.cache;if(y.selectedText!==undefined)return y.selectedText;var z='',A=this.getNative();if(this.getType()==2)z=c?A.createRange().text:A.toString();return y.selectedText=z;},lock:function(){var y=this;y.getRanges();y.getStartElement();y.getSelectedElement();y.getSelectedText();y._.cache.nativeSel={};y.isLocked=1;y.document.setCustomData('cke_locked_selection',y);},unlock:function(y){var D=this;var z=D.document,A=z.getCustomData('cke_locked_selection');if(A){z.setCustomData('cke_locked_selection',null);if(y){var B=A.getSelectedElement(),C=!B&&A.getRanges();D.isLocked=0;D.reset();z.getBody().focus();if(B)D.selectElement(B);else D.selectRanges(C);}}if(!A||!y){D.isLocked=0;D.reset();}},reset:function(){this._.cache={};},selectElement:function(y){var A=this;if(A.isLocked){var z=new d.range(A.document);z.setStartBefore(y);z.setEndAfter(y);A._.cache.selectedElement=y;A._.cache.startElement=y;A._.cache.ranges=new d.rangeList(z);A._.cache.type=3;return;}z=new d.range(y.getDocument());z.setStartBefore(y);z.setEndAfter(y);z.select();A.document.fire('selectionchange');A.reset();},selectRanges:function(y){var M=this;if(M.isLocked){M._.cache.selectedElement=null;M._.cache.startElement=y[0]&&y[0].getTouchedStartNode();M._.cache.ranges=new d.rangeList(y);M._.cache.type=2;return;}if(c){if(y.length>1){var z=y[y.length-1];y[0].setEnd(z.endContainer,z.endOffset);y.length=1;}if(y[0])y[0].select();M.reset();}else{var A=M.getNative();if(!A)return;if(y.length){A.removeAllRanges();b.webkit&&w(M.document);}for(var B=0;B=0){H.collapse(1);I.setEnd(H.endContainer.$,H.endOffset);}else throw N;}A.addRange(I);}M.document.fire('selectionchange');M.reset();}},createBookmarks:function(y){return this.getRanges().createBookmarks(y);},createBookmarks2:function(y){return this.getRanges().createBookmarks2(y);},selectBookmarks:function(y){var z=[];for(var A=0;A','','',this.label,'','=10900&&!o.hc?'':" href=\"javascript:void('"+this.label+"')\"",' role="button" aria-labelledby="',p,'_label" aria-describedby="',p,'_text" aria-haspopup="true"');if(b.opera||b.gecko&&b.mac)n.push(' onkeypress="return false;"');if(b.gecko)n.push(' onblur="this.style.cssText = this.style.cssText;"');n.push(' onkeydown="CKEDITOR.tools.callFunction( ',t,', event, this );" onfocus="return CKEDITOR.tools.callFunction(',u,', event);" '+(c?'onclick="return false;" onmouseup':'onclick')+'="CKEDITOR.tools.callFunction(',q,', this); return false;">'+this.label+''+''+''+(b.hc?'▼':b.air?' ':'')+''+''+''+'');if(this.onRender)this.onRender();return r;},createPanel:function(m){if(this._.panel)return;var n=this._.panelDefinition,o=this._.panelDefinition.block,p=n.parent||a.document.getBody(),q=new k.floatPanel(m,p,n),r=q.addListBlock(this.id,o),s=this;q.onShow=function(){if(s.className)this.element.getFirst().addClass(s.className+'_panel');s.setState(1);r.focus(!s.multiSelect&&s.getValue());s._.on=1;if(s.onOpen)s.onOpen();};q.onHide=function(t){if(s.className)this.element.getFirst().removeClass(s.className+'_panel');s.setState(s.modes&&s.modes[m.mode]?2:0);s._.on=0;if(!t&&s.onClose)s.onClose();};q.onEscape=function(){q.hide();};r.onClick=function(t,u){s.document.getWindow().focus();if(s.onClick)s.onClick.call(s,t,u);if(u)s.setValue(t,s._.items[t]);else s.setValue(''); +q.hide(false);};this._.panel=q;this._.list=r;q.getBlock(this.id).onHide=function(){s._.on=0;s.setState(2);};if(this.init)this.init();},setValue:function(m,n){var p=this;p._.value=m;var o=p.document.getById('cke_'+p.id+'_text');if(o){if(!(m||n)){n=p.label;o.addClass('cke_inline_label');}else o.removeClass('cke_inline_label');o.setHtml(typeof n!='undefined'?n:m);}},getValue:function(){return this._.value||'';},unmarkAll:function(){this._.list.unmarkAll();},mark:function(m){this._.list.mark(m);},hideItem:function(m){this._.list.hideItem(m);},hideGroup:function(m){this._.list.hideGroup(m);},showAll:function(){this._.list.showAll();},add:function(m,n,o){this._.items[m]=o||m;this._.list.add(m,n,o);},startGroup:function(m){this._.list.startGroup(m);},commit:function(){var m=this;if(!m._.committed){m._.list.commit();m._.committed=1;k.fire('ready',m);}m._.committed=1;},setState:function(m){var n=this;if(n._.state==m)return;n.document.getById('cke_'+n.id).setState(m);n._.state=m;}}});k.prototype.addRichCombo=function(m,n){this.add(m,'richcombo',n);};j.add('htmlwriter');a.htmlWriter=e.createClass({base:a.htmlParser.basicWriter,$:function(){var o=this;o.base();o.indentationChars='\t';o.selfClosingEnd=' />';o.lineBreakChars='\n';o.forceSimpleAmpersand=0;o.sortAttributes=1;o._.indent=0;o._.indentation='';o._.inPre=0;o._.rules={};var m=f;for(var n in e.extend({},m.$nonBodyContent,m.$block,m.$listItem,m.$tableContent))o.setRules(n,{indent:1,breakBeforeOpen:1,breakAfterOpen:1,breakBeforeClose:!m[n]['#'],breakAfterClose:1});o.setRules('br',{breakAfterOpen:1});o.setRules('title',{indent:0,breakAfterOpen:0});o.setRules('style',{indent:0,breakBeforeClose:1});o.setRules('pre',{indent:0});},proto:{openTag:function(m,n){var p=this;var o=p._.rules[m];if(p._.indent)p.indentation();else if(o&&o.breakBeforeOpen){p.lineBreak();p.indentation();}p._.output.push('<',m);},openTagClose:function(m,n){var p=this;var o=p._.rules[m];if(n)p._.output.push(p.selfClosingEnd);else{p._.output.push('>');if(o&&o.indent)p._.indentation+=p.indentationChars;}if(o&&o.breakAfterOpen)p.lineBreak();m=='pre'&&(p._.inPre=1);},attribute:function(m,n){if(typeof n=='string'){this.forceSimpleAmpersand&&(n=n.replace(/&/g,'&'));n=e.htmlEncodeAttr(n);}this._.output.push(' ',m,'="',n,'"');},closeTag:function(m){var o=this;var n=o._.rules[m];if(n&&n.indent)o._.indentation=o._.indentation.substr(o.indentationChars.length);if(o._.indent)o.indentation();else if(n&&n.breakBeforeClose){o.lineBreak();o.indentation();}o._.output.push(''); +m=='pre'&&(o._.inPre=0);if(n&&n.breakAfterClose)o.lineBreak();},text:function(m){var n=this;if(n._.indent){n.indentation();!n._.inPre&&(m=e.ltrim(m));}n._.output.push(m);},comment:function(m){if(this._.indent)this.indentation();this._.output.push('');},lineBreak:function(){var m=this;if(!m._.inPre&&m._.output.length>0)m._.output.push(m.lineBreakChars);m._.indent=1;},indentation:function(){var m=this;if(!m._.inPre)m._.output.push(m._.indentation);m._.indent=0;},setRules:function(m,n){var o=this._.rules[m];if(o)e.extend(o,n,true);else this._.rules[m]=n;}}});j.add('menubutton',{requires:['button','menu'],beforeInit:function(m){m.ui.addHandler('menubutton',k.menuButton.handler);}});a.UI_MENUBUTTON='menubutton';(function(){var m=function(n){var o=this._;if(o.state===0)return;o.previousState=o.state;var p=o.menu;if(!p){p=o.menu=new a.menu(n,{panel:{className:n.skinClass+' cke_contextmenu',attributes:{'aria-label':n.lang.common.options}}});p.onHide=e.bind(function(){this.setState(this.modes&&this.modes[n.mode]?o.previousState:0);},this);if(this.onMenu)p.addListener(this.onMenu);}if(o.on){p.hide();return;}this.setState(1);p.show(a.document.getById(this._.id),4);};k.menuButton=e.createClass({base:k.button,$:function(n){var o=n.panel;delete n.panel;this.base(n);this.hasArrow=true;this.click=m;},statics:{handler:{create:function(n){return new k.menuButton(n);}}}});})();j.add('dialogui');(function(){var m=function(u){var x=this;x._||(x._={});x._['default']=x._.initValue=u['default']||'';x._.required=u.required||false;var v=[x._];for(var w=1;w',v.label,'','');else{var D={type:'hbox',widths:v.widths,padding:0,children:[{type:'html',html:'