richtext-or-file-procs.tcl

Rich text input widget and datatype for OpenACS templating system.

Location:
packages/acs-templating/tcl/richtext-or-file-procs.tcl
Created:
2003-01-27
Author:
Lars Pind <lars@pinds.com>
CVS Identification:
$Id: richtext-or-file-procs.tcl,v 1.15 2024/09/11 06:15:48 gustafn Exp $

Procedures in this file

Detailed information

template::data::transform::richtext_or_file (public)

 template::data::transform::richtext_or_file element_ref

Transform submitted data into a valid richtext_or_file data structure (list)

Parameters:
element_ref (required)
Reference variable to the form element
Returns:
Submitted data in the richtext_or_datafile list form

Partial Call Graph (max 5 caller/called nodes):
%3 template::util::file::get_property template::util::file::get_property (public) template::util::file_transform template::util::file_transform (public) template::data::transform::richtext_or_file template::data::transform::richtext_or_file template::data::transform::richtext_or_file->template::util::file::get_property template::data::transform::richtext_or_file->template::util::file_transform

Testcases:
No testcase defined.

template::data::validate::richtext_or_file (public)

 template::data::validate::richtext_or_file value_ref message_ref

Validate submitted richtext_or_file by checking that the format is valid, HTML doesn't contain illegal tags, etc.

Parameters:
value_ref (required)
Reference variable to the submitted value
message_ref (required)
Reference variable for returning an error message
Returns:
True (1) if the submitted value is valid, false (0) otherwise

Partial Call Graph (max 5 caller/called nodes):
%3 ad_html_security_check ad_html_security_check (public) template::data::validate::text template::data::validate::text (public) template::util::richtext_or_file::formats template::util::richtext_or_file::formats (public) template::data::validate::richtext_or_file template::data::validate::richtext_or_file template::data::validate::richtext_or_file->ad_html_security_check template::data::validate::richtext_or_file->template::data::validate::text template::data::validate::richtext_or_file->template::util::richtext_or_file::formats

Testcases:
No testcase defined.

template::util::richtext_or_file (public)

 template::util::richtext_or_file command [ args... ]

Dispatch procedure for the richtext_or_file object

Parameters:
command (required)

Partial Call Graph (max 5 caller/called nodes):
%3

Testcases:
No testcase defined.

template::util::richtext_or_file::acquire (public)

 template::util::richtext_or_file::acquire type [ value ]

Create a new richtext_or_file value with some predefined value Basically, create and set the richtext_or_file value

Parameters:
type (required)
value (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 template::util::richtext_or_file::create template::util::richtext_or_file::create (public) template::util::richtext_or_file::set_property template::util::richtext_or_file::set_property (public) template::util::richtext_or_file::acquire template::util::richtext_or_file::acquire template::util::richtext_or_file::acquire->template::util::richtext_or_file::create template::util::richtext_or_file::acquire->template::util::richtext_or_file::set_property

Testcases:
No testcase defined.

template::util::richtext_or_file::create (public)

 template::util::richtext_or_file::create [ storage_type ] \
    [ mime_type ] [ text ] [ filename ] [ tmp_filename ] \
    [ content_url ]

Create a richtext_or_file datastructure.

Parameters:
storage_type (optional)
mime_type (optional)
text (optional)
filename (optional)
tmp_filename (optional)
content_url (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 template::util::richtext_or_file::acquire template::util::richtext_or_file::acquire (public) template::util::richtext_or_file::create template::util::richtext_or_file::create template::util::richtext_or_file::acquire->template::util::richtext_or_file::create

Testcases:
No testcase defined.

template::util::richtext_or_file::format_options (public)

 template::util::richtext_or_file::format_options

Returns a formatting option list

Partial Call Graph (max 5 caller/called nodes):
%3 template::widget::richtext_or_file template::widget::richtext_or_file (public) template::util::richtext_or_file::format_options template::util::richtext_or_file::format_options template::widget::richtext_or_file->template::util::richtext_or_file::format_options

Testcases:
No testcase defined.

template::util::richtext_or_file::formats (public)

 template::util::richtext_or_file::formats

Returns a list of valid richtext_or_file formats

Partial Call Graph (max 5 caller/called nodes):
%3 template::data::validate::richtext_or_file template::data::validate::richtext_or_file (public) template::util::richtext_or_file::formats template::util::richtext_or_file::formats template::data::validate::richtext_or_file->template::util::richtext_or_file::formats

Testcases:
No testcase defined.

template::util::richtext_or_file::get_property (public)

 template::util::richtext_or_file::get_property what \
    richtext_or_file_list

Get a property of the richtext_or_file datatype. Valid properties are:

  • storage_type
  • mime_type
  • text
  • filename
  • tmp_filename
  • content_url

Parameters:
what (required)
richtext_or_file_list (required)

Partial Call Graph (max 5 caller/called nodes):
%3 template::widget::richtext_or_file template::widget::richtext_or_file (public) template::util::richtext_or_file::get_property template::util::richtext_or_file::get_property template::widget::richtext_or_file->template::util::richtext_or_file::get_property ad_html_text_convert ad_html_text_convert (public) template::util::richtext_or_file::get_property->ad_html_text_convert

Testcases:
No testcase defined.

template::util::richtext_or_file::set_property (public)

 template::util::richtext_or_file::set_property what \
    richtext_or_file_list value

Set a property of the richtext_or_file datatype. Valid properties are:

  • storage_type
  • mime_type
  • text
  • filename
  • tmp_filename
  • content_url

Parameters:
what (required)
richtext_or_file_list (required)
value (required)

Partial Call Graph (max 5 caller/called nodes):
%3 template::util::richtext_or_file::acquire template::util::richtext_or_file::acquire (public) template::util::richtext_or_file::set_property template::util::richtext_or_file::set_property template::util::richtext_or_file::acquire->template::util::richtext_or_file::set_property

Testcases:
No testcase defined.

template::widget::richtext_or_file (public)

 template::widget::richtext_or_file element_reference tag_attributes

Render a richtext_or_file widget

Parameters:
element_reference (required)
Reference variable to the form element
tag_attributes (required)
Attributes to include in the generated HTML
Returns:
Form HTML for the widget

Partial Call Graph (max 5 caller/called nodes):
%3 security::csp::nonce security::csp::nonce (public) template::add_event_listener template::add_event_listener (public) template::head::add_javascript template::head::add_javascript (public) template::util::richtext_or_file::format_options template::util::richtext_or_file::format_options (public) template::util::richtext_or_file::get_property template::util::richtext_or_file::get_property (public) template::widget::richtext_or_file template::widget::richtext_or_file template::widget::richtext_or_file->security::csp::nonce template::widget::richtext_or_file->template::add_event_listener template::widget::richtext_or_file->template::head::add_javascript template::widget::richtext_or_file->template::util::richtext_or_file::format_options template::widget::richtext_or_file->template::util::richtext_or_file::get_property

Testcases:
No testcase defined.
[ hide source ] | [ make this the default ]

Content File Source

ad_library {
    Rich text input widget and datatype for OpenACS templating system.

    @author Lars Pind (lars@pinds.com)
    @creation-date 2003-01-27
    @cvs-id $Id: richtext-or-file-procs.tcl,v 1.15 2024/09/11 06:15:48 gustafn Exp $
}

namespace eval template {}
namespace eval template::data {}
namespace eval template::data::transform {}
namespace eval template::data::validate {}
namespace eval template::util {}
namespace eval template::util::richtext_or_file {}
namespace eval template::widget {}

ad_proc -public template::util::richtext_or_file { command args } {
    Dispatch procedure for the richtext_or_file object
} {
  template::util::richtext_or_file::$command {*}$args
}

d_proc -public template::util::richtext_or_file::create {
    {storage_type {}}
    {mime_type {}}
    {text {}}
    {filename {}}
    {tmp_filename {}}
    {content_url {}}
} {
    Create a richtext_or_file datastructure.
} {
    return [list $storage_type $mime_type $text $filename $tmp_filename $content_url]
}

ad_proc -public template::util::richtext_or_file::acquire { type { value "" } } {
    Create a new richtext_or_file value with some predefined value
    Basically, create and set the richtext_or_file value
} {
  set richtext_or_file_list [template::util::richtext_or_file::create]
  return [template::util::richtext_or_file::set_property $type $richtext_or_file_list $value]
}

ad_proc -public template::util::richtext_or_file::formats {} {
    Returns a list of valid richtext_or_file formats
} {
    return { text/enhanced text/markdown text/plain text/html text/fixed-width }
}

ad_proc -public template::util::richtext_or_file::format_options {} {
    Returns a formatting option list
} {
    return {
        {"Enhanced Text" text/enhanced}
        {"Markdown Text" text/markdown}
        {"Plain Text" text/plain}
        {"Fixed-width Text" text/fixed-width}
        {"HTML" text/html}
    }
}

d_proc -public template::data::validate::richtext_or_file {
    value_ref
    message_ref
} {
    Validate submitted richtext_or_file by checking that the format is valid, HTML doesn't
    contain illegal tags, etc.

    @param value_ref Reference variable to the submitted value
    @param message_ref Reference variable for returning an error message

    @return True (1) if the submitted value is valid, false (0) otherwise
} {


    upvar 2 $message_ref message $value_ref richtext_or_file_list

    lassign $richtext_or_file_list storage_type mime_type text filename tmp_filename content_url

    if { $text ne "" && [lsearch -exact [template::util::richtext_or_file::formats$mime_type] == -1 } {
        set message "Invalid text format, '$mime_type'."
        return 0
    }

    # enhanced text and HTML needs to be security checked
    if { $mime_type in { text/enhanced text/html } } {
        set check_result [ad_html_security_check $text]
        if { $check_result ne "" } {
            set message $check_result
            return 0
        }
    }

    return 1
}

d_proc -public template::data::transform::richtext_or_file {
    element_ref
} {
    Transform submitted data into a valid richtext_or_file data structure (list)

    @param element_ref Reference variable to the form element

    @return Submitted data in the richtext_or_datafile list form

} {

    upvar $element_ref element
    set element_id $element(id)

    # We need to return the empty list in order for form builder to think of it
    # as a non-value in case of a required element.

    set storage_type [ns_queryget $element_id.storage_type]
    switch -- $storage_type {
        text {
            set text [ns_queryget $element_id.text]
            if { $text eq "" } {
                return [list]
            }
            set mime_type [ns_queryget $element_id.mime_type]

            return [list [list "text" $mime_type $text {} {} {}]]
        }
        file {
            set file [template::util::file_transform $element_id.file]
            if { $file eq "" } {
                return [list]
            }
            set filename [template::util::file::get_property filename $file]
            set tmp_filename [template::util::file::get_property tmp_filename $file]
            set mime_type [template::util::file::get_property mime_type $file]

            return [list [list "file" $mime_type {} $filename $tmp_filename {}]]
        }
        default {
            return [list]
        }
    }
}

ad_proc -public template::util::richtext_or_file::set_property { what richtext_or_file_list value } {
    Set a property of the richtext_or_file datatype. Valid properties are:

    <ul>
      <li>storage_type
      <li>mime_type
      <li>text
      <li>filename
      <li>tmp_filename
      <li>content_url
    </ul>
} {
    lassign richtext_or_file_list storage_type mime_type text filename tmp_filename content_url

    switch -- $what {
        storage_type {
            # Replace contents with value
            return [list $value $mime_type $text $filename $tmp_filename $content_url]
        }
        mime_type {
            # Replace format with value
            return [list $storage_type $value $text $filename $tmp_filename $content_url]
        }
        text {
            # Replace contents with value
            return [list $storage_type $mime_type $value $filename $tmp_filename $content_url]
        }
        filename {
            return [list $storage_type $mime_type $text $value $tmp_filename $content_url]
        }
        tmp_filename {
            return [list $storage_type $mime_type $text $filename $value $content_url]
        }
        content_url {
            return [list $storage_type $mime_type $text $filename $tmp_filename $value]
        }
        default {
            error "Invalid property $what, valid properties are storage_type, mime_type, text, filename, tmp_filanme, content_url."
        }
    }
}

ad_proc -public template::util::richtext_or_file::get_property { what richtext_or_file_list } {

    Get a property of the richtext_or_file datatype. Valid properties are:

    <ul>
      <li>storage_type
      <li>mime_type
      <li>text
      <li>filename
      <li>tmp_filename
      <li>content_url
    </ul>
} {
    lassign $richtext_or_file_list storage_type mime_type text filename tmp_filename content_url

    switch -- $what {
        storage_type {
            return $storage_type
        }
        mime_type {
            return $mime_type
        }
        text {
            return $text
        }
        filename {
            return $filename
        }
        tmp_filename {
            return $tmp_filename
        }
        content_url {
            return $content_url
        }
        file {
            return [list $filename $tmp_filename $mime_type]
        }
        html_value {
            switch -- $storage_type {
                text {
                    return [ad_html_text_convert -from $mime_type -to "text/html" -- $text]
                }
                file {
                    return "<a href=\"[ns_quotehtml $content_url]\">Download file</a>"
                }
            }
            return {}
        }
        default {
            error "Invalid property $what, valid properties are storage_type, mime_type, text, filename, tmp_filanme, content_url, html_value, file."
        }
    }
}

d_proc -public template::widget::richtext_or_file {
    element_reference
    tag_attributes
} {
    Render a richtext_or_file widget

    @param element_reference Reference variable to the form element
    @param tag_attributes Attributes to include in the generated HTML

    @return Form HTML for the widget

} {
  upvar $element_reference element

  array set attributes \
      [::template::widget::merge_tag_attributes element $tag_attributes]

  if { [info exists element(value)] } {
      set storage_type [template::util::richtext_or_file::get_property storage_type $element(value)]
      set mime_type    [template::util::richtext_or_file::get_property mime_type $element(value)]
      set text         [template::util::richtext_or_file::get_property text $element(value)]
      set filename     [template::util::richtext_or_file::get_property filename $element(value)]
      set tmp_filename [template::util::richtext_or_file::get_property tmp_filename $element(value)]
      set content_url  [template::util::richtext_or_file::get_property content_url $element(value)]
  } else {
      set storage_type {}
      set mime_type    {}
      set text         {}
      set filename     {}
      set tmp_filename {}
      set content_url  {}
  }

  set output {}

  if {$element(mode) eq "edit"} {
      if { $storage_type eq "" } {
          append output [subst {
              <input type="radio" name="$element(id).storage_type" id="$element(id).storage_type_text" value="text"
                checked>
              <label for="$element(id).storage_type_text">Enter text</label><blockquote>
          }]
          template::add_event_listener \
              -id "$element(id).storage_type_file" \
              -script [subst {acs_RichText_Or_File_InputMethodChanged('$element(form_id)', '$element(id)', this);}]

      } else {
          append output [subst {
              <input type="hidden" name="$element(id).storage_type" value="[ns_quotehtml $storage_type]">
          }]
      }

      ::template::head::add_javascript -src /resources/acs-templating/richtext-or-file.js

      if { $storage_type eq "" || $storage_type eq "text" } {
          append output [subst {<script type="text/javascript" nonce='[security::csp::nonce]'><!--}] \
              \n {acs_RichText_WriteButtons();  //--></script>} \
              [textarea_internal "$element(id).text" attributes $text] \
              [subst {<br>Format: \
                          [menu "$element(id).mime_type" \
                               [template::util::richtext_or_file::format_options] \
                               $mime_type \
                               attributes]}]
      }

      if { $storage_type eq "" } {
          append output [subst {
              </blockquote>
              <input type="radio" name="$element(id).storage_type" id="$element(id).storage_type_file" value="file">
              <label for="$element(id).storage_type_file">Upload a file</label>
              <blockquote>
          }]
          template::add_event_listener \
              -id "$element(id).storage_type_file" \
              -script [subst {acs_RichText_Or_File_InputMethodChanged('$element(form_id)', '$element(id)', this);}]

      }

      if {$storage_type eq "file"} {
          append output \
              [template::util::richtext_or_file::get_property html_value $element(value)] \
              "<p>Replace uploaded file: " \
              [subst {<input type="file" name="$element(id).file">}]
      }
      if { $storage_type eq "" } {
          append output [subst {<input type="file" name="$element(id).file" disabled>}]
      }

      if { $storage_type eq "" } {
          append output "</blockquote>"
      }
  } else {
      # Display mode
      if { [info exists element(value)] } {
          append output [template::util::richtext_or_file::get_property html_value $element(value)]
          append output "<input type=\"hidden\" name=\"$element(id).mime_type\" value=\"[ns_quotehtml $mime_type]\">"
          append output "<input type=\"hidden\" name=\"$element(id).storage_type\" value=\"[ns_quotehtml $storage_type]\">"
          append output "<input type=\"hidden\" name=\"$element(id).text\" value=\"[ns_quotehtml $text]\">"
      }
  }

  return $output
}

# Local variables:
#    mode: tcl
#    tcl-indent-level: 4
#    indent-tabs-mode: nil
# End: