Fossil SCM
Add the new "ms=brlist" version of the "ms" query parameter on /timeline. Use it with the multi-branch selector on the /brlist page.
Commit
2e9520a2b7cddc67e0dd49cece448e01fd480d80781bb8f71298dceaf67998d4
Parent
262c0fb675bd633…
2 files changed
+3
-3
+16
-3
+3
-3
| --- src/fossil.page.brlist.js | ||
| +++ src/fossil.page.brlist.js | ||
| @@ -12,20 +12,20 @@ | ||
| 12 | 12 | */ |
| 13 | 13 | window.addEventListener( 'load', function() { |
| 14 | 14 | |
| 15 | 15 | var anchor = document.querySelector("div.submenu > a:first-of-type" ); |
| 16 | 16 | if( !anchor || anchor.innerText != "Timeline" ) return; |
| 17 | -var prefix = anchor.href.toString() + "?ms=regexp&rel&t="; | |
| 17 | +var prefix = anchor.href.toString() + "?ms=brlist&t="; | |
| 18 | 18 | anchor.classList.add('timeline-link'); |
| 19 | 19 | |
| 20 | 20 | var amendAnchor = function( selected ){ |
| 21 | 21 | if( selected.length == 0 ){ |
| 22 | 22 | anchor.classList.remove('selected'); |
| 23 | 23 | anchor.href = prefix; |
| 24 | 24 | return; |
| 25 | 25 | } |
| 26 | - re = selected.join("|"); | |
| 26 | + re = selected.join(","); | |
| 27 | 27 | try{re = encodeURIComponent(re);} |
| 28 | 28 | catch{console.log("encodeURIComponent() failed for ",re);} |
| 29 | 29 | anchor.href = prefix + re; |
| 30 | 30 | anchor.innerHTML = "View " + selected.length + |
| 31 | 31 | ( selected.length > 1 ? " branches" : " branch" ); |
| @@ -38,11 +38,11 @@ | ||
| 38 | 38 | var tr = cbx.parentElement.parentElement; |
| 39 | 39 | var tag = cbx.parentElement.children[0].innerText; |
| 40 | 40 | var re = anchor.href.substr(prefix.length); |
| 41 | 41 | try{re = decodeURIComponent(re);} |
| 42 | 42 | catch{console.log("decodeURIComponent() failed for ",re);} |
| 43 | - var selected = ( re != "" ? re.split("|") : [] ); | |
| 43 | + var selected = ( re != "" ? re.split(",") : [] ); | |
| 44 | 44 | if( cbx.checked ){ |
| 45 | 45 | selected.push(tag); |
| 46 | 46 | tr.classList.add('selected'); |
| 47 | 47 | } |
| 48 | 48 | else { |
| 49 | 49 |
| --- src/fossil.page.brlist.js | |
| +++ src/fossil.page.brlist.js | |
| @@ -12,20 +12,20 @@ | |
| 12 | */ |
| 13 | window.addEventListener( 'load', function() { |
| 14 | |
| 15 | var anchor = document.querySelector("div.submenu > a:first-of-type" ); |
| 16 | if( !anchor || anchor.innerText != "Timeline" ) return; |
| 17 | var prefix = anchor.href.toString() + "?ms=regexp&rel&t="; |
| 18 | anchor.classList.add('timeline-link'); |
| 19 | |
| 20 | var amendAnchor = function( selected ){ |
| 21 | if( selected.length == 0 ){ |
| 22 | anchor.classList.remove('selected'); |
| 23 | anchor.href = prefix; |
| 24 | return; |
| 25 | } |
| 26 | re = selected.join("|"); |
| 27 | try{re = encodeURIComponent(re);} |
| 28 | catch{console.log("encodeURIComponent() failed for ",re);} |
| 29 | anchor.href = prefix + re; |
| 30 | anchor.innerHTML = "View " + selected.length + |
| 31 | ( selected.length > 1 ? " branches" : " branch" ); |
| @@ -38,11 +38,11 @@ | |
| 38 | var tr = cbx.parentElement.parentElement; |
| 39 | var tag = cbx.parentElement.children[0].innerText; |
| 40 | var re = anchor.href.substr(prefix.length); |
| 41 | try{re = decodeURIComponent(re);} |
| 42 | catch{console.log("decodeURIComponent() failed for ",re);} |
| 43 | var selected = ( re != "" ? re.split("|") : [] ); |
| 44 | if( cbx.checked ){ |
| 45 | selected.push(tag); |
| 46 | tr.classList.add('selected'); |
| 47 | } |
| 48 | else { |
| 49 |
| --- src/fossil.page.brlist.js | |
| +++ src/fossil.page.brlist.js | |
| @@ -12,20 +12,20 @@ | |
| 12 | */ |
| 13 | window.addEventListener( 'load', function() { |
| 14 | |
| 15 | var anchor = document.querySelector("div.submenu > a:first-of-type" ); |
| 16 | if( !anchor || anchor.innerText != "Timeline" ) return; |
| 17 | var prefix = anchor.href.toString() + "?ms=brlist&t="; |
| 18 | anchor.classList.add('timeline-link'); |
| 19 | |
| 20 | var amendAnchor = function( selected ){ |
| 21 | if( selected.length == 0 ){ |
| 22 | anchor.classList.remove('selected'); |
| 23 | anchor.href = prefix; |
| 24 | return; |
| 25 | } |
| 26 | re = selected.join(","); |
| 27 | try{re = encodeURIComponent(re);} |
| 28 | catch{console.log("encodeURIComponent() failed for ",re);} |
| 29 | anchor.href = prefix + re; |
| 30 | anchor.innerHTML = "View " + selected.length + |
| 31 | ( selected.length > 1 ? " branches" : " branch" ); |
| @@ -38,11 +38,11 @@ | |
| 38 | var tr = cbx.parentElement.parentElement; |
| 39 | var tag = cbx.parentElement.children[0].innerText; |
| 40 | var re = anchor.href.substr(prefix.length); |
| 41 | try{re = decodeURIComponent(re);} |
| 42 | catch{console.log("decodeURIComponent() failed for ",re);} |
| 43 | var selected = ( re != "" ? re.split(",") : [] ); |
| 44 | if( cbx.checked ){ |
| 45 | selected.push(tag); |
| 46 | tr.classList.add('selected'); |
| 47 | } |
| 48 | else { |
| 49 |
+16
-3
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1275,11 +1275,13 @@ | ||
| 1275 | 1275 | */ |
| 1276 | 1276 | typedef enum { |
| 1277 | 1277 | MS_EXACT, /* Matches a single tag by exact string comparison. */ |
| 1278 | 1278 | MS_GLOB, /* Matches tags against a list of GLOB patterns. */ |
| 1279 | 1279 | MS_LIKE, /* Matches tags against a list of LIKE patterns. */ |
| 1280 | - MS_REGEXP /* Matches tags against a list of regular expressions. */ | |
| 1280 | + MS_REGEXP, /* Matches tags against a list of regular expressions. */ | |
| 1281 | + MS_BRLIST, /* Same as REGEXP, except the regular expression is a list | |
| 1282 | + ** of branch names */ | |
| 1281 | 1283 | } MatchStyle; |
| 1282 | 1284 | |
| 1283 | 1285 | /* |
| 1284 | 1286 | ** Quote a tag string by surrounding it with double quotes and preceding |
| 1285 | 1287 | ** internal double quotes and backslashes with backslashes. |
| @@ -1310,11 +1312,13 @@ | ||
| 1310 | 1312 | |
| 1311 | 1313 | /* |
| 1312 | 1314 | ** Construct the tag match SQL expression. |
| 1313 | 1315 | ** |
| 1314 | 1316 | ** This function is adapted from glob_expr() to support the MS_EXACT, MS_GLOB, |
| 1315 | -** MS_LIKE, and MS_REGEXP match styles. For MS_EXACT, the returned expression | |
| 1317 | +** MS_LIKE, MS_REGEXP, and MS_BRLIST match styles. | |
| 1318 | +** | |
| 1319 | +** For MS_EXACT, the returned expression | |
| 1316 | 1320 | ** checks for integer match against the tag ID which is looked up directly by |
| 1317 | 1321 | ** this function. For the other modes, the returned SQL expression performs |
| 1318 | 1322 | ** string comparisons against the tag names, so it is necessary to join against |
| 1319 | 1323 | ** the tag table to access the "tagname" column. |
| 1320 | 1324 | ** |
| @@ -1372,17 +1376,24 @@ | ||
| 1372 | 1376 | zDelimiter = " OR "; |
| 1373 | 1377 | zEnd = ")"; |
| 1374 | 1378 | zPrefix = "tagname LIKE 'sym-"; |
| 1375 | 1379 | zSuffix = "'"; |
| 1376 | 1380 | zIntro = "SQL LIKE pattern "; |
| 1377 | - }else/* if( matchStyle==MS_REGEXP )*/{ | |
| 1381 | + }else if( matchStyle==MS_REGEXP ){ | |
| 1378 | 1382 | zStart = "(tagname REGEXP '^sym-("; |
| 1379 | 1383 | zDelimiter = "|"; |
| 1380 | 1384 | zEnd = ")$')"; |
| 1381 | 1385 | zPrefix = ""; |
| 1382 | 1386 | zSuffix = ""; |
| 1383 | 1387 | zIntro = "regular expression "; |
| 1388 | + }else/* if( matchStyle==MS_BRLIST )*/{ | |
| 1389 | + zStart = "tagname IN ('sym-"; | |
| 1390 | + zDelimiter = "','sym-"; | |
| 1391 | + zEnd = "')"; | |
| 1392 | + zPrefix = ""; | |
| 1393 | + zSuffix = ""; | |
| 1394 | + zIntro = "any of "; | |
| 1384 | 1395 | } |
| 1385 | 1396 | |
| 1386 | 1397 | /* Convert the list of matches into an SQL expression and text description. */ |
| 1387 | 1398 | blob_zero(&expr); |
| 1388 | 1399 | blob_zero(&desc); |
| @@ -1792,10 +1803,12 @@ | ||
| 1792 | 1803 | matchStyle = MS_GLOB; |
| 1793 | 1804 | }else if( fossil_stricmp(zMatchStyle, "like")==0 ){ |
| 1794 | 1805 | matchStyle = MS_LIKE; |
| 1795 | 1806 | }else if( fossil_stricmp(zMatchStyle, "regexp")==0 ){ |
| 1796 | 1807 | matchStyle = MS_REGEXP; |
| 1808 | + }else if( fossil_stricmp(zMatchStyle, "brlist")==0 ){ | |
| 1809 | + matchStyle = MS_BRLIST; | |
| 1797 | 1810 | }else{ |
| 1798 | 1811 | /* For exact maching, inhibit links to the selected tag. */ |
| 1799 | 1812 | zThisTag = zTagName; |
| 1800 | 1813 | Th_Store("current_checkin", zTagName); |
| 1801 | 1814 | } |
| 1802 | 1815 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1275,11 +1275,13 @@ | |
| 1275 | */ |
| 1276 | typedef enum { |
| 1277 | MS_EXACT, /* Matches a single tag by exact string comparison. */ |
| 1278 | MS_GLOB, /* Matches tags against a list of GLOB patterns. */ |
| 1279 | MS_LIKE, /* Matches tags against a list of LIKE patterns. */ |
| 1280 | MS_REGEXP /* Matches tags against a list of regular expressions. */ |
| 1281 | } MatchStyle; |
| 1282 | |
| 1283 | /* |
| 1284 | ** Quote a tag string by surrounding it with double quotes and preceding |
| 1285 | ** internal double quotes and backslashes with backslashes. |
| @@ -1310,11 +1312,13 @@ | |
| 1310 | |
| 1311 | /* |
| 1312 | ** Construct the tag match SQL expression. |
| 1313 | ** |
| 1314 | ** This function is adapted from glob_expr() to support the MS_EXACT, MS_GLOB, |
| 1315 | ** MS_LIKE, and MS_REGEXP match styles. For MS_EXACT, the returned expression |
| 1316 | ** checks for integer match against the tag ID which is looked up directly by |
| 1317 | ** this function. For the other modes, the returned SQL expression performs |
| 1318 | ** string comparisons against the tag names, so it is necessary to join against |
| 1319 | ** the tag table to access the "tagname" column. |
| 1320 | ** |
| @@ -1372,17 +1376,24 @@ | |
| 1372 | zDelimiter = " OR "; |
| 1373 | zEnd = ")"; |
| 1374 | zPrefix = "tagname LIKE 'sym-"; |
| 1375 | zSuffix = "'"; |
| 1376 | zIntro = "SQL LIKE pattern "; |
| 1377 | }else/* if( matchStyle==MS_REGEXP )*/{ |
| 1378 | zStart = "(tagname REGEXP '^sym-("; |
| 1379 | zDelimiter = "|"; |
| 1380 | zEnd = ")$')"; |
| 1381 | zPrefix = ""; |
| 1382 | zSuffix = ""; |
| 1383 | zIntro = "regular expression "; |
| 1384 | } |
| 1385 | |
| 1386 | /* Convert the list of matches into an SQL expression and text description. */ |
| 1387 | blob_zero(&expr); |
| 1388 | blob_zero(&desc); |
| @@ -1792,10 +1803,12 @@ | |
| 1792 | matchStyle = MS_GLOB; |
| 1793 | }else if( fossil_stricmp(zMatchStyle, "like")==0 ){ |
| 1794 | matchStyle = MS_LIKE; |
| 1795 | }else if( fossil_stricmp(zMatchStyle, "regexp")==0 ){ |
| 1796 | matchStyle = MS_REGEXP; |
| 1797 | }else{ |
| 1798 | /* For exact maching, inhibit links to the selected tag. */ |
| 1799 | zThisTag = zTagName; |
| 1800 | Th_Store("current_checkin", zTagName); |
| 1801 | } |
| 1802 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1275,11 +1275,13 @@ | |
| 1275 | */ |
| 1276 | typedef enum { |
| 1277 | MS_EXACT, /* Matches a single tag by exact string comparison. */ |
| 1278 | MS_GLOB, /* Matches tags against a list of GLOB patterns. */ |
| 1279 | MS_LIKE, /* Matches tags against a list of LIKE patterns. */ |
| 1280 | MS_REGEXP, /* Matches tags against a list of regular expressions. */ |
| 1281 | MS_BRLIST, /* Same as REGEXP, except the regular expression is a list |
| 1282 | ** of branch names */ |
| 1283 | } MatchStyle; |
| 1284 | |
| 1285 | /* |
| 1286 | ** Quote a tag string by surrounding it with double quotes and preceding |
| 1287 | ** internal double quotes and backslashes with backslashes. |
| @@ -1310,11 +1312,13 @@ | |
| 1312 | |
| 1313 | /* |
| 1314 | ** Construct the tag match SQL expression. |
| 1315 | ** |
| 1316 | ** This function is adapted from glob_expr() to support the MS_EXACT, MS_GLOB, |
| 1317 | ** MS_LIKE, MS_REGEXP, and MS_BRLIST match styles. |
| 1318 | ** |
| 1319 | ** For MS_EXACT, the returned expression |
| 1320 | ** checks for integer match against the tag ID which is looked up directly by |
| 1321 | ** this function. For the other modes, the returned SQL expression performs |
| 1322 | ** string comparisons against the tag names, so it is necessary to join against |
| 1323 | ** the tag table to access the "tagname" column. |
| 1324 | ** |
| @@ -1372,17 +1376,24 @@ | |
| 1376 | zDelimiter = " OR "; |
| 1377 | zEnd = ")"; |
| 1378 | zPrefix = "tagname LIKE 'sym-"; |
| 1379 | zSuffix = "'"; |
| 1380 | zIntro = "SQL LIKE pattern "; |
| 1381 | }else if( matchStyle==MS_REGEXP ){ |
| 1382 | zStart = "(tagname REGEXP '^sym-("; |
| 1383 | zDelimiter = "|"; |
| 1384 | zEnd = ")$')"; |
| 1385 | zPrefix = ""; |
| 1386 | zSuffix = ""; |
| 1387 | zIntro = "regular expression "; |
| 1388 | }else/* if( matchStyle==MS_BRLIST )*/{ |
| 1389 | zStart = "tagname IN ('sym-"; |
| 1390 | zDelimiter = "','sym-"; |
| 1391 | zEnd = "')"; |
| 1392 | zPrefix = ""; |
| 1393 | zSuffix = ""; |
| 1394 | zIntro = "any of "; |
| 1395 | } |
| 1396 | |
| 1397 | /* Convert the list of matches into an SQL expression and text description. */ |
| 1398 | blob_zero(&expr); |
| 1399 | blob_zero(&desc); |
| @@ -1792,10 +1803,12 @@ | |
| 1803 | matchStyle = MS_GLOB; |
| 1804 | }else if( fossil_stricmp(zMatchStyle, "like")==0 ){ |
| 1805 | matchStyle = MS_LIKE; |
| 1806 | }else if( fossil_stricmp(zMatchStyle, "regexp")==0 ){ |
| 1807 | matchStyle = MS_REGEXP; |
| 1808 | }else if( fossil_stricmp(zMatchStyle, "brlist")==0 ){ |
| 1809 | matchStyle = MS_BRLIST; |
| 1810 | }else{ |
| 1811 | /* For exact maching, inhibit links to the selected tag. */ |
| 1812 | zThisTag = zTagName; |
| 1813 | Th_Store("current_checkin", zTagName); |
| 1814 | } |
| 1815 |