a5b512a7a022c72d644b843b88f8d0e6c990a5cf
braney
  Fri Aug 11 14:49:58 2017 -0700
move to jstree, first pass at Cath's spec

diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c
index 30e02ba..63992af 100644
--- src/hg/hgCollection/hgCollection.c
+++ src/hg/hgCollection/hgCollection.c
@@ -91,57 +91,60 @@
         hashStore(nameHash, buffer);
         return cloneString(buffer);
         }
     }
 
 return NULL;
 }
 
 static boolean trackCanBeAdded(struct trackDb *tdb)
 // are we allowing this track into a custom composite
 {
 return  (tdb->subtracks == NULL) && !startsWith("wigMaf",tdb->type) &&  (startsWith("wig",tdb->type) || startsWith("bigWig",tdb->type)) ;
 }
 
 static void printGroup(char *parent, struct trackDb *tdb, boolean folder, boolean user)
-// output the table rows for a group
+// output list elements for a group
 {
 char *userString = "";
 char *prefix = "";
 
-if (user)
+//if (user)
     {
-    prefix = "coll_";
+    //prefix = "coll_";
     if (tdb->parent && tdb->subtracks) 
-        userString = "class='user view'";
+        userString = "viewType='view'";
     else
-        userString = "class='user'";
+        userString = "viewType='track'";
     }
     
 #define IMAKECOLOR_32(r,g,b) ( ((unsigned int)b<<0) | ((unsigned int)g << 8) | ((unsigned int)r << 16))
 
-jsInlineF("<tr color='#%06x' visibility='%s'  data-tt-parent-id='%s%s' data-tt-id='%s%s' %s><td><span class='%s'>%s</span></td>",  IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), hStringFromTv(tdb->visibility), prefix, parent,prefix,  trackHubSkipHubName(tdb->track),   userString, folder ? "folder" : "file", tdb->shortLabel );
-jsInlineF("<td>%s</td></tr>", tdb->longLabel);
+jsInlineF("<li shortLabel='%s' longLabel='%s' color='#%06x' visibility='%s'  name='%s%s' %s><span class='%s'>%s</span>",  tdb->shortLabel, tdb->longLabel,IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), hStringFromTv(tdb->visibility), prefix,  trackHubSkipHubName(tdb->track),   userString, folder ? "folder" : "file", tdb->shortLabel );
+jsInlineF("%s", tdb->longLabel);
 
 
 if (tdb->subtracks)
     {
     struct trackDb *subTdb;
 
+    jsInlineF("<ul>");
     for(subTdb = tdb->subtracks; subTdb; subTdb = subTdb->next)
         printGroup(trackHubSkipHubName(tdb->track), subTdb, user && (subTdb->subtracks != NULL), user);
+    jsInlineF("</ul>");
     }
+jsInlineF("</li>");
 }
 
 static void outHubHeader(FILE *f, char *db, char *hubName)
 // output a track hub header
 {
 char *hubFile = strrchr(hubName, '/') + 1;
 
 fprintf(f,"hub hub1\n\
 shortLabel User Composite\n\
 longLabel User Composite\n\
 genomesFile %s\n\
 email braney@soe.ucsc.edu\n\
 descriptionUrl hub.html\n\n", hubFile);
 fprintf(f,"genome %s\n\
 trackDb %s\n\n", db, hubFile);  
@@ -216,76 +219,84 @@
 boolean vis;
 if (cartVis != NULL) 
     vis =  differentString(cartVis, "hide");
 else if (tdbIsSuperTrack(tdb->parent))
     vis = tdb->parent->isShow;
 else
     vis = tdb->parent->visibility != tvHide;
 
 return vis;
 }
 
 
 void addVisibleTracks()
 // add the visible tracks table rows
 {
-printf("<tr data-tt-id='visible' ><td><span class='file'>All Visible</td><td>All the tracks visible in hgTracks</td></tr>\n");
+printf("<tr name='visible' ><td><span class='file'>All Visible</td><td>All the tracks visible in hgTracks</td></tr>\n");
 struct trackDb *tdb;
 for(tdb = fullTrackList; tdb; tdb = tdb->next)
     {
     if (isParentVisible(tdb) &&  isSubtrackVisible(tdb))
         {
         printGroup("visible", tdb, FALSE, FALSE);
         }
     }
 }
 
 void doTable()
 // output the tree table
 {
 char *hubName = hubNameFromUrl(getHubName(database));
-jsInlineF("$('#tracks tr:last').after(\"");
+jsInlineF("$('#tracks').append(\"");
 struct grp *curGroup;
 for(curGroup = fullGroupList; curGroup;  curGroup = curGroup->next)
     {
     if ((hubName != NULL) && sameString(curGroup->name, hubName))
         break;
     }
 if (curGroup != NULL)
     {
     // print out all the tracks in this group
     struct trackDb *tdb;
+    jsInlineF("<ul>");
     for(tdb = fullTrackList; tdb;  tdb = tdb->next)
         {
         if (sameString(tdb->grp, hubName))
             printGroup("collections", tdb, TRUE, TRUE);
         }
+    jsInlineF("</ul>");
     }
 //addVisibleTracks();
 for(curGroup = fullGroupList; curGroup;  curGroup = curGroup->next)
     {
     if ((hubName != NULL) && sameString(curGroup->name, hubName))
         continue;
-    jsInlineF("<tr data-tt-id='%s'><td><span class='file'>%s</span></td><td></td></tr>", curGroup->name, curGroup->label );
+    jsInlineF("<ul>");
+    jsInlineF("<li name='%s'><span class='file'>%s</span>", curGroup->name, curGroup->label );
     struct trackDb *tdb;
+    jsInlineF("<ul>");
     for(tdb = fullTrackList; tdb;  tdb = tdb->next)
         {
         if ( sameString(tdb->grp, curGroup->name))
             {
             printGroup(curGroup->name, tdb, FALSE, FALSE);
             }
         }
+    jsInlineF("</ul>");
+    jsInlineF("</li>");
+    jsInlineF("</ul>");
+
     }
 jsInlineF("\");\n");
 jsInlineF("collections.init();\n");
 }
 
 static void onclickJumpToTop(char *id)
 /* CSP-safe click handler arrows that cause scroll to top */
 {
 jsOnEventById("click", id, "$('html,body').scrollTop(0);");
 }
 
 static void printHelp()
 // print out the help page
 {
 puts(
@@ -312,45 +323,44 @@
 puts("</div>");
 webIncludeHelpFileSubst("hgCompositeHelp", NULL, FALSE);
 
 puts("<div class='dataInfo'>");
 puts("</div>");
 
 puts(
 "     </div>\n"
 "   </div>\n");
 }
 
 void doMainPage()
 /* Print out initial HTML of control page. */
 {
 webStartGbNoBanner(cart, database, "Collections");
-webIncludeResourceFile("jquery.treetable.css");
-webIncludeResourceFile("jquery.treetable.theme.default.css");
 webIncludeResourceFile("gb.css");
-//webIncludeResourceFile("jWest.css");
 webIncludeResourceFile("spectrum.min.css");
 webIncludeResourceFile("hgGtexTrackSettings.css");
 
 webIncludeFile("inc/hgCollection.html");
 
 printHelp();
 doTable();
 
-puts("<script src=\"//code.jquery.com/jquery-1.9.1.min.js\"></script>");
+puts("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css' />");
+puts("<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js'></script>");
+//puts("<script src=\"//code.jquery.com/jquery-1.12.1.min.js\"></script>");
 puts("<script src=\"//code.jquery.com/ui/1.10.3/jquery-ui.min.js\"></script>");
-jsIncludeFile("jquery.treetable.js", NULL);
+puts("<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.4/jstree.min.js\"></script>\n");
 jsIncludeFile("utils.js", NULL);
 jsIncludeFile("ajax.js", NULL);
 jsIncludeFile("spectrum.min.js", NULL);
 jsIncludeFile("hgCollection.js", NULL);
 webEndGb();
 }
 
 static char *getSqlBigWig(struct sqlConnection *conn, char *db, struct trackDb *tdb)
 // figure out the bigWig for native tables
 {
 char buffer[4096];
 
 safef(buffer, sizeof buffer, "NOSQLINJ select fileName from %s", tdb->table);
 return sqlQuickString(conn, buffer);
 }
@@ -502,31 +512,31 @@
 }
 
 static unsigned long hexStringToLong(char *str)
 {
 /*
 char buffer[1024];
 
 strcpy(buffer, "0x");
 strcat(buffer, &str[1]);
 */
 
 return strtol(&str[1], NULL, 16);
 }
 
 static struct track *parseJson(char *jsonText)
-// parse the JSON of the treetable from the Javascript
+// parse the JSON returned from the ap
 {
 struct hash *trackHash = newHash(5);
 struct track *collectionList = NULL;
 struct track *track;
 char *ptr = jsonText;
 if (*ptr != '[')
     errAbort("element didn't start with [");
 ptr++;
 
 do
     {
     if (*ptr != '[')
         errAbort("element didn't start with [");
     ptr++;