Fossil SCM

Define the spacing between copy buttons and adjacent elements by CSS rules, so that (0) no additional white space (nbsp) needs to be inserted into the HTML document, (1) the spacing can be modified by CSS rules, and (2) the copy buttons can be hidden by CSS rules.

florian 2019-06-05 07:47 copybtn.js-tweaks
Commit 63ebcafb19dd004ba246149fe1ae7018345db2ba7af70209fdee1bc293702845
+2 -1
--- src/copybtn.js
+++ src/copybtn.js
@@ -21,13 +21,14 @@
2121
** HTML snippet for statically created buttons:
2222
**
2323
** <span class="copy-button" id="copy-<idTarget>"
2424
** data-copytarget="<idTarget>" data-copylength="<cchLength>"></span>
2525
*/
26
-function makeCopyButton(idTarget,cchLength){
26
+function makeCopyButton(idTarget,bFlipped,cchLength){
2727
var elButton = document.createElement("span");
2828
elButton.className = "copy-button";
29
+ if( bFlipped ) elButton.className += " copy-button-flipped";
2930
elButton.id = "copy-" + idTarget;
3031
initCopyButton(elButton,idTarget,cchLength);
3132
return elButton;
3233
}
3334
function initCopyButtonById(idButton,idTarget,cchLength){
3435
--- src/copybtn.js
+++ src/copybtn.js
@@ -21,13 +21,14 @@
21 ** HTML snippet for statically created buttons:
22 **
23 ** <span class="copy-button" id="copy-<idTarget>"
24 ** data-copytarget="<idTarget>" data-copylength="<cchLength>"></span>
25 */
26 function makeCopyButton(idTarget,cchLength){
27 var elButton = document.createElement("span");
28 elButton.className = "copy-button";
 
29 elButton.id = "copy-" + idTarget;
30 initCopyButton(elButton,idTarget,cchLength);
31 return elButton;
32 }
33 function initCopyButtonById(idButton,idTarget,cchLength){
34
--- src/copybtn.js
+++ src/copybtn.js
@@ -21,13 +21,14 @@
21 ** HTML snippet for statically created buttons:
22 **
23 ** <span class="copy-button" id="copy-<idTarget>"
24 ** data-copytarget="<idTarget>" data-copylength="<cchLength>"></span>
25 */
26 function makeCopyButton(idTarget,bFlipped,cchLength){
27 var elButton = document.createElement("span");
28 elButton.className = "copy-button";
29 if( bFlipped ) elButton.className += " copy-button-flipped";
30 elButton.id = "copy-" + idTarget;
31 initCopyButton(elButton,idTarget,cchLength);
32 return elButton;
33 }
34 function initCopyButtonById(idButton,idTarget,cchLength){
35
--- src/default_css.txt
+++ src/default_css.txt
@@ -771,15 +771,21 @@
771771
}
772772
.copy-button {
773773
display: inline-block;
774774
width: 14px;
775775
height: 14px;
776
- margin: -2px 0 0 0;
776
+//Note: .24em is slightly smaller than the average width of a normal space.
777
+ margin: -2px .24em 0 0;
777778
padding: 0;
778779
border: 0;
779780
vertical-align: middle;
780781
//Note: the mkcss utility does not support line breaks in data URIs.
781782
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath style='fill: black; opacity:0' d='M 14 14 H 0 V 0 h 14 v 14 z'/%3E%3Cpath style='fill:rgb(240,240,240)' d='M 1 0 h 6.6 l 2 2 h 1 l 3.4 3.4 v 8.6 h -10 v -2 h -3 z'/%3E%3Cpath style='fill:rgb(64,64,64)' d='M 2 1 h 5 l 3 3 v 7 h -8 z'/%3E%3Cpath style='fill:rgb(248,248,248)' d='M 3 2 h 3.6 l 2.4 2.4 v 5.6 h -6 z'/%3E%3Cpath style='fill:rgb(80,128,208)' d='M 4 5 h 4 v 1 h -4 z m 0 2 h 4 v 1 h -4 z'/%3E%3Cpath style='fill:rgb(64,64,64)' d='M 5 3 h 5 l 3 3 v 7 h -8 z'/%3E%3Cpath style='fill:rgb(248,248,248)' d='M 10 4.4 v 1.6 h 1.6 z m -4 -0.6 h 3 v 3 h -3 z m 0 3 h 6 v 5.4 h -6 z'/%3E%3Cpath style='fill:rgb(80,128,208)' d='M 7 8 h 4 v 1 h -4 z m 0 2 h 4 v 1 h -4 z'/%3E%3C/svg%3E");
782783
background-repeat: no-repeat;
783784
background-position: center;
784785
cursor: pointer;
786
+}
787
+.copy-button-flipped {
788
+//Note: .16em is suitable for element grouping.
789
+ margin-left: .16em;
790
+ margin-right: 0;
785791
}
786792
--- src/default_css.txt
+++ src/default_css.txt
@@ -771,15 +771,21 @@
771 }
772 .copy-button {
773 display: inline-block;
774 width: 14px;
775 height: 14px;
776 margin: -2px 0 0 0;
 
777 padding: 0;
778 border: 0;
779 vertical-align: middle;
780 //Note: the mkcss utility does not support line breaks in data URIs.
781 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath style='fill: black; opacity:0' d='M 14 14 H 0 V 0 h 14 v 14 z'/%3E%3Cpath style='fill:rgb(240,240,240)' d='M 1 0 h 6.6 l 2 2 h 1 l 3.4 3.4 v 8.6 h -10 v -2 h -3 z'/%3E%3Cpath style='fill:rgb(64,64,64)' d='M 2 1 h 5 l 3 3 v 7 h -8 z'/%3E%3Cpath style='fill:rgb(248,248,248)' d='M 3 2 h 3.6 l 2.4 2.4 v 5.6 h -6 z'/%3E%3Cpath style='fill:rgb(80,128,208)' d='M 4 5 h 4 v 1 h -4 z m 0 2 h 4 v 1 h -4 z'/%3E%3Cpath style='fill:rgb(64,64,64)' d='M 5 3 h 5 l 3 3 v 7 h -8 z'/%3E%3Cpath style='fill:rgb(248,248,248)' d='M 10 4.4 v 1.6 h 1.6 z m -4 -0.6 h 3 v 3 h -3 z m 0 3 h 6 v 5.4 h -6 z'/%3E%3Cpath style='fill:rgb(80,128,208)' d='M 7 8 h 4 v 1 h -4 z m 0 2 h 4 v 1 h -4 z'/%3E%3C/svg%3E");
782 background-repeat: no-repeat;
783 background-position: center;
784 cursor: pointer;
 
 
 
 
 
785 }
786
--- src/default_css.txt
+++ src/default_css.txt
@@ -771,15 +771,21 @@
771 }
772 .copy-button {
773 display: inline-block;
774 width: 14px;
775 height: 14px;
776 //Note: .24em is slightly smaller than the average width of a normal space.
777 margin: -2px .24em 0 0;
778 padding: 0;
779 border: 0;
780 vertical-align: middle;
781 //Note: the mkcss utility does not support line breaks in data URIs.
782 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath style='fill: black; opacity:0' d='M 14 14 H 0 V 0 h 14 v 14 z'/%3E%3Cpath style='fill:rgb(240,240,240)' d='M 1 0 h 6.6 l 2 2 h 1 l 3.4 3.4 v 8.6 h -10 v -2 h -3 z'/%3E%3Cpath style='fill:rgb(64,64,64)' d='M 2 1 h 5 l 3 3 v 7 h -8 z'/%3E%3Cpath style='fill:rgb(248,248,248)' d='M 3 2 h 3.6 l 2.4 2.4 v 5.6 h -6 z'/%3E%3Cpath style='fill:rgb(80,128,208)' d='M 4 5 h 4 v 1 h -4 z m 0 2 h 4 v 1 h -4 z'/%3E%3Cpath style='fill:rgb(64,64,64)' d='M 5 3 h 5 l 3 3 v 7 h -8 z'/%3E%3Cpath style='fill:rgb(248,248,248)' d='M 10 4.4 v 1.6 h 1.6 z m -4 -0.6 h 3 v 3 h -3 z m 0 3 h 6 v 5.4 h -6 z'/%3E%3Cpath style='fill:rgb(80,128,208)' d='M 7 8 h 4 v 1 h -4 z m 0 2 h 4 v 1 h -4 z'/%3E%3C/svg%3E");
783 background-repeat: no-repeat;
784 background-position: center;
785 cursor: pointer;
786 }
787 .copy-button-flipped {
788 //Note: .16em is suitable for element grouping.
789 margin-left: .16em;
790 margin-right: 0;
791 }
792
+1 -3
--- src/graph.js
+++ src/graph.js
@@ -628,13 +628,11 @@
628628
}
629629
tooltipObj.style.borderColor =
630630
tooltipObj.style.color = s.getPropertyValue('color')
631631
tooltipObj.style.visibility = "hidden"
632632
tooltipObj.innerHTML = html
633
- tooltipObj.appendChild(document.createTextNode(' '));
634
- tooltipObj.appendChild(
635
- makeCopyButton("tooltip-link",0));
633
+ tooltipObj.appendChild(makeCopyButton("tooltip-link",true,0));
636634
tooltipObj.style.display = "inline"
637635
tooltipObj.style.position = "absolute"
638636
var x = tooltipInfo.posX + 4 + window.pageXOffset
639637
- absoluteX(tooltipObj.offsetParent)
640638
tooltipObj.style.left = x+"px"
641639
--- src/graph.js
+++ src/graph.js
@@ -628,13 +628,11 @@
628 }
629 tooltipObj.style.borderColor =
630 tooltipObj.style.color = s.getPropertyValue('color')
631 tooltipObj.style.visibility = "hidden"
632 tooltipObj.innerHTML = html
633 tooltipObj.appendChild(document.createTextNode(' '));
634 tooltipObj.appendChild(
635 makeCopyButton("tooltip-link",0));
636 tooltipObj.style.display = "inline"
637 tooltipObj.style.position = "absolute"
638 var x = tooltipInfo.posX + 4 + window.pageXOffset
639 - absoluteX(tooltipObj.offsetParent)
640 tooltipObj.style.left = x+"px"
641
--- src/graph.js
+++ src/graph.js
@@ -628,13 +628,11 @@
628 }
629 tooltipObj.style.borderColor =
630 tooltipObj.style.color = s.getPropertyValue('color')
631 tooltipObj.style.visibility = "hidden"
632 tooltipObj.innerHTML = html
633 tooltipObj.appendChild(makeCopyButton("tooltip-link",true,0));
 
 
634 tooltipObj.style.display = "inline"
635 tooltipObj.style.position = "absolute"
636 var x = tooltipInfo.posX + 4 + window.pageXOffset
637 - absoluteX(tooltipObj.offsetParent)
638 tooltipObj.style.left = x+"px"
639
+4 -4
--- src/info.c
+++ src/info.c
@@ -765,11 +765,11 @@
765765
while( db_step(&q2)==SQLITE_ROW ){
766766
const char *zTagName = db_column_text(&q2, 0);
767767
if( fossil_strcmp(zTagName,zBrName)==0 ){
768768
@ | <span class="copy-button" id="copy-name-br"
769769
@ data-copytarget="name-br" data-copylength="0">
770
- @ </span>&nbsp;<span id="name-br"><!--
770
+ @ </span><span id="name-br"><!--
771771
@ -->%z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
772772
@ </span>
773773
if( wiki_tagid2("branch",zTagName)!=0 ){
774774
blob_appendf(&wiki_read_links, " | %z%h</a>",
775775
href("%R/wiki?name=branch/%h",zTagName), zTagName);
@@ -800,11 +800,11 @@
800800
@ </tr>
801801
802802
@ <tr><th>%s(hname_alg(nUuid)):</th><td>
803803
@ <span class="copy-button" id="copy-hash-ci"
804804
@ data-copytarget="hash-ci" data-copylength="%d(hash_digits(1))">
805
- @ </span>&nbsp;<span id="hash-ci">%.32s(zUuid)<wbr>%s(zUuid+32)</span>
805
+ @ </span><span id="hash-ci">%.32s(zUuid)<wbr>%s(zUuid+32)</span>
806806
if( g.perm.Setup ){
807807
@ (Record ID: %d(rid))
808808
}
809809
@ </td></tr>
810810
@ <tr><th>User&nbsp;&amp;&nbsp;Date:</th><td>
@@ -2195,13 +2195,13 @@
21952195
style_copy_button();
21962196
@ <h2>Artifact
21972197
@ <span class="copy-button" id="copy-hash-ar"
21982198
@ data-copytarget="hash-ar" data-copylength="%d(hash_digits(1))">
21992199
if( g.perm.Setup ){
2200
- @ </span>&nbsp;<span id="hash-ar">%s(zUuid)</span> (%d(rid)):</h2>
2200
+ @ </span><span id="hash-ar">%s(zUuid)</span> (%d(rid)):</h2>
22012201
}else{
2202
- @ </span>&nbsp;<span id="hash-ar">%s(zUuid)</span>:</h2>
2202
+ @ </span><span id="hash-ar">%s(zUuid)</span>:</h2>
22032203
}
22042204
}
22052205
blob_zero(&downloadName);
22062206
asText = P("txt")!=0;
22072207
if( asText ) objdescFlags &= ~OBJDESC_BASE;
22082208
--- src/info.c
+++ src/info.c
@@ -765,11 +765,11 @@
765 while( db_step(&q2)==SQLITE_ROW ){
766 const char *zTagName = db_column_text(&q2, 0);
767 if( fossil_strcmp(zTagName,zBrName)==0 ){
768 @ | <span class="copy-button" id="copy-name-br"
769 @ data-copytarget="name-br" data-copylength="0">
770 @ </span>&nbsp;<span id="name-br"><!--
771 @ -->%z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
772 @ </span>
773 if( wiki_tagid2("branch",zTagName)!=0 ){
774 blob_appendf(&wiki_read_links, " | %z%h</a>",
775 href("%R/wiki?name=branch/%h",zTagName), zTagName);
@@ -800,11 +800,11 @@
800 @ </tr>
801
802 @ <tr><th>%s(hname_alg(nUuid)):</th><td>
803 @ <span class="copy-button" id="copy-hash-ci"
804 @ data-copytarget="hash-ci" data-copylength="%d(hash_digits(1))">
805 @ </span>&nbsp;<span id="hash-ci">%.32s(zUuid)<wbr>%s(zUuid+32)</span>
806 if( g.perm.Setup ){
807 @ (Record ID: %d(rid))
808 }
809 @ </td></tr>
810 @ <tr><th>User&nbsp;&amp;&nbsp;Date:</th><td>
@@ -2195,13 +2195,13 @@
2195 style_copy_button();
2196 @ <h2>Artifact
2197 @ <span class="copy-button" id="copy-hash-ar"
2198 @ data-copytarget="hash-ar" data-copylength="%d(hash_digits(1))">
2199 if( g.perm.Setup ){
2200 @ </span>&nbsp;<span id="hash-ar">%s(zUuid)</span> (%d(rid)):</h2>
2201 }else{
2202 @ </span>&nbsp;<span id="hash-ar">%s(zUuid)</span>:</h2>
2203 }
2204 }
2205 blob_zero(&downloadName);
2206 asText = P("txt")!=0;
2207 if( asText ) objdescFlags &= ~OBJDESC_BASE;
2208
--- src/info.c
+++ src/info.c
@@ -765,11 +765,11 @@
765 while( db_step(&q2)==SQLITE_ROW ){
766 const char *zTagName = db_column_text(&q2, 0);
767 if( fossil_strcmp(zTagName,zBrName)==0 ){
768 @ | <span class="copy-button" id="copy-name-br"
769 @ data-copytarget="name-br" data-copylength="0">
770 @ </span><span id="name-br"><!--
771 @ -->%z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
772 @ </span>
773 if( wiki_tagid2("branch",zTagName)!=0 ){
774 blob_appendf(&wiki_read_links, " | %z%h</a>",
775 href("%R/wiki?name=branch/%h",zTagName), zTagName);
@@ -800,11 +800,11 @@
800 @ </tr>
801
802 @ <tr><th>%s(hname_alg(nUuid)):</th><td>
803 @ <span class="copy-button" id="copy-hash-ci"
804 @ data-copytarget="hash-ci" data-copylength="%d(hash_digits(1))">
805 @ </span><span id="hash-ci">%.32s(zUuid)<wbr>%s(zUuid+32)</span>
806 if( g.perm.Setup ){
807 @ (Record ID: %d(rid))
808 }
809 @ </td></tr>
810 @ <tr><th>User&nbsp;&amp;&nbsp;Date:</th><td>
@@ -2195,13 +2195,13 @@
2195 style_copy_button();
2196 @ <h2>Artifact
2197 @ <span class="copy-button" id="copy-hash-ar"
2198 @ data-copytarget="hash-ar" data-copylength="%d(hash_digits(1))">
2199 if( g.perm.Setup ){
2200 @ </span><span id="hash-ar">%s(zUuid)</span> (%d(rid)):</h2>
2201 }else{
2202 @ </span><span id="hash-ar">%s(zUuid)</span>:</h2>
2203 }
2204 }
2205 blob_zero(&downloadName);
2206 asText = P("txt")!=0;
2207 if( asText ) objdescFlags &= ~OBJDESC_BASE;
2208
+36 -18
--- src/th_main.c
+++ src/th_main.c
@@ -992,17 +992,19 @@
992992
}
993993
return TH_OK;
994994
}
995995
996996
/*
997
-** TH1 command: copybtn TARGETID TEXT ?COPYLENGTH?
997
+** TH1 command: copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
998998
**
999999
** Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
10001000
** Javascript module, and generates HTML elements with the following IDs:
10011001
**
10021002
** TARGETID: The <span> wrapper around TEXT.
10031003
** copy-TARGETID: The <span> for the copy button.
1004
+**
1005
+** If the FLIPPED argument is non-zero, the copy button is displayed after TEXT.
10041006
**
10051007
** The optional COPYLENGTH argument defines the length of the substring of TEXT
10061008
** copied to clipboard:
10071009
**
10081010
** <= 0: No limit (default if the argument is omitted).
@@ -1016,35 +1018,51 @@
10161018
void *p,
10171019
int argc,
10181020
const char **argv,
10191021
int *argl
10201022
){
1021
- if( argc!=3 && argc!=4 ){
1022
- return Th_WrongNumArgs(interp, "copybtn TARGETID TEXT COPYLENGTH");
1023
+ if( argc!=4 && argc!=5 ){
1024
+ return Th_WrongNumArgs(interp,
1025
+ "copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?");
10231026
}
10241027
if( enableOutput ){
1028
+ int flipped = 0;
10251029
int copylength = 0;
10261030
char *zTargetId, *zText, *zResult;
1027
- if( argc==4 && Th_ToInt(interp, argv[3], argl[3], &copylength) ){
1028
- return TH_ERROR;
1031
+ if( Th_ToInt(interp, argv[2], argl[2], &flipped) ) return TH_ERROR;
1032
+ if( argc==5 ){
1033
+ if( Th_ToInt(interp, argv[4], argl[4], &copylength) ) return TH_ERROR;
10291034
}
10301035
if( copylength==1 ) copylength = hash_digits(0);
10311036
else if( copylength==2 ) copylength = hash_digits(1);
10321037
zTargetId = htmlize((char*)argv[1], argl[1]);
1033
- zText = htmlize((char*)argv[2], argl[2]);
1034
- zResult = mprintf(
1035
- "<span "
1036
- "class=\"copy-button\" "
1037
- "id=\"copy-%s\" "
1038
- "data-copytarget=\"%s\" "
1039
- "data-copylength=\"%d\">"
1040
- "</span>"
1041
- "&nbsp;"
1042
- "<span id=\"%s\">"
1043
- "%s"
1044
- "</span>",
1045
- zTargetId, zTargetId, copylength, zTargetId, zText);
1038
+ zText = htmlize((char*)argv[3], argl[3]);
1039
+ if( !flipped ){
1040
+ zResult = mprintf(
1041
+ "<span "
1042
+ "class=\"copy-button\" "
1043
+ "id=\"copy-%s\" "
1044
+ "data-copytarget=\"%s\" "
1045
+ "data-copylength=\"%d\">"
1046
+ "</span>"
1047
+ "<span id=\"%s\">"
1048
+ "%s"
1049
+ "</span>",
1050
+ zTargetId, zTargetId, copylength, zTargetId, zText);
1051
+ }else{
1052
+ zResult = mprintf(
1053
+ "<span id=\"%s\">"
1054
+ "%s"
1055
+ "</span>"
1056
+ "<span "
1057
+ "class=\"copy-button copy-button-flipped\" "
1058
+ "id=\"copy-%s\" "
1059
+ "data-copytarget=\"%s\" "
1060
+ "data-copylength=\"%d\">"
1061
+ "</span>",
1062
+ zTargetId, zText, zTargetId, zTargetId, copylength);
1063
+ }
10461064
free(zTargetId);
10471065
free(zText);
10481066
style_copy_button();
10491067
sendText(zResult, -1, 0);
10501068
free(zResult);
10511069
--- src/th_main.c
+++ src/th_main.c
@@ -992,17 +992,19 @@
992 }
993 return TH_OK;
994 }
995
996 /*
997 ** TH1 command: copybtn TARGETID TEXT ?COPYLENGTH?
998 **
999 ** Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
1000 ** Javascript module, and generates HTML elements with the following IDs:
1001 **
1002 ** TARGETID: The <span> wrapper around TEXT.
1003 ** copy-TARGETID: The <span> for the copy button.
 
 
1004 **
1005 ** The optional COPYLENGTH argument defines the length of the substring of TEXT
1006 ** copied to clipboard:
1007 **
1008 ** <= 0: No limit (default if the argument is omitted).
@@ -1016,35 +1018,51 @@
1016 void *p,
1017 int argc,
1018 const char **argv,
1019 int *argl
1020 ){
1021 if( argc!=3 && argc!=4 ){
1022 return Th_WrongNumArgs(interp, "copybtn TARGETID TEXT COPYLENGTH");
 
1023 }
1024 if( enableOutput ){
 
1025 int copylength = 0;
1026 char *zTargetId, *zText, *zResult;
1027 if( argc==4 && Th_ToInt(interp, argv[3], argl[3], &copylength) ){
1028 return TH_ERROR;
 
1029 }
1030 if( copylength==1 ) copylength = hash_digits(0);
1031 else if( copylength==2 ) copylength = hash_digits(1);
1032 zTargetId = htmlize((char*)argv[1], argl[1]);
1033 zText = htmlize((char*)argv[2], argl[2]);
1034 zResult = mprintf(
1035 "<span "
1036 "class=\"copy-button\" "
1037 "id=\"copy-%s\" "
1038 "data-copytarget=\"%s\" "
1039 "data-copylength=\"%d\">"
1040 "</span>"
1041 "&nbsp;"
1042 "<span id=\"%s\">"
1043 "%s"
1044 "</span>",
1045 zTargetId, zTargetId, copylength, zTargetId, zText);
 
 
 
 
 
 
 
 
 
 
 
 
 
1046 free(zTargetId);
1047 free(zText);
1048 style_copy_button();
1049 sendText(zResult, -1, 0);
1050 free(zResult);
1051
--- src/th_main.c
+++ src/th_main.c
@@ -992,17 +992,19 @@
992 }
993 return TH_OK;
994 }
995
996 /*
997 ** TH1 command: copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
998 **
999 ** Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
1000 ** Javascript module, and generates HTML elements with the following IDs:
1001 **
1002 ** TARGETID: The <span> wrapper around TEXT.
1003 ** copy-TARGETID: The <span> for the copy button.
1004 **
1005 ** If the FLIPPED argument is non-zero, the copy button is displayed after TEXT.
1006 **
1007 ** The optional COPYLENGTH argument defines the length of the substring of TEXT
1008 ** copied to clipboard:
1009 **
1010 ** <= 0: No limit (default if the argument is omitted).
@@ -1016,35 +1018,51 @@
1018 void *p,
1019 int argc,
1020 const char **argv,
1021 int *argl
1022 ){
1023 if( argc!=4 && argc!=5 ){
1024 return Th_WrongNumArgs(interp,
1025 "copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?");
1026 }
1027 if( enableOutput ){
1028 int flipped = 0;
1029 int copylength = 0;
1030 char *zTargetId, *zText, *zResult;
1031 if( Th_ToInt(interp, argv[2], argl[2], &flipped) ) return TH_ERROR;
1032 if( argc==5 ){
1033 if( Th_ToInt(interp, argv[4], argl[4], &copylength) ) return TH_ERROR;
1034 }
1035 if( copylength==1 ) copylength = hash_digits(0);
1036 else if( copylength==2 ) copylength = hash_digits(1);
1037 zTargetId = htmlize((char*)argv[1], argl[1]);
1038 zText = htmlize((char*)argv[3], argl[3]);
1039 if( !flipped ){
1040 zResult = mprintf(
1041 "<span "
1042 "class=\"copy-button\" "
1043 "id=\"copy-%s\" "
1044 "data-copytarget=\"%s\" "
1045 "data-copylength=\"%d\">"
1046 "</span>"
1047 "<span id=\"%s\">"
1048 "%s"
1049 "</span>",
1050 zTargetId, zTargetId, copylength, zTargetId, zText);
1051 }else{
1052 zResult = mprintf(
1053 "<span id=\"%s\">"
1054 "%s"
1055 "</span>"
1056 "<span "
1057 "class=\"copy-button copy-button-flipped\" "
1058 "id=\"copy-%s\" "
1059 "data-copytarget=\"%s\" "
1060 "data-copylength=\"%d\">"
1061 "</span>",
1062 zTargetId, zText, zTargetId, zTargetId, copylength);
1063 }
1064 free(zTargetId);
1065 free(zText);
1066 style_copy_button();
1067 sendText(zResult, -1, 0);
1068 free(zResult);
1069
+1 -1
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -447,11 +447,11 @@
447447
@ <table cellpadding="5">
448448
@ <tr><td class="tktDspLabel">Ticket&nbsp;UUID:</td>
449449
@ <th1>
450450
@ if {[info exists tkt_uuid]} {
451451
@ html "<td class='tktDspValue' colspan='3'>"
452
-@ copybtn hash-tk $tkt_uuid 1
452
+@ copybtn hash-tk 0 $tkt_uuid 1
453453
@ if {[hascap s]} {
454454
@ html " ($tkt_id)"
455455
@ }
456456
@ html "</td></tr>\n"
457457
@ } else {
458458
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -447,11 +447,11 @@
447 @ <table cellpadding="5">
448 @ <tr><td class="tktDspLabel">Ticket&nbsp;UUID:</td>
449 @ <th1>
450 @ if {[info exists tkt_uuid]} {
451 @ html "<td class='tktDspValue' colspan='3'>"
452 @ copybtn hash-tk $tkt_uuid 1
453 @ if {[hascap s]} {
454 @ html " ($tkt_id)"
455 @ }
456 @ html "</td></tr>\n"
457 @ } else {
458
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -447,11 +447,11 @@
447 @ <table cellpadding="5">
448 @ <tr><td class="tktDspLabel">Ticket&nbsp;UUID:</td>
449 @ <th1>
450 @ if {[info exists tkt_uuid]} {
451 @ html "<td class='tktDspValue' colspan='3'>"
452 @ copybtn hash-tk 0 $tkt_uuid 1
453 @ if {[hascap s]} {
454 @ html " ($tkt_id)"
455 @ }
456 @ html "</td></tr>\n"
457 @ } else {
458
+3 -1
--- www/th1.md
+++ www/th1.md
@@ -281,17 +281,19 @@
281281
than one then the display is a listbox with the number of lines given.
282282
283283
<a name="copybtn"></a>TH1 copybtn Command
284284
-----------------------------------------
285285
286
- * copybtn TARGETID TEXT ?COPYLENGTH?
286
+ * copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
287287
288288
Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
289289
Javascript module, and generates HTML elements with the following IDs:
290290
291291
* TARGETID: The `<span>` wrapper around TEXT.
292292
* copy-TARGETID: The `<span>` for the copy button.
293
+
294
+If the FLIPPED argument is non-zero, the copy button is displayed after TEXT.
293295
294296
The optional COPYLENGTH argument defines the length of the substring of TEXT
295297
copied to clipboard:
296298
297299
* <= 0: No limit (default if the argument is omitted).
298300
--- www/th1.md
+++ www/th1.md
@@ -281,17 +281,19 @@
281 than one then the display is a listbox with the number of lines given.
282
283 <a name="copybtn"></a>TH1 copybtn Command
284 -----------------------------------------
285
286 * copybtn TARGETID TEXT ?COPYLENGTH?
287
288 Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
289 Javascript module, and generates HTML elements with the following IDs:
290
291 * TARGETID: The `<span>` wrapper around TEXT.
292 * copy-TARGETID: The `<span>` for the copy button.
 
 
293
294 The optional COPYLENGTH argument defines the length of the substring of TEXT
295 copied to clipboard:
296
297 * <= 0: No limit (default if the argument is omitted).
298
--- www/th1.md
+++ www/th1.md
@@ -281,17 +281,19 @@
281 than one then the display is a listbox with the number of lines given.
282
283 <a name="copybtn"></a>TH1 copybtn Command
284 -----------------------------------------
285
286 * copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
287
288 Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
289 Javascript module, and generates HTML elements with the following IDs:
290
291 * TARGETID: The `<span>` wrapper around TEXT.
292 * copy-TARGETID: The `<span>` for the copy button.
293
294 If the FLIPPED argument is non-zero, the copy button is displayed after TEXT.
295
296 The optional COPYLENGTH argument defines the length of the substring of TEXT
297 copied to clipboard:
298
299 * <= 0: No limit (default if the argument is omitted).
300

Keyboard Shortcuts

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