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(""); - } -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(""); +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(""); + 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("];"); + 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)