Fossil SCM
Improvements to line-numbered text output.
Commit
b699040d701464ced678af7a7c353871d23440dd505fb9c8ef68043eed388271
Parent
22f2d083d6f374c…
19 files changed
+3
+1
-1
+2
-2
+2
-1
+1
-1
+135
-10
+135
-10
+1
-1
+9
+12
+3
+93
+8
+65
+100
-44
+3
+1
-1
+3
+6
~
skins/ardoise/css.txt
~
skins/eagle/css.txt
~
skins/xekri/css.txt
~
src/ajax.c
~
src/attach.c
~
src/default.css
~
src/default.css
~
src/diff.c
~
src/file.c
~
src/fossil.bootstrap.js
~
src/fossil.copybutton.js
~
src/fossil.dom.js
~
src/fossil.numbered-lines.js
~
src/fossil.popupwidget.js
~
src/info.c
~
src/main.mk
~
src/scroll.js
~
win/Makefile.mingw
~
win/Makefile.msc
| --- skins/ardoise/css.txt | ||
| +++ skins/ardoise/css.txt | ||
| @@ -572,10 +572,13 @@ | ||
| 572 | 572 | white-space: nowrap; |
| 573 | 573 | background: #000; |
| 574 | 574 | border: 2px solid #bbb; |
| 575 | 575 | border-radius: 5px |
| 576 | 576 | } |
| 577 | +table.numbered-lines td.file-content > pre { | |
| 578 | + margin-top: -2px/*offset CODE tag border*/; | |
| 579 | +} | |
| 577 | 580 | pre > code { |
| 578 | 581 | padding: 1rem 1.5rem; |
| 579 | 582 | white-space: pre |
| 580 | 583 | } |
| 581 | 584 | td, |
| 582 | 585 |
| --- skins/ardoise/css.txt | |
| +++ skins/ardoise/css.txt | |
| @@ -572,10 +572,13 @@ | |
| 572 | white-space: nowrap; |
| 573 | background: #000; |
| 574 | border: 2px solid #bbb; |
| 575 | border-radius: 5px |
| 576 | } |
| 577 | pre > code { |
| 578 | padding: 1rem 1.5rem; |
| 579 | white-space: pre |
| 580 | } |
| 581 | td, |
| 582 |
| --- skins/ardoise/css.txt | |
| +++ skins/ardoise/css.txt | |
| @@ -572,10 +572,13 @@ | |
| 572 | white-space: nowrap; |
| 573 | background: #000; |
| 574 | border: 2px solid #bbb; |
| 575 | border-radius: 5px |
| 576 | } |
| 577 | table.numbered-lines td.file-content > pre { |
| 578 | margin-top: -2px/*offset CODE tag border*/; |
| 579 | } |
| 580 | pre > code { |
| 581 | padding: 1rem 1.5rem; |
| 582 | white-space: pre |
| 583 | } |
| 584 | td, |
| 585 |
+1
-1
| --- skins/eagle/css.txt | ||
| +++ skins/eagle/css.txt | ||
| @@ -399,11 +399,11 @@ | ||
| 399 | 399 | |
| 400 | 400 | div.filetreeline:hover { |
| 401 | 401 | background-color: #7EA2D9; |
| 402 | 402 | } |
| 403 | 403 | |
| 404 | -div.selectedText { | |
| 404 | +table.numbered-lines td.line-numbers span.selected-line { | |
| 405 | 405 | background-color: #7EA2D9; |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | 408 | .statistics-report-graph-line { |
| 409 | 409 | background-color: #7EA2D9; |
| 410 | 410 |
| --- skins/eagle/css.txt | |
| +++ skins/eagle/css.txt | |
| @@ -399,11 +399,11 @@ | |
| 399 | |
| 400 | div.filetreeline:hover { |
| 401 | background-color: #7EA2D9; |
| 402 | } |
| 403 | |
| 404 | div.selectedText { |
| 405 | background-color: #7EA2D9; |
| 406 | } |
| 407 | |
| 408 | .statistics-report-graph-line { |
| 409 | background-color: #7EA2D9; |
| 410 |
| --- skins/eagle/css.txt | |
| +++ skins/eagle/css.txt | |
| @@ -399,11 +399,11 @@ | |
| 399 | |
| 400 | div.filetreeline:hover { |
| 401 | background-color: #7EA2D9; |
| 402 | } |
| 403 | |
| 404 | table.numbered-lines td.line-numbers span.selected-line { |
| 405 | background-color: #7EA2D9; |
| 406 | } |
| 407 | |
| 408 | .statistics-report-graph-line { |
| 409 | background-color: #7EA2D9; |
| 410 |
+2
-2
| --- skins/xekri/css.txt | ||
| +++ skins/xekri/css.txt | ||
| @@ -1000,15 +1000,15 @@ | ||
| 1000 | 1000 | /************************************** |
| 1001 | 1001 | * Did not encounter these |
| 1002 | 1002 | */ |
| 1003 | 1003 | |
| 1004 | 1004 | /* selected lines of text within a linenumbered artifact display */ |
| 1005 | -div.selectedText { | |
| 1005 | +table.numbered-lines td.line-numbers span.selected-line { | |
| 1006 | 1006 | font-weight: bold; |
| 1007 | 1007 | color: #00f; |
| 1008 | 1008 | background-color: #d5d5ff; |
| 1009 | - border: 1px #00f solid; | |
| 1009 | + border-color: #00f; | |
| 1010 | 1010 | } |
| 1011 | 1011 | |
| 1012 | 1012 | /* format for missing privileges note on user setup page */ |
| 1013 | 1013 | p.missingPriv { |
| 1014 | 1014 | color: #00f; |
| 1015 | 1015 |
| --- skins/xekri/css.txt | |
| +++ skins/xekri/css.txt | |
| @@ -1000,15 +1000,15 @@ | |
| 1000 | /************************************** |
| 1001 | * Did not encounter these |
| 1002 | */ |
| 1003 | |
| 1004 | /* selected lines of text within a linenumbered artifact display */ |
| 1005 | div.selectedText { |
| 1006 | font-weight: bold; |
| 1007 | color: #00f; |
| 1008 | background-color: #d5d5ff; |
| 1009 | border: 1px #00f solid; |
| 1010 | } |
| 1011 | |
| 1012 | /* format for missing privileges note on user setup page */ |
| 1013 | p.missingPriv { |
| 1014 | color: #00f; |
| 1015 |
| --- skins/xekri/css.txt | |
| +++ skins/xekri/css.txt | |
| @@ -1000,15 +1000,15 @@ | |
| 1000 | /************************************** |
| 1001 | * Did not encounter these |
| 1002 | */ |
| 1003 | |
| 1004 | /* selected lines of text within a linenumbered artifact display */ |
| 1005 | table.numbered-lines td.line-numbers span.selected-line { |
| 1006 | font-weight: bold; |
| 1007 | color: #00f; |
| 1008 | background-color: #d5d5ff; |
| 1009 | border-color: #00f; |
| 1010 | } |
| 1011 | |
| 1012 | /* format for missing privileges note on user setup page */ |
| 1013 | p.missingPriv { |
| 1014 | color: #00f; |
| 1015 |
+2
-1
| --- src/ajax.c | ||
| +++ src/ajax.c | ||
| @@ -130,11 +130,12 @@ | ||
| 130 | 130 | wiki_render_by_mimetype(pContent, zMime); |
| 131 | 131 | break; |
| 132 | 132 | default:{ |
| 133 | 133 | const char *zContent = blob_str(pContent); |
| 134 | 134 | if(AJAX_PREVIEW_LINE_NUMBERS & flags){ |
| 135 | - output_text_with_line_numbers(zContent, "on"); | |
| 135 | + output_text_with_line_numbers(zContent, blob_size(pContent), | |
| 136 | + zName, "on"); | |
| 136 | 137 | }else{ |
| 137 | 138 | const char *zExt = strrchr(zName,'.'); |
| 138 | 139 | if(zExt && zExt[1]){ |
| 139 | 140 | CX("<pre><code class='language-%s'>%h</code></pre>", |
| 140 | 141 | zExt+1, zContent); |
| 141 | 142 |
| --- src/ajax.c | |
| +++ src/ajax.c | |
| @@ -130,11 +130,12 @@ | |
| 130 | wiki_render_by_mimetype(pContent, zMime); |
| 131 | break; |
| 132 | default:{ |
| 133 | const char *zContent = blob_str(pContent); |
| 134 | if(AJAX_PREVIEW_LINE_NUMBERS & flags){ |
| 135 | output_text_with_line_numbers(zContent, "on"); |
| 136 | }else{ |
| 137 | const char *zExt = strrchr(zName,'.'); |
| 138 | if(zExt && zExt[1]){ |
| 139 | CX("<pre><code class='language-%s'>%h</code></pre>", |
| 140 | zExt+1, zContent); |
| 141 |
| --- src/ajax.c | |
| +++ src/ajax.c | |
| @@ -130,11 +130,12 @@ | |
| 130 | wiki_render_by_mimetype(pContent, zMime); |
| 131 | break; |
| 132 | default:{ |
| 133 | const char *zContent = blob_str(pContent); |
| 134 | if(AJAX_PREVIEW_LINE_NUMBERS & flags){ |
| 135 | output_text_with_line_numbers(zContent, blob_size(pContent), |
| 136 | zName, "on"); |
| 137 | }else{ |
| 138 | const char *zExt = strrchr(zName,'.'); |
| 139 | if(zExt && zExt[1]){ |
| 140 | CX("<pre><code class='language-%s'>%h</code></pre>", |
| 141 | zExt+1, zContent); |
| 142 |
+1
-1
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -617,11 +617,11 @@ | ||
| 617 | 617 | const char *z; |
| 618 | 618 | content_get(ridSrc, &attach); |
| 619 | 619 | blob_to_utf8_no_bom(&attach, 0); |
| 620 | 620 | z = blob_str(&attach); |
| 621 | 621 | if( zLn ){ |
| 622 | - output_text_with_line_numbers(z, zLn); | |
| 622 | + output_text_with_line_numbers(z, blob_size(&attach), zName, zLn); | |
| 623 | 623 | }else{ |
| 624 | 624 | @ <pre> |
| 625 | 625 | @ %h(z) |
| 626 | 626 | @ </pre> |
| 627 | 627 | } |
| 628 | 628 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -617,11 +617,11 @@ | |
| 617 | const char *z; |
| 618 | content_get(ridSrc, &attach); |
| 619 | blob_to_utf8_no_bom(&attach, 0); |
| 620 | z = blob_str(&attach); |
| 621 | if( zLn ){ |
| 622 | output_text_with_line_numbers(z, zLn); |
| 623 | }else{ |
| 624 | @ <pre> |
| 625 | @ %h(z) |
| 626 | @ </pre> |
| 627 | } |
| 628 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -617,11 +617,11 @@ | |
| 617 | const char *z; |
| 618 | content_get(ridSrc, &attach); |
| 619 | blob_to_utf8_no_bom(&attach, 0); |
| 620 | z = blob_str(&attach); |
| 621 | if( zLn ){ |
| 622 | output_text_with_line_numbers(z, blob_size(&attach), zName, zLn); |
| 623 | }else{ |
| 624 | @ <pre> |
| 625 | @ %h(z) |
| 626 | @ </pre> |
| 627 | } |
| 628 |
+135
-10
| --- src/default.css | ||
| +++ src/default.css | ||
| @@ -440,16 +440,10 @@ | ||
| 440 | 440 | content:"'"; |
| 441 | 441 | } |
| 442 | 442 | span.usertype:after { |
| 443 | 443 | content:"'"; |
| 444 | 444 | } |
| 445 | -div.selectedText { | |
| 446 | - font-weight: bold; | |
| 447 | - color: blue; | |
| 448 | - background-color: #d5d5ff; | |
| 449 | - border: 1px blue solid; | |
| 450 | -} | |
| 451 | 445 | p.missingPriv { |
| 452 | 446 | color: blue; |
| 453 | 447 | } |
| 454 | 448 | span.wikiruleHead { |
| 455 | 449 | font-weight: bold; |
| @@ -953,14 +947,19 @@ | ||
| 953 | 947 | color: darkred; |
| 954 | 948 | background: yellow; |
| 955 | 949 | opacity: 0.7; |
| 956 | 950 | } |
| 957 | 951 | .hidden { |
| 958 | - position: absolute; | |
| 959 | - opacity: 0; | |
| 960 | - pointer-events: none; | |
| 961 | - display: none; | |
| 952 | + /* The framework-wide way of hiding elements is to assign them this | |
| 953 | + CSS class. To make them visible again, remove it. The !important | |
| 954 | + qualifiers are unfortunate but sometimes necessary when hidden | |
| 955 | + element has other classes which specify visibility-related | |
| 956 | + options. */ | |
| 957 | + position: absolute !important; | |
| 958 | + opacity: 0 !important; | |
| 959 | + pointer-events: none !important; | |
| 960 | + display: none !important; | |
| 962 | 961 | } |
| 963 | 962 | input { |
| 964 | 963 | max-width: 95%; |
| 965 | 964 | } |
| 966 | 965 | textarea { |
| @@ -1148,5 +1147,131 @@ | ||
| 1148 | 1147 | .input-with-label > label { |
| 1149 | 1148 | font-weight: initial; |
| 1150 | 1149 | margin: 0 0.25em 0 0.25em; |
| 1151 | 1150 | vertical-align: middle; |
| 1152 | 1151 | } |
| 1152 | + | |
| 1153 | +table.numbered-lines { | |
| 1154 | + width: 100%; | |
| 1155 | + table-layout: fixed /* required to keep ultra-wide code from exceeding | |
| 1156 | + window width, and instead force a scrollbar | |
| 1157 | + on them. */; | |
| 1158 | +} | |
| 1159 | +table.numbered-lines > tbody > tr { | |
| 1160 | + font-family: monospace; | |
| 1161 | + font-size: 1.2em; | |
| 1162 | + line-height: 1.35; | |
| 1163 | + white-space: pre; | |
| 1164 | +} | |
| 1165 | +table.numbered-lines > tbody > tr > td { | |
| 1166 | + font-family: inherit; | |
| 1167 | + font-size: inherit; | |
| 1168 | + line-height: inherit; | |
| 1169 | + white-space: inherit; | |
| 1170 | + margin: 0; | |
| 1171 | + vertical-align: top; | |
| 1172 | + padding: 0.25em 0 0 0 /*prevents slight overlap at top */; | |
| 1173 | +} | |
| 1174 | +table.numbered-lines td.line-numbers { | |
| 1175 | + width: 4.5em; | |
| 1176 | +} | |
| 1177 | +table.numbered-lines td.line-numbers > span:first-of-type { | |
| 1178 | + margin-top: 0.25em/*must match top PADDING of | |
| 1179 | + td.file-content > pre > code*/; | |
| 1180 | +} | |
| 1181 | +table.numbered-lines td.line-numbers > span { | |
| 1182 | + display: block; | |
| 1183 | + margin: 0; | |
| 1184 | + padding: 0; | |
| 1185 | + line-height: inherit; | |
| 1186 | + font-size: inherit; | |
| 1187 | + font-family: inherit; | |
| 1188 | + cursor: pointer; | |
| 1189 | + white-space: pre; | |
| 1190 | + margin-right: 2px/*keep selection from nudging the right column */; | |
| 1191 | + text-align: right; | |
| 1192 | +} | |
| 1193 | +table.numbered-lines td.line-numbers > span:hover { | |
| 1194 | + background-color: rgba(112, 112, 112, 0.25); | |
| 1195 | +} | |
| 1196 | +table.numbered-lines td.file-content { | |
| 1197 | + padding-left: 0.25em; | |
| 1198 | +} | |
| 1199 | +table.numbered-lines td.file-content > pre, | |
| 1200 | +table.numbered-lines td.file-content > pre > code { | |
| 1201 | + margin: 0; | |
| 1202 | + padding: 0; | |
| 1203 | + line-height: inherit; | |
| 1204 | + font-size: inherit; | |
| 1205 | + font-family: inherit; | |
| 1206 | + white-space: pre; | |
| 1207 | + display: block/*necessary for certain skins!*/; | |
| 1208 | +} | |
| 1209 | +table.numbered-lines td.file-content > pre { | |
| 1210 | +} | |
| 1211 | +table.numbered-lines td.file-content > pre > code { | |
| 1212 | + overflow: auto; | |
| 1213 | + padding-left: 0.5em; | |
| 1214 | + padding-right: 0.5em; | |
| 1215 | + padding-top: 0.25em/*any top padding here must match the top MARGIN of | |
| 1216 | + td.line-numbers's first span child or the | |
| 1217 | + lines/code will get misaligned. */; | |
| 1218 | + padding-bottom: 0.25em/*prevents a slight overlap at bottom from | |
| 1219 | + triggering a scroller*/; | |
| 1220 | +} | |
| 1221 | +table.numbered-lines td.file-content > pre > code > * { | |
| 1222 | + /* Defense against syntax highlighters indirectly messing up these | |
| 1223 | + properties... */ | |
| 1224 | + line-height: inherit; | |
| 1225 | + font-size: inherit; | |
| 1226 | + font-family: inherit; | |
| 1227 | +} | |
| 1228 | +table.numbered-lines td.line-numbers span.selected-line/*replacement*/ { | |
| 1229 | + font-weight: bold; | |
| 1230 | + color: blue; | |
| 1231 | + background-color: #d5d5ff; | |
| 1232 | + border: 1px blue solid; | |
| 1233 | + border-top-width: 0; | |
| 1234 | + border-bottom-width: 0; | |
| 1235 | + padding: 0; | |
| 1236 | + margin: 0; | |
| 1237 | +} | |
| 1238 | +table.numbered-lines td.line-numbers span.selected-line.start { | |
| 1239 | + border-top-width: 1px; | |
| 1240 | + margin-top: -1px/*restore alignment*/; | |
| 1241 | +} | |
| 1242 | +table.numbered-lines td.line-numbers span.selected-line.end { | |
| 1243 | + border-bottom-width: 1px; | |
| 1244 | + margin-top: -1px/*restore alignment*/; | |
| 1245 | +} | |
| 1246 | +table.numbered-lines td.line-numbers span.selected-line.start.end { | |
| 1247 | + margin-top: -2px/*restore alignment*/; | |
| 1248 | +} | |
| 1249 | + | |
| 1250 | +.fossil-tooltip { | |
| 1251 | + text-align: center; | |
| 1252 | + padding: 0.2em 1em; | |
| 1253 | + border: 1px solid black; | |
| 1254 | + border-radius: 0.25em; | |
| 1255 | + position: absolute; | |
| 1256 | + display: inline-block; | |
| 1257 | + z-index: 100; | |
| 1258 | + box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75); | |
| 1259 | + background-color: inherit; | |
| 1260 | + font-size: 80%; | |
| 1261 | +} | |
| 1262 | + | |
| 1263 | +.fossil-toast {/* "toast"-style popup message */ | |
| 1264 | + padding: 0.25em 0.5em; | |
| 1265 | + margin: 0; | |
| 1266 | + border-radius: 0.25em; | |
| 1267 | + font-size: 1em; | |
| 1268 | + opacity: 0.8; | |
| 1269 | + border-size: 1px; | |
| 1270 | + border-style: dotted; | |
| 1271 | + border-color: rgb( 127, 127, 127, 0.5 ); | |
| 1272 | +} | |
| 1273 | + | |
| 1274 | +blockquote.file-content { | |
| 1275 | + /* file content block in the /file page */ | |
| 1276 | + margin: 0 1em; | |
| 1277 | +} | |
| 1153 | 1278 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -440,16 +440,10 @@ | |
| 440 | content:"'"; |
| 441 | } |
| 442 | span.usertype:after { |
| 443 | content:"'"; |
| 444 | } |
| 445 | div.selectedText { |
| 446 | font-weight: bold; |
| 447 | color: blue; |
| 448 | background-color: #d5d5ff; |
| 449 | border: 1px blue solid; |
| 450 | } |
| 451 | p.missingPriv { |
| 452 | color: blue; |
| 453 | } |
| 454 | span.wikiruleHead { |
| 455 | font-weight: bold; |
| @@ -953,14 +947,19 @@ | |
| 953 | color: darkred; |
| 954 | background: yellow; |
| 955 | opacity: 0.7; |
| 956 | } |
| 957 | .hidden { |
| 958 | position: absolute; |
| 959 | opacity: 0; |
| 960 | pointer-events: none; |
| 961 | display: none; |
| 962 | } |
| 963 | input { |
| 964 | max-width: 95%; |
| 965 | } |
| 966 | textarea { |
| @@ -1148,5 +1147,131 @@ | |
| 1148 | .input-with-label > label { |
| 1149 | font-weight: initial; |
| 1150 | margin: 0 0.25em 0 0.25em; |
| 1151 | vertical-align: middle; |
| 1152 | } |
| 1153 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -440,16 +440,10 @@ | |
| 440 | content:"'"; |
| 441 | } |
| 442 | span.usertype:after { |
| 443 | content:"'"; |
| 444 | } |
| 445 | p.missingPriv { |
| 446 | color: blue; |
| 447 | } |
| 448 | span.wikiruleHead { |
| 449 | font-weight: bold; |
| @@ -953,14 +947,19 @@ | |
| 947 | color: darkred; |
| 948 | background: yellow; |
| 949 | opacity: 0.7; |
| 950 | } |
| 951 | .hidden { |
| 952 | /* The framework-wide way of hiding elements is to assign them this |
| 953 | CSS class. To make them visible again, remove it. The !important |
| 954 | qualifiers are unfortunate but sometimes necessary when hidden |
| 955 | element has other classes which specify visibility-related |
| 956 | options. */ |
| 957 | position: absolute !important; |
| 958 | opacity: 0 !important; |
| 959 | pointer-events: none !important; |
| 960 | display: none !important; |
| 961 | } |
| 962 | input { |
| 963 | max-width: 95%; |
| 964 | } |
| 965 | textarea { |
| @@ -1148,5 +1147,131 @@ | |
| 1147 | .input-with-label > label { |
| 1148 | font-weight: initial; |
| 1149 | margin: 0 0.25em 0 0.25em; |
| 1150 | vertical-align: middle; |
| 1151 | } |
| 1152 | |
| 1153 | table.numbered-lines { |
| 1154 | width: 100%; |
| 1155 | table-layout: fixed /* required to keep ultra-wide code from exceeding |
| 1156 | window width, and instead force a scrollbar |
| 1157 | on them. */; |
| 1158 | } |
| 1159 | table.numbered-lines > tbody > tr { |
| 1160 | font-family: monospace; |
| 1161 | font-size: 1.2em; |
| 1162 | line-height: 1.35; |
| 1163 | white-space: pre; |
| 1164 | } |
| 1165 | table.numbered-lines > tbody > tr > td { |
| 1166 | font-family: inherit; |
| 1167 | font-size: inherit; |
| 1168 | line-height: inherit; |
| 1169 | white-space: inherit; |
| 1170 | margin: 0; |
| 1171 | vertical-align: top; |
| 1172 | padding: 0.25em 0 0 0 /*prevents slight overlap at top */; |
| 1173 | } |
| 1174 | table.numbered-lines td.line-numbers { |
| 1175 | width: 4.5em; |
| 1176 | } |
| 1177 | table.numbered-lines td.line-numbers > span:first-of-type { |
| 1178 | margin-top: 0.25em/*must match top PADDING of |
| 1179 | td.file-content > pre > code*/; |
| 1180 | } |
| 1181 | table.numbered-lines td.line-numbers > span { |
| 1182 | display: block; |
| 1183 | margin: 0; |
| 1184 | padding: 0; |
| 1185 | line-height: inherit; |
| 1186 | font-size: inherit; |
| 1187 | font-family: inherit; |
| 1188 | cursor: pointer; |
| 1189 | white-space: pre; |
| 1190 | margin-right: 2px/*keep selection from nudging the right column */; |
| 1191 | text-align: right; |
| 1192 | } |
| 1193 | table.numbered-lines td.line-numbers > span:hover { |
| 1194 | background-color: rgba(112, 112, 112, 0.25); |
| 1195 | } |
| 1196 | table.numbered-lines td.file-content { |
| 1197 | padding-left: 0.25em; |
| 1198 | } |
| 1199 | table.numbered-lines td.file-content > pre, |
| 1200 | table.numbered-lines td.file-content > pre > code { |
| 1201 | margin: 0; |
| 1202 | padding: 0; |
| 1203 | line-height: inherit; |
| 1204 | font-size: inherit; |
| 1205 | font-family: inherit; |
| 1206 | white-space: pre; |
| 1207 | display: block/*necessary for certain skins!*/; |
| 1208 | } |
| 1209 | table.numbered-lines td.file-content > pre { |
| 1210 | } |
| 1211 | table.numbered-lines td.file-content > pre > code { |
| 1212 | overflow: auto; |
| 1213 | padding-left: 0.5em; |
| 1214 | padding-right: 0.5em; |
| 1215 | padding-top: 0.25em/*any top padding here must match the top MARGIN of |
| 1216 | td.line-numbers's first span child or the |
| 1217 | lines/code will get misaligned. */; |
| 1218 | padding-bottom: 0.25em/*prevents a slight overlap at bottom from |
| 1219 | triggering a scroller*/; |
| 1220 | } |
| 1221 | table.numbered-lines td.file-content > pre > code > * { |
| 1222 | /* Defense against syntax highlighters indirectly messing up these |
| 1223 | properties... */ |
| 1224 | line-height: inherit; |
| 1225 | font-size: inherit; |
| 1226 | font-family: inherit; |
| 1227 | } |
| 1228 | table.numbered-lines td.line-numbers span.selected-line/*replacement*/ { |
| 1229 | font-weight: bold; |
| 1230 | color: blue; |
| 1231 | background-color: #d5d5ff; |
| 1232 | border: 1px blue solid; |
| 1233 | border-top-width: 0; |
| 1234 | border-bottom-width: 0; |
| 1235 | padding: 0; |
| 1236 | margin: 0; |
| 1237 | } |
| 1238 | table.numbered-lines td.line-numbers span.selected-line.start { |
| 1239 | border-top-width: 1px; |
| 1240 | margin-top: -1px/*restore alignment*/; |
| 1241 | } |
| 1242 | table.numbered-lines td.line-numbers span.selected-line.end { |
| 1243 | border-bottom-width: 1px; |
| 1244 | margin-top: -1px/*restore alignment*/; |
| 1245 | } |
| 1246 | table.numbered-lines td.line-numbers span.selected-line.start.end { |
| 1247 | margin-top: -2px/*restore alignment*/; |
| 1248 | } |
| 1249 | |
| 1250 | .fossil-tooltip { |
| 1251 | text-align: center; |
| 1252 | padding: 0.2em 1em; |
| 1253 | border: 1px solid black; |
| 1254 | border-radius: 0.25em; |
| 1255 | position: absolute; |
| 1256 | display: inline-block; |
| 1257 | z-index: 100; |
| 1258 | box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75); |
| 1259 | background-color: inherit; |
| 1260 | font-size: 80%; |
| 1261 | } |
| 1262 | |
| 1263 | .fossil-toast {/* "toast"-style popup message */ |
| 1264 | padding: 0.25em 0.5em; |
| 1265 | margin: 0; |
| 1266 | border-radius: 0.25em; |
| 1267 | font-size: 1em; |
| 1268 | opacity: 0.8; |
| 1269 | border-size: 1px; |
| 1270 | border-style: dotted; |
| 1271 | border-color: rgb( 127, 127, 127, 0.5 ); |
| 1272 | } |
| 1273 | |
| 1274 | blockquote.file-content { |
| 1275 | /* file content block in the /file page */ |
| 1276 | margin: 0 1em; |
| 1277 | } |
| 1278 |
+135
-10
| --- src/default.css | ||
| +++ src/default.css | ||
| @@ -440,16 +440,10 @@ | ||
| 440 | 440 | content:"'"; |
| 441 | 441 | } |
| 442 | 442 | span.usertype:after { |
| 443 | 443 | content:"'"; |
| 444 | 444 | } |
| 445 | -div.selectedText { | |
| 446 | - font-weight: bold; | |
| 447 | - color: blue; | |
| 448 | - background-color: #d5d5ff; | |
| 449 | - border: 1px blue solid; | |
| 450 | -} | |
| 451 | 445 | p.missingPriv { |
| 452 | 446 | color: blue; |
| 453 | 447 | } |
| 454 | 448 | span.wikiruleHead { |
| 455 | 449 | font-weight: bold; |
| @@ -953,14 +947,19 @@ | ||
| 953 | 947 | color: darkred; |
| 954 | 948 | background: yellow; |
| 955 | 949 | opacity: 0.7; |
| 956 | 950 | } |
| 957 | 951 | .hidden { |
| 958 | - position: absolute; | |
| 959 | - opacity: 0; | |
| 960 | - pointer-events: none; | |
| 961 | - display: none; | |
| 952 | + /* The framework-wide way of hiding elements is to assign them this | |
| 953 | + CSS class. To make them visible again, remove it. The !important | |
| 954 | + qualifiers are unfortunate but sometimes necessary when hidden | |
| 955 | + element has other classes which specify visibility-related | |
| 956 | + options. */ | |
| 957 | + position: absolute !important; | |
| 958 | + opacity: 0 !important; | |
| 959 | + pointer-events: none !important; | |
| 960 | + display: none !important; | |
| 962 | 961 | } |
| 963 | 962 | input { |
| 964 | 963 | max-width: 95%; |
| 965 | 964 | } |
| 966 | 965 | textarea { |
| @@ -1148,5 +1147,131 @@ | ||
| 1148 | 1147 | .input-with-label > label { |
| 1149 | 1148 | font-weight: initial; |
| 1150 | 1149 | margin: 0 0.25em 0 0.25em; |
| 1151 | 1150 | vertical-align: middle; |
| 1152 | 1151 | } |
| 1152 | + | |
| 1153 | +table.numbered-lines { | |
| 1154 | + width: 100%; | |
| 1155 | + table-layout: fixed /* required to keep ultra-wide code from exceeding | |
| 1156 | + window width, and instead force a scrollbar | |
| 1157 | + on them. */; | |
| 1158 | +} | |
| 1159 | +table.numbered-lines > tbody > tr { | |
| 1160 | + font-family: monospace; | |
| 1161 | + font-size: 1.2em; | |
| 1162 | + line-height: 1.35; | |
| 1163 | + white-space: pre; | |
| 1164 | +} | |
| 1165 | +table.numbered-lines > tbody > tr > td { | |
| 1166 | + font-family: inherit; | |
| 1167 | + font-size: inherit; | |
| 1168 | + line-height: inherit; | |
| 1169 | + white-space: inherit; | |
| 1170 | + margin: 0; | |
| 1171 | + vertical-align: top; | |
| 1172 | + padding: 0.25em 0 0 0 /*prevents slight overlap at top */; | |
| 1173 | +} | |
| 1174 | +table.numbered-lines td.line-numbers { | |
| 1175 | + width: 4.5em; | |
| 1176 | +} | |
| 1177 | +table.numbered-lines td.line-numbers > span:first-of-type { | |
| 1178 | + margin-top: 0.25em/*must match top PADDING of | |
| 1179 | + td.file-content > pre > code*/; | |
| 1180 | +} | |
| 1181 | +table.numbered-lines td.line-numbers > span { | |
| 1182 | + display: block; | |
| 1183 | + margin: 0; | |
| 1184 | + padding: 0; | |
| 1185 | + line-height: inherit; | |
| 1186 | + font-size: inherit; | |
| 1187 | + font-family: inherit; | |
| 1188 | + cursor: pointer; | |
| 1189 | + white-space: pre; | |
| 1190 | + margin-right: 2px/*keep selection from nudging the right column */; | |
| 1191 | + text-align: right; | |
| 1192 | +} | |
| 1193 | +table.numbered-lines td.line-numbers > span:hover { | |
| 1194 | + background-color: rgba(112, 112, 112, 0.25); | |
| 1195 | +} | |
| 1196 | +table.numbered-lines td.file-content { | |
| 1197 | + padding-left: 0.25em; | |
| 1198 | +} | |
| 1199 | +table.numbered-lines td.file-content > pre, | |
| 1200 | +table.numbered-lines td.file-content > pre > code { | |
| 1201 | + margin: 0; | |
| 1202 | + padding: 0; | |
| 1203 | + line-height: inherit; | |
| 1204 | + font-size: inherit; | |
| 1205 | + font-family: inherit; | |
| 1206 | + white-space: pre; | |
| 1207 | + display: block/*necessary for certain skins!*/; | |
| 1208 | +} | |
| 1209 | +table.numbered-lines td.file-content > pre { | |
| 1210 | +} | |
| 1211 | +table.numbered-lines td.file-content > pre > code { | |
| 1212 | + overflow: auto; | |
| 1213 | + padding-left: 0.5em; | |
| 1214 | + padding-right: 0.5em; | |
| 1215 | + padding-top: 0.25em/*any top padding here must match the top MARGIN of | |
| 1216 | + td.line-numbers's first span child or the | |
| 1217 | + lines/code will get misaligned. */; | |
| 1218 | + padding-bottom: 0.25em/*prevents a slight overlap at bottom from | |
| 1219 | + triggering a scroller*/; | |
| 1220 | +} | |
| 1221 | +table.numbered-lines td.file-content > pre > code > * { | |
| 1222 | + /* Defense against syntax highlighters indirectly messing up these | |
| 1223 | + properties... */ | |
| 1224 | + line-height: inherit; | |
| 1225 | + font-size: inherit; | |
| 1226 | + font-family: inherit; | |
| 1227 | +} | |
| 1228 | +table.numbered-lines td.line-numbers span.selected-line/*replacement*/ { | |
| 1229 | + font-weight: bold; | |
| 1230 | + color: blue; | |
| 1231 | + background-color: #d5d5ff; | |
| 1232 | + border: 1px blue solid; | |
| 1233 | + border-top-width: 0; | |
| 1234 | + border-bottom-width: 0; | |
| 1235 | + padding: 0; | |
| 1236 | + margin: 0; | |
| 1237 | +} | |
| 1238 | +table.numbered-lines td.line-numbers span.selected-line.start { | |
| 1239 | + border-top-width: 1px; | |
| 1240 | + margin-top: -1px/*restore alignment*/; | |
| 1241 | +} | |
| 1242 | +table.numbered-lines td.line-numbers span.selected-line.end { | |
| 1243 | + border-bottom-width: 1px; | |
| 1244 | + margin-top: -1px/*restore alignment*/; | |
| 1245 | +} | |
| 1246 | +table.numbered-lines td.line-numbers span.selected-line.start.end { | |
| 1247 | + margin-top: -2px/*restore alignment*/; | |
| 1248 | +} | |
| 1249 | + | |
| 1250 | +.fossil-tooltip { | |
| 1251 | + text-align: center; | |
| 1252 | + padding: 0.2em 1em; | |
| 1253 | + border: 1px solid black; | |
| 1254 | + border-radius: 0.25em; | |
| 1255 | + position: absolute; | |
| 1256 | + display: inline-block; | |
| 1257 | + z-index: 100; | |
| 1258 | + box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75); | |
| 1259 | + background-color: inherit; | |
| 1260 | + font-size: 80%; | |
| 1261 | +} | |
| 1262 | + | |
| 1263 | +.fossil-toast {/* "toast"-style popup message */ | |
| 1264 | + padding: 0.25em 0.5em; | |
| 1265 | + margin: 0; | |
| 1266 | + border-radius: 0.25em; | |
| 1267 | + font-size: 1em; | |
| 1268 | + opacity: 0.8; | |
| 1269 | + border-size: 1px; | |
| 1270 | + border-style: dotted; | |
| 1271 | + border-color: rgb( 127, 127, 127, 0.5 ); | |
| 1272 | +} | |
| 1273 | + | |
| 1274 | +blockquote.file-content { | |
| 1275 | + /* file content block in the /file page */ | |
| 1276 | + margin: 0 1em; | |
| 1277 | +} | |
| 1153 | 1278 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -440,16 +440,10 @@ | |
| 440 | content:"'"; |
| 441 | } |
| 442 | span.usertype:after { |
| 443 | content:"'"; |
| 444 | } |
| 445 | div.selectedText { |
| 446 | font-weight: bold; |
| 447 | color: blue; |
| 448 | background-color: #d5d5ff; |
| 449 | border: 1px blue solid; |
| 450 | } |
| 451 | p.missingPriv { |
| 452 | color: blue; |
| 453 | } |
| 454 | span.wikiruleHead { |
| 455 | font-weight: bold; |
| @@ -953,14 +947,19 @@ | |
| 953 | color: darkred; |
| 954 | background: yellow; |
| 955 | opacity: 0.7; |
| 956 | } |
| 957 | .hidden { |
| 958 | position: absolute; |
| 959 | opacity: 0; |
| 960 | pointer-events: none; |
| 961 | display: none; |
| 962 | } |
| 963 | input { |
| 964 | max-width: 95%; |
| 965 | } |
| 966 | textarea { |
| @@ -1148,5 +1147,131 @@ | |
| 1148 | .input-with-label > label { |
| 1149 | font-weight: initial; |
| 1150 | margin: 0 0.25em 0 0.25em; |
| 1151 | vertical-align: middle; |
| 1152 | } |
| 1153 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -440,16 +440,10 @@ | |
| 440 | content:"'"; |
| 441 | } |
| 442 | span.usertype:after { |
| 443 | content:"'"; |
| 444 | } |
| 445 | p.missingPriv { |
| 446 | color: blue; |
| 447 | } |
| 448 | span.wikiruleHead { |
| 449 | font-weight: bold; |
| @@ -953,14 +947,19 @@ | |
| 947 | color: darkred; |
| 948 | background: yellow; |
| 949 | opacity: 0.7; |
| 950 | } |
| 951 | .hidden { |
| 952 | /* The framework-wide way of hiding elements is to assign them this |
| 953 | CSS class. To make them visible again, remove it. The !important |
| 954 | qualifiers are unfortunate but sometimes necessary when hidden |
| 955 | element has other classes which specify visibility-related |
| 956 | options. */ |
| 957 | position: absolute !important; |
| 958 | opacity: 0 !important; |
| 959 | pointer-events: none !important; |
| 960 | display: none !important; |
| 961 | } |
| 962 | input { |
| 963 | max-width: 95%; |
| 964 | } |
| 965 | textarea { |
| @@ -1148,5 +1147,131 @@ | |
| 1147 | .input-with-label > label { |
| 1148 | font-weight: initial; |
| 1149 | margin: 0 0.25em 0 0.25em; |
| 1150 | vertical-align: middle; |
| 1151 | } |
| 1152 | |
| 1153 | table.numbered-lines { |
| 1154 | width: 100%; |
| 1155 | table-layout: fixed /* required to keep ultra-wide code from exceeding |
| 1156 | window width, and instead force a scrollbar |
| 1157 | on them. */; |
| 1158 | } |
| 1159 | table.numbered-lines > tbody > tr { |
| 1160 | font-family: monospace; |
| 1161 | font-size: 1.2em; |
| 1162 | line-height: 1.35; |
| 1163 | white-space: pre; |
| 1164 | } |
| 1165 | table.numbered-lines > tbody > tr > td { |
| 1166 | font-family: inherit; |
| 1167 | font-size: inherit; |
| 1168 | line-height: inherit; |
| 1169 | white-space: inherit; |
| 1170 | margin: 0; |
| 1171 | vertical-align: top; |
| 1172 | padding: 0.25em 0 0 0 /*prevents slight overlap at top */; |
| 1173 | } |
| 1174 | table.numbered-lines td.line-numbers { |
| 1175 | width: 4.5em; |
| 1176 | } |
| 1177 | table.numbered-lines td.line-numbers > span:first-of-type { |
| 1178 | margin-top: 0.25em/*must match top PADDING of |
| 1179 | td.file-content > pre > code*/; |
| 1180 | } |
| 1181 | table.numbered-lines td.line-numbers > span { |
| 1182 | display: block; |
| 1183 | margin: 0; |
| 1184 | padding: 0; |
| 1185 | line-height: inherit; |
| 1186 | font-size: inherit; |
| 1187 | font-family: inherit; |
| 1188 | cursor: pointer; |
| 1189 | white-space: pre; |
| 1190 | margin-right: 2px/*keep selection from nudging the right column */; |
| 1191 | text-align: right; |
| 1192 | } |
| 1193 | table.numbered-lines td.line-numbers > span:hover { |
| 1194 | background-color: rgba(112, 112, 112, 0.25); |
| 1195 | } |
| 1196 | table.numbered-lines td.file-content { |
| 1197 | padding-left: 0.25em; |
| 1198 | } |
| 1199 | table.numbered-lines td.file-content > pre, |
| 1200 | table.numbered-lines td.file-content > pre > code { |
| 1201 | margin: 0; |
| 1202 | padding: 0; |
| 1203 | line-height: inherit; |
| 1204 | font-size: inherit; |
| 1205 | font-family: inherit; |
| 1206 | white-space: pre; |
| 1207 | display: block/*necessary for certain skins!*/; |
| 1208 | } |
| 1209 | table.numbered-lines td.file-content > pre { |
| 1210 | } |
| 1211 | table.numbered-lines td.file-content > pre > code { |
| 1212 | overflow: auto; |
| 1213 | padding-left: 0.5em; |
| 1214 | padding-right: 0.5em; |
| 1215 | padding-top: 0.25em/*any top padding here must match the top MARGIN of |
| 1216 | td.line-numbers's first span child or the |
| 1217 | lines/code will get misaligned. */; |
| 1218 | padding-bottom: 0.25em/*prevents a slight overlap at bottom from |
| 1219 | triggering a scroller*/; |
| 1220 | } |
| 1221 | table.numbered-lines td.file-content > pre > code > * { |
| 1222 | /* Defense against syntax highlighters indirectly messing up these |
| 1223 | properties... */ |
| 1224 | line-height: inherit; |
| 1225 | font-size: inherit; |
| 1226 | font-family: inherit; |
| 1227 | } |
| 1228 | table.numbered-lines td.line-numbers span.selected-line/*replacement*/ { |
| 1229 | font-weight: bold; |
| 1230 | color: blue; |
| 1231 | background-color: #d5d5ff; |
| 1232 | border: 1px blue solid; |
| 1233 | border-top-width: 0; |
| 1234 | border-bottom-width: 0; |
| 1235 | padding: 0; |
| 1236 | margin: 0; |
| 1237 | } |
| 1238 | table.numbered-lines td.line-numbers span.selected-line.start { |
| 1239 | border-top-width: 1px; |
| 1240 | margin-top: -1px/*restore alignment*/; |
| 1241 | } |
| 1242 | table.numbered-lines td.line-numbers span.selected-line.end { |
| 1243 | border-bottom-width: 1px; |
| 1244 | margin-top: -1px/*restore alignment*/; |
| 1245 | } |
| 1246 | table.numbered-lines td.line-numbers span.selected-line.start.end { |
| 1247 | margin-top: -2px/*restore alignment*/; |
| 1248 | } |
| 1249 | |
| 1250 | .fossil-tooltip { |
| 1251 | text-align: center; |
| 1252 | padding: 0.2em 1em; |
| 1253 | border: 1px solid black; |
| 1254 | border-radius: 0.25em; |
| 1255 | position: absolute; |
| 1256 | display: inline-block; |
| 1257 | z-index: 100; |
| 1258 | box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75); |
| 1259 | background-color: inherit; |
| 1260 | font-size: 80%; |
| 1261 | } |
| 1262 | |
| 1263 | .fossil-toast {/* "toast"-style popup message */ |
| 1264 | padding: 0.25em 0.5em; |
| 1265 | margin: 0; |
| 1266 | border-radius: 0.25em; |
| 1267 | font-size: 1em; |
| 1268 | opacity: 0.8; |
| 1269 | border-size: 1px; |
| 1270 | border-style: dotted; |
| 1271 | border-color: rgb( 127, 127, 127, 0.5 ); |
| 1272 | } |
| 1273 | |
| 1274 | blockquote.file-content { |
| 1275 | /* file content block in the /file page */ |
| 1276 | margin: 0 1em; |
| 1277 | } |
| 1278 |
+1
-1
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -125,11 +125,11 @@ | ||
| 125 | 125 | ** in the count even if it lacks the \n terminator. If an empty string |
| 126 | 126 | ** is specified, the number of lines is zero. For the purposes of this |
| 127 | 127 | ** function, a string is considered empty if it contains no characters |
| 128 | 128 | ** -OR- it contains only NUL characters. |
| 129 | 129 | */ |
| 130 | -static int count_lines( | |
| 130 | +int count_lines( | |
| 131 | 131 | const char *z, |
| 132 | 132 | int n, |
| 133 | 133 | int *pnLine |
| 134 | 134 | ){ |
| 135 | 135 | int nLine; |
| 136 | 136 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -125,11 +125,11 @@ | |
| 125 | ** in the count even if it lacks the \n terminator. If an empty string |
| 126 | ** is specified, the number of lines is zero. For the purposes of this |
| 127 | ** function, a string is considered empty if it contains no characters |
| 128 | ** -OR- it contains only NUL characters. |
| 129 | */ |
| 130 | static int count_lines( |
| 131 | const char *z, |
| 132 | int n, |
| 133 | int *pnLine |
| 134 | ){ |
| 135 | int nLine; |
| 136 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -125,11 +125,11 @@ | |
| 125 | ** in the count even if it lacks the \n terminator. If an empty string |
| 126 | ** is specified, the number of lines is zero. For the purposes of this |
| 127 | ** function, a string is considered empty if it contains no characters |
| 128 | ** -OR- it contains only NUL characters. |
| 129 | */ |
| 130 | int count_lines( |
| 131 | const char *z, |
| 132 | int n, |
| 133 | int *pnLine |
| 134 | ){ |
| 135 | int nLine; |
| 136 |
+9
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -2397,5 +2397,14 @@ | ||
| 2397 | 2397 | changeCount); |
| 2398 | 2398 | }else{ |
| 2399 | 2399 | fossil_print("Touched %d file(s)\n", changeCount); |
| 2400 | 2400 | } |
| 2401 | 2401 | } |
| 2402 | + | |
| 2403 | +/* | |
| 2404 | +** If zFileName is not NULL and contains a '.', this returns a pointer | |
| 2405 | +** to the position after the final '.', else it returns NULL. | |
| 2406 | +*/ | |
| 2407 | +const char * file_extension(const char *zFileName){ | |
| 2408 | + const char * zExt = strrchr(zFileName, '.'); | |
| 2409 | + return zExt ? &zExt[1] : 0; | |
| 2410 | +} | |
| 2402 | 2411 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -2397,5 +2397,14 @@ | |
| 2397 | changeCount); |
| 2398 | }else{ |
| 2399 | fossil_print("Touched %d file(s)\n", changeCount); |
| 2400 | } |
| 2401 | } |
| 2402 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -2397,5 +2397,14 @@ | |
| 2397 | changeCount); |
| 2398 | }else{ |
| 2399 | fossil_print("Touched %d file(s)\n", changeCount); |
| 2400 | } |
| 2401 | } |
| 2402 | |
| 2403 | /* |
| 2404 | ** If zFileName is not NULL and contains a '.', this returns a pointer |
| 2405 | ** to the position after the final '.', else it returns NULL. |
| 2406 | */ |
| 2407 | const char * file_extension(const char *zFileName){ |
| 2408 | const char * zExt = strrchr(zFileName, '.'); |
| 2409 | return zExt ? &zExt[1] : 0; |
| 2410 | } |
| 2411 |
+12
| --- src/fossil.bootstrap.js | ||
| +++ src/fossil.bootstrap.js | ||
| @@ -1,6 +1,18 @@ | ||
| 1 | 1 | "use strict"; |
| 2 | +(function () { | |
| 3 | + /* CustomEvent polyfill, courtesy of Mozilla: | |
| 4 | + https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent | |
| 5 | + */ | |
| 6 | + if(typeof window.CustomEvent === "function") return false; | |
| 7 | + window.CustomEvent = function(event, params) { | |
| 8 | + if(!params) params = {bubbles: false, cancelable: false, detail: null}; | |
| 9 | + const evt = document.createEvent('CustomEvent'); | |
| 10 | + evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail ); | |
| 11 | + return evt; | |
| 12 | + }; | |
| 13 | +})(); | |
| 2 | 14 | (function(global){ |
| 3 | 15 | /* Bootstrapping bits for the global.fossil object. Must be |
| 4 | 16 | loaded after style.c:style_emit_script_tag() has initialized |
| 5 | 17 | that object. |
| 6 | 18 | */ |
| 7 | 19 | |
| 8 | 20 | ADDED src/fossil.copybutton.js |
| --- src/fossil.bootstrap.js | |
| +++ src/fossil.bootstrap.js | |
| @@ -1,6 +1,18 @@ | |
| 1 | "use strict"; |
| 2 | (function(global){ |
| 3 | /* Bootstrapping bits for the global.fossil object. Must be |
| 4 | loaded after style.c:style_emit_script_tag() has initialized |
| 5 | that object. |
| 6 | */ |
| 7 | |
| 8 | DDED src/fossil.copybutton.js |
| --- src/fossil.bootstrap.js | |
| +++ src/fossil.bootstrap.js | |
| @@ -1,6 +1,18 @@ | |
| 1 | "use strict"; |
| 2 | (function () { |
| 3 | /* CustomEvent polyfill, courtesy of Mozilla: |
| 4 | https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent |
| 5 | */ |
| 6 | if(typeof window.CustomEvent === "function") return false; |
| 7 | window.CustomEvent = function(event, params) { |
| 8 | if(!params) params = {bubbles: false, cancelable: false, detail: null}; |
| 9 | const evt = document.createEvent('CustomEvent'); |
| 10 | evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail ); |
| 11 | return evt; |
| 12 | }; |
| 13 | })(); |
| 14 | (function(global){ |
| 15 | /* Bootstrapping bits for the global.fossil object. Must be |
| 16 | loaded after style.c:style_emit_script_tag() has initialized |
| 17 | that object. |
| 18 | */ |
| 19 | |
| 20 | DDED src/fossil.copybutton.js |
| --- a/src/fossil.copybutton.js | ||
| +++ b/src/fossil.copybutton.js | ||
| @@ -0,0 +1,3 @@ | ||
| 1 | +(function(F/*fossil object*/){ | |
| 2 | + /** | |
| 3 | + A basic API for creating and |
| --- a/src/fossil.copybutton.js | |
| +++ b/src/fossil.copybutton.js | |
| @@ -0,0 +1,3 @@ | |
| --- a/src/fossil.copybutton.js | |
| +++ b/src/fossil.copybutton.js | |
| @@ -0,0 +1,3 @@ | |
| 1 | (function(F/*fossil object*/){ |
| 2 | /** |
| 3 | A basic API for creating and |
+93
| --- src/fossil.dom.js | ||
| +++ src/fossil.dom.js | ||
| @@ -465,10 +465,103 @@ | ||
| 465 | 465 | e = src.querySelector(x); |
| 466 | 466 | if(!e){ |
| 467 | 467 | e = new Error("Cannot find DOM element: "+x); |
| 468 | 468 | console.error(e, src); |
| 469 | 469 | throw e; |
| 470 | + } | |
| 471 | + return e; | |
| 472 | + }; | |
| 473 | + | |
| 474 | + /** | |
| 475 | + "Blinks" the given element a single time for the given number of | |
| 476 | + milliseconds, defaulting (if the 2nd argument is falsy or not a | |
| 477 | + number) to flashOnce.defaultTimeMs. If a 3rd argument is passed | |
| 478 | + in, it must be a function, and it gets callback back at the end | |
| 479 | + of the asynchronous flashing processes. | |
| 480 | + | |
| 481 | + This will only activate once per element during that timeframe - | |
| 482 | + further calls will become no-ops until the blink is | |
| 483 | + completed. This routine adds a dataset member to the element for | |
| 484 | + the duration of the blink, to allow it to block multiple blinks. | |
| 485 | + | |
| 486 | + If passed 2 arguments and the 2nd is a function, it behaves as if | |
| 487 | + it were called as (arg1, undefined, arg2). | |
| 488 | + | |
| 489 | + Returns e, noting that the flash itself is asynchronous and may | |
| 490 | + still be running, or not yet started, when this function returns. | |
| 491 | + */ | |
| 492 | + dom.flashOnce = function f(e,howLongMs,afterFlashCallback){ | |
| 493 | + if(e.dataset.isBlinking){ | |
| 494 | + return; | |
| 495 | + } | |
| 496 | + if(2===arguments.length && 'function' ===typeof howLongMs){ | |
| 497 | + afterFlashCallback = howLongMs; | |
| 498 | + howLongMs = f.defaultTimeMs; | |
| 499 | + } | |
| 500 | + if(!howLongMs || 'number'!==typeof howLongMs){ | |
| 501 | + howLongMs = f.defaultTimeMs; | |
| 502 | + } | |
| 503 | + e.dataset.isBlinking = true; | |
| 504 | + const transition = e.style.transition; | |
| 505 | + e.style.transition = "opacity "+howLongMs+"ms ease-in-out"; | |
| 506 | + const opacity = e.style.opacity; | |
| 507 | + e.style.opacity = 0; | |
| 508 | + setTimeout(function(){ | |
| 509 | + e.style.transition = transition; | |
| 510 | + e.style.opacity = opacity; | |
| 511 | + delete e.dataset.isBlinking; | |
| 512 | + if(afterFlashCallback) afterFlashCallback(); | |
| 513 | + }, howLongMs); | |
| 514 | + return e; | |
| 515 | + }; | |
| 516 | + dom.flashOnce.defaultTimeMs = 400; | |
| 517 | + | |
| 518 | + /** | |
| 519 | + Attempts to copy the given text to the system clipboard. Returns | |
| 520 | + true if it succeeds, else false. | |
| 521 | + */ | |
| 522 | + dom.copyTextToClipboard = function(text){ | |
| 523 | + if( window.clipboardData && window.clipboardData.setData ){ | |
| 524 | + clipboardData.setData('Text',text); | |
| 525 | + return true; | |
| 526 | + }else{ | |
| 527 | + const x = document.createElement("textarea"); | |
| 528 | + x.style.position = 'fixed'; | |
| 529 | + x.value = text; | |
| 530 | + document.body.appendChild(x); | |
| 531 | + x.select(); | |
| 532 | + var rc; | |
| 533 | + try{ | |
| 534 | + document.execCommand('copy'); | |
| 535 | + rc = true; | |
| 536 | + }catch(err){ | |
| 537 | + rc = false; | |
| 538 | + }finally{ | |
| 539 | + document.body.removeChild(x); | |
| 540 | + } | |
| 541 | + return rc; | |
| 542 | + } | |
| 543 | + }; | |
| 544 | + | |
| 545 | + /** | |
| 546 | + Copies all properties from the 2nd argument (a plain object) into | |
| 547 | + the style member of the first argument (DOM element or a | |
| 548 | + forEach-capable list of elements). If the 2nd argument is falsy | |
| 549 | + or empty, this is a no-op. | |
| 550 | + | |
| 551 | + Returns its first argument. | |
| 552 | + */ | |
| 553 | + dom.copyStyle = function f(e, style){ | |
| 554 | + if(e.forEach){ | |
| 555 | + e.forEach((x)=>f(x, style)); | |
| 556 | + return e; | |
| 557 | + } | |
| 558 | + if(style){ | |
| 559 | + let k; | |
| 560 | + for(k in style){ | |
| 561 | + if(style.hasOwnProperty(k)) e.style[k] = style[k]; | |
| 562 | + } | |
| 470 | 563 | } |
| 471 | 564 | return e; |
| 472 | 565 | }; |
| 473 | 566 | |
| 474 | 567 | return F.dom = dom; |
| 475 | 568 | |
| 476 | 569 | ADDED src/fossil.numbered-lines.js |
| 477 | 570 | ADDED src/fossil.popupwidget.js |
| --- src/fossil.dom.js | |
| +++ src/fossil.dom.js | |
| @@ -465,10 +465,103 @@ | |
| 465 | e = src.querySelector(x); |
| 466 | if(!e){ |
| 467 | e = new Error("Cannot find DOM element: "+x); |
| 468 | console.error(e, src); |
| 469 | throw e; |
| 470 | } |
| 471 | return e; |
| 472 | }; |
| 473 | |
| 474 | return F.dom = dom; |
| 475 | |
| 476 | DDED src/fossil.numbered-lines.js |
| 477 | DDED src/fossil.popupwidget.js |
| --- src/fossil.dom.js | |
| +++ src/fossil.dom.js | |
| @@ -465,10 +465,103 @@ | |
| 465 | e = src.querySelector(x); |
| 466 | if(!e){ |
| 467 | e = new Error("Cannot find DOM element: "+x); |
| 468 | console.error(e, src); |
| 469 | throw e; |
| 470 | } |
| 471 | return e; |
| 472 | }; |
| 473 | |
| 474 | /** |
| 475 | "Blinks" the given element a single time for the given number of |
| 476 | milliseconds, defaulting (if the 2nd argument is falsy or not a |
| 477 | number) to flashOnce.defaultTimeMs. If a 3rd argument is passed |
| 478 | in, it must be a function, and it gets callback back at the end |
| 479 | of the asynchronous flashing processes. |
| 480 | |
| 481 | This will only activate once per element during that timeframe - |
| 482 | further calls will become no-ops until the blink is |
| 483 | completed. This routine adds a dataset member to the element for |
| 484 | the duration of the blink, to allow it to block multiple blinks. |
| 485 | |
| 486 | If passed 2 arguments and the 2nd is a function, it behaves as if |
| 487 | it were called as (arg1, undefined, arg2). |
| 488 | |
| 489 | Returns e, noting that the flash itself is asynchronous and may |
| 490 | still be running, or not yet started, when this function returns. |
| 491 | */ |
| 492 | dom.flashOnce = function f(e,howLongMs,afterFlashCallback){ |
| 493 | if(e.dataset.isBlinking){ |
| 494 | return; |
| 495 | } |
| 496 | if(2===arguments.length && 'function' ===typeof howLongMs){ |
| 497 | afterFlashCallback = howLongMs; |
| 498 | howLongMs = f.defaultTimeMs; |
| 499 | } |
| 500 | if(!howLongMs || 'number'!==typeof howLongMs){ |
| 501 | howLongMs = f.defaultTimeMs; |
| 502 | } |
| 503 | e.dataset.isBlinking = true; |
| 504 | const transition = e.style.transition; |
| 505 | e.style.transition = "opacity "+howLongMs+"ms ease-in-out"; |
| 506 | const opacity = e.style.opacity; |
| 507 | e.style.opacity = 0; |
| 508 | setTimeout(function(){ |
| 509 | e.style.transition = transition; |
| 510 | e.style.opacity = opacity; |
| 511 | delete e.dataset.isBlinking; |
| 512 | if(afterFlashCallback) afterFlashCallback(); |
| 513 | }, howLongMs); |
| 514 | return e; |
| 515 | }; |
| 516 | dom.flashOnce.defaultTimeMs = 400; |
| 517 | |
| 518 | /** |
| 519 | Attempts to copy the given text to the system clipboard. Returns |
| 520 | true if it succeeds, else false. |
| 521 | */ |
| 522 | dom.copyTextToClipboard = function(text){ |
| 523 | if( window.clipboardData && window.clipboardData.setData ){ |
| 524 | clipboardData.setData('Text',text); |
| 525 | return true; |
| 526 | }else{ |
| 527 | const x = document.createElement("textarea"); |
| 528 | x.style.position = 'fixed'; |
| 529 | x.value = text; |
| 530 | document.body.appendChild(x); |
| 531 | x.select(); |
| 532 | var rc; |
| 533 | try{ |
| 534 | document.execCommand('copy'); |
| 535 | rc = true; |
| 536 | }catch(err){ |
| 537 | rc = false; |
| 538 | }finally{ |
| 539 | document.body.removeChild(x); |
| 540 | } |
| 541 | return rc; |
| 542 | } |
| 543 | }; |
| 544 | |
| 545 | /** |
| 546 | Copies all properties from the 2nd argument (a plain object) into |
| 547 | the style member of the first argument (DOM element or a |
| 548 | forEach-capable list of elements). If the 2nd argument is falsy |
| 549 | or empty, this is a no-op. |
| 550 | |
| 551 | Returns its first argument. |
| 552 | */ |
| 553 | dom.copyStyle = function f(e, style){ |
| 554 | if(e.forEach){ |
| 555 | e.forEach((x)=>f(x, style)); |
| 556 | return e; |
| 557 | } |
| 558 | if(style){ |
| 559 | let k; |
| 560 | for(k in style){ |
| 561 | if(style.hasOwnProperty(k)) e.style[k] = style[k]; |
| 562 | } |
| 563 | } |
| 564 | return e; |
| 565 | }; |
| 566 | |
| 567 | return F.dom = dom; |
| 568 | |
| 569 | DDED src/fossil.numbered-lines.js |
| 570 | DDED src/fossil.popupwidget.js |
| --- a/src/fossil.numbered-lines.js | ||
| +++ b/src/fossil.numbered-lines.js | ||
| @@ -0,0 +1,8 @@ | ||
| 1 | +(function callee(arg){ | |
| 2 | + /* | |
| 3 | + JSelse if(!arg){tion callee(arg){ | |
| 4 | + /* | |
| 5 | + JS(function callee(arg){ | |
| 6 | + /* | |
| 7 | + JSfossil', | |
| 8 | + ( |
| --- a/src/fossil.numbered-lines.js | |
| +++ b/src/fossil.numbered-lines.js | |
| @@ -0,0 +1,8 @@ | |
| --- a/src/fossil.numbered-lines.js | |
| +++ b/src/fossil.numbered-lines.js | |
| @@ -0,0 +1,8 @@ | |
| 1 | (function callee(arg){ |
| 2 | /* |
| 3 | JSelse if(!arg){tion callee(arg){ |
| 4 | /* |
| 5 | JS(function callee(arg){ |
| 6 | /* |
| 7 | JSfossil', |
| 8 | ( |
| --- a/src/fossil.popupwidget.js | ||
| +++ b/src/fossil.popupwidget.js | ||
| @@ -0,0 +1,65 @@ | ||
| 1 | +(function(F/*fossil object*/){ | |
| 2 | + 30 */ | |
| 3 | + installClickToHiden or basic user intera(function(F/*fossil object*/){ | |
| 4 | + 3000sClass = cssClass; | |
| 5 | + unct}, true);isplay basic information ClickToHide(nction(F/*fossil object*/fossil object*/){ | |
| 6 | + 3000sClass = cssClass; | |
| 7 | + unction(F/*fossil object*/){ | |
| 8 | + /** | |
| 9 | + A very basic tooltip-like widget. It's intended to be popped up | |
| 10 | + to display basic information or basic user interaction | |
| 11 | + components, e.g. a cop or movopy-to-clipboard butt | |
| 12 | + if needed,l.dom | |
| 13 | + */ | |
| 14 | + const D = F.dom | |
| 15 | + base DOMwidget using the | |
| 16 | +). If theallback whic | |
| 17 | + h is called just before*/){ | |
| 18 | + 30 */ | |
| 19 | + instfunction(F/*fossil object*/){ | |
| 20 | + 30 */ | |
| 21 | + installClickToHiden or basic user intera(function(F/*fossil object*/){ | |
| 22 | + 3000sClass = cssClass; | |
| 23 | + unct}, true);isplay basic information ClickToHide(nction(F/*fossil object*/fossil object*/){ | |
| 24 | + 3000sClass = cssClass; | |
| 25 | + unction(F/*fossil object*/){ | |
| 26 | + /** | |
| 27 | + A very basic tooltip-like widget. It's intended to be popped up | |
| 28 | + to display basic information or basic user interaction | |
| 29 | + components, e.g. a copy-to-clipboard button. | |
| 30 | + | |
| 31 | + Requires: fossil.bootstrap, fossil.dom | |
| 32 | + */ | |
| 33 | + conbjecthe popup when either | |
| 34 | + call this | |
| 35 | + show(falseshow(falseshow(falseconst hide Just be careful to mess only with the X coordinate | |
| 36 | + and the width. The browser will try to keep the widget | |
| 37 | + from being truncated off-screen on the right, shifting it | |
| 38 | + to the left if needed, and we cannot generically be sure | |
| 39 | + that an enforced fully on-screen size will actually fit | |
| 40 | + the current help textclickHandler){const rect1unction(F/*fossil object*(function(F/*fossil object*/){})(window.fossil); | |
| 41 | +deleteleft'); | |
| 42 | + deletea toas(function(F/*fossil o*fossil object*/){ | |
| 43 | +function(F/*fossil ct*/){ | |
| 44 | + 30 */ | |
| 45 | + installClickToHiden or basic user intera(fun*/ | |
| 46 | + F.toast = function f(/*...*/){ | |
| 47 | + f.toast = function ff(argsObject){ | |
| 48 | + if(!ff.toaster) f ['fossil-tooltip', 'fossil-toast'] | |
| 49 | + }); | |
| 50 | + i@1hi,X: D.clearElement(ff.toaster.e);9@1SA,2w:var i = 0; | |
| 51 | + for( ; i < argsObject.length; ++i ){ | |
| 52 | + D.append(ff.toaster.e, argsObject[i]); | |
| 53 | + }; | |
| 54 | + ff.toaster.show(f.config.position.x, f.config.position.y); | |
| 55 | + Q@1mw,1m:()=>ff.toaster.hide(), f.config.displayTimeMs); | |
| 56 | + }; | |
| 57 | + } | |
| 58 | + f.toast(arguments); | |
| 59 | + }; | |
| 60 | + F.toast.config = { | |
| 61 | +10@1pR,i:displayTimeMs: 2500 | |
| 62 | + }; | |
| 63 | + | |
| 64 | +})(window.fossil); | |
| 65 | +ZfWzX; |
| --- a/src/fossil.popupwidget.js | |
| +++ b/src/fossil.popupwidget.js | |
| @@ -0,0 +1,65 @@ | |
| --- a/src/fossil.popupwidget.js | |
| +++ b/src/fossil.popupwidget.js | |
| @@ -0,0 +1,65 @@ | |
| 1 | (function(F/*fossil object*/){ |
| 2 | 30 */ |
| 3 | installClickToHiden or basic user intera(function(F/*fossil object*/){ |
| 4 | 3000sClass = cssClass; |
| 5 | unct}, true);isplay basic information ClickToHide(nction(F/*fossil object*/fossil object*/){ |
| 6 | 3000sClass = cssClass; |
| 7 | unction(F/*fossil object*/){ |
| 8 | /** |
| 9 | A very basic tooltip-like widget. It's intended to be popped up |
| 10 | to display basic information or basic user interaction |
| 11 | components, e.g. a cop or movopy-to-clipboard butt |
| 12 | if needed,l.dom |
| 13 | */ |
| 14 | const D = F.dom |
| 15 | base DOMwidget using the |
| 16 | ). If theallback whic |
| 17 | h is called just before*/){ |
| 18 | 30 */ |
| 19 | instfunction(F/*fossil object*/){ |
| 20 | 30 */ |
| 21 | installClickToHiden or basic user intera(function(F/*fossil object*/){ |
| 22 | 3000sClass = cssClass; |
| 23 | unct}, true);isplay basic information ClickToHide(nction(F/*fossil object*/fossil object*/){ |
| 24 | 3000sClass = cssClass; |
| 25 | unction(F/*fossil object*/){ |
| 26 | /** |
| 27 | A very basic tooltip-like widget. It's intended to be popped up |
| 28 | to display basic information or basic user interaction |
| 29 | components, e.g. a copy-to-clipboard button. |
| 30 | |
| 31 | Requires: fossil.bootstrap, fossil.dom |
| 32 | */ |
| 33 | conbjecthe popup when either |
| 34 | call this |
| 35 | show(falseshow(falseshow(falseconst hide Just be careful to mess only with the X coordinate |
| 36 | and the width. The browser will try to keep the widget |
| 37 | from being truncated off-screen on the right, shifting it |
| 38 | to the left if needed, and we cannot generically be sure |
| 39 | that an enforced fully on-screen size will actually fit |
| 40 | the current help textclickHandler){const rect1unction(F/*fossil object*(function(F/*fossil object*/){})(window.fossil); |
| 41 | deleteleft'); |
| 42 | deletea toas(function(F/*fossil o*fossil object*/){ |
| 43 | function(F/*fossil ct*/){ |
| 44 | 30 */ |
| 45 | installClickToHiden or basic user intera(fun*/ |
| 46 | F.toast = function f(/*...*/){ |
| 47 | f.toast = function ff(argsObject){ |
| 48 | if(!ff.toaster) f ['fossil-tooltip', 'fossil-toast'] |
| 49 | }); |
| 50 | i@1hi,X: D.clearElement(ff.toaster.e);9@1SA,2w:var i = 0; |
| 51 | for( ; i < argsObject.length; ++i ){ |
| 52 | D.append(ff.toaster.e, argsObject[i]); |
| 53 | }; |
| 54 | ff.toaster.show(f.config.position.x, f.config.position.y); |
| 55 | Q@1mw,1m:()=>ff.toaster.hide(), f.config.displayTimeMs); |
| 56 | }; |
| 57 | } |
| 58 | f.toast(arguments); |
| 59 | }; |
| 60 | F.toast.config = { |
| 61 | 10@1pR,i:displayTimeMs: 2500 |
| 62 | }; |
| 63 | |
| 64 | })(window.fossil); |
| 65 | ZfWzX; |
+100
-44
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -2011,27 +2011,37 @@ | ||
| 2011 | 2011 | manifest_destroy(pManifest); |
| 2012 | 2012 | return rid; |
| 2013 | 2013 | } |
| 2014 | 2014 | |
| 2015 | 2015 | /* |
| 2016 | -** The "z" argument is a string that contains the text of a source code | |
| 2017 | -** file. This routine appends that text to the HTTP reply with line numbering. | |
| 2016 | +** The "z" argument is a string that contains the text of a source | |
| 2017 | +** code file and nZ is its length in bytes. This routine appends that | |
| 2018 | +** text to the HTTP reply with line numbering. | |
| 2019 | +** | |
| 2020 | +** zName is the content's file name, if any (it may be NULL). If that | |
| 2021 | +** name contains a '.' then the part after the final '.' is used as | |
| 2022 | +** the X part of a "language-X" CSS class on the generated CODE block. | |
| 2018 | 2023 | ** |
| 2019 | 2024 | ** zLn is the ?ln= parameter for the HTTP query. If there is an argument, |
| 2020 | 2025 | ** then highlight that line number and scroll to it once the page loads. |
| 2021 | 2026 | ** If there are two line numbers, highlight the range of lines. |
| 2022 | 2027 | ** Multiple ranges can be highlighed by adding additional line numbers |
| 2023 | 2028 | ** separated by a non-digit character (also not one of [-,.]). |
| 2024 | 2029 | */ |
| 2025 | 2030 | void output_text_with_line_numbers( |
| 2026 | 2031 | const char *z, |
| 2032 | + int nZ, | |
| 2033 | + const char *zName, | |
| 2027 | 2034 | const char *zLn |
| 2028 | 2035 | ){ |
| 2029 | 2036 | int iStart, iEnd; /* Start and end of region to highlight */ |
| 2030 | 2037 | int n = 0; /* Current line number */ |
| 2031 | 2038 | int i = 0; /* Loop index */ |
| 2032 | 2039 | int iTop = 0; /* Scroll so that this line is on top of screen. */ |
| 2040 | + int nLine = 0; /* content line count */ | |
| 2041 | + int nSpans = 0; /* number of distinct zLn spans */ | |
| 2042 | + const char *zExt = file_extension(zName); | |
| 2033 | 2043 | Stmt q; |
| 2034 | 2044 | |
| 2035 | 2045 | iStart = iEnd = atoi(zLn); |
| 2036 | 2046 | db_multi_exec( |
| 2037 | 2047 | "CREATE TEMP TABLE lnos(iStart INTEGER PRIMARY KEY, iEnd INTEGER)"); |
| @@ -2047,56 +2057,101 @@ | ||
| 2047 | 2057 | while( fossil_isdigit(zLn[i]) ) i++; |
| 2048 | 2058 | if( iEnd<iStart ) iEnd = iStart; |
| 2049 | 2059 | db_multi_exec( |
| 2050 | 2060 | "INSERT OR REPLACE INTO lnos VALUES(%d,%d)", iStart, iEnd |
| 2051 | 2061 | ); |
| 2062 | + ++nSpans; | |
| 2052 | 2063 | iStart = iEnd = atoi(&zLn[i++]); |
| 2053 | 2064 | }while( zLn[i] && iStart && iEnd ); |
| 2054 | 2065 | } |
| 2055 | - db_prepare(&q, "SELECT min(iStart), max(iEnd) FROM lnos"); | |
| 2056 | - if( db_step(&q)==SQLITE_ROW ){ | |
| 2057 | - iStart = db_column_int(&q, 0); | |
| 2058 | - iEnd = db_column_int(&q, 1); | |
| 2059 | - iTop = iStart - 15 + (iEnd-iStart)/4; | |
| 2060 | - if( iTop>iStart - 2 ) iTop = iStart-2; | |
| 2061 | - } | |
| 2062 | - db_finalize(&q); | |
| 2063 | - @ <pre> | |
| 2064 | - while( z[0] ){ | |
| 2065 | - n++; | |
| 2066 | - db_prepare(&q, | |
| 2067 | - "SELECT min(iStart), max(iEnd) FROM lnos" | |
| 2068 | - " WHERE iStart <= %d AND iEnd >= %d", n, n); | |
| 2069 | - if( db_step(&q)==SQLITE_ROW ){ | |
| 2070 | - iStart = db_column_int(&q, 0); | |
| 2071 | - iEnd = db_column_int(&q, 1); | |
| 2072 | - } | |
| 2073 | - db_finalize(&q); | |
| 2074 | - for(i=0; z[i] && z[i]!='\n'; i++){} | |
| 2075 | - if( n==iTop ) cgi_append_content("<span id=\"scrollToMe\">", -1); | |
| 2076 | - if( n==iStart ){ | |
| 2077 | - cgi_append_content("<div class=\"selectedText\">",-1); | |
| 2078 | - } | |
| 2079 | - cgi_printf("%6d ", n); | |
| 2080 | - if( i>0 ){ | |
| 2081 | - char *zHtml = htmlize(z, i); | |
| 2082 | - cgi_append_content(zHtml, -1); | |
| 2083 | - fossil_free(zHtml); | |
| 2084 | - } | |
| 2085 | - if( n==iTop ) cgi_append_content("</span>", -1); | |
| 2086 | - if( n==iEnd ) cgi_append_content("</div>", -1); | |
| 2087 | - else cgi_append_content("\n", 1); | |
| 2088 | - z += i; | |
| 2089 | - if( z[0]=='\n' ) z++; | |
| 2090 | - } | |
| 2091 | - if( n<iEnd ) cgi_printf("</div>"); | |
| 2092 | - @ </pre> | |
| 2066 | + /*cgi_printf("<!-- ln span count=%d -->", nSpans);*/ | |
| 2067 | + cgi_append_content("<table class='numbered-lines'><tbody>" | |
| 2068 | + "<tr><td class='line-numbers'>", -1); | |
| 2069 | + iStart = iEnd = 0; | |
| 2070 | + count_lines(z, nZ, &nLine); | |
| 2071 | + for( n=1 ; n<=nLine; ++n ){ | |
| 2072 | + const char * zAttr = ""; | |
| 2073 | + const char * zId = ""; | |
| 2074 | + if(nSpans>0 && iEnd==0){/*Grab the next range of zLn marking*/ | |
| 2075 | + db_prepare(&q, "SELECT iStart, iEnd FROM lnos " | |
| 2076 | + "WHERE iStart >= %d ORDER BY iStart", n); | |
| 2077 | + if( db_step(&q)==SQLITE_ROW ){ | |
| 2078 | + iStart = db_column_int(&q, 0); | |
| 2079 | + iEnd = db_column_int(&q, 1); | |
| 2080 | + if(!iTop){ | |
| 2081 | + iTop = iStart - 15 + (iEnd-iStart)/4; | |
| 2082 | + if( iTop>iStart - 2 ) iTop = iStart-2; | |
| 2083 | + } | |
| 2084 | + }else{ | |
| 2085 | + /* Note that overlapping multi-spans, e.g. 10-15+12-20, | |
| 2086 | + can cause us to miss a row. */ | |
| 2087 | + iStart = iEnd = 0; | |
| 2088 | + } | |
| 2089 | + db_finalize(&q); | |
| 2090 | + --nSpans; | |
| 2091 | + /*cgi_printf("<!-- iStart=%d, iEnd=%d -->", iStart, iEnd);*/ | |
| 2092 | + } | |
| 2093 | + if(n==iTop) { | |
| 2094 | + zId = " id='scrollToMe'"; | |
| 2095 | + } | |
| 2096 | + if(n==iStart){/*Figure out which CSS class(es) this line needs...*/ | |
| 2097 | + if(n==iEnd){ | |
| 2098 | + zAttr = " class='selected-line start end'"; | |
| 2099 | + iEnd = 0; | |
| 2100 | + }else{ | |
| 2101 | + zAttr = " class='selected-line start'"; | |
| 2102 | + } | |
| 2103 | + iStart = 0; | |
| 2104 | + }else if(n==iEnd){ | |
| 2105 | + zAttr = " class='selected-line end'"; | |
| 2106 | + iEnd = 0; | |
| 2107 | + }else if( n>iStart && n<iEnd ){ | |
| 2108 | + zAttr = " class='selected-line'"; | |
| 2109 | + } | |
| 2110 | + cgi_printf("<span%s%s>%6d</span>", zId, zAttr, n); | |
| 2111 | + } | |
| 2112 | + cgi_append_content("</td><td class='file-content'><pre>",-1); | |
| 2113 | + if(zExt && *zExt){ | |
| 2114 | + cgi_printf("<code class='language-%h'>",zExt); | |
| 2115 | + }else{ | |
| 2116 | + cgi_append_content("<code>", -1); | |
| 2117 | + } | |
| 2118 | + cgi_printf("%z", htmlize(z, nZ)); | |
| 2119 | + CX("</code></pre></td></tr></tbody></table>\n"); | |
| 2093 | 2120 | if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){ |
| 2094 | 2121 | builtin_request_js("scroll.js"); |
| 2095 | 2122 | } |
| 2123 | + style_emit_fossil_js_apis(0, "dom", "copybutton", "popupwidget", | |
| 2124 | + "numbered-lines", 0); | |
| 2096 | 2125 | } |
| 2097 | 2126 | |
| 2127 | +/* | |
| 2128 | +** COMMAND: test-line-numbers | |
| 2129 | +** | |
| 2130 | +** Usage: %fossil test-line-numbers FILE ?LN-SPEC? | |
| 2131 | +** | |
| 2132 | +*/ | |
| 2133 | +void cmd_test_line_numbers(void){ | |
| 2134 | + Blob content = empty_blob; | |
| 2135 | + const char * zLn = ""; | |
| 2136 | + const char * zFilename = 0; | |
| 2137 | + | |
| 2138 | + if(g.argc < 3){ | |
| 2139 | + usage("FILE"); | |
| 2140 | + }else if(g.argc>3){ | |
| 2141 | + zLn = g.argv[3]; | |
| 2142 | + } | |
| 2143 | + db_find_and_open_repository(0,0); | |
| 2144 | + zFilename = g.argv[2]; | |
| 2145 | + fossil_print("%s %s\n", zFilename, zLn); | |
| 2146 | + | |
| 2147 | + blob_read_from_file(&content, zFilename, ExtFILE); | |
| 2148 | + output_text_with_line_numbers(blob_str(&content), blob_size(&content), | |
| 2149 | + zFilename, zLn); | |
| 2150 | + blob_reset(&content); | |
| 2151 | + fossil_print("%b\n", cgi_output_blob()); | |
| 2152 | +} | |
| 2098 | 2153 | |
| 2099 | 2154 | /* |
| 2100 | 2155 | ** WEBPAGE: artifact |
| 2101 | 2156 | ** WEBPAGE: file |
| 2102 | 2157 | ** WEBPAGE: whatis |
| @@ -2387,25 +2442,26 @@ | ||
| 2387 | 2442 | if( zLn==0 || atoi(zLn)==0 ){ |
| 2388 | 2443 | style_submenu_checkbox("ln", "Line Numbers", 0, 0); |
| 2389 | 2444 | } |
| 2390 | 2445 | blob_to_utf8_no_bom(&content, 0); |
| 2391 | 2446 | zMime = mimetype_from_content(&content); |
| 2392 | - @ <blockquote> | |
| 2447 | + @ <blockquote class="file-content"> | |
| 2393 | 2448 | if( zMime==0 ){ |
| 2394 | 2449 | const char *z, *zFileName, *zExt; |
| 2395 | 2450 | z = blob_str(&content); |
| 2396 | 2451 | zFileName = db_text(0, |
| 2397 | 2452 | "SELECT name FROM mlink, filename" |
| 2398 | 2453 | " WHERE filename.fnid=mlink.fnid" |
| 2399 | 2454 | " AND mlink.fid=%d", |
| 2400 | 2455 | rid); |
| 2401 | - zExt = zFileName ? strrchr(zFileName, '.') : 0; | |
| 2456 | + zExt = file_extension(zFileName); | |
| 2402 | 2457 | if( zLn ){ |
| 2403 | - output_text_with_line_numbers(z, zLn); | |
| 2458 | + output_text_with_line_numbers(z, blob_size(&content), | |
| 2459 | + zFileName, zLn); | |
| 2404 | 2460 | }else if( zExt && zExt[1] ){ |
| 2405 | 2461 | @ <pre> |
| 2406 | - @ <code class="language-%s(zExt+1)">%h(z)</code> | |
| 2462 | + @ <code class="language-%s(zExt)">%h(z)</code> | |
| 2407 | 2463 | @ </pre> |
| 2408 | 2464 | }else{ |
| 2409 | 2465 | @ <pre> |
| 2410 | 2466 | @ %h(z) |
| 2411 | 2467 | @ </pre> |
| 2412 | 2468 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -2011,27 +2011,37 @@ | |
| 2011 | manifest_destroy(pManifest); |
| 2012 | return rid; |
| 2013 | } |
| 2014 | |
| 2015 | /* |
| 2016 | ** The "z" argument is a string that contains the text of a source code |
| 2017 | ** file. This routine appends that text to the HTTP reply with line numbering. |
| 2018 | ** |
| 2019 | ** zLn is the ?ln= parameter for the HTTP query. If there is an argument, |
| 2020 | ** then highlight that line number and scroll to it once the page loads. |
| 2021 | ** If there are two line numbers, highlight the range of lines. |
| 2022 | ** Multiple ranges can be highlighed by adding additional line numbers |
| 2023 | ** separated by a non-digit character (also not one of [-,.]). |
| 2024 | */ |
| 2025 | void output_text_with_line_numbers( |
| 2026 | const char *z, |
| 2027 | const char *zLn |
| 2028 | ){ |
| 2029 | int iStart, iEnd; /* Start and end of region to highlight */ |
| 2030 | int n = 0; /* Current line number */ |
| 2031 | int i = 0; /* Loop index */ |
| 2032 | int iTop = 0; /* Scroll so that this line is on top of screen. */ |
| 2033 | Stmt q; |
| 2034 | |
| 2035 | iStart = iEnd = atoi(zLn); |
| 2036 | db_multi_exec( |
| 2037 | "CREATE TEMP TABLE lnos(iStart INTEGER PRIMARY KEY, iEnd INTEGER)"); |
| @@ -2047,56 +2057,101 @@ | |
| 2047 | while( fossil_isdigit(zLn[i]) ) i++; |
| 2048 | if( iEnd<iStart ) iEnd = iStart; |
| 2049 | db_multi_exec( |
| 2050 | "INSERT OR REPLACE INTO lnos VALUES(%d,%d)", iStart, iEnd |
| 2051 | ); |
| 2052 | iStart = iEnd = atoi(&zLn[i++]); |
| 2053 | }while( zLn[i] && iStart && iEnd ); |
| 2054 | } |
| 2055 | db_prepare(&q, "SELECT min(iStart), max(iEnd) FROM lnos"); |
| 2056 | if( db_step(&q)==SQLITE_ROW ){ |
| 2057 | iStart = db_column_int(&q, 0); |
| 2058 | iEnd = db_column_int(&q, 1); |
| 2059 | iTop = iStart - 15 + (iEnd-iStart)/4; |
| 2060 | if( iTop>iStart - 2 ) iTop = iStart-2; |
| 2061 | } |
| 2062 | db_finalize(&q); |
| 2063 | @ <pre> |
| 2064 | while( z[0] ){ |
| 2065 | n++; |
| 2066 | db_prepare(&q, |
| 2067 | "SELECT min(iStart), max(iEnd) FROM lnos" |
| 2068 | " WHERE iStart <= %d AND iEnd >= %d", n, n); |
| 2069 | if( db_step(&q)==SQLITE_ROW ){ |
| 2070 | iStart = db_column_int(&q, 0); |
| 2071 | iEnd = db_column_int(&q, 1); |
| 2072 | } |
| 2073 | db_finalize(&q); |
| 2074 | for(i=0; z[i] && z[i]!='\n'; i++){} |
| 2075 | if( n==iTop ) cgi_append_content("<span id=\"scrollToMe\">", -1); |
| 2076 | if( n==iStart ){ |
| 2077 | cgi_append_content("<div class=\"selectedText\">",-1); |
| 2078 | } |
| 2079 | cgi_printf("%6d ", n); |
| 2080 | if( i>0 ){ |
| 2081 | char *zHtml = htmlize(z, i); |
| 2082 | cgi_append_content(zHtml, -1); |
| 2083 | fossil_free(zHtml); |
| 2084 | } |
| 2085 | if( n==iTop ) cgi_append_content("</span>", -1); |
| 2086 | if( n==iEnd ) cgi_append_content("</div>", -1); |
| 2087 | else cgi_append_content("\n", 1); |
| 2088 | z += i; |
| 2089 | if( z[0]=='\n' ) z++; |
| 2090 | } |
| 2091 | if( n<iEnd ) cgi_printf("</div>"); |
| 2092 | @ </pre> |
| 2093 | if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){ |
| 2094 | builtin_request_js("scroll.js"); |
| 2095 | } |
| 2096 | } |
| 2097 | |
| 2098 | |
| 2099 | /* |
| 2100 | ** WEBPAGE: artifact |
| 2101 | ** WEBPAGE: file |
| 2102 | ** WEBPAGE: whatis |
| @@ -2387,25 +2442,26 @@ | |
| 2387 | if( zLn==0 || atoi(zLn)==0 ){ |
| 2388 | style_submenu_checkbox("ln", "Line Numbers", 0, 0); |
| 2389 | } |
| 2390 | blob_to_utf8_no_bom(&content, 0); |
| 2391 | zMime = mimetype_from_content(&content); |
| 2392 | @ <blockquote> |
| 2393 | if( zMime==0 ){ |
| 2394 | const char *z, *zFileName, *zExt; |
| 2395 | z = blob_str(&content); |
| 2396 | zFileName = db_text(0, |
| 2397 | "SELECT name FROM mlink, filename" |
| 2398 | " WHERE filename.fnid=mlink.fnid" |
| 2399 | " AND mlink.fid=%d", |
| 2400 | rid); |
| 2401 | zExt = zFileName ? strrchr(zFileName, '.') : 0; |
| 2402 | if( zLn ){ |
| 2403 | output_text_with_line_numbers(z, zLn); |
| 2404 | }else if( zExt && zExt[1] ){ |
| 2405 | @ <pre> |
| 2406 | @ <code class="language-%s(zExt+1)">%h(z)</code> |
| 2407 | @ </pre> |
| 2408 | }else{ |
| 2409 | @ <pre> |
| 2410 | @ %h(z) |
| 2411 | @ </pre> |
| 2412 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -2011,27 +2011,37 @@ | |
| 2011 | manifest_destroy(pManifest); |
| 2012 | return rid; |
| 2013 | } |
| 2014 | |
| 2015 | /* |
| 2016 | ** The "z" argument is a string that contains the text of a source |
| 2017 | ** code file and nZ is its length in bytes. This routine appends that |
| 2018 | ** text to the HTTP reply with line numbering. |
| 2019 | ** |
| 2020 | ** zName is the content's file name, if any (it may be NULL). If that |
| 2021 | ** name contains a '.' then the part after the final '.' is used as |
| 2022 | ** the X part of a "language-X" CSS class on the generated CODE block. |
| 2023 | ** |
| 2024 | ** zLn is the ?ln= parameter for the HTTP query. If there is an argument, |
| 2025 | ** then highlight that line number and scroll to it once the page loads. |
| 2026 | ** If there are two line numbers, highlight the range of lines. |
| 2027 | ** Multiple ranges can be highlighed by adding additional line numbers |
| 2028 | ** separated by a non-digit character (also not one of [-,.]). |
| 2029 | */ |
| 2030 | void output_text_with_line_numbers( |
| 2031 | const char *z, |
| 2032 | int nZ, |
| 2033 | const char *zName, |
| 2034 | const char *zLn |
| 2035 | ){ |
| 2036 | int iStart, iEnd; /* Start and end of region to highlight */ |
| 2037 | int n = 0; /* Current line number */ |
| 2038 | int i = 0; /* Loop index */ |
| 2039 | int iTop = 0; /* Scroll so that this line is on top of screen. */ |
| 2040 | int nLine = 0; /* content line count */ |
| 2041 | int nSpans = 0; /* number of distinct zLn spans */ |
| 2042 | const char *zExt = file_extension(zName); |
| 2043 | Stmt q; |
| 2044 | |
| 2045 | iStart = iEnd = atoi(zLn); |
| 2046 | db_multi_exec( |
| 2047 | "CREATE TEMP TABLE lnos(iStart INTEGER PRIMARY KEY, iEnd INTEGER)"); |
| @@ -2047,56 +2057,101 @@ | |
| 2057 | while( fossil_isdigit(zLn[i]) ) i++; |
| 2058 | if( iEnd<iStart ) iEnd = iStart; |
| 2059 | db_multi_exec( |
| 2060 | "INSERT OR REPLACE INTO lnos VALUES(%d,%d)", iStart, iEnd |
| 2061 | ); |
| 2062 | ++nSpans; |
| 2063 | iStart = iEnd = atoi(&zLn[i++]); |
| 2064 | }while( zLn[i] && iStart && iEnd ); |
| 2065 | } |
| 2066 | /*cgi_printf("<!-- ln span count=%d -->", nSpans);*/ |
| 2067 | cgi_append_content("<table class='numbered-lines'><tbody>" |
| 2068 | "<tr><td class='line-numbers'>", -1); |
| 2069 | iStart = iEnd = 0; |
| 2070 | count_lines(z, nZ, &nLine); |
| 2071 | for( n=1 ; n<=nLine; ++n ){ |
| 2072 | const char * zAttr = ""; |
| 2073 | const char * zId = ""; |
| 2074 | if(nSpans>0 && iEnd==0){/*Grab the next range of zLn marking*/ |
| 2075 | db_prepare(&q, "SELECT iStart, iEnd FROM lnos " |
| 2076 | "WHERE iStart >= %d ORDER BY iStart", n); |
| 2077 | if( db_step(&q)==SQLITE_ROW ){ |
| 2078 | iStart = db_column_int(&q, 0); |
| 2079 | iEnd = db_column_int(&q, 1); |
| 2080 | if(!iTop){ |
| 2081 | iTop = iStart - 15 + (iEnd-iStart)/4; |
| 2082 | if( iTop>iStart - 2 ) iTop = iStart-2; |
| 2083 | } |
| 2084 | }else{ |
| 2085 | /* Note that overlapping multi-spans, e.g. 10-15+12-20, |
| 2086 | can cause us to miss a row. */ |
| 2087 | iStart = iEnd = 0; |
| 2088 | } |
| 2089 | db_finalize(&q); |
| 2090 | --nSpans; |
| 2091 | /*cgi_printf("<!-- iStart=%d, iEnd=%d -->", iStart, iEnd);*/ |
| 2092 | } |
| 2093 | if(n==iTop) { |
| 2094 | zId = " id='scrollToMe'"; |
| 2095 | } |
| 2096 | if(n==iStart){/*Figure out which CSS class(es) this line needs...*/ |
| 2097 | if(n==iEnd){ |
| 2098 | zAttr = " class='selected-line start end'"; |
| 2099 | iEnd = 0; |
| 2100 | }else{ |
| 2101 | zAttr = " class='selected-line start'"; |
| 2102 | } |
| 2103 | iStart = 0; |
| 2104 | }else if(n==iEnd){ |
| 2105 | zAttr = " class='selected-line end'"; |
| 2106 | iEnd = 0; |
| 2107 | }else if( n>iStart && n<iEnd ){ |
| 2108 | zAttr = " class='selected-line'"; |
| 2109 | } |
| 2110 | cgi_printf("<span%s%s>%6d</span>", zId, zAttr, n); |
| 2111 | } |
| 2112 | cgi_append_content("</td><td class='file-content'><pre>",-1); |
| 2113 | if(zExt && *zExt){ |
| 2114 | cgi_printf("<code class='language-%h'>",zExt); |
| 2115 | }else{ |
| 2116 | cgi_append_content("<code>", -1); |
| 2117 | } |
| 2118 | cgi_printf("%z", htmlize(z, nZ)); |
| 2119 | CX("</code></pre></td></tr></tbody></table>\n"); |
| 2120 | if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){ |
| 2121 | builtin_request_js("scroll.js"); |
| 2122 | } |
| 2123 | style_emit_fossil_js_apis(0, "dom", "copybutton", "popupwidget", |
| 2124 | "numbered-lines", 0); |
| 2125 | } |
| 2126 | |
| 2127 | /* |
| 2128 | ** COMMAND: test-line-numbers |
| 2129 | ** |
| 2130 | ** Usage: %fossil test-line-numbers FILE ?LN-SPEC? |
| 2131 | ** |
| 2132 | */ |
| 2133 | void cmd_test_line_numbers(void){ |
| 2134 | Blob content = empty_blob; |
| 2135 | const char * zLn = ""; |
| 2136 | const char * zFilename = 0; |
| 2137 | |
| 2138 | if(g.argc < 3){ |
| 2139 | usage("FILE"); |
| 2140 | }else if(g.argc>3){ |
| 2141 | zLn = g.argv[3]; |
| 2142 | } |
| 2143 | db_find_and_open_repository(0,0); |
| 2144 | zFilename = g.argv[2]; |
| 2145 | fossil_print("%s %s\n", zFilename, zLn); |
| 2146 | |
| 2147 | blob_read_from_file(&content, zFilename, ExtFILE); |
| 2148 | output_text_with_line_numbers(blob_str(&content), blob_size(&content), |
| 2149 | zFilename, zLn); |
| 2150 | blob_reset(&content); |
| 2151 | fossil_print("%b\n", cgi_output_blob()); |
| 2152 | } |
| 2153 | |
| 2154 | /* |
| 2155 | ** WEBPAGE: artifact |
| 2156 | ** WEBPAGE: file |
| 2157 | ** WEBPAGE: whatis |
| @@ -2387,25 +2442,26 @@ | |
| 2442 | if( zLn==0 || atoi(zLn)==0 ){ |
| 2443 | style_submenu_checkbox("ln", "Line Numbers", 0, 0); |
| 2444 | } |
| 2445 | blob_to_utf8_no_bom(&content, 0); |
| 2446 | zMime = mimetype_from_content(&content); |
| 2447 | @ <blockquote class="file-content"> |
| 2448 | if( zMime==0 ){ |
| 2449 | const char *z, *zFileName, *zExt; |
| 2450 | z = blob_str(&content); |
| 2451 | zFileName = db_text(0, |
| 2452 | "SELECT name FROM mlink, filename" |
| 2453 | " WHERE filename.fnid=mlink.fnid" |
| 2454 | " AND mlink.fid=%d", |
| 2455 | rid); |
| 2456 | zExt = file_extension(zFileName); |
| 2457 | if( zLn ){ |
| 2458 | output_text_with_line_numbers(z, blob_size(&content), |
| 2459 | zFileName, zLn); |
| 2460 | }else if( zExt && zExt[1] ){ |
| 2461 | @ <pre> |
| 2462 | @ <code class="language-%s(zExt)">%h(z)</code> |
| 2463 | @ </pre> |
| 2464 | }else{ |
| 2465 | @ <pre> |
| 2466 | @ %h(z) |
| 2467 | @ </pre> |
| 2468 |
+3
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -223,15 +223,18 @@ | ||
| 223 | 223 | $(SRCDIR)/default.css \ |
| 224 | 224 | $(SRCDIR)/diff.tcl \ |
| 225 | 225 | $(SRCDIR)/forum.js \ |
| 226 | 226 | $(SRCDIR)/fossil.bootstrap.js \ |
| 227 | 227 | $(SRCDIR)/fossil.confirmer.js \ |
| 228 | + $(SRCDIR)/fossil.copybutton.js \ | |
| 228 | 229 | $(SRCDIR)/fossil.dom.js \ |
| 229 | 230 | $(SRCDIR)/fossil.fetch.js \ |
| 231 | + $(SRCDIR)/fossil.numbered-lines.js \ | |
| 230 | 232 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 231 | 233 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 232 | 234 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 235 | + $(SRCDIR)/fossil.popupwidget.js \ | |
| 233 | 236 | $(SRCDIR)/fossil.storage.js \ |
| 234 | 237 | $(SRCDIR)/fossil.tabs.js \ |
| 235 | 238 | $(SRCDIR)/graph.js \ |
| 236 | 239 | $(SRCDIR)/href.js \ |
| 237 | 240 | $(SRCDIR)/login.js \ |
| 238 | 241 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -223,15 +223,18 @@ | |
| 223 | $(SRCDIR)/default.css \ |
| 224 | $(SRCDIR)/diff.tcl \ |
| 225 | $(SRCDIR)/forum.js \ |
| 226 | $(SRCDIR)/fossil.bootstrap.js \ |
| 227 | $(SRCDIR)/fossil.confirmer.js \ |
| 228 | $(SRCDIR)/fossil.dom.js \ |
| 229 | $(SRCDIR)/fossil.fetch.js \ |
| 230 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 231 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 232 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 233 | $(SRCDIR)/fossil.storage.js \ |
| 234 | $(SRCDIR)/fossil.tabs.js \ |
| 235 | $(SRCDIR)/graph.js \ |
| 236 | $(SRCDIR)/href.js \ |
| 237 | $(SRCDIR)/login.js \ |
| 238 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -223,15 +223,18 @@ | |
| 223 | $(SRCDIR)/default.css \ |
| 224 | $(SRCDIR)/diff.tcl \ |
| 225 | $(SRCDIR)/forum.js \ |
| 226 | $(SRCDIR)/fossil.bootstrap.js \ |
| 227 | $(SRCDIR)/fossil.confirmer.js \ |
| 228 | $(SRCDIR)/fossil.copybutton.js \ |
| 229 | $(SRCDIR)/fossil.dom.js \ |
| 230 | $(SRCDIR)/fossil.fetch.js \ |
| 231 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 232 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 233 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 234 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 235 | $(SRCDIR)/fossil.popupwidget.js \ |
| 236 | $(SRCDIR)/fossil.storage.js \ |
| 237 | $(SRCDIR)/fossil.tabs.js \ |
| 238 | $(SRCDIR)/graph.js \ |
| 239 | $(SRCDIR)/href.js \ |
| 240 | $(SRCDIR)/login.js \ |
| 241 |
+1
-1
| --- src/scroll.js | ||
| +++ src/scroll.js | ||
| @@ -1,2 +1,2 @@ | ||
| 1 | 1 | /* Cause the page to scroll so that the #scrollToMe is visible */ |
| 2 | -document.getElementById('scrollToMe').scrollIntoView(true); | |
| 2 | +(document.getElementById('scrollToMe')||document.body).scrollIntoView(true); | |
| 3 | 3 |
| --- src/scroll.js | |
| +++ src/scroll.js | |
| @@ -1,2 +1,2 @@ | |
| 1 | /* Cause the page to scroll so that the #scrollToMe is visible */ |
| 2 | document.getElementById('scrollToMe').scrollIntoView(true); |
| 3 |
| --- src/scroll.js | |
| +++ src/scroll.js | |
| @@ -1,2 +1,2 @@ | |
| 1 | /* Cause the page to scroll so that the #scrollToMe is visible */ |
| 2 | (document.getElementById('scrollToMe')||document.body).scrollIntoView(true); |
| 3 |
+3
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -635,15 +635,18 @@ | ||
| 635 | 635 | $(SRCDIR)/default.css \ |
| 636 | 636 | $(SRCDIR)/diff.tcl \ |
| 637 | 637 | $(SRCDIR)/forum.js \ |
| 638 | 638 | $(SRCDIR)/fossil.bootstrap.js \ |
| 639 | 639 | $(SRCDIR)/fossil.confirmer.js \ |
| 640 | + $(SRCDIR)/fossil.copybutton.js \ | |
| 640 | 641 | $(SRCDIR)/fossil.dom.js \ |
| 641 | 642 | $(SRCDIR)/fossil.fetch.js \ |
| 643 | + $(SRCDIR)/fossil.numbered-lines.js \ | |
| 642 | 644 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 643 | 645 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 644 | 646 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 647 | + $(SRCDIR)/fossil.popupwidget.js \ | |
| 645 | 648 | $(SRCDIR)/fossil.storage.js \ |
| 646 | 649 | $(SRCDIR)/fossil.tabs.js \ |
| 647 | 650 | $(SRCDIR)/graph.js \ |
| 648 | 651 | $(SRCDIR)/href.js \ |
| 649 | 652 | $(SRCDIR)/login.js \ |
| 650 | 653 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -635,15 +635,18 @@ | |
| 635 | $(SRCDIR)/default.css \ |
| 636 | $(SRCDIR)/diff.tcl \ |
| 637 | $(SRCDIR)/forum.js \ |
| 638 | $(SRCDIR)/fossil.bootstrap.js \ |
| 639 | $(SRCDIR)/fossil.confirmer.js \ |
| 640 | $(SRCDIR)/fossil.dom.js \ |
| 641 | $(SRCDIR)/fossil.fetch.js \ |
| 642 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 643 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 644 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 645 | $(SRCDIR)/fossil.storage.js \ |
| 646 | $(SRCDIR)/fossil.tabs.js \ |
| 647 | $(SRCDIR)/graph.js \ |
| 648 | $(SRCDIR)/href.js \ |
| 649 | $(SRCDIR)/login.js \ |
| 650 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -635,15 +635,18 @@ | |
| 635 | $(SRCDIR)/default.css \ |
| 636 | $(SRCDIR)/diff.tcl \ |
| 637 | $(SRCDIR)/forum.js \ |
| 638 | $(SRCDIR)/fossil.bootstrap.js \ |
| 639 | $(SRCDIR)/fossil.confirmer.js \ |
| 640 | $(SRCDIR)/fossil.copybutton.js \ |
| 641 | $(SRCDIR)/fossil.dom.js \ |
| 642 | $(SRCDIR)/fossil.fetch.js \ |
| 643 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 644 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 645 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 646 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 647 | $(SRCDIR)/fossil.popupwidget.js \ |
| 648 | $(SRCDIR)/fossil.storage.js \ |
| 649 | $(SRCDIR)/fossil.tabs.js \ |
| 650 | $(SRCDIR)/graph.js \ |
| 651 | $(SRCDIR)/href.js \ |
| 652 | $(SRCDIR)/login.js \ |
| 653 |
+6
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -556,15 +556,18 @@ | ||
| 556 | 556 | "$(SRCDIR)\default.css" \ |
| 557 | 557 | "$(SRCDIR)\diff.tcl" \ |
| 558 | 558 | "$(SRCDIR)\forum.js" \ |
| 559 | 559 | "$(SRCDIR)\fossil.bootstrap.js" \ |
| 560 | 560 | "$(SRCDIR)\fossil.confirmer.js" \ |
| 561 | + "$(SRCDIR)\fossil.copybutton.js" \ | |
| 561 | 562 | "$(SRCDIR)\fossil.dom.js" \ |
| 562 | 563 | "$(SRCDIR)\fossil.fetch.js" \ |
| 564 | + "$(SRCDIR)\fossil.numbered-lines.js" \ | |
| 563 | 565 | "$(SRCDIR)\fossil.page.fileedit.js" \ |
| 564 | 566 | "$(SRCDIR)\fossil.page.forumpost.js" \ |
| 565 | 567 | "$(SRCDIR)\fossil.page.wikiedit.js" \ |
| 568 | + "$(SRCDIR)\fossil.popupwidget.js" \ | |
| 566 | 569 | "$(SRCDIR)\fossil.storage.js" \ |
| 567 | 570 | "$(SRCDIR)\fossil.tabs.js" \ |
| 568 | 571 | "$(SRCDIR)\graph.js" \ |
| 569 | 572 | "$(SRCDIR)\href.js" \ |
| 570 | 573 | "$(SRCDIR)\login.js" \ |
| @@ -1150,15 +1153,18 @@ | ||
| 1150 | 1153 | echo "$(SRCDIR)\default.css" >> $@ |
| 1151 | 1154 | echo "$(SRCDIR)\diff.tcl" >> $@ |
| 1152 | 1155 | echo "$(SRCDIR)\forum.js" >> $@ |
| 1153 | 1156 | echo "$(SRCDIR)\fossil.bootstrap.js" >> $@ |
| 1154 | 1157 | echo "$(SRCDIR)\fossil.confirmer.js" >> $@ |
| 1158 | + echo "$(SRCDIR)\fossil.copybutton.js" >> $@ | |
| 1155 | 1159 | echo "$(SRCDIR)\fossil.dom.js" >> $@ |
| 1156 | 1160 | echo "$(SRCDIR)\fossil.fetch.js" >> $@ |
| 1161 | + echo "$(SRCDIR)\fossil.numbered-lines.js" >> $@ | |
| 1157 | 1162 | echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ |
| 1158 | 1163 | echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ |
| 1159 | 1164 | echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ |
| 1165 | + echo "$(SRCDIR)\fossil.popupwidget.js" >> $@ | |
| 1160 | 1166 | echo "$(SRCDIR)\fossil.storage.js" >> $@ |
| 1161 | 1167 | echo "$(SRCDIR)\fossil.tabs.js" >> $@ |
| 1162 | 1168 | echo "$(SRCDIR)\graph.js" >> $@ |
| 1163 | 1169 | echo "$(SRCDIR)\href.js" >> $@ |
| 1164 | 1170 | echo "$(SRCDIR)\login.js" >> $@ |
| 1165 | 1171 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -556,15 +556,18 @@ | |
| 556 | "$(SRCDIR)\default.css" \ |
| 557 | "$(SRCDIR)\diff.tcl" \ |
| 558 | "$(SRCDIR)\forum.js" \ |
| 559 | "$(SRCDIR)\fossil.bootstrap.js" \ |
| 560 | "$(SRCDIR)\fossil.confirmer.js" \ |
| 561 | "$(SRCDIR)\fossil.dom.js" \ |
| 562 | "$(SRCDIR)\fossil.fetch.js" \ |
| 563 | "$(SRCDIR)\fossil.page.fileedit.js" \ |
| 564 | "$(SRCDIR)\fossil.page.forumpost.js" \ |
| 565 | "$(SRCDIR)\fossil.page.wikiedit.js" \ |
| 566 | "$(SRCDIR)\fossil.storage.js" \ |
| 567 | "$(SRCDIR)\fossil.tabs.js" \ |
| 568 | "$(SRCDIR)\graph.js" \ |
| 569 | "$(SRCDIR)\href.js" \ |
| 570 | "$(SRCDIR)\login.js" \ |
| @@ -1150,15 +1153,18 @@ | |
| 1150 | echo "$(SRCDIR)\default.css" >> $@ |
| 1151 | echo "$(SRCDIR)\diff.tcl" >> $@ |
| 1152 | echo "$(SRCDIR)\forum.js" >> $@ |
| 1153 | echo "$(SRCDIR)\fossil.bootstrap.js" >> $@ |
| 1154 | echo "$(SRCDIR)\fossil.confirmer.js" >> $@ |
| 1155 | echo "$(SRCDIR)\fossil.dom.js" >> $@ |
| 1156 | echo "$(SRCDIR)\fossil.fetch.js" >> $@ |
| 1157 | echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ |
| 1158 | echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ |
| 1159 | echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ |
| 1160 | echo "$(SRCDIR)\fossil.storage.js" >> $@ |
| 1161 | echo "$(SRCDIR)\fossil.tabs.js" >> $@ |
| 1162 | echo "$(SRCDIR)\graph.js" >> $@ |
| 1163 | echo "$(SRCDIR)\href.js" >> $@ |
| 1164 | echo "$(SRCDIR)\login.js" >> $@ |
| 1165 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -556,15 +556,18 @@ | |
| 556 | "$(SRCDIR)\default.css" \ |
| 557 | "$(SRCDIR)\diff.tcl" \ |
| 558 | "$(SRCDIR)\forum.js" \ |
| 559 | "$(SRCDIR)\fossil.bootstrap.js" \ |
| 560 | "$(SRCDIR)\fossil.confirmer.js" \ |
| 561 | "$(SRCDIR)\fossil.copybutton.js" \ |
| 562 | "$(SRCDIR)\fossil.dom.js" \ |
| 563 | "$(SRCDIR)\fossil.fetch.js" \ |
| 564 | "$(SRCDIR)\fossil.numbered-lines.js" \ |
| 565 | "$(SRCDIR)\fossil.page.fileedit.js" \ |
| 566 | "$(SRCDIR)\fossil.page.forumpost.js" \ |
| 567 | "$(SRCDIR)\fossil.page.wikiedit.js" \ |
| 568 | "$(SRCDIR)\fossil.popupwidget.js" \ |
| 569 | "$(SRCDIR)\fossil.storage.js" \ |
| 570 | "$(SRCDIR)\fossil.tabs.js" \ |
| 571 | "$(SRCDIR)\graph.js" \ |
| 572 | "$(SRCDIR)\href.js" \ |
| 573 | "$(SRCDIR)\login.js" \ |
| @@ -1150,15 +1153,18 @@ | |
| 1153 | echo "$(SRCDIR)\default.css" >> $@ |
| 1154 | echo "$(SRCDIR)\diff.tcl" >> $@ |
| 1155 | echo "$(SRCDIR)\forum.js" >> $@ |
| 1156 | echo "$(SRCDIR)\fossil.bootstrap.js" >> $@ |
| 1157 | echo "$(SRCDIR)\fossil.confirmer.js" >> $@ |
| 1158 | echo "$(SRCDIR)\fossil.copybutton.js" >> $@ |
| 1159 | echo "$(SRCDIR)\fossil.dom.js" >> $@ |
| 1160 | echo "$(SRCDIR)\fossil.fetch.js" >> $@ |
| 1161 | echo "$(SRCDIR)\fossil.numbered-lines.js" >> $@ |
| 1162 | echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ |
| 1163 | echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ |
| 1164 | echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ |
| 1165 | echo "$(SRCDIR)\fossil.popupwidget.js" >> $@ |
| 1166 | echo "$(SRCDIR)\fossil.storage.js" >> $@ |
| 1167 | echo "$(SRCDIR)\fossil.tabs.js" >> $@ |
| 1168 | echo "$(SRCDIR)\graph.js" >> $@ |
| 1169 | echo "$(SRCDIR)\href.js" >> $@ |
| 1170 | echo "$(SRCDIR)\login.js" >> $@ |
| 1171 |