Fossil SCM
/chat: experimental HTML5 history support for using the back button to return to a message from which a #nnn message ID was clicked.
Commit
9df3fc6b0f2c4becf4ea54bec6342f69d8bc514c8c0b1e1c95eb647ec77ddaee
Parent
99b23d0fa357acc…
1 file changed
+21
-12
+21
-12
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -889,39 +889,47 @@ | ||
| 889 | 889 | }, false); |
| 890 | 890 | return cs; |
| 891 | 891 | })()/*Chat initialization*/; |
| 892 | 892 | |
| 893 | 893 | /** |
| 894 | - An experiment in history navigation: when a message numref is | |
| 894 | + An experiment in history navigation: when a message numtag is | |
| 895 | 895 | clicked, we push the origin message onto the history and |
| 896 | 896 | set up the back button to return to that message. |
| 897 | 897 | */ |
| 898 | - if(0) window.onpopstate = function(event){ | |
| 899 | - console.debug("onpopstate event",event.state, event); | |
| 900 | - if(event.state && event.state.msgId){ | |
| 898 | + window.onpopstate = function(event){ | |
| 899 | + const msgid = Chat.numtagHistoryStack.pop(); | |
| 900 | + if(msgid){ | |
| 901 | 901 | const e = Chat.setCurrentView(Chat.e.viewMessages). |
| 902 | - querySelector('.message-widget[data-msgid="'+event.state.msgId+'"]'); | |
| 903 | - console.debug("Popping history back to",event.state, e); | |
| 902 | + querySelector('.message-widget[data-msgid="'+msgid+'"]'); | |
| 903 | + //console.debug("Popping history back to",msgid, e); | |
| 904 | 904 | if(e){ |
| 905 | 905 | Chat.MessageWidget.scrollToMessageElem(e); |
| 906 | - //F.page.setPageTitle("Fossil Chat #"+event.state.msgId); | |
| 907 | 906 | return; |
| 908 | 907 | } |
| 909 | 908 | } |
| 910 | 909 | Chat.scrollMessagesTo(1); |
| 911 | 910 | }; |
| 911 | + Chat.numtagHistoryStack = [ | |
| 912 | + /* Relying on the pushHistory() state object for holding | |
| 913 | + the message ID is completely misbehaving, not giving | |
| 914 | + us the expected state object when window.onpopstate | |
| 915 | + is triggered (plus, the browser persists it, which | |
| 916 | + introduces its own problems). Thus we use our own | |
| 917 | + stack of message IDs for history navigation purposes. */]; | |
| 912 | 918 | |
| 919 | + /** If e or one of its parents has the given CSS class, that element | |
| 920 | + is returned, else falsy is returned. */ | |
| 913 | 921 | const findParentWithClass = function(e, className){ |
| 914 | 922 | while(e && !e.classList.contains(className)){ |
| 915 | 923 | e = e.parentNode; |
| 916 | 924 | } |
| 917 | 925 | return e; |
| 918 | 926 | }; |
| 919 | 927 | |
| 920 | 928 | /** To be passed each MessageWidget's top-level DOM element |
| 921 | 929 | after initial processing of the message, to set up |
| 922 | - hashtag references. */ | |
| 930 | + hashtag and numtag references. */ | |
| 923 | 931 | const setupHashtags = function f(elem){ |
| 924 | 932 | if(!f.$click){ |
| 925 | 933 | f.$click = function(ev){ |
| 926 | 934 | /* Click handler for hashtags */ |
| 927 | 935 | const tag = ev.target.dataset.hashtag; |
| @@ -940,16 +948,17 @@ | ||
| 940 | 948 | '.message-widget[data-msgid="'+tag+'"]' |
| 941 | 949 | ); |
| 942 | 950 | if(e){ |
| 943 | 951 | Chat.MessageWidget.scrollToMessageElem(e); |
| 944 | 952 | //Set up window.history() state... |
| 945 | - const p = 1 ? false : findParentWithClass(ev.target, 'message-widget'); | |
| 953 | + const p = 0 ? false : findParentWithClass(ev.target, 'message-widget'); | |
| 946 | 954 | if(p){ |
| 947 | 955 | const state = {msgId: p.dataset.msgid}; |
| 948 | - console.debug("Pushing history for msgid", state); | |
| 949 | - const rc = window.history.pushState(state, "?"); | |
| 950 | - console.debug("History length =",window.history.length, rc); | |
| 956 | + Chat.numtagHistoryStack.push(p.dataset.msgid); | |
| 957 | + const rc = window.history.pushState(state, ""); | |
| 958 | + //console.debug("Pushing history for msgid", state); | |
| 959 | + //console.debug("Chat.numtagHistoryStack =",Chat.numtagHistoryStack); | |
| 951 | 960 | } |
| 952 | 961 | }else{ |
| 953 | 962 | F.toast.warning("Message #"+tag+" not found in loaded messages."); |
| 954 | 963 | } |
| 955 | 964 | } |
| 956 | 965 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -889,39 +889,47 @@ | |
| 889 | }, false); |
| 890 | return cs; |
| 891 | })()/*Chat initialization*/; |
| 892 | |
| 893 | /** |
| 894 | An experiment in history navigation: when a message numref is |
| 895 | clicked, we push the origin message onto the history and |
| 896 | set up the back button to return to that message. |
| 897 | */ |
| 898 | if(0) window.onpopstate = function(event){ |
| 899 | console.debug("onpopstate event",event.state, event); |
| 900 | if(event.state && event.state.msgId){ |
| 901 | const e = Chat.setCurrentView(Chat.e.viewMessages). |
| 902 | querySelector('.message-widget[data-msgid="'+event.state.msgId+'"]'); |
| 903 | console.debug("Popping history back to",event.state, e); |
| 904 | if(e){ |
| 905 | Chat.MessageWidget.scrollToMessageElem(e); |
| 906 | //F.page.setPageTitle("Fossil Chat #"+event.state.msgId); |
| 907 | return; |
| 908 | } |
| 909 | } |
| 910 | Chat.scrollMessagesTo(1); |
| 911 | }; |
| 912 | |
| 913 | const findParentWithClass = function(e, className){ |
| 914 | while(e && !e.classList.contains(className)){ |
| 915 | e = e.parentNode; |
| 916 | } |
| 917 | return e; |
| 918 | }; |
| 919 | |
| 920 | /** To be passed each MessageWidget's top-level DOM element |
| 921 | after initial processing of the message, to set up |
| 922 | hashtag references. */ |
| 923 | const setupHashtags = function f(elem){ |
| 924 | if(!f.$click){ |
| 925 | f.$click = function(ev){ |
| 926 | /* Click handler for hashtags */ |
| 927 | const tag = ev.target.dataset.hashtag; |
| @@ -940,16 +948,17 @@ | |
| 940 | '.message-widget[data-msgid="'+tag+'"]' |
| 941 | ); |
| 942 | if(e){ |
| 943 | Chat.MessageWidget.scrollToMessageElem(e); |
| 944 | //Set up window.history() state... |
| 945 | const p = 1 ? false : findParentWithClass(ev.target, 'message-widget'); |
| 946 | if(p){ |
| 947 | const state = {msgId: p.dataset.msgid}; |
| 948 | console.debug("Pushing history for msgid", state); |
| 949 | const rc = window.history.pushState(state, "?"); |
| 950 | console.debug("History length =",window.history.length, rc); |
| 951 | } |
| 952 | }else{ |
| 953 | F.toast.warning("Message #"+tag+" not found in loaded messages."); |
| 954 | } |
| 955 | } |
| 956 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -889,39 +889,47 @@ | |
| 889 | }, false); |
| 890 | return cs; |
| 891 | })()/*Chat initialization*/; |
| 892 | |
| 893 | /** |
| 894 | An experiment in history navigation: when a message numtag is |
| 895 | clicked, we push the origin message onto the history and |
| 896 | set up the back button to return to that message. |
| 897 | */ |
| 898 | window.onpopstate = function(event){ |
| 899 | const msgid = Chat.numtagHistoryStack.pop(); |
| 900 | if(msgid){ |
| 901 | const e = Chat.setCurrentView(Chat.e.viewMessages). |
| 902 | querySelector('.message-widget[data-msgid="'+msgid+'"]'); |
| 903 | //console.debug("Popping history back to",msgid, e); |
| 904 | if(e){ |
| 905 | Chat.MessageWidget.scrollToMessageElem(e); |
| 906 | return; |
| 907 | } |
| 908 | } |
| 909 | Chat.scrollMessagesTo(1); |
| 910 | }; |
| 911 | Chat.numtagHistoryStack = [ |
| 912 | /* Relying on the pushHistory() state object for holding |
| 913 | the message ID is completely misbehaving, not giving |
| 914 | us the expected state object when window.onpopstate |
| 915 | is triggered (plus, the browser persists it, which |
| 916 | introduces its own problems). Thus we use our own |
| 917 | stack of message IDs for history navigation purposes. */]; |
| 918 | |
| 919 | /** If e or one of its parents has the given CSS class, that element |
| 920 | is returned, else falsy is returned. */ |
| 921 | const findParentWithClass = function(e, className){ |
| 922 | while(e && !e.classList.contains(className)){ |
| 923 | e = e.parentNode; |
| 924 | } |
| 925 | return e; |
| 926 | }; |
| 927 | |
| 928 | /** To be passed each MessageWidget's top-level DOM element |
| 929 | after initial processing of the message, to set up |
| 930 | hashtag and numtag references. */ |
| 931 | const setupHashtags = function f(elem){ |
| 932 | if(!f.$click){ |
| 933 | f.$click = function(ev){ |
| 934 | /* Click handler for hashtags */ |
| 935 | const tag = ev.target.dataset.hashtag; |
| @@ -940,16 +948,17 @@ | |
| 948 | '.message-widget[data-msgid="'+tag+'"]' |
| 949 | ); |
| 950 | if(e){ |
| 951 | Chat.MessageWidget.scrollToMessageElem(e); |
| 952 | //Set up window.history() state... |
| 953 | const p = 0 ? false : findParentWithClass(ev.target, 'message-widget'); |
| 954 | if(p){ |
| 955 | const state = {msgId: p.dataset.msgid}; |
| 956 | Chat.numtagHistoryStack.push(p.dataset.msgid); |
| 957 | const rc = window.history.pushState(state, ""); |
| 958 | //console.debug("Pushing history for msgid", state); |
| 959 | //console.debug("Chat.numtagHistoryStack =",Chat.numtagHistoryStack); |
| 960 | } |
| 961 | }else{ |
| 962 | F.toast.warning("Message #"+tag+" not found in loaded messages."); |
| 963 | } |
| 964 | } |
| 965 |