Class ::xowiki::includelet::toc (public)

 ::xowiki::IncludeletClass ::xowiki::includelet::toc[i]

Defined in

Testcases:
No testcase defined.
Source code:
namespace eval ::xowiki::includelet {}
::nsf::object::alloc ::xowiki::IncludeletClass ::xowiki::includelet::toc {set :__default_metaclass ::xotcl::Class
   set :__default_superclass ::xotcl::Object
   set :aggregating true
   set :cacheable false
   set :localized true
   set :personalized false}
::xowiki::includelet::toc proc anchor name {
    # try to strip the language prefix from the name
    regexp {^.*:([^:]+)$} $name _ name
    # anchor is used between single quotes
    regsub -all ' $name {\'} anchor
    return $anchor
  }
::xowiki::includelet::toc instproc render_yui_list {{-full false} pages} {
    :get_parameters

    #
    # Render the tree with the yui widget (with or without ajax)
    #
    if {$book_mode} {
      #:log "--warn: cannot use bookmode with ajax, resetting ajax"
      set ajax 0
    }
    set :ajax $ajax

    if {$ajax} {
      set :js [:yui_ajax]
    } else {
      set :js [:yui_non_ajax]
    }

    set tree [::xowiki::Tree new -id [:id] -destroy_on_cleanup]
    $tree array set open_node [array get :open_node]
    $tree add_pages -full $full -remove_levels $remove_levels  -book_mode $book_mode -open_page $open_page -expand_all $expand_all  -owner [self]  $pages

    set HTML [$tree render -style yuitree -js ${:js}]
    return $HTML
  }
::xowiki::includelet::toc instproc count {} {return [set :navigation(count)]}
::xowiki::includelet::toc instproc yui_non_ajax {} {
    return "
      var [:js_name];
      YAHOO.util.Event.onDOMReady(function() {
         [:js_name] = new YAHOO.widget.TreeView('[:id]');
         [:js_name].subscribe('clickEvent',function(oArgs) {
            //console.info(oArgs);
            var m = /href=\"(\[^\"\]+)\"/.exec(oArgs.node.html);
            //console.info(m\[1\]);
            //window.location.href = m\[1\];
            return false;
    });
        [:js_name].render();
      });
     "
  }
::xowiki::includelet::toc instproc position {} {return [set :navigation(position)]}
::xowiki::includelet::toc instproc page_name p {return [set :page_name($p)]}
::xowiki::includelet::toc instproc cache_includelet_data key {
    append data  [list :array set navigation [array get :navigation]] \n  [list :array set page_name [array get :page_name]] \n
    return $data
  }
::xowiki::includelet::toc instproc page_number {page_order remove_levels} {
    #: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
  }
::xowiki::includelet::toc instproc include_head_entries {} {
    switch -- ${:renderer} {
      yuitree {
        ::xowiki::Tree include_head_entries -renderer yuitree -style ${:style}
      }
      list    {
        :get_parameters
        set tree_renderer [expr {$allow_reorder eq "" ? "list" : "listdnd"}]
        ::xowiki::Tree include_head_entries -renderer $tree_renderer -style ${:style}
      }
      none {}
    }
  }
::xowiki::includelet::toc instproc build_navigation pages {
    #
    # compute associative arrays open_node and navigation (position
    # and current)
    #
    :get_parameters
    array set :navigation {position 0 current ""}

    # the top node is always open
    set :open_node() true
    set node_cnt 0
    foreach o [$pages children] {
      $o instvar page_order name
      incr node_cnt
      set :page_name($node_cnt$name
      if {![regexp {^(.*)[.]([^.]+)} $page_order _ parent]} {set parent ""}
      #
      # If we are on the provided $open_page, we remember our position
      # for the progress bar.
      set on_current_node [expr {$open_page eq $name} ? "true" : "false"]
      if {$on_current_node} {
        set :navigation(position) $node_cnt
        set :navigation(current) $page_order
      }
      if {$expand_all} {
        set :open_node($page_order) true
      } elseif {$on_current_node} {
        set :open_node($page_order) true
        # make sure to open all nodes to the root
        for {set p $parent} {$p ne ""} {} {
          set :open_node($p) true
          if {![regexp {^(.*)[.]([^.]+)} $p _ p]} {set p ""}
        }
      }
    }
    set :navigation(count) $node_cnt
    #:log OPEN=[lsort [array names :open_node]]
  }
::xowiki::includelet::toc instproc render {} {
    :get_parameters

    if {![info exists :id]} {
      set :id [::xowiki::Includelet html_id [self]]
    }
    if {[info exists category_id]} {
      set :category_id $category_id
    }

    #
    # Collect the pages which are either children of the page, or
    # children of the parent of the page depending on "folder_mode".
    #
    set pages [:build_toc $package_id $locale $source $range]

    #foreach p [$pages children] {
    #  ns_log notice "... [$p set page_order] [$p set name]"
    #}

    #
    # Build the general navigation structure using associative arrays
    #
    :build_navigation $pages
    #
    # Call a render on the created structure
    #
    if {[nsf::is object ::__xowiki__MenuBar] && ${:include_in_foldertree}} {
      ::__xowiki__MenuBar additional_sub_menu -kind folder -pages $pages -owner [self]
    }
    #
    # TODO: We should call here the appropriate tree-renderer instead
    # of the toc-specific renderers, but first we have to check, if
    # these are fully feature-compatible.
    #
    #:log "=== toc render with <${:renderer}> treerenderer ${:use_tree_renderer} list_mode <${:list_mode}>"
    if {${:renderer} eq "none"} {
    } elseif {${:use_tree_renderer}} {
      return [:render_tree -full 1 $pages]
    } elseif {${:list_mode}} {
      return [:render_list $pages]
    } else {
      return [:render_yui_list -full true $pages]
    }
  }
::xowiki::includelet::toc instproc initialize {} {
    :get_parameters
    array set :navigation {count 0 position 0 current ""}
    set list_mode 0
    dict set :render_properties CSSclass_ul $CSSclass_ul
    dict set :render_properties CSSclass_top_ul $CSSclass_top_ul

    #
    # If there is no renderer specified, determine the renderer from
    # the (provided) style. When the render is explicitly specified,
    # use it for rendering.
    #
    if {$renderer eq ""} {
      switch -- $style {
        "menu"    {set renderer yuitree}
        "folders" {set renderer yuitree}
        "yuitree" {set renderer "yuitree"}
        "list"    {set style ""set list_mode 1; set renderer list}
        "none"    {set style ""set renderer none}
        "default" {set style ""set list_mode 1; set renderer list
          #
          # Fall back to "xowiki-tree" for "CSSclass_ul" only when
          # value was not specified as a parameter.
          #
          if {$CSSclass_ul eq ""} {
            dict set :render_properties CSSclass_ul xowiki-tree
          }
        }
      }
      set :use_tree_renderer 0
    } else {
      set :use_tree_renderer 1
    }

    set :include_in_foldertree $include_in_foldertree
    set :renderer $renderer
    set :style $style
    set :list_mode $list_mode
    set :book_mode $book_mode
  }
::xowiki::includelet::toc instproc yui_ajax {} {
    return "var [:js_name] = {

         count: [set :navigation(count)],

         getPage: function(href, c) {
             //console.log('getPage: ' + href + ' type: ' + typeof href) ;

             if ( typeof c == 'undefined' ) {

                 // no c given, search it from the objects
                 // console.log('search for href <' + href + '>');

                 for (i in this.objs) {
                     if (this.objs\[i\].ref == href) {
                        c = this.objs\[i\].c;
                        // console.log('found href ' + href + ' c=' + c);
                        var node = this.tree.getNodeByIndex(c);
                        if (!node.expanded) {node.expand();}
                        node = node.parent;
                        while (node.index > 1) {
                            if (!node.expanded) {node.expand();}
                            node = node.parent;
                        }
                        break;
                     }
                 }
                 if (typeof c == 'undefined') {
                     // console.warn('c undefined');
                     return false;
                 }
             }
             //console.log('have href ' + href + ' c=' + c);

             var transaction = YAHOO.util.Connect.asyncRequest('GET',  href + '?template_file=view-page&return_url=' + encodeURI(href),
                {
                  success:function(o) {
                     var bookpage = document.getElementById('book-page');
                  var fadeOutAnim = new YAHOO.util.Anim(bookpage, { opacity: {to: 0} }, 0.5 );

                     var doFadeIn = function(type, args) {
                        // console.log('fadein starts');
                        var bookpage = document.getElementById('book-page');
                        bookpage.innerHTML = o.responseText;
                        var fadeInAnim = new YAHOO.util.Anim(bookpage, { opacity: {to: 1} }, 0.1 );
                        fadeInAnim.animate();
                     }

                     // console.log(' tree: ' + this.tree + ' count: ' + this.count);
                     // console.info(this);

                     if (this.count > 0) {
                        var percent = (100 * o.argument.count / this.count).toFixed(2) + '%';
                     } else {
                        var percent = '0.00%';
                     }

                     if (o.argument.count > 1) {
                        var link = o.argument.href;
                        var src = '/resources/xowiki/previous.png';
                        var onclick = 'return [:js_name].getPage(\"' + link + '\");' ;
                     } else {
                        var link = '#';
                        var onclick = '';
                        var src = '/resources/xowiki/previous-end.png';
                     }

                     // console.log('changing prev href to ' + link);
                     // console.log('changing prev onclick to ' + onclick);

                     document.getElementById('bookNavPrev.img').src = src;
                     document.getElementById('bookNavPrev.a').href = link;
                     document.getElementById('bookNavPrev.a').setAttribute('onclick',onclick);

                     if (o.argument.count < this.count) {
                        var link = o.argument.href;
                        var src = '/resources/xowiki/next.png';
                        var onclick = 'return [:js_name].getPage(\"' + link + '\");' ;
                     } else {
                        var link = '#';
                        var onclick = '';
                        var src = '/resources/xowiki/next-end.png';
                     }

                     // console.log('changing next href to ' + link);
                     // console.log('changing next onclick to ' + onclick);
                     document.getElementById('bookNavNext.img').src = src;
                     document.getElementById('bookNavNext.a').href = link;

                     document.getElementById('bookNavNext.a').setAttribute('onclick',onclick);
                     document.getElementById('bookNavRelPosText').innerHTML = percent;
                     //document.getElementById('bookNavBar').setAttribute('style', 'width: ' + percent + ';');
                     document.getElementById('bookNavBar').style.width = percent;

                     fadeOutAnim.onComplete.subscribe(doFadeIn);
               fadeOutAnim.animate();
                  },
                  failure:function(o) {
                     // console.error(o);
                     // alert('failure ');
                     return false;
                  },
                  argument: {count: c, href: href},
                  scope: [:js_name]
                }, null);

                return false;
            },

         treeInit: function() {
            [:js_name].tree = new YAHOO.widget.TreeView('[:id]');
            [:js_name].tree.subscribe('clickEvent', function(oArgs) {
              var m = /href=\"(\[^\"\]+)\"/.exec(oArgs.node.html);
              [:js_name].getPage( m\[1\], oArgs.node.index);
            });
            [:js_name].tree.draw();
         }

      };

     YAHOO.util.Event.addListener(window, 'load', [:js_name].treeInit);
"
  }
::xowiki::includelet::toc instproc current {} {return [set :navigation(current)]}
::xowiki::includelet::toc instproc render_list {{-full false} pages} {
    :get_parameters

    #
    # Build a reduced toc tree based on pure HTML (no JavaScript or
    # AJAX involved).  If an open_page is specified, produce an as
    # small as possible tree and omit all non-visible nodes.
    #
    if {$open_page ne ""} {
      # TODO: can we allow open_page and reorder?
      set allow_reorder ""
    } else {
      set allow_reorder [:page_reorder_check_allow -with_head_entries false $allow_reorder]
    }
    set tree [::xowiki::Tree new -id [:id] -destroy_on_cleanup]
    $tree array set open_node [array get :open_node]
    $tree add_pages -full $full  -remove_levels $remove_levels  -book_mode $book_mode -open_page $open_page -expand_all $expand_all  -owner [self]  -properties ${:render_properties}  $pages

    if {$allow_reorder ne ""} {
      :page_reorder_init_vars -allow_reorder $allow_reorder js last_level ID min_level
      #set js "\nYAHOO.xo_page_order_region.DDApp.package_url = '[::$package_id package_url]';"
      set HTML [$tree render -style listdnd -context [list min_level $min_level]]
    } else {
      set HTML [$tree render -style list -properties ${:render_properties}]
    }

    return $HTML
  }
::xowiki::includelet::toc instproc href {book_mode name} {
    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
  }
::xowiki::includelet::toc instproc build_toc {package_id locale source range} {
    :get_parameters
    array set :navigation {parent "" position 0 current ""}

    set extra_where_clause ""
    if {[info exists :category_id]} {
      lassign [:category_clause ${:category_id}] cnames extra_where_clause
    }
    lassign [::xowiki::Includelet locale_clause -revisions p -items p $package_id $locale]  locale locale_clause
    #:msg locale_clause=$locale_clause
    set order_direction asc
    set order_attribute page_order

    if {$source ne ""} {
      :get_page_order -source $source
      set page_order_clause "and name in ([ns_dbquotelist [array names :page_order]])"
      set page_order_att ""
    } elseif {$orderby ne ""} {
      lassign [split $orderby ,] order_attribute order_direction
      if {$order_attribute ni {page_order title}} {
        ns_log warning "toc includelet: ignore invalid page order '$orderby'"
        set order_attribute page_order
        set order_direction asc
        set page_order_att "page_order,"
        set page_order_clause "and not page_order is NULL"
      } else {
        set page_order_att "page_order,"
        set page_order_clause ""
        append extra_where_clause " and page_id != [${:__including_page} revision_id]"
      }
    } else {
      set page_order_clause "and not page_order is NULL"
      set page_order_att "page_order,"
    }

    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 sql [::xo::dc select  -vars "page_id, $page_order_att name, title"  -from "xowiki_page_live_revision p"  -where "parent_id = :parent_id  $page_order_clause  $extra_where_clause $locale_clause"]
    set pages [::xowiki::Page instantiate_objects -sql $sql]

    #
    # Set the mixin for page-order before the call of __value_compare.
    # Probably, we should use here a different approach to support as well
    # sorting by different attributes.
    #
    $pages orderby  -order [expr {$order_direction in {asc ""} ? "increasing" : "decreasing"}]  -type [ad_decode $order_attribute page_order index dictionary]  $order_attribute

    if {$range ne "" && $page_order_att ne ""} {
      lassign [split $range -] from to
      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 {$source ne ""} {
      # add the page_order to the objects
      foreach p [$pages children] {
        $p set page_order [set :page_order([$p set name])]
      }
    }

    return $pages
  }
::xowiki::includelet::toc instproc parent_id {} {
    ${:__including_page} parent_id
  }
::xowiki::includelet::toc instproc render_tree {{-full false} pages} {
    :get_parameters
    set tree [::xowiki::Tree new  -id [:id]  -verbose 0  -owner [self]  -destroy_on_cleanup]
    $tree array set open_node [array get :open_node]
    $tree add_pages -full $full -remove_levels $remove_levels  -book_mode $book_mode -open_page $open_page  -owner [self]  $pages

    if {$allow_reorder ne ""} {
      set allow_reorder [:page_reorder_check_allow -with_head_entries false $allow_reorder]
    }

    if {$allow_reorder ne ""} {
      :page_reorder_init_vars -allow_reorder $allow_reorder js last_level ID min_level
      #:log "=== call tree render [list $tree render -style listdnd] min_level=$min_level"
      set HTML [$tree render -style listdnd -context [list min_level $min_level]]
    } else {
      set HTML [$tree render -style list]
    }
    #:log "render_tree HTML  => $HTML"
    return $HTML
  }
::xowiki::includelet::toc instparametercmd id
::xowiki::includelet::toc instparametercmd __decoration
::xowiki::includelet::toc instparametercmd parameter_declaration
::nsf::relation::set ::xowiki::includelet::toc superclass ::xowiki::Includelet
::nsf::relation::set ::xowiki::includelet::toc class-mixin ::xowiki::includelet::PageReorderSupport

::nx::slotObj -container slot ::xowiki::includelet::toc
::xowiki::includelet::toc::slot eval {set :__parameter {
        {__decoration plain}
        {parameter_declaration {
          {-style ""}
          {-renderer ""}
          {-open_page ""}
          {-book_mode false}
          {-folder_mode false}
          {-ajax false}
          {-expand_all false}
          {-remove_levels 0}
          {-category_id}
          {-locale ""}
          {-orderby ""}
          {-source ""}
          {-range ""}
          {-allow_reorder ""}
          {-include_in_foldertree "true"}
          {-CSSclass_top_ul ""}
          {-CSSclass_ul ""}
        }}
        id
      }}

::nsf::object::alloc ::xotcl::Attribute ::xowiki::includelet::toc::slot::id {set :accessor public
   set :configurable true
   set :convert false
   set :defaultmethods {}
   set :disposition alias
   set :domain ::xowiki::includelet::toc
   set :incremental 0
   set :manager ::xowiki::includelet::toc::slot::id
   set :methodname id
   set :multiplicity 1..1
   set :name id
   set :per-object false
   set :position 0
   set :required false
   set :trace none
   : init}

::nsf::object::alloc ::xotcl::Attribute ::xowiki::includelet::toc::slot::parameter_declaration {set :accessor public
   set :configurable true
   set :convert false
   set :default {
          {-style ""}
          {-renderer ""}
          {-open_page ""}
          {-book_mode false}
          {-folder_mode false}
          {-ajax false}
          {-expand_all false}
          {-remove_levels 0}
          {-category_id}
          {-locale ""}
          {-orderby ""}
          {-source ""}
          {-range ""}
          {-allow_reorder ""}
          {-include_in_foldertree "true"}
          {-CSSclass_top_ul ""}
          {-CSSclass_ul ""}
        }
   set :defaultmethods {}
   set :disposition alias
   set :domain ::xowiki::includelet::toc
   set :incremental 0
   set :manager ::xowiki::includelet::toc::slot::parameter_declaration
   set :methodname parameter_declaration
   set :multiplicity 1..1
   set :name parameter_declaration
   set :per-object false
   set :position 0
   set :required false
   set :substdefault 0b111
   set :trace none
   : init}

::nsf::object::alloc ::xotcl::Attribute ::xowiki::includelet::toc::slot::__decoration {set :accessor public
   set :configurable true
   set :convert false
   set :default plain
   set :defaultmethods {}
   set :disposition alias
   set :domain ::xowiki::includelet::toc
   set :incremental 0
   set :manager ::xowiki::includelet::toc::slot::__decoration
   set :methodname __decoration
   set :multiplicity 1..1
   set :name __decoration
   set :per-object false
   set :position 0
   set :required false
   set :substdefault 0b111
   set :trace none
   : init}
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: