Fossil

Check-in [13fabf3f4d]
Login

Check-in [13fabf3f4d]

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

Overview
Comment:Consolidated /wikiedit, /pikchrshow, /fileedit, and /chat to use shift-enter to run preview mode. The former 3 previously used ctrl-enter but it was poorly documented and probably not widely used like ctrl-enter is in chat (to send a message).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 13fabf3f4d87d0016fc97bb0035273c1e0f8785fe433db74ba63c083d6c49aef
User & Date: stephan 2021-09-29 16:45:50.856
Context
2021-09-29
17:03
/chat: shift-enter when in preview mode now switches back to message list mode if the input field is empty. It was previously only possible to switch back via button or sending a message. ... (check-in: 79995e1355 user: stephan tags: trunk)
16:50
Merged in trunk for latest changes. ... (check-in: 09f86815c6 user: stephan tags: markdown-tagrefs)
16:45
Consolidated /wikiedit, /pikchrshow, /fileedit, and /chat to use shift-enter to run preview mode. The former 3 previously used ctrl-enter but it was poorly documented and probably not widely used like ctrl-enter is in chat (to send a message). ... (check-in: 13fabf3f4d user: stephan tags: trunk)
07:27
When generating a repository name from the URL, include parsing of port to avoid undesirable behavior discovered in [forum:4409f66dae988dc5] in which the parser doesn't handle single-label host names which include a port (with or without a final slash). ... (check-in: 000f80213e user: andybradford tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/chat.c.
140
141
142
143
144
145
146





147
148
149
150
151
152
153
154


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
**
** Other /chat-OP pages are used by XHR requests from this page to
** send new chat message, delete older messages, or poll for changes.
*/
void chat_webpage(void){
  char *zAlert;
  char *zProjectName;





  login_check_credentials();
  if( !g.perm.Chat ){
    login_needed(g.anon.Chat);
    return;
  }
  zAlert = mprintf("%s/builtin/%s", g.zBaseURL,
                db_get("chat-alert-sound","alerts/plunk.wav"));
  zProjectName = db_get("project-name","Unnamed project");


  style_set_current_feature("chat");
  style_header("Chat");
  @ <div id='chat-input-area'>
  @   <div id='chat-input-line' class='single-line'>
  @     <input type="text" name="msg" id="chat-input-single" \
  @      placeholder="Type markdown-formatted message for %h(zProjectName)." \
  @      autocomplete="off">
  @     <textarea rows="8" id="chat-input-multi" \
  @      placeholder="Type markdown-formatted message for %h(zProjectName). Ctrl-Enter sends it." \
  @      class="hidden"></textarea>
  @     <div id='chat-edit-buttons'>
  @       <button id="chat-preview-button" \
  @         title="Preview message">&#128065;</button>
  @       <button id="chat-settings-button" \
  @         title="Configure chat">&#9881;</button>
  @       <button id="chat-message-submit" \
  @         title="Send message">&#128228;</button>
  @     </div>
  @   </div>
  @   <div id='chat-input-file-area'>
  @     <div class='file-selection-wrapper'>
  @       <div class='help-buttonlet'>
  @        Select a file to upload, drag/drop a file into this spot,
  @        or paste an image from the clipboard if supported by







>
>
>
>
>








>
>





|


|



|



|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
**
** Other /chat-OP pages are used by XHR requests from this page to
** send new chat message, delete older messages, or poll for changes.
*/
void chat_webpage(void){
  char *zAlert;
  char *zProjectName;
  const char * zInputPlaceholder1 = /* Placeholder for 1-line input */
    "Enter sends and Shift-Enter previews.";
  const char * zInputPlaceholder2 = /* Placeholder for textarea input*/
    "Ctrl-Enter sends and Shift-Enter previews.";
  char * zInputPlaceholder0;  /* Common text input placeholder value */
  login_check_credentials();
  if( !g.perm.Chat ){
    login_needed(g.anon.Chat);
    return;
  }
  zAlert = mprintf("%s/builtin/%s", g.zBaseURL,
                db_get("chat-alert-sound","alerts/plunk.wav"));
  zProjectName = db_get("project-name","Unnamed project");
  zInputPlaceholder0 =
    mprintf("Type markdown-formatted message for %h.", zProjectName);
  style_set_current_feature("chat");
  style_header("Chat");
  @ <div id='chat-input-area'>
  @   <div id='chat-input-line' class='single-line'>
  @     <input type="text" name="msg" id="chat-input-single" \
  @      placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder1)" \
  @      autocomplete="off">
  @     <textarea rows="8" id="chat-input-multi" \
  @      placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder2)" \
  @      class="hidden"></textarea>
  @     <div id='chat-edit-buttons'>
  @       <button id="chat-preview-button" \
  @         title="Preview message (Shift-Enter)">&#128065;</button>
  @       <button id="chat-settings-button" \
  @         title="Configure chat">&#9881;</button>
  @       <button id="chat-message-submit" \
  @         title="Send message (Ctrl-Enter)">&#128228;</button>
  @     </div>
  @   </div>
  @   <div id='chat-input-file-area'>
  @     <div class='file-selection-wrapper'>
  @       <div class='help-buttonlet'>
  @        Select a file to upload, drag/drop a file into this spot,
  @        or paste an image from the clipboard if supported by
207
208
209
210
211
212
213

214
215
216
217
218
219
220
  @ <button>Close Settings</button>
  @ </div>
  @ <div id='chat-messages-wrapper' class='chat-view'>
  /* New chat messages get inserted immediately after this element */
  @ <span id='message-inject-point'></span>
  @ </div>
  fossil_free(zProjectName);

  builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch",
                              "pikchr", "confirmer", NULL);
  /* Always in-line the javascript for the chat page */
  @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
  /* We need an onload handler to ensure that window.fossil is
     initialized before the chat init code runs. */
  @ window.addEventListener('load', function(){







>







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  @ <button>Close Settings</button>
  @ </div>
  @ <div id='chat-messages-wrapper' class='chat-view'>
  /* New chat messages get inserted immediately after this element */
  @ <span id='message-inject-point'></span>
  @ </div>
  fossil_free(zProjectName);
  fossil_free(zInputPlaceholder0);
  builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch",
                              "pikchr", "confirmer", NULL);
  /* Always in-line the javascript for the chat page */
  @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
  /* We need an onload handler to ensure that window.fossil is
     initialized before the chat init code runs. */
  @ window.addEventListener('load', function(){
Changes to src/fossil.page.chat.js.
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
              mh1 = m.clientHeight;
        D.addClass(old, 'hidden');
        D.removeClass(this.e.inputCurrent, 'hidden');
        const mh2 = m.clientHeight;
        m.scrollTo(0, sTop + (mh1-mh2));
        this.e.inputCurrent.value = old.value;
        old.value = '';
        this.animate(this.e.inputCurrent, "anim-flip-v");
        return this;
      },
      /**
         If passed true or no arguments, switches to multi-line mode
         if currently in single-line mode. If passed false, switches
         to single-line mode if currently in multi-line mode. Returns
         this.







<







200
201
202
203
204
205
206

207
208
209
210
211
212
213
              mh1 = m.clientHeight;
        D.addClass(old, 'hidden');
        D.removeClass(this.e.inputCurrent, 'hidden');
        const mh2 = m.clientHeight;
        m.scrollTo(0, sTop + (mh1-mh2));
        this.e.inputCurrent.value = old.value;
        old.value = '';

        return this;
      },
      /**
         If passed true or no arguments, switches to multi-line mode
         if currently in single-line mode. If passed false, switches
         to single-line mode if currently in multi-line mode. Returns
         this.
1193
1194
1195
1196
1197
1198
1199
1200
1201

1202
1203
1204
1205
1206
1207
1208
1209


1210
1211
1212
1213
1214



1215


1216
1217
1218
1219
1220
1221
1222
        }
      }
    });
    BlobXferState.clear();
    Chat.inputValue("").inputFocus();
  };

  Chat.e.inputSingle.addEventListener('keydown',function(ev){
    if(13===ev.keyCode/*ENTER*/){

      ev.preventDefault();
      ev.stopPropagation();
      Chat.submitMessage();
      return false;
    }
  }, false);
  Chat.e.inputMulti.addEventListener('keydown',function(ev){
    if(ev.ctrlKey && 13 === ev.keyCode){


      ev.preventDefault();
      ev.stopPropagation();
      Chat.submitMessage();
      return false;
    }



  }, false);


  Chat.e.btnSubmit.addEventListener('click',(e)=>{
    e.preventDefault();
    Chat.submitMessage();
    return false;
  });

  (function(){/*Set up #chat-settings-button */







|
|
>
|
|
|
|
<
<
|
|
>
>
|
|
|
|
|
>
>
>
|
>
>







1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205


1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
        }
      }
    });
    BlobXferState.clear();
    Chat.inputValue("").inputFocus();
  };

  const inputWidgetKeydown = function(ev){
    if(13 === ev.keyCode){
      if(ev.shiftKey){
        ev.preventDefault();
        ev.stopPropagation();
        Chat.e.btnPreview.click();
        return false;


      }else if((Chat.e.inputSingle===ev.target)
               || (ev.ctrlKey && Chat.e.inputMulti===ev.target)){
        /* ^^^ note that it is intended that both ctrl-enter and enter
           work for single-line input mode. */
        ev.preventDefault();
        ev.stopPropagation();
        Chat.submitMessage();
        return false;
      }
    }
  };  
  Chat.e.inputSingle
    .addEventListener('keydown', inputWidgetKeydown, false);
  Chat.e.inputMulti
    .addEventListener('keydown', inputWidgetKeydown, false);
  Chat.e.btnSubmit.addEventListener('click',(e)=>{
    e.preventDefault();
    Chat.submitMessage();
    return false;
  });

  (function(){/*Set up #chat-settings-button */
Changes to src/fossil.page.fileedit.js.
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
        }
      }
    );
    ////////////////////////////////////////////////////////////
    // Trigger preview on Ctrl-Enter. This only works on the built-in
    // editor widget, not a client-provided one.
    P.e.taEditor.addEventListener('keydown',function(ev){
      if(ev.ctrlKey && 13 === ev.keyCode){
        ev.preventDefault();
        ev.stopPropagation();
        P.e.taEditor.blur(/*force change event, if needed*/);
        P.tabs.switchToTab(P.e.tabs.preview);
        if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */
          P.preview();
        }
        return false;
      }
    }, false);
    // If we're in the preview tab, have ctrl-enter switch back to the editor.
    document.body.addEventListener('keydown',function(ev){
      if(ev.ctrlKey && 13 === ev.keyCode){
        if(currentTab === P.e.tabs.preview){
          ev.preventDefault();
          ev.stopPropagation();
          P.tabs.switchToTab(P.e.tabs.content);
          P.e.taEditor.focus(/*doesn't work for client-supplied editor widget!
                              And it's slow as molasses for long docs, as focus()
                              forces a document reflow.*/);







|












|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
        }
      }
    );
    ////////////////////////////////////////////////////////////
    // Trigger preview on Ctrl-Enter. This only works on the built-in
    // editor widget, not a client-provided one.
    P.e.taEditor.addEventListener('keydown',function(ev){
      if(ev.shiftKey && 13 === ev.keyCode){
        ev.preventDefault();
        ev.stopPropagation();
        P.e.taEditor.blur(/*force change event, if needed*/);
        P.tabs.switchToTab(P.e.tabs.preview);
        if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */
          P.preview();
        }
        return false;
      }
    }, false);
    // If we're in the preview tab, have ctrl-enter switch back to the editor.
    document.body.addEventListener('keydown',function(ev){
      if(ev.shiftKey && 13 === ev.keyCode){
        if(currentTab === P.e.tabs.preview){
          ev.preventDefault();
          ev.stopPropagation();
          P.tabs.switchToTab(P.e.tabs.content);
          P.e.taEditor.focus(/*doesn't work for client-supplied editor widget!
                              And it's slow as molasses for long docs, as focus()
                              forces a document reflow.*/);
Changes to src/fossil.page.pikchrshow.js.
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
              P.e.previewModeToggle,
              '\u00a0',
              P.e.previewCopyButton,
              P.e.previewModeLabel,
              P.e.markupAlignWrapper );

    ////////////////////////////////////////////////////////////
    // Trigger preview on Ctrl-Enter.
    P.e.taContent.addEventListener('keydown',function(ev){
      if(ev.ctrlKey && 13 === ev.keyCode){
        ev.preventDefault();
        ev.stopPropagation();
        P.preview();
        return false;
      }
    }, false);








|

|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
              P.e.previewModeToggle,
              '\u00a0',
              P.e.previewCopyButton,
              P.e.previewModeLabel,
              P.e.markupAlignWrapper );

    ////////////////////////////////////////////////////////////
    // Trigger preview on Shift-Enter.
    P.e.taContent.addEventListener('keydown',function(ev){
      if(ev.shiftKey && 13 === ev.keyCode){
        ev.preventDefault();
        ev.stopPropagation();
        P.preview();
        return false;
      }
    }, false);

388
389
390
391
392
393
394

395
396
397
398
399
400
401
          this.response.raw;
        console.error("svg parsed HTML nodes:",childs);
      }
      D.append(D.clearElement(preTgt), this.e.taPreviewText);
      break;
    }
    this.e.previewModeLabel.innerText = label;

  };

  /**
     Fetches the preview from the server and updates the preview to
     the rendered SVG content or error report.
  */
  P.preview = function fp(){







>







388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
          this.response.raw;
        console.error("svg parsed HTML nodes:",childs);
      }
      D.append(D.clearElement(preTgt), this.e.taPreviewText);
      break;
    }
    this.e.previewModeLabel.innerText = label;
    this.e.taContent.focus(/*not sure why this gets lost on preview!*/);
  };

  /**
     Fetches the preview from the server and updates the preview to
     the rendered SVG content or error report.
  */
  P.preview = function fp(){
Changes to src/fossil.page.wikiedit.js.
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
        }
      }
    );
    ////////////////////////////////////////////////////////////
    // Trigger preview on Ctrl-Enter. This only works on the built-in
    // editor widget, not a client-provided one.
    P.e.taEditor.addEventListener('keydown',function(ev){
      if(ev.ctrlKey && 13 === ev.keyCode){
        ev.preventDefault();
        ev.stopPropagation();
        P.e.taEditor.blur(/*force change event, if needed*/);
        P.tabs.switchToTab(P.e.tabs.preview);
        if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */
          P.preview();
        }
      }
    }, false);
    // If we're in the preview tab, have ctrl-enter switch back to the editor.
    document.body.addEventListener('keydown',function(ev){
      if(ev.ctrlKey && 13 === ev.keyCode){
        if(currentTab === P.e.tabs.preview){
          ev.preventDefault();
          ev.stopPropagation();
          P.tabs.switchToTab(P.e.tabs.content);
          P.e.taEditor.focus(/*doesn't work for client-supplied editor widget!
                              And it's slow as molasses for long docs, as focus()
                              forces a document reflow. */);







|











|







912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
        }
      }
    );
    ////////////////////////////////////////////////////////////
    // Trigger preview on Ctrl-Enter. This only works on the built-in
    // editor widget, not a client-provided one.
    P.e.taEditor.addEventListener('keydown',function(ev){
      if(ev.shiftKey && 13 === ev.keyCode){
        ev.preventDefault();
        ev.stopPropagation();
        P.e.taEditor.blur(/*force change event, if needed*/);
        P.tabs.switchToTab(P.e.tabs.preview);
        if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */
          P.preview();
        }
      }
    }, false);
    // If we're in the preview tab, have ctrl-enter switch back to the editor.
    document.body.addEventListener('keydown',function(ev){
      if(ev.shiftKey && 13 === ev.keyCode){
        if(currentTab === P.e.tabs.preview){
          ev.preventDefault();
          ev.stopPropagation();
          P.tabs.switchToTab(P.e.tabs.content);
          P.e.taEditor.focus(/*doesn't work for client-supplied editor widget!
                              And it's slow as molasses for long docs, as focus()
                              forces a document reflow. */);
Changes to src/pikchrshow.c.
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
       "margin-right: 0.5em; vertical-align: middle;"
       "}\n");
    CX("body.pikchrshow .v-align-middle{"
       "vertical-align: middle"
       "}\n");
    CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n");
  } CX("</style>");
  CX("<div>Input pikchr code and tap Preview (or Ctrl-Enter) to render "
     "it:</div>");
  CX("<div id='sbs-wrapper'>"); {
    CX("<div id='pikchrshow-form'>"); {
      CX("<textarea id='content' name='content' rows='15'>"
         "%s</textarea>",zContent/*safe-for-%s*/);
      CX("<div id='pikchrshow-controls'>"); {
        CX("<button id='pikchr-submit-preview'>Preview</button>");







|







333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
       "margin-right: 0.5em; vertical-align: middle;"
       "}\n");
    CX("body.pikchrshow .v-align-middle{"
       "vertical-align: middle"
       "}\n");
    CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n");
  } CX("</style>");
  CX("<div>Input pikchr code and tap Preview (or Shift-Enter) to render "
     "it:</div>");
  CX("<div id='sbs-wrapper'>"); {
    CX("<div id='pikchrshow-form'>"); {
      CX("<textarea id='content' name='content' rows='15'>"
         "%s</textarea>",zContent/*safe-for-%s*/);
      CX("<div id='pikchrshow-controls'>"); {
        CX("<button id='pikchr-submit-preview'>Preview</button>");
Changes to src/style.fileedit.css.
68
69
70
71
72
73
74



75
76
77
78
79
80
81
  padding: 0;
}
body.fileedit #fileedit-tabs {
  margin: 0.5em 0 0 0;
}
body.fileedit #fileedit-tab-preview-wrapper {
  overflow: auto;



}
body.fileedit #fileedit-tab-fileselect > h1 {
  margin: 0;
}
body.fileedit .fileedit-options.commit-message > div {
  display: flex;
  flex-direction: column;







>
>
>







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  padding: 0;
}
body.fileedit #fileedit-tabs {
  margin: 0.5em 0 0 0;
}
body.fileedit #fileedit-tab-preview-wrapper {
  overflow: auto;
}
body.fileedit #fileedit-tab-preview-wrapper > pre {
  margin: 0;
}
body.fileedit #fileedit-tab-fileselect > h1 {
  margin: 0;
}
body.fileedit .fileedit-options.commit-message > div {
  display: flex;
  flex-direction: column;
Changes to www/changes.wiki.
43
44
45
46
47
48
49





50
51
52
53
54
55
56
     selection of notification sounds via unversioned files].
  *  The [/help?cmd=/chat|/chat] messages now use fossil's full complement of
     markdown features, instead of the prior small subset of markup it
     previously supported. This retroactively applies to all chat messages,
     as they are markdown-processed when they are sent instead of when they
     are saved. Added a preview mode so messages can be previewed before
     being sent. See [./chat.md#usage|the chat docs] for more details.






<h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2>
  *  <b>Security:</b> Fix the client-side TLS so that it verifies that the
     server hostname matches its certificate.
  *  The default "ssh" command on Windows is changed to "ssh" instead of the
     legacy "plink", as ssh is now generally available on Windows systems.
     Installations that still need to use the legacy "plink" can make that







>
>
>
>
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
     selection of notification sounds via unversioned files].
  *  The [/help?cmd=/chat|/chat] messages now use fossil's full complement of
     markdown features, instead of the prior small subset of markup it
     previously supported. This retroactively applies to all chat messages,
     as they are markdown-processed when they are sent instead of when they
     are saved. Added a preview mode so messages can be previewed before
     being sent. See [./chat.md#usage|the chat docs] for more details.
  *  The hotkey to activate preview mode in [/help?cmd=/wikiedit|/wikiedit],
     [/help?cmd=/fileedit|/fileedit], and [/help?cmd=/pikchrshow|/pikchrshow]
     was changed from ctrl-enter to shift-enter in order to align with
     [/help?cmd=/chat|/chat]'s new preview feature and related future
     changes.

<h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2>
  *  <b>Security:</b> Fix the client-side TLS so that it verifies that the
     server hostname matches its certificate.
  *  The default "ssh" command on Windows is changed to "ssh" instead of the
     legacy "plink", as ssh is now generally available on Windows systems.
     Installations that still need to use the legacy "plink" can make that