9a24eab7aa53e82ca200d92f532411f37d8487f3
braney
Sat Feb 24 18:09:09 2018 -0800
add lazy loading to hgCollection, modify CSP policy to allow blob:
diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c
index 69f9167..a39a3bd 100644
--- src/hg/hgCollection/hgCollection.c
+++ src/hg/hgCollection/hgCollection.c
@@ -66,97 +66,45 @@
{
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) || startsWith("bedGraph",tdb->type)) ;
}
-static void printGroup(char *parent, struct trackDb *tdb, boolean folder, boolean user)
+static void printTrack(char *parent, struct trackDb *tdb, boolean user)
// output list elements for a group
{
char *userString = "";
-char *prefix = "";
-char *viewFunc = NULL;
-char *missingMethod = NULL;
-if (user)
- {
- if (tdb->parent && tdb->subtracks)
- {
- viewFunc = trackDbSetting(tdb, "viewFunc");
- missingMethod = trackDbSetting(tdb, "missingMethod");
- userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' viewType='view' class='folder'";
- }
- else if (tdb->subtracks)
- {
- viewFunc = trackDbSetting(tdb, "viewFunc");
- missingMethod = trackDbSetting(tdb, "missingMethod");
- userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' viewType='collection' class='folder'";
- }
- else
- userString = "data-jstree='{\\\"icon\\\":\\\"fa fa-minus-square\\\"}' class='track' viewType='track'";
- }
-else
- {
- if (tdb->parent && tdb->subtracks)
- userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' class='nodrop' viewType='view'";
- else if (tdb->subtracks)
- userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' class='collection' viewType='track'";
+if (tdb->subtracks)
+ userString = "icon:'../images/folderC.png',children:true,";
+else if (user)
+ userString = "icon:'fa fa-minus-square',";
else
- userString = "data-jstree='{\\\"icon\\\":\\\"fa fa-plus\\\"}' class='nodrop' viewType='track'";
- }
-
+ userString = "icon:'fa fa-plus',";
#define IMAKECOLOR_32(r,g,b) ( ((unsigned int)b<<0) | ((unsigned int)g << 8) | ((unsigned int)r << 16))
-char buffer[1024];
-char *viewFuncString = "";
-if (viewFunc != NULL)
- {
- safef(buffer, sizeof buffer, "viewFunc='%s' ", viewFunc);
- viewFuncString = cloneString(buffer);
- }
-
-char *missingString = "";
-if (missingMethod != NULL)
- {
- safef(buffer, sizeof buffer, "missingMethod='%s' ", missingMethod);
- missingString = cloneString(buffer);
- }
-
-jsInlineF("
%s", tdb->shortLabel, tdb->longLabel,IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), viewFuncString, missingString, hStringFromTv(tdb->visibility), prefix, trackHubSkipHubName(tdb->track), userString, tdb->shortLabel );
-jsInlineF(" (%s)", tdb->longLabel);
-
-
-if (tdb->subtracks)
- {
- struct trackDb *subTdb;
-
- jsInlineF("");
- for(subTdb = tdb->subtracks; subTdb; subTdb = subTdb->next)
- printGroup(trackHubSkipHubName(tdb->track), subTdb, user && (subTdb->subtracks != NULL), user);
- jsInlineF("
");
- }
-jsInlineF("");
+jsInlineF("{%s id:'%s',li_attr:{shortlabel:'%s', longlabel:'%s',color:'#%06x',name:'%s'},text:'%s (%s)',parent:'%s'}",userString, trackHubSkipHubName(tdb->track), tdb->shortLabel, tdb->longLabel, IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB),trackHubSkipHubName(tdb->track),tdb->shortLabel,tdb->longLabel,parent);
}
static void outHubHeader(FILE *f, char *db)
// output a track hub header
{
fprintf(f,"hub hub1\n\
shortLabel Track Collections\n\
longLabel Track Collections\n\
useOneFile on\n\
email genome-www@soe.ucsc.edu\n\n");
fprintf(f,"genome %s\n\n", db);
}
static char *getHubName(struct cart *cart, char *db)
@@ -258,121 +206,182 @@
isVisible = tdb->visibility != tvHide;
else
isVisible = differentString(cartVis, "hide");
}
else if (isParentVisible(cart, tdb) && isSubtrackVisible(cart, tdb))
isVisible = TRUE;
if (isVisible)
{
struct trackDbRef *tdbRef;
AllocVar(tdbRef);
tdbRef->tdb = tdb;
slAddHead(list, tdbRef);
safef(buffer, sizeof buffer, "%s_imgOrd", tdb->track);
- tdbRef->order = cartUsualInt(cart, buffer, 0);
+ tdbRef->order = cartUsualInt(cart, buffer, tdb->priority);
}
}
}
static int tdbRefCompare (const void *va, const void *vb)
// Compare to sort on imgTrack->order.
{
const struct trackDbRef *a = *((struct trackDbRef **)va);
const struct trackDbRef *b = *((struct trackDbRef **)vb);
return (a->order - b->order);
}
-static void addVisibleTracks(struct cart *cart, struct trackDb *trackList)
+static void addVisibleTracks(struct dyString *rootChildren, struct cart *cart, struct trackDb *trackList)
// add the visible tracks table rows.
{
struct trackDb *tdb;
struct trackDbRef *tdbRefList = NULL, *tdbRef;
-//checkForVisible(fullTrackList);
for(tdb = trackList; tdb; tdb = tdb->next)
{
checkForVisible(cart, &tdbRefList, tdb);
}
slSort(&tdbRefList, tdbRefCompare);
-
-jsInlineF("");
-jsInlineF("- %s", "visibile", "Visible Tracks");
-jsInlineF("
");
+if (!isEmpty(rootChildren->string))
+ dyStringPrintf(rootChildren, ",");
+dyStringPrintf(rootChildren, "{icon:'../images/folderC.png',id:'visible', text:'Visible Tracks', parent:'#'");
+if (tdbRefList != NULL)
+ dyStringPrintf(rootChildren, ",children:true");
+dyStringPrintf(rootChildren, "}");
+
+jsInlineF("trackData['visible'] = [");
for(tdbRef = tdbRefList; tdbRef; tdbRef = tdbRef->next)
- printGroup("visible", tdbRef->tdb, FALSE, FALSE);
+ {
+ printTrack("visible", tdbRef->tdb, FALSE);
+ if (tdbRef->next != NULL)
+ jsInlineF(",");
+ }
+jsInlineF("];");
+}
+
+void printSubtracks(char *arrayName, struct trackDb *parentTdb, boolean user)
+{
+if (parentTdb->subtracks == NULL)
+ return;
+jsInlineF("%s['%s'] = [", arrayName, trackHubSkipHubName(parentTdb->track));
+boolean first = TRUE;
+struct trackDb *tdb;
+for(tdb = parentTdb->subtracks; tdb; tdb = tdb->next)
+ {
+ if (!first)
+ jsInlineF(",");
+ printTrack(trackHubSkipHubName(parentTdb->track), tdb, user);
+ first = FALSE;
+ }
+jsInlineF("];");
+for(tdb = parentTdb->subtracks; tdb; tdb = tdb->next)
+ printSubtracks(arrayName,tdb, user);
+}
+
+void addSubtrackNames(struct dyString *dy, struct trackDb *parentTdb)
+{
+if (parentTdb->subtracks == NULL)
+ return;
-jsInlineF("
");
-jsInlineF(" ");
-jsInlineF("
");
+struct trackDb *tdb;
+for(tdb = parentTdb->subtracks; tdb; tdb = tdb->next)
+ {
+ dyStringPrintf(dy, ",'%s'", trackHubSkipHubName(tdb->track));
+ addSubtrackNames(dy, tdb);
+ }
}
static void doTable(struct cart *cart, char *db, struct grp *groupList, struct trackDb *trackList)
// output the tree table
{
char *hubName = hubNameFromUrl(getHubName(cart, db));
struct grp *curGroup;
for(curGroup = groupList; curGroup; curGroup = curGroup->next)
{
if ((hubName != NULL) && sameString(curGroup->name, hubName))
break;
}
-jsInlineF("$('#currentCollection').append(\"");
-jsInlineF("");
+jsInlineF("var collectionData = []; ");
+struct dyString *dy = newDyString(100);
if (curGroup != NULL)
{
// print out all the tracks in all the collections
struct trackDb *tdb;
+ jsInlineF("collectionData['#'] = [");
+ boolean first = TRUE;
for(tdb = trackList; tdb; tdb = tdb->next)
{
if (sameString(tdb->grp, hubName))
{
- jsInlineF("
");
- printGroup("collections", tdb, TRUE, TRUE);
- jsInlineF("
");
+ if (!first)
+ {
+ jsInlineF(",");
+ dyStringPrintf(dy, ",");
}
+ printTrack("#", tdb, TRUE);
+ dyStringPrintf(dy, "'%s'", trackHubSkipHubName(tdb->track));
+ first = FALSE;
}
}
-jsInlineF("
");
-jsInlineF("\");\n");
+ jsInlineF("];");
+ for(tdb = trackList; tdb; tdb = tdb->next)
+ {
+ if ( sameString(tdb->grp, curGroup->name))
+ {
+ printSubtracks("collectionData", tdb, TRUE);
+ addSubtrackNames(dy, tdb);
+ }
+ }
+ }
+else
+ jsInlineF("collectionData['#'] = [];");
+
+jsInlineF("var collectionNames = new Set([%s]);", dy->string);
-jsInlineF("$('#tracks').append(\"");
-addVisibleTracks(cart, trackList);
+jsInlineF("var trackData = []; ");
+struct dyString *rootChildren = newDyString(512);
+addVisibleTracks(rootChildren, cart, trackList);
for(curGroup = groupList; curGroup; curGroup = curGroup->next)
{
if ((hubName != NULL) && sameString(curGroup->name, hubName))
continue;
- jsInlineF("");
- jsInlineF("- %s", curGroup->name, curGroup->label );
+ if (!isEmpty(rootChildren->string))
+ dyStringPrintf(rootChildren, ",");
+ dyStringPrintf(rootChildren, "{icon:'../images/folderC.png',id:'%s', text:'%s', parent:'#', children:true}", curGroup->name, curGroup->label);
struct trackDb *tdb;
- jsInlineF("
");
+ jsInlineF("trackData['%s'] = [", curGroup->name);
+ boolean first = TRUE;
for(tdb = trackList; tdb; tdb = tdb->next)
{
if ( sameString(tdb->grp, curGroup->name))
{
- printGroup(curGroup->name, tdb, FALSE, FALSE);
+ if (!first)
+ jsInlineF(",");
+ printTrack(curGroup->name, tdb, FALSE);
+ first = FALSE;
}
}
- jsInlineF("
");
- jsInlineF(" ");
- jsInlineF("
");
-
+ jsInlineF("];");
+ for(tdb = trackList; tdb; tdb = tdb->next)
+ {
+ if ( sameString(tdb->grp, curGroup->name))
+ printSubtracks("trackData", tdb, FALSE);
}
-jsInlineF("\");\n");
-jsReloadOnBackButton(cart);
+ }
+jsInlineF("trackData['#'] = [%s];", rootChildren->string);
jsInlineF("hgCollection.init();\n");
}
static void printHelp()
// print out the help page
{
puts(
"
\n"
" \n"
"
Track Collection Builder Help
\n"
"
\n"
);
puts(
"
\n"
"
\n"
@@ -658,52 +667,39 @@
{
struct hash *attrHash = jsonObjectVal(attEle, "name");
struct jsonElement *strEle = (struct jsonElement *)hashFindVal(attrHash, "name");
if (strEle == NULL)
return;
track->name = jsonStringEscape(strEle->val.jeString);
hashAdd(trackHash, parentId, track);
strEle = (struct jsonElement *)hashMustFindVal(attrHash, "shortlabel");
track->shortLabel = jsonStringEscape(strEle->val.jeString);
strEle = (struct jsonElement *)hashMustFindVal(attrHash, "longlabel");
track->longLabel = jsonStringEscape(strEle->val.jeString);
track->visibility = "pack";
strEle = (struct jsonElement *)hashMustFindVal(attrHash, "color");
track->color = hexStringToLong(jsonStringEscape(strEle->val.jeString));
- /*
- strEle = (struct jsonElement *)hashMustFindVal(attrHash, "visibility");
- track->visibility = jsonStringEscape(strEle->val.jeString);
- strEle = (struct jsonElement *)hashMustFindVal(attrHash, "color");
- track->color = hexStringToLong(jsonStringEscape(strEle->val.jeString));
- strEle = (struct jsonElement *)hashFindVal(attrHash, "viewfunc");
- if (strEle)
- track->viewFunc = jsonStringEscape(strEle->val.jeString);
- strEle = (struct jsonElement *)hashFindVal(attrHash, "missingmethod");
- if (strEle)
- track->missingMethod = jsonStringEscape(strEle->val.jeString);
- */
}
if (sameString(parentName, "#"))
slAddHead(collectionList, track);
else
{
struct track *parent = hashMustFindVal(trackHash, parentName);
slAddTail(&parent->trackList, track);
}
-
}
}
static struct track *parseJsonElements( struct jsonElement *collectionElements)
// parse the JSON returned from the ap
{
struct track *collectionList = NULL;
struct hash *trackHash = hashNew(5);
struct jsonParseData jpd = {&collectionList, trackHash};
jsonElementRecurse(collectionElements, NULL, FALSE, jsonObjStart, NULL, &jpd);
slReverse(&collectionList);
return collectionList;
}
@@ -789,31 +785,31 @@
struct hash *superHash = newHash(5);
for(tdb = trackList; tdb; tdb = nextTdb)
{
nextTdb = tdb->next;
if (tdb->parent)
{
// part of a super track
if (hashLookup(superHash, tdb->parent->track) == NULL)
{
hashStore(superHash, tdb->parent->track);
slAddHead(&newList, tdb->parent);
}
- slAddHead(&tdb->parent->subtracks, tdb);
+ slAddTail(&tdb->parent->subtracks, tdb);
}
else
slAddHead(&newList, tdb);
}
slReverse(&newList);
return newList;
}
static void outOneTdb(char *db, struct sqlConnection *conn, FILE *f, struct trackDb *tdb, int numTabs)
/* Put out a single trackDb entry to our collections hub. */
{
char *tabs = "";
if (numTabs == 1)