59c4b5446987113a20a88c2860c469ae14dcc0b9 larrym Thu Jul 28 21:39:44 2011 -0700 switch to using in-memory json; refactor trackDbJson so it is part of hgTracks global in the client (redmine #4550) diff --git src/hg/hgTracks/imageV2.c src/hg/hgTracks/imageV2.c index 09ecbf2..b515bde 100644 --- src/hg/hgTracks/imageV2.c +++ src/hg/hgTracks/imageV2.c @@ -234,95 +234,101 @@ { enum kindOfChild kindOfChild = kocOrphan; if (tdbIsFolderContent(tdb)) kindOfChild = kocFolderContent; else if (tdbIsCompositeChild(tdb)) kindOfChild = kocCompositeChild; else if (tdbIsMultiTrackChild(tdb)) kindOfChild = kocMultiTrackChild; return kindOfChild; } ///////////////////////// // JSON support. Eventually the whole imgTbl could be written out as JSON -static void jsonTdbSettingsInit(struct dyString **jsonTdbSettingsString) +static void jsonTdbSettingsInit(struct jsonHashElement *settings) // Inititializes trackDbJson { -*jsonTdbSettingsString = newDyString(1024); -dyStringPrintf(*jsonTdbSettingsString, "<script type='text/javascript'>\n// START trackDbJson\nvar trackDbJson = {\n\"ruler\": {\"shortLabel\": \"ruler\", \"longLabel\": \"Base Position Controls\", \"canPack\": 0, \"visibility\": %d, \"configureBy\": \"popup\", \"kindOfParent\": 0}", rulerMode); +struct jsonHashElement *ele = newJsonHash(newHash(8)); +jsonHashAddString(ele, "shortLabel", "ruler"); +jsonHashAddString(ele, "longLabel", "Base Position Controls"); +jsonHashAddNumber(ele, "canPack", 0); +jsonHashAddNumber(ele, "visibility", rulerMode); +jsonHashAddString(ele, "configureBy", "popup"); +jsonHashAddNumber(ele, "kindOfParent", 0); +jsonHashAdd(settings, "ruler", (struct jsonElement *) ele); } -void jsonTdbSettingsBuild(struct dyString **jsonTdbSettingsString, struct track *track, boolean configurable) -// Creates then successively adds trackDb settings to the jsonTdbSettingsString -// Initially pass in NULL pointer to a dyString to properly begin building +void jsonTdbSettingsBuild(struct jsonHashElement *settings, struct track *track, boolean configurable) +// Adds trackDb settings to the jsonTdbSettings { -if(*jsonTdbSettingsString == NULL) - jsonTdbSettingsInit(jsonTdbSettingsString); -dyStringAppend(*jsonTdbSettingsString, ", \n"); - +struct jsonHashElement *ele = newJsonHash(newHash(8)); +jsonHashAdd(settings, track->track, (struct jsonElement *) ele); // track name and type -dyStringPrintf(*jsonTdbSettingsString, "\t\"%s\": {", track->track); -dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"type\": \"%s\",", track->tdb->type); +jsonHashAddString(ele, "type", track->tdb->type); // Tell which kind of parent and which kind of child enum kindOfParent kindOfParent = tdbKindOfParent(track->tdb); enum kindOfChild kindOfChild = tdbKindOfChild(track->tdb); -dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"kindOfParent\": %d,\n\t\t\"kindOfChild\": %d,",kindOfParent,kindOfChild); +jsonHashAddNumber(ele, "kindOfParent", kindOfParent); +jsonHashAddNumber(ele, "kindOfChild", kindOfChild); // Tell something about the parent and/or children if (kindOfChild != kocOrphan) { struct trackDb *parentTdb = (kindOfChild == kocFolderContent ? track->tdb->parent :tdbGetContainer(track->tdb)); - dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"parentTrack\": \"%s\",\n\t\t\"parentLabel\": \"%s\",", - parentTdb->track, javaScriptLiteralEncode(parentTdb->shortLabel)); + jsonHashAddString(ele, "parentTrack", parentTdb->track); + jsonHashAddString(ele, "parentLabel", parentTdb->shortLabel); if (kindOfChild != kocFolderContent && !track->canPack) { - dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"shouldPack\": 0,"); // default vis is full, but pack is an option + jsonHashAddNumber(ele, "shouldPack", 0); // default vis is full, but pack is an option track->canPack = parentTdb->canPack; } } -dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"hasChildren\": %d,", slCount(track->tdb->subtracks)); + +// XXXX really s/d be numChildren +jsonHashAddNumber(ele, "hasChildren", slCount(track->tdb->subtracks)); // Configuring? if (!configurable || track->hasUi == FALSE) - dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"configureBy\": \"none\","); + jsonHashAddString(ele, "configureBy", "none"); else if (sameString(trackDbSettingClosestToHomeOrDefault(track->tdb, "configureByPopup", regexMatch(track->track, "^snp[0-9]+") || regexMatch(track->track, "^cons[0-9]+way") || regexMatch(track->track, "^multiz") ? "off" : "on"), "off")) - dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"configureBy\": \"clickThrough\","); + jsonHashAddString(ele, "configureBy", "clickThrough"); else - dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"configureBy\": \"popup\","); + jsonHashAddString(ele, "configureBy", "popup"); // Remote access by URL? if (sameWord(track->tdb->type, "remote") && trackDbSetting(track->tdb, "url") != NULL) - dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"url\": \"%s\",", trackDbSetting(track->tdb, "url")); + jsonHashAddString(ele, "url", trackDbSetting(track->tdb, "url")); // Close with some standard vars -dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"shortLabel\": \"%s\",\n\t\t\"longLabel\": \"%s\",\n\t\t\"canPack\": %d,", - javaScriptLiteralEncode(track->shortLabel), javaScriptLiteralEncode(track->longLabel), track->canPack); +jsonHashAddString(ele, "shortLabel", track->shortLabel); +jsonHashAddString(ele, "longLabel", track->longLabel); +jsonHashAddNumber(ele, "canPack", track->canPack); + if(track->limitedVis != track->visibility) - dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"limitedVis\": %d,", track->limitedVis); -dyStringPrintf(*jsonTdbSettingsString, "\n\t\t\"visibility\": %d\n\t}", track->visibility); + jsonHashAddNumber(ele, "limitedVis", track->limitedVis); +jsonHashAddNumber(ele, "visibility", track->visibility); } -char *jsonTdbSettingsUse(struct dyString **jsonTdbSettingsString) -// Closes and returns the contents of the jsonTdbSettingsString +void jsonTdbSettingsUse(struct jsonHashElement *settings) { -dyStringAppend(*jsonTdbSettingsString, "};\n// END trackDbJson\n</script>\n"); -return dyStringCannibalize(jsonTdbSettingsString); +// add the settings to the hgTracks output object +jsonHashAdd(jsonForClient, "trackDb", (struct jsonElement *) settings); } ///////////////////////// // IMAGEv2 // The new way to do images: PLEASE REFER TO imageV2.h FOR A DETAILED DESCRIPTION ///////////////////////// /////////////////////// Maps struct mapSet *mapSetStart(char *name,struct image *img,char *linkRoot) /* Starts a map (aka mapSet) which is the seet of links and image locations used in HTML. Complete a map by adding items with mapItemAdd() */ { @@ -1870,41 +1876,41 @@ hPrintf("var imgBoxChromStart=%d;var imgBoxChromEnd=%d;var imgBoxWidth=%d;", imgBox->chromStart, imgBox->chromEnd,(imgBox->width - imgBox->sideLabelWidth)); hPrintf("var imgBoxPortalStart=%d;var imgBoxPortalEnd=%d;var imgBoxPortalWidth=%d;", imgBox->portalStart, imgBox->portalEnd, imgBox->portalWidth); hPrintf("var imgBoxLeftLabel=%d;var imgBoxPortalOffsetX=%d;var imgBoxBasesPerPixel=%lf;</script>\n", (imgBox->plusStrand?imgBox->sideLabelWidth:0), (int)((imgBox->portalStart - imgBox->chromStart) / imgBox->basesPerPixel),imgBox->basesPerPixel); } #endif//def IMAGEv2_DRAG_SCROLL hPrintf("<TABLE id='imgTbl' border=0 cellspacing=0 cellpadding=0 BGCOLOR='%s'",COLOR_WHITE);//COLOR_RED); // RED to help find bugs hPrintf(" width=%d",imgBox->showPortal?(imgBox->portalWidth+imgBox->sideLabelWidth):imgBox->width); hPrintf(" class='tableWithDragAndDrop'"); hPrintf(" style='border:1px solid blue;border-collapse:separate;'>\n"); -struct dyString *jsonTdbVars = NULL; -jsonTdbSettingsInit(&jsonTdbVars); +struct jsonHashElement *jsonTdbVars = newJsonHash(newHash(8)); +jsonTdbSettingsInit(jsonTdbVars); char *newLine = NEWLINE_TO_USE(cgiClientBrowser(NULL,NULL,NULL)); struct imgTrack *imgTrack = imgBox->imgTracks; for(;imgTrack!=NULL;imgTrack=imgTrack->next) { char *trackName = (imgTrack->name != NULL ? imgTrack->name : imgTrack->tdb->track ); struct track *track = hashFindVal(trackHash, trackName); if(track) - jsonTdbSettingsBuild(&jsonTdbVars, track, TRUE); + jsonTdbSettingsBuild(jsonTdbVars, track, TRUE); hPrintf("<TR id='tr_%s' abbr='%d' class='imgOrd%s%s%s'>\n",trackName,imgTrack->order, (imgTrack->reorderable?" trDraggable":" nodrop nodrag"), (imgTrack->centerLabelSeen != clAlways?" clOpt":""), (imgTrack->ajaxRetrieval ?" mustRetrieve":"")); if(imgBox->showSideLabel && imgBox->plusStrand) { // button safef(name, sizeof(name), "btn_%s", trackName); hPrintf(" <TD id='td_%s'%s>\n",name,(imgTrack->reorderable?" class='dragHandle'":"")); sliceAndMapDraw(imgBox,imgTrack,stButton,name,FALSE); hPrintf("</TD>\n"); // leftLabel safef(name,sizeof(name),"side_%s",trackName); if (imgTrack->reorderable) @@ -1937,19 +1943,17 @@ hPrintf(" <TD id='td_%s' class='dragHandle' title='%s%sdrag to reorder'>\n",name,htmlEncode(imgTrack->tdb->longLabel),newLine); else hPrintf(" <TD id='td_%s'>\n",name); sliceAndMapDraw(imgBox,imgTrack,stSide,name,FALSE); hPrintf("</TD>\n"); // button safef(name, sizeof(name), "btn_%s", trackName); hPrintf(" <TD id='td_%s'%s>\n",name,(imgTrack->reorderable?" class='dragHandle'":"")); sliceAndMapDraw(imgBox,imgTrack,stButton, name,FALSE); hPrintf("</TD>\n"); } hPrintf("</TR>\n"); } hPrintf("</TABLE>\n"); hPrintf("<!-- - - - - - - - ^^^ IMAGEv2 ^^^ - - - - - - - -->\n"); // DANGER FF interprets '--' as end of comment, not '-->' - -if (jsonTdbVars != NULL) - hWrites(jsonTdbSettingsUse(&jsonTdbVars)); +jsonTdbSettingsUse(jsonTdbVars); }