Fossil

Diff
Login

Differences From Artifact [852a72cc73]:

To Artifact [af126c545b]:


337
338
339
340
341
342
343
344

345
346
347
348













349
350
351
352
353
354
355
337
338
339
340
341
342
343

344
345



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365







-
+

-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







** parameters that are investigated are obtainted by concatenation of
** the caller-provided zPrefix with suffix "smplX", where X is either
** nothing or a positive digit. zPrefix must start with a lowercase
** letter, be short and have no strange characters. Parameter's value
** is well-formed if its first filepath segment (separated by '/')
** has no strange characters. Malformed values are silently ignored.
**
** The text for the resulting submenu item equals to the value of the
** The text for the resulting submenu label equals to the value of the
** parameter modulus some prettification for better UX:
** "✧" symbol is prepended unless parameter's value starts with a
** lowercase letter or contains '/', also underscores in the first
** path segment are replaced with spaces.
**  1)  If a parameter's value starts with a lowercase letter and
**      contains '/' then it goes unchanged into the user-visible label.
**  2a) If the first letter is uppercase then the label is
**      truncated at the first '/' (if any),
**  2b) otherwise the first letter is capitalized.
**  3)  Underscores in the first path segment are replaced with spaces.
**  4)  If the resulting label starts with an uppercase letter
**      then it is prepended with "✧" symbol for explicit distinction
**      from the built-in labels
**
** Important security-related note:
**   zLabel and zLink are formatted using %s because it is expected that
**   style_finish_page() provides propper escaping via %h format.
*/
void style_submenu_parametric(
  const char *zPrefix   /* common prefix of the query parameters names */
){
  static const char *suffix = "smpl"; /* common suffix for param names */
  static const short sfxlen =  4;     /* length of the above suffix    */
  const char *zQS;     /* QUERY_STRING */
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391







-
+







  l += sfxlen;
  zN[l+1] = 0; /* nul-terminator after digit's placeholder (if any) */
  zQS = PD("QUERY_STRING","");
  for( i = 0; i <= 9; i++ ){
    const char *zV, *z;
    zN[l] = ( i == 0 ?  0 : '0' + i ); /* ...smpl instead of ...smpl0 */
    zV = PD(zN,"");
    if( zV[0] == 0 || zV[0] == '/' ){
    if( zV[0] == 0 || zV[0] == '/' || zV[0] == '_' || zV[0] == '-' ){
      continue;
    }
    /* require the first path segment to be unfancy ASCII string */
    for( z = zV; z[0] && z[0] != '/' ;){
      if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++;
      else break;
    }
389
390
391
392
393
394
395
396

397




398
399
400
401
402
403
404
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418







-
+

+
+
+
+







      ** this clearly distincts it from the built-in elements */
      static const char *mark = "✧";
      char *z = mprintf("%s%s",mark,zV);
      aSubmenu[nSubmenu].zLabel = z;
      /* also prettify the first segment */
      z += strlen(mark);
      z[0] = fossil_toupper(z[0]);
      for(; z[0]!=0 && z[0]!='/'; z++ ){
      for(; z[0]!=0; z++ ){
        if( z[0]=='_' ) z[0] = ' ';
        else if( z[0] == '/' ){     /* show just the first segment */
          z[0] = 0;
          break;
        }
      }
    }
    if( zQS[0] ){
      aSubmenu[nSubmenu].zLink  = mprintf("%R/%s?%s",zV,zQS);
    }else{
      aSubmenu[nSubmenu].zLink  = mprintf("%R/%s",zV);
    }
977
978
979
980
981
982
983




984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008







+
+
+
+







      cgi_tag_query_parameter("udc");
    }
    @ <div class="submenu">
    if( nSubmenu>0 ){
      qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
      for(i=0; i<nSubmenu; i++){
        struct Submenu *p = &aSubmenu[i];
        /* switching away from the %h formatting below might be dangerous
        ** because some places use %s to compose zLabel and zLink;
        ** e.g. /rptview page and the style_submenu_parametic() function
        */
        if( p->zLink==0 ){
          @ <span class="label">%h(p->zLabel)</span>
        }else{
          @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
        }
      }
    }