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.
Commit
63ebcafb19dd004ba246149fe1ae7018345db2ba7af70209fdee1bc293702845
Parent
42972005c42a31a…
7 files changed
+2
-1
+7
-1
+1
-3
+4
-4
+36
-18
+1
-1
+3
-1
+2
-1
| --- src/copybtn.js | ||
| +++ src/copybtn.js | ||
| @@ -21,13 +21,14 @@ | ||
| 21 | 21 | ** HTML snippet for statically created buttons: |
| 22 | 22 | ** |
| 23 | 23 | ** <span class="copy-button" id="copy-<idTarget>" |
| 24 | 24 | ** data-copytarget="<idTarget>" data-copylength="<cchLength>"></span> |
| 25 | 25 | */ |
| 26 | -function makeCopyButton(idTarget,cchLength){ | |
| 26 | +function makeCopyButton(idTarget,bFlipped,cchLength){ | |
| 27 | 27 | var elButton = document.createElement("span"); |
| 28 | 28 | elButton.className = "copy-button"; |
| 29 | + if( bFlipped ) elButton.className += " copy-button-flipped"; | |
| 29 | 30 | elButton.id = "copy-" + idTarget; |
| 30 | 31 | initCopyButton(elButton,idTarget,cchLength); |
| 31 | 32 | return elButton; |
| 32 | 33 | } |
| 33 | 34 | function initCopyButtonById(idButton,idTarget,cchLength){ |
| 34 | 35 |
| --- 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 |
+7
-1
| --- src/default_css.txt | ||
| +++ src/default_css.txt | ||
| @@ -771,15 +771,21 @@ | ||
| 771 | 771 | } |
| 772 | 772 | .copy-button { |
| 773 | 773 | display: inline-block; |
| 774 | 774 | width: 14px; |
| 775 | 775 | 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; | |
| 777 | 778 | padding: 0; |
| 778 | 779 | border: 0; |
| 779 | 780 | vertical-align: middle; |
| 780 | 781 | //Note: the mkcss utility does not support line breaks in data URIs. |
| 781 | 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"); |
| 782 | 783 | background-repeat: no-repeat; |
| 783 | 784 | background-position: center; |
| 784 | 785 | cursor: pointer; |
| 786 | +} | |
| 787 | +.copy-button-flipped { | |
| 788 | +//Note: .16em is suitable for element grouping. | |
| 789 | + margin-left: .16em; | |
| 790 | + margin-right: 0; | |
| 785 | 791 | } |
| 786 | 792 |
| --- 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 @@ | ||
| 628 | 628 | } |
| 629 | 629 | tooltipObj.style.borderColor = |
| 630 | 630 | tooltipObj.style.color = s.getPropertyValue('color') |
| 631 | 631 | tooltipObj.style.visibility = "hidden" |
| 632 | 632 | tooltipObj.innerHTML = html |
| 633 | - tooltipObj.appendChild(document.createTextNode(' ')); | |
| 634 | - tooltipObj.appendChild( | |
| 635 | - makeCopyButton("tooltip-link",0)); | |
| 633 | + tooltipObj.appendChild(makeCopyButton("tooltip-link",true,0)); | |
| 636 | 634 | tooltipObj.style.display = "inline" |
| 637 | 635 | tooltipObj.style.position = "absolute" |
| 638 | 636 | var x = tooltipInfo.posX + 4 + window.pageXOffset |
| 639 | 637 | - absoluteX(tooltipObj.offsetParent) |
| 640 | 638 | tooltipObj.style.left = x+"px" |
| 641 | 639 |
| --- 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 @@ | ||
| 765 | 765 | while( db_step(&q2)==SQLITE_ROW ){ |
| 766 | 766 | const char *zTagName = db_column_text(&q2, 0); |
| 767 | 767 | if( fossil_strcmp(zTagName,zBrName)==0 ){ |
| 768 | 768 | @ | <span class="copy-button" id="copy-name-br" |
| 769 | 769 | @ data-copytarget="name-br" data-copylength="0"> |
| 770 | - @ </span> <span id="name-br"><!-- | |
| 770 | + @ </span><span id="name-br"><!-- | |
| 771 | 771 | @ -->%z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a> |
| 772 | 772 | @ </span> |
| 773 | 773 | if( wiki_tagid2("branch",zTagName)!=0 ){ |
| 774 | 774 | blob_appendf(&wiki_read_links, " | %z%h</a>", |
| 775 | 775 | href("%R/wiki?name=branch/%h",zTagName), zTagName); |
| @@ -800,11 +800,11 @@ | ||
| 800 | 800 | @ </tr> |
| 801 | 801 | |
| 802 | 802 | @ <tr><th>%s(hname_alg(nUuid)):</th><td> |
| 803 | 803 | @ <span class="copy-button" id="copy-hash-ci" |
| 804 | 804 | @ data-copytarget="hash-ci" data-copylength="%d(hash_digits(1))"> |
| 805 | - @ </span> <span id="hash-ci">%.32s(zUuid)<wbr>%s(zUuid+32)</span> | |
| 805 | + @ </span><span id="hash-ci">%.32s(zUuid)<wbr>%s(zUuid+32)</span> | |
| 806 | 806 | if( g.perm.Setup ){ |
| 807 | 807 | @ (Record ID: %d(rid)) |
| 808 | 808 | } |
| 809 | 809 | @ </td></tr> |
| 810 | 810 | @ <tr><th>User & Date:</th><td> |
| @@ -2195,13 +2195,13 @@ | ||
| 2195 | 2195 | style_copy_button(); |
| 2196 | 2196 | @ <h2>Artifact |
| 2197 | 2197 | @ <span class="copy-button" id="copy-hash-ar" |
| 2198 | 2198 | @ data-copytarget="hash-ar" data-copylength="%d(hash_digits(1))"> |
| 2199 | 2199 | if( g.perm.Setup ){ |
| 2200 | - @ </span> <span id="hash-ar">%s(zUuid)</span> (%d(rid)):</h2> | |
| 2200 | + @ </span><span id="hash-ar">%s(zUuid)</span> (%d(rid)):</h2> | |
| 2201 | 2201 | }else{ |
| 2202 | - @ </span> <span id="hash-ar">%s(zUuid)</span>:</h2> | |
| 2202 | + @ </span><span id="hash-ar">%s(zUuid)</span>:</h2> | |
| 2203 | 2203 | } |
| 2204 | 2204 | } |
| 2205 | 2205 | blob_zero(&downloadName); |
| 2206 | 2206 | asText = P("txt")!=0; |
| 2207 | 2207 | if( asText ) objdescFlags &= ~OBJDESC_BASE; |
| 2208 | 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 & 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 |
| --- 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 & 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 @@ | ||
| 992 | 992 | } |
| 993 | 993 | return TH_OK; |
| 994 | 994 | } |
| 995 | 995 | |
| 996 | 996 | /* |
| 997 | -** TH1 command: copybtn TARGETID TEXT ?COPYLENGTH? | |
| 997 | +** TH1 command: copybtn TARGETID FLIPPED TEXT ?COPYLENGTH? | |
| 998 | 998 | ** |
| 999 | 999 | ** Output TEXT with a click-to-copy button next to it. Loads the copybtn.js |
| 1000 | 1000 | ** Javascript module, and generates HTML elements with the following IDs: |
| 1001 | 1001 | ** |
| 1002 | 1002 | ** TARGETID: The <span> wrapper around TEXT. |
| 1003 | 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. | |
| 1004 | 1006 | ** |
| 1005 | 1007 | ** The optional COPYLENGTH argument defines the length of the substring of TEXT |
| 1006 | 1008 | ** copied to clipboard: |
| 1007 | 1009 | ** |
| 1008 | 1010 | ** <= 0: No limit (default if the argument is omitted). |
| @@ -1016,35 +1018,51 @@ | ||
| 1016 | 1018 | void *p, |
| 1017 | 1019 | int argc, |
| 1018 | 1020 | const char **argv, |
| 1019 | 1021 | int *argl |
| 1020 | 1022 | ){ |
| 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?"); | |
| 1023 | 1026 | } |
| 1024 | 1027 | if( enableOutput ){ |
| 1028 | + int flipped = 0; | |
| 1025 | 1029 | int copylength = 0; |
| 1026 | 1030 | char *zTargetId, *zText, *zResult; |
| 1027 | - if( argc==4 && Th_ToInt(interp, argv[3], argl[3], ©length) ){ | |
| 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], ©length) ) return TH_ERROR; | |
| 1029 | 1034 | } |
| 1030 | 1035 | if( copylength==1 ) copylength = hash_digits(0); |
| 1031 | 1036 | else if( copylength==2 ) copylength = hash_digits(1); |
| 1032 | 1037 | 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 | - " " | |
| 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 | + } | |
| 1046 | 1064 | free(zTargetId); |
| 1047 | 1065 | free(zText); |
| 1048 | 1066 | style_copy_button(); |
| 1049 | 1067 | sendText(zResult, -1, 0); |
| 1050 | 1068 | free(zResult); |
| 1051 | 1069 |
| --- 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], ©length) ){ |
| 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 | " " |
| 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], ©length) ) 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 @@ | ||
| 447 | 447 | @ <table cellpadding="5"> |
| 448 | 448 | @ <tr><td class="tktDspLabel">Ticket UUID:</td> |
| 449 | 449 | @ <th1> |
| 450 | 450 | @ if {[info exists tkt_uuid]} { |
| 451 | 451 | @ html "<td class='tktDspValue' colspan='3'>" |
| 452 | -@ copybtn hash-tk $tkt_uuid 1 | |
| 452 | +@ copybtn hash-tk 0 $tkt_uuid 1 | |
| 453 | 453 | @ if {[hascap s]} { |
| 454 | 454 | @ html " ($tkt_id)" |
| 455 | 455 | @ } |
| 456 | 456 | @ html "</td></tr>\n" |
| 457 | 457 | @ } else { |
| 458 | 458 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -447,11 +447,11 @@ | |
| 447 | @ <table cellpadding="5"> |
| 448 | @ <tr><td class="tktDspLabel">Ticket 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 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 @@ | ||
| 281 | 281 | than one then the display is a listbox with the number of lines given. |
| 282 | 282 | |
| 283 | 283 | <a name="copybtn"></a>TH1 copybtn Command |
| 284 | 284 | ----------------------------------------- |
| 285 | 285 | |
| 286 | - * copybtn TARGETID TEXT ?COPYLENGTH? | |
| 286 | + * copybtn TARGETID FLIPPED TEXT ?COPYLENGTH? | |
| 287 | 287 | |
| 288 | 288 | Output TEXT with a click-to-copy button next to it. Loads the copybtn.js |
| 289 | 289 | Javascript module, and generates HTML elements with the following IDs: |
| 290 | 290 | |
| 291 | 291 | * TARGETID: The `<span>` wrapper around TEXT. |
| 292 | 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. | |
| 293 | 295 | |
| 294 | 296 | The optional COPYLENGTH argument defines the length of the substring of TEXT |
| 295 | 297 | copied to clipboard: |
| 296 | 298 | |
| 297 | 299 | * <= 0: No limit (default if the argument is omitted). |
| 298 | 300 |
| --- 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 |