Fossil SCM
Persist expand/collapse state of tree-view directories in all modern browsers.
Commit
cd554eb63cb2e0b17c3f57fa4882fa4cbccdd5df
Parent
6228efbb7cb9521…
1 file changed
+36
-15
+36
-15
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -634,44 +634,65 @@ | ||
| 634 | 634 | } |
| 635 | 635 | } |
| 636 | 636 | @ </ul> |
| 637 | 637 | @ </ul></div> |
| 638 | 638 | @ <script>(function(){ |
| 639 | - @ function style(elem, prop){ | |
| 640 | - @ return window.getComputedStyle(elem).getPropertyValue(prop); | |
| 639 | + @ function isExpanded(ul){ | |
| 640 | + @ var display = window.getComputedStyle(ul).getPropertyValue('display'); | |
| 641 | + @ return display!='none'; | |
| 642 | + @ } | |
| 643 | + @ | |
| 644 | + @ function toggleDir(a, useInitValue){ | |
| 645 | + @ var ul = a.nextSibling; | |
| 646 | + @ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling; | |
| 647 | + @ if( !ul ) return false; /* This is a file link, not a directory */ | |
| 648 | + @ if( !useInitValue ) expandMap[a.id] = !isExpanded(ul); | |
| 649 | + @ ul.style.display = expandMap[a.id] ? 'block' : 'none'; | |
| 650 | + @ return true; | |
| 641 | 651 | @ } |
| 642 | 652 | @ |
| 643 | - @ function toggleAll(tree){ | |
| 653 | + @ function toggleAll(tree, useInitValue){ | |
| 644 | 654 | @ var lists = tree.querySelectorAll('.subdir > ul > li ul'); |
| 645 | - @ var display = 'block'; /* Default action: make all sublists visible */ | |
| 646 | - @ for( var i=0; lists[i]; i++ ){ | |
| 647 | - @ if( style(lists[i], 'display')!='none'){ | |
| 648 | - @ display = 'none'; /* Any already visible - make them all hidden */ | |
| 649 | - @ break; | |
| 655 | + @ if( !useInitValue ){ | |
| 656 | + @ expand = true; /* Default action: make all sublists visible */ | |
| 657 | + @ for( var i=0; lists[i]; i++ ){ | |
| 658 | + @ if( isExpanded(lists[i]) ){ | |
| 659 | + @ expand = false; /* Any already visible - make them all hidden */ | |
| 660 | + @ break; | |
| 661 | + @ } | |
| 650 | 662 | @ } |
| 663 | + @ expandMap = {'*': expand}; | |
| 651 | 664 | @ } |
| 665 | + @ var display = expandMap['*'] ? 'block' : 'none'; | |
| 652 | 666 | @ for( var i=0; lists[i]; i++ ){ |
| 653 | 667 | @ lists[i].style.display = display; |
| 654 | 668 | @ } |
| 655 | 669 | @ } |
| 656 | - @ | |
| 670 | + @ | |
| 671 | + @ var expandMap; | |
| 657 | 672 | @ var outer_ul = document.querySelector('.filetree > ul'); |
| 658 | 673 | @ var subdir = outer_ul.querySelector('.subdir'); |
| 659 | - @ outer_ul.onclick = function( e ){ | |
| 674 | + @ outer_ul.onclick = function(e){ | |
| 660 | 675 | @ var a = e.target; |
| 661 | 676 | @ if( a.nodeName!='A' ) return true; |
| 662 | 677 | @ if( a.parentNode==subdir ){ |
| 663 | 678 | @ toggleAll(outer_ul); |
| 664 | 679 | @ return false; |
| 665 | 680 | @ } |
| 666 | 681 | @ if( !subdir.contains(a) ) return true; |
| 667 | - @ var ul = a.nextSibling; | |
| 668 | - @ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling; | |
| 669 | - @ if( !ul ) return true; /* This is a file link, not a directory */ | |
| 670 | - @ ul.style.display = style(ul, 'display')=='none' ? 'block' : 'none'; | |
| 671 | - @ return false; | |
| 682 | + @ return !toggleDir(a); | |
| 672 | 683 | @ } |
| 684 | + @ addEventListener('pagehide', function(){ | |
| 685 | + @ sessionStorage.setItem('tree-expandMap', JSON.stringify(expandMap)); | |
| 686 | + @ }); | |
| 687 | + @ addEventListener('pageshow', function(){ | |
| 688 | + @ expandMap = JSON.parse(sessionStorage.getItem('tree-expandMap')) || {}; | |
| 689 | + @ if( expandMap['*'] ) toggleAll(outer_ul, true); | |
| 690 | + @ for( var id in expandMap ){ | |
| 691 | + @ if( id!=='*' ) toggleDir(gebi(id), true); | |
| 692 | + @ } | |
| 693 | + @ }); | |
| 673 | 694 | @ }())</script> |
| 674 | 695 | style_footer(); |
| 675 | 696 | |
| 676 | 697 | /* We could free memory used by sTree here if we needed to. But |
| 677 | 698 | ** the process is about to exit, so doing so would not really accomplish |
| 678 | 699 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -634,44 +634,65 @@ | |
| 634 | } |
| 635 | } |
| 636 | @ </ul> |
| 637 | @ </ul></div> |
| 638 | @ <script>(function(){ |
| 639 | @ function style(elem, prop){ |
| 640 | @ return window.getComputedStyle(elem).getPropertyValue(prop); |
| 641 | @ } |
| 642 | @ |
| 643 | @ function toggleAll(tree){ |
| 644 | @ var lists = tree.querySelectorAll('.subdir > ul > li ul'); |
| 645 | @ var display = 'block'; /* Default action: make all sublists visible */ |
| 646 | @ for( var i=0; lists[i]; i++ ){ |
| 647 | @ if( style(lists[i], 'display')!='none'){ |
| 648 | @ display = 'none'; /* Any already visible - make them all hidden */ |
| 649 | @ break; |
| 650 | @ } |
| 651 | @ } |
| 652 | @ for( var i=0; lists[i]; i++ ){ |
| 653 | @ lists[i].style.display = display; |
| 654 | @ } |
| 655 | @ } |
| 656 | @ |
| 657 | @ var outer_ul = document.querySelector('.filetree > ul'); |
| 658 | @ var subdir = outer_ul.querySelector('.subdir'); |
| 659 | @ outer_ul.onclick = function( e ){ |
| 660 | @ var a = e.target; |
| 661 | @ if( a.nodeName!='A' ) return true; |
| 662 | @ if( a.parentNode==subdir ){ |
| 663 | @ toggleAll(outer_ul); |
| 664 | @ return false; |
| 665 | @ } |
| 666 | @ if( !subdir.contains(a) ) return true; |
| 667 | @ var ul = a.nextSibling; |
| 668 | @ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling; |
| 669 | @ if( !ul ) return true; /* This is a file link, not a directory */ |
| 670 | @ ul.style.display = style(ul, 'display')=='none' ? 'block' : 'none'; |
| 671 | @ return false; |
| 672 | @ } |
| 673 | @ }())</script> |
| 674 | style_footer(); |
| 675 | |
| 676 | /* We could free memory used by sTree here if we needed to. But |
| 677 | ** the process is about to exit, so doing so would not really accomplish |
| 678 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -634,44 +634,65 @@ | |
| 634 | } |
| 635 | } |
| 636 | @ </ul> |
| 637 | @ </ul></div> |
| 638 | @ <script>(function(){ |
| 639 | @ function isExpanded(ul){ |
| 640 | @ var display = window.getComputedStyle(ul).getPropertyValue('display'); |
| 641 | @ return display!='none'; |
| 642 | @ } |
| 643 | @ |
| 644 | @ function toggleDir(a, useInitValue){ |
| 645 | @ var ul = a.nextSibling; |
| 646 | @ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling; |
| 647 | @ if( !ul ) return false; /* This is a file link, not a directory */ |
| 648 | @ if( !useInitValue ) expandMap[a.id] = !isExpanded(ul); |
| 649 | @ ul.style.display = expandMap[a.id] ? 'block' : 'none'; |
| 650 | @ return true; |
| 651 | @ } |
| 652 | @ |
| 653 | @ function toggleAll(tree, useInitValue){ |
| 654 | @ var lists = tree.querySelectorAll('.subdir > ul > li ul'); |
| 655 | @ if( !useInitValue ){ |
| 656 | @ expand = true; /* Default action: make all sublists visible */ |
| 657 | @ for( var i=0; lists[i]; i++ ){ |
| 658 | @ if( isExpanded(lists[i]) ){ |
| 659 | @ expand = false; /* Any already visible - make them all hidden */ |
| 660 | @ break; |
| 661 | @ } |
| 662 | @ } |
| 663 | @ expandMap = {'*': expand}; |
| 664 | @ } |
| 665 | @ var display = expandMap['*'] ? 'block' : 'none'; |
| 666 | @ for( var i=0; lists[i]; i++ ){ |
| 667 | @ lists[i].style.display = display; |
| 668 | @ } |
| 669 | @ } |
| 670 | @ |
| 671 | @ var expandMap; |
| 672 | @ var outer_ul = document.querySelector('.filetree > ul'); |
| 673 | @ var subdir = outer_ul.querySelector('.subdir'); |
| 674 | @ outer_ul.onclick = function(e){ |
| 675 | @ var a = e.target; |
| 676 | @ if( a.nodeName!='A' ) return true; |
| 677 | @ if( a.parentNode==subdir ){ |
| 678 | @ toggleAll(outer_ul); |
| 679 | @ return false; |
| 680 | @ } |
| 681 | @ if( !subdir.contains(a) ) return true; |
| 682 | @ return !toggleDir(a); |
| 683 | @ } |
| 684 | @ addEventListener('pagehide', function(){ |
| 685 | @ sessionStorage.setItem('tree-expandMap', JSON.stringify(expandMap)); |
| 686 | @ }); |
| 687 | @ addEventListener('pageshow', function(){ |
| 688 | @ expandMap = JSON.parse(sessionStorage.getItem('tree-expandMap')) || {}; |
| 689 | @ if( expandMap['*'] ) toggleAll(outer_ul, true); |
| 690 | @ for( var id in expandMap ){ |
| 691 | @ if( id!=='*' ) toggleDir(gebi(id), true); |
| 692 | @ } |
| 693 | @ }); |
| 694 | @ }())</script> |
| 695 | style_footer(); |
| 696 | |
| 697 | /* We could free memory used by sTree here if we needed to. But |
| 698 | ** the process is about to exit, so doing so would not really accomplish |
| 699 |