Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Added style_select_list_str(), selection list for commit comment mime type, and a toggle to switch between single- and multi-line comment editing modes. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | fileedit-ajaxify |
Files: | files | file ages | folders |
SHA3-256: |
4d5004ef2d8cdf02bd106910d18f76ee |
User & Date: | stephan 2020-05-09 12:36:51 |
Context
2020-05-09
| ||
12:54 | Determine which comment editing mode to enable based on which of the editor fields is hidden by default, so that we stay in sync if the C side changes. ... (check-in: a4314603 user: stephan tags: fileedit-ajaxify) | |
12:36 | Added style_select_list_str(), selection list for commit comment mime type, and a toggle to switch between single- and multi-line comment editing modes. ... (check-in: 4d5004ef user: stephan tags: fileedit-ajaxify) | |
2020-05-08
| ||
14:15 | Swapped the style_emit_script_builtin() parameters for consistency with style_emit_script_tag(). ... (check-in: 02240eec user: stephan tags: fileedit-ajaxify) | |
Changes
Changes to src/default_css.txt.
︙ | ︙ | |||
994 995 996 997 998 999 1000 | padding: 0; } #fileedit-comment { width: 100%; font-family: monospace; } .tab-container > .tabs > .tab-panel > .fileedit-options { | | > > > | 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | padding: 0; } #fileedit-comment { width: 100%; font-family: monospace; } .tab-container > .tabs > .tab-panel > .fileedit-options { margin-top: 0.25em 0; border: none; border-radius: 0; border-bottom-width: 1px; border-bottom-style: dotted; } .tab-container > .tabs > .tab-panel > .fileedit-options > button { vertical-align: middle; margin: 0.5em; } //////////////////////////////////////////////////////////////////// // Styles developed for /fileedit but which have wider // applicability: .flex-container { display: flex; } .flex-container.row { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; } .fileedit-options.flex-container.row { align-items: first baseline; } .flex-container.row.stretch { flex-direction: row; flex-wrap: wrap; align-items: stretch; margin: 0; } |
︙ | ︙ |
Changes to src/fileedit.c.
︙ | ︙ | |||
1786 1787 1788 1789 1790 1791 1792 | "Windows", 2, NULL); CX("</div>"/*checkboxes*/); } { /******* Commit comment, button, and result manifest *******/ CX("<fieldset class='fileedit-options'>" | | > > > > | < < > > | > > > > | > > | > | < > > > > > | | > | > | 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 | "Windows", 2, NULL); CX("</div>"/*checkboxes*/); } { /******* Commit comment, button, and result manifest *******/ CX("<fieldset class='fileedit-options'>" "<legend>Message (required) " "</legend><div>"); /* We have two comment input fields, defaulting to single-line ** mode. JS code sets up the ability to toggle between single- ** and multi-line modes. */ CX("<input type='text' name='comment' " "id='fileedit-comment'></input>\n"); CX("<textarea name='commentBig' class='hidden' " "rows='5' id='fileedit-comment-big'></textarea>"); { /* comment options... */ CX("<div class='fileedit-options flex-container row'>"); CX("<button id='comment-toggle' " "title='Toggle between single- and multi-line comment mode, " "noting that switching from multi- to single-line may cause " "newlines to get stripped.'" ">toggle single-/multi-line</button> "); style_select_list_str("comment-mimetype", "comment_mimetype", "Comment style:", "Specify how fossil will interpret the " "comment string.", NULL, "Fossil", "text/x-fossil-wiki", "Markdown", "text/x-markdown", "Plain text", "text/plain", NULL); CX("</div>\n"); CX("<div class='fileedit-hint flex-container row'>" "(Warning: switching from multi- to single-line mode will " "strip out all newlines!)</div>"); } CX("</div></fieldset>\n"/*commit comment*/); CX("<div class='flex-container row'>" "<button id='fileedit-btn-commit'>Commit</button>" "</div>\n"); CX("<div id='fileedit-manifest'></div>\n"); } |
︙ | ︙ |
Changes to src/fossil.page.fileedit.js.
1 2 3 4 5 6 7 8 9 10 11 12 13 | (function(F/*the fossil object*/){ "use strict"; /** Code for the /filepage app. Requires that the fossil JS bootstrapping is complete and fossil.fetch() has been installed. */ const E = (s)=>document.querySelector(s), D = F.dom, P = F.page; window.addEventListener("load", function() { P.tabs = new fossil.TabManager('#fileedit-tabs'); P.e = { taEditor: E('#fileedit-content-editor'), | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | (function(F/*the fossil object*/){ "use strict"; /** Code for the /filepage app. Requires that the fossil JS bootstrapping is complete and fossil.fetch() has been installed. */ const E = (s)=>document.querySelector(s), D = F.dom, P = F.page; window.addEventListener("load", function() { P.tabs = new fossil.TabManager('#fileedit-tabs'); P.e = { taEditor: E('#fileedit-content-editor'), taCommentSmall: E('#fileedit-comment'), taCommentBig: E('#fileedit-comment-big'), ajaxContentTarget: E('#ajax-target'), btnCommit: E("#fileedit-btn-commit"), btnReload: E("#fileedit-tab-content > .fileedit-options > " +"button.fileedit-content-reload"), selectPreviewModeWrap: E('#select-preview-mode'), selectHtmlEmsWrap: E('#select-preview-html-ems'), selectEolWrap: E('#select-preview-html-ems'), cbLineNumbersWrap: E('#cb-line-numbers'), tabs:{ content: E('#fileedit-tab-content'), preview: E('#fileedit-tab-preview'), diff: E('#fileedit-tab-diff'), commit: E('#fileedit-tab-commit') } }; P.e.taComment = P.e.taCommentSmall; P.tabs.e.container.insertBefore( E('#fossil-status-bar'), P.tabs.e.tabs ); const stopEvent = function(e){ //e.preventDefault(); |
︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | "click",(e)=>P.commit(), false ); F.confirmer(P.e.btnReload, { confirmText: "Really reload, losing edits?", onconfirm: (e)=>P.loadFile(), ticks: 3 }); /** Cosmetic: jump through some hoops to enable/disable certain preview options depending on the current preview mode... */ const selectPreviewMode = P.e.selectPreviewModeWrap.querySelector('select'); | > > > > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | "click",(e)=>P.commit(), false ); F.confirmer(P.e.btnReload, { confirmText: "Really reload, losing edits?", onconfirm: (e)=>P.loadFile(), ticks: 3 }); E('#comment-toggle').addEventListener( "click",(e)=>P.toggleCommentMode(), false ); /** Cosmetic: jump through some hoops to enable/disable certain preview options depending on the current preview mode... */ const selectPreviewMode = P.e.selectPreviewModeWrap.querySelector('select'); |
︙ | ︙ | |||
101 102 103 104 105 106 107 108 109 110 111 112 113 114 | ); selectFontSize.dispatchEvent( // Force UI update new Event('change',{target:selectFontSize}) ); } }, false)/*onload event handler*/; /** updateVersion() updates the filename and version in various UI elements... Returns this object. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 107 108 109 110 111 112 113 114 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 142 143 144 145 146 147 148 149 150 151 | ); selectFontSize.dispatchEvent( // Force UI update new Event('change',{target:selectFontSize}) ); } }, false)/*onload event handler*/; /** Toggles between single- and multi-line comment mode. */ P.toggleCommentMode = function(){ var s, h, c = this.e.taComment.value; if(this.e.taComment === this.e.taCommentSmall){ s = this.e.taCommentBig; h = this.e.taCommentSmall; }else{ s = this.e.taCommentSmall; h = this.e.taCommentBig; /* Doing (input[type=text].value = textarea.value) unfortunately strips all newlines. To compensate we'll replace each EOL with a space. Not ideal. If we were to instead escape them as \n, and do the reverse when toggling again, then they would get committed as escaped newlines if the user did not first switch back to multi-line mode. We cannot blindly unescape the newlines, in the off chance that the user actually enters \n in the comment. */ c = c.replace(/\r?\n/g,' '); } s.value = c; this.e.taComment = s; D.addClass(h, 'hidden'); D.removeClass(s, 'hidden'); console.debug(s,h); }; /** updateVersion() updates the filename and version in various UI elements... Returns this object. */ |
︙ | ︙ |
Changes to src/style.c.
︙ | ︙ | |||
1414 1415 1416 1417 1418 1419 1420 1421 | CX("%s", zOption); }else{ CX("%d",v); } CX("</option>\n"); } CX("</select>\n"); if(zLabel && *zLabel){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > | 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 | CX("%s", zOption); }else{ CX("%d",v); } CX("</option>\n"); } CX("</select>\n"); CX("</span>\n"); va_end(vargs); } /* ** The C-string counterpart of style_select_list_int(), this variant ** differs only in that its variadic arguments are C-strings in pairs ** of (optionLabel, optionValue). If a given optionLabel is an empty ** string, the corresponding optionValue is used as its label. If any ** given value matches zSelectedVal, that option gets preselected. If ** no options match zSelectedVal then the first entry is selected by ** default. ** ** Any of (zWrapperId, zTooltip, zSelectedVal) may be NULL or empty. ** ** Example: ** ** style_select_list_str("my-grapes", "my_grapes", "Grapes", ** "Select the number of grapes", ** P("my_field"), ** "1", "One", "2", "Two", "", "3", ** NULL); */ void style_select_list_str(const char * zWrapperId, const char *zFieldName, const char * zLabel, const char * zToolTip, char const * zSelectedVal, ... ){ va_list vargs; va_start(vargs,zSelectedVal); if(!zSelectedVal){ zSelectedVal = __FILE__/*some string we'll never match*/; } CX("<span class='input-with-label'"); if(zToolTip && *zToolTip){ CX(" title='%h'",zToolTip); } if(zWrapperId && *zWrapperId){ CX(" id='%s'",zWrapperId); } CX(">"); if(zLabel && *zLabel){ CX("<span>%h</span>", zLabel); } CX("<select name='%s'>",zFieldName); while(1){ const char * zLabel = va_arg(vargs,char *); const char * zVal; if(NULL==zLabel){ break; } zVal = va_arg(vargs,char *); CX("<option value='%T'%s>", zVal, 0==fossil_strcmp(zVal, zSelectedVal) ? " selected" : ""); if(*zLabel){ CX("%s", zLabel); }else{ CX("%h",zVal); } CX("</option>\n"); } CX("</select>\n"); CX("</span>\n"); va_end(vargs); } /* ** The first time this is called, it emits code to install and ** bootstrap the window.fossil object, using the built-in file ** fossil.bootstrap.js (not to be confused with bootstrap.js). ** ** Subsequent calls are no-ops. |
︙ | ︙ |