From a1dee2b998bc3dc8436bb076435d405ec412e054 Mon Sep 17 00:00:00 2001
From: Adrian Lang <mail@adrianlang.de>
Date: Mon, 11 Jul 2011 22:17:27 +0200
Subject: [PATCH] Fix some bugs and glitches in (mediamanager) tree

  * Fix selector in subtree loading callback
  * Remove HTML inconsistencies between AJAX and plain PHP lists
  * Unify icon and CSS class switching in dw_tree and dw_mediamanager
---
 inc/html.php              | 16 +++++++++++++---
 inc/media.php             |  9 ++-------
 lib/exe/ajax.php          | 18 ++++++------------
 lib/plugins/acl/admin.php | 11 ++---------
 lib/plugins/acl/ajax.php  | 11 ++++-------
 lib/scripts/media.js      |  9 ++++-----
 lib/scripts/tree.js       | 28 +++++++++++++++-------------
 7 files changed, 46 insertions(+), 56 deletions(-)

diff --git a/inc/html.php b/inc/html.php
index 6e187ebe1..de860a0fe 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -737,7 +737,7 @@ function html_list_index($item){
 /**
  * Index List item
  *
- * This user function is used in html_build_lidt to build the
+ * This user function is used in html_buildlist to build the
  * <li> tags for namespaces when displaying the page index
  * it gives different classes to opened or closed "folders"
  *
@@ -778,10 +778,20 @@ function html_li_default($item){
  * @author Andreas Gohr <andi@splitbrain.org>
  */
 function html_buildlist($data,$class,$func,$lifunc='html_li_default'){
-    $level = 0;
+    if (count($data) === 0) {
+        return '';
+    }
+
+    $level = $data[0]['level'];
     $opens = 0;
     $ret   = '';
 
+    if ($level < 2) {
+        // Trigger building a wrapper ul if the first level is
+        // 0 (we have a root object) or 1 (just the root content)
+        --$level;
+    }
+
     foreach ($data as $item){
 
         if( $item['level'] > $level ){
@@ -797,7 +807,7 @@ function html_buildlist($data,$class,$func,$lifunc='html_li_default'){
                 //close higher lists
                 $ret .= "</ul>\n</li>\n";
             }
-        }else{
+        } elseif ($ret !== '') {
             //close last item
             $ret .= "</li>\n";
         }
diff --git a/inc/media.php b/inc/media.php
index 10da501b0..731ba1668 100644
--- a/inc/media.php
+++ b/inc/media.php
@@ -767,15 +767,10 @@ function media_nstree($ns){
     search($data,$conf['mediadir'],'search_index',array('ns' => $ns, 'nofiles' => true));
 
     // wrap a list with the root level around the other namespaces
-    $item = array( 'level' => 0, 'id' => '',
-            'open' =>'true', 'label' => '['.$lang['mediaroot'].']');
+    array_unshift($data, array('level' => 0, 'id' => '', 'open' =>'true',
+                               'label' => '['.$lang['mediaroot'].']'));
 
-    echo '<ul class="idx">';
-    echo media_nstree_li($item);
-    echo media_nstree_item($item);
     echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li');
-    echo '</li>';
-    echo '</ul>';
 }
 
 /**
diff --git a/lib/exe/ajax.php b/lib/exe/ajax.php
index 1056a05f8..2bfa3680c 100644
--- a/lib/exe/ajax.php
+++ b/lib/exe/ajax.php
@@ -192,12 +192,10 @@ function ajax_medians(){
 
     $data = array();
     search($data,$conf['mediadir'],'search_index',array('nofiles' => true),$dir);
-    foreach($data as $item){
-        $item['level'] = $lvl+1;
-        echo media_nstree_li($item);
-        echo media_nstree_item($item);
-        echo '</li>';
+    foreach(array_keys($data) as $item){
+        $data[$item]['level'] = $lvl+1;
     }
+    echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li');
 }
 
 /**
@@ -229,14 +227,10 @@ function ajax_index(){
 
     $data = array();
     search($data,$conf['datadir'],'search_index',array('ns' => $ns),$dir);
-    foreach($data as $item){
-        $item['level'] = $lvl+1;
-        echo html_li_index($item);
-        echo '<div class="li">';
-        echo html_list_index($item);
-        echo '</div>';
-        echo '</li>';
+    foreach(array_keys($data) as $item){
+        $data[$item]['level'] = $lvl+1;
     }
+    echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index');
 }
 
 /**
diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php
index ea4184ca3..7c12b3374 100644
--- a/lib/plugins/acl/admin.php
+++ b/lib/plugins/acl/admin.php
@@ -253,19 +253,12 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin {
         $data = $this->_get_tree($ns);
 
         // wrap a list with the root level around the other namespaces
-        $item = array( 'level' => 0, 'id' => '*', 'type' => 'd',
-                   'open' =>'true', 'label' => '['.$lang['mediaroot'].']');
+        array_unshift($data, array( 'level' => 0, 'id' => '*', 'type' => 'd',
+                   'open' =>'true', 'label' => '['.$lang['mediaroot'].']'));
 
-        echo '<ul class="acltree">';
-        echo $this->_html_li_acl($item);
-        echo '<div class="li">';
-        echo $this->_html_list_acl($item);
-        echo '</div>';
         echo html_buildlist($data,'acl',
                             array($this,'_html_list_acl'),
                             array($this,'_html_li_acl'));
-        echo '</li>';
-        echo '</ul>';
 
     }
 
diff --git a/lib/plugins/acl/ajax.php b/lib/plugins/acl/ajax.php
index d91586a5d..d704fa8c9 100644
--- a/lib/plugins/acl/ajax.php
+++ b/lib/plugins/acl/ajax.php
@@ -44,13 +44,10 @@ if($ajax == 'info'){
 
     $data = $acl->_get_tree($ns,$ns);
 
-    foreach($data as $item){
-        $item['level'] = $lvl+1;
-        echo $acl->_html_li_acl($item);
-        echo '<div class="li">';
-        echo $acl->_html_list_acl($item);
-        echo '</div>';
-        echo '</li>';
+    foreach(array_keys($data) as $item){
+        $data[$item]['level'] = $lvl+1;
     }
+    echo html_buildlist($data, 'acl', array($acl, '_html_list_acl'),
+                        array($acl, '_html_li_acl'));
 }
 
diff --git a/lib/scripts/media.js b/lib/scripts/media.js
index 695fbd807..b9dacfa29 100644
--- a/lib/scripts/media.js
+++ b/lib/scripts/media.js
@@ -43,7 +43,7 @@ var dw_mediamanager = {
         $tree.dw_tree({toggle_selector: 'img',
                        load_data: function (show_sublist, $clicky) {
                            // get the enclosed link (is always the first one)
-                           var $link = $clicky.siblings('a').first();
+                           var $link = $clicky.parent().find('div.li a.idx_dir');
 
                            jQuery.post(
                                DOKU_BASE + 'lib/exe/ajax.php',
@@ -51,13 +51,12 @@ var dw_mediamanager = {
                                show_sublist,
                                'html'
                            );
-
-                           $clicky.attr('src', DOKU_BASE + 'lib/images/minus.gif');
                        },
 
-                       close: function ($clicky) {
+                       toggle_display: function ($clicky, opening) {
                            $clicky.attr('src',
-                                        DOKU_BASE + 'lib/images/plus.gif');
+                                        DOKU_BASE + 'lib/images/' +
+                                        (opening ? 'minus' : 'plus') + '.gif');
                        }});
         $tree.delegate('a', 'click', dw_mediamanager.list);
     },
diff --git a/lib/scripts/tree.js b/lib/scripts/tree.js
index 46b0f6695..98d3f55d4 100644
--- a/lib/scripts/tree.js
+++ b/lib/scripts/tree.js
@@ -29,33 +29,34 @@ jQuery.fn.dw_tree = function(overrides) {
          * @author Pierre Spring <pierre.spring@caillou.ch>
          */
         toggle: function (e) {
-            var $listitem, $sublist, timeout, $clicky, show_sublist, dw_tree;
+            var $listitem, $sublist, timeout, $clicky, show_sublist, dw_tree, opening;
 
             e.preventDefault();
 
+            dw_tree = e.data;
             $clicky = jQuery(this);
             $listitem = $clicky.closest('li');
             $sublist = $listitem.find('ul').first();
-            dw_tree = e.data;
+            opening = $listitem.hasClass('closed');
+            $listitem.toggleClass('open closed');
+            dw_tree.toggle_display($clicky, opening);
 
             // if already open, close by hiding the sublist
-            if ($listitem.hasClass('open')) {
-                $sublist.dw_hide(function () {
-                    dw_tree.close($clicky);
-                    $listitem.addClass('closed').removeClass('open');
-                });
+            if (!opening) {
+                $sublist.dw_hide();
                 return;
             }
 
             show_sublist = function (data) {
-                if (!$listitem.hasClass('open') || $sublist.parent().length === 0) {
-                    $listitem.append($sublist).addClass('open').removeClass('closed');
-                }
                 $sublist.hide();
-                if (data) {
+                if (typeof data !== 'undefined') {
                     $sublist.html(data);
                 }
-                $sublist.dw_show();
+                if ($listitem.hasClass('open')) {
+                    // Only show if user didn’t close the list since starting
+                    // to load the content
+                    $sublist.dw_show();
+                }
             };
 
             // just show if already loaded
@@ -66,6 +67,7 @@ jQuery.fn.dw_tree = function(overrides) {
 
             //prepare the new ul
             $sublist = jQuery('<ul class="idx"/>');
+            $listitem.append($sublist);
 
             timeout = window.setTimeout(
                 bind(show_sublist, '<li><img src="' + DOKU_BASE + 'lib/images/throbber.gif" alt="loading..." title="loading..." /></li>'), dw_tree.throbber_delay);
@@ -76,7 +78,7 @@ jQuery.fn.dw_tree = function(overrides) {
                               }, $clicky);
         },
 
-        close: function ($clicky) {
+        toggle_display: function ($clicky, opening) {
         },
 
         load_data: function (show_data, $clicky) {
-- 
GitLab