f0950c077f8427a3f65e8cc7ab37a42446041ae6
max
  Wed Sep 16 00:18:19 2015 -0700
libifying cartGetPosition because this code is needed twice, once in
hgTracks and also in cart.c for setting the page title. refs #16022,
note 18

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index e95dfe8..9952fd8 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -1757,31 +1757,31 @@
 	char *cookieName, char **exclude, struct hash *oldVars)
 /* Load cart from cookie and session cgi variable.  Write web-page
  * preamble including head and title, call doMiddle with cart, and write end of web-page.
  * Exclude may be NULL.  If it exists it's a comma-separated list of
  * variables that you don't want to save in the cart between
  * invocations of the cgi-script. */
 {
 struct cart *cart;
 char *db, *org, *pos, *clade=NULL;
 char titlePlus[128];
 char extra[128];
 pushWarnHandler(cartEarlyWarningHandler);
 cart = cartAndCookie(cookieName, exclude, oldVars);
 getDbAndGenome(cart, &db, &org, oldVars);
 clade = hClade(org);
-pos = cartOptionalString(cart, positionCgiName);
+pos = cartGetPosition(cart, db);
 pos = addCommasToPos(db, stripCommas(pos));
 if(pos != NULL && oldVars != NULL)
     {
     struct hashEl *oldpos = hashLookup(oldVars, positionCgiName);
     if(oldpos != NULL && differentString(pos,oldpos->val))
         cartSetString(cart,"lastPosition",oldpos->val);
     }
 *extra = 0;
 if (pos == NULL && org != NULL)
     safef(titlePlus,sizeof(titlePlus), "%s%s - %s",trackHubSkipHubName(org), extra, title );
 else if (pos != NULL && org == NULL)
     safef(titlePlus,sizeof(titlePlus), "%s - %s",pos, title );
 else if (pos == NULL && org == NULL)
     safef(titlePlus,sizeof(titlePlus), "%s", title );
 else
@@ -2796,15 +2796,57 @@
 
     if (exists)
 	dyStringPrintf(dyMessage,
 		       "<P>Note: the session contains BLAT results.  ");
     else
 	dyStringPrintf(dyMessage,
 		"<P>Note: the session contains an expired reference to "
 		"previously saved BLAT results, so it may not appear as "
 		"originally intended.  ");
     dyStringPrintf(dyMessage,
 		   "BLAT results are subject to an "
 		   "<A HREF=\"../goldenPath/help/hgSessionHelp.html#CTs\" TARGET=_BLANK>"
 		   "expiration policy</A>.");
     }
 }
+
+char *cartGetPosition(struct cart *cart, char *database)
+/* get the current position in cart as a string chr:start-end.
+ * This can handle the special CGI params 'default' and 'lastDbPos'
+ * Returned value has to be freed. Returns 
+ * default position of assembly is no position set in cart nor as CGI var.
+ * Returns NULL if no position set anywhere and no default position.
+*/
+{
+// position=lastDbPos in URL? -> go back to the last browsed position for this db
+char *position = NULL;
+char dbPosKey[256];
+char *defaultPosition = hDefaultPos(database);
+safef(dbPosKey, sizeof(dbPosKey), "position.%s", database);
+if (sameOk(cgiOptionalString("position"), "lastDbPos"))
+    {
+    position = cartUsualString(cart, dbPosKey, defaultPosition);
+    cartSetString(cart, "position", position);
+    }
+    
+if (position == NULL)
+    {
+    position = cloneString(cartUsualString(cart, "position", NULL));
+    }
+
+/* default if not set at all, as would happen if it came from a URL with no
+ * position. Otherwise tell them to go back to the gateway. Also recognize
+ * "default" as specifying the default position. */
+if (((position == NULL) || sameString(position, "default"))
+    && (defaultPosition != NULL))
+    position = cloneString(defaultPosition);
+
+return position;
+}
+
+void cartSetDbPosition(struct cart *cart, char *database, char *position)
+/* set the 'position.db' variable in the cart */
+{
+char dbPosKey[256];
+safef(dbPosKey, sizeof(dbPosKey), "position.%s", database);
+cartSetString(cart, dbPosKey, cloneString(position)); // XX need to clone here?
+}