| | @@ -366,10 +366,90 @@ |
| 366 | 366 | char *zConfigName = mprintf("%s-image", zImageName); |
| 367 | 367 | url_var(zVarPrefix, zConfigName, zImageName); |
| 368 | 368 | free(zVarPrefix); |
| 369 | 369 | free(zConfigName); |
| 370 | 370 | } |
| 371 | + |
| 372 | +/* |
| 373 | +** Output TEXT with a click-to-copy button next to it. Loads the copybtn.js |
| 374 | +** Javascript module, and generates HTML elements with the following IDs: |
| 375 | +** |
| 376 | +** TARGETID: The <span> wrapper around TEXT. |
| 377 | +** copy-TARGETID: The <span> for the copy button. |
| 378 | +** |
| 379 | +** If the FLIPPED argument is non-zero, the copy button is displayed after TEXT. |
| 380 | +** |
| 381 | +** The COPYLENGTH argument defines the length of the substring of TEXT copied to |
| 382 | +** clipboard: |
| 383 | +** |
| 384 | +** <= 0: No limit (default if the argument is omitted). |
| 385 | +** >= 3: Truncate TEXT after COPYLENGTH (single-byte) characters. |
| 386 | +** 1: Use the "hash-digits" setting as the limit. |
| 387 | +** 2: Use the length appropriate for URLs as the limit (defined at |
| 388 | +** compile-time by FOSSIL_HASH_DIGITS_URL, defaults to 16). |
| 389 | +*/ |
| 390 | +char *copybtn( |
| 391 | + int bOutputCGI, /* Don't return result, but send to cgi_printf(). */ |
| 392 | + const char *zTargetId, /* The TARGETID argument. */ |
| 393 | + int bFlipped, /* The FLIPPED argument. */ |
| 394 | + int cchLength, /* The COPYLENGTH argument. */ |
| 395 | + const char *zTextFmt, /* Formatting of the TEXT argument (htmlized). */ |
| 396 | + ... /* Formatting parameters of the TEXT argument. */ |
| 397 | +){ |
| 398 | + va_list ap; |
| 399 | + char *zText; |
| 400 | + char *zResult = 0; |
| 401 | + va_start(ap,zTextFmt); |
| 402 | + zText = vmprintf(zTextFmt/*works-like:?*/,ap); |
| 403 | + va_end(ap); |
| 404 | + if( cchLength==1 ) cchLength = hash_digits(0); |
| 405 | + else if( cchLength==2 ) cchLength = hash_digits(1); |
| 406 | + if( !bFlipped ){ |
| 407 | + const char *zBtnFmt = |
| 408 | + "<span " |
| 409 | + "class=\"copy-button\" " |
| 410 | + "id=\"copy-%h\" " |
| 411 | + "data-copytarget=\"%h\" " |
| 412 | + "data-copylength=\"%d\">" |
| 413 | + "</span>" |
| 414 | + "<span id=\"%h\">" |
| 415 | + "%s" |
| 416 | + "</span>"; |
| 417 | + if( bOutputCGI ){ |
| 418 | + cgi_printf( |
| 419 | + zBtnFmt/*works-like:"%h%h%d%h%s"*/, |
| 420 | + zTargetId,zTargetId,cchLength,zTargetId,zText); |
| 421 | + }else{ |
| 422 | + zResult = mprintf( |
| 423 | + zBtnFmt/*works-like:"%h%h%d%h%s"*/, |
| 424 | + zTargetId,zTargetId,cchLength,zTargetId,zText); |
| 425 | + } |
| 426 | + }else{ |
| 427 | + const char *zBtnFmt = |
| 428 | + "<span id=\"%h\">" |
| 429 | + "%s" |
| 430 | + "</span>" |
| 431 | + "<span " |
| 432 | + "class=\"copy-button copy-button-flipped\" " |
| 433 | + "id=\"copy-%h\" " |
| 434 | + "data-copytarget=\"%h\" " |
| 435 | + "data-copylength=\"%d\">" |
| 436 | + "</span>"; |
| 437 | + if( bOutputCGI ){ |
| 438 | + cgi_printf( |
| 439 | + zBtnFmt/*works-like:"%h%s%h%h%d"*/, |
| 440 | + zTargetId,zText,zTargetId,zTargetId,cchLength); |
| 441 | + }else{ |
| 442 | + zResult = mprintf( |
| 443 | + zBtnFmt/*works-like:"%h%s%h%h%d"*/, |
| 444 | + zTargetId,zText,zTargetId,zTargetId,cchLength); |
| 445 | + } |
| 446 | + } |
| 447 | + free(zText); |
| 448 | + style_copybtn(); |
| 449 | + return zResult; |
| 450 | +} |
| 371 | 451 | |
| 372 | 452 | /* |
| 373 | 453 | ** Return a random nonce that is stored in static space. For a particular |
| 374 | 454 | ** run, the same nonce is always returned. |
| 375 | 455 | */ |
| | @@ -543,11 +623,11 @@ |
| 543 | 623 | } |
| 544 | 624 | |
| 545 | 625 | /* |
| 546 | 626 | ** Indicate that the copy button javascript is needed. |
| 547 | 627 | */ |
| 548 | | -void style_copy_button(void){ |
| 628 | +void style_copybtn(void){ |
| 549 | 629 | needCopyBtnJs = 1; |
| 550 | 630 | } |
| 551 | 631 | |
| 552 | 632 | /* |
| 553 | 633 | ** Generate code to load a single javascript file |
| 554 | 634 | |