@@ -620,5 +620,129 @@
620 620 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
});
621 621 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return F;
622 622 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
};
623 623 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Diff.setupDiffContextLoad();
624 624 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
});
625 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*
626 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** For a side-by-side diff, ensure that horizontal scrolling of either
627 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** side of the diff is synchronized with the other side.
628 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
629 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ window.fossil.onPageLoad(function(){
630 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const F = window.fossil, D = F.dom, Diff = F.diff;
631 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
632 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Look for a parent element to hold the sbs-sync-scroll toggle
633 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ checkbox. This differs per page. If we don't find one, simply
634 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elide that toggle and use whatever preference the user last
635 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ specified (defaulting to on). */
636 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ let cbSync /* scroll-sync checkbox */;
637 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ let eToggleParent /* element to put the sync-scroll checkbox in */;
638 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const potentialParents = [ /* possible parents for the checkbox */
639 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Put the most likely pages at the end, as array.pop() is more
640 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ efficient than array.shift() (see loop below). */
641 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
642 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
643 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* /vdiff */ 'body.vdiff form div.submenu',
644 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* /info, /vinfo */ 'body.vinfo div.sectionmenu.info-changes-menu'
645 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ];
646 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ while( potentialParents.length ){
647 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( (eToggleParent = document.querySelector(potentialParents.pop())) ){
648 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ break;
649 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
650 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
651 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
652 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( eToggleParent ){
653 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Add a checkbox to toggle sbs scroll sync. Remember that in
654 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ order to be UI-consistent in the /vdiff page we have to ensure
655 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ that the checkbox is to the LEFT of of its label. We store the
656 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ sync-scroll preference in F.storage (not a cookie) so that it
657 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ persists across page loads and different apps. */
658 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
659 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.append(eToggleParent, D.append(
660 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.addClass(D.create('span'), 'input-with-label'),
661 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.append(D.create('label'),
662 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cbSync, "Sync side-by-side scrolling?")
663 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ));
664 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cbSync.addEventListener('change', function(e){
665 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ F.storage.set(keySbsScroll, e.target.checked);
666 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ });
667 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
668 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const useSync = cbSync ? ()=>cbSync.checked : ()=>F.storage.getBool(keySbsScroll,true);
669 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
670 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Now set up the events to enable syncronized scrolling... */
671 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const scrollLeft = function(event){
672 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const table = this.parentElement/*TD*/.parentElement/*TR*/.
673 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ parentElement/*TBODY*/.parentElement/*TABLE*/;
674 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( useSync() ){
675 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ table.$txtPres.forEach((e)=>(e===this) ? 1 : (e.scrollLeft = this.scrollLeft));
676 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
677 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return false;
678 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ };
679 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const SCROLL_LEN = 64/* pixels to scroll for keyboard events */;
680 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const keycodes = Object.assign(Object.create(null),{
681 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ 37/*cursor left*/: -SCROLL_LEN, 39/*cursor right*/: SCROLL_LEN
682 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ });
683 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /**
684 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Sets up synchronized scrolling of table.splitdiff element
685 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ `diff`. If passed no argument, it scans the dom for elements to
686 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ initialize. The second argument is for this function's own
687 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ internal use.
688 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
689 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ It's okay (but wasteful) to pass the same element to this
690 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ function multiple times: it will only be set up for sync
691 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ scrolling the first time it's passed to this function.
692 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
693 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Note that this setup is ignorant of the cbSync toggle: the toggle
694 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ is checked when scrolling, not when initializing the sync-scroll
695 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ capability.
696 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
697 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const initTableDiff = function f(diff, unifiedDiffs){
698 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!diff){
699 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ let i, diffs;
700 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diffs = document.querySelectorAll('table.splitdiff');
701 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for(i=0; i<diffs.length; ++i){
702 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.call(this, diffs[i], false);
703 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
704 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diffs = document.querySelectorAll('table.udiff');
705 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for(i=0; i<diffs.length; ++i){
706 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.call(this, diffs[i], true);
707 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
708 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return this;
709 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
710 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diff.$txtCols = diff.querySelectorAll('td.difftxt');
711 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diff.$txtPres = diff.querySelectorAll('td.difftxt pre');
712 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!unifiedDiffs){
713 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diff.$txtPres.forEach(function(e){
714 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!e.classList.contains('scroller')){
715 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.addClass(e, 'scroller');
716 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ e.addEventListener('scroll', scrollLeft, false);
717 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
718 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ });
719 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diff.tabIndex = 0;
720 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!diff.classList.contains('scroller')){
721 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Keyboard-based scrolling requires special-case handling to
722 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ensure that we scroll the proper side of the diff when sync
723 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ is off. */
724 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.addClass(diff, 'scroller');
725 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diff.addEventListener('keydown', function(e){
726 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const len = keycodes[e.keyCode];
727 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( !len ) return false;
728 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( useSync() ){
729 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.$txtPres[0].scrollLeft += len;
730 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else if( diff.$preCurrent ){
731 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.$preCurrent.scrollLeft += len;
732 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
733 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return false;
734 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }, false);
735 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diff.$txtPres.forEach((e)=>{
736 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ e.addEventListener('click', function(ev){
737 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ diff.$preCurrent = this /* NOT ev.target, which is probably a child element */;
738 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }, false);
739 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ })
740 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
741 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
742 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return this;
743 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
744 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ window.fossil.page.tweakSbsDiffs = function(){
745 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ document.querySelectorAll('table.splitdiff').forEach((e)=>initTableDiff(e));
746 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ };
747 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ initTableDiff();
748 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }, false);
625 749 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!