Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch tooltip-copyhash Excluding Merge-Ins
This is equivalent to a diff from d57c1a797c to 21f38e85b3
2019-06-03
| ||
08:51 | Cherry-pick [2196555351]: Use the longer hash prefix for the click-to-copy. ... (Closed-Leaf check-in: 21f38e85b3 user: florian tags: tooltip-copyhash) | |
08:48 | Minimize impact of the SVG icon on line height. ... (check-in: 787650c36a user: florian tags: tooltip-copyhash) | |
2019-06-01
| ||
00:52 | Use the longer hash prefix for the click-to-copy. ... (check-in: 2196555351 user: drh tags: copybtn.js-demonstration) | |
2019-05-28
| ||
12:16 | Explicitly query the client mouse coordinates, to fix the positioning of tooltips for nodes in IE. ... (Closed-Leaf check-in: ac199e7a8a user: florian tags: tooltip-experiments) | |
2019-05-27
| ||
09:19 | Add a "Copy Hash" icon to the tooltip, to copy the hash or branch name of the underlying element to the clipboard. See the wiki page linked to this branch for more information. ... (check-in: 371943c936 user: florian tags: tooltip-copyhash) | |
06:58 | Ensure the close timer is started for tooltips belonging to nodes instead of rails, and prevent an out-of-bounds array access for double-clicks outside of rails. ... (check-in: d57c1a797c user: florian tags: tooltip-experiments) | |
2019-05-23
| ||
17:18 | Hide the tooltip when leaving the page. ... (check-in: 356c0d017e user: drh tags: tooltip-experiments) | |
Added src/copybtn.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | /* Manage "Copy Buttons" linked to target elements, to copy the text (or, parts ** thereof) of the target elements to the clipboard. ** ** Newly created buttons are <span> elements with an SVG background icon, ** defined by the "copy-button" class in the default CSS style sheet. ** ** To simplify customization, the only properties modified for HTML-defined ** buttons are the "onclick" handler, and the "transition" and "opacity" styles ** (used for animation). ** ** For HTML-defined buttons, either initCopyButtonById(), or initCopyButton(), ** needs to be called to attach the "onclick" handler (done automatically from ** a handler attached to the "DOMContentLoaded" event). ** ** The initialization functions do not overwrite the "data-copytarget" and ** "data-copylength" attributes with empty or null values for <idTarget> and ** <cchLength>, respectively. Set <cchLength> to "-1" to explicitly remove the ** previous copy length limit. ** ** HTML snippet for statically created buttons: ** ** <span class="copy-button" id="idButton" ** data-copytarget="idTarget" data-copylength="cchLength"></span> */ function makeCopyButton(idButton,idTarget,cchLength){ var elButton = document.createElement("span"); elButton.className = "copy-button"; elButton.id = idButton; initCopyButton(elButton,idTarget,cchLength); return elButton; } function initCopyButtonById(idButton,idTarget,cchLength){ var elButton = document.getElementById(idButton); if( elButton ) initCopyButton(elButton,idTarget,cchLength); return elButton; } function initCopyButton(elButton,idTarget,cchLength){ elButton.style.transition = ""; elButton.style.opacity = 1; if( idTarget ) elButton.setAttribute("data-copytarget",idTarget); if( cchLength ) elButton.setAttribute("data-copylength",cchLength); elButton.onclick = clickCopyButton; return elButton; } onContentLoaded(function(){ var aButtons = document.getElementsByClassName("copy-button"); for ( var i=0; i<aButtons.length; i++ ){ initCopyButton(aButtons[i],0,0); } }); /* The onclick handler for the "Copy Button". */ var lockCopyText = false; function clickCopyButton(e){ e.preventDefault(); /* Mandatory for <a> and <button>. */ e.stopPropagation(); if( lockCopyText ) return; lockCopyText = true; this.style.transition = "opacity 400ms ease-in-out"; this.style.opacity = 0; var idTarget = this.getAttribute("data-copytarget"); var elTarget = document.getElementById(idTarget); if( elTarget ){ var text = elTarget.innerText.replace(/^\s+|\s+$/g,''); var cchLength = parseInt(this.getAttribute("data-copylength")); if( !isNaN(cchLength) && cchLength>0 ){ text = text.slice(0,cchLength); // Assume single-byte chars. } copyTextToClipboard(text); } setTimeout(function(id){ var elButton = document.getElementById(id); if( elButton ){ elButton.style.transition = ""; elButton.style.opacity = 1; } lockCopyText = false; }.bind(null,this.id),400); } /* Create a temporary <textarea> element and copy the contents to clipboard. */ function copyTextToClipboard(text){ var textArea = document.createElement("textarea"); textArea.style.position = 'fixed'; textArea.style.top = 0; textArea.style.left = 0; textArea.style.width = '2em'; textArea.style.height = '2em'; textArea.style.padding = 0; textArea.style.border = 'none'; textArea.style.outline = 'none'; textArea.style.boxShadow = 'none'; textArea.style.background = 'transparent'; textArea.value = text; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try{ document.execCommand('copy'); }catch(err){ } document.body.removeChild(textArea); } /* Execute a function as soon as the HTML document has been completely loaded. ** The idea for this code is based on the contentLoaded() function presented ** here: ** ** Cross-browser wrapper for DOMContentLoaded ** http://javascript.nwbox.com/ContentLoaded/ */ function onContentLoaded(fnready) { var fninit = function() { if (document.addEventListener || event.type === 'load' || document.readyState === 'complete') { if (document.addEventListener) { document.removeEventListener('DOMContentLoaded',fninit,false); window.removeEventListener('load',fninit,false); } else { document.detachEvent('onreadystatechange',fninit); window.detachEvent('onload',fninit); } } fnready.call(window); }; if (document.readyState === 'complete') fnready.call(window); else if (document.addEventListener) { document.addEventListener('DOMContentLoaded',fninit,false); window.addEventListener('load',fninit,false); } else { document.attachEvent('onreadystatechange',fninit); window.attachEvent('onload',fninit); } } |
Changes to src/default_css.txt.
︙ | ︙ | |||
765 766 767 768 769 770 771 | } .capsumWrite { background-color: #ffb; } label { white-space: nowrap; } | > > > > > > > > > > > > > > | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 | } .capsumWrite { background-color: #ffb; } label { white-space: nowrap; } .copy-button { display: inline-block; width: 14px; height: 14px; margin: -2px 0 0 0; padding: 0; border: 0; vertical-align: middle; //Note: the mkcss utility does not support line breaks in data URIs. 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"); background-repeat: no-repeat; background-position: center; cursor: pointer; } |
Changes to src/graph.js.
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** "omitDescenders": BOOLEAN, // Omit ancestor lines off bottom of screen ** "fileDiff": BOOLEAN, // True for file diff. False for check-in ** "scrollToSelect": BOOLEAN, // Scroll to selection on first render ** "nrail": INTEGER, // Number of vertical "rails" ** "baseUrl": TEXT, // Top-level URL ** "dwellTimeout": INTEGER, // Tooltip show delay in milliseconds ** "closeTimeout": INTEGER, // Tooltip close delay in milliseconds ** "rowinfo": ROWINFO-ARRAY } ** ** The rowinfo field is an array of structures, one per entry in the timeline, ** where each structure has the following fields: ** ** id: The id of the <div> element for the row. This is an integer. ** to get an actual id, prepend "m" to the integer. The top node | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ** "omitDescenders": BOOLEAN, // Omit ancestor lines off bottom of screen ** "fileDiff": BOOLEAN, // True for file diff. False for check-in ** "scrollToSelect": BOOLEAN, // Scroll to selection on first render ** "nrail": INTEGER, // Number of vertical "rails" ** "baseUrl": TEXT, // Top-level URL ** "dwellTimeout": INTEGER, // Tooltip show delay in milliseconds ** "closeTimeout": INTEGER, // Tooltip close delay in milliseconds ** "hashDigits": INTEGER, // Limit of tooltip hashes ("hash-digits") ** "rowinfo": ROWINFO-ARRAY } ** ** The rowinfo field is an array of structures, one per entry in the timeline, ** where each structure has the following fields: ** ** id: The id of the <div> element for the row. This is an integer. ** to get an actual id, prepend "m" to the integer. The top node |
︙ | ︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 | if (tooltipInfo.ixActive != -1) resumeCloseTimer(); }; /* State information for the tooltip popup and its timers */ window.tooltipInfo = { dwellTimeout: 250, /* The tooltip dwell timeout. */ closeTimeout: 3000, /* The tooltip close timeout. */ idTimer: 0, /* The tooltip dwell timer id. */ idTimerClose: 0, /* The tooltip close timer id. */ ixHover: -1, /* The id of the element with the mouse. */ ixActive: -1, /* The id of the element with the tooltip. */ nodeHover: null, /* Graph node under mouse when ixHover==-2 */ posX: 0, posY: 0 /* The last mouse position. */ }; | > | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | if (tooltipInfo.ixActive != -1) resumeCloseTimer(); }; /* State information for the tooltip popup and its timers */ window.tooltipInfo = { dwellTimeout: 250, /* The tooltip dwell timeout. */ closeTimeout: 3000, /* The tooltip close timeout. */ hashDigits: 16, /* Limit of tooltip hashes ("hash-digits"). */ idTimer: 0, /* The tooltip dwell timer id. */ idTimerClose: 0, /* The tooltip close timer id. */ ixHover: -1, /* The id of the element with the mouse. */ ixActive: -1, /* The id of the element with the tooltip. */ nodeHover: null, /* Graph node under mouse when ixHover==-2 */ posX: 0, posY: 0 /* The last mouse position. */ }; |
︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | /* Construct that graph corresponding to the timeline-data-N object that ** is passed in by the tx parameter */ function TimelineGraph(tx){ var topObj = document.getElementById("timelineTable"+tx.iTableId); amendCss(tx.circleNodes, tx.showArrowheads); tooltipInfo.dwellTimeout = tx.dwellTimeout tooltipInfo.closeTimeout = tx.closeTimeout topObj.onclick = clickOnGraph topObj.ondblclick = dblclickOnGraph topObj.onmousemove = function(e) { var ix = findTxIndex(e); topObj.style.cursor = (ix<0) ? "" : "pointer" /* Keep the already visible tooltip at a constant position, as long as the ** mouse is over the same element. */ if(tooltipObj.style.display != "none"){ if(ix == tooltipInfo.ixHover) return; } /* The tooltip is either not visible, or the mouse is over a different ** element, so clear the dwell timer, and record the new element id and ** mouse position. */ stopDwellTimer(); if(ix >= 0){ tooltipInfo.ixHover = ix; | > | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | /* Construct that graph corresponding to the timeline-data-N object that ** is passed in by the tx parameter */ function TimelineGraph(tx){ var topObj = document.getElementById("timelineTable"+tx.iTableId); amendCss(tx.circleNodes, tx.showArrowheads); tooltipInfo.dwellTimeout = tx.dwellTimeout tooltipInfo.closeTimeout = tx.closeTimeout tooltipInfo.hashDigits = tx.hashDigits topObj.onclick = clickOnGraph topObj.ondblclick = dblclickOnGraph topObj.onmousemove = function(e) { var ix = findTxIndex(e); topObj.style.cursor = (ix<0) ? "" : "pointer" /* Keep the already visible tooltip at a constant position, as long as the ** mouse is over the same element. */ if(tooltipObj.style.display != "none"){ if(ix == tooltipInfo.ixHover) return; } /* The tooltip is either not visible, or the mouse is over a different ** element, so clear the dwell timer, and record the new element id and ** mouse position. */ stopDwellTimer(); if(ix >= 0){ tooltipInfo.ixHover = ix; tooltipInfo.posX = e.clientX; tooltipInfo.posY = e.clientY; stopCloseTimer(); if(tooltipInfo.dwellTimeout>0){ tooltipInfo.idTimer = setTimeout(function() { tooltipInfo.idTimer = 0; stopCloseTimer(); showGraphTooltip(); },tooltipInfo.dwellTimeout); |
︙ | ︙ | |||
186 187 188 189 190 191 192 | } }; function nodeHover(e){ /* Invoked by mousemove events over a graph node */ e.stopPropagation() if(tooltipInfo.ixHover==-2) return tooltipInfo.ixHover = -2 | | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | } }; function nodeHover(e){ /* Invoked by mousemove events over a graph node */ e.stopPropagation() if(tooltipInfo.ixHover==-2) return tooltipInfo.ixHover = -2 tooltipInfo.posX = e.clientX tooltipInfo.posY = e.clientY tooltipInfo.nodeHover = this stopCloseTimer(); if(tooltipInfo.dwellTimeout>0){ tooltipInfo.idTimer = setTimeout(function() { tooltipInfo.idTimer = 0; stopCloseTimer(); showGraphTooltip(); |
︙ | ︙ | |||
555 556 557 558 559 560 561 | window.location.href = tx.baseUrl+"/info/"+p.h e.stopPropagation() } function findTxIndex(e){ /* Look at all the graph elements. If any graph elements that is near ** the click-point "e" and has a "data-ix" attribute, then return ** the value of that attribute. Otherwise return -1 */ | | | | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | window.location.href = tx.baseUrl+"/info/"+p.h e.stopPropagation() } function findTxIndex(e){ /* Look at all the graph elements. If any graph elements that is near ** the click-point "e" and has a "data-ix" attribute, then return ** the value of that attribute. Otherwise return -1 */ var x = e.clientX + window.pageXOffset - absoluteX(canvasDiv); var y = e.clientY + window.pageYOffset - absoluteY(canvasDiv); var aNode = canvasDiv.childNodes var nNode = aNode.length; var i; for(i=0;i<nNode;i++){ var n = aNode[i] if( !n.hasAttribute("data-ix") ) continue; if( x<n.offsetLeft-5 ) continue; |
︙ | ︙ | |||
581 582 583 584 585 586 587 | var dest = tx.baseUrl + "/timeline?r=" + encodeURIComponent(br) dest += tx.fileDiff ? "&m&cf=" : "&m&c=" dest += encodeURIComponent(tx.rowinfo[ix].h) return dest } function clickOnGraph(e){ tooltipInfo.ixHover = findTxIndex(e); | | | > | | | > > > | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | var dest = tx.baseUrl + "/timeline?r=" + encodeURIComponent(br) dest += tx.fileDiff ? "&m&cf=" : "&m&c=" dest += encodeURIComponent(tx.rowinfo[ix].h) return dest } function clickOnGraph(e){ tooltipInfo.ixHover = findTxIndex(e); tooltipInfo.posX = e.clientX; tooltipInfo.posY = e.clientY; showGraphTooltip(); } function showGraphTooltip(){ var html = null var ix = -1 if( tooltipInfo.ixHover==-2 ){ ix = parseInt(tooltipInfo.nodeHover.id.match(/\d+$/)[0],10)-tx.iTopRow var h = tx.rowinfo[ix].h var dest = tx.baseUrl + "/info/" + h h = h.slice(0,tooltipInfo.hashDigits); // Assume single-byte characters. if( tx.fileDiff ){ html = "artifact <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" }else{ html = "check-in <a id=\"tooltip-link\" href=\""+dest+"\">"+h+"</a>" } tooltipInfo.ixActive = -2; }else if( tooltipInfo.ixHover>=0 ){ ix = tooltipInfo.ixHover var br = tx.rowinfo[ix].br var dest = branchHyperlink(ix) var hbr = br.replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); html = "branch <a id=\"tooltip-link\" href=\""+dest+"\">"+hbr+"</a>" tooltipInfo.ixActive = ix; } if( html ){ /* Setup while hidden, to ensure proper dimensions. */ var s = getComputedStyle(document.body) if( tx.rowinfo[ix].bg.length ){ tooltipObj.style.backgroundColor = tx.rowinfo[ix].bg }else{ tooltipObj.style.backgroundColor = s.getPropertyValue('background-color') } tooltipObj.style.borderColor = tooltipObj.style.color = s.getPropertyValue('color') tooltipObj.style.visibility = "hidden" tooltipObj.innerHTML = html tooltipObj.appendChild(document.createTextNode(' ')); tooltipObj.appendChild( makeCopyButton("tooltip-copybtn","tooltip-link",0)); tooltipObj.style.display = "inline" tooltipObj.style.position = "absolute" var x = tooltipInfo.posX + 4 + window.pageXOffset - absoluteX(tooltipObj.offsetParent) tooltipObj.style.left = x+"px" var y = tooltipInfo.posY + window.pageYOffset - tooltipObj.clientHeight - 4 |
︙ | ︙ |
Changes to src/main.mk.
︙ | ︙ | |||
208 209 210 211 212 213 214 215 216 217 218 219 220 221 | $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/ci_edit.js \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/forum.js \ $(SRCDIR)/graph.js \ $(SRCDIR)/href.js \ $(SRCDIR)/login.js \ $(SRCDIR)/markdown.md \ $(SRCDIR)/menu.js \ | > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/ci_edit.js \ $(SRCDIR)/copybtn.js \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/forum.js \ $(SRCDIR)/graph.js \ $(SRCDIR)/href.js \ $(SRCDIR)/login.js \ $(SRCDIR)/markdown.md \ $(SRCDIR)/menu.js \ |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
46 47 48 49 50 51 52 | #endif /* ** Return the number of artifact hash digits to display. The number is for ** human output if the bForUrl is false and is destined for a URL if ** bForUrl is false. */ | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #endif /* ** Return the number of artifact hash digits to display. The number is for ** human output if the bForUrl is false and is destined for a URL if ** bForUrl is false. */ int hash_digits(int bForUrl){ static int nDigitHuman = 0; static int nDigitUrl = 0; if( nDigitHuman==0 ){ nDigitHuman = db_get_int("hash-digits", FOSSIL_HASH_DIGITS); if( nDigitHuman < 6 ) nDigitHuman = 6; if( nDigitHuman > 40 ) nDigitHuman = 40; nDigitUrl = nDigitHuman + 6; if( nDigitUrl < FOSSIL_HASH_DIGITS_URL ) nDigitUrl = FOSSIL_HASH_DIGITS_URL; if( nDigitUrl > 40 ) nDigitUrl = 40; } return bForUrl ? nDigitUrl : nDigitHuman; } /* ** Return the number of characters in a %S output. */ int length_of_S_display(void){ return hash_digits(0); } /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ |
︙ | ︙ | |||
677 678 679 680 681 682 683 | int limit = flag_alternateform ? va_arg(ap,int) : -1; bufpt = va_arg(ap,char*); if( bufpt==0 ){ bufpt = ""; }else if( xtype==etDYNSTRING ){ zExtra = bufpt; }else if( xtype==etSTRINGID ){ | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | int limit = flag_alternateform ? va_arg(ap,int) : -1; bufpt = va_arg(ap,char*); if( bufpt==0 ){ bufpt = ""; }else if( xtype==etDYNSTRING ){ zExtra = bufpt; }else if( xtype==etSTRINGID ){ precision = hash_digits(flag_altform2); } length = StrNLen32(bufpt, limit); if( precision>=0 && precision<length ) length = precision; break; } case etBLOB: { int limit = flag_alternateform ? va_arg(ap, int) : -1; |
︙ | ︙ |
Changes to src/style.c.
︙ | ︙ | |||
80 81 82 83 84 85 86 | ** Ad-unit styles. */ static unsigned adUnitFlags = 0; /* ** Flags for various javascript files needed prior to </body> */ | | | | > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | ** Ad-unit styles. */ static unsigned adUnitFlags = 0; /* ** Flags for various javascript files needed prior to </body> */ static int needHrefJs = 0; /* href.js */ static int needSortJs = 0; /* sorttable.js */ static int needGraphJs = 0; /* graph.js */ static int needCopyBtnJs = 0; /* copybtn.js */ /* ** Extra JS added to the end of the file. */ static Blob blobOnLoad = BLOB_INITIALIZER; /* |
︙ | ︙ | |||
531 532 533 534 535 536 537 | ** Indicate that the table-sorting javascript is needed. */ void style_table_sorter(void){ needSortJs = 1; } /* | | > > > > > > > | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | ** Indicate that the table-sorting javascript is needed. */ void style_table_sorter(void){ needSortJs = 1; } /* ** Indicate that the timeline graph javascript is needed. */ void style_graph_generator(void){ needGraphJs = 1; } /* ** Indicate that the copy button javascript is needed. */ void style_copy_button(void){ needCopyBtnJs = 1; } /* ** Generate code to load a single javascript file */ void style_load_one_js_file(const char *zFile){ @ <script src='%R/builtin/%s(zFile)?id=%S(MANIFEST_UUID)'></script> } |
︙ | ︙ | |||
589 590 591 592 593 594 595 596 597 598 599 600 601 602 | } if( needSortJs ){ cgi_append_content(builtin_text("sorttable.js"),-1); } if( needGraphJs ){ cgi_append_content(builtin_text("graph.js"),-1); } for(i=0; i<nJsToLoad; i++){ cgi_append_content(builtin_text(azJsToLoad[i]),-1); } if( blob_size(&blobOnLoad)>0 ){ @ window.onload = function(){ cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad)); cgi_append_content("\n}\n", -1); | > > > | 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 | } if( needSortJs ){ cgi_append_content(builtin_text("sorttable.js"),-1); } if( needGraphJs ){ cgi_append_content(builtin_text("graph.js"),-1); } if( needCopyBtnJs ){ cgi_append_content(builtin_text("copybtn.js"),-1); } for(i=0; i<nJsToLoad; i++){ cgi_append_content(builtin_text(azJsToLoad[i]),-1); } if( blob_size(&blobOnLoad)>0 ){ @ window.onload = function(){ cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad)); cgi_append_content("\n}\n", -1); |
︙ | ︙ |
Changes to src/timeline.c.
︙ | ︙ | |||
857 858 859 860 861 862 863 864 865 866 867 868 869 870 | @ "omitDescenders": %d(omitDescenders), @ "fileDiff": %d(fileDiff), @ "scrollToSelect": %d(scrollToSelect), @ "nrail": %d(pGraph->mxRail+1), @ "baseUrl": "%R", @ "dwellTimeout": %d(dwellTimeout), @ "closeTimeout": %d(closeTimeout), @ "bottomRowId": "btm-%d(iTableId)", if( pGraph->nRow==0 ){ @ "rowinfo": null }else{ @ "rowinfo": [ } | > | 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 | @ "omitDescenders": %d(omitDescenders), @ "fileDiff": %d(fileDiff), @ "scrollToSelect": %d(scrollToSelect), @ "nrail": %d(pGraph->mxRail+1), @ "baseUrl": "%R", @ "dwellTimeout": %d(dwellTimeout), @ "closeTimeout": %d(closeTimeout), @ "hashDigit": %d(hash_digits(1)), @ "bottomRowId": "btm-%d(iTableId)", if( pGraph->nRow==0 ){ @ "rowinfo": null }else{ @ "rowinfo": [ } |
︙ | ︙ | |||
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 | if( k ) cgi_printf("],"); cgi_printf("\"br\":\"%j\",", pRow->zBranch ? pRow->zBranch : ""); cgi_printf("\"h\":\"%!S\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "]\n"); } @ }</script> style_graph_generator(); graph_free(pGraph); } } /* ** Create a temporary table suitable for storing timeline data. */ | > | 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 | if( k ) cgi_printf("],"); cgi_printf("\"br\":\"%j\",", pRow->zBranch ? pRow->zBranch : ""); cgi_printf("\"h\":\"%!S\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "]\n"); } @ }</script> style_graph_generator(); style_copy_button(); /* Dependency: graph.js requires copybtn.js. */ graph_free(pGraph); } } /* ** Create a temporary table suitable for storing timeline data. */ |
︙ | ︙ |
Changes to win/Makefile.mingw.
︙ | ︙ | |||
630 631 632 633 634 635 636 637 638 639 640 641 642 643 | $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/ci_edit.js \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/forum.js \ $(SRCDIR)/graph.js \ $(SRCDIR)/href.js \ $(SRCDIR)/login.js \ $(SRCDIR)/markdown.md \ $(SRCDIR)/menu.js \ | > | 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/ci_edit.js \ $(SRCDIR)/copybtn.js \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/forum.js \ $(SRCDIR)/graph.js \ $(SRCDIR)/href.js \ $(SRCDIR)/login.js \ $(SRCDIR)/markdown.md \ $(SRCDIR)/menu.js \ |
︙ | ︙ |
Changes to win/Makefile.msc.
︙ | ︙ | |||
533 534 535 536 537 538 539 540 541 542 543 544 545 546 | $(SRCDIR)\..\skins\rounded1\footer.txt \ $(SRCDIR)\..\skins\rounded1\header.txt \ $(SRCDIR)\..\skins\xekri\css.txt \ $(SRCDIR)\..\skins\xekri\details.txt \ $(SRCDIR)\..\skins\xekri\footer.txt \ $(SRCDIR)\..\skins\xekri\header.txt \ $(SRCDIR)\ci_edit.js \ $(SRCDIR)\diff.tcl \ $(SRCDIR)\forum.js \ $(SRCDIR)\graph.js \ $(SRCDIR)\href.js \ $(SRCDIR)\login.js \ $(SRCDIR)\markdown.md \ $(SRCDIR)\menu.js \ | > | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | $(SRCDIR)\..\skins\rounded1\footer.txt \ $(SRCDIR)\..\skins\rounded1\header.txt \ $(SRCDIR)\..\skins\xekri\css.txt \ $(SRCDIR)\..\skins\xekri\details.txt \ $(SRCDIR)\..\skins\xekri\footer.txt \ $(SRCDIR)\..\skins\xekri\header.txt \ $(SRCDIR)\ci_edit.js \ $(SRCDIR)\copybtn.js \ $(SRCDIR)\diff.tcl \ $(SRCDIR)\forum.js \ $(SRCDIR)\graph.js \ $(SRCDIR)\href.js \ $(SRCDIR)\login.js \ $(SRCDIR)\markdown.md \ $(SRCDIR)\menu.js \ |
︙ | ︙ |