@@ -32,10 +32,11 @@
32 32 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** style_submenu_entry()
33 33 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** style_submenu_checkbox()
34 34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** style_submenu_binary()
35 35 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** style_submenu_multichoice()
36 36 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** style_submenu_sql()
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** style_submenu_parametric()
37 38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
**
38 39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** prior to calling style_finish_page(). The style_finish_page() routine
39 40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** will generate the appropriate HTML text just below the main
40 41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** menu.
41 42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
@@ -329,10 +330,104 @@
329 330 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
330 331 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
331 332 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
nSubmenuCtrl++;
332 333 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
333 334 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
335 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
336 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Add hyperlinks depending on the existence and values of special
337 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** parameters in the request's query string. The names of a query's
338 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** parameters that are investigated are obtainted by concatenation of
339 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** the caller-provided zPrefix with suffix "smplXY", where optional
340 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** ending XY consists of a digit X from the set {1,2,3,4,5} and an
341 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** optional letter Y which (if present) must be either 'a' or 's'.
342 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** zPrefix must start with a lowercase letter,
343 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** be short and have no strange characters. Parameter's value
344 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** is well-formed if its first filepath segment (separated by '/')
345 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** has no strange characters. Malformed values are silently ignored.
346 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
347 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** The text for the resulting submenu label equals to the value of the
348 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** parameter modulus some prettification for better UX:
349 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 1) If a parameter's value starts with a lowercase letter and
350 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** contains '/' then it goes unchanged into the user-visible label.
351 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 2a) If the first letter is uppercase then the label is
352 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** truncated at the first '/' (if any),
353 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 2b) otherwise the first letter is capitalized.
354 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 3) Underscores in the first path segment are replaced with spaces.
355 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 4) If the resulting label starts with an uppercase letter
356 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** then it is prepended with "✧" symbol for explicit distinction
357 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** from the built-in labels
358 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
359 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Important security-related note:
360 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** zLabel and zLink are formatted using %s because it is expected that
361 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** style_finish_page() provides propper escaping via %h format.
362 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
363 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ void style_submenu_parametric(
364 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const char *zPrefix /* common prefix of the query parameters names */
365 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ){
366 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ static const char *suffix = "smpl"; /* common suffix for param names */
367 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ static const short sfxlen = 4; /* length of the above suffix */
368 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ static const char sfxext[3] = {'a','s',0}; /* extra suffix ending */
369 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const char *zQS; /* QUERY_STRING */
370 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char zN[32]; /* buffer for parameter names to probe */
371 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ short i,j,l;
372 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
373 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* zPrefix must be tidy and short; also filter out ENV/CGI variables */
374 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert( zPrefix != 0 && fossil_islower(zPrefix[0]) );
375 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ l = strnlen( zPrefix, sizeof(zN) );
376 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert( l+sfxlen+3 <= sizeof(zN) );
377 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert( fossil_no_strange_characters(zPrefix) );
378 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* concatenate zPrefix and suffix */
379 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ strcpy( zN, zPrefix );
380 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ strcpy( zN + l, suffix );
381 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ l += sfxlen;
382 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zN[l+2] = 0; /* nul-terminator after ...smplXY suffix */
383 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zQS = PD("QUERY_STRING","");
384 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for( i = 0; i <= 5; i++ ){
385 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zN[l] = ( i == 0 ? 0 : '0' + i ); /* ...smpl instead of ...smpl0 */
386 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for( j = (i ? 0 : sizeof(sfxext)-1); j < sizeof(sfxext); j++ ){
387 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const char *zV, *z;
388 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zN[l+1] = sfxext[j];
389 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zV = PD(zN,"");
390 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( zV[0] == 0 || zV[0] == '/' || zV[0] == '_' || zV[0] == '-' ){
391 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ continue;
392 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
393 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* require the first path segment to be unfancy ASCII string */
394 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for( z = zV; z[0] && z[0] != '/' ;){
395 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++;
396 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else break;
397 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
398 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( z[0] != 0 && z[0] != '/' )
399 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ continue;
400 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert( nSubmenu < count(aSubmenu) );
401 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(fossil_islower(zV[0]) && z[0]=='/'){
402 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ aSubmenu[nSubmenu].zLabel = mprintf( "%s",zV); /* memory leak? */
403 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else{
404 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* prepend a label with an unobtrusive symbol that "sorts-last";
405 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** this clearly distincts it from the built-in elements */
406 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ static const char *mark = "✧";
407 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *z = mprintf("%s%s",mark,zV);
408 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ aSubmenu[nSubmenu].zLabel = z;
409 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* also prettify the first segment */
410 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ z += strlen(mark);
411 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ z[0] = fossil_toupper(z[0]);
412 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for(; z[0]!=0; z++ ){
413 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( z[0]=='_' ) z[0] = ' ';
414 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else if( z[0] == '/' ){ /* show just the first segment */
415 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ z[0] = 0;
416 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ break;
417 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
418 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
419 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
420 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( zQS[0] ){
421 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,zQS);
422 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else{
423 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ aSubmenu[nSubmenu].zLink = mprintf("%R/%s",zV);
424 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
425 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ nSubmenu++;
426 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
427 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
428 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
334 429 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
335 430 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
336 431 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Disable or enable the submenu
337 432 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
338 433 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
void style_submenu_enable(int onOff){
@@ -907,11 +1002,11 @@
907 1002 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
908 1003 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
for(i=0; i<nSubmenu; i++){
909 1004 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
struct Submenu *p = &aSubmenu[i];
910 1005 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* switching away from the %h formatting below might be dangerous
911 1006 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** because some places use %s to compose zLabel and zLink;
912 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** e.g. /rptview page
1007 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** e.g. /rptview page and the style_submenu_parametic() function
913 1008 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
914 1009 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( p->zLink==0 ){
915 1010 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@ <span class="label">%h(p->zLabel)</span>
916 1011 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else{
917 1012 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
918 1013 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!