532df37bf012ea6b52943707aaa6ab4a8b4f379f
max
  Fri Oct 25 14:50:53 2024 -0700
hide others is getting worse and worse, need to address case that track to hide is a child itself and the problem that superTrack visibility is NOT (!) inherited by children. Encode regulation can be at hide, but the children are visible! refs #27890

diff --git src/hg/js/utils.js src/hg/js/utils.js
index 85a31ea..46df8a0 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -457,30 +457,53 @@
 // json help routines
 function tdbGetJsonRecord(trackName)  { return hgTracks.trackDb[trackName]; }
 // NOTE: These must jive with tdbKindOfParent() and tdbKindOfChild() in trackDb.h
 function tdbIsFolder(tdb)             { return (tdb.kindOfParent === 1); } 
 function tdbIsComposite(tdb)          { return (tdb.kindOfParent === 2); }
 function tdbIsMultiTrack(tdb)         { return (tdb.kindOfParent === 3); }
 function tdbIsView(tdb)               { return (tdb.kindOfParent === 4); } // Don't expect to use
 function tdbIsContainer(tdb)          { return (tdb.kindOfParent === 2 || tdb.kindOfParent === 3); }
 function tdbIsLeaf(tdb)               { return (tdb.kindOfParent === 0); }
 function tdbIsFolderContent(tdb)      { return (tdb.kindOfChild  === 1); }
 function tdbIsCompositeSubtrack(tdb)  { return (tdb.kindOfChild  === 2); }
 function tdbIsMultiTrackSubtrack(tdb) { return (tdb.kindOfChild  === 3); }
 function tdbIsSubtrack(tdb)           { return (tdb.kindOfChild  === 2 || tdb.kindOfChild === 3); }
 function tdbHasParent(tdb)            { return (tdb.kindOfChild  !== 0 && tdb.parentTrack); }
 
+function cartHideAnyTrack (id, cartVars, cartVals) {
+    /* set the right cart variables to hide a track, changes cartVars and cartVals */
+    var rec = hgTracks.trackDb[id];
+    if (tdbIsSubtrack(rec)) {
+        cartVars.push(id);
+        cartVals.push('[]');
+
+        cartVars.push(id+"_sel");
+        cartVals.push(0);
+    } else if (tdbIsFolderContent(rec)) {
+        // supertrack children need to have _sel set to trigger superttrack reshaping
+        cartVars.push(id);
+        cartVals.push('hide');
+
+        cartVars.push(id+"_sel");
+        cartVals.push(0);
+    } else {
+        // normal, top-level track
+        cartVars.push(id);
+        cartVals.push('hide');
+    }
+}
+
 function tdbFindChildless(trackDb, delTracks) {
     /* Find parents that have no children left anymore in hgTracks.trackDb if you remove delTracks.
      * return obj with o.loneParents as array of [parent, array of children] , and o.others as an array of all other tracks*/
     others = [];
 
     var familySize = {};
     var families = {};
     // sort trackDb into object topParent -> count of children
     for (var trackName of Object.keys(hgTracks.trackDb)) {
         var rec = hgTracks.trackDb[trackName];
         if (rec.topParent===undefined) {
             //others.push(trackName);
             continue; // ignore top-level tracks
         }
 
@@ -489,38 +512,44 @@
             familySize[topParent] = 0;
             families[topParent] = [];
         }
         familySize[topParent]++;
         families[topParent].push(trackName);
     }
 
     // decrease the parent's count for each track to delete
     for (var delTrack of delTracks) {
         var tdbRec = hgTracks.trackDb[delTrack];
         if (tdbRec.topParent)
             familySize[tdbRec.topParent]--;
     }
 
     // for the parents of deleted tracks with a count of 0, create an array of [parentName, children]
-    loneParents = [];
+    var loneParents = [];
+    var doneParents = [];
     for (delTrack of delTracks) {
         var parentName = hgTracks.trackDb[delTrack].topParent;
         if (parentName) {
-            if (familySize[parentName]===0)
+            if (familySize[parentName]===0) {
+                if (!doneParents.includes(parentName)) {
                     loneParents.push([parentName, families[parentName]]);
-            else
+                    doneParents.push(parentName);
+                }
+            } else
                 for (var child of families[parentName])
+                    // but do not hide tracks of lone parents that are not in delTracks
+                    if (delTracks.includes(child))
                         others.push(child);
         } else {
             others.push(delTrack);
         }
     }
 
     o = {};
     o.loneParents = loneParents;
     o.others = others;
     return o;
 }
 
 function aryFind(ary,val)
 {// returns the index of a value on the array or -1;
     for (var ix=0; ix < ary.length; ix++) {