Fossil SCM
Disabled wikiedit save confirmation, by popular demand. (Discard/reload still requires confirmation due to the risk of data loss.) Added link to /wiki/PageName to the per-page links.
Commit
8635cb3d177e884b40e400748508f7036483bf5c9551bd13c4dd410b36a023c5
Parent
f0805380f7b4ddb…
1 file changed
+82
-58
+82
-58
| --- src/fossil.page.wikiedit.js | ||
| +++ src/fossil.page.wikiedit.js | ||
| @@ -67,11 +67,19 @@ | ||
| 67 | 67 | D = F.dom, |
| 68 | 68 | P = F.page; |
| 69 | 69 | P.config = { |
| 70 | 70 | /* Max number of locally-edited pages to stash, after which we |
| 71 | 71 | drop the least-recently used. */ |
| 72 | - defaultMaxStashSize: 10 | |
| 72 | + defaultMaxStashSize: 10, | |
| 73 | + useConfirmerButtons:{ | |
| 74 | + /* If true during fossil.page setup, certain buttons will use a | |
| 75 | + "confirmer" step, else they will not. The confirmer topic has | |
| 76 | + been the source of much contention in the forum. */ | |
| 77 | + save: false, | |
| 78 | + reload: true, | |
| 79 | + discardStash: true | |
| 80 | + } | |
| 73 | 81 | }; |
| 74 | 82 | |
| 75 | 83 | /** |
| 76 | 84 | $stash is an internal-use-only object for managing "stashed" |
| 77 | 85 | local edits, to help avoid that users accidentally lose content |
| @@ -689,15 +697,19 @@ | ||
| 689 | 697 | P.addEventListener('wiki-page-loaded',(e)=>this.updateList($stash, e.detail)); |
| 690 | 698 | sel.addEventListener('change',function(e){ |
| 691 | 699 | const opt = this.selectedOptions[0]; |
| 692 | 700 | if(opt && opt._winfo) P.loadPage(opt._winfo); |
| 693 | 701 | }); |
| 694 | - F.confirmer(btnClear, { | |
| 695 | - confirmText: "REALLY delete ALL local edits?", | |
| 696 | - onconfirm: (e)=>P.clearStash(), | |
| 697 | - ticks: F.config.confirmerButtonTicks | |
| 698 | - }); | |
| 702 | + if(P.config.useConfirmerButtons.discardStash){ | |
| 703 | + F.confirmer(btnClear, { | |
| 704 | + confirmText: "REALLY delete ALL local edits?", | |
| 705 | + onconfirm: ()=>P.clearStash(), | |
| 706 | + ticks: F.config.confirmerButtonTicks | |
| 707 | + }); | |
| 708 | + }else{ | |
| 709 | + btnClear.addEventListener('click', ()=>P.clearStash(), false); | |
| 710 | + } | |
| 699 | 711 | if(F.storage.isTransient()){/*Warn if our storage is particularly transient...*/ |
| 700 | 712 | D.append(wrapper, D.append( |
| 701 | 713 | D.addClass(D.span(),'warning'), |
| 702 | 714 | "Warning: persistent storage is not available, "+ |
| 703 | 715 | "so uncomitted edits will not survive a page reload." |
| @@ -895,61 +907,72 @@ | ||
| 895 | 907 | "click",(e)=>P.diff(false), false |
| 896 | 908 | ); |
| 897 | 909 | if(0) P.e.btnCommit.addEventListener( |
| 898 | 910 | "click",(e)=>P.commit(), false |
| 899 | 911 | ); |
| 900 | - F.confirmer(P.e.btnReload, { | |
| 901 | - confirmText: "Really reload, losing edits?", | |
| 902 | - onconfirm: function(e){ | |
| 903 | - const w = P.winfo; | |
| 904 | - if(!w){ | |
| 905 | - F.error("No page loaded."); | |
| 906 | - return; | |
| 907 | - } | |
| 908 | - if(!w.version/* new/unsaved page */ | |
| 909 | - && w.type!=='sandbox' | |
| 910 | - && P.wikiContent()){ | |
| 911 | - F.error("This new/unsaved page has content.", | |
| 912 | - "To really discard this page,", | |
| 913 | - "first clear its content", | |
| 914 | - "then use the Discard button."); | |
| 915 | - return; | |
| 916 | - } | |
| 917 | - P.unstashContent(); | |
| 918 | - if(w.version || w.type==='sandbox'){ | |
| 919 | - P.loadPage(w); | |
| 920 | - }else{ | |
| 921 | - WikiList.removeEntry(w.name); | |
| 922 | - delete P.winfo; | |
| 923 | - P.updatePageTitle(); | |
| 924 | - F.message("Discarded new page ["+w.name+"]."); | |
| 925 | - } | |
| 926 | - }, | |
| 927 | - ticks: F.config.confirmerButtonTicks | |
| 928 | - }); | |
| 929 | - F.confirmer(P.e.btnSave, { | |
| 930 | - confirmText: "Really save changes?", | |
| 931 | - onconfirm: function(e){ | |
| 932 | - const w = P.winfo; | |
| 933 | - if(!w){ | |
| 934 | - F.error("No page loaded."); | |
| 935 | - return; | |
| 936 | - } | |
| 937 | - setTimeout( | |
| 938 | - ()=>P.save(), 0 | |
| 939 | - /* timeout is a workaround to allow save() to update the | |
| 940 | - button's text (per forum feedback). The idea is to force | |
| 941 | - the call of save() to happen *after* the confirmer | |
| 942 | - callback returns so that we can change the button label | |
| 943 | - without the confirmer setting it back to its | |
| 944 | - pre-confirmed state. This is, however, no guaranty that | |
| 945 | - save() will actually be called *after* the confirmer | |
| 946 | - re-sets the button label. */ | |
| 947 | - ); | |
| 948 | - }, | |
| 949 | - ticks: F.config.confirmerButtonTicks | |
| 950 | - }); | |
| 912 | + const doSave = function(e){ | |
| 913 | + const w = P.winfo; | |
| 914 | + if(!w){ | |
| 915 | + F.error("No page loaded."); | |
| 916 | + return; | |
| 917 | + } | |
| 918 | + setTimeout( | |
| 919 | + ()=>P.save(), 0 | |
| 920 | + /* timeout is a workaround to allow save() to update the | |
| 921 | + button's text (per forum feedback). The idea is to force | |
| 922 | + the call of save() to happen *after* the confirmer | |
| 923 | + callback returns so that we can change the button label | |
| 924 | + without the confirmer setting it back to its | |
| 925 | + pre-confirmed state. This is, however, no guaranty that | |
| 926 | + save() will actually be called *after* the confirmer | |
| 927 | + re-sets the button label. */ | |
| 928 | + ); | |
| 929 | + }; | |
| 930 | + const doReload = function(e){ | |
| 931 | + const w = P.winfo; | |
| 932 | + if(!w){ | |
| 933 | + F.error("No page loaded."); | |
| 934 | + return; | |
| 935 | + } | |
| 936 | + if(!w.version/* new/unsaved page */ | |
| 937 | + && w.type!=='sandbox' | |
| 938 | + && P.wikiContent()){ | |
| 939 | + F.error("This new/unsaved page has content.", | |
| 940 | + "To really discard this page,", | |
| 941 | + "first clear its content", | |
| 942 | + "then use the Discard button."); | |
| 943 | + return; | |
| 944 | + } | |
| 945 | + P.unstashContent(); | |
| 946 | + if(w.version || w.type==='sandbox'){ | |
| 947 | + P.loadPage(w); | |
| 948 | + }else{ | |
| 949 | + WikiList.removeEntry(w.name); | |
| 950 | + delete P.winfo; | |
| 951 | + P.updatePageTitle(); | |
| 952 | + F.message("Discarded new page ["+w.name+"]."); | |
| 953 | + } | |
| 954 | + }; | |
| 955 | + | |
| 956 | + if(P.config.useConfirmerButtons.reload){ | |
| 957 | + F.confirmer(P.e.btnReload, { | |
| 958 | + confirmText: "Really reload, losing edits?", | |
| 959 | + onconfirm: doReload, | |
| 960 | + ticks: F.config.confirmerButtonTicks | |
| 961 | + }); | |
| 962 | + }else{ | |
| 963 | + P.e.btnReload.addEventListener('click', doReload, false); | |
| 964 | + } | |
| 965 | + if(P.config.useConfirmerButtons.save){ | |
| 966 | + F.confirmer(P.e.btnSave, { | |
| 967 | + confirmText: "Really save changes?", | |
| 968 | + onconfirm: doSave, | |
| 969 | + ticks: F.config.confirmerButtonTicks | |
| 970 | + }); | |
| 971 | + }else{ | |
| 972 | + P.e.btnSave.addEventListener('click', doSave, false); | |
| 973 | + } | |
| 951 | 974 | |
| 952 | 975 | P.e.taEditor.addEventListener( |
| 953 | 976 | 'change', ()=>P.stashContentChange(), false |
| 954 | 977 | ); |
| 955 | 978 | |
| @@ -1061,13 +1084,14 @@ | ||
| 1061 | 1084 | var marker = getEditMarker(wi, false); |
| 1062 | 1085 | D.append(f.eName,marker,wi.name); |
| 1063 | 1086 | if(wi.version){ |
| 1064 | 1087 | D.append( |
| 1065 | 1088 | f.eLinks, |
| 1089 | + D.a(F.repoUrl('wiki',{name:wi.name}),"viewer"), | |
| 1066 | 1090 | D.a(F.repoUrl('whistory',{name:wi.name}),'history'), |
| 1067 | 1091 | D.a(F.repoUrl('attachlist',{page:wi.name}),"attachments"), |
| 1068 | - D.a(F.repoUrl('attachadd',{page:wi.name,from: F.repoUrl('wikiedit',{name: wi.name})}), "attach") | |
| 1092 | + D.a(F.repoUrl('attachadd',{page:wi.name,from: F.repoUrl('wikiedit',{name: wi.name})}), "attach") | |
| 1069 | 1093 | ); |
| 1070 | 1094 | } |
| 1071 | 1095 | }; |
| 1072 | 1096 | |
| 1073 | 1097 | /** |
| 1074 | 1098 |
| --- src/fossil.page.wikiedit.js | |
| +++ src/fossil.page.wikiedit.js | |
| @@ -67,11 +67,19 @@ | |
| 67 | D = F.dom, |
| 68 | P = F.page; |
| 69 | P.config = { |
| 70 | /* Max number of locally-edited pages to stash, after which we |
| 71 | drop the least-recently used. */ |
| 72 | defaultMaxStashSize: 10 |
| 73 | }; |
| 74 | |
| 75 | /** |
| 76 | $stash is an internal-use-only object for managing "stashed" |
| 77 | local edits, to help avoid that users accidentally lose content |
| @@ -689,15 +697,19 @@ | |
| 689 | P.addEventListener('wiki-page-loaded',(e)=>this.updateList($stash, e.detail)); |
| 690 | sel.addEventListener('change',function(e){ |
| 691 | const opt = this.selectedOptions[0]; |
| 692 | if(opt && opt._winfo) P.loadPage(opt._winfo); |
| 693 | }); |
| 694 | F.confirmer(btnClear, { |
| 695 | confirmText: "REALLY delete ALL local edits?", |
| 696 | onconfirm: (e)=>P.clearStash(), |
| 697 | ticks: F.config.confirmerButtonTicks |
| 698 | }); |
| 699 | if(F.storage.isTransient()){/*Warn if our storage is particularly transient...*/ |
| 700 | D.append(wrapper, D.append( |
| 701 | D.addClass(D.span(),'warning'), |
| 702 | "Warning: persistent storage is not available, "+ |
| 703 | "so uncomitted edits will not survive a page reload." |
| @@ -895,61 +907,72 @@ | |
| 895 | "click",(e)=>P.diff(false), false |
| 896 | ); |
| 897 | if(0) P.e.btnCommit.addEventListener( |
| 898 | "click",(e)=>P.commit(), false |
| 899 | ); |
| 900 | F.confirmer(P.e.btnReload, { |
| 901 | confirmText: "Really reload, losing edits?", |
| 902 | onconfirm: function(e){ |
| 903 | const w = P.winfo; |
| 904 | if(!w){ |
| 905 | F.error("No page loaded."); |
| 906 | return; |
| 907 | } |
| 908 | if(!w.version/* new/unsaved page */ |
| 909 | && w.type!=='sandbox' |
| 910 | && P.wikiContent()){ |
| 911 | F.error("This new/unsaved page has content.", |
| 912 | "To really discard this page,", |
| 913 | "first clear its content", |
| 914 | "then use the Discard button."); |
| 915 | return; |
| 916 | } |
| 917 | P.unstashContent(); |
| 918 | if(w.version || w.type==='sandbox'){ |
| 919 | P.loadPage(w); |
| 920 | }else{ |
| 921 | WikiList.removeEntry(w.name); |
| 922 | delete P.winfo; |
| 923 | P.updatePageTitle(); |
| 924 | F.message("Discarded new page ["+w.name+"]."); |
| 925 | } |
| 926 | }, |
| 927 | ticks: F.config.confirmerButtonTicks |
| 928 | }); |
| 929 | F.confirmer(P.e.btnSave, { |
| 930 | confirmText: "Really save changes?", |
| 931 | onconfirm: function(e){ |
| 932 | const w = P.winfo; |
| 933 | if(!w){ |
| 934 | F.error("No page loaded."); |
| 935 | return; |
| 936 | } |
| 937 | setTimeout( |
| 938 | ()=>P.save(), 0 |
| 939 | /* timeout is a workaround to allow save() to update the |
| 940 | button's text (per forum feedback). The idea is to force |
| 941 | the call of save() to happen *after* the confirmer |
| 942 | callback returns so that we can change the button label |
| 943 | without the confirmer setting it back to its |
| 944 | pre-confirmed state. This is, however, no guaranty that |
| 945 | save() will actually be called *after* the confirmer |
| 946 | re-sets the button label. */ |
| 947 | ); |
| 948 | }, |
| 949 | ticks: F.config.confirmerButtonTicks |
| 950 | }); |
| 951 | |
| 952 | P.e.taEditor.addEventListener( |
| 953 | 'change', ()=>P.stashContentChange(), false |
| 954 | ); |
| 955 | |
| @@ -1061,13 +1084,14 @@ | |
| 1061 | var marker = getEditMarker(wi, false); |
| 1062 | D.append(f.eName,marker,wi.name); |
| 1063 | if(wi.version){ |
| 1064 | D.append( |
| 1065 | f.eLinks, |
| 1066 | D.a(F.repoUrl('whistory',{name:wi.name}),'history'), |
| 1067 | D.a(F.repoUrl('attachlist',{page:wi.name}),"attachments"), |
| 1068 | D.a(F.repoUrl('attachadd',{page:wi.name,from: F.repoUrl('wikiedit',{name: wi.name})}), "attach") |
| 1069 | ); |
| 1070 | } |
| 1071 | }; |
| 1072 | |
| 1073 | /** |
| 1074 |
| --- src/fossil.page.wikiedit.js | |
| +++ src/fossil.page.wikiedit.js | |
| @@ -67,11 +67,19 @@ | |
| 67 | D = F.dom, |
| 68 | P = F.page; |
| 69 | P.config = { |
| 70 | /* Max number of locally-edited pages to stash, after which we |
| 71 | drop the least-recently used. */ |
| 72 | defaultMaxStashSize: 10, |
| 73 | useConfirmerButtons:{ |
| 74 | /* If true during fossil.page setup, certain buttons will use a |
| 75 | "confirmer" step, else they will not. The confirmer topic has |
| 76 | been the source of much contention in the forum. */ |
| 77 | save: false, |
| 78 | reload: true, |
| 79 | discardStash: true |
| 80 | } |
| 81 | }; |
| 82 | |
| 83 | /** |
| 84 | $stash is an internal-use-only object for managing "stashed" |
| 85 | local edits, to help avoid that users accidentally lose content |
| @@ -689,15 +697,19 @@ | |
| 697 | P.addEventListener('wiki-page-loaded',(e)=>this.updateList($stash, e.detail)); |
| 698 | sel.addEventListener('change',function(e){ |
| 699 | const opt = this.selectedOptions[0]; |
| 700 | if(opt && opt._winfo) P.loadPage(opt._winfo); |
| 701 | }); |
| 702 | if(P.config.useConfirmerButtons.discardStash){ |
| 703 | F.confirmer(btnClear, { |
| 704 | confirmText: "REALLY delete ALL local edits?", |
| 705 | onconfirm: ()=>P.clearStash(), |
| 706 | ticks: F.config.confirmerButtonTicks |
| 707 | }); |
| 708 | }else{ |
| 709 | btnClear.addEventListener('click', ()=>P.clearStash(), false); |
| 710 | } |
| 711 | if(F.storage.isTransient()){/*Warn if our storage is particularly transient...*/ |
| 712 | D.append(wrapper, D.append( |
| 713 | D.addClass(D.span(),'warning'), |
| 714 | "Warning: persistent storage is not available, "+ |
| 715 | "so uncomitted edits will not survive a page reload." |
| @@ -895,61 +907,72 @@ | |
| 907 | "click",(e)=>P.diff(false), false |
| 908 | ); |
| 909 | if(0) P.e.btnCommit.addEventListener( |
| 910 | "click",(e)=>P.commit(), false |
| 911 | ); |
| 912 | const doSave = function(e){ |
| 913 | const w = P.winfo; |
| 914 | if(!w){ |
| 915 | F.error("No page loaded."); |
| 916 | return; |
| 917 | } |
| 918 | setTimeout( |
| 919 | ()=>P.save(), 0 |
| 920 | /* timeout is a workaround to allow save() to update the |
| 921 | button's text (per forum feedback). The idea is to force |
| 922 | the call of save() to happen *after* the confirmer |
| 923 | callback returns so that we can change the button label |
| 924 | without the confirmer setting it back to its |
| 925 | pre-confirmed state. This is, however, no guaranty that |
| 926 | save() will actually be called *after* the confirmer |
| 927 | re-sets the button label. */ |
| 928 | ); |
| 929 | }; |
| 930 | const doReload = function(e){ |
| 931 | const w = P.winfo; |
| 932 | if(!w){ |
| 933 | F.error("No page loaded."); |
| 934 | return; |
| 935 | } |
| 936 | if(!w.version/* new/unsaved page */ |
| 937 | && w.type!=='sandbox' |
| 938 | && P.wikiContent()){ |
| 939 | F.error("This new/unsaved page has content.", |
| 940 | "To really discard this page,", |
| 941 | "first clear its content", |
| 942 | "then use the Discard button."); |
| 943 | return; |
| 944 | } |
| 945 | P.unstashContent(); |
| 946 | if(w.version || w.type==='sandbox'){ |
| 947 | P.loadPage(w); |
| 948 | }else{ |
| 949 | WikiList.removeEntry(w.name); |
| 950 | delete P.winfo; |
| 951 | P.updatePageTitle(); |
| 952 | F.message("Discarded new page ["+w.name+"]."); |
| 953 | } |
| 954 | }; |
| 955 | |
| 956 | if(P.config.useConfirmerButtons.reload){ |
| 957 | F.confirmer(P.e.btnReload, { |
| 958 | confirmText: "Really reload, losing edits?", |
| 959 | onconfirm: doReload, |
| 960 | ticks: F.config.confirmerButtonTicks |
| 961 | }); |
| 962 | }else{ |
| 963 | P.e.btnReload.addEventListener('click', doReload, false); |
| 964 | } |
| 965 | if(P.config.useConfirmerButtons.save){ |
| 966 | F.confirmer(P.e.btnSave, { |
| 967 | confirmText: "Really save changes?", |
| 968 | onconfirm: doSave, |
| 969 | ticks: F.config.confirmerButtonTicks |
| 970 | }); |
| 971 | }else{ |
| 972 | P.e.btnSave.addEventListener('click', doSave, false); |
| 973 | } |
| 974 | |
| 975 | P.e.taEditor.addEventListener( |
| 976 | 'change', ()=>P.stashContentChange(), false |
| 977 | ); |
| 978 | |
| @@ -1061,13 +1084,14 @@ | |
| 1084 | var marker = getEditMarker(wi, false); |
| 1085 | D.append(f.eName,marker,wi.name); |
| 1086 | if(wi.version){ |
| 1087 | D.append( |
| 1088 | f.eLinks, |
| 1089 | D.a(F.repoUrl('wiki',{name:wi.name}),"viewer"), |
| 1090 | D.a(F.repoUrl('whistory',{name:wi.name}),'history'), |
| 1091 | D.a(F.repoUrl('attachlist',{page:wi.name}),"attachments"), |
| 1092 | D.a(F.repoUrl('attachadd',{page:wi.name,from: F.repoUrl('wikiedit',{name: wi.name})}), "attach") |
| 1093 | ); |
| 1094 | } |
| 1095 | }; |
| 1096 | |
| 1097 | /** |
| 1098 |