Fossil

Check-in [fb77abd3]
Login

Check-in [fb77abd3]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Reworked how /wikiedit edit status is displayed, added history/attachment links to the new info bar, and remove attachment links from the Help tab.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: fb77abd3b5b116b423870f3045aa464172d6900712e007094da54792f6009d0d
User & Date: stephan 2020-08-01 16:07:22
Context
2020-08-01
17:56
Style tweaks and re-did how the OPTION elements are marked is-new/is-modified so that the mobile browsers can show that state. ... (check-in: d9f4b6db user: stephan tags: trunk)
16:07
Reworked how /wikiedit edit status is displayed, added history/attachment links to the new info bar, and remove attachment links from the Help tab. ... (check-in: fb77abd3 user: stephan tags: trunk)
13:53
Merged in the Ajax-based /wikiedit reimplementation. ... (check-in: 19f27535 user: stephan tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/fossil.page.wikiedit.js.

589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
      btnSave: E("button.wikiedit-save"),
      selectMimetype: E('select[name=mimetype]'),
      selectFontSizeWrap: E('#select-font-size'),
//      selectDiffWS:  E('select[name=diff_ws]'),
      cbAutoPreview: E('#cb-preview-autoupdate > input[type=checkbox]'),
      previewTarget: E('#wikiedit-tab-preview-wrapper'),
      diffTarget: E('#wikiedit-tab-diff-wrapper'),
      attachmentWrapper: E("#wikiedit-attachments"),
      tabContainer: E('#wikiedit-tabs'),
      tabs:{
        pageList: E('#wikiedit-tab-pages'),
        content: E('#wikiedit-tab-content'),
        preview: E('#wikiedit-tab-preview'),
        diff: E('#wikiedit-tab-diff'),
        misc: E('#wikiedit-tab-misc')
        //commit: E('#wikiedit-tab-commit')
      }
    };
    P.tabs = new fossil.TabManager(D.clearElement(P.e.tabContainer));

    P.tabs.e.container.insertBefore(
      /* Move the status bar between the tab buttons and
         tab panels. Seems to be the best fit in terms of
         functionality and visibility. */
      E('#fossil-status-bar'), P.tabs.e.tabs
    );
    P.tabs.addEventListener(







|











>







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
      btnSave: E("button.wikiedit-save"),
      selectMimetype: E('select[name=mimetype]'),
      selectFontSizeWrap: E('#select-font-size'),
//      selectDiffWS:  E('select[name=diff_ws]'),
      cbAutoPreview: E('#cb-preview-autoupdate > input[type=checkbox]'),
      previewTarget: E('#wikiedit-tab-preview-wrapper'),
      diffTarget: E('#wikiedit-tab-diff-wrapper'),
      editStatus: E('#wikiedit-edit-status'),
      tabContainer: E('#wikiedit-tabs'),
      tabs:{
        pageList: E('#wikiedit-tab-pages'),
        content: E('#wikiedit-tab-content'),
        preview: E('#wikiedit-tab-preview'),
        diff: E('#wikiedit-tab-diff'),
        misc: E('#wikiedit-tab-misc')
        //commit: E('#wikiedit-tab-commit')
      }
    };
    P.tabs = new fossil.TabManager(D.clearElement(P.e.tabContainer));
    P.tabs.e.container.insertBefore(P.e.editStatus, P.tabs.e.tabs);
    P.tabs.e.container.insertBefore(
      /* Move the status bar between the tab buttons and
         tab panels. Seems to be the best fit in terms of
         functionality and visibility. */
      E('#fossil-status-bar'), P.tabs.e.tabs
    );
    P.tabs.addEventListener(
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
             current SBS diff widget is wider than the window. When
             the diff IS in view then CSS overflow magically reduces
             the page size again. Weird. Maybe FF-specific. Note that
             this weirdness happens even though P.e.diffTarget's parent
             is hidden (and therefore P.e.diffTarget is also hidden).
          */
          D.removeClass(P.e.diffTarget, 'hidden');
        }else if(theTab===P.e.tabs.misc){
          P.updateAttachmentView();
        }
      }
    );
    P.tabs.addEventListener(
      /* Set up auto-refresh of the preview tab... */
      'before-switch-from', function(ev){
        const theTab = ev.detail;







<
<







631
632
633
634
635
636
637


638
639
640
641
642
643
644
             current SBS diff widget is wider than the window. When
             the diff IS in view then CSS overflow magically reduces
             the page size again. Weird. Maybe FF-specific. Note that
             this weirdness happens even though P.e.diffTarget's parent
             is hidden (and therefore P.e.diffTarget is also hidden).
          */
          D.removeClass(P.e.diffTarget, 'hidden');


        }
      }
    );
    P.tabs.addEventListener(
      /* Set up auto-refresh of the preview tab... */
      'before-switch-from', function(ev){
        const theTab = ev.detail;
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795




























796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
        P.winfo = winfo;
        P.previewNeedsUpdate = true;
        P.e.selectMimetype.value = winfo.mimetype;
        P.tabs.switchToTab(P.e.tabs.content);
        P.wikiContent(winfo.content || '');
        WikiList.e.select.value = winfo.name;
        if(!winfo.version && winfo.type!=='sandbox'){
          F.error('You are editing a new, unsaved page:',winfo.name);
        }
        P.updatePageTitle();
      },
      false
    );
    P.addEventListener('wiki-stash-updated', ()=>P.updateSaveButton())
      .updatePageTitle().updateAttachmentView().updateSaveButton();
  }/*F.onPageLoad()*/);

  /**
     Returns true if fossil.page.winfo is set, indicating that a page
     has been loaded, else it reports an error and returns false.

     If passed a truthy value any error message about not having
     a wiki page loaded is suppressed.
  */
  const affirmPageLoaded = function(quiet){
    if(!P.winfo && !quiet) F.error("No wiki page is loaded.");
    return !!P.winfo;
  };





























  /**
     Update the page title and header based on the state of
     this.winfo. A no-op if this.winfo is not set. Returns this.
  */
  P.updatePageTitle = function f(){
    if(!f.titleElement){
      f.titleElement = document.head.querySelector('title');
      f.pageTitleHeader = document.querySelector('#wikiedit-page-name > span');
    }
    var title = [];
    const wi = P.winfo;
    if(wi){
      if(!wi.version && 'sandbox'!==wi.type) title.push(P.config.editStateMarkers.isNew);
      else if($stash.getWinfo(wi)) title.push(P.config.editStateMarkers.isModified)
      title.push(wi.name);
    }else{
      title.push('(no page loaded)');
    }
    title = title.join(' ');
    f.pageTitleHeader.innerText = title;
    f.titleElement.innerText = 'Wiki Editor:' + title;

    return this;
  };

  /**
     Change the save button depending on whether we have stuff to save
     or not.
  */
  P.updateSaveButton = function(){
    if(!this.winfo || !this.getStashedWinfo(this.winfo)){
      D.disable(this.e.btnSave).innerText =
        "There are no changes to save";
    }else{
      D.enable(this.e.btnSave).innerText = "Save changes";
    }
    return this;
  };

  /** Updates attachment-related links and returns this. */
  P.updateAttachmentView = function(){
    const wrapper = P.e.attachmentWrapper;
    D.clearElement(wrapper);
    const ul = D.ul();
    D.append(wrapper, ul);
    if(!P.winfo){
      D.append(D.li(ul),
               "Load a page to get access to its attachment-related pages.");
      return this;
    }else if(!P.winfo.version){
      D.append(D.li(ul),
               "A new/unsaved page cannot have attachments. Save it first.");
      return this;
    }
    const wi = P.winfo;
    D.append(
      D.li(ul),
      D.a(F.repoUrl('attachadd',{
        page:wi.name,
        from: F.repoUrl('wikiedit',{
          name: wi.name
        })
      }), "Add attachments.")
    );
    D.append(
      D.li(ul),
      D.a(F.repoUrl('attachlist',{page:wi.name}),
          "List attachments"),
      " (if any)."
    );
    return this;
  };
  
  /**
     Getter (if called with no args) or setter (if passed an arg) for
     the current file content.

     The setter form sets the content, dispatches a
     'wiki-content-replaced' event, and returns this object.
  */







|






|













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








<

|


|
|
|

|

<
<
|
>

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840


841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859


































860
861
862
863
864
865
866
        P.winfo = winfo;
        P.previewNeedsUpdate = true;
        P.e.selectMimetype.value = winfo.mimetype;
        P.tabs.switchToTab(P.e.tabs.content);
        P.wikiContent(winfo.content || '');
        WikiList.e.select.value = winfo.name;
        if(!winfo.version && winfo.type!=='sandbox'){
          F.message('You are editing a new, unsaved page:',winfo.name);
        }
        P.updatePageTitle();
      },
      false
    );
    P.addEventListener('wiki-stash-updated', ()=>P.updateSaveButton())
      .updatePageTitle().updateSaveButton();
  }/*F.onPageLoad()*/);

  /**
     Returns true if fossil.page.winfo is set, indicating that a page
     has been loaded, else it reports an error and returns false.

     If passed a truthy value any error message about not having
     a wiki page loaded is suppressed.
  */
  const affirmPageLoaded = function(quiet){
    if(!P.winfo && !quiet) F.error("No wiki page is loaded.");
    return !!P.winfo;
  };

  /** Updates the in-tab title/edit status information */
  P.updateEditStatus = function f(editFlag/*for use by updatePageTitle() only*/){
    if(!f.eLinks){
      f.eName = P.e.editStatus.querySelector('span.name');
      f.eLinks = P.e.editStatus.querySelector('span.links');
    }
    const wi = this.winfo;
    D.clearElement(f.eName, f.eLinks);
    if(!wi){
      D.append(f.eName, '(no page loaded)');
      return;
    }
    var marker = editFlag || '';
    if(0===arguments){
      if(!wi.version && 'sandbox'!==wi.type) marker = P.config.editStateMarkers.isNew;
      else if($stash.getWinfo(wi)) marker = P.config.editStateMarkers.isModified;
    }
    D.append(f.eName,marker,wi.name,);
    if(wi.version){
      D.append(
        f.eLinks,
        D.a(F.repoUrl('whistory',{name:wi.name}),'[history]'),
        D.a(F.repoUrl('attachlist',{page:wi.name}),"[attachments]"),
        D.a(F.repoUrl('attachadd',{page:wi.name,from: F.repoUrl('wikiedit',{name: wi.name})}), "[attach]")
      );
    }
  };

  /**
     Update the page title and header based on the state of
     this.winfo. A no-op if this.winfo is not set. Returns this.
  */
  P.updatePageTitle = function f(){
    if(!f.titleElement){
      f.titleElement = document.head.querySelector('title');

    }
    var title, marker = '';
    const wi = P.winfo;
    if(wi){
      if(!wi.version && 'sandbox'!==wi.type) marker = P.config.editStateMarkers.isNew;
      else if($stash.getWinfo(wi)) marker = P.config.editStateMarkers.isModified;
      title = wi.name;
    }else{
      title = 'no page loaded';
    }


    f.titleElement.innerText = 'Wiki Editor: ' + marker + title;
    this.updateEditStatus(marker);
    return this;
  };

  /**
     Change the save button depending on whether we have stuff to save
     or not.
  */
  P.updateSaveButton = function(){
    if(!this.winfo || !this.getStashedWinfo(this.winfo)){
      D.disable(this.e.btnSave).innerText =
        "There are no changes to save";
    }else{
      D.enable(this.e.btnSave).innerText = "Save changes";
    }
    return this;
  };



































  /**
     Getter (if called with no args) or setter (if passed an arg) for
     the current file content.

     The setter form sets the content, dispatches a
     'wiki-content-replaced' event, and returns this object.
  */

Changes to src/style.wikiedit.css.

115
116
117
118
119
120
121
122









123








124
body.wikiedit span.save-button-slot {
  /* These invisible placeholders mark spots in the UI
     (max. 1 per tab) to where the save button gets
     relocated as we switch between tabs. */
  display: none;
}

body.wikiedit #wikiedit-page-name > span {









  font-family: monospace;








}







|
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
body.wikiedit span.save-button-slot {
  /* These invisible placeholders mark spots in the UI
     (max. 1 per tab) to where the save button gets
     relocated as we switch between tabs. */
  display: none;
}

body.wikiedit #wikiedit-edit-status {
  border-radius: 0.25em 0.25em 0 0;
  margin: 0;
  padding: 0;
  width: 100%;
  cursor: initial;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
  font-family: monospace;
  font-size: 1.2em;
}

body.wikiedit #wikiedit-edit-status > span {
  display: block;
}
body.wikiedit #wikiedit-edit-status > span.links > a {
  margin: 0 0.25em;
}

Changes to src/wiki.c.

1104
1105
1106
1107
1108
1109
1110
1111



1112
1113
1114
1115
1116
1117
1118

  /* Status bar */
  CX("<div id='fossil-status-bar' "
     "title='Status message area. Double-click to clear them.'>"
     "Status messages will go here.</div>\n"
     /* will be moved into the tab container via JS */);

  CX("<div id='wikiedit-page-name'>Editing: <span>(no file loaded)</span></div>");



  
  /* Main tab container... */
  CX("<div id='wikiedit-tabs' class='tab-container'>Loading...</div>");
  /* The .hidden class on the following tab elements is to help lessen
     the FOUC effect of the tabs before JS re-assembles them. */

  /******* Page list *******/







|
>
>
>







1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121

  /* Status bar */
  CX("<div id='fossil-status-bar' "
     "title='Status message area. Double-click to clear them.'>"
     "Status messages will go here.</div>\n"
     /* will be moved into the tab container via JS */);

  CX("<div id='wikiedit-edit-status''>"
     "<span class='name'></span>"
     "<span class='links'></span>"
     "</div>");
  
  /* Main tab container... */
  CX("<div id='wikiedit-tabs' class='tab-container'>Loading...</div>");
  /* The .hidden class on the following tab elements is to help lessen
     the FOUC effect of the tabs before JS re-assembles them. */

  /******* Page list *******/
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
    CX("</div>"/*#wikiedit-tab-diff*/);
  }

  /****** The obligatory "Misc" tab ******/
  {
    CX("<div id='wikiedit-tab-misc' "
       "data-tab-parent='wikiedit-tabs' "
       "data-tab-label='Help, Attachments, etc.' "
       "class='hidden'"
       ">");
    CX("<h3>Wiki formatting rules</h3>");
    CX("<ul>");
    CX("<li><a href='%R/wiki_rules'>Fossil wiki format</a></li>");
    CX("<li><a href='%R/md_rules'>Markdown format</a></li>");
    CX("<li>Plain-text pages use no special formatting.</li>");
    CX("</ul>");
    CX("<hr><h3>Attachments</h3>");
    CX("<div id='wikiedit-attachments'></div>"
       /* Filled out by JS */);
    CX("<hr><h3>The \"Sandbox\" Page</h3>");
    CX("<p>The page named \"Sandbox\" is not a real wiki page. "
       "It provides a place where users may test out wiki syntax "
       "without having to actually save anything, nor pollute "
       "the repo with endless test runs. Any attempt to save the "
       "sandbox page will fail.</p>");
    CX("<hr><h3>Wiki Name Rules</h3>");
    well_formed_wiki_name_rules();
    CX("</div>"/*#wikiedit-tab-save*/);
  }

  builtin_request_js("sbsdiff.js");
  style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
                            "storage", "page.wikiedit", 0);







|


|





<
<
<
|





|







1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232



1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
    CX("</div>"/*#wikiedit-tab-diff*/);
  }

  /****** The obligatory "Misc" tab ******/
  {
    CX("<div id='wikiedit-tab-misc' "
       "data-tab-parent='wikiedit-tabs' "
       "data-tab-label='Help' "
       "class='hidden'"
       ">");
    CX("<h2>Wiki formatting rules</h2>");
    CX("<ul>");
    CX("<li><a href='%R/wiki_rules'>Fossil wiki format</a></li>");
    CX("<li><a href='%R/md_rules'>Markdown format</a></li>");
    CX("<li>Plain-text pages use no special formatting.</li>");
    CX("</ul>");



    CX("<h2>The \"Sandbox\" Page</h2>");
    CX("<p>The page named \"Sandbox\" is not a real wiki page. "
       "It provides a place where users may test out wiki syntax "
       "without having to actually save anything, nor pollute "
       "the repo with endless test runs. Any attempt to save the "
       "sandbox page will fail.</p>");
    CX("<h2>Wiki Name Rules</h2>");
    well_formed_wiki_name_rules();
    CX("</div>"/*#wikiedit-tab-save*/);
  }

  builtin_request_js("sbsdiff.js");
  style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
                            "storage", "page.wikiedit", 0);