Fossil SCM

Integrate rptview-submenu-paralinks brach. For this check-in parametric links in submenus are enabled on [/rptview?rn=6&wikismpl=rptview&rvsmpl=wiki/To+Do+List|/rptview] page (may be triggered by rvsmpl,rvsmplX,rptview_smpl,rptview_smplX parameter names) and also for [/rptview?rn=6&wikismpl=rptview&rvsmpl=wiki/To+Do+List|/wiki] page (may be triggered by wikismpl,wikismplX parameter names).

george 2021-03-26 18:25 trunk merge
Commit 5c5aa19cc5098ac2e15aa9a525158a8d302e3ece6318aec196381d5c8a0a2c26
+25 -4
--- src/report.c
+++ src/report.c
@@ -968,14 +968,18 @@
968968
}
969969
970970
/*
971971
** WEBPAGE: rptview
972972
**
973
-** Generate a report. The rn query parameter is the report number
974
-** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
973
+** Generate a report. The "rn" query parameter is the report number
974
+** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists,
975975
** then the output consists of lines of tab-separated fields instead of
976
-** an HTML table.
976
+** an HTML table. If the "rvsmpl" query parameter is set then report's
977
+** submenu will contain an extra hyperlink that have a value-driven
978
+** label and target.
979
+**
980
+** "rvsmpl" stands for Report View SubMenu's Parametric Link.
977981
*/
978982
void rptview_page(void){
979983
int count = 0;
980984
int rn, rc;
981985
char *zSql;
@@ -1029,14 +1033,31 @@
10291033
}
10301034
10311035
count = 0;
10321036
if( !tabs ){
10331037
struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1038
+ const char *zQS = PD("QUERY_STRING","");
10341039
10351040
db_multi_exec("PRAGMA empty_result_callbacks=ON");
10361041
style_set_current_feature("report");
1037
- style_submenu_element("Raw", "rptview?tablist=1&rn=%d&%h", rn, PD("QUERY_STRING","") );
1042
+ /*
1043
+ ** Lets use a funcy button for /reportlist since that page may be
1044
+ ** heavily customized by the user. Some variants: ⊚ ⦾ ❊ ⊛ ⚛ ⸎ 💠
1045
+ ** Enclosing it inside of square brackets makes its position
1046
+ ** determenistic and clearly distincts regular submenu links from
1047
+ ** those that are induced by the query string parameters.
1048
+ */
1049
+ if( zQS[0] ){
1050
+ style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS);
1051
+ style_submenu_element("[⊚]","%R/reportlist?%s",zQS);
1052
+ } else {
1053
+ style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1054
+ style_submenu_element("[⊚]","%R/reportlist");
1055
+ }
1056
+ style_submenu_parametric("rptview_",5);
1057
+ style_submenu_parametric("rv",5);
1058
+
10381059
if( g.perm.Admin
10391060
|| (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
10401061
style_submenu_element("Edit", "rptedit?rn=%d", rn);
10411062
}
10421063
if( g.perm.TktFmt ){
10431064
--- src/report.c
+++ src/report.c
@@ -968,14 +968,18 @@
968 }
969
970 /*
971 ** WEBPAGE: rptview
972 **
973 ** Generate a report. The rn query parameter is the report number
974 ** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
975 ** then the output consists of lines of tab-separated fields instead of
976 ** an HTML table.
 
 
 
 
977 */
978 void rptview_page(void){
979 int count = 0;
980 int rn, rc;
981 char *zSql;
@@ -1029,14 +1033,31 @@
1029 }
1030
1031 count = 0;
1032 if( !tabs ){
1033 struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
1034
1035 db_multi_exec("PRAGMA empty_result_callbacks=ON");
1036 style_set_current_feature("report");
1037 style_submenu_element("Raw", "rptview?tablist=1&rn=%d&%h", rn, PD("QUERY_STRING","") );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1038 if( g.perm.Admin
1039 || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1040 style_submenu_element("Edit", "rptedit?rn=%d", rn);
1041 }
1042 if( g.perm.TktFmt ){
1043
--- src/report.c
+++ src/report.c
@@ -968,14 +968,18 @@
968 }
969
970 /*
971 ** WEBPAGE: rptview
972 **
973 ** Generate a report. The "rn" query parameter is the report number
974 ** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists,
975 ** then the output consists of lines of tab-separated fields instead of
976 ** an HTML table. If the "rvsmpl" query parameter is set then report's
977 ** submenu will contain an extra hyperlink that have a value-driven
978 ** label and target.
979 **
980 ** "rvsmpl" stands for Report View SubMenu's Parametric Link.
981 */
982 void rptview_page(void){
983 int count = 0;
984 int rn, rc;
985 char *zSql;
@@ -1029,14 +1033,31 @@
1033 }
1034
1035 count = 0;
1036 if( !tabs ){
1037 struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1038 const char *zQS = PD("QUERY_STRING","");
1039
1040 db_multi_exec("PRAGMA empty_result_callbacks=ON");
1041 style_set_current_feature("report");
1042 /*
1043 ** Lets use a funcy button for /reportlist since that page may be
1044 ** heavily customized by the user. Some variants: ⊚ ⦾ ❊ ⊛ ⚛ ⸎ 💠
1045 ** Enclosing it inside of square brackets makes its position
1046 ** determenistic and clearly distincts regular submenu links from
1047 ** those that are induced by the query string parameters.
1048 */
1049 if( zQS[0] ){
1050 style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS);
1051 style_submenu_element("[⊚]","%R/reportlist?%s",zQS);
1052 } else {
1053 style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1054 style_submenu_element("[⊚]","%R/reportlist");
1055 }
1056 style_submenu_parametric("rptview_",5);
1057 style_submenu_parametric("rv",5);
1058
1059 if( g.perm.Admin
1060 || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1061 style_submenu_element("Edit", "rptedit?rn=%d", rn);
1062 }
1063 if( g.perm.TktFmt ){
1064
+62
--- src/style.c
+++ src/style.c
@@ -329,10 +329,72 @@
329329
aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
330330
aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
331331
nSubmenuCtrl++;
332332
}
333333
}
334
+
335
+/* Add hyperlinks depending on the existence and values of special
336
+** parameters in the request's query string. The names of these
337
+** parameters that are investigated are obtainted by concatenation
338
+** of zPrefix with suffix "smplX", where X is either nothing or
339
+** a positive digit <= nMaxDigit. zPrefix must start with a lowercase
340
+** letter, be short and have no strange characters. A value is
341
+** well-formed if its first filepath segment (separated by '/')
342
+** has no strange characters. The labels of the resulting submenu items
343
+** are equal to the well-formed values that are prepended by "✧"
344
+** unless a value starts with a lowercase letter.
345
+** Malformed values are silently ignored.
346
+*/
347
+void style_submenu_parametric(
348
+ const char *zPrefix, /* common prefix of the query parameters names */
349
+ const int nMaxDigit /* maximal digit on the end of param names */
350
+){
351
+ const char *zQS; /* QUERY_STRING */
352
+ const char *suffix = "smpl"; /* common suffix for all parameters */
353
+ const short sfxlen = 4; /* length of the above suffix */
354
+ char zN[32]; /* short names => no dynamic allocations */
355
+ short i,l;
356
+
357
+ /* zPrefix must be tidy and short; also filter out ENV/CGI variables */
358
+ assert( zPrefix != 0 && fossil_islower(zPrefix[0]) );
359
+ l = strnlen( zPrefix, sizeof(zN) );
360
+ assert( l+sfxlen+2 <= sizeof(zN) );
361
+ assert( fossil_no_strange_characters(zPrefix) );
362
+ /* concatenate zPrefix and suffix */
363
+ strcpy( zN, zPrefix );
364
+ strcpy( zN + l, suffix );
365
+ l += sfxlen;
366
+ zN[l+1] = 0; /* nul-terminator after digit's placeholder (if any) */
367
+ zQS = PD("QUERY_STRING","");
368
+ for( i = 0; i <= 9 && i <= nMaxDigit; i++ ){
369
+ const char *zV, *z;
370
+ zN[l] = ( i == 0 ? 0 : '0' + i ); /* ...smpl instead of ...smpl0 */
371
+ zV = PD(zN,"");
372
+ if( zV[0] == 0 || zV[0] == '/' ){
373
+ continue;
374
+ }
375
+ /* require the first path segment to be unfancy ASCII string */
376
+ for( z = zV; z[0] && z[0] != '/' ;){
377
+ if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++;
378
+ else break;
379
+ }
380
+ if( z[0] != 0 && z[0] != '/' )
381
+ continue;
382
+ assert( nSubmenu < count(aSubmenu) );
383
+ if(fossil_islower(zV[0])){
384
+ aSubmenu[nSubmenu].zLabel = mprintf( "%s",zV); /* memory leak? */
385
+ }else{
386
+ aSubmenu[nSubmenu].zLabel = mprintf("✧%s",zV); /* maybe: ◦✧⸰⸎ ✨ */
387
+ }
388
+ if( zQS[0] ){
389
+ aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,zQS);
390
+ }else{
391
+ aSubmenu[nSubmenu].zLink = mprintf("%R/%s",zV);
392
+ }
393
+ nSubmenu++;
394
+ }
395
+}
334396
335397
/*
336398
** Disable or enable the submenu
337399
*/
338400
void style_submenu_enable(int onOff){
339401
--- src/style.c
+++ src/style.c
@@ -329,10 +329,72 @@
329 aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
330 aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
331 nSubmenuCtrl++;
332 }
333 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
335 /*
336 ** Disable or enable the submenu
337 */
338 void style_submenu_enable(int onOff){
339
--- src/style.c
+++ src/style.c
@@ -329,10 +329,72 @@
329 aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
330 aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
331 nSubmenuCtrl++;
332 }
333 }
334
335 /* Add hyperlinks depending on the existence and values of special
336 ** parameters in the request's query string. The names of these
337 ** parameters that are investigated are obtainted by concatenation
338 ** of zPrefix with suffix "smplX", where X is either nothing or
339 ** a positive digit <= nMaxDigit. zPrefix must start with a lowercase
340 ** letter, be short and have no strange characters. A value is
341 ** well-formed if its first filepath segment (separated by '/')
342 ** has no strange characters. The labels of the resulting submenu items
343 ** are equal to the well-formed values that are prepended by "✧"
344 ** unless a value starts with a lowercase letter.
345 ** Malformed values are silently ignored.
346 */
347 void style_submenu_parametric(
348 const char *zPrefix, /* common prefix of the query parameters names */
349 const int nMaxDigit /* maximal digit on the end of param names */
350 ){
351 const char *zQS; /* QUERY_STRING */
352 const char *suffix = "smpl"; /* common suffix for all parameters */
353 const short sfxlen = 4; /* length of the above suffix */
354 char zN[32]; /* short names => no dynamic allocations */
355 short i,l;
356
357 /* zPrefix must be tidy and short; also filter out ENV/CGI variables */
358 assert( zPrefix != 0 && fossil_islower(zPrefix[0]) );
359 l = strnlen( zPrefix, sizeof(zN) );
360 assert( l+sfxlen+2 <= sizeof(zN) );
361 assert( fossil_no_strange_characters(zPrefix) );
362 /* concatenate zPrefix and suffix */
363 strcpy( zN, zPrefix );
364 strcpy( zN + l, suffix );
365 l += sfxlen;
366 zN[l+1] = 0; /* nul-terminator after digit's placeholder (if any) */
367 zQS = PD("QUERY_STRING","");
368 for( i = 0; i <= 9 && i <= nMaxDigit; i++ ){
369 const char *zV, *z;
370 zN[l] = ( i == 0 ? 0 : '0' + i ); /* ...smpl instead of ...smpl0 */
371 zV = PD(zN,"");
372 if( zV[0] == 0 || zV[0] == '/' ){
373 continue;
374 }
375 /* require the first path segment to be unfancy ASCII string */
376 for( z = zV; z[0] && z[0] != '/' ;){
377 if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++;
378 else break;
379 }
380 if( z[0] != 0 && z[0] != '/' )
381 continue;
382 assert( nSubmenu < count(aSubmenu) );
383 if(fossil_islower(zV[0])){
384 aSubmenu[nSubmenu].zLabel = mprintf( "%s",zV); /* memory leak? */
385 }else{
386 aSubmenu[nSubmenu].zLabel = mprintf("✧%s",zV); /* maybe: ◦✧⸰⸎ ✨ */
387 }
388 if( zQS[0] ){
389 aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,zQS);
390 }else{
391 aSubmenu[nSubmenu].zLink = mprintf("%R/%s",zV);
392 }
393 nSubmenu++;
394 }
395 }
396
397 /*
398 ** Disable or enable the submenu
399 */
400 void style_submenu_enable(int onOff){
401
+1
--- src/wiki.c
+++ src/wiki.c
@@ -593,10 +593,11 @@
593593
}else if( rid && g.perm.ApndWiki ){
594594
style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
595595
}
596596
if( g.perm.Hyperlink ){
597597
style_submenu_element("History", "%R/whistory?name=%T", zPageName);
598
+ style_submenu_parametric("wiki",7);
598599
}
599600
}
600601
if( !isPopup ){
601602
style_set_current_page("%T?name=%T", g.zPath, zPageName);
602603
wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
603604
--- src/wiki.c
+++ src/wiki.c
@@ -593,10 +593,11 @@
593 }else if( rid && g.perm.ApndWiki ){
594 style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
595 }
596 if( g.perm.Hyperlink ){
597 style_submenu_element("History", "%R/whistory?name=%T", zPageName);
 
598 }
599 }
600 if( !isPopup ){
601 style_set_current_page("%T?name=%T", g.zPath, zPageName);
602 wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
603
--- src/wiki.c
+++ src/wiki.c
@@ -593,10 +593,11 @@
593 }else if( rid && g.perm.ApndWiki ){
594 style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
595 }
596 if( g.perm.Hyperlink ){
597 style_submenu_element("History", "%R/whistory?name=%T", zPageName);
598 style_submenu_parametric("wiki",7);
599 }
600 }
601 if( !isPopup ){
602 style_set_current_page("%T?name=%T", g.zPath, zPageName);
603 wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
604

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button