Fossil SCM

Make tree-view expansions and contractions persist on a "Back" in Chrome and IE. (Works without the extra javascript on Firefox and Safari.)

drh 2014-01-15 02:54 trunk merge
Commit ab00f2b007d5229da6868718bad9ce126bb34506
1 file changed +42 -14
+42 -14
--- src/browse.c
+++ src/browse.c
@@ -418,10 +418,11 @@
418418
FileTreeNode *p; /* One line of the tree */
419419
FileTree sTree; /* The complete tree of files */
420420
HQuery sURI; /* Hyperlink */
421421
int startExpanded; /* True to start out with the tree expanded */
422422
int showDirOnly; /* Show directories only. Omit files */
423
+ int nDir = 0; /* Number of directories. Used for ID attributes */
423424
char *zProjectName = db_get("project-name", 0);
424425
425426
if( strcmp(PD("type",""),"flat")==0 ){ page_dir(); return; }
426427
memset(&sTree, 0, sizeof(sTree));
427428
login_check_credentials();
@@ -602,23 +603,24 @@
602603
}else{
603604
@ <li class="dir subdir">
604605
}
605606
@ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>
606607
@ <ul>
607
- for(p=sTree.pFirst; p; p=p->pNext){
608
+ for(p=sTree.pFirst, nDir=0; p; p=p->pNext){
608609
if( p->isDir ){
609610
if( p->nFullName==nD-1 ){
610611
@ <li class="dir subdir">
611612
}else{
612613
@ <li class="dir">
613614
}
614615
@ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>
615616
if( startExpanded || p->nFullName<=nD ){
616
- @ <ul>
617
+ @ <ul id="dir%d(nDir)">
617618
}else{
618
- @ <ul style='display:none;'>
619
+ @ <ul id="dir%d(nDir)" style='display:none;'>
619620
}
621
+ nDir++;
620622
}else if( !showDirOnly ){
621623
char *zLink;
622624
if( zCI ){
623625
zLink = href("%R/artifact/%S",p->zUuid);
624626
}else{
@@ -634,31 +636,57 @@
634636
}
635637
}
636638
@ </ul>
637639
@ </ul></div>
638640
@ <script>(function(){
639
- @ function style(elem, prop){
640
- @ return window.getComputedStyle(elem).getPropertyValue(prop);
641
+ @ function isExpanded(ul){
642
+ @ var display = window.getComputedStyle(ul).getPropertyValue('display');
643
+ @ return display!='none';
644
+ @ }
645
+ @
646
+ @ function toggleDir(ul, useInitValue){
647
+ @ if( !useInitValue ){
648
+ @ expandMap[ul.id] = !isExpanded(ul);
649
+ @ history.replaceState(expandMap, '');
650
+ @ }
651
+ @ ul.style.display = expandMap[ul.id] ? 'block' : 'none';
641652
@ }
642653
@
643
- @ function toggleAll(tree){
654
+ @ function toggleAll(tree, useInitValue){
644655
@ 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;
656
+ @ if( !useInitValue ){
657
+ @ var expand = true; /* Default action: make all sublists visible */
658
+ @ for( var i=0; lists[i]; i++ ){
659
+ @ if( isExpanded(lists[i]) ){
660
+ @ expand = false; /* Any already visible - make them all hidden */
661
+ @ break;
662
+ @ }
650663
@ }
664
+ @ expandMap = {'*': expand};
665
+ @ history.replaceState(expandMap, '');
651666
@ }
667
+ @ var display = expandMap['*'] ? 'block' : 'none';
652668
@ for( var i=0; lists[i]; i++ ){
653669
@ lists[i].style.display = display;
654670
@ }
655671
@ }
656
- @
672
+ @
673
+ @ function checkState(){
674
+ @ expandMap = history.state || {};
675
+ @ if( expandMap['*'] ) toggleAll(outer_ul, true);
676
+ @ for( var id in expandMap ){
677
+ @ if( id!=='*' ) toggleDir(gebi(id), true);
678
+ @ }
679
+ @ }
680
+ @
681
+ @ /* No-op shim for IE9 */
682
+ @ if( !history.replaceState ) history.replaceState = function(){};
657683
@ var outer_ul = document.querySelector('.filetree > ul');
658684
@ var subdir = outer_ul.querySelector('.subdir');
659
- @ outer_ul.onclick = function( e ){
685
+ @ var expandMap = {};
686
+ @ checkState();
687
+ @ outer_ul.onclick = function(e){
660688
@ var a = e.target;
661689
@ if( a.nodeName!='A' ) return true;
662690
@ if( a.parentNode==subdir ){
663691
@ toggleAll(outer_ul);
664692
@ return false;
@@ -665,11 +693,11 @@
665693
@ }
666694
@ if( !subdir.contains(a) ) return true;
667695
@ var ul = a.nextSibling;
668696
@ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling;
669697
@ if( !ul ) return true; /* This is a file link, not a directory */
670
- @ ul.style.display = style(ul, 'display')=='none' ? 'block' : 'none';
698
+ @ toggleDir(ul);
671699
@ return false;
672700
@ }
673701
@ }())</script>
674702
style_footer();
675703
676704
--- src/browse.c
+++ src/browse.c
@@ -418,10 +418,11 @@
418 FileTreeNode *p; /* One line of the tree */
419 FileTree sTree; /* The complete tree of files */
420 HQuery sURI; /* Hyperlink */
421 int startExpanded; /* True to start out with the tree expanded */
422 int showDirOnly; /* Show directories only. Omit files */
 
423 char *zProjectName = db_get("project-name", 0);
424
425 if( strcmp(PD("type",""),"flat")==0 ){ page_dir(); return; }
426 memset(&sTree, 0, sizeof(sTree));
427 login_check_credentials();
@@ -602,23 +603,24 @@
602 }else{
603 @ <li class="dir subdir">
604 }
605 @ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>
606 @ <ul>
607 for(p=sTree.pFirst; p; p=p->pNext){
608 if( p->isDir ){
609 if( p->nFullName==nD-1 ){
610 @ <li class="dir subdir">
611 }else{
612 @ <li class="dir">
613 }
614 @ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>
615 if( startExpanded || p->nFullName<=nD ){
616 @ <ul>
617 }else{
618 @ <ul style='display:none;'>
619 }
 
620 }else if( !showDirOnly ){
621 char *zLink;
622 if( zCI ){
623 zLink = href("%R/artifact/%S",p->zUuid);
624 }else{
@@ -634,31 +636,57 @@
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,11 +693,11 @@
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
--- src/browse.c
+++ src/browse.c
@@ -418,10 +418,11 @@
418 FileTreeNode *p; /* One line of the tree */
419 FileTree sTree; /* The complete tree of files */
420 HQuery sURI; /* Hyperlink */
421 int startExpanded; /* True to start out with the tree expanded */
422 int showDirOnly; /* Show directories only. Omit files */
423 int nDir = 0; /* Number of directories. Used for ID attributes */
424 char *zProjectName = db_get("project-name", 0);
425
426 if( strcmp(PD("type",""),"flat")==0 ){ page_dir(); return; }
427 memset(&sTree, 0, sizeof(sTree));
428 login_check_credentials();
@@ -602,23 +603,24 @@
603 }else{
604 @ <li class="dir subdir">
605 }
606 @ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>
607 @ <ul>
608 for(p=sTree.pFirst, nDir=0; p; p=p->pNext){
609 if( p->isDir ){
610 if( p->nFullName==nD-1 ){
611 @ <li class="dir subdir">
612 }else{
613 @ <li class="dir">
614 }
615 @ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>
616 if( startExpanded || p->nFullName<=nD ){
617 @ <ul id="dir%d(nDir)">
618 }else{
619 @ <ul id="dir%d(nDir)" style='display:none;'>
620 }
621 nDir++;
622 }else if( !showDirOnly ){
623 char *zLink;
624 if( zCI ){
625 zLink = href("%R/artifact/%S",p->zUuid);
626 }else{
@@ -634,31 +636,57 @@
636 }
637 }
638 @ </ul>
639 @ </ul></div>
640 @ <script>(function(){
641 @ function isExpanded(ul){
642 @ var display = window.getComputedStyle(ul).getPropertyValue('display');
643 @ return display!='none';
644 @ }
645 @
646 @ function toggleDir(ul, useInitValue){
647 @ if( !useInitValue ){
648 @ expandMap[ul.id] = !isExpanded(ul);
649 @ history.replaceState(expandMap, '');
650 @ }
651 @ ul.style.display = expandMap[ul.id] ? 'block' : 'none';
652 @ }
653 @
654 @ function toggleAll(tree, useInitValue){
655 @ var lists = tree.querySelectorAll('.subdir > ul > li ul');
656 @ if( !useInitValue ){
657 @ var expand = true; /* Default action: make all sublists visible */
658 @ for( var i=0; lists[i]; i++ ){
659 @ if( isExpanded(lists[i]) ){
660 @ expand = false; /* Any already visible - make them all hidden */
661 @ break;
662 @ }
663 @ }
664 @ expandMap = {'*': expand};
665 @ history.replaceState(expandMap, '');
666 @ }
667 @ var display = expandMap['*'] ? 'block' : 'none';
668 @ for( var i=0; lists[i]; i++ ){
669 @ lists[i].style.display = display;
670 @ }
671 @ }
672 @
673 @ function checkState(){
674 @ expandMap = history.state || {};
675 @ if( expandMap['*'] ) toggleAll(outer_ul, true);
676 @ for( var id in expandMap ){
677 @ if( id!=='*' ) toggleDir(gebi(id), true);
678 @ }
679 @ }
680 @
681 @ /* No-op shim for IE9 */
682 @ if( !history.replaceState ) history.replaceState = function(){};
683 @ var outer_ul = document.querySelector('.filetree > ul');
684 @ var subdir = outer_ul.querySelector('.subdir');
685 @ var expandMap = {};
686 @ checkState();
687 @ outer_ul.onclick = function(e){
688 @ var a = e.target;
689 @ if( a.nodeName!='A' ) return true;
690 @ if( a.parentNode==subdir ){
691 @ toggleAll(outer_ul);
692 @ return false;
@@ -665,11 +693,11 @@
693 @ }
694 @ if( !subdir.contains(a) ) return true;
695 @ var ul = a.nextSibling;
696 @ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling;
697 @ if( !ul ) return true; /* This is a file link, not a directory */
698 @ toggleDir(ul);
699 @ return false;
700 @ }
701 @ }())</script>
702 style_footer();
703
704

Keyboard Shortcuts

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