@@ -4,16 +4,16 @@ function getRepoUrl() {
44 return `https://useful-forks.github.io/?repo=${ user } /${ repo } `
55}
66
7- function setBtnUrl ( btnId ) {
8- const button = document . getElementById ( btnId ) ;
7+ function setBtnUrl ( ) {
8+ const button = document . getElementById ( UF_BTN_ID ) ;
99 button . addEventListener ( 'click' , ( ) => {
1010 window . open ( getRepoUrl ( ) , '_blank' ) ;
1111 } ) ;
1212}
1313
14- function setContent ( li , btnId ) {
14+ function setContent ( li ) {
1515 const content = `<div class="float-left">
16- <button id="${ btnId } " class="btn-sm btn">
16+ <button id="${ UF_BTN_ID } " class="btn-sm btn">
1717 <svg height="16" width="16" version="1.1" viewBox="0 0 183.79 183.79" class="octicon octicon-pin mr-1">
1818 <path d="M54.734,9.053C39.12,18.067,27.95,32.624,23.284,50.039c-4.667,17.415-2.271,35.606,6.743,51.22 c12.023,20.823,34.441,33.759,58.508,33.759c7.599,0,15.139-1.308,22.287-3.818l30.364,52.592l21.65-12.5l-30.359-52.583 c10.255-8.774,17.638-20.411,21.207-33.73c4.666-17.415,2.27-35.605-6.744-51.22C134.918,12.936,112.499,0,88.433,0 C76.645,0,64.992,3.13,54.734,9.053z M125.29,46.259c5.676,9.831,7.184,21.285,4.246,32.25c-2.938,10.965-9.971,20.13-19.802,25.806 c-6.462,3.731-13.793,5.703-21.199,5.703c-15.163,0-29.286-8.146-36.857-21.259c-5.676-9.831-7.184-21.284-4.245-32.25 c2.938-10.965,9.971-20.13,19.802-25.807C73.696,26.972,81.027,25,88.433,25C103.597,25,117.719,33.146,125.29,46.259z"></path>
1919 </svg>
@@ -24,15 +24,45 @@ function setContent(li, btnId) {
2424}
2525
2626function init ( ) {
27+ // This is required for some cases like on Back/Forward navigation
28+ const oldLi = document . getElementById ( UF_LI_ID ) ;
29+ if ( oldLi ) {
30+ oldLi . remove ( ) ;
31+ }
32+
2733 const forkBtn = document . getElementById ( "fork-button" ) ;
2834 if ( forkBtn ) { // sufficient to know the user is looking at a repository
2935 const parentLi = forkBtn . closest ( "li" ) ;
3036 const newLi = document . createElement ( "li" ) ;
31- const btnId = "useful_forks_btn" ;
32- setContent ( newLi , btnId ) ;
37+ newLi . id = UF_LI_ID
38+ setContent ( newLi ) ;
3339 parentLi . parentNode . insertBefore ( newLi , parentLi ) ;
34- setBtnUrl ( btnId ) ;
40+ setBtnUrl ( ) ;
3541 }
3642}
3743
44+ const UF_LI_ID = "useful_forks_li" ;
45+ const UF_BTN_ID = "useful_forks_btn" ;
3846init ( ) ; // entry point of the script
47+
48+ /*
49+ Without a timeout, the Back/Forward browser navigation ends up messing up
50+ the JavaScript onClick event assigned to the button.
51+ The trade-off here is that the button appears a bit after the page loads.
52+
53+ Moreover, it's worth pointing out that a MutationObserver is required here
54+ because GitHub does some optimizations that do not require reloading an
55+ entire page.
56+ PJax is one of those tricks used, but it does not seem to be exclusive,
57+ hence why `document.addEventListener("pjax:end", init);` is not sufficient.
58+ */
59+ let timeout ;
60+ const observer = new MutationObserver ( ( ) => {
61+ clearTimeout ( timeout ) ;
62+ timeout = setTimeout ( init , 10 ) ;
63+ } ) ;
64+ /*
65+ `subtree: false` is used to reduce the amount of callbacks triggered.
66+ `document.body` may be of narrower scope, but I couldn't figure it out.
67+ */
68+ observer . observe ( document . body , { childList : true , subtree : false } ) ;
0 commit comments