Fossil SCM
Merge the CSS and XHTML fixes from the wolfgangFormat2CSS branch into the trunk.
Commit
3243e63bba43c3dd5ca2fde9eaaf7642af389061
Parent
08aa440a3d1400d…
24 files changed
+8
-8
+8
-8
+9
-8
+1
-1
+8
-5
+11
-9
+35
-33
+36
-36
+12
-12
+309
-278
+29
-26
+11
-11
+18
-6
+316
-50
+8
-6
+2
-1
+33
-24
+16
-13
+94
-98
+11
-8
+1
+1
-1
+46
-46
+47
-21
~
src/attach.c
~
src/branch.c
~
src/browse.c
~
src/db.c
~
src/descendants.c
~
src/finfo.c
~
src/info.c
~
src/login.c
~
src/report.c
~
src/setup.c
~
src/shun.c
~
src/skins.c
~
src/stat.c
~
src/style.c
~
src/tag.c
~
src/th_main.c
~
src/timeline.c
~
src/tkt.c
~
src/tktsetup.c
~
src/translate.c
~
src/update.c
~
src/url.c
~
src/wiki.c
~
src/wikiformat.c
+8
-8
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -75,20 +75,20 @@ | ||
| 75 | 75 | zFilename = &zFilename[i+1]; |
| 76 | 76 | i = -1; |
| 77 | 77 | } |
| 78 | 78 | } |
| 79 | 79 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 80 | - zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename); | |
| 80 | + zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename); | |
| 81 | 81 | }else{ |
| 82 | - zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename); | |
| 82 | + zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename); | |
| 83 | 83 | } |
| 84 | 84 | @ |
| 85 | 85 | @ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a> |
| 86 | - @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br> | |
| 86 | + @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br /> | |
| 87 | 87 | if( zComment ) while( isspace(zComment[0]) ) zComment++; |
| 88 | 88 | if( zComment && zComment[0] ){ |
| 89 | - @ %w(zComment)<br> | |
| 89 | + @ %w(zComment)<br /> | |
| 90 | 90 | } |
| 91 | 91 | if( zPage==0 && zTkt==0 ){ |
| 92 | 92 | if( zSrc==0 || zSrc[0]==0 ){ |
| 93 | 93 | zSrc = "Deleted from"; |
| 94 | 94 | }else { |
| @@ -273,13 +273,13 @@ | ||
| 273 | 273 | style_header("Add Attachment"); |
| 274 | 274 | @ <h2>Add Attachment To %s(zTargetType)</h2> |
| 275 | 275 | @ <form action="%s(g.zBaseURL)/attachadd" method="POST" |
| 276 | 276 | @ enctype="multipart/form-data"> |
| 277 | 277 | @ File to Attach: |
| 278 | - @ <input type="file" name="f" size="60"><br> | |
| 279 | - @ Description:<br> | |
| 280 | - @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br> | |
| 278 | + @ <input type="file" name="f" size="60"><br /> | |
| 279 | + @ Description:<br /> | |
| 280 | + @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br /> | |
| 281 | 281 | if( zTkt ){ |
| 282 | 282 | @ <input type="hidden" name="tkt" value="%h(zTkt)"> |
| 283 | 283 | }else{ |
| 284 | 284 | @ <input type="hidden" name="page" value="%h(zPage)"> |
| 285 | 285 | } |
| @@ -351,11 +351,11 @@ | ||
| 351 | 351 | cgi_redirect(zFrom); |
| 352 | 352 | } |
| 353 | 353 | style_header("Delete Attachment"); |
| 354 | 354 | @ <form action="%s(g.zBaseURL)/attachdelete" method="POST"> |
| 355 | 355 | @ <p>Confirm that you want to delete the attachment named |
| 356 | - @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br> | |
| 356 | + @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br /> | |
| 357 | 357 | if( zTkt ){ |
| 358 | 358 | @ <input type="hidden" name="tkt" value="%h(zTkt)"> |
| 359 | 359 | }else{ |
| 360 | 360 | @ <input type="hidden" name="page" value="%h(zPage)"> |
| 361 | 361 | } |
| 362 | 362 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -75,20 +75,20 @@ | |
| 75 | zFilename = &zFilename[i+1]; |
| 76 | i = -1; |
| 77 | } |
| 78 | } |
| 79 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 80 | zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename); |
| 81 | }else{ |
| 82 | zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename); |
| 83 | } |
| 84 | @ |
| 85 | @ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a> |
| 86 | @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br> |
| 87 | if( zComment ) while( isspace(zComment[0]) ) zComment++; |
| 88 | if( zComment && zComment[0] ){ |
| 89 | @ %w(zComment)<br> |
| 90 | } |
| 91 | if( zPage==0 && zTkt==0 ){ |
| 92 | if( zSrc==0 || zSrc[0]==0 ){ |
| 93 | zSrc = "Deleted from"; |
| 94 | }else { |
| @@ -273,13 +273,13 @@ | |
| 273 | style_header("Add Attachment"); |
| 274 | @ <h2>Add Attachment To %s(zTargetType)</h2> |
| 275 | @ <form action="%s(g.zBaseURL)/attachadd" method="POST" |
| 276 | @ enctype="multipart/form-data"> |
| 277 | @ File to Attach: |
| 278 | @ <input type="file" name="f" size="60"><br> |
| 279 | @ Description:<br> |
| 280 | @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br> |
| 281 | if( zTkt ){ |
| 282 | @ <input type="hidden" name="tkt" value="%h(zTkt)"> |
| 283 | }else{ |
| 284 | @ <input type="hidden" name="page" value="%h(zPage)"> |
| 285 | } |
| @@ -351,11 +351,11 @@ | |
| 351 | cgi_redirect(zFrom); |
| 352 | } |
| 353 | style_header("Delete Attachment"); |
| 354 | @ <form action="%s(g.zBaseURL)/attachdelete" method="POST"> |
| 355 | @ <p>Confirm that you want to delete the attachment named |
| 356 | @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br> |
| 357 | if( zTkt ){ |
| 358 | @ <input type="hidden" name="tkt" value="%h(zTkt)"> |
| 359 | }else{ |
| 360 | @ <input type="hidden" name="page" value="%h(zPage)"> |
| 361 | } |
| 362 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -75,20 +75,20 @@ | |
| 75 | zFilename = &zFilename[i+1]; |
| 76 | i = -1; |
| 77 | } |
| 78 | } |
| 79 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 80 | zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename); |
| 81 | }else{ |
| 82 | zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename); |
| 83 | } |
| 84 | @ |
| 85 | @ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a> |
| 86 | @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br /> |
| 87 | if( zComment ) while( isspace(zComment[0]) ) zComment++; |
| 88 | if( zComment && zComment[0] ){ |
| 89 | @ %w(zComment)<br /> |
| 90 | } |
| 91 | if( zPage==0 && zTkt==0 ){ |
| 92 | if( zSrc==0 || zSrc[0]==0 ){ |
| 93 | zSrc = "Deleted from"; |
| 94 | }else { |
| @@ -273,13 +273,13 @@ | |
| 273 | style_header("Add Attachment"); |
| 274 | @ <h2>Add Attachment To %s(zTargetType)</h2> |
| 275 | @ <form action="%s(g.zBaseURL)/attachadd" method="POST" |
| 276 | @ enctype="multipart/form-data"> |
| 277 | @ File to Attach: |
| 278 | @ <input type="file" name="f" size="60"><br /> |
| 279 | @ Description:<br /> |
| 280 | @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br /> |
| 281 | if( zTkt ){ |
| 282 | @ <input type="hidden" name="tkt" value="%h(zTkt)"> |
| 283 | }else{ |
| 284 | @ <input type="hidden" name="page" value="%h(zPage)"> |
| 285 | } |
| @@ -351,11 +351,11 @@ | |
| 351 | cgi_redirect(zFrom); |
| 352 | } |
| 353 | style_header("Delete Attachment"); |
| 354 | @ <form action="%s(g.zBaseURL)/attachdelete" method="POST"> |
| 355 | @ <p>Confirm that you want to delete the attachment named |
| 356 | @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br /> |
| 357 | if( zTkt ){ |
| 358 | @ <input type="hidden" name="tkt" value="%h(zTkt)"> |
| 359 | }else{ |
| 360 | @ <input type="hidden" name="page" value="%h(zPage)"> |
| 361 | } |
| 362 |
+8
-8
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -231,16 +231,19 @@ | ||
| 231 | 231 | } |
| 232 | 232 | login_anonymous_available(); |
| 233 | 233 | compute_leaves(0, 1); |
| 234 | 234 | style_sidebox_begin("Nomenclature:", "33%"); |
| 235 | 235 | @ <ol> |
| 236 | - @ <li> An <a href="brlist">open branch</a> is a branch that has one or | |
| 236 | + @ <li> An <div class="sideboxDescribed"><a href="brlist"> | |
| 237 | + @ open branch</a></div> is a branch that has one or | |
| 237 | 238 | @ more <a href="leaves">open leaves.</a> |
| 238 | 239 | @ The presence of open leaves presumably means |
| 239 | 240 | @ that the branch is still being extended with new check-ins.</li> |
| 240 | - @ <li> A <a href="brlist?closed">closed branch</a> is a branch with only | |
| 241 | - @ <a href="leaves?closed">closed leaves</a>. | |
| 241 | + @ <li> A <div class="sideboxDescribed"><a href="brlist?closed"> | |
| 242 | + @ closed branch</a></div> is a branch with only | |
| 243 | + @ <div class="sideboxDescribed"><a href="leaves?closed"> | |
| 244 | + @ closed leaves</a></div>. | |
| 242 | 245 | @ Closed branches are fixed and do not change (unless they are first |
| 243 | 246 | @ reopened)</li> |
| 244 | 247 | @ </ol> |
| 245 | 248 | style_sidebox_end(); |
| 246 | 249 | |
| @@ -284,13 +287,11 @@ | ||
| 284 | 287 | } |
| 285 | 288 | if( cnt ){ |
| 286 | 289 | @ </ul> |
| 287 | 290 | } |
| 288 | 291 | db_finalize(&q); |
| 289 | - @ </ul> | |
| 290 | - @ <br clear="both"> | |
| 291 | - @ <script> | |
| 292 | + @ <script type="text/JavaScript"> | |
| 292 | 293 | @ function xin(id){ |
| 293 | 294 | @ } |
| 294 | 295 | @ function xout(id){ |
| 295 | 296 | @ } |
| 296 | 297 | @ </script> |
| @@ -341,14 +342,13 @@ | ||
| 341 | 342 | " ORDER BY event.mtime DESC", |
| 342 | 343 | timeline_query_for_www(), TAG_BRANCH |
| 343 | 344 | ); |
| 344 | 345 | www_print_timeline(&q, 0, brtimeline_extra); |
| 345 | 346 | db_finalize(&q); |
| 346 | - @ <br clear="both"> | |
| 347 | - @ <script> | |
| 347 | + @ <script type="text/JavaScript"> | |
| 348 | 348 | @ function xin(id){ |
| 349 | 349 | @ } |
| 350 | 350 | @ function xout(id){ |
| 351 | 351 | @ } |
| 352 | 352 | @ </script> |
| 353 | 353 | style_footer(); |
| 354 | 354 | } |
| 355 | 355 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -231,16 +231,19 @@ | |
| 231 | } |
| 232 | login_anonymous_available(); |
| 233 | compute_leaves(0, 1); |
| 234 | style_sidebox_begin("Nomenclature:", "33%"); |
| 235 | @ <ol> |
| 236 | @ <li> An <a href="brlist">open branch</a> is a branch that has one or |
| 237 | @ more <a href="leaves">open leaves.</a> |
| 238 | @ The presence of open leaves presumably means |
| 239 | @ that the branch is still being extended with new check-ins.</li> |
| 240 | @ <li> A <a href="brlist?closed">closed branch</a> is a branch with only |
| 241 | @ <a href="leaves?closed">closed leaves</a>. |
| 242 | @ Closed branches are fixed and do not change (unless they are first |
| 243 | @ reopened)</li> |
| 244 | @ </ol> |
| 245 | style_sidebox_end(); |
| 246 | |
| @@ -284,13 +287,11 @@ | |
| 284 | } |
| 285 | if( cnt ){ |
| 286 | @ </ul> |
| 287 | } |
| 288 | db_finalize(&q); |
| 289 | @ </ul> |
| 290 | @ <br clear="both"> |
| 291 | @ <script> |
| 292 | @ function xin(id){ |
| 293 | @ } |
| 294 | @ function xout(id){ |
| 295 | @ } |
| 296 | @ </script> |
| @@ -341,14 +342,13 @@ | |
| 341 | " ORDER BY event.mtime DESC", |
| 342 | timeline_query_for_www(), TAG_BRANCH |
| 343 | ); |
| 344 | www_print_timeline(&q, 0, brtimeline_extra); |
| 345 | db_finalize(&q); |
| 346 | @ <br clear="both"> |
| 347 | @ <script> |
| 348 | @ function xin(id){ |
| 349 | @ } |
| 350 | @ function xout(id){ |
| 351 | @ } |
| 352 | @ </script> |
| 353 | style_footer(); |
| 354 | } |
| 355 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -231,16 +231,19 @@ | |
| 231 | } |
| 232 | login_anonymous_available(); |
| 233 | compute_leaves(0, 1); |
| 234 | style_sidebox_begin("Nomenclature:", "33%"); |
| 235 | @ <ol> |
| 236 | @ <li> An <div class="sideboxDescribed"><a href="brlist"> |
| 237 | @ open branch</a></div> is a branch that has one or |
| 238 | @ more <a href="leaves">open leaves.</a> |
| 239 | @ The presence of open leaves presumably means |
| 240 | @ that the branch is still being extended with new check-ins.</li> |
| 241 | @ <li> A <div class="sideboxDescribed"><a href="brlist?closed"> |
| 242 | @ closed branch</a></div> is a branch with only |
| 243 | @ <div class="sideboxDescribed"><a href="leaves?closed"> |
| 244 | @ closed leaves</a></div>. |
| 245 | @ Closed branches are fixed and do not change (unless they are first |
| 246 | @ reopened)</li> |
| 247 | @ </ol> |
| 248 | style_sidebox_end(); |
| 249 | |
| @@ -284,13 +287,11 @@ | |
| 287 | } |
| 288 | if( cnt ){ |
| 289 | @ </ul> |
| 290 | } |
| 291 | db_finalize(&q); |
| 292 | @ <script type="text/JavaScript"> |
| 293 | @ function xin(id){ |
| 294 | @ } |
| 295 | @ function xout(id){ |
| 296 | @ } |
| 297 | @ </script> |
| @@ -341,14 +342,13 @@ | |
| 342 | " ORDER BY event.mtime DESC", |
| 343 | timeline_query_for_www(), TAG_BRANCH |
| 344 | ); |
| 345 | www_print_timeline(&q, 0, brtimeline_extra); |
| 346 | db_finalize(&q); |
| 347 | @ <script type="text/JavaScript"> |
| 348 | @ function xin(id){ |
| 349 | @ } |
| 350 | @ function xout(id){ |
| 351 | @ } |
| 352 | @ </script> |
| 353 | style_footer(); |
| 354 | } |
| 355 |
+9
-8
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -144,11 +144,11 @@ | ||
| 144 | 144 | char zShort[20]; |
| 145 | 145 | memcpy(zShort, zUuid, 10); |
| 146 | 146 | zShort[10] = 0; |
| 147 | 147 | @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>] |
| 148 | 148 | @ %s(blob_str(&dirname))</h2> |
| 149 | - zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix); | |
| 149 | + zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix); | |
| 150 | 150 | if( zD ){ |
| 151 | 151 | style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid); |
| 152 | 152 | style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD); |
| 153 | 153 | }else{ |
| 154 | 154 | style_submenu_element("All", "All", "%s/dir", g.zBaseURL); |
| @@ -157,13 +157,13 @@ | ||
| 157 | 157 | @ <h2>The union of all files from all check-ins |
| 158 | 158 | @ %s(blob_str(&dirname))</h2> |
| 159 | 159 | zSubdirLink = mprintf("%s/dir?name=%T", g.zBaseURL, zPrefix); |
| 160 | 160 | if( zD ){ |
| 161 | 161 | style_submenu_element("Top", "Top", "%s/dir", g.zBaseURL); |
| 162 | - style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip", | |
| 162 | + style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip", | |
| 163 | 163 | g.zBaseURL, zD); |
| 164 | - style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk", | |
| 164 | + style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk", | |
| 165 | 165 | g.zBaseURL,zD); |
| 166 | 166 | }else{ |
| 167 | 167 | style_submenu_element("Tip", "Tip", "%s/dir?ci=tip", g.zBaseURL); |
| 168 | 168 | style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zBaseURL); |
| 169 | 169 | } |
| @@ -216,29 +216,30 @@ | ||
| 216 | 216 | mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/"); |
| 217 | 217 | cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/"); |
| 218 | 218 | nCol = 4; |
| 219 | 219 | nRow = (cnt+nCol-1)/nCol; |
| 220 | 220 | db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/"); |
| 221 | - @ <table border="0" width="100%%"><tr><td valign="top" width="25%%"> | |
| 221 | + @ <table class="browser"><tr><td class="browser"><ul class="browser"> | |
| 222 | 222 | i = 0; |
| 223 | 223 | while( db_step(&q)==SQLITE_ROW ){ |
| 224 | 224 | const char *zFN; |
| 225 | 225 | if( i==nRow ){ |
| 226 | - @ </td><td valign="top" width="25%%"> | |
| 226 | + @ </ul></td><td class="browser"><ul class="browser"> | |
| 227 | 227 | i = 0; |
| 228 | 228 | } |
| 229 | 229 | i++; |
| 230 | 230 | zFN = db_column_text(&q, 0); |
| 231 | 231 | if( zFN[0]=='/' ){ |
| 232 | 232 | zFN++; |
| 233 | 233 | @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> |
| 234 | 234 | }else if( zCI ){ |
| 235 | 235 | const char *zUuid = db_column_text(&q, 1); |
| 236 | - @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a> | |
| 236 | + @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a></li> | |
| 237 | 237 | }else{ |
| 238 | - @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)</a> | |
| 238 | + @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN) | |
| 239 | + @ </a></li> | |
| 239 | 240 | } |
| 240 | 241 | } |
| 241 | 242 | db_finalize(&q); |
| 242 | - @ </td></tr></table> | |
| 243 | + @ </ul></td></tr></table> | |
| 243 | 244 | style_footer(); |
| 244 | 245 | } |
| 245 | 246 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -144,11 +144,11 @@ | |
| 144 | char zShort[20]; |
| 145 | memcpy(zShort, zUuid, 10); |
| 146 | zShort[10] = 0; |
| 147 | @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>] |
| 148 | @ %s(blob_str(&dirname))</h2> |
| 149 | zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix); |
| 150 | if( zD ){ |
| 151 | style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid); |
| 152 | style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD); |
| 153 | }else{ |
| 154 | style_submenu_element("All", "All", "%s/dir", g.zBaseURL); |
| @@ -157,13 +157,13 @@ | |
| 157 | @ <h2>The union of all files from all check-ins |
| 158 | @ %s(blob_str(&dirname))</h2> |
| 159 | zSubdirLink = mprintf("%s/dir?name=%T", g.zBaseURL, zPrefix); |
| 160 | if( zD ){ |
| 161 | style_submenu_element("Top", "Top", "%s/dir", g.zBaseURL); |
| 162 | style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip", |
| 163 | g.zBaseURL, zD); |
| 164 | style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk", |
| 165 | g.zBaseURL,zD); |
| 166 | }else{ |
| 167 | style_submenu_element("Tip", "Tip", "%s/dir?ci=tip", g.zBaseURL); |
| 168 | style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zBaseURL); |
| 169 | } |
| @@ -216,29 +216,30 @@ | |
| 216 | mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/"); |
| 217 | cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/"); |
| 218 | nCol = 4; |
| 219 | nRow = (cnt+nCol-1)/nCol; |
| 220 | db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/"); |
| 221 | @ <table border="0" width="100%%"><tr><td valign="top" width="25%%"> |
| 222 | i = 0; |
| 223 | while( db_step(&q)==SQLITE_ROW ){ |
| 224 | const char *zFN; |
| 225 | if( i==nRow ){ |
| 226 | @ </td><td valign="top" width="25%%"> |
| 227 | i = 0; |
| 228 | } |
| 229 | i++; |
| 230 | zFN = db_column_text(&q, 0); |
| 231 | if( zFN[0]=='/' ){ |
| 232 | zFN++; |
| 233 | @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> |
| 234 | }else if( zCI ){ |
| 235 | const char *zUuid = db_column_text(&q, 1); |
| 236 | @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a> |
| 237 | }else{ |
| 238 | @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)</a> |
| 239 | } |
| 240 | } |
| 241 | db_finalize(&q); |
| 242 | @ </td></tr></table> |
| 243 | style_footer(); |
| 244 | } |
| 245 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -144,11 +144,11 @@ | |
| 144 | char zShort[20]; |
| 145 | memcpy(zShort, zUuid, 10); |
| 146 | zShort[10] = 0; |
| 147 | @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>] |
| 148 | @ %s(blob_str(&dirname))</h2> |
| 149 | zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix); |
| 150 | if( zD ){ |
| 151 | style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid); |
| 152 | style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD); |
| 153 | }else{ |
| 154 | style_submenu_element("All", "All", "%s/dir", g.zBaseURL); |
| @@ -157,13 +157,13 @@ | |
| 157 | @ <h2>The union of all files from all check-ins |
| 158 | @ %s(blob_str(&dirname))</h2> |
| 159 | zSubdirLink = mprintf("%s/dir?name=%T", g.zBaseURL, zPrefix); |
| 160 | if( zD ){ |
| 161 | style_submenu_element("Top", "Top", "%s/dir", g.zBaseURL); |
| 162 | style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip", |
| 163 | g.zBaseURL, zD); |
| 164 | style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk", |
| 165 | g.zBaseURL,zD); |
| 166 | }else{ |
| 167 | style_submenu_element("Tip", "Tip", "%s/dir?ci=tip", g.zBaseURL); |
| 168 | style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zBaseURL); |
| 169 | } |
| @@ -216,29 +216,30 @@ | |
| 216 | mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/"); |
| 217 | cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/"); |
| 218 | nCol = 4; |
| 219 | nRow = (cnt+nCol-1)/nCol; |
| 220 | db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/"); |
| 221 | @ <table class="browser"><tr><td class="browser"><ul class="browser"> |
| 222 | i = 0; |
| 223 | while( db_step(&q)==SQLITE_ROW ){ |
| 224 | const char *zFN; |
| 225 | if( i==nRow ){ |
| 226 | @ </ul></td><td class="browser"><ul class="browser"> |
| 227 | i = 0; |
| 228 | } |
| 229 | i++; |
| 230 | zFN = db_column_text(&q, 0); |
| 231 | if( zFN[0]=='/' ){ |
| 232 | zFN++; |
| 233 | @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> |
| 234 | }else if( zCI ){ |
| 235 | const char *zUuid = db_column_text(&q, 1); |
| 236 | @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a></li> |
| 237 | }else{ |
| 238 | @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN) |
| 239 | @ </a></li> |
| 240 | } |
| 241 | } |
| 242 | db_finalize(&q); |
| 243 | @ </ul></td></tr></table> |
| 244 | style_footer(); |
| 245 | } |
| 246 |
M
src/db.c
+1
-1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -664,11 +664,11 @@ | ||
| 664 | 664 | } |
| 665 | 665 | #endif |
| 666 | 666 | if( file_isdir(zHome)!=1 ){ |
| 667 | 667 | fossil_fatal("invalid home directory: %s", zHome); |
| 668 | 668 | } |
| 669 | -#ifndef __MINGW32__ | |
| 669 | +#ifndef _WIN32 | |
| 670 | 670 | if( access(zHome, W_OK) ){ |
| 671 | 671 | fossil_fatal("home directory %s must be writeable", zHome); |
| 672 | 672 | } |
| 673 | 673 | #endif |
| 674 | 674 | g.zHome = mprintf("%/", zHome); |
| 675 | 675 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -664,11 +664,11 @@ | |
| 664 | } |
| 665 | #endif |
| 666 | if( file_isdir(zHome)!=1 ){ |
| 667 | fossil_fatal("invalid home directory: %s", zHome); |
| 668 | } |
| 669 | #ifndef __MINGW32__ |
| 670 | if( access(zHome, W_OK) ){ |
| 671 | fossil_fatal("home directory %s must be writeable", zHome); |
| 672 | } |
| 673 | #endif |
| 674 | g.zHome = mprintf("%/", zHome); |
| 675 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -664,11 +664,11 @@ | |
| 664 | } |
| 665 | #endif |
| 666 | if( file_isdir(zHome)!=1 ){ |
| 667 | fossil_fatal("invalid home directory: %s", zHome); |
| 668 | } |
| 669 | #ifndef _WIN32 |
| 670 | if( access(zHome, W_OK) ){ |
| 671 | fossil_fatal("home directory %s must be writeable", zHome); |
| 672 | } |
| 673 | #endif |
| 674 | g.zHome = mprintf("%/", zHome); |
| 675 |
+8
-5
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -318,14 +318,17 @@ | ||
| 318 | 318 | style_header("Leaves"); |
| 319 | 319 | login_anonymous_available(); |
| 320 | 320 | compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1); |
| 321 | 321 | style_sidebox_begin("Nomenclature:", "33%"); |
| 322 | 322 | @ <ol> |
| 323 | - @ <li> A <b>leaf</b> is a check-in with no descendants.</li> | |
| 324 | - @ <li> An <b>open leaf</b> is a leaf that does not have a "closed" tag | |
| 323 | + @ <li> A <div class="sideboxDescribed">leaf</div> | |
| 324 | + @ is a check-in with no descendants.</li> | |
| 325 | + @ <li> An <div class="sideboxDescribed">open leaf</div> | |
| 326 | + @ is a leaf that does not have a "closed" tag | |
| 325 | 327 | @ and is thus assumed to still be in use.</li> |
| 326 | - @ <li> A <b>closed leaf</b> has a "closed" tag and is thus assumed to | |
| 328 | + @ <li> A <div class="sideboxDescribed">closed leaf</div> | |
| 329 | + @ has a "closed" tag and is thus assumed to | |
| 327 | 330 | @ be historical and no longer in active use.</li> |
| 328 | 331 | @ </ol> |
| 329 | 332 | style_sidebox_end(); |
| 330 | 333 | |
| 331 | 334 | if( showAll ){ |
| @@ -341,14 +344,14 @@ | ||
| 341 | 344 | " ORDER BY event.mtime DESC", |
| 342 | 345 | timeline_query_for_www() |
| 343 | 346 | ); |
| 344 | 347 | www_print_timeline(&q, TIMELINE_LEAFONLY, leaves_extra); |
| 345 | 348 | db_finalize(&q); |
| 346 | - @ <br clear="both"> | |
| 347 | - @ <script> | |
| 349 | + @ <br /> | |
| 350 | + @ <script type="text/JavaScript"> | |
| 348 | 351 | @ function xin(id){ |
| 349 | 352 | @ } |
| 350 | 353 | @ function xout(id){ |
| 351 | 354 | @ } |
| 352 | 355 | @ </script> |
| 353 | 356 | style_footer(); |
| 354 | 357 | } |
| 355 | 358 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -318,14 +318,17 @@ | |
| 318 | style_header("Leaves"); |
| 319 | login_anonymous_available(); |
| 320 | compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1); |
| 321 | style_sidebox_begin("Nomenclature:", "33%"); |
| 322 | @ <ol> |
| 323 | @ <li> A <b>leaf</b> is a check-in with no descendants.</li> |
| 324 | @ <li> An <b>open leaf</b> is a leaf that does not have a "closed" tag |
| 325 | @ and is thus assumed to still be in use.</li> |
| 326 | @ <li> A <b>closed leaf</b> has a "closed" tag and is thus assumed to |
| 327 | @ be historical and no longer in active use.</li> |
| 328 | @ </ol> |
| 329 | style_sidebox_end(); |
| 330 | |
| 331 | if( showAll ){ |
| @@ -341,14 +344,14 @@ | |
| 341 | " ORDER BY event.mtime DESC", |
| 342 | timeline_query_for_www() |
| 343 | ); |
| 344 | www_print_timeline(&q, TIMELINE_LEAFONLY, leaves_extra); |
| 345 | db_finalize(&q); |
| 346 | @ <br clear="both"> |
| 347 | @ <script> |
| 348 | @ function xin(id){ |
| 349 | @ } |
| 350 | @ function xout(id){ |
| 351 | @ } |
| 352 | @ </script> |
| 353 | style_footer(); |
| 354 | } |
| 355 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -318,14 +318,17 @@ | |
| 318 | style_header("Leaves"); |
| 319 | login_anonymous_available(); |
| 320 | compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1); |
| 321 | style_sidebox_begin("Nomenclature:", "33%"); |
| 322 | @ <ol> |
| 323 | @ <li> A <div class="sideboxDescribed">leaf</div> |
| 324 | @ is a check-in with no descendants.</li> |
| 325 | @ <li> An <div class="sideboxDescribed">open leaf</div> |
| 326 | @ is a leaf that does not have a "closed" tag |
| 327 | @ and is thus assumed to still be in use.</li> |
| 328 | @ <li> A <div class="sideboxDescribed">closed leaf</div> |
| 329 | @ has a "closed" tag and is thus assumed to |
| 330 | @ be historical and no longer in active use.</li> |
| 331 | @ </ol> |
| 332 | style_sidebox_end(); |
| 333 | |
| 334 | if( showAll ){ |
| @@ -341,14 +344,14 @@ | |
| 344 | " ORDER BY event.mtime DESC", |
| 345 | timeline_query_for_www() |
| 346 | ); |
| 347 | www_print_timeline(&q, TIMELINE_LEAFONLY, leaves_extra); |
| 348 | db_finalize(&q); |
| 349 | @ <br /> |
| 350 | @ <script type="text/JavaScript"> |
| 351 | @ function xin(id){ |
| 352 | @ } |
| 353 | @ function xout(id){ |
| 354 | @ } |
| 355 | @ </script> |
| 356 | style_footer(); |
| 357 | } |
| 358 |
+11
-9
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -136,11 +136,11 @@ | ||
| 136 | 136 | hyperlinked_path(zFilename, &title); |
| 137 | 137 | @ <h2>%b(&title)</h2> |
| 138 | 138 | blob_reset(&title); |
| 139 | 139 | pGraph = graph_init(); |
| 140 | 140 | @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div> |
| 141 | - @ <table cellspacing=0 border=0 cellpadding=0> | |
| 141 | + @ <table class="timelineTable"> | |
| 142 | 142 | while( db_step(&q)==SQLITE_ROW ){ |
| 143 | 143 | const char *zDate = db_column_text(&q, 0); |
| 144 | 144 | const char *zCom = db_column_text(&q, 1); |
| 145 | 145 | const char *zUser = db_column_text(&q, 2); |
| 146 | 146 | int fpid = db_column_int(&q, 3); |
| @@ -157,22 +157,22 @@ | ||
| 157 | 157 | if( zBr==0 ) zBr = "trunk"; |
| 158 | 158 | gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr); |
| 159 | 159 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 160 | 160 | sprintf(zPrevDate, "%.10s", zDate); |
| 161 | 161 | @ <tr><td> |
| 162 | - @ <div class="divider"><nobr>%s(zPrevDate)</nobr></div> | |
| 162 | + @ <div class="divider">%s(zPrevDate)</div> | |
| 163 | 163 | @ </td></tr> |
| 164 | 164 | } |
| 165 | 165 | memcpy(zTime, &zDate[11], 5); |
| 166 | 166 | zTime[5] = 0; |
| 167 | - @ <tr><td valign="top" align="right"> | |
| 167 | + @ <tr><td class="timelineTime"> | |
| 168 | 168 | @ <a href="%s(g.zTop)/timeline?c=%t(zDate)">%s(zTime)</a></td> |
| 169 | - @ <td width="20" align="left" valign="top"><div id="m%d(gidx)"></div></td> | |
| 169 | + @ <td class="timelineGraph"><div id="m%d(gidx)"></div></td> | |
| 170 | 170 | if( zBgClr && zBgClr[0] ){ |
| 171 | - @ <td valign="top" align="left" bgcolor="%h(zBgClr)"> | |
| 171 | + @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> | |
| 172 | 172 | }else{ |
| 173 | - @ <td valign="top" align="left"> | |
| 173 | + @ <td class="timelineTableCell"> | |
| 174 | 174 | } |
| 175 | 175 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); |
| 176 | 176 | sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); |
| 177 | 177 | if( zUuid ){ |
| 178 | 178 | if( g.okHistory ){ |
| @@ -187,27 +187,29 @@ | ||
| 187 | 187 | hyperlink_to_uuid(zShortCkin); |
| 188 | 188 | @ %h(zCom) (user: |
| 189 | 189 | hyperlink_to_user(zUser, zDate, ""); |
| 190 | 190 | @ branch: %h(zBr)) |
| 191 | 191 | if( g.okHistory && zUuid ){ |
| 192 | + const char *z = zFilename; | |
| 192 | 193 | if( fpid ){ |
| 193 | 194 | @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&v2=%s(zUuid)">[diff]</a> |
| 194 | 195 | } |
| 195 | - @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(zFilename)"> | |
| 196 | + @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(z)"> | |
| 196 | 197 | @ [annotate]</a> |
| 197 | 198 | } |
| 198 | - @ </td> | |
| 199 | + @ </td></tr> | |
| 199 | 200 | } |
| 200 | 201 | db_finalize(&q); |
| 201 | 202 | if( pGraph ){ |
| 202 | 203 | graph_finish(pGraph, 1); |
| 203 | 204 | if( pGraph->nErr ){ |
| 204 | 205 | graph_free(pGraph); |
| 205 | 206 | pGraph = 0; |
| 206 | 207 | }else{ |
| 207 | - @ <tr><td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div> | |
| 208 | + @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div> | |
| 209 | + @ </td></tr> | |
| 208 | 210 | } |
| 209 | 211 | } |
| 210 | 212 | @ </table> |
| 211 | 213 | timeline_output_graph_javascript(pGraph); |
| 212 | 214 | style_footer(); |
| 213 | 215 | } |
| 214 | 216 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -136,11 +136,11 @@ | |
| 136 | hyperlinked_path(zFilename, &title); |
| 137 | @ <h2>%b(&title)</h2> |
| 138 | blob_reset(&title); |
| 139 | pGraph = graph_init(); |
| 140 | @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div> |
| 141 | @ <table cellspacing=0 border=0 cellpadding=0> |
| 142 | while( db_step(&q)==SQLITE_ROW ){ |
| 143 | const char *zDate = db_column_text(&q, 0); |
| 144 | const char *zCom = db_column_text(&q, 1); |
| 145 | const char *zUser = db_column_text(&q, 2); |
| 146 | int fpid = db_column_int(&q, 3); |
| @@ -157,22 +157,22 @@ | |
| 157 | if( zBr==0 ) zBr = "trunk"; |
| 158 | gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr); |
| 159 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 160 | sprintf(zPrevDate, "%.10s", zDate); |
| 161 | @ <tr><td> |
| 162 | @ <div class="divider"><nobr>%s(zPrevDate)</nobr></div> |
| 163 | @ </td></tr> |
| 164 | } |
| 165 | memcpy(zTime, &zDate[11], 5); |
| 166 | zTime[5] = 0; |
| 167 | @ <tr><td valign="top" align="right"> |
| 168 | @ <a href="%s(g.zTop)/timeline?c=%t(zDate)">%s(zTime)</a></td> |
| 169 | @ <td width="20" align="left" valign="top"><div id="m%d(gidx)"></div></td> |
| 170 | if( zBgClr && zBgClr[0] ){ |
| 171 | @ <td valign="top" align="left" bgcolor="%h(zBgClr)"> |
| 172 | }else{ |
| 173 | @ <td valign="top" align="left"> |
| 174 | } |
| 175 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); |
| 176 | sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); |
| 177 | if( zUuid ){ |
| 178 | if( g.okHistory ){ |
| @@ -187,27 +187,29 @@ | |
| 187 | hyperlink_to_uuid(zShortCkin); |
| 188 | @ %h(zCom) (user: |
| 189 | hyperlink_to_user(zUser, zDate, ""); |
| 190 | @ branch: %h(zBr)) |
| 191 | if( g.okHistory && zUuid ){ |
| 192 | if( fpid ){ |
| 193 | @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&v2=%s(zUuid)">[diff]</a> |
| 194 | } |
| 195 | @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(zFilename)"> |
| 196 | @ [annotate]</a> |
| 197 | } |
| 198 | @ </td> |
| 199 | } |
| 200 | db_finalize(&q); |
| 201 | if( pGraph ){ |
| 202 | graph_finish(pGraph, 1); |
| 203 | if( pGraph->nErr ){ |
| 204 | graph_free(pGraph); |
| 205 | pGraph = 0; |
| 206 | }else{ |
| 207 | @ <tr><td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 208 | } |
| 209 | } |
| 210 | @ </table> |
| 211 | timeline_output_graph_javascript(pGraph); |
| 212 | style_footer(); |
| 213 | } |
| 214 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -136,11 +136,11 @@ | |
| 136 | hyperlinked_path(zFilename, &title); |
| 137 | @ <h2>%b(&title)</h2> |
| 138 | blob_reset(&title); |
| 139 | pGraph = graph_init(); |
| 140 | @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div> |
| 141 | @ <table class="timelineTable"> |
| 142 | while( db_step(&q)==SQLITE_ROW ){ |
| 143 | const char *zDate = db_column_text(&q, 0); |
| 144 | const char *zCom = db_column_text(&q, 1); |
| 145 | const char *zUser = db_column_text(&q, 2); |
| 146 | int fpid = db_column_int(&q, 3); |
| @@ -157,22 +157,22 @@ | |
| 157 | if( zBr==0 ) zBr = "trunk"; |
| 158 | gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr); |
| 159 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 160 | sprintf(zPrevDate, "%.10s", zDate); |
| 161 | @ <tr><td> |
| 162 | @ <div class="divider">%s(zPrevDate)</div> |
| 163 | @ </td></tr> |
| 164 | } |
| 165 | memcpy(zTime, &zDate[11], 5); |
| 166 | zTime[5] = 0; |
| 167 | @ <tr><td class="timelineTime"> |
| 168 | @ <a href="%s(g.zTop)/timeline?c=%t(zDate)">%s(zTime)</a></td> |
| 169 | @ <td class="timelineGraph"><div id="m%d(gidx)"></div></td> |
| 170 | if( zBgClr && zBgClr[0] ){ |
| 171 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 172 | }else{ |
| 173 | @ <td class="timelineTableCell"> |
| 174 | } |
| 175 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); |
| 176 | sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); |
| 177 | if( zUuid ){ |
| 178 | if( g.okHistory ){ |
| @@ -187,27 +187,29 @@ | |
| 187 | hyperlink_to_uuid(zShortCkin); |
| 188 | @ %h(zCom) (user: |
| 189 | hyperlink_to_user(zUser, zDate, ""); |
| 190 | @ branch: %h(zBr)) |
| 191 | if( g.okHistory && zUuid ){ |
| 192 | const char *z = zFilename; |
| 193 | if( fpid ){ |
| 194 | @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&v2=%s(zUuid)">[diff]</a> |
| 195 | } |
| 196 | @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(z)"> |
| 197 | @ [annotate]</a> |
| 198 | } |
| 199 | @ </td></tr> |
| 200 | } |
| 201 | db_finalize(&q); |
| 202 | if( pGraph ){ |
| 203 | graph_finish(pGraph, 1); |
| 204 | if( pGraph->nErr ){ |
| 205 | graph_free(pGraph); |
| 206 | pGraph = 0; |
| 207 | }else{ |
| 208 | @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 209 | @ </td></tr> |
| 210 | } |
| 211 | } |
| 212 | @ </table> |
| 213 | timeline_output_graph_javascript(pGraph); |
| 214 | style_footer(); |
| 215 | } |
| 216 |
+35
-33
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -194,15 +194,15 @@ | ||
| 194 | 194 | @ <div class="section">Tags And Properties</div> |
| 195 | 195 | @ <ul> |
| 196 | 196 | } |
| 197 | 197 | @ <li> |
| 198 | 198 | if( tagtype==0 ){ |
| 199 | - @ <b><s>%h(zTagname)</s></b> cancelled | |
| 199 | + @ <span class="infoTagCancelled">%h(zTagname)</span> cancelled | |
| 200 | 200 | }else if( zValue ){ |
| 201 | - @ <b>%h(zTagname)=%h(zValue)</b> | |
| 201 | + @ <span class="infoTag">%h(zTagname)=%h(zValue)</span> | |
| 202 | 202 | }else { |
| 203 | - @ <b>%h(zTagname)</b> | |
| 203 | + @ <span class="infoTag">%h(zTagname)</span> | |
| 204 | 204 | } |
| 205 | 205 | if( tagtype==2 ){ |
| 206 | 206 | if( zOrigUuid && zOrigUuid[0] ){ |
| 207 | 207 | @ inherited from |
| 208 | 208 | hyperlink_to_uuid(zOrigUuid); |
| @@ -222,10 +222,11 @@ | ||
| 222 | 222 | } |
| 223 | 223 | hyperlink_to_uuid(zSrcUuid); |
| 224 | 224 | @ on |
| 225 | 225 | hyperlink_to_date(zDate,0); |
| 226 | 226 | } |
| 227 | + @ </li> | |
| 227 | 228 | } |
| 228 | 229 | db_finalize(&q); |
| 229 | 230 | if( cnt ){ |
| 230 | 231 | @ </ul> |
| 231 | 232 | } |
| @@ -276,18 +277,19 @@ | ||
| 276 | 277 | @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 277 | 278 | @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 278 | 279 | @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> |
| 279 | 280 | if( !showDiff ){ |
| 280 | 281 | @ |
| 281 | - @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> | |
| 282 | + @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> | |
| 282 | 283 | }else{ |
| 283 | 284 | int rid1 = uuid_to_rid(zOld, 0); |
| 284 | 285 | int rid2 = uuid_to_rid(zNew, 0); |
| 285 | 286 | @ <blockquote><pre> |
| 286 | 287 | append_diff(rid1, rid2); |
| 287 | 288 | @ </pre></blockquote> |
| 288 | 289 | } |
| 290 | + @ </p> | |
| 289 | 291 | }else if( zOld ){ |
| 290 | 292 | @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 291 | 293 | @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a></p> |
| 292 | 294 | }else{ |
| 293 | 295 | @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| @@ -354,11 +356,11 @@ | ||
| 354 | 356 | TAG_COMMENT, rid); |
| 355 | 357 | zUser = db_column_text(&q, 2); |
| 356 | 358 | zComment = db_column_text(&q, 3); |
| 357 | 359 | zDate = db_column_text(&q,1); |
| 358 | 360 | @ <div class="section">Overview</div> |
| 359 | - @ <p><table class="label-value"> | |
| 361 | + @ <table class="label-value"> | |
| 360 | 362 | @ <tr><th>SHA1 Hash:</th><td>%s(zUuid) |
| 361 | 363 | if( g.okSetup ){ |
| 362 | 364 | @ (Record ID: %d(rid)) |
| 363 | 365 | } |
| 364 | 366 | @ </td></tr> |
| @@ -397,13 +399,13 @@ | ||
| 397 | 399 | db_finalize(&q); |
| 398 | 400 | } |
| 399 | 401 | if( g.okHistory ){ |
| 400 | 402 | const char *zProjName = db_get("project-name", "unnamed"); |
| 401 | 403 | @ <tr><th>Timelines:</th><td> |
| 402 | - @ <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a> | |
| 403 | - @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a> | |
| 404 | - @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a> | |
| 404 | + @ <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a> | |
| 405 | + @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a> | |
| 406 | + @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a> | |
| 405 | 407 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 406 | 408 | " WHERE rid=%d AND tagtype>0 " |
| 407 | 409 | " AND tag.tagid=tagxref.tagid " |
| 408 | 410 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| 409 | 411 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -424,11 +426,11 @@ | ||
| 424 | 426 | @ | <a href="%s(g.zTop)/ci_edit?r=%S(zUuid)">edit</a> |
| 425 | 427 | } |
| 426 | 428 | @ </td> |
| 427 | 429 | @ </tr> |
| 428 | 430 | } |
| 429 | - @ </table></p> | |
| 431 | + @ </table> | |
| 430 | 432 | }else{ |
| 431 | 433 | style_header("Check-in Information"); |
| 432 | 434 | login_anonymous_available(); |
| 433 | 435 | } |
| 434 | 436 | db_finalize(&q); |
| @@ -616,11 +618,11 @@ | ||
| 616 | 618 | } |
| 617 | 619 | |
| 618 | 620 | |
| 619 | 621 | /* |
| 620 | 622 | ** WEBPAGE: vdiff |
| 621 | -** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN | |
| 623 | +** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN | |
| 622 | 624 | ** |
| 623 | 625 | ** Show all differences between two checkins. |
| 624 | 626 | */ |
| 625 | 627 | void vdiff_page(void){ |
| 626 | 628 | int ridFrom, ridTo; |
| @@ -638,11 +640,11 @@ | ||
| 638 | 640 | style_header("Check-in Differences"); |
| 639 | 641 | @ <h2>Difference From:</h2><blockquote> |
| 640 | 642 | checkin_description(ridFrom); |
| 641 | 643 | @ </blockquote><h2>To:</h2><blockquote> |
| 642 | 644 | checkin_description(ridTo); |
| 643 | - @ </blockquote><hr><p> | |
| 645 | + @ </blockquote><hr /><p> | |
| 644 | 646 | |
| 645 | 647 | iFrom = iTo = 0; |
| 646 | 648 | while( iFrom<mFrom.nFile && iTo<mTo.nFile ){ |
| 647 | 649 | int cmp; |
| 648 | 650 | if( iFrom>=mFrom.nFile ){ |
| @@ -880,18 +882,18 @@ | ||
| 880 | 882 | v1 = name_to_rid_www("v1"); |
| 881 | 883 | v2 = name_to_rid_www("v2"); |
| 882 | 884 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 883 | 885 | style_header("Diff"); |
| 884 | 886 | @ <h2>Differences From:</h2> |
| 885 | - @ <blockquote> | |
| 887 | + @ <blockquote><p> | |
| 886 | 888 | object_description(v1, 1, 0); |
| 887 | - @ </blockquote> | |
| 889 | + @ </p></blockquote> | |
| 888 | 890 | @ <h2>To:</h2> |
| 889 | - @ <blockquote> | |
| 891 | + @ <blockquote><p> | |
| 890 | 892 | object_description(v2, 1, 0); |
| 891 | - @ </blockquote> | |
| 892 | - @ <hr> | |
| 893 | + @ </p></blockquote> | |
| 894 | + @ <hr /> | |
| 893 | 895 | @ <blockquote><pre> |
| 894 | 896 | content_get(v1, &c1); |
| 895 | 897 | content_get(v2, &c2); |
| 896 | 898 | blob_zero(&diff); |
| 897 | 899 | text_diff(&c1, &c2, &diff, 4, 1); |
| @@ -994,27 +996,27 @@ | ||
| 994 | 996 | if( !g.okRead ){ login_needed(); return; } |
| 995 | 997 | if( rid==0 ) fossil_redirect_home(); |
| 996 | 998 | if( g.okAdmin ){ |
| 997 | 999 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 998 | 1000 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 999 | - style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", | |
| 1001 | + style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", | |
| 1000 | 1002 | g.zTop, zUuid); |
| 1001 | 1003 | }else{ |
| 1002 | 1004 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1003 | 1005 | g.zTop, zUuid); |
| 1004 | 1006 | } |
| 1005 | 1007 | } |
| 1006 | 1008 | style_header("Hex Artifact Content"); |
| 1007 | 1009 | zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1008 | 1010 | @ <h2>Artifact %s(zUuid):</h2> |
| 1009 | - @ <blockquote> | |
| 1011 | + @ <blockquote><p> | |
| 1010 | 1012 | blob_zero(&downloadName); |
| 1011 | 1013 | object_description(rid, 0, &downloadName); |
| 1012 | 1014 | style_submenu_element("Download", "Download", |
| 1013 | 1015 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1014 | - @ </blockquote> | |
| 1015 | - @ <hr> | |
| 1016 | + @ </p></blockquote> | |
| 1017 | + @ <hr /> | |
| 1016 | 1018 | content_get(rid, &content); |
| 1017 | 1019 | @ <blockquote><pre> |
| 1018 | 1020 | hexdump(&content); |
| 1019 | 1021 | @ </pre></blockquote> |
| 1020 | 1022 | style_footer(); |
| @@ -1076,21 +1078,21 @@ | ||
| 1076 | 1078 | if( !g.okRead ){ login_needed(); return; } |
| 1077 | 1079 | if( rid==0 ) fossil_redirect_home(); |
| 1078 | 1080 | if( g.okAdmin ){ |
| 1079 | 1081 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1080 | 1082 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1081 | - style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", | |
| 1083 | + style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", | |
| 1082 | 1084 | g.zTop, zUuid); |
| 1083 | 1085 | }else{ |
| 1084 | 1086 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1085 | 1087 | g.zTop, zUuid); |
| 1086 | 1088 | } |
| 1087 | 1089 | } |
| 1088 | 1090 | style_header("Artifact Content"); |
| 1089 | 1091 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1090 | 1092 | @ <h2>Artifact %s(zUuid)</h2> |
| 1091 | - @ <blockquote> | |
| 1093 | + @ <blockquote><p> | |
| 1092 | 1094 | blob_zero(&downloadName); |
| 1093 | 1095 | object_description(rid, 0, &downloadName); |
| 1094 | 1096 | style_submenu_element("Download", "Download", |
| 1095 | 1097 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1096 | 1098 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| @@ -1100,25 +1102,25 @@ | ||
| 1100 | 1102 | style_submenu_element("Html", "Html", |
| 1101 | 1103 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1102 | 1104 | }else{ |
| 1103 | 1105 | renderAsHtml = 1; |
| 1104 | 1106 | style_submenu_element("Text", "Text", |
| 1105 | - "%s/artifact?name=%s&txt=1", g.zTop, zUuid); | |
| 1107 | + "%s/artifact?name=%s&txt=1", g.zTop, zUuid); | |
| 1106 | 1108 | } |
| 1107 | 1109 | }else if( strcmp(zMime, "application/x-fossil-wiki")==0 ){ |
| 1108 | 1110 | if( P("txt") ){ |
| 1109 | 1111 | style_submenu_element("Wiki", "Wiki", |
| 1110 | 1112 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1111 | 1113 | }else{ |
| 1112 | 1114 | renderAsWiki = 1; |
| 1113 | 1115 | style_submenu_element("Text", "Text", |
| 1114 | - "%s/artifact?name=%s&txt=1", g.zTop, zUuid); | |
| 1116 | + "%s/artifact?name=%s&txt=1", g.zTop, zUuid); | |
| 1115 | 1117 | } |
| 1116 | 1118 | } |
| 1117 | 1119 | } |
| 1118 | - @ </blockquote> | |
| 1119 | - @ <hr> | |
| 1120 | + @ </p></blockquote> | |
| 1121 | + @ <hr /> | |
| 1120 | 1122 | content_get(rid, &content); |
| 1121 | 1123 | if( renderAsWiki ){ |
| 1122 | 1124 | wiki_convert(&content, 0, 0); |
| 1123 | 1125 | }else if( renderAsHtml ){ |
| 1124 | 1126 | @ <div> |
| @@ -1131,11 +1133,11 @@ | ||
| 1131 | 1133 | @ <pre> |
| 1132 | 1134 | @ %h(blob_str(&content)) |
| 1133 | 1135 | @ </pre> |
| 1134 | 1136 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1135 | 1137 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 1136 | - @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&m=%s(zMime)"></img> | |
| 1138 | + @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&m=%s(zMime)"></img> | |
| 1137 | 1139 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1138 | 1140 | }else{ |
| 1139 | 1141 | @ <pre> |
| 1140 | 1142 | hexdump(&content); |
| 1141 | 1143 | @ </pre> |
| @@ -1164,11 +1166,11 @@ | ||
| 1164 | 1166 | rid = name_to_rid_www("name"); |
| 1165 | 1167 | if( rid==0 ){ fossil_redirect_home(); } |
| 1166 | 1168 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1167 | 1169 | if( g.okAdmin ){ |
| 1168 | 1170 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1169 | - style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", | |
| 1171 | + style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", | |
| 1170 | 1172 | g.zTop, zUuid); |
| 1171 | 1173 | }else{ |
| 1172 | 1174 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1173 | 1175 | g.zTop, zUuid); |
| 1174 | 1176 | } |
| @@ -1442,11 +1444,11 @@ | ||
| 1442 | 1444 | int nTag = 0; |
| 1443 | 1445 | @ <b>Preview:</b> |
| 1444 | 1446 | @ <blockquote> |
| 1445 | 1447 | @ <table border=0> |
| 1446 | 1448 | if( zNewColor && zNewColor[0] ){ |
| 1447 | - @ <tr><td bgcolor="%h(zNewColor)"> | |
| 1449 | + @ <tr><td style="background-color: %h(zNewColor);"> | |
| 1448 | 1450 | }else{ |
| 1449 | 1451 | @ <tr><td> |
| 1450 | 1452 | } |
| 1451 | 1453 | wiki_convert(&comment, 0, WIKI_INLINE); |
| 1452 | 1454 | blob_zero(&suffix); |
| @@ -1467,11 +1469,11 @@ | ||
| 1467 | 1469 | db_finalize(&q); |
| 1468 | 1470 | blob_appendf(&suffix, ")"); |
| 1469 | 1471 | @ %s(blob_str(&suffix)) |
| 1470 | 1472 | @ </td></tr></table> |
| 1471 | 1473 | @ </blockquote> |
| 1472 | - @ <hr> | |
| 1474 | + @ <hr /> | |
| 1473 | 1475 | blob_reset(&suffix); |
| 1474 | 1476 | } |
| 1475 | 1477 | @ <p>Make changes to attributes of check-in |
| 1476 | 1478 | @ [<a href="ci?name=%s(zUuid)">%s(zUuid)</a>]:</p> |
| 1477 | 1479 | @ <form action="%s(g.zBaseURL)/ci_edit" method="POST"> |
| @@ -1505,11 +1507,11 @@ | ||
| 1505 | 1507 | } |
| 1506 | 1508 | @ Propagate color to descendants</input></td></tr> |
| 1507 | 1509 | @ <tr> |
| 1508 | 1510 | for(i=0; i<nColor; i++){ |
| 1509 | 1511 | if( aColor[i].zColor[0] ){ |
| 1510 | - @ <td bgcolor="%h(aColor[i].zColor)"> | |
| 1512 | + @ <td style="background-color: %h(aColor[i].zColor);"> | |
| 1511 | 1513 | }else{ |
| 1512 | 1514 | @ <td> |
| 1513 | 1515 | } |
| 1514 | 1516 | if( strcmp(zNewColor, aColor[i].zColor)==0 ){ |
| 1515 | 1517 | @ <input type="radio" name="clr" value="%h(aColor[i].zColor)" checked> |
| @@ -1541,13 +1543,13 @@ | ||
| 1541 | 1543 | int tagid = db_column_int(&q, 0); |
| 1542 | 1544 | const char *zTagName = db_column_text(&q, 1); |
| 1543 | 1545 | char zLabel[30]; |
| 1544 | 1546 | sprintf(zLabel, "c%d", tagid); |
| 1545 | 1547 | if( P(zLabel) ){ |
| 1546 | - @ <br><input type="checkbox" name="c%d(tagid)" checked> | |
| 1548 | + @ <br /><input type="checkbox" name="c%d(tagid)" checked> | |
| 1547 | 1549 | }else{ |
| 1548 | - @ <br><input type="checkbox" name="c%d(tagid)"> | |
| 1550 | + @ <br /><input type="checkbox" name="c%d(tagid)"> | |
| 1549 | 1551 | } |
| 1550 | 1552 | if( strncmp(zTagName, "sym-", 4)==0 ){ |
| 1551 | 1553 | @ Cancel tag <b>%h(&zTagName[4])</b> |
| 1552 | 1554 | }else{ |
| 1553 | 1555 | @ Cancel special tag <b>%h(zTagName)</b> |
| 1554 | 1556 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -194,15 +194,15 @@ | |
| 194 | @ <div class="section">Tags And Properties</div> |
| 195 | @ <ul> |
| 196 | } |
| 197 | @ <li> |
| 198 | if( tagtype==0 ){ |
| 199 | @ <b><s>%h(zTagname)</s></b> cancelled |
| 200 | }else if( zValue ){ |
| 201 | @ <b>%h(zTagname)=%h(zValue)</b> |
| 202 | }else { |
| 203 | @ <b>%h(zTagname)</b> |
| 204 | } |
| 205 | if( tagtype==2 ){ |
| 206 | if( zOrigUuid && zOrigUuid[0] ){ |
| 207 | @ inherited from |
| 208 | hyperlink_to_uuid(zOrigUuid); |
| @@ -222,10 +222,11 @@ | |
| 222 | } |
| 223 | hyperlink_to_uuid(zSrcUuid); |
| 224 | @ on |
| 225 | hyperlink_to_date(zDate,0); |
| 226 | } |
| 227 | } |
| 228 | db_finalize(&q); |
| 229 | if( cnt ){ |
| 230 | @ </ul> |
| 231 | } |
| @@ -276,18 +277,19 @@ | |
| 276 | @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 277 | @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 278 | @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> |
| 279 | if( !showDiff ){ |
| 280 | @ |
| 281 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 282 | }else{ |
| 283 | int rid1 = uuid_to_rid(zOld, 0); |
| 284 | int rid2 = uuid_to_rid(zNew, 0); |
| 285 | @ <blockquote><pre> |
| 286 | append_diff(rid1, rid2); |
| 287 | @ </pre></blockquote> |
| 288 | } |
| 289 | }else if( zOld ){ |
| 290 | @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 291 | @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a></p> |
| 292 | }else{ |
| 293 | @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| @@ -354,11 +356,11 @@ | |
| 354 | TAG_COMMENT, rid); |
| 355 | zUser = db_column_text(&q, 2); |
| 356 | zComment = db_column_text(&q, 3); |
| 357 | zDate = db_column_text(&q,1); |
| 358 | @ <div class="section">Overview</div> |
| 359 | @ <p><table class="label-value"> |
| 360 | @ <tr><th>SHA1 Hash:</th><td>%s(zUuid) |
| 361 | if( g.okSetup ){ |
| 362 | @ (Record ID: %d(rid)) |
| 363 | } |
| 364 | @ </td></tr> |
| @@ -397,13 +399,13 @@ | |
| 397 | db_finalize(&q); |
| 398 | } |
| 399 | if( g.okHistory ){ |
| 400 | const char *zProjName = db_get("project-name", "unnamed"); |
| 401 | @ <tr><th>Timelines:</th><td> |
| 402 | @ <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a> |
| 403 | @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a> |
| 404 | @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a> |
| 405 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 406 | " WHERE rid=%d AND tagtype>0 " |
| 407 | " AND tag.tagid=tagxref.tagid " |
| 408 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| 409 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -424,11 +426,11 @@ | |
| 424 | @ | <a href="%s(g.zTop)/ci_edit?r=%S(zUuid)">edit</a> |
| 425 | } |
| 426 | @ </td> |
| 427 | @ </tr> |
| 428 | } |
| 429 | @ </table></p> |
| 430 | }else{ |
| 431 | style_header("Check-in Information"); |
| 432 | login_anonymous_available(); |
| 433 | } |
| 434 | db_finalize(&q); |
| @@ -616,11 +618,11 @@ | |
| 616 | } |
| 617 | |
| 618 | |
| 619 | /* |
| 620 | ** WEBPAGE: vdiff |
| 621 | ** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN |
| 622 | ** |
| 623 | ** Show all differences between two checkins. |
| 624 | */ |
| 625 | void vdiff_page(void){ |
| 626 | int ridFrom, ridTo; |
| @@ -638,11 +640,11 @@ | |
| 638 | style_header("Check-in Differences"); |
| 639 | @ <h2>Difference From:</h2><blockquote> |
| 640 | checkin_description(ridFrom); |
| 641 | @ </blockquote><h2>To:</h2><blockquote> |
| 642 | checkin_description(ridTo); |
| 643 | @ </blockquote><hr><p> |
| 644 | |
| 645 | iFrom = iTo = 0; |
| 646 | while( iFrom<mFrom.nFile && iTo<mTo.nFile ){ |
| 647 | int cmp; |
| 648 | if( iFrom>=mFrom.nFile ){ |
| @@ -880,18 +882,18 @@ | |
| 880 | v1 = name_to_rid_www("v1"); |
| 881 | v2 = name_to_rid_www("v2"); |
| 882 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 883 | style_header("Diff"); |
| 884 | @ <h2>Differences From:</h2> |
| 885 | @ <blockquote> |
| 886 | object_description(v1, 1, 0); |
| 887 | @ </blockquote> |
| 888 | @ <h2>To:</h2> |
| 889 | @ <blockquote> |
| 890 | object_description(v2, 1, 0); |
| 891 | @ </blockquote> |
| 892 | @ <hr> |
| 893 | @ <blockquote><pre> |
| 894 | content_get(v1, &c1); |
| 895 | content_get(v2, &c2); |
| 896 | blob_zero(&diff); |
| 897 | text_diff(&c1, &c2, &diff, 4, 1); |
| @@ -994,27 +996,27 @@ | |
| 994 | if( !g.okRead ){ login_needed(); return; } |
| 995 | if( rid==0 ) fossil_redirect_home(); |
| 996 | if( g.okAdmin ){ |
| 997 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 998 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 999 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 1000 | g.zTop, zUuid); |
| 1001 | }else{ |
| 1002 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1003 | g.zTop, zUuid); |
| 1004 | } |
| 1005 | } |
| 1006 | style_header("Hex Artifact Content"); |
| 1007 | zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1008 | @ <h2>Artifact %s(zUuid):</h2> |
| 1009 | @ <blockquote> |
| 1010 | blob_zero(&downloadName); |
| 1011 | object_description(rid, 0, &downloadName); |
| 1012 | style_submenu_element("Download", "Download", |
| 1013 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1014 | @ </blockquote> |
| 1015 | @ <hr> |
| 1016 | content_get(rid, &content); |
| 1017 | @ <blockquote><pre> |
| 1018 | hexdump(&content); |
| 1019 | @ </pre></blockquote> |
| 1020 | style_footer(); |
| @@ -1076,21 +1078,21 @@ | |
| 1076 | if( !g.okRead ){ login_needed(); return; } |
| 1077 | if( rid==0 ) fossil_redirect_home(); |
| 1078 | if( g.okAdmin ){ |
| 1079 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1080 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1081 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 1082 | g.zTop, zUuid); |
| 1083 | }else{ |
| 1084 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1085 | g.zTop, zUuid); |
| 1086 | } |
| 1087 | } |
| 1088 | style_header("Artifact Content"); |
| 1089 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1090 | @ <h2>Artifact %s(zUuid)</h2> |
| 1091 | @ <blockquote> |
| 1092 | blob_zero(&downloadName); |
| 1093 | object_description(rid, 0, &downloadName); |
| 1094 | style_submenu_element("Download", "Download", |
| 1095 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1096 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| @@ -1100,25 +1102,25 @@ | |
| 1100 | style_submenu_element("Html", "Html", |
| 1101 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1102 | }else{ |
| 1103 | renderAsHtml = 1; |
| 1104 | style_submenu_element("Text", "Text", |
| 1105 | "%s/artifact?name=%s&txt=1", g.zTop, zUuid); |
| 1106 | } |
| 1107 | }else if( strcmp(zMime, "application/x-fossil-wiki")==0 ){ |
| 1108 | if( P("txt") ){ |
| 1109 | style_submenu_element("Wiki", "Wiki", |
| 1110 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1111 | }else{ |
| 1112 | renderAsWiki = 1; |
| 1113 | style_submenu_element("Text", "Text", |
| 1114 | "%s/artifact?name=%s&txt=1", g.zTop, zUuid); |
| 1115 | } |
| 1116 | } |
| 1117 | } |
| 1118 | @ </blockquote> |
| 1119 | @ <hr> |
| 1120 | content_get(rid, &content); |
| 1121 | if( renderAsWiki ){ |
| 1122 | wiki_convert(&content, 0, 0); |
| 1123 | }else if( renderAsHtml ){ |
| 1124 | @ <div> |
| @@ -1131,11 +1133,11 @@ | |
| 1131 | @ <pre> |
| 1132 | @ %h(blob_str(&content)) |
| 1133 | @ </pre> |
| 1134 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1135 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 1136 | @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&m=%s(zMime)"></img> |
| 1137 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1138 | }else{ |
| 1139 | @ <pre> |
| 1140 | hexdump(&content); |
| 1141 | @ </pre> |
| @@ -1164,11 +1166,11 @@ | |
| 1164 | rid = name_to_rid_www("name"); |
| 1165 | if( rid==0 ){ fossil_redirect_home(); } |
| 1166 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1167 | if( g.okAdmin ){ |
| 1168 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1169 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 1170 | g.zTop, zUuid); |
| 1171 | }else{ |
| 1172 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1173 | g.zTop, zUuid); |
| 1174 | } |
| @@ -1442,11 +1444,11 @@ | |
| 1442 | int nTag = 0; |
| 1443 | @ <b>Preview:</b> |
| 1444 | @ <blockquote> |
| 1445 | @ <table border=0> |
| 1446 | if( zNewColor && zNewColor[0] ){ |
| 1447 | @ <tr><td bgcolor="%h(zNewColor)"> |
| 1448 | }else{ |
| 1449 | @ <tr><td> |
| 1450 | } |
| 1451 | wiki_convert(&comment, 0, WIKI_INLINE); |
| 1452 | blob_zero(&suffix); |
| @@ -1467,11 +1469,11 @@ | |
| 1467 | db_finalize(&q); |
| 1468 | blob_appendf(&suffix, ")"); |
| 1469 | @ %s(blob_str(&suffix)) |
| 1470 | @ </td></tr></table> |
| 1471 | @ </blockquote> |
| 1472 | @ <hr> |
| 1473 | blob_reset(&suffix); |
| 1474 | } |
| 1475 | @ <p>Make changes to attributes of check-in |
| 1476 | @ [<a href="ci?name=%s(zUuid)">%s(zUuid)</a>]:</p> |
| 1477 | @ <form action="%s(g.zBaseURL)/ci_edit" method="POST"> |
| @@ -1505,11 +1507,11 @@ | |
| 1505 | } |
| 1506 | @ Propagate color to descendants</input></td></tr> |
| 1507 | @ <tr> |
| 1508 | for(i=0; i<nColor; i++){ |
| 1509 | if( aColor[i].zColor[0] ){ |
| 1510 | @ <td bgcolor="%h(aColor[i].zColor)"> |
| 1511 | }else{ |
| 1512 | @ <td> |
| 1513 | } |
| 1514 | if( strcmp(zNewColor, aColor[i].zColor)==0 ){ |
| 1515 | @ <input type="radio" name="clr" value="%h(aColor[i].zColor)" checked> |
| @@ -1541,13 +1543,13 @@ | |
| 1541 | int tagid = db_column_int(&q, 0); |
| 1542 | const char *zTagName = db_column_text(&q, 1); |
| 1543 | char zLabel[30]; |
| 1544 | sprintf(zLabel, "c%d", tagid); |
| 1545 | if( P(zLabel) ){ |
| 1546 | @ <br><input type="checkbox" name="c%d(tagid)" checked> |
| 1547 | }else{ |
| 1548 | @ <br><input type="checkbox" name="c%d(tagid)"> |
| 1549 | } |
| 1550 | if( strncmp(zTagName, "sym-", 4)==0 ){ |
| 1551 | @ Cancel tag <b>%h(&zTagName[4])</b> |
| 1552 | }else{ |
| 1553 | @ Cancel special tag <b>%h(zTagName)</b> |
| 1554 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -194,15 +194,15 @@ | |
| 194 | @ <div class="section">Tags And Properties</div> |
| 195 | @ <ul> |
| 196 | } |
| 197 | @ <li> |
| 198 | if( tagtype==0 ){ |
| 199 | @ <span class="infoTagCancelled">%h(zTagname)</span> cancelled |
| 200 | }else if( zValue ){ |
| 201 | @ <span class="infoTag">%h(zTagname)=%h(zValue)</span> |
| 202 | }else { |
| 203 | @ <span class="infoTag">%h(zTagname)</span> |
| 204 | } |
| 205 | if( tagtype==2 ){ |
| 206 | if( zOrigUuid && zOrigUuid[0] ){ |
| 207 | @ inherited from |
| 208 | hyperlink_to_uuid(zOrigUuid); |
| @@ -222,10 +222,11 @@ | |
| 222 | } |
| 223 | hyperlink_to_uuid(zSrcUuid); |
| 224 | @ on |
| 225 | hyperlink_to_date(zDate,0); |
| 226 | } |
| 227 | @ </li> |
| 228 | } |
| 229 | db_finalize(&q); |
| 230 | if( cnt ){ |
| 231 | @ </ul> |
| 232 | } |
| @@ -276,18 +277,19 @@ | |
| 277 | @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 278 | @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 279 | @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> |
| 280 | if( !showDiff ){ |
| 281 | @ |
| 282 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 283 | }else{ |
| 284 | int rid1 = uuid_to_rid(zOld, 0); |
| 285 | int rid2 = uuid_to_rid(zNew, 0); |
| 286 | @ <blockquote><pre> |
| 287 | append_diff(rid1, rid2); |
| 288 | @ </pre></blockquote> |
| 289 | } |
| 290 | @ </p> |
| 291 | }else if( zOld ){ |
| 292 | @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 293 | @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a></p> |
| 294 | }else{ |
| 295 | @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| @@ -354,11 +356,11 @@ | |
| 356 | TAG_COMMENT, rid); |
| 357 | zUser = db_column_text(&q, 2); |
| 358 | zComment = db_column_text(&q, 3); |
| 359 | zDate = db_column_text(&q,1); |
| 360 | @ <div class="section">Overview</div> |
| 361 | @ <table class="label-value"> |
| 362 | @ <tr><th>SHA1 Hash:</th><td>%s(zUuid) |
| 363 | if( g.okSetup ){ |
| 364 | @ (Record ID: %d(rid)) |
| 365 | } |
| 366 | @ </td></tr> |
| @@ -397,13 +399,13 @@ | |
| 399 | db_finalize(&q); |
| 400 | } |
| 401 | if( g.okHistory ){ |
| 402 | const char *zProjName = db_get("project-name", "unnamed"); |
| 403 | @ <tr><th>Timelines:</th><td> |
| 404 | @ <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a> |
| 405 | @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a> |
| 406 | @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a> |
| 407 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 408 | " WHERE rid=%d AND tagtype>0 " |
| 409 | " AND tag.tagid=tagxref.tagid " |
| 410 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| 411 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -424,11 +426,11 @@ | |
| 426 | @ | <a href="%s(g.zTop)/ci_edit?r=%S(zUuid)">edit</a> |
| 427 | } |
| 428 | @ </td> |
| 429 | @ </tr> |
| 430 | } |
| 431 | @ </table> |
| 432 | }else{ |
| 433 | style_header("Check-in Information"); |
| 434 | login_anonymous_available(); |
| 435 | } |
| 436 | db_finalize(&q); |
| @@ -616,11 +618,11 @@ | |
| 618 | } |
| 619 | |
| 620 | |
| 621 | /* |
| 622 | ** WEBPAGE: vdiff |
| 623 | ** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN |
| 624 | ** |
| 625 | ** Show all differences between two checkins. |
| 626 | */ |
| 627 | void vdiff_page(void){ |
| 628 | int ridFrom, ridTo; |
| @@ -638,11 +640,11 @@ | |
| 640 | style_header("Check-in Differences"); |
| 641 | @ <h2>Difference From:</h2><blockquote> |
| 642 | checkin_description(ridFrom); |
| 643 | @ </blockquote><h2>To:</h2><blockquote> |
| 644 | checkin_description(ridTo); |
| 645 | @ </blockquote><hr /><p> |
| 646 | |
| 647 | iFrom = iTo = 0; |
| 648 | while( iFrom<mFrom.nFile && iTo<mTo.nFile ){ |
| 649 | int cmp; |
| 650 | if( iFrom>=mFrom.nFile ){ |
| @@ -880,18 +882,18 @@ | |
| 882 | v1 = name_to_rid_www("v1"); |
| 883 | v2 = name_to_rid_www("v2"); |
| 884 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 885 | style_header("Diff"); |
| 886 | @ <h2>Differences From:</h2> |
| 887 | @ <blockquote><p> |
| 888 | object_description(v1, 1, 0); |
| 889 | @ </p></blockquote> |
| 890 | @ <h2>To:</h2> |
| 891 | @ <blockquote><p> |
| 892 | object_description(v2, 1, 0); |
| 893 | @ </p></blockquote> |
| 894 | @ <hr /> |
| 895 | @ <blockquote><pre> |
| 896 | content_get(v1, &c1); |
| 897 | content_get(v2, &c2); |
| 898 | blob_zero(&diff); |
| 899 | text_diff(&c1, &c2, &diff, 4, 1); |
| @@ -994,27 +996,27 @@ | |
| 996 | if( !g.okRead ){ login_needed(); return; } |
| 997 | if( rid==0 ) fossil_redirect_home(); |
| 998 | if( g.okAdmin ){ |
| 999 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1000 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1001 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 1002 | g.zTop, zUuid); |
| 1003 | }else{ |
| 1004 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1005 | g.zTop, zUuid); |
| 1006 | } |
| 1007 | } |
| 1008 | style_header("Hex Artifact Content"); |
| 1009 | zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1010 | @ <h2>Artifact %s(zUuid):</h2> |
| 1011 | @ <blockquote><p> |
| 1012 | blob_zero(&downloadName); |
| 1013 | object_description(rid, 0, &downloadName); |
| 1014 | style_submenu_element("Download", "Download", |
| 1015 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1016 | @ </p></blockquote> |
| 1017 | @ <hr /> |
| 1018 | content_get(rid, &content); |
| 1019 | @ <blockquote><pre> |
| 1020 | hexdump(&content); |
| 1021 | @ </pre></blockquote> |
| 1022 | style_footer(); |
| @@ -1076,21 +1078,21 @@ | |
| 1078 | if( !g.okRead ){ login_needed(); return; } |
| 1079 | if( rid==0 ) fossil_redirect_home(); |
| 1080 | if( g.okAdmin ){ |
| 1081 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1082 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1083 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 1084 | g.zTop, zUuid); |
| 1085 | }else{ |
| 1086 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1087 | g.zTop, zUuid); |
| 1088 | } |
| 1089 | } |
| 1090 | style_header("Artifact Content"); |
| 1091 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1092 | @ <h2>Artifact %s(zUuid)</h2> |
| 1093 | @ <blockquote><p> |
| 1094 | blob_zero(&downloadName); |
| 1095 | object_description(rid, 0, &downloadName); |
| 1096 | style_submenu_element("Download", "Download", |
| 1097 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1098 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| @@ -1100,25 +1102,25 @@ | |
| 1102 | style_submenu_element("Html", "Html", |
| 1103 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1104 | }else{ |
| 1105 | renderAsHtml = 1; |
| 1106 | style_submenu_element("Text", "Text", |
| 1107 | "%s/artifact?name=%s&txt=1", g.zTop, zUuid); |
| 1108 | } |
| 1109 | }else if( strcmp(zMime, "application/x-fossil-wiki")==0 ){ |
| 1110 | if( P("txt") ){ |
| 1111 | style_submenu_element("Wiki", "Wiki", |
| 1112 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1113 | }else{ |
| 1114 | renderAsWiki = 1; |
| 1115 | style_submenu_element("Text", "Text", |
| 1116 | "%s/artifact?name=%s&txt=1", g.zTop, zUuid); |
| 1117 | } |
| 1118 | } |
| 1119 | } |
| 1120 | @ </p></blockquote> |
| 1121 | @ <hr /> |
| 1122 | content_get(rid, &content); |
| 1123 | if( renderAsWiki ){ |
| 1124 | wiki_convert(&content, 0, 0); |
| 1125 | }else if( renderAsHtml ){ |
| 1126 | @ <div> |
| @@ -1131,11 +1133,11 @@ | |
| 1133 | @ <pre> |
| 1134 | @ %h(blob_str(&content)) |
| 1135 | @ </pre> |
| 1136 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1137 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 1138 | @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&m=%s(zMime)"></img> |
| 1139 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1140 | }else{ |
| 1141 | @ <pre> |
| 1142 | hexdump(&content); |
| 1143 | @ </pre> |
| @@ -1164,11 +1166,11 @@ | |
| 1166 | rid = name_to_rid_www("name"); |
| 1167 | if( rid==0 ){ fossil_redirect_home(); } |
| 1168 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1169 | if( g.okAdmin ){ |
| 1170 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1171 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 1172 | g.zTop, zUuid); |
| 1173 | }else{ |
| 1174 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1175 | g.zTop, zUuid); |
| 1176 | } |
| @@ -1442,11 +1444,11 @@ | |
| 1444 | int nTag = 0; |
| 1445 | @ <b>Preview:</b> |
| 1446 | @ <blockquote> |
| 1447 | @ <table border=0> |
| 1448 | if( zNewColor && zNewColor[0] ){ |
| 1449 | @ <tr><td style="background-color: %h(zNewColor);"> |
| 1450 | }else{ |
| 1451 | @ <tr><td> |
| 1452 | } |
| 1453 | wiki_convert(&comment, 0, WIKI_INLINE); |
| 1454 | blob_zero(&suffix); |
| @@ -1467,11 +1469,11 @@ | |
| 1469 | db_finalize(&q); |
| 1470 | blob_appendf(&suffix, ")"); |
| 1471 | @ %s(blob_str(&suffix)) |
| 1472 | @ </td></tr></table> |
| 1473 | @ </blockquote> |
| 1474 | @ <hr /> |
| 1475 | blob_reset(&suffix); |
| 1476 | } |
| 1477 | @ <p>Make changes to attributes of check-in |
| 1478 | @ [<a href="ci?name=%s(zUuid)">%s(zUuid)</a>]:</p> |
| 1479 | @ <form action="%s(g.zBaseURL)/ci_edit" method="POST"> |
| @@ -1505,11 +1507,11 @@ | |
| 1507 | } |
| 1508 | @ Propagate color to descendants</input></td></tr> |
| 1509 | @ <tr> |
| 1510 | for(i=0; i<nColor; i++){ |
| 1511 | if( aColor[i].zColor[0] ){ |
| 1512 | @ <td style="background-color: %h(aColor[i].zColor);"> |
| 1513 | }else{ |
| 1514 | @ <td> |
| 1515 | } |
| 1516 | if( strcmp(zNewColor, aColor[i].zColor)==0 ){ |
| 1517 | @ <input type="radio" name="clr" value="%h(aColor[i].zColor)" checked> |
| @@ -1541,13 +1543,13 @@ | |
| 1543 | int tagid = db_column_int(&q, 0); |
| 1544 | const char *zTagName = db_column_text(&q, 1); |
| 1545 | char zLabel[30]; |
| 1546 | sprintf(zLabel, "c%d", tagid); |
| 1547 | if( P(zLabel) ){ |
| 1548 | @ <br /><input type="checkbox" name="c%d(tagid)" checked> |
| 1549 | }else{ |
| 1550 | @ <br /><input type="checkbox" name="c%d(tagid)"> |
| 1551 | } |
| 1552 | if( strncmp(zTagName, "sym-", 4)==0 ){ |
| 1553 | @ Cancel tag <b>%h(&zTagName[4])</b> |
| 1554 | }else{ |
| 1555 | @ Cancel special tag <b>%h(zTagName)</b> |
| 1556 |
+36
-36
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -153,21 +153,21 @@ | ||
| 153 | 153 | if( db_int(1, "SELECT 0 FROM user" |
| 154 | 154 | " WHERE uid=%d AND (pw=%Q OR pw=%Q)", |
| 155 | 155 | g.userUid, zPasswd, zSha1Pw) ){ |
| 156 | 156 | sleep(1); |
| 157 | 157 | zErrMsg = |
| 158 | - @ <p><font color="red"> | |
| 158 | + @ <p><span class="loginError"> | |
| 159 | 159 | @ You entered an incorrect old password while attempting to change |
| 160 | 160 | @ your password. Your password is unchanged. |
| 161 | - @ </font></p> | |
| 161 | + @ </span></p> | |
| 162 | 162 | ; |
| 163 | 163 | }else if( strcmp(zNew1,zNew2)!=0 ){ |
| 164 | 164 | zErrMsg = |
| 165 | - @ <p><font color="red"> | |
| 165 | + @ <p><span class="loginError"> | |
| 166 | 166 | @ The two copies of your new passwords do not match. |
| 167 | 167 | @ Your password is unchanged. |
| 168 | - @ </font></p> | |
| 168 | + @ </span></p> | |
| 169 | 169 | ; |
| 170 | 170 | }else{ |
| 171 | 171 | char *zNewPw = sha1_shared_secret(zNew1, g.zLogin); |
| 172 | 172 | db_multi_exec( |
| 173 | 173 | "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid |
| @@ -206,13 +206,13 @@ | ||
| 206 | 206 | zUsername, zPasswd, zSha1Pw |
| 207 | 207 | ); |
| 208 | 208 | if( uid<=0 ){ |
| 209 | 209 | sleep(1); |
| 210 | 210 | zErrMsg = |
| 211 | - @ <p><font color="red"> | |
| 211 | + @ <p><span class="loginError"> | |
| 212 | 212 | @ You entered an unknown user or an incorrect password. |
| 213 | - @ </font></p> | |
| 213 | + @ </span></p> | |
| 214 | 214 | ; |
| 215 | 215 | }else{ |
| 216 | 216 | char *zCookie; |
| 217 | 217 | const char *zCookieName = login_cookie_name(); |
| 218 | 218 | const char *zExpire = db_get("cookie-expire","8766"); |
| @@ -229,38 +229,38 @@ | ||
| 229 | 229 | redirect_to_g(); |
| 230 | 230 | } |
| 231 | 231 | } |
| 232 | 232 | style_header("Login/Logout"); |
| 233 | 233 | @ %s(zErrMsg) |
| 234 | - @ <form action="login" method="POST"> | |
| 234 | + @ <form action="login" method="post"> | |
| 235 | 235 | if( P("g") ){ |
| 236 | - @ <input type="hidden" name="g" value="%h(P("g"))"> | |
| 236 | + @ <input type="hidden" name="g" value="%h(P("g"))" /> | |
| 237 | 237 | } |
| 238 | - @ <table align="left" hspace="10"> | |
| 238 | + @ <table class="login_out"> | |
| 239 | 239 | @ <tr> |
| 240 | - @ <td align="right">User ID:</td> | |
| 240 | + @ <td class="login_out_label">User ID:</td> | |
| 241 | 241 | if( anonFlag ){ |
| 242 | - @ <td><input type="text" id="u" name="u" value="anonymous" size=30></td> | |
| 242 | + @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td> | |
| 243 | 243 | }else{ |
| 244 | - @ <td><input type="text" id="u" name="u" value="" size=30></td> | |
| 244 | + @ <td><input type="text" id="u" name="u" value="" size="30" /></td> | |
| 245 | 245 | } |
| 246 | 246 | @ </tr> |
| 247 | 247 | @ <tr> |
| 248 | - @ <td align="right">Password:</td> | |
| 249 | - @ <td><input type="password" id="p" name="p" value="" size=30></td> | |
| 248 | + @ <td class="login_out_label">Password:</td> | |
| 249 | + @ <td><input type="password" id="p" name="p" value="" size="30" /></td> | |
| 250 | 250 | @ </tr> |
| 251 | 251 | if( g.zLogin==0 ){ |
| 252 | 252 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 253 | 253 | " WHERE login='anonymous'" |
| 254 | 254 | " AND cap!=''"); |
| 255 | 255 | } |
| 256 | 256 | @ <tr> |
| 257 | 257 | @ <td></td> |
| 258 | - @ <td><input type="submit" name="in" value="Login"></td> | |
| 258 | + @ <td><input type="submit" name="in" value="Login" /></td> | |
| 259 | 259 | @ </tr> |
| 260 | 260 | @ </table> |
| 261 | - @ <script>document.getElementById('u').focus()</script> | |
| 261 | + @ <script type="text/JavaScript">document.getElementById('u').focus()</script> | |
| 262 | 262 | if( g.zLogin==0 ){ |
| 263 | 263 | @ <p>Enter |
| 264 | 264 | }else{ |
| 265 | 265 | @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p> |
| 266 | 266 | @ <p>To change your login to a different user, enter |
| @@ -273,46 +273,46 @@ | ||
| 273 | 273 | unsigned int uSeed = captcha_seed(); |
| 274 | 274 | char const *zDecoded = captcha_decode(uSeed); |
| 275 | 275 | int bAutoCaptcha = db_get_boolean("auto-captcha", 1); |
| 276 | 276 | char *zCaptcha = captcha_render(zDecoded); |
| 277 | 277 | |
| 278 | - @ <input type="hidden" name="cs" value="%u(uSeed)"/> | |
| 279 | - @ <p>Visitors may enter <b>anonymous</b> as the user-ID with | |
| 278 | + @ <p><input type="hidden" name="cs" value="%u(uSeed)" /> | |
| 279 | + @ Visitors may enter <b>anonymous</b> as the user-ID with | |
| 280 | 280 | @ the 8-character hexadecimal password shown below:</p> |
| 281 | - @ <center><table border="1" cellpadding="10"><tr><td><pre> | |
| 281 | + @ <div class="captcha"><table class="captcha"><tr><td><pre> | |
| 282 | 282 | @ %s(zCaptcha) |
| 283 | 283 | @ </pre></td></tr></table> |
| 284 | 284 | if( bAutoCaptcha ) { |
| 285 | 285 | @ <input type="button" value="Fill out captcha" |
| 286 | 286 | @ onclick="document.getElementById('u').value='anonymous'; |
| 287 | - @ document.getElementById('p').value='%s(zDecoded)';"/> | |
| 287 | + @ document.getElementById('p').value='%s(zDecoded)';" /> | |
| 288 | 288 | } |
| 289 | - @ </center> | |
| 289 | + @ </div> | |
| 290 | 290 | free(zCaptcha); |
| 291 | 291 | } |
| 292 | 292 | if( g.zLogin ){ |
| 293 | - @ <br clear="both"><hr> | |
| 293 | + @ <hr /> | |
| 294 | 294 | @ <p>To log off the system (and delete your login cookie) |
| 295 | - @ press the following button:<br> | |
| 296 | - @ <input type="submit" name="out" value="Logout"></p> | |
| 295 | + @ press the following button:<br /> | |
| 296 | + @ <input type="submit" name="out" value="Logout" /></p> | |
| 297 | 297 | } |
| 298 | 298 | @ </form> |
| 299 | 299 | if( g.okPassword ){ |
| 300 | - @ <br clear="both"><hr> | |
| 300 | + @ <hr /> | |
| 301 | 301 | @ <p>To change your password, enter your old password and your |
| 302 | 302 | @ new password twice below then press the "Change Password" |
| 303 | 303 | @ button.</p> |
| 304 | - @ <form action="login" method="POST"> | |
| 304 | + @ <form action="login" method="post"> | |
| 305 | 305 | @ <table> |
| 306 | - @ <tr><td align="right">Old Password:</td> | |
| 307 | - @ <td><input type="password" name="p" size=30></td></tr> | |
| 308 | - @ <tr><td align="right">New Password:</td> | |
| 309 | - @ <td><input type="password" name="n1" size=30></td></tr> | |
| 310 | - @ <tr><td align="right">Repeat New Password:</td> | |
| 311 | - @ <td><input type="password" name="n2" size=30></td></tr> | |
| 306 | + @ <tr><td class="login_out_label">Old Password:</td> | |
| 307 | + @ <td><input type="password" name="p" size="30" /></td></tr> | |
| 308 | + @ <tr><td class="login_out_label">New Password:</td> | |
| 309 | + @ <td><input type="password" name="n1" size="30" /></td></tr> | |
| 310 | + @ <tr><td class="login_out_label">Repeat New Password:</td> | |
| 311 | + @ <td><input type="password" name="n2" size="30" /></td></tr> | |
| 312 | 312 | @ <tr><td></td> |
| 313 | - @ <td><input type="submit" value="Change Password"></td></tr> | |
| 313 | + @ <td><input type="submit" value="Change Password" /></td></tr> | |
| 314 | 314 | @ </table> |
| 315 | 315 | @ </form> |
| 316 | 316 | } |
| 317 | 317 | style_footer(); |
| 318 | 318 | } |
| @@ -596,22 +596,22 @@ | ||
| 596 | 596 | if( !g.okHistory && |
| 597 | 597 | db_exists("SELECT 1 FROM user" |
| 598 | 598 | " WHERE login='anonymous'" |
| 599 | 599 | " AND cap LIKE '%%h%%'") ){ |
| 600 | 600 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 601 | - @ <p>Many <font color="red">hyperlinks are disabled.</font><br /> | |
| 602 | - @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> | |
| 601 | + @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> | |
| 602 | + @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> | |
| 603 | 603 | @ to enable hyperlinks.</p> |
| 604 | 604 | } |
| 605 | 605 | } |
| 606 | 606 | |
| 607 | 607 | /* |
| 608 | 608 | ** While rendering a form, call this routine to add the Anti-CSRF token |
| 609 | 609 | ** as a hidden element of the form. |
| 610 | 610 | */ |
| 611 | 611 | void login_insert_csrf_secret(void){ |
| 612 | - @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)"> | |
| 612 | + @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)" /> | |
| 613 | 613 | } |
| 614 | 614 | |
| 615 | 615 | /* |
| 616 | 616 | ** Before using the results of a form, first call this routine to verify |
| 617 | 617 | ** that ths Anti-CSRF token is present and is valid. If the Anti-CSRF token |
| 618 | 618 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -153,21 +153,21 @@ | |
| 153 | if( db_int(1, "SELECT 0 FROM user" |
| 154 | " WHERE uid=%d AND (pw=%Q OR pw=%Q)", |
| 155 | g.userUid, zPasswd, zSha1Pw) ){ |
| 156 | sleep(1); |
| 157 | zErrMsg = |
| 158 | @ <p><font color="red"> |
| 159 | @ You entered an incorrect old password while attempting to change |
| 160 | @ your password. Your password is unchanged. |
| 161 | @ </font></p> |
| 162 | ; |
| 163 | }else if( strcmp(zNew1,zNew2)!=0 ){ |
| 164 | zErrMsg = |
| 165 | @ <p><font color="red"> |
| 166 | @ The two copies of your new passwords do not match. |
| 167 | @ Your password is unchanged. |
| 168 | @ </font></p> |
| 169 | ; |
| 170 | }else{ |
| 171 | char *zNewPw = sha1_shared_secret(zNew1, g.zLogin); |
| 172 | db_multi_exec( |
| 173 | "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid |
| @@ -206,13 +206,13 @@ | |
| 206 | zUsername, zPasswd, zSha1Pw |
| 207 | ); |
| 208 | if( uid<=0 ){ |
| 209 | sleep(1); |
| 210 | zErrMsg = |
| 211 | @ <p><font color="red"> |
| 212 | @ You entered an unknown user or an incorrect password. |
| 213 | @ </font></p> |
| 214 | ; |
| 215 | }else{ |
| 216 | char *zCookie; |
| 217 | const char *zCookieName = login_cookie_name(); |
| 218 | const char *zExpire = db_get("cookie-expire","8766"); |
| @@ -229,38 +229,38 @@ | |
| 229 | redirect_to_g(); |
| 230 | } |
| 231 | } |
| 232 | style_header("Login/Logout"); |
| 233 | @ %s(zErrMsg) |
| 234 | @ <form action="login" method="POST"> |
| 235 | if( P("g") ){ |
| 236 | @ <input type="hidden" name="g" value="%h(P("g"))"> |
| 237 | } |
| 238 | @ <table align="left" hspace="10"> |
| 239 | @ <tr> |
| 240 | @ <td align="right">User ID:</td> |
| 241 | if( anonFlag ){ |
| 242 | @ <td><input type="text" id="u" name="u" value="anonymous" size=30></td> |
| 243 | }else{ |
| 244 | @ <td><input type="text" id="u" name="u" value="" size=30></td> |
| 245 | } |
| 246 | @ </tr> |
| 247 | @ <tr> |
| 248 | @ <td align="right">Password:</td> |
| 249 | @ <td><input type="password" id="p" name="p" value="" size=30></td> |
| 250 | @ </tr> |
| 251 | if( g.zLogin==0 ){ |
| 252 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 253 | " WHERE login='anonymous'" |
| 254 | " AND cap!=''"); |
| 255 | } |
| 256 | @ <tr> |
| 257 | @ <td></td> |
| 258 | @ <td><input type="submit" name="in" value="Login"></td> |
| 259 | @ </tr> |
| 260 | @ </table> |
| 261 | @ <script>document.getElementById('u').focus()</script> |
| 262 | if( g.zLogin==0 ){ |
| 263 | @ <p>Enter |
| 264 | }else{ |
| 265 | @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p> |
| 266 | @ <p>To change your login to a different user, enter |
| @@ -273,46 +273,46 @@ | |
| 273 | unsigned int uSeed = captcha_seed(); |
| 274 | char const *zDecoded = captcha_decode(uSeed); |
| 275 | int bAutoCaptcha = db_get_boolean("auto-captcha", 1); |
| 276 | char *zCaptcha = captcha_render(zDecoded); |
| 277 | |
| 278 | @ <input type="hidden" name="cs" value="%u(uSeed)"/> |
| 279 | @ <p>Visitors may enter <b>anonymous</b> as the user-ID with |
| 280 | @ the 8-character hexadecimal password shown below:</p> |
| 281 | @ <center><table border="1" cellpadding="10"><tr><td><pre> |
| 282 | @ %s(zCaptcha) |
| 283 | @ </pre></td></tr></table> |
| 284 | if( bAutoCaptcha ) { |
| 285 | @ <input type="button" value="Fill out captcha" |
| 286 | @ onclick="document.getElementById('u').value='anonymous'; |
| 287 | @ document.getElementById('p').value='%s(zDecoded)';"/> |
| 288 | } |
| 289 | @ </center> |
| 290 | free(zCaptcha); |
| 291 | } |
| 292 | if( g.zLogin ){ |
| 293 | @ <br clear="both"><hr> |
| 294 | @ <p>To log off the system (and delete your login cookie) |
| 295 | @ press the following button:<br> |
| 296 | @ <input type="submit" name="out" value="Logout"></p> |
| 297 | } |
| 298 | @ </form> |
| 299 | if( g.okPassword ){ |
| 300 | @ <br clear="both"><hr> |
| 301 | @ <p>To change your password, enter your old password and your |
| 302 | @ new password twice below then press the "Change Password" |
| 303 | @ button.</p> |
| 304 | @ <form action="login" method="POST"> |
| 305 | @ <table> |
| 306 | @ <tr><td align="right">Old Password:</td> |
| 307 | @ <td><input type="password" name="p" size=30></td></tr> |
| 308 | @ <tr><td align="right">New Password:</td> |
| 309 | @ <td><input type="password" name="n1" size=30></td></tr> |
| 310 | @ <tr><td align="right">Repeat New Password:</td> |
| 311 | @ <td><input type="password" name="n2" size=30></td></tr> |
| 312 | @ <tr><td></td> |
| 313 | @ <td><input type="submit" value="Change Password"></td></tr> |
| 314 | @ </table> |
| 315 | @ </form> |
| 316 | } |
| 317 | style_footer(); |
| 318 | } |
| @@ -596,22 +596,22 @@ | |
| 596 | if( !g.okHistory && |
| 597 | db_exists("SELECT 1 FROM user" |
| 598 | " WHERE login='anonymous'" |
| 599 | " AND cap LIKE '%%h%%'") ){ |
| 600 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 601 | @ <p>Many <font color="red">hyperlinks are disabled.</font><br /> |
| 602 | @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> |
| 603 | @ to enable hyperlinks.</p> |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | /* |
| 608 | ** While rendering a form, call this routine to add the Anti-CSRF token |
| 609 | ** as a hidden element of the form. |
| 610 | */ |
| 611 | void login_insert_csrf_secret(void){ |
| 612 | @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)"> |
| 613 | } |
| 614 | |
| 615 | /* |
| 616 | ** Before using the results of a form, first call this routine to verify |
| 617 | ** that ths Anti-CSRF token is present and is valid. If the Anti-CSRF token |
| 618 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -153,21 +153,21 @@ | |
| 153 | if( db_int(1, "SELECT 0 FROM user" |
| 154 | " WHERE uid=%d AND (pw=%Q OR pw=%Q)", |
| 155 | g.userUid, zPasswd, zSha1Pw) ){ |
| 156 | sleep(1); |
| 157 | zErrMsg = |
| 158 | @ <p><span class="loginError"> |
| 159 | @ You entered an incorrect old password while attempting to change |
| 160 | @ your password. Your password is unchanged. |
| 161 | @ </span></p> |
| 162 | ; |
| 163 | }else if( strcmp(zNew1,zNew2)!=0 ){ |
| 164 | zErrMsg = |
| 165 | @ <p><span class="loginError"> |
| 166 | @ The two copies of your new passwords do not match. |
| 167 | @ Your password is unchanged. |
| 168 | @ </span></p> |
| 169 | ; |
| 170 | }else{ |
| 171 | char *zNewPw = sha1_shared_secret(zNew1, g.zLogin); |
| 172 | db_multi_exec( |
| 173 | "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid |
| @@ -206,13 +206,13 @@ | |
| 206 | zUsername, zPasswd, zSha1Pw |
| 207 | ); |
| 208 | if( uid<=0 ){ |
| 209 | sleep(1); |
| 210 | zErrMsg = |
| 211 | @ <p><span class="loginError"> |
| 212 | @ You entered an unknown user or an incorrect password. |
| 213 | @ </span></p> |
| 214 | ; |
| 215 | }else{ |
| 216 | char *zCookie; |
| 217 | const char *zCookieName = login_cookie_name(); |
| 218 | const char *zExpire = db_get("cookie-expire","8766"); |
| @@ -229,38 +229,38 @@ | |
| 229 | redirect_to_g(); |
| 230 | } |
| 231 | } |
| 232 | style_header("Login/Logout"); |
| 233 | @ %s(zErrMsg) |
| 234 | @ <form action="login" method="post"> |
| 235 | if( P("g") ){ |
| 236 | @ <input type="hidden" name="g" value="%h(P("g"))" /> |
| 237 | } |
| 238 | @ <table class="login_out"> |
| 239 | @ <tr> |
| 240 | @ <td class="login_out_label">User ID:</td> |
| 241 | if( anonFlag ){ |
| 242 | @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td> |
| 243 | }else{ |
| 244 | @ <td><input type="text" id="u" name="u" value="" size="30" /></td> |
| 245 | } |
| 246 | @ </tr> |
| 247 | @ <tr> |
| 248 | @ <td class="login_out_label">Password:</td> |
| 249 | @ <td><input type="password" id="p" name="p" value="" size="30" /></td> |
| 250 | @ </tr> |
| 251 | if( g.zLogin==0 ){ |
| 252 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 253 | " WHERE login='anonymous'" |
| 254 | " AND cap!=''"); |
| 255 | } |
| 256 | @ <tr> |
| 257 | @ <td></td> |
| 258 | @ <td><input type="submit" name="in" value="Login" /></td> |
| 259 | @ </tr> |
| 260 | @ </table> |
| 261 | @ <script type="text/JavaScript">document.getElementById('u').focus()</script> |
| 262 | if( g.zLogin==0 ){ |
| 263 | @ <p>Enter |
| 264 | }else{ |
| 265 | @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p> |
| 266 | @ <p>To change your login to a different user, enter |
| @@ -273,46 +273,46 @@ | |
| 273 | unsigned int uSeed = captcha_seed(); |
| 274 | char const *zDecoded = captcha_decode(uSeed); |
| 275 | int bAutoCaptcha = db_get_boolean("auto-captcha", 1); |
| 276 | char *zCaptcha = captcha_render(zDecoded); |
| 277 | |
| 278 | @ <p><input type="hidden" name="cs" value="%u(uSeed)" /> |
| 279 | @ Visitors may enter <b>anonymous</b> as the user-ID with |
| 280 | @ the 8-character hexadecimal password shown below:</p> |
| 281 | @ <div class="captcha"><table class="captcha"><tr><td><pre> |
| 282 | @ %s(zCaptcha) |
| 283 | @ </pre></td></tr></table> |
| 284 | if( bAutoCaptcha ) { |
| 285 | @ <input type="button" value="Fill out captcha" |
| 286 | @ onclick="document.getElementById('u').value='anonymous'; |
| 287 | @ document.getElementById('p').value='%s(zDecoded)';" /> |
| 288 | } |
| 289 | @ </div> |
| 290 | free(zCaptcha); |
| 291 | } |
| 292 | if( g.zLogin ){ |
| 293 | @ <hr /> |
| 294 | @ <p>To log off the system (and delete your login cookie) |
| 295 | @ press the following button:<br /> |
| 296 | @ <input type="submit" name="out" value="Logout" /></p> |
| 297 | } |
| 298 | @ </form> |
| 299 | if( g.okPassword ){ |
| 300 | @ <hr /> |
| 301 | @ <p>To change your password, enter your old password and your |
| 302 | @ new password twice below then press the "Change Password" |
| 303 | @ button.</p> |
| 304 | @ <form action="login" method="post"> |
| 305 | @ <table> |
| 306 | @ <tr><td class="login_out_label">Old Password:</td> |
| 307 | @ <td><input type="password" name="p" size="30" /></td></tr> |
| 308 | @ <tr><td class="login_out_label">New Password:</td> |
| 309 | @ <td><input type="password" name="n1" size="30" /></td></tr> |
| 310 | @ <tr><td class="login_out_label">Repeat New Password:</td> |
| 311 | @ <td><input type="password" name="n2" size="30" /></td></tr> |
| 312 | @ <tr><td></td> |
| 313 | @ <td><input type="submit" value="Change Password" /></td></tr> |
| 314 | @ </table> |
| 315 | @ </form> |
| 316 | } |
| 317 | style_footer(); |
| 318 | } |
| @@ -596,22 +596,22 @@ | |
| 596 | if( !g.okHistory && |
| 597 | db_exists("SELECT 1 FROM user" |
| 598 | " WHERE login='anonymous'" |
| 599 | " AND cap LIKE '%%h%%'") ){ |
| 600 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 601 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 602 | @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> |
| 603 | @ to enable hyperlinks.</p> |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | /* |
| 608 | ** While rendering a form, call this routine to add the Anti-CSRF token |
| 609 | ** as a hidden element of the form. |
| 610 | */ |
| 611 | void login_insert_csrf_secret(void){ |
| 612 | @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)" /> |
| 613 | } |
| 614 | |
| 615 | /* |
| 616 | ** Before using the results of a form, first call this routine to verify |
| 617 | ** that ths Anti-CSRF token is present and is valid. If the Anti-CSRF token |
| 618 |
+12
-12
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -277,13 +277,13 @@ | ||
| 277 | 277 | zSQL = db_column_text(&q, 1); |
| 278 | 278 | zOwner = db_column_text(&q, 2); |
| 279 | 279 | zClrKey = db_column_text(&q, 3); |
| 280 | 280 | @ <table cellpadding=0 cellspacing=0 border=0> |
| 281 | 281 | @ <tr><td valign="top" align="right">Title:</td><td width=15></td> |
| 282 | - @ <td colspan=3>%h(zTitle)</td></tr> | |
| 282 | + @ <td colspan="3">%h(zTitle)</td></tr> | |
| 283 | 283 | @ <tr><td valign="top" align="right">Owner:</td><td></td> |
| 284 | - @ <td colspan=3>%h(zOwner)</td></tr> | |
| 284 | + @ <td colspan="3">%h(zOwner)</td></tr> | |
| 285 | 285 | @ <tr><td valign="top" align="right">SQL:</td><td></td> |
| 286 | 286 | @ <td valign="top"><pre> |
| 287 | 287 | @ %h(zSQL) |
| 288 | 288 | @ </pre></td> |
| 289 | 289 | @ <td width=15></td><td valign="top"> |
| @@ -393,21 +393,21 @@ | ||
| 393 | 393 | } |
| 394 | 394 | } |
| 395 | 395 | if( zOwner==0 ) zOwner = g.zLogin; |
| 396 | 396 | style_submenu_element("Cancel", "Cancel", "reportlist"); |
| 397 | 397 | if( rn>0 ){ |
| 398 | - style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); | |
| 398 | + style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); | |
| 399 | 399 | } |
| 400 | 400 | style_header(rn>0 ? "Edit Report Format":"Create New Report Format"); |
| 401 | 401 | if( zErr ){ |
| 402 | 402 | @ <blockquote><font color="#ff0000"><b>%h(zErr)</b></font></blockquote> |
| 403 | 403 | } |
| 404 | 404 | @ <form action="rptedit" method="POST"> |
| 405 | 405 | @ <input type="hidden" name="rn" value="%d(rn)"> |
| 406 | - @ <p>Report Title:<br> | |
| 406 | + @ <p>Report Title:<br /> | |
| 407 | 407 | @ <input type="text" name="t" value="%h(zTitle)" size="60"></p> |
| 408 | - @ <p>Enter a complete SQL query statement against the "TICKET" table:<br> | |
| 408 | + @ <p>Enter a complete SQL query statement against the "TICKET" table:<br /> | |
| 409 | 409 | @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea> |
| 410 | 410 | @ </p> |
| 411 | 411 | login_insert_csrf_secret(); |
| 412 | 412 | if( g.okAdmin ){ |
| 413 | 413 | @ <p>Report owner: |
| @@ -417,11 +417,11 @@ | ||
| 417 | 417 | @ <input type="hidden" name="w" value="%h(zOwner)"> |
| 418 | 418 | } |
| 419 | 419 | @ <p>Enter an optional color key in the following box. (If blank, no |
| 420 | 420 | @ color key is displayed.) Each line contains the text for a single |
| 421 | 421 | @ entry in the key. The first token of each line is the background |
| 422 | - @ color for that line.<br> | |
| 422 | + @ color for that line.<br /> | |
| 423 | 423 | @ <textarea name="k" rows="8" cols="50">%h(zClrKey)</textarea> |
| 424 | 424 | @ </p> |
| 425 | 425 | if( !g.okAdmin && strcmp(zOwner,g.zLogin)!=0 ){ |
| 426 | 426 | @ <p>This report format is owned by %h(zOwner). You are not allowed |
| 427 | 427 | @ to change it.</p> |
| @@ -448,11 +448,11 @@ | ||
| 448 | 448 | zSchema = db_text(0,"SELECT sql FROM sqlite_master WHERE name='ticket'"); |
| 449 | 449 | if( zSchema==0 ){ |
| 450 | 450 | zSchema = db_text(0,"SELECT sql FROM repository.sqlite_master" |
| 451 | 451 | " WHERE name='ticket'"); |
| 452 | 452 | } |
| 453 | - @ <hr><h3>TICKET Schema</h3> | |
| 453 | + @ <hr /><h3>TICKET Schema</h3> | |
| 454 | 454 | @ <blockquote><pre> |
| 455 | 455 | @ %h(zSchema) |
| 456 | 456 | @ </pre></blockquote> |
| 457 | 457 | @ <h3>Notes</h3> |
| 458 | 458 | @ <ul> |
| @@ -829,14 +829,14 @@ | ||
| 829 | 829 | while( isspace(*zSafeKey) ) zSafeKey++; |
| 830 | 830 | for(i=0; zSafeKey[i] && !isspace(zSafeKey[i]); i++){} |
| 831 | 831 | for(j=i; isspace(zSafeKey[j]); j++){} |
| 832 | 832 | for(k=j; zSafeKey[k] && zSafeKey[k]!='\n' && zSafeKey[k]!='\r'; k++){} |
| 833 | 833 | if( !horiz ){ |
| 834 | - cgi_printf("<tr bgcolor=\"%.*s\"><td>%.*s</td></tr>\n", | |
| 834 | + cgi_printf("<tr style=\"background-color: %.*s;\"><td>%.*s</td></tr>\n", | |
| 835 | 835 | i, zSafeKey, k-j, &zSafeKey[j]); |
| 836 | 836 | }else{ |
| 837 | - cgi_printf("<td bgcolor=\"%.*s\">%.*s</td>\n", | |
| 837 | + cgi_printf("<td style=\"background-color: %.*s;\">%.*s</td>\n", | |
| 838 | 838 | i, zSafeKey, k-j, &zSafeKey[j]); |
| 839 | 839 | } |
| 840 | 840 | zSafeKey += k; |
| 841 | 841 | } |
| 842 | 842 | free(zToFree); |
| @@ -907,11 +907,11 @@ | ||
| 907 | 907 | if( !tabs ){ |
| 908 | 908 | struct GenerateHTML sState; |
| 909 | 909 | |
| 910 | 910 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 911 | 911 | style_submenu_element("Raw", "Raw", |
| 912 | - "rptview?tablist=1&%s", PD("QUERY_STRING","")); | |
| 912 | + "rptview?tablist=1&%s", PD("QUERY_STRING","")); | |
| 913 | 913 | if( g.okAdmin |
| 914 | 914 | || (g.okTktFmt && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){ |
| 915 | 915 | style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn); |
| 916 | 916 | } |
| 917 | 917 | if( g.okTktFmt ){ |
| @@ -921,12 +921,12 @@ | ||
| 921 | 921 | style_submenu_element("New Ticket", "Create a new ticket", |
| 922 | 922 | "%s/tktnew", g.zTop); |
| 923 | 923 | } |
| 924 | 924 | style_header(zTitle); |
| 925 | 925 | output_color_key(zClrKey, 1, |
| 926 | - "border=0 cellpadding=3 cellspacing=0 class=\"report\""); | |
| 927 | - @ <table border=1 cellpadding=2 cellspacing=0 class="report"> | |
| 926 | + "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\""); | |
| 927 | + @ <table border="1" cellpadding="2" cellspacing="0" class="report"> | |
| 928 | 928 | sState.rn = rn; |
| 929 | 929 | sState.nCount = 0; |
| 930 | 930 | sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1); |
| 931 | 931 | sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2); |
| 932 | 932 | sqlite3_set_authorizer(g.db, 0, 0); |
| 933 | 933 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -277,13 +277,13 @@ | |
| 277 | zSQL = db_column_text(&q, 1); |
| 278 | zOwner = db_column_text(&q, 2); |
| 279 | zClrKey = db_column_text(&q, 3); |
| 280 | @ <table cellpadding=0 cellspacing=0 border=0> |
| 281 | @ <tr><td valign="top" align="right">Title:</td><td width=15></td> |
| 282 | @ <td colspan=3>%h(zTitle)</td></tr> |
| 283 | @ <tr><td valign="top" align="right">Owner:</td><td></td> |
| 284 | @ <td colspan=3>%h(zOwner)</td></tr> |
| 285 | @ <tr><td valign="top" align="right">SQL:</td><td></td> |
| 286 | @ <td valign="top"><pre> |
| 287 | @ %h(zSQL) |
| 288 | @ </pre></td> |
| 289 | @ <td width=15></td><td valign="top"> |
| @@ -393,21 +393,21 @@ | |
| 393 | } |
| 394 | } |
| 395 | if( zOwner==0 ) zOwner = g.zLogin; |
| 396 | style_submenu_element("Cancel", "Cancel", "reportlist"); |
| 397 | if( rn>0 ){ |
| 398 | style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); |
| 399 | } |
| 400 | style_header(rn>0 ? "Edit Report Format":"Create New Report Format"); |
| 401 | if( zErr ){ |
| 402 | @ <blockquote><font color="#ff0000"><b>%h(zErr)</b></font></blockquote> |
| 403 | } |
| 404 | @ <form action="rptedit" method="POST"> |
| 405 | @ <input type="hidden" name="rn" value="%d(rn)"> |
| 406 | @ <p>Report Title:<br> |
| 407 | @ <input type="text" name="t" value="%h(zTitle)" size="60"></p> |
| 408 | @ <p>Enter a complete SQL query statement against the "TICKET" table:<br> |
| 409 | @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea> |
| 410 | @ </p> |
| 411 | login_insert_csrf_secret(); |
| 412 | if( g.okAdmin ){ |
| 413 | @ <p>Report owner: |
| @@ -417,11 +417,11 @@ | |
| 417 | @ <input type="hidden" name="w" value="%h(zOwner)"> |
| 418 | } |
| 419 | @ <p>Enter an optional color key in the following box. (If blank, no |
| 420 | @ color key is displayed.) Each line contains the text for a single |
| 421 | @ entry in the key. The first token of each line is the background |
| 422 | @ color for that line.<br> |
| 423 | @ <textarea name="k" rows="8" cols="50">%h(zClrKey)</textarea> |
| 424 | @ </p> |
| 425 | if( !g.okAdmin && strcmp(zOwner,g.zLogin)!=0 ){ |
| 426 | @ <p>This report format is owned by %h(zOwner). You are not allowed |
| 427 | @ to change it.</p> |
| @@ -448,11 +448,11 @@ | |
| 448 | zSchema = db_text(0,"SELECT sql FROM sqlite_master WHERE name='ticket'"); |
| 449 | if( zSchema==0 ){ |
| 450 | zSchema = db_text(0,"SELECT sql FROM repository.sqlite_master" |
| 451 | " WHERE name='ticket'"); |
| 452 | } |
| 453 | @ <hr><h3>TICKET Schema</h3> |
| 454 | @ <blockquote><pre> |
| 455 | @ %h(zSchema) |
| 456 | @ </pre></blockquote> |
| 457 | @ <h3>Notes</h3> |
| 458 | @ <ul> |
| @@ -829,14 +829,14 @@ | |
| 829 | while( isspace(*zSafeKey) ) zSafeKey++; |
| 830 | for(i=0; zSafeKey[i] && !isspace(zSafeKey[i]); i++){} |
| 831 | for(j=i; isspace(zSafeKey[j]); j++){} |
| 832 | for(k=j; zSafeKey[k] && zSafeKey[k]!='\n' && zSafeKey[k]!='\r'; k++){} |
| 833 | if( !horiz ){ |
| 834 | cgi_printf("<tr bgcolor=\"%.*s\"><td>%.*s</td></tr>\n", |
| 835 | i, zSafeKey, k-j, &zSafeKey[j]); |
| 836 | }else{ |
| 837 | cgi_printf("<td bgcolor=\"%.*s\">%.*s</td>\n", |
| 838 | i, zSafeKey, k-j, &zSafeKey[j]); |
| 839 | } |
| 840 | zSafeKey += k; |
| 841 | } |
| 842 | free(zToFree); |
| @@ -907,11 +907,11 @@ | |
| 907 | if( !tabs ){ |
| 908 | struct GenerateHTML sState; |
| 909 | |
| 910 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 911 | style_submenu_element("Raw", "Raw", |
| 912 | "rptview?tablist=1&%s", PD("QUERY_STRING","")); |
| 913 | if( g.okAdmin |
| 914 | || (g.okTktFmt && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){ |
| 915 | style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn); |
| 916 | } |
| 917 | if( g.okTktFmt ){ |
| @@ -921,12 +921,12 @@ | |
| 921 | style_submenu_element("New Ticket", "Create a new ticket", |
| 922 | "%s/tktnew", g.zTop); |
| 923 | } |
| 924 | style_header(zTitle); |
| 925 | output_color_key(zClrKey, 1, |
| 926 | "border=0 cellpadding=3 cellspacing=0 class=\"report\""); |
| 927 | @ <table border=1 cellpadding=2 cellspacing=0 class="report"> |
| 928 | sState.rn = rn; |
| 929 | sState.nCount = 0; |
| 930 | sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1); |
| 931 | sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2); |
| 932 | sqlite3_set_authorizer(g.db, 0, 0); |
| 933 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -277,13 +277,13 @@ | |
| 277 | zSQL = db_column_text(&q, 1); |
| 278 | zOwner = db_column_text(&q, 2); |
| 279 | zClrKey = db_column_text(&q, 3); |
| 280 | @ <table cellpadding=0 cellspacing=0 border=0> |
| 281 | @ <tr><td valign="top" align="right">Title:</td><td width=15></td> |
| 282 | @ <td colspan="3">%h(zTitle)</td></tr> |
| 283 | @ <tr><td valign="top" align="right">Owner:</td><td></td> |
| 284 | @ <td colspan="3">%h(zOwner)</td></tr> |
| 285 | @ <tr><td valign="top" align="right">SQL:</td><td></td> |
| 286 | @ <td valign="top"><pre> |
| 287 | @ %h(zSQL) |
| 288 | @ </pre></td> |
| 289 | @ <td width=15></td><td valign="top"> |
| @@ -393,21 +393,21 @@ | |
| 393 | } |
| 394 | } |
| 395 | if( zOwner==0 ) zOwner = g.zLogin; |
| 396 | style_submenu_element("Cancel", "Cancel", "reportlist"); |
| 397 | if( rn>0 ){ |
| 398 | style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); |
| 399 | } |
| 400 | style_header(rn>0 ? "Edit Report Format":"Create New Report Format"); |
| 401 | if( zErr ){ |
| 402 | @ <blockquote><font color="#ff0000"><b>%h(zErr)</b></font></blockquote> |
| 403 | } |
| 404 | @ <form action="rptedit" method="POST"> |
| 405 | @ <input type="hidden" name="rn" value="%d(rn)"> |
| 406 | @ <p>Report Title:<br /> |
| 407 | @ <input type="text" name="t" value="%h(zTitle)" size="60"></p> |
| 408 | @ <p>Enter a complete SQL query statement against the "TICKET" table:<br /> |
| 409 | @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea> |
| 410 | @ </p> |
| 411 | login_insert_csrf_secret(); |
| 412 | if( g.okAdmin ){ |
| 413 | @ <p>Report owner: |
| @@ -417,11 +417,11 @@ | |
| 417 | @ <input type="hidden" name="w" value="%h(zOwner)"> |
| 418 | } |
| 419 | @ <p>Enter an optional color key in the following box. (If blank, no |
| 420 | @ color key is displayed.) Each line contains the text for a single |
| 421 | @ entry in the key. The first token of each line is the background |
| 422 | @ color for that line.<br /> |
| 423 | @ <textarea name="k" rows="8" cols="50">%h(zClrKey)</textarea> |
| 424 | @ </p> |
| 425 | if( !g.okAdmin && strcmp(zOwner,g.zLogin)!=0 ){ |
| 426 | @ <p>This report format is owned by %h(zOwner). You are not allowed |
| 427 | @ to change it.</p> |
| @@ -448,11 +448,11 @@ | |
| 448 | zSchema = db_text(0,"SELECT sql FROM sqlite_master WHERE name='ticket'"); |
| 449 | if( zSchema==0 ){ |
| 450 | zSchema = db_text(0,"SELECT sql FROM repository.sqlite_master" |
| 451 | " WHERE name='ticket'"); |
| 452 | } |
| 453 | @ <hr /><h3>TICKET Schema</h3> |
| 454 | @ <blockquote><pre> |
| 455 | @ %h(zSchema) |
| 456 | @ </pre></blockquote> |
| 457 | @ <h3>Notes</h3> |
| 458 | @ <ul> |
| @@ -829,14 +829,14 @@ | |
| 829 | while( isspace(*zSafeKey) ) zSafeKey++; |
| 830 | for(i=0; zSafeKey[i] && !isspace(zSafeKey[i]); i++){} |
| 831 | for(j=i; isspace(zSafeKey[j]); j++){} |
| 832 | for(k=j; zSafeKey[k] && zSafeKey[k]!='\n' && zSafeKey[k]!='\r'; k++){} |
| 833 | if( !horiz ){ |
| 834 | cgi_printf("<tr style=\"background-color: %.*s;\"><td>%.*s</td></tr>\n", |
| 835 | i, zSafeKey, k-j, &zSafeKey[j]); |
| 836 | }else{ |
| 837 | cgi_printf("<td style=\"background-color: %.*s;\">%.*s</td>\n", |
| 838 | i, zSafeKey, k-j, &zSafeKey[j]); |
| 839 | } |
| 840 | zSafeKey += k; |
| 841 | } |
| 842 | free(zToFree); |
| @@ -907,11 +907,11 @@ | |
| 907 | if( !tabs ){ |
| 908 | struct GenerateHTML sState; |
| 909 | |
| 910 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 911 | style_submenu_element("Raw", "Raw", |
| 912 | "rptview?tablist=1&%s", PD("QUERY_STRING","")); |
| 913 | if( g.okAdmin |
| 914 | || (g.okTktFmt && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){ |
| 915 | style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn); |
| 916 | } |
| 917 | if( g.okTktFmt ){ |
| @@ -921,12 +921,12 @@ | |
| 921 | style_submenu_element("New Ticket", "Create a new ticket", |
| 922 | "%s/tktnew", g.zTop); |
| 923 | } |
| 924 | style_header(zTitle); |
| 925 | output_color_key(zClrKey, 1, |
| 926 | "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\""); |
| 927 | @ <table border="1" cellpadding="2" cellspacing="0" class="report"> |
| 928 | sState.rn = rn; |
| 929 | sState.nCount = 0; |
| 930 | sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1); |
| 931 | sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2); |
| 932 | sqlite3_set_authorizer(g.db, 0, 0); |
| 933 |
+309
-278
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -99,42 +99,40 @@ | ||
| 99 | 99 | return; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | style_submenu_element("Add", "Add User", "setup_uedit"); |
| 103 | 103 | style_header("User List"); |
| 104 | - @ <table border="0" cellpadding="0" cellspacing="25"> | |
| 105 | - @ <tr><td valign="top"> | |
| 106 | - @ <b>Users:</b> | |
| 107 | - @ <table border="1" cellpadding="10"><tr><td> | |
| 108 | - @ <table cellspacing=0 cellpadding=0 border=0> | |
| 104 | + @ <table class="usetupLayoutTable"> | |
| 105 | + @ <tr><td class="usetupColumnLayout"> | |
| 106 | + @ <span class="note">Users:</span> | |
| 107 | + @ <table class="usetupUserList"> | |
| 109 | 108 | @ <tr> |
| 110 | - @ <th align="right">User ID</th><td width="20"> </td> | |
| 111 | - @ <th>Capabilities</th><td width="15"> </td> | |
| 112 | - @ <th>Contact Info</th> | |
| 109 | + @ <th class="usetupListUser" style="text-align: right;padding-right: 20px;">User ID</th> | |
| 110 | + @ <th class="usetupListCap" style="text-align: center;padding-right: 15px;">Capabilities</th> | |
| 111 | + @ <th class="usetupListCon" style="text-align: left;">Contact Info</th> | |
| 113 | 112 | @ </tr> |
| 114 | 113 | db_prepare(&s, "SELECT uid, login, cap, info FROM user ORDER BY login"); |
| 115 | 114 | while( db_step(&s)==SQLITE_ROW ){ |
| 116 | 115 | const char *zCap = db_column_text(&s, 2); |
| 117 | 116 | if( strstr(zCap, "s") ) zCap = "s"; |
| 118 | 117 | @ <tr> |
| 119 | - @ <td align="right"> | |
| 118 | + @ <td class="usetupListUser" style="text-align: right;padding-right: 20px;white-space:nowrap;"> | |
| 120 | 119 | if( g.okAdmin && (zCap[0]!='s' || g.okSetup) ){ |
| 121 | 120 | @ <a href="setup_uedit?id=%d(db_column_int(&s,0))"> |
| 122 | 121 | } |
| 123 | - @ <nobr>%h(db_column_text(&s,1))</nobr> | |
| 122 | + @ %h(db_column_text(&s,1)) | |
| 124 | 123 | if( g.okAdmin ){ |
| 125 | 124 | @ </a> |
| 126 | 125 | } |
| 127 | - @ </td><td> </td> | |
| 128 | - @ <td align="center">%s(zCap)</td> | |
| 129 | - @ <td> </td> | |
| 130 | - @ <td align="left">%s(db_column_text(&s,3))</td> | |
| 126 | + @ </td> | |
| 127 | + @ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td> | |
| 128 | + @ <td class="usetupListCon" style="text-align: left;">%s(db_column_text(&s,3))</td> | |
| 131 | 129 | @ </tr> |
| 132 | 130 | } |
| 133 | - @ </table></td></tr></table> | |
| 134 | - @ <td valign="top"> | |
| 135 | - @ <b>Notes:</b> | |
| 131 | + @ </table> | |
| 132 | + @ </td><td class="usetupColumnLayout"> | |
| 133 | + @ <span class="note">Notes:</span> | |
| 136 | 134 | @ <ol> |
| 137 | 135 | @ <li><p>The permission flags are as follows:</p> |
| 138 | 136 | @ <table> |
| 139 | 137 | @ <tr><td valign="top"><b>a</b></td> |
| 140 | 138 | @ <td><i>Admin:</i> Create and delete users</td></tr> |
| @@ -181,31 +179,35 @@ | ||
| 181 | 179 | @ user <tt>developer</tt></td></tr> |
| 182 | 180 | @ <tr><td valign="top"><b>w</b></td> |
| 183 | 181 | @ <td><i>Write-Tkt:</i> Edit tickets</td></tr> |
| 184 | 182 | @ <tr><td valign="top"><b>z</b></td> |
| 185 | 183 | @ <td><i>Zip download:</i> Download a baseline via the |
| 186 | - @ <tt>/zip</tt> URL even without check<b>o</b>ut | |
| 187 | - @ and <b>h</b>istory permissions</td></tr> | |
| 184 | + @ <tt>/zip</tt> URL even without | |
| 185 | + @ check<span class="capability">o</span>ut | |
| 186 | + @ and <span class="capability">h</span>istory permissions</td></tr> | |
| 188 | 187 | @ </table> |
| 189 | 188 | @ </li> |
| 190 | 189 | @ |
| 191 | 190 | @ <li><p> |
| 192 | - @ Every user, logged in or not, inherits the privileges of <b>nobody</b>. | |
| 191 | + @ Every user, logged in or not, inherits the privileges of | |
| 192 | + @ <span class="usertype">nobody</span>. | |
| 193 | 193 | @ </p></li> |
| 194 | 194 | @ |
| 195 | 195 | @ <li><p> |
| 196 | - @ Any human can login as <b>anonymous</b> since the password is | |
| 197 | - @ clearly displayed on the login page for them to type. The purpose | |
| 198 | - @ of requiring anonymous to log in is to prevent access by spiders. | |
| 196 | + @ Any human can login as <span class="usertype">anonymous</span> since the | |
| 197 | + @ password is clearly displayed on the login page for them to type. The | |
| 198 | + @ purpose of requiring anonymous to log in is to prevent access by spiders. | |
| 199 | 199 | @ Every logged-in user inherits the combined privileges of |
| 200 | - @ <b>anonymous</b> and | |
| 201 | - @ <b>nobody</b>. | |
| 200 | + @ <span class="usertype">anonymous</span> and | |
| 201 | + @ <span class="usertype">nobody</span>. | |
| 202 | 202 | @ </p></li> |
| 203 | 203 | @ |
| 204 | 204 | @ <li><p> |
| 205 | - @ Users with privilege <b>v</b> inherit the combined privileges of | |
| 206 | - @ <b>developer</b>, <b>anonymous</b>, and <b>nobody</b>. | |
| 205 | + @ Users with privilege <span class="capability">v</span> inherit the combined | |
| 206 | + @ privileges of <span class="usertype">developer</span>, | |
| 207 | + @ <span class="usertype">anonymous</span>, and | |
| 208 | + @ <span class="usertype">nobody</span>. | |
| 207 | 209 | @ </p></li> |
| 208 | 210 | @ |
| 209 | 211 | @ </ol> |
| 210 | 212 | @ </td></tr></table> |
| 211 | 213 | style_footer(); |
| @@ -323,12 +325,12 @@ | ||
| 323 | 325 | } |
| 324 | 326 | if( uid>0 && |
| 325 | 327 | db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid) |
| 326 | 328 | ){ |
| 327 | 329 | style_header("User Creation Error"); |
| 328 | - @ <font color="red">Login "%h(zLogin)" is already used by a different | |
| 329 | - @ user.</font> | |
| 330 | + @ <span class="loginError">Login "%h(zLogin)" is already used by | |
| 331 | + @ a different user.</span> | |
| 330 | 332 | @ |
| 331 | 333 | @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p> |
| 332 | 334 | style_footer(); |
| 333 | 335 | return; |
| 334 | 336 | } |
| @@ -353,65 +355,69 @@ | ||
| 353 | 355 | if( uid ){ |
| 354 | 356 | zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); |
| 355 | 357 | zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); |
| 356 | 358 | zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); |
| 357 | 359 | zPw = db_text("", "SELECT pw FROM user WHERE uid=%d", uid); |
| 358 | - if( strchr(zCap, 'a') ) oaa = " checked"; | |
| 359 | - if( strchr(zCap, 'b') ) oab = " checked"; | |
| 360 | - if( strchr(zCap, 'c') ) oac = " checked"; | |
| 361 | - if( strchr(zCap, 'd') ) oad = " checked"; | |
| 362 | - if( strchr(zCap, 'e') ) oae = " checked"; | |
| 363 | - if( strchr(zCap, 'f') ) oaf = " checked"; | |
| 364 | - if( strchr(zCap, 'g') ) oag = " checked"; | |
| 365 | - if( strchr(zCap, 'h') ) oah = " checked"; | |
| 366 | - if( strchr(zCap, 'i') ) oai = " checked"; | |
| 367 | - if( strchr(zCap, 'j') ) oaj = " checked"; | |
| 368 | - if( strchr(zCap, 'k') ) oak = " checked"; | |
| 369 | - if( strchr(zCap, 'm') ) oam = " checked"; | |
| 370 | - if( strchr(zCap, 'n') ) oan = " checked"; | |
| 371 | - if( strchr(zCap, 'o') ) oao = " checked"; | |
| 372 | - if( strchr(zCap, 'p') ) oap = " checked"; | |
| 373 | - if( strchr(zCap, 'r') ) oar = " checked"; | |
| 374 | - if( strchr(zCap, 's') ) oas = " checked"; | |
| 375 | - if( strchr(zCap, 't') ) oat = " checked"; | |
| 376 | - if( strchr(zCap, 'u') ) oau = " checked"; | |
| 377 | - if( strchr(zCap, 'v') ) oav = " checked"; | |
| 378 | - if( strchr(zCap, 'w') ) oaw = " checked"; | |
| 379 | - if( strchr(zCap, 'z') ) oaz = " checked"; | |
| 360 | + if( strchr(zCap, 'a') ) oaa = " checked=\"checked\""; | |
| 361 | + if( strchr(zCap, 'b') ) oab = " checked=\"checked\""; | |
| 362 | + if( strchr(zCap, 'c') ) oac = " checked=\"checked\""; | |
| 363 | + if( strchr(zCap, 'd') ) oad = " checked=\"checked\""; | |
| 364 | + if( strchr(zCap, 'e') ) oae = " checked=\"checked\""; | |
| 365 | + if( strchr(zCap, 'f') ) oaf = " checked=\"checked\""; | |
| 366 | + if( strchr(zCap, 'g') ) oag = " checked=\"checked\""; | |
| 367 | + if( strchr(zCap, 'h') ) oah = " checked=\"checked\""; | |
| 368 | + if( strchr(zCap, 'i') ) oai = " checked=\"checked\""; | |
| 369 | + if( strchr(zCap, 'j') ) oaj = " checked=\"checked\""; | |
| 370 | + if( strchr(zCap, 'k') ) oak = " checked=\"checked\""; | |
| 371 | + if( strchr(zCap, 'm') ) oam = " checked=\"checked\""; | |
| 372 | + if( strchr(zCap, 'n') ) oan = " checked=\"checked\""; | |
| 373 | + if( strchr(zCap, 'o') ) oao = " checked=\"checked\""; | |
| 374 | + if( strchr(zCap, 'p') ) oap = " checked=\"checked\""; | |
| 375 | + if( strchr(zCap, 'r') ) oar = " checked=\"checked\""; | |
| 376 | + if( strchr(zCap, 's') ) oas = " checked=\"checked\""; | |
| 377 | + if( strchr(zCap, 't') ) oat = " checked=\"checked\""; | |
| 378 | + if( strchr(zCap, 'u') ) oau = " checked=\"checked\""; | |
| 379 | + if( strchr(zCap, 'v') ) oav = " checked=\"checked\""; | |
| 380 | + if( strchr(zCap, 'w') ) oaw = " checked=\"checked\""; | |
| 381 | + if( strchr(zCap, 'z') ) oaz = " checked=\"checked\""; | |
| 380 | 382 | } |
| 381 | 383 | |
| 382 | 384 | /* figure out inherited permissions */ |
| 383 | 385 | memset(inherit, 0, sizeof(inherit)); |
| 384 | 386 | if( strcmp(zLogin, "developer") ){ |
| 385 | 387 | char *z1, *z2; |
| 386 | 388 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); |
| 387 | 389 | while( z1 && *z1 ){ |
| 388 | - inherit[0x7f & *(z1++)] = "<font color=\"red\">•</font>"; | |
| 390 | + inherit[0x7f & *(z1++)] = | |
| 391 | + "<span class=\"ueditInheritDeveloper\">•</span>"; | |
| 389 | 392 | } |
| 390 | 393 | free(z2); |
| 391 | 394 | } |
| 392 | 395 | if( strcmp(zLogin, "reader") ){ |
| 393 | 396 | char *z1, *z2; |
| 394 | 397 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); |
| 395 | 398 | while( z1 && *z1 ){ |
| 396 | - inherit[0x7f & *(z1++)] = "<font color=\"black\">•</font>"; | |
| 399 | + inherit[0x7f & *(z1++)] = | |
| 400 | + "<span class=\"ueditInheritReader\">•</span>"; | |
| 397 | 401 | } |
| 398 | 402 | free(z2); |
| 399 | 403 | } |
| 400 | 404 | if( strcmp(zLogin, "anonymous") ){ |
| 401 | 405 | char *z1, *z2; |
| 402 | 406 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); |
| 403 | 407 | while( z1 && *z1 ){ |
| 404 | - inherit[0x7f & *(z1++)] = "<font color=\"blue\">•</font>"; | |
| 408 | + inherit[0x7f & *(z1++)] = | |
| 409 | + "<span class=\"ueditInheritAnonymous\">•</span>"; | |
| 405 | 410 | } |
| 406 | 411 | free(z2); |
| 407 | 412 | } |
| 408 | 413 | if( strcmp(zLogin, "nobody") ){ |
| 409 | 414 | char *z1, *z2; |
| 410 | 415 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); |
| 411 | 416 | while( z1 && *z1 ){ |
| 412 | - inherit[0x7f & *(z1++)] = "<font color=\"green\">•</font>"; | |
| 417 | + inherit[0x7f & *(z1++)] = | |
| 418 | + "<span class=\"ueditInheritNobody\">•</span>"; | |
| 413 | 419 | } |
| 414 | 420 | free(z2); |
| 415 | 421 | } |
| 416 | 422 | |
| 417 | 423 | /* Begin generating the page |
| @@ -420,77 +426,79 @@ | ||
| 420 | 426 | if( uid ){ |
| 421 | 427 | style_header(mprintf("Edit User %h", zLogin)); |
| 422 | 428 | }else{ |
| 423 | 429 | style_header("Add A New User"); |
| 424 | 430 | } |
| 425 | - @ <table align="left" hspace="20" vspace="10"><tr><td> | |
| 426 | - @ <form action="%s(g.zPath)" method="POST"> | |
| 431 | + @ <div class="ueditCapBox"> | |
| 432 | + @ <form action="%s(g.zPath)" method="post"><div> | |
| 427 | 433 | login_insert_csrf_secret(); |
| 428 | 434 | @ <table> |
| 429 | 435 | @ <tr> |
| 430 | - @ <td align="right"><nobr>User ID:</nobr></td> | |
| 431 | - if( uid ){ | |
| 432 | - @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)"></td> | |
| 433 | - }else{ | |
| 434 | - @ <td>(new user)<input type="hidden" name="id" value=0></td> | |
| 435 | - } | |
| 436 | - @ </tr> | |
| 437 | - @ <tr> | |
| 438 | - @ <td align="right"><nobr>Login:</nobr></td> | |
| 439 | - @ <td><input type="text" name="login" value="%h(zLogin)"></td> | |
| 440 | - @ </tr> | |
| 441 | - @ <tr> | |
| 442 | - @ <td align="right"><nobr>Contact Info:</nobr></td> | |
| 443 | - @ <td><input type="text" name="info" size=40 value="%h(zInfo)"></td> | |
| 444 | - @ </tr> | |
| 445 | - @ <tr> | |
| 446 | - @ <td align="right" valign="top">Capabilities:</td> | |
| 436 | + @ <td class="usetupEditLabel">User ID:</td> | |
| 437 | + if( uid ){ | |
| 438 | + @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td> | |
| 439 | + }else{ | |
| 440 | + @ <td>(new user)<input type="hidden" name="id" value="0" /></td> | |
| 441 | + } | |
| 442 | + @ </tr> | |
| 443 | + @ <tr> | |
| 444 | + @ <td class="usetupEditLabel">Login:</td> | |
| 445 | + @ <td><input type="text" name="login" value="%h(zLogin)" /></td> | |
| 446 | + @ </tr> | |
| 447 | + @ <tr> | |
| 448 | + @ <td class="usetupEditLabel">Contact Info:</td> | |
| 449 | + @ <td><input type="text" name="info" size="40" value="%h(zInfo)" /></td> | |
| 450 | + @ </tr> | |
| 451 | + @ <tr> | |
| 452 | + @ <td class="usetupEditLabel">Capabilities:</td> | |
| 447 | 453 | @ <td> |
| 448 | 454 | #define B(x) inherit[x] |
| 449 | 455 | if( g.okSetup ){ |
| 450 | - @ <input type="checkbox" name="as"%s(oas)/>%s(B('s'))Setup<br> | |
| 451 | - } | |
| 452 | - @ <input type="checkbox" name="aa"%s(oaa)/>%s(B('a'))Admin<br> | |
| 453 | - @ <input type="checkbox" name="ad"%s(oad)/>%s(B('d'))Delete<br> | |
| 454 | - @ <input type="checkbox" name="ae"%s(oae)/>%s(B('e'))Email<br> | |
| 455 | - @ <input type="checkbox" name="ap"%s(oap)/>%s(B('p'))Password<br> | |
| 456 | - @ <input type="checkbox" name="ai"%s(oai)/>%s(B('i'))Check-In<br> | |
| 457 | - @ <input type="checkbox" name="ao"%s(oao)/>%s(B('o'))Check-Out<br> | |
| 458 | - @ <input type="checkbox" name="ah"%s(oah)/>%s(B('h'))History<br> | |
| 459 | - @ <input type="checkbox" name="au"%s(oau)/>%s(B('u'))Reader<br> | |
| 460 | - @ <input type="checkbox" name="av"%s(oav)/>%s(B('v'))Developer<br> | |
| 461 | - @ <input type="checkbox" name="ag"%s(oag)/>%s(B('g'))Clone<br> | |
| 462 | - @ <input type="checkbox" name="aj"%s(oaj)/>%s(B('j'))Read Wiki<br> | |
| 463 | - @ <input type="checkbox" name="af"%s(oaf)/>%s(B('f'))New Wiki<br> | |
| 464 | - @ <input type="checkbox" name="am"%s(oam)/>%s(B('m'))Append Wiki<br> | |
| 465 | - @ <input type="checkbox" name="ak"%s(oak)/>%s(B('k'))Write Wiki<br> | |
| 466 | - @ <input type="checkbox" name="ab"%s(oab)/>%s(B('b'))Attachments<br> | |
| 467 | - @ <input type="checkbox" name="ar"%s(oar)/>%s(B('r'))Read Ticket<br> | |
| 468 | - @ <input type="checkbox" name="an"%s(oan)/>%s(B('n'))New Ticket<br> | |
| 469 | - @ <input type="checkbox" name="ac"%s(oac)/>%s(B('c'))Append Ticket<br> | |
| 470 | - @ <input type="checkbox" name="aw"%s(oaw)/>%s(B('w'))Write Ticket<br> | |
| 471 | - @ <input type="checkbox" name="at"%s(oat)/>%s(B('t'))Ticket Report<br> | |
| 472 | - @ <input type="checkbox" name="az"%s(oaz)/>%s(B('z'))Download Zip | |
| 456 | + @ <input type="checkbox" name="as"%s(oas) />%s(B('s'))Setup<br /> | |
| 457 | + } | |
| 458 | + @ <input type="checkbox" name="aa"%s(oaa) />%s(B('a'))Admin<br /> | |
| 459 | + @ <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br /> | |
| 460 | + @ <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br /> | |
| 461 | + @ <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br /> | |
| 462 | + @ <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br /> | |
| 463 | + @ <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br /> | |
| 464 | + @ <input type="checkbox" name="ah"%s(oah) />%s(B('h'))History<br /> | |
| 465 | + @ <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br /> | |
| 466 | + @ <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br /> | |
| 467 | + @ <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br /> | |
| 468 | + @ <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br /> | |
| 469 | + @ <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br /> | |
| 470 | + @ <input type="checkbox" name="am"%s(oam) />%s(B('m'))Append Wiki<br /> | |
| 471 | + @ <input type="checkbox" name="ak"%s(oak) />%s(B('k'))Write Wiki<br /> | |
| 472 | + @ <input type="checkbox" name="ab"%s(oab) />%s(B('b'))Attachments<br /> | |
| 473 | + @ <input type="checkbox" name="ar"%s(oar) />%s(B('r'))Read Ticket<br /> | |
| 474 | + @ <input type="checkbox" name="an"%s(oan) />%s(B('n'))New Ticket<br /> | |
| 475 | + @ <input type="checkbox" name="ac"%s(oac) />%s(B('c'))Append Ticket<br /> | |
| 476 | + @ <input type="checkbox" name="aw"%s(oaw) />%s(B('w'))Write Ticket<br /> | |
| 477 | + @ <input type="checkbox" name="at"%s(oat) />%s(B('t'))Ticket Report<br /> | |
| 478 | + @ <input type="checkbox" name="az"%s(oaz) />%s(B('z'))Download Zip | |
| 473 | 479 | @ </td> |
| 474 | 480 | @ </tr> |
| 475 | 481 | @ <tr> |
| 476 | 482 | @ <td align="right">Password:</td> |
| 477 | 483 | if( zPw[0] ){ |
| 478 | 484 | /* Obscure the password for all users */ |
| 479 | - @ <td><input type="password" name="pw" value="**********"></td> | |
| 485 | + @ <td><input type="password" name="pw" value="**********" /></td> | |
| 480 | 486 | }else{ |
| 481 | 487 | /* Show an empty password as an empty input field */ |
| 482 | - @ <td><input type="password" name="pw" value=""></td> | |
| 488 | + @ <td><input type="password" name="pw" value="" /></td> | |
| 483 | 489 | } |
| 484 | 490 | @ </tr> |
| 485 | 491 | if( !higherUser ){ |
| 486 | 492 | @ <tr> |
| 487 | - @ <td> </td> | |
| 488 | - @ <td><input type="submit" name="submit" value="Apply Changes"> | |
| 493 | + @ <td> </td> | |
| 494 | + @ <td><input type="submit" name="submit" value="Apply Changes" /></td> | |
| 489 | 495 | @ </tr> |
| 490 | 496 | } |
| 491 | - @ </table></td></tr></table> | |
| 497 | + @ </table> | |
| 498 | + @ </div></form> | |
| 499 | + @ </div> | |
| 492 | 500 | @ <h2>Privileges And Capabilities:</h2> |
| 493 | 501 | @ <ul> |
| 494 | 502 | if( higherUser ){ |
| 495 | 503 | @ <li><p><font color="blue"><b> |
| 496 | 504 | @ User %h(zLogin) has Setup privileges and you only have Admin privileges |
| @@ -497,95 +505,114 @@ | ||
| 497 | 505 | @ so you are not permitted to make changes to %h(zLogin). |
| 498 | 506 | @ </b></font></p></li> |
| 499 | 507 | @ |
| 500 | 508 | } |
| 501 | 509 | @ <li><p> |
| 502 | - @ The <b>Setup</b> user can make arbitrary configuration changes. | |
| 503 | - @ An <b>Admin</b> user can add other users and change user privileges | |
| 510 | + @ The <span class="capability">Setup</span> user can make arbitrary | |
| 511 | + @ configuration changes. An <span class="usertype">Admin</span> user | |
| 512 | + @ can add other users and change user privileges | |
| 504 | 513 | @ and reset user passwords. Both automatically get all other privileges |
| 505 | 514 | @ listed below. Use these two settings with discretion. |
| 506 | 515 | @ </p></li> |
| 507 | 516 | @ |
| 508 | 517 | @ <li><p> |
| 509 | - @ The "<font color="green"><big>•</big></font>" mark indicates | |
| 510 | - @ the privileges of "nobody" that are available to all users | |
| 511 | - @ regardless of whether or not they are logged in. | |
| 512 | - @ </p></li> | |
| 513 | - @ | |
| 514 | - @ <li><p> | |
| 515 | - @ The "<font color="blue"><big>•</big></font>" mark indicates | |
| 516 | - @ the privileges of "anonymous" that are inherited by all logged-in users. | |
| 517 | - @ </p></li> | |
| 518 | - @ | |
| 519 | - @ <li><p> | |
| 520 | - @ The "<font color="red"><big>•</big></font>" mark indicates | |
| 521 | - @ the privileges of "developer" that are inherited by all users with | |
| 522 | - @ the <b>Developer</b> privilege. | |
| 523 | - @ </p></li> | |
| 524 | - @ | |
| 525 | - @ <li><p> | |
| 526 | - @ The "<font color="black"><big>•</big></font>" mark indicates | |
| 527 | - @ the privileges of "reader" that are inherited by all users with | |
| 528 | - @ the <b>Reader</b> privilege. | |
| 529 | - @ </p></li> | |
| 530 | - @ | |
| 531 | - @ <li><p> | |
| 532 | - @ The <b>Delete</b> privilege give the user the ability to erase | |
| 533 | - @ wiki, tickets, and attachments that have been added by anonymous | |
| 534 | - @ users. This capability is intended for deletion of spam. The | |
| 535 | - @ delete capability is only in effect for 24 hours after the item | |
| 536 | - @ is first posted. The Setup user can delete anything at any time. | |
| 537 | - @ </p></li> | |
| 538 | - @ | |
| 539 | - @ <li><p> | |
| 540 | - @ The <b>History</b> privilege allows a user to see most hyperlinks. | |
| 541 | - @ This is recommended ON for most logged-in users but OFF for | |
| 542 | - @ user "nobody" to avoid problems with spiders trying to walk every | |
| 543 | - @ historical version of every baseline and file. | |
| 544 | - @ </p></li> | |
| 545 | - @ | |
| 546 | - @ <li><p> | |
| 547 | - @ The <b>Zip</b> privilege allows a user to see the "download as ZIP" | |
| 548 | - @ hyperlink and permits access to the <tt>/zip</tt> page. This allows | |
| 549 | - @ users to download ZIP archives without granting other rights like | |
| 550 | - @ <b>Read</b> or <b>History</b>. This privilege is recommended for | |
| 551 | - @ user <b>nobody</b> so that automatic package downloaders can obtain | |
| 552 | - @ the sources without going through the login procedure. | |
| 553 | - @ </p></li> | |
| 554 | - @ | |
| 555 | - @ <li><p> | |
| 556 | - @ The <b>Check-in</b> privilege allows remote users to "push". | |
| 557 | - @ The <b>Check-out</b> privilege allows remote users to "pull". | |
| 558 | - @ The <b>Clone</b> privilege allows remote users to "clone". | |
| 559 | - @ </li><p> | |
| 560 | - @ | |
| 561 | - @ <li><p> | |
| 562 | - @ The <b>Read Wiki</b>, <b>New Wiki</b>, <b>Append Wiki</b>, and | |
| 563 | - @ <b>Write Wiki</b> privileges control access to wiki pages. The | |
| 564 | - @ <b>Read Ticket</b>, <b>New Ticket</b>, <b>Append Ticket</b>, and | |
| 565 | - @ <b>Write Ticket</b> privileges control access to trouble tickets. | |
| 566 | - @ The <b>Ticket Report</b> privilege allows the user to create or edit | |
| 567 | - @ ticket report formats. | |
| 568 | - @ </p></li> | |
| 569 | - @ | |
| 570 | - @ <li><p> | |
| 571 | - @ Users with the <b>Password</b> privilege are allowed to change their | |
| 572 | - @ own password. Recommended ON for most users but OFF for special | |
| 573 | - @ users "developer", "anonymous", and "nobody". | |
| 574 | - @ </p></li> | |
| 575 | - @ | |
| 576 | - @ <li><p> | |
| 577 | - @ The <b>EMail</b> privilege allows the display of sensitive information | |
| 578 | - @ such as the email address of users and contact information on tickets. | |
| 579 | - @ Recommended OFF for "anonymous" and for "nobody" but ON for | |
| 580 | - @ "developer". | |
| 581 | - @ </p></li> | |
| 582 | - @ | |
| 583 | - @ <li><p> | |
| 584 | - @ The <b>Attachment</b> privilege is needed in order to add attachments | |
| 585 | - @ to tickets or wiki. Write privilege on the ticket or wiki is also | |
| 586 | - @ required.</p></li> | |
| 518 | + @ The "<span class="ueditInheritNobody"><big>•</big></span>" mark | |
| 519 | + @ indicates the privileges of <span class="usertype">nobody</span> that | |
| 520 | + @ are available to all users regardless of whether or not they are logged in. | |
| 521 | + @ </p></li> | |
| 522 | + @ | |
| 523 | + @ <li><p> | |
| 524 | + @ The "<span class="ueditInheritAnonymous"><big>•</big></span>" mark | |
| 525 | + @ indicates the privileges of <span class="usertype">anonymous</span> that | |
| 526 | + @ are inherited by all logged-in users. | |
| 527 | + @ </p></li> | |
| 528 | + @ | |
| 529 | + @ <li><p> | |
| 530 | + @ The "<span class="ueditInheritDeveloper"><big>•</big></span>" mark | |
| 531 | + @ indicates the privileges of <span class="usertype">developer</span> that | |
| 532 | + @ are inherited by all users with the | |
| 533 | + @ <span class="capability">Developer</span> privilege. | |
| 534 | + @ </p></li> | |
| 535 | + @ | |
| 536 | + @ <li><p> | |
| 537 | + @ The "<span class="ueditInheritReader"><big>•</big></span>" mark | |
| 538 | + @ indicates the privileges of <span class="usertype">reader</span> that | |
| 539 | + @ are inherited by all users with the <span class="capability">Reader</span> | |
| 540 | + @ privilege. | |
| 541 | + @ </p></li> | |
| 542 | + @ | |
| 543 | + @ <li><p> | |
| 544 | + @ The <span class="capability">Delete</span> privilege give the user the | |
| 545 | + @ ability to erase wiki, tickets, and attachments that have been added | |
| 546 | + @ by anonymous users. This capability is intended for deletion of spam. | |
| 547 | + @ The delete capability is only in effect for 24 hours after the item | |
| 548 | + @ is first posted. The <span class="usertype">Setup</span> user can | |
| 549 | + @ delete anything at any time. | |
| 550 | + @ </p></li> | |
| 551 | + @ | |
| 552 | + @ <li><p> | |
| 553 | + @ The <span class="capability">History</span> privilege allows a user | |
| 554 | + @ to see most hyperlinks. This is recommended ON for most logged-in users | |
| 555 | + @ but OFF for user "nobody" to avoid problems with spiders trying to walk | |
| 556 | + @ every historical version of every baseline and file. | |
| 557 | + @ </p></li> | |
| 558 | + @ | |
| 559 | + @ <li><p> | |
| 560 | + @ The <span class="capability">Zip</span> privilege allows a user to | |
| 561 | + @ see the "download as ZIP" | |
| 562 | + @ hyperlink and permits access to the <tt>/zip</tt> page. This allows | |
| 563 | + @ users to download ZIP archives without granting other rights like | |
| 564 | + @ <span class="capability">Read</span> or | |
| 565 | + @ <span class="capability">History</span>. This privilege is recommended for | |
| 566 | + @ user <span class="usertype">nobody</span> so that automatic package | |
| 567 | + @ downloaders can obtain the sources without going through the login | |
| 568 | + @ procedure. | |
| 569 | + @ </p></li> | |
| 570 | + @ | |
| 571 | + @ <li><p> | |
| 572 | + @ The <span class="capability">Check-in</span> privilege allows remote | |
| 573 | + @ users to "push". The <span class="capability">Check-out</span> privilege | |
| 574 | + @ allows remote users to "pull". The <span class="capability">Clone</span> | |
| 575 | + @ privilege allows remote users to "clone". | |
| 576 | + @ </p></li> | |
| 577 | + @ | |
| 578 | + @ <li><p> | |
| 579 | + @ The <span class="capability">Read Wiki</span>, | |
| 580 | + @ <span class="capability">New Wiki</span>, | |
| 581 | + @ <span class="capability">Append Wiki</span>, and | |
| 582 | + @ <b>Write Wiki</b> privileges control access to wiki pages. The | |
| 583 | + @ <span class="capability">Read Ticket</span>, | |
| 584 | + @ <span class="capability">New Ticket</span>, | |
| 585 | + @ <span class="capability">Append Ticket</span>, and | |
| 586 | + @ <span class="capability">Write Ticket</span> privileges control access | |
| 587 | + @ to trouble tickets. | |
| 588 | + @ The <span class="capability">Ticket Report</span> privilege allows | |
| 589 | + @ the user to create or edit ticket report formats. | |
| 590 | + @ </p></li> | |
| 591 | + @ | |
| 592 | + @ <li><p> | |
| 593 | + @ Users with the <span class="capability">Password</span> privilege | |
| 594 | + @ are allowed to change their own password. Recommended ON for most | |
| 595 | + @ users but OFF for special users <span class="usertype">developer</span>, | |
| 596 | + @ <span class="usertype">anonymous</span>, | |
| 597 | + @ and <span class="usertype">nobody</span>. | |
| 598 | + @ </p></li> | |
| 599 | + @ | |
| 600 | + @ <li><p> | |
| 601 | + @ The <span class="capability">EMail</span> privilege allows the display of | |
| 602 | + @ sensitive information such as the email address of users and contact | |
| 603 | + @ information on tickets. Recommended OFF for | |
| 604 | + @ <span class="usertype">anonymousy</span> and for | |
| 605 | + @ <span class="usertype">nobody</span> but ON for | |
| 606 | + @ <span class="usertype">developer</span>. | |
| 607 | + @ </p></li> | |
| 608 | + @ | |
| 609 | + @ <li><p> | |
| 610 | + @ The <span class="capability">Attachment</span> privilege is needed in | |
| 611 | + @ order to add attachments to tickets or wiki. Write privilege on the | |
| 612 | + @ ticket or wiki is also required. | |
| 613 | + @ </p></li> | |
| 587 | 614 | @ |
| 588 | 615 | @ <li><p> |
| 589 | 616 | @ Login is prohibited if the password is an empty string. |
| 590 | 617 | @ </p></li> |
| 591 | 618 | @ </ul> |
| @@ -592,42 +619,46 @@ | ||
| 592 | 619 | @ |
| 593 | 620 | @ <h2>Special Logins</h2> |
| 594 | 621 | @ |
| 595 | 622 | @ <ul> |
| 596 | 623 | @ <li><p> |
| 597 | - @ No login is required for user "<b>nobody</b>". The capabilities | |
| 598 | - @ of the <b>nobody</b> user are inherited by all users, regardless of | |
| 599 | - @ whether or not they are logged in. To disable universal access | |
| 600 | - @ to the repository, make sure no user named "<b>nobody</b>" exists or | |
| 601 | - @ that the <b>nobody</b> user has no capabilities enabled. | |
| 602 | - @ The password for <b>nobody</b> is ignore. To avoid problems with | |
| 603 | - @ spiders overloading the server, it is recommended | |
| 604 | - @ that the 'h' (History) capability be turned off for the <b>nobody</b> | |
| 605 | - @ user. | |
| 606 | - @ </p></li> | |
| 607 | - @ | |
| 608 | - @ <li><p> | |
| 609 | - @ Login is required for user "<b>anonymous</b>" but the password | |
| 610 | - @ is displayed on the login screen beside the password entry box | |
| 611 | - @ so anybody who can read should be able to login as anonymous. | |
| 612 | - @ On the other hand, spiders and web-crawlers will typically not | |
| 613 | - @ be able to login. Set the capabilities of the anonymous user | |
| 614 | - @ to things that you want any human to be able to do, but not any | |
| 615 | - @ spider. Every other logged-in user inherits the privileges of | |
| 616 | - @ <b>anonymous</b>. | |
| 617 | - @ </p></li> | |
| 618 | - @ | |
| 619 | - @ <li><p> | |
| 620 | - @ The "<b>developer</b>" user is intended as a template for trusted users | |
| 621 | - @ with check-in privileges. When adding new trusted users, simply | |
| 622 | - @ select the <b>Developer</b> privilege to cause the new user to inherit | |
| 623 | - @ all privileges of the "developer" user. Similarly, the "<b>reader</b>" | |
| 624 | - @ user is a template for users who are allowed more access than anonymous, | |
| 625 | - @ but less than a developer. | |
| 626 | - @ </p></li> | |
| 627 | - @ </ul> | |
| 628 | - @ </form> | |
| 624 | + @ No login is required for user <span class="usertype">nobody</span>. The | |
| 625 | + @ capabilities of the <span class="usertype">nobody</span> user are | |
| 626 | + @ inherited by all users, regardless of whether or not they are logged in. | |
| 627 | + @ To disable universal access to the repository, make sure no user named | |
| 628 | + @ <span class="usertype">nobody</span> exists or that the | |
| 629 | + @ <span class="usertype">nobody</span> user has no capabilities | |
| 630 | + @ enabled. The password for <span class="usertype">nobody</span> is ignore. | |
| 631 | + @ To avoid problems with spiders overloading the server, it is recommended | |
| 632 | + @ that the <span class="capability">h</span> (History) capability be turned | |
| 633 | + @ off for the <span class="usertype">nobody</span> user. | |
| 634 | + @ </p></li> | |
| 635 | + @ | |
| 636 | + @ <li><p> | |
| 637 | + @ Login is required for user <span class="usertype">anonymous</span> but the | |
| 638 | + @ password is displayed on the login screen beside the password entry box | |
| 639 | + @ so anybody who can read should be able to login as anonymous. | |
| 640 | + @ On the other hand, spiders and web-crawlers will typically not | |
| 641 | + @ be able to login. Set the capabilities of the | |
| 642 | + @ <span class="usertype">anonymous</span> | |
| 643 | + @ user to things that you want any human to be able to do, but not any | |
| 644 | + @ spider. Every other logged-in user inherits the privileges of | |
| 645 | + @ <span class="usertype">anonymous</span>. | |
| 646 | + @ </p></li> | |
| 647 | + @ | |
| 648 | + @ <li><p> | |
| 649 | + @ The <span class="usertype">developer</span> user is intended as a template | |
| 650 | + @ for trusted users with check-in privileges. When adding new trusted users, | |
| 651 | + @ simply select the <span class="capability">developer</span> privilege to | |
| 652 | + @ cause the new user to inherit all privileges of the | |
| 653 | + @ <span class="usertype">developer</span> | |
| 654 | + @ user. Similarly, the <span class="usertype">reader</span> user is a | |
| 655 | + @ template for users who are allowed more access than | |
| 656 | + @ <span class="usertype">anonymous</span>, | |
| 657 | + @ but less than a <span class="usertype">developer</span>. | |
| 658 | + @ </p></li> | |
| 659 | + @ </ul> | |
| 629 | 660 | style_footer(); |
| 630 | 661 | } |
| 631 | 662 | |
| 632 | 663 | |
| 633 | 664 | /* |
| @@ -651,13 +682,14 @@ | ||
| 651 | 682 | db_set(zVar, iQ ? "1" : "0", 0); |
| 652 | 683 | iVal = iQ; |
| 653 | 684 | } |
| 654 | 685 | } |
| 655 | 686 | if( iVal ){ |
| 656 | - @ <input type="checkbox" name="%s(zQParm)" checked><b>%s(zLabel)</b></input> | |
| 687 | + @ <input type="checkbox" name="%s(zQParm)" checked="checked" /> | |
| 688 | + @ <b>%s(zLabel)</b> | |
| 657 | 689 | }else{ |
| 658 | - @ <input type="checkbox" name="%s(zQParm)"><b>%s(zLabel)</b></input> | |
| 690 | + @ <input type="checkbox" name="%s(zQParm)" /><b>%s(zLabel)</b> | |
| 659 | 691 | } |
| 660 | 692 | } |
| 661 | 693 | |
| 662 | 694 | /* |
| 663 | 695 | ** Generate an entry box for an attribute. |
| @@ -674,11 +706,11 @@ | ||
| 674 | 706 | if( zQ && strcmp(zQ,zVal)!=0 ){ |
| 675 | 707 | login_verify_csrf_secret(); |
| 676 | 708 | db_set(zVar, zQ, 0); |
| 677 | 709 | zVal = zQ; |
| 678 | 710 | } |
| 679 | - @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)"> | |
| 711 | + @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" /> | |
| 680 | 712 | @ <b>%s(zLabel)</b> |
| 681 | 713 | } |
| 682 | 714 | |
| 683 | 715 | /* |
| 684 | 716 | ** Generate a text box for an attribute. |
| @@ -698,11 +730,12 @@ | ||
| 698 | 730 | db_set(zVar, zQ, 0); |
| 699 | 731 | z = zQ; |
| 700 | 732 | } |
| 701 | 733 | if( rows>0 && cols>0 ){ |
| 702 | 734 | @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea> |
| 703 | - @ <b>%s(zLabel)</b> | |
| 735 | + if (zLabel && *zLabel) | |
| 736 | + @ <span class="textareaLabel">%s(zLabel)</span> | |
| 704 | 737 | } |
| 705 | 738 | } |
| 706 | 739 | |
| 707 | 740 | |
| 708 | 741 | /* |
| @@ -714,57 +747,57 @@ | ||
| 714 | 747 | login_needed(); |
| 715 | 748 | } |
| 716 | 749 | |
| 717 | 750 | style_header("Access Control Settings"); |
| 718 | 751 | db_begin_transaction(); |
| 719 | - @ <form action="%s(g.zBaseURL)/setup_access" method="POST"> | |
| 752 | + @ <form action="%s(g.zBaseURL)/setup_access" method="post"><div> | |
| 720 | 753 | login_insert_csrf_secret(); |
| 721 | - @ <hr> | |
| 754 | + @ <hr /> | |
| 722 | 755 | onoff_attribute("Require password for local access", |
| 723 | 756 | "localauth", "localauth", 0); |
| 724 | 757 | @ <p>When enabled, the password sign-in is required for |
| 725 | 758 | @ web access coming from 127.0.0.1. When disabled, web access |
| 726 | 759 | @ from 127.0.0.1 is allows without any login - the user id is selected |
| 727 | 760 | @ from the ~/.fossil database. Password login is always required |
| 728 | 761 | @ for incoming web connections on internet addresses other than |
| 729 | - @ 127.0.0.1.</p></li> | |
| 762 | + @ 127.0.0.1.</p> | |
| 730 | 763 | |
| 731 | - @ <hr> | |
| 764 | + @ <hr /> | |
| 732 | 765 | onoff_attribute("Allow REMOTE_USER authentication", |
| 733 | 766 | "remote_user_ok", "remote_user_ok", 0); |
| 734 | 767 | @ <p>When enabled, if the REMOTE_USER environment variable is set to the |
| 735 | 768 | @ login name of a valid user and no other login credentials are available, |
| 736 | 769 | @ then the REMOTE_USER is accepted as an authenticated user. |
| 737 | - @ </p></li> | |
| 770 | + @ </p> | |
| 738 | 771 | |
| 739 | - @ <hr> | |
| 772 | + @ <hr /> | |
| 740 | 773 | entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766"); |
| 741 | 774 | @ <p>The number of hours for which a login is valid. This must be a |
| 742 | 775 | @ positive number. The default is 8760 hours which is approximately equal |
| 743 | 776 | @ to a year.</p> |
| 744 | 777 | |
| 745 | - @ <hr> | |
| 778 | + @ <hr /> | |
| 746 | 779 | entry_attribute("Download packet limit", 10, "max-download", "mxdwn", |
| 747 | 780 | "5000000"); |
| 748 | 781 | @ <p>Fossil tries to limit out-bound sync, clone, and pull packets |
| 749 | 782 | @ to this many bytes, uncompressed. If the client requires more data |
| 750 | 783 | @ than this, then the client will issue multiple HTTP requests. |
| 751 | 784 | @ Values below 1 million are not recommended. 5 million is a |
| 752 | 785 | @ reasonable number.</p> |
| 753 | 786 | |
| 754 | - @ <hr> | |
| 787 | + @ <hr /> | |
| 755 | 788 | onoff_attribute("Show javascript button to fill in CAPTCHA", |
| 756 | 789 | "auto-captcha", "autocaptcha", 0); |
| 757 | 790 | @ <p>When enabled, a button appears on the login screen for user |
| 758 | 791 | @ "anonymous" that will automatically fill in the CAPTCHA password. |
| 759 | 792 | @ This is less secure that forcing the user to do it manually, but is |
| 760 | 793 | @ probably secure enough and it is certainly more convenient for |
| 761 | 794 | @ anonymous users.</p> |
| 762 | 795 | |
| 763 | - @ <hr> | |
| 764 | - @ <p><input type="submit" name="submit" value="Apply Changes"></p> | |
| 765 | - @ </form> | |
| 796 | + @ <hr /> | |
| 797 | + @ <p><input type="submit" name="submit" value="Apply Changes" /></p> | |
| 798 | + @ </div></form> | |
| 766 | 799 | db_end_transaction(0); |
| 767 | 800 | style_footer(); |
| 768 | 801 | } |
| 769 | 802 | |
| 770 | 803 | /* |
| @@ -776,42 +809,42 @@ | ||
| 776 | 809 | login_needed(); |
| 777 | 810 | } |
| 778 | 811 | |
| 779 | 812 | style_header("Timeline Display Preferences"); |
| 780 | 813 | db_begin_transaction(); |
| 781 | - @ <form action="%s(g.zBaseURL)/setup_timeline" method="POST"> | |
| 814 | + @ <form action="%s(g.zBaseURL)/setup_timeline" method="post"><div> | |
| 782 | 815 | login_insert_csrf_secret(); |
| 783 | 816 | |
| 784 | - @ <hr> | |
| 817 | + @ <hr /> | |
| 785 | 818 | onoff_attribute("Allow block-markup in timeline", |
| 786 | 819 | "timeline-block-markup", "tbm", 0); |
| 787 | 820 | @ <p>In timeline displays, check-in comments can be displayed with or |
| 788 | 821 | @ without block markup (paragraphs, tables, etc.)</p> |
| 789 | 822 | |
| 790 | - @ <hr> | |
| 823 | + @ <hr /> | |
| 791 | 824 | onoff_attribute("Use Universal Coordinated Time (UTC)", |
| 792 | 825 | "timeline-utc", "utc", 1); |
| 793 | 826 | @ <p>Show times as UTC (also sometimes called Greenwich Mean Time (GMT) or |
| 794 | 827 | @ Zulu) instead of in local time.</p> |
| 795 | 828 | |
| 796 | - @ <hr> | |
| 829 | + @ <hr /> | |
| 797 | 830 | onoff_attribute("Show version differences by default", |
| 798 | 831 | "show-version-diffs", "vdiff", 0); |
| 799 | 832 | @ <p>On the version-information pages linked from the timeline can either |
| 800 | 833 | @ show complete diffs of all file changes, or can just list the names of |
| 801 | 834 | @ the files that have changed. Users can get to either page by |
| 802 | 835 | @ clicking. This setting selects the default.</p> |
| 803 | 836 | |
| 804 | - @ <hr> | |
| 837 | + @ <hr /> | |
| 805 | 838 | entry_attribute("Max timeline comment length", 6, |
| 806 | 839 | "timeline-max-comment", "tmc", "0"); |
| 807 | 840 | @ <p>The maximum length of a comment to be displayed in a timeline. |
| 808 | 841 | @ "0" there is no length limit.</p> |
| 809 | 842 | |
| 810 | - @ <hr> | |
| 811 | - @ <p><input type="submit" name="submit" value="Apply Changes"></p> | |
| 812 | - @ </form> | |
| 843 | + @ <hr /> | |
| 844 | + @ <p><input type="submit" name="submit" value="Apply Changes" /></p> | |
| 845 | + @ </div></form> | |
| 813 | 846 | db_end_transaction(0); |
| 814 | 847 | style_footer(); |
| 815 | 848 | } |
| 816 | 849 | |
| 817 | 850 | /* |
| @@ -823,11 +856,11 @@ | ||
| 823 | 856 | login_needed(); |
| 824 | 857 | } |
| 825 | 858 | |
| 826 | 859 | style_header("WWW Configuration"); |
| 827 | 860 | db_begin_transaction(); |
| 828 | - @ <form action="%s(g.zBaseURL)/setup_config" method="POST"> | |
| 861 | + @ <form action="%s(g.zBaseURL)/setup_config" method="post"><div> | |
| 829 | 862 | login_insert_csrf_secret(); |
| 830 | 863 | @ <hr /> |
| 831 | 864 | entry_attribute("Project Name", 60, "project-name", "pn", ""); |
| 832 | 865 | @ <p>Give your project a name so visitors know what this site is about. |
| 833 | 866 | @ The project name will also be used as the RSS feed title.</p> |
| @@ -840,36 +873,37 @@ | ||
| 840 | 873 | entry_attribute("Index Page", 60, "index-page", "idxpg", "/home"); |
| 841 | 874 | @ <p>Enter the pathname of the page to display when the "Home" menu |
| 842 | 875 | @ option is selected and when no pathname is |
| 843 | 876 | @ specified in the URL. For example, if you visit the url:</p> |
| 844 | 877 | @ |
| 845 | - @ <blockquote>%h(g.zBaseURL)</blockquote> | |
| 878 | + @ <blockquote><p>%h(g.zBaseURL)</p></blockquote> | |
| 846 | 879 | @ |
| 847 | 880 | @ <p>And you have specified an index page of "/home" the above will |
| 848 | 881 | @ automatically redirect to:</p> |
| 849 | 882 | @ |
| 850 | - @ <blockquote>%h(g.zBaseURL)/home</blockquote> | |
| 883 | + @ <blockquote><p>%h(g.zBaseURL)/home</p></blockquote> | |
| 851 | 884 | @ |
| 852 | 885 | @ <p>The default "/home" page displays a Wiki page with the same name |
| 853 | 886 | @ as the Project Name specified above. Some sites prefer to redirect |
| 854 | 887 | @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p> |
| 855 | 888 | @ <hr /> |
| 856 | 889 | onoff_attribute("Use HTML as wiki markup language", |
| 857 | 890 | "wiki-use-html", "wiki-use-html", 0); |
| 858 | - @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed but | |
| 859 | - @ all other wiki formatting will be ignored. This option is helpful if you have | |
| 860 | - @ chosen to use a rich HTML editor for wiki markup such as TinyMCE.</p> | |
| 891 | + @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed | |
| 892 | + @ but all other wiki formatting will be ignored. This option is helpful | |
| 893 | + @ if you have chosen to use a rich HTML editor for wiki markup such as | |
| 894 | + @ TinyMCE.</p> | |
| 861 | 895 | @ <p><strong>CAUTION:</strong> when |
| 862 | 896 | @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki. |
| 863 | 897 | @ No sanitization is done. This means that it is very possible for malicious |
| 864 | 898 | @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p> |
| 865 | 899 | @ <p>This should <strong>only</strong> be enabled when wiki editing is limited |
| 866 | 900 | @ to trusted users. It should <strong>not</strong> be used on a publically |
| 867 | 901 | @ editable wiki.</p> |
| 868 | 902 | @ <hr /> |
| 869 | - @ <p><input type="submit" name="submit" value="Apply Changes"></p> | |
| 870 | - @ </form> | |
| 903 | + @ <p><input type="submit" name="submit" value="Apply Changes" /></p> | |
| 904 | + @ </div></form> | |
| 871 | 905 | db_end_transaction(0); |
| 872 | 906 | style_footer(); |
| 873 | 907 | } |
| 874 | 908 | |
| 875 | 909 | /* |
| @@ -892,30 +926,27 @@ | ||
| 892 | 926 | if( P("submit")!=0 ){ |
| 893 | 927 | db_end_transaction(0); |
| 894 | 928 | cgi_redirect("setup_editcss"); |
| 895 | 929 | } |
| 896 | 930 | style_header("Edit CSS"); |
| 897 | - @ <form action="%s(g.zBaseURL)/setup_editcss" method="POST"> | |
| 931 | + @ <form action="%s(g.zBaseURL)/setup_editcss" method="post"><div> | |
| 898 | 932 | login_insert_csrf_secret(); |
| 899 | 933 | @ Edit the CSS below:<br /> |
| 900 | 934 | textarea_attribute("", 40, 80, "css", "css", zDefaultCSS); |
| 901 | 935 | @ <br /> |
| 902 | - @ <input type="submit" name="submit" value="Apply Changes"> | |
| 903 | - @ <input type="submit" name="clear" value="Revert To Default"> | |
| 904 | - @ </form> | |
| 905 | - @ <p><b>Note:</b> Press your browser Reload button after modifying the | |
| 906 | - @ CSS in order to pull in the modified CSS file.</p> | |
| 907 | - @ <hr> | |
| 936 | + @ <input type="submit" name="submit" value="Apply Changes" /> | |
| 937 | + @ <input type="submit" name="clear" value="Revert To Default" /> | |
| 938 | + @ </div></form> | |
| 939 | + @ <p><span class="note">Note:</span> Press your browser Reload button after | |
| 940 | + @ modifying the CSS in order to pull in the modified CSS file.</p> | |
| 941 | + @ <hr /> | |
| 908 | 942 | @ The default CSS is shown below for reference. Other examples |
| 909 | 943 | @ of CSS files can be seen on the <a href="setup_skin">skins page</a>. |
| 910 | 944 | @ See also the <a href="setup_header">header</a> and |
| 911 | 945 | @ <a href="setup_footer">footer</a> editing screens. |
| 912 | 946 | @ <blockquote><pre> |
| 913 | - @ %h(zDefaultCSS) | |
| 914 | - @ %h(zTableLabelValueCSS) | |
| 915 | - @ %h(zDivSidebox) | |
| 916 | - @ %h(zDivSideboxTitle) | |
| 947 | + cgi_append_default_css(); | |
| 917 | 948 | @ </pre></blockquote> |
| 918 | 949 | style_footer(); |
| 919 | 950 | db_end_transaction(0); |
| 920 | 951 | } |
| 921 | 952 | |
| @@ -933,21 +964,21 @@ | ||
| 933 | 964 | cgi_replace_parameter("header", zDefaultHeader); |
| 934 | 965 | }else{ |
| 935 | 966 | textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader); |
| 936 | 967 | } |
| 937 | 968 | style_header("Edit Page Header"); |
| 938 | - @ <form action="%s(g.zBaseURL)/setup_header" method="POST"> | |
| 969 | + @ <form action="%s(g.zBaseURL)/setup_header" method="post"><div> | |
| 939 | 970 | login_insert_csrf_secret(); |
| 940 | 971 | @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to |
| 941 | 972 | @ generate the beginning of every page through start of the main |
| 942 | 973 | @ menu.</p> |
| 943 | 974 | textarea_attribute("", 40, 80, "header", "header", zDefaultHeader); |
| 944 | 975 | @ <br /> |
| 945 | - @ <input type="submit" name="submit" value="Apply Changes"> | |
| 946 | - @ <input type="submit" name="clear" value="Revert To Default"> | |
| 947 | - @ </form> | |
| 948 | - @ <hr> | |
| 976 | + @ <input type="submit" name="submit" value="Apply Changes" /> | |
| 977 | + @ <input type="submit" name="clear" value="Revert To Default" /> | |
| 978 | + @ </div></form> | |
| 979 | + @ <hr /> | |
| 949 | 980 | @ The default header is shown below for reference. Other examples |
| 950 | 981 | @ of headers can be seen on the <a href="setup_skin">skins page</a>. |
| 951 | 982 | @ See also the <a href="setup_editcss">CSS</a> and |
| 952 | 983 | @ <a href="setup_footer">footer</a> editing screeens. |
| 953 | 984 | @ <blockquote><pre> |
| @@ -971,20 +1002,20 @@ | ||
| 971 | 1002 | cgi_replace_parameter("footer", zDefaultFooter); |
| 972 | 1003 | }else{ |
| 973 | 1004 | textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter); |
| 974 | 1005 | } |
| 975 | 1006 | style_header("Edit Page Footer"); |
| 976 | - @ <form action="%s(g.zBaseURL)/setup_footer" method="POST"> | |
| 1007 | + @ <form action="%s(g.zBaseURL)/setup_footer" method="post"><div> | |
| 977 | 1008 | login_insert_csrf_secret(); |
| 978 | 1009 | @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to |
| 979 | 1010 | @ generate the end of every page.</p> |
| 980 | 1011 | textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter); |
| 981 | 1012 | @ <br /> |
| 982 | - @ <input type="submit" name="submit" value="Apply Changes"> | |
| 983 | - @ <input type="submit" name="clear" value="Revert To Default"> | |
| 984 | - @ </form> | |
| 985 | - @ <hr> | |
| 1013 | + @ <input type="submit" name="submit" value="Apply Changes" /> | |
| 1014 | + @ <input type="submit" name="clear" value="Revert To Default" /> | |
| 1015 | + @ </div></form> | |
| 1016 | + @ <hr /> | |
| 986 | 1017 | @ The default footer is shown below for reference. Other examples |
| 987 | 1018 | @ of footers can be seen on the <a href="setup_skin">skins page</a>. |
| 988 | 1019 | @ See also the <a href="setup_editcss">CSS</a> and |
| 989 | 1020 | @ <a href="setup_header">header</a> editing screens. |
| 990 | 1021 | @ <blockquote><pre> |
| @@ -1034,31 +1065,31 @@ | ||
| 1034 | 1065 | cgi_redirect("setup_logo"); |
| 1035 | 1066 | } |
| 1036 | 1067 | style_header("Edit Project Logo"); |
| 1037 | 1068 | @ <p>The current project logo has a MIME-Type of <b>%h(zMime)</b> and looks |
| 1038 | 1069 | @ like this:</p> |
| 1039 | - @ <blockquote><img src="%s(g.zTop)/logo" alt="logo"></blockquote> | |
| 1070 | + @ <blockquote><p><img src="%s(g.zTop)/logo" alt="logo" /></p></blockquote> | |
| 1040 | 1071 | @ |
| 1041 | 1072 | @ <p>The logo is accessible to all users at this URL: |
| 1042 | 1073 | @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>. |
| 1043 | 1074 | @ The logo may or may not appear on each |
| 1044 | 1075 | @ page depending on the <a href="setup_editcss">CSS</a> and |
| 1045 | 1076 | @ <a href="setup_header">header setup</a>.</p> |
| 1046 | 1077 | @ |
| 1047 | - @ <form action="%s(g.zBaseURL)/setup_logo" method="POST" | |
| 1048 | - @ enctype="multipart/form-data"> | |
| 1078 | + @ <form action="%s(g.zBaseURL)/setup_logo" method="post" | |
| 1079 | + @ enctype="multipart/form-data"><div> | |
| 1049 | 1080 | @ <p>To set a new logo image, select a file to use as the logo using |
| 1050 | 1081 | @ the entry box below and then press the "Change Logo" button.</p> |
| 1051 | 1082 | login_insert_csrf_secret(); |
| 1052 | 1083 | @ Logo Image file: |
| 1053 | - @ <input type="file" name="im" size="60" accepts="image/*"><br> | |
| 1054 | - @ <input type="submit" name="set" value="Change Logo"> | |
| 1055 | - @ <input type="submit" name="clr" value="Revert To Default"> | |
| 1056 | - @ </form> | |
| 1057 | - @ | |
| 1058 | - @ <p><b>Note:</b> Your browser has probably cached the logo image, so | |
| 1059 | - @ you will probably need to press the Reload button on your browser after | |
| 1060 | - @ changing the logo to provoke your browser to reload the new logo image. | |
| 1061 | - @ </p> | |
| 1084 | + @ <input type="file" name="im" size="60" accept="image/*" /><br /> | |
| 1085 | + @ <input type="submit" name="set" value="Change Logo" /> | |
| 1086 | + @ <input type="submit" name="clr" value="Revert To Default" /> | |
| 1087 | + @ </div></form> | |
| 1088 | + @ | |
| 1089 | + @ <p><span class="note">Note:</span> Your browser has probably cached the | |
| 1090 | + @ logo image, so you will probably need to press the Reload button on your | |
| 1091 | + @ browser after changing the logo to provoke your browser to reload the new | |
| 1092 | + @ logo image. </p> | |
| 1062 | 1093 | style_footer(); |
| 1063 | 1094 | db_end_transaction(0); |
| 1064 | 1095 | } |
| 1065 | 1096 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -99,42 +99,40 @@ | |
| 99 | return; |
| 100 | } |
| 101 | |
| 102 | style_submenu_element("Add", "Add User", "setup_uedit"); |
| 103 | style_header("User List"); |
| 104 | @ <table border="0" cellpadding="0" cellspacing="25"> |
| 105 | @ <tr><td valign="top"> |
| 106 | @ <b>Users:</b> |
| 107 | @ <table border="1" cellpadding="10"><tr><td> |
| 108 | @ <table cellspacing=0 cellpadding=0 border=0> |
| 109 | @ <tr> |
| 110 | @ <th align="right">User ID</th><td width="20"> </td> |
| 111 | @ <th>Capabilities</th><td width="15"> </td> |
| 112 | @ <th>Contact Info</th> |
| 113 | @ </tr> |
| 114 | db_prepare(&s, "SELECT uid, login, cap, info FROM user ORDER BY login"); |
| 115 | while( db_step(&s)==SQLITE_ROW ){ |
| 116 | const char *zCap = db_column_text(&s, 2); |
| 117 | if( strstr(zCap, "s") ) zCap = "s"; |
| 118 | @ <tr> |
| 119 | @ <td align="right"> |
| 120 | if( g.okAdmin && (zCap[0]!='s' || g.okSetup) ){ |
| 121 | @ <a href="setup_uedit?id=%d(db_column_int(&s,0))"> |
| 122 | } |
| 123 | @ <nobr>%h(db_column_text(&s,1))</nobr> |
| 124 | if( g.okAdmin ){ |
| 125 | @ </a> |
| 126 | } |
| 127 | @ </td><td> </td> |
| 128 | @ <td align="center">%s(zCap)</td> |
| 129 | @ <td> </td> |
| 130 | @ <td align="left">%s(db_column_text(&s,3))</td> |
| 131 | @ </tr> |
| 132 | } |
| 133 | @ </table></td></tr></table> |
| 134 | @ <td valign="top"> |
| 135 | @ <b>Notes:</b> |
| 136 | @ <ol> |
| 137 | @ <li><p>The permission flags are as follows:</p> |
| 138 | @ <table> |
| 139 | @ <tr><td valign="top"><b>a</b></td> |
| 140 | @ <td><i>Admin:</i> Create and delete users</td></tr> |
| @@ -181,31 +179,35 @@ | |
| 181 | @ user <tt>developer</tt></td></tr> |
| 182 | @ <tr><td valign="top"><b>w</b></td> |
| 183 | @ <td><i>Write-Tkt:</i> Edit tickets</td></tr> |
| 184 | @ <tr><td valign="top"><b>z</b></td> |
| 185 | @ <td><i>Zip download:</i> Download a baseline via the |
| 186 | @ <tt>/zip</tt> URL even without check<b>o</b>ut |
| 187 | @ and <b>h</b>istory permissions</td></tr> |
| 188 | @ </table> |
| 189 | @ </li> |
| 190 | @ |
| 191 | @ <li><p> |
| 192 | @ Every user, logged in or not, inherits the privileges of <b>nobody</b>. |
| 193 | @ </p></li> |
| 194 | @ |
| 195 | @ <li><p> |
| 196 | @ Any human can login as <b>anonymous</b> since the password is |
| 197 | @ clearly displayed on the login page for them to type. The purpose |
| 198 | @ of requiring anonymous to log in is to prevent access by spiders. |
| 199 | @ Every logged-in user inherits the combined privileges of |
| 200 | @ <b>anonymous</b> and |
| 201 | @ <b>nobody</b>. |
| 202 | @ </p></li> |
| 203 | @ |
| 204 | @ <li><p> |
| 205 | @ Users with privilege <b>v</b> inherit the combined privileges of |
| 206 | @ <b>developer</b>, <b>anonymous</b>, and <b>nobody</b>. |
| 207 | @ </p></li> |
| 208 | @ |
| 209 | @ </ol> |
| 210 | @ </td></tr></table> |
| 211 | style_footer(); |
| @@ -323,12 +325,12 @@ | |
| 323 | } |
| 324 | if( uid>0 && |
| 325 | db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid) |
| 326 | ){ |
| 327 | style_header("User Creation Error"); |
| 328 | @ <font color="red">Login "%h(zLogin)" is already used by a different |
| 329 | @ user.</font> |
| 330 | @ |
| 331 | @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p> |
| 332 | style_footer(); |
| 333 | return; |
| 334 | } |
| @@ -353,65 +355,69 @@ | |
| 353 | if( uid ){ |
| 354 | zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); |
| 355 | zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); |
| 356 | zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); |
| 357 | zPw = db_text("", "SELECT pw FROM user WHERE uid=%d", uid); |
| 358 | if( strchr(zCap, 'a') ) oaa = " checked"; |
| 359 | if( strchr(zCap, 'b') ) oab = " checked"; |
| 360 | if( strchr(zCap, 'c') ) oac = " checked"; |
| 361 | if( strchr(zCap, 'd') ) oad = " checked"; |
| 362 | if( strchr(zCap, 'e') ) oae = " checked"; |
| 363 | if( strchr(zCap, 'f') ) oaf = " checked"; |
| 364 | if( strchr(zCap, 'g') ) oag = " checked"; |
| 365 | if( strchr(zCap, 'h') ) oah = " checked"; |
| 366 | if( strchr(zCap, 'i') ) oai = " checked"; |
| 367 | if( strchr(zCap, 'j') ) oaj = " checked"; |
| 368 | if( strchr(zCap, 'k') ) oak = " checked"; |
| 369 | if( strchr(zCap, 'm') ) oam = " checked"; |
| 370 | if( strchr(zCap, 'n') ) oan = " checked"; |
| 371 | if( strchr(zCap, 'o') ) oao = " checked"; |
| 372 | if( strchr(zCap, 'p') ) oap = " checked"; |
| 373 | if( strchr(zCap, 'r') ) oar = " checked"; |
| 374 | if( strchr(zCap, 's') ) oas = " checked"; |
| 375 | if( strchr(zCap, 't') ) oat = " checked"; |
| 376 | if( strchr(zCap, 'u') ) oau = " checked"; |
| 377 | if( strchr(zCap, 'v') ) oav = " checked"; |
| 378 | if( strchr(zCap, 'w') ) oaw = " checked"; |
| 379 | if( strchr(zCap, 'z') ) oaz = " checked"; |
| 380 | } |
| 381 | |
| 382 | /* figure out inherited permissions */ |
| 383 | memset(inherit, 0, sizeof(inherit)); |
| 384 | if( strcmp(zLogin, "developer") ){ |
| 385 | char *z1, *z2; |
| 386 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); |
| 387 | while( z1 && *z1 ){ |
| 388 | inherit[0x7f & *(z1++)] = "<font color=\"red\">•</font>"; |
| 389 | } |
| 390 | free(z2); |
| 391 | } |
| 392 | if( strcmp(zLogin, "reader") ){ |
| 393 | char *z1, *z2; |
| 394 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); |
| 395 | while( z1 && *z1 ){ |
| 396 | inherit[0x7f & *(z1++)] = "<font color=\"black\">•</font>"; |
| 397 | } |
| 398 | free(z2); |
| 399 | } |
| 400 | if( strcmp(zLogin, "anonymous") ){ |
| 401 | char *z1, *z2; |
| 402 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); |
| 403 | while( z1 && *z1 ){ |
| 404 | inherit[0x7f & *(z1++)] = "<font color=\"blue\">•</font>"; |
| 405 | } |
| 406 | free(z2); |
| 407 | } |
| 408 | if( strcmp(zLogin, "nobody") ){ |
| 409 | char *z1, *z2; |
| 410 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); |
| 411 | while( z1 && *z1 ){ |
| 412 | inherit[0x7f & *(z1++)] = "<font color=\"green\">•</font>"; |
| 413 | } |
| 414 | free(z2); |
| 415 | } |
| 416 | |
| 417 | /* Begin generating the page |
| @@ -420,77 +426,79 @@ | |
| 420 | if( uid ){ |
| 421 | style_header(mprintf("Edit User %h", zLogin)); |
| 422 | }else{ |
| 423 | style_header("Add A New User"); |
| 424 | } |
| 425 | @ <table align="left" hspace="20" vspace="10"><tr><td> |
| 426 | @ <form action="%s(g.zPath)" method="POST"> |
| 427 | login_insert_csrf_secret(); |
| 428 | @ <table> |
| 429 | @ <tr> |
| 430 | @ <td align="right"><nobr>User ID:</nobr></td> |
| 431 | if( uid ){ |
| 432 | @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)"></td> |
| 433 | }else{ |
| 434 | @ <td>(new user)<input type="hidden" name="id" value=0></td> |
| 435 | } |
| 436 | @ </tr> |
| 437 | @ <tr> |
| 438 | @ <td align="right"><nobr>Login:</nobr></td> |
| 439 | @ <td><input type="text" name="login" value="%h(zLogin)"></td> |
| 440 | @ </tr> |
| 441 | @ <tr> |
| 442 | @ <td align="right"><nobr>Contact Info:</nobr></td> |
| 443 | @ <td><input type="text" name="info" size=40 value="%h(zInfo)"></td> |
| 444 | @ </tr> |
| 445 | @ <tr> |
| 446 | @ <td align="right" valign="top">Capabilities:</td> |
| 447 | @ <td> |
| 448 | #define B(x) inherit[x] |
| 449 | if( g.okSetup ){ |
| 450 | @ <input type="checkbox" name="as"%s(oas)/>%s(B('s'))Setup<br> |
| 451 | } |
| 452 | @ <input type="checkbox" name="aa"%s(oaa)/>%s(B('a'))Admin<br> |
| 453 | @ <input type="checkbox" name="ad"%s(oad)/>%s(B('d'))Delete<br> |
| 454 | @ <input type="checkbox" name="ae"%s(oae)/>%s(B('e'))Email<br> |
| 455 | @ <input type="checkbox" name="ap"%s(oap)/>%s(B('p'))Password<br> |
| 456 | @ <input type="checkbox" name="ai"%s(oai)/>%s(B('i'))Check-In<br> |
| 457 | @ <input type="checkbox" name="ao"%s(oao)/>%s(B('o'))Check-Out<br> |
| 458 | @ <input type="checkbox" name="ah"%s(oah)/>%s(B('h'))History<br> |
| 459 | @ <input type="checkbox" name="au"%s(oau)/>%s(B('u'))Reader<br> |
| 460 | @ <input type="checkbox" name="av"%s(oav)/>%s(B('v'))Developer<br> |
| 461 | @ <input type="checkbox" name="ag"%s(oag)/>%s(B('g'))Clone<br> |
| 462 | @ <input type="checkbox" name="aj"%s(oaj)/>%s(B('j'))Read Wiki<br> |
| 463 | @ <input type="checkbox" name="af"%s(oaf)/>%s(B('f'))New Wiki<br> |
| 464 | @ <input type="checkbox" name="am"%s(oam)/>%s(B('m'))Append Wiki<br> |
| 465 | @ <input type="checkbox" name="ak"%s(oak)/>%s(B('k'))Write Wiki<br> |
| 466 | @ <input type="checkbox" name="ab"%s(oab)/>%s(B('b'))Attachments<br> |
| 467 | @ <input type="checkbox" name="ar"%s(oar)/>%s(B('r'))Read Ticket<br> |
| 468 | @ <input type="checkbox" name="an"%s(oan)/>%s(B('n'))New Ticket<br> |
| 469 | @ <input type="checkbox" name="ac"%s(oac)/>%s(B('c'))Append Ticket<br> |
| 470 | @ <input type="checkbox" name="aw"%s(oaw)/>%s(B('w'))Write Ticket<br> |
| 471 | @ <input type="checkbox" name="at"%s(oat)/>%s(B('t'))Ticket Report<br> |
| 472 | @ <input type="checkbox" name="az"%s(oaz)/>%s(B('z'))Download Zip |
| 473 | @ </td> |
| 474 | @ </tr> |
| 475 | @ <tr> |
| 476 | @ <td align="right">Password:</td> |
| 477 | if( zPw[0] ){ |
| 478 | /* Obscure the password for all users */ |
| 479 | @ <td><input type="password" name="pw" value="**********"></td> |
| 480 | }else{ |
| 481 | /* Show an empty password as an empty input field */ |
| 482 | @ <td><input type="password" name="pw" value=""></td> |
| 483 | } |
| 484 | @ </tr> |
| 485 | if( !higherUser ){ |
| 486 | @ <tr> |
| 487 | @ <td> </td> |
| 488 | @ <td><input type="submit" name="submit" value="Apply Changes"> |
| 489 | @ </tr> |
| 490 | } |
| 491 | @ </table></td></tr></table> |
| 492 | @ <h2>Privileges And Capabilities:</h2> |
| 493 | @ <ul> |
| 494 | if( higherUser ){ |
| 495 | @ <li><p><font color="blue"><b> |
| 496 | @ User %h(zLogin) has Setup privileges and you only have Admin privileges |
| @@ -497,95 +505,114 @@ | |
| 497 | @ so you are not permitted to make changes to %h(zLogin). |
| 498 | @ </b></font></p></li> |
| 499 | @ |
| 500 | } |
| 501 | @ <li><p> |
| 502 | @ The <b>Setup</b> user can make arbitrary configuration changes. |
| 503 | @ An <b>Admin</b> user can add other users and change user privileges |
| 504 | @ and reset user passwords. Both automatically get all other privileges |
| 505 | @ listed below. Use these two settings with discretion. |
| 506 | @ </p></li> |
| 507 | @ |
| 508 | @ <li><p> |
| 509 | @ The "<font color="green"><big>•</big></font>" mark indicates |
| 510 | @ the privileges of "nobody" that are available to all users |
| 511 | @ regardless of whether or not they are logged in. |
| 512 | @ </p></li> |
| 513 | @ |
| 514 | @ <li><p> |
| 515 | @ The "<font color="blue"><big>•</big></font>" mark indicates |
| 516 | @ the privileges of "anonymous" that are inherited by all logged-in users. |
| 517 | @ </p></li> |
| 518 | @ |
| 519 | @ <li><p> |
| 520 | @ The "<font color="red"><big>•</big></font>" mark indicates |
| 521 | @ the privileges of "developer" that are inherited by all users with |
| 522 | @ the <b>Developer</b> privilege. |
| 523 | @ </p></li> |
| 524 | @ |
| 525 | @ <li><p> |
| 526 | @ The "<font color="black"><big>•</big></font>" mark indicates |
| 527 | @ the privileges of "reader" that are inherited by all users with |
| 528 | @ the <b>Reader</b> privilege. |
| 529 | @ </p></li> |
| 530 | @ |
| 531 | @ <li><p> |
| 532 | @ The <b>Delete</b> privilege give the user the ability to erase |
| 533 | @ wiki, tickets, and attachments that have been added by anonymous |
| 534 | @ users. This capability is intended for deletion of spam. The |
| 535 | @ delete capability is only in effect for 24 hours after the item |
| 536 | @ is first posted. The Setup user can delete anything at any time. |
| 537 | @ </p></li> |
| 538 | @ |
| 539 | @ <li><p> |
| 540 | @ The <b>History</b> privilege allows a user to see most hyperlinks. |
| 541 | @ This is recommended ON for most logged-in users but OFF for |
| 542 | @ user "nobody" to avoid problems with spiders trying to walk every |
| 543 | @ historical version of every baseline and file. |
| 544 | @ </p></li> |
| 545 | @ |
| 546 | @ <li><p> |
| 547 | @ The <b>Zip</b> privilege allows a user to see the "download as ZIP" |
| 548 | @ hyperlink and permits access to the <tt>/zip</tt> page. This allows |
| 549 | @ users to download ZIP archives without granting other rights like |
| 550 | @ <b>Read</b> or <b>History</b>. This privilege is recommended for |
| 551 | @ user <b>nobody</b> so that automatic package downloaders can obtain |
| 552 | @ the sources without going through the login procedure. |
| 553 | @ </p></li> |
| 554 | @ |
| 555 | @ <li><p> |
| 556 | @ The <b>Check-in</b> privilege allows remote users to "push". |
| 557 | @ The <b>Check-out</b> privilege allows remote users to "pull". |
| 558 | @ The <b>Clone</b> privilege allows remote users to "clone". |
| 559 | @ </li><p> |
| 560 | @ |
| 561 | @ <li><p> |
| 562 | @ The <b>Read Wiki</b>, <b>New Wiki</b>, <b>Append Wiki</b>, and |
| 563 | @ <b>Write Wiki</b> privileges control access to wiki pages. The |
| 564 | @ <b>Read Ticket</b>, <b>New Ticket</b>, <b>Append Ticket</b>, and |
| 565 | @ <b>Write Ticket</b> privileges control access to trouble tickets. |
| 566 | @ The <b>Ticket Report</b> privilege allows the user to create or edit |
| 567 | @ ticket report formats. |
| 568 | @ </p></li> |
| 569 | @ |
| 570 | @ <li><p> |
| 571 | @ Users with the <b>Password</b> privilege are allowed to change their |
| 572 | @ own password. Recommended ON for most users but OFF for special |
| 573 | @ users "developer", "anonymous", and "nobody". |
| 574 | @ </p></li> |
| 575 | @ |
| 576 | @ <li><p> |
| 577 | @ The <b>EMail</b> privilege allows the display of sensitive information |
| 578 | @ such as the email address of users and contact information on tickets. |
| 579 | @ Recommended OFF for "anonymous" and for "nobody" but ON for |
| 580 | @ "developer". |
| 581 | @ </p></li> |
| 582 | @ |
| 583 | @ <li><p> |
| 584 | @ The <b>Attachment</b> privilege is needed in order to add attachments |
| 585 | @ to tickets or wiki. Write privilege on the ticket or wiki is also |
| 586 | @ required.</p></li> |
| 587 | @ |
| 588 | @ <li><p> |
| 589 | @ Login is prohibited if the password is an empty string. |
| 590 | @ </p></li> |
| 591 | @ </ul> |
| @@ -592,42 +619,46 @@ | |
| 592 | @ |
| 593 | @ <h2>Special Logins</h2> |
| 594 | @ |
| 595 | @ <ul> |
| 596 | @ <li><p> |
| 597 | @ No login is required for user "<b>nobody</b>". The capabilities |
| 598 | @ of the <b>nobody</b> user are inherited by all users, regardless of |
| 599 | @ whether or not they are logged in. To disable universal access |
| 600 | @ to the repository, make sure no user named "<b>nobody</b>" exists or |
| 601 | @ that the <b>nobody</b> user has no capabilities enabled. |
| 602 | @ The password for <b>nobody</b> is ignore. To avoid problems with |
| 603 | @ spiders overloading the server, it is recommended |
| 604 | @ that the 'h' (History) capability be turned off for the <b>nobody</b> |
| 605 | @ user. |
| 606 | @ </p></li> |
| 607 | @ |
| 608 | @ <li><p> |
| 609 | @ Login is required for user "<b>anonymous</b>" but the password |
| 610 | @ is displayed on the login screen beside the password entry box |
| 611 | @ so anybody who can read should be able to login as anonymous. |
| 612 | @ On the other hand, spiders and web-crawlers will typically not |
| 613 | @ be able to login. Set the capabilities of the anonymous user |
| 614 | @ to things that you want any human to be able to do, but not any |
| 615 | @ spider. Every other logged-in user inherits the privileges of |
| 616 | @ <b>anonymous</b>. |
| 617 | @ </p></li> |
| 618 | @ |
| 619 | @ <li><p> |
| 620 | @ The "<b>developer</b>" user is intended as a template for trusted users |
| 621 | @ with check-in privileges. When adding new trusted users, simply |
| 622 | @ select the <b>Developer</b> privilege to cause the new user to inherit |
| 623 | @ all privileges of the "developer" user. Similarly, the "<b>reader</b>" |
| 624 | @ user is a template for users who are allowed more access than anonymous, |
| 625 | @ but less than a developer. |
| 626 | @ </p></li> |
| 627 | @ </ul> |
| 628 | @ </form> |
| 629 | style_footer(); |
| 630 | } |
| 631 | |
| 632 | |
| 633 | /* |
| @@ -651,13 +682,14 @@ | |
| 651 | db_set(zVar, iQ ? "1" : "0", 0); |
| 652 | iVal = iQ; |
| 653 | } |
| 654 | } |
| 655 | if( iVal ){ |
| 656 | @ <input type="checkbox" name="%s(zQParm)" checked><b>%s(zLabel)</b></input> |
| 657 | }else{ |
| 658 | @ <input type="checkbox" name="%s(zQParm)"><b>%s(zLabel)</b></input> |
| 659 | } |
| 660 | } |
| 661 | |
| 662 | /* |
| 663 | ** Generate an entry box for an attribute. |
| @@ -674,11 +706,11 @@ | |
| 674 | if( zQ && strcmp(zQ,zVal)!=0 ){ |
| 675 | login_verify_csrf_secret(); |
| 676 | db_set(zVar, zQ, 0); |
| 677 | zVal = zQ; |
| 678 | } |
| 679 | @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)"> |
| 680 | @ <b>%s(zLabel)</b> |
| 681 | } |
| 682 | |
| 683 | /* |
| 684 | ** Generate a text box for an attribute. |
| @@ -698,11 +730,12 @@ | |
| 698 | db_set(zVar, zQ, 0); |
| 699 | z = zQ; |
| 700 | } |
| 701 | if( rows>0 && cols>0 ){ |
| 702 | @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea> |
| 703 | @ <b>%s(zLabel)</b> |
| 704 | } |
| 705 | } |
| 706 | |
| 707 | |
| 708 | /* |
| @@ -714,57 +747,57 @@ | |
| 714 | login_needed(); |
| 715 | } |
| 716 | |
| 717 | style_header("Access Control Settings"); |
| 718 | db_begin_transaction(); |
| 719 | @ <form action="%s(g.zBaseURL)/setup_access" method="POST"> |
| 720 | login_insert_csrf_secret(); |
| 721 | @ <hr> |
| 722 | onoff_attribute("Require password for local access", |
| 723 | "localauth", "localauth", 0); |
| 724 | @ <p>When enabled, the password sign-in is required for |
| 725 | @ web access coming from 127.0.0.1. When disabled, web access |
| 726 | @ from 127.0.0.1 is allows without any login - the user id is selected |
| 727 | @ from the ~/.fossil database. Password login is always required |
| 728 | @ for incoming web connections on internet addresses other than |
| 729 | @ 127.0.0.1.</p></li> |
| 730 | |
| 731 | @ <hr> |
| 732 | onoff_attribute("Allow REMOTE_USER authentication", |
| 733 | "remote_user_ok", "remote_user_ok", 0); |
| 734 | @ <p>When enabled, if the REMOTE_USER environment variable is set to the |
| 735 | @ login name of a valid user and no other login credentials are available, |
| 736 | @ then the REMOTE_USER is accepted as an authenticated user. |
| 737 | @ </p></li> |
| 738 | |
| 739 | @ <hr> |
| 740 | entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766"); |
| 741 | @ <p>The number of hours for which a login is valid. This must be a |
| 742 | @ positive number. The default is 8760 hours which is approximately equal |
| 743 | @ to a year.</p> |
| 744 | |
| 745 | @ <hr> |
| 746 | entry_attribute("Download packet limit", 10, "max-download", "mxdwn", |
| 747 | "5000000"); |
| 748 | @ <p>Fossil tries to limit out-bound sync, clone, and pull packets |
| 749 | @ to this many bytes, uncompressed. If the client requires more data |
| 750 | @ than this, then the client will issue multiple HTTP requests. |
| 751 | @ Values below 1 million are not recommended. 5 million is a |
| 752 | @ reasonable number.</p> |
| 753 | |
| 754 | @ <hr> |
| 755 | onoff_attribute("Show javascript button to fill in CAPTCHA", |
| 756 | "auto-captcha", "autocaptcha", 0); |
| 757 | @ <p>When enabled, a button appears on the login screen for user |
| 758 | @ "anonymous" that will automatically fill in the CAPTCHA password. |
| 759 | @ This is less secure that forcing the user to do it manually, but is |
| 760 | @ probably secure enough and it is certainly more convenient for |
| 761 | @ anonymous users.</p> |
| 762 | |
| 763 | @ <hr> |
| 764 | @ <p><input type="submit" name="submit" value="Apply Changes"></p> |
| 765 | @ </form> |
| 766 | db_end_transaction(0); |
| 767 | style_footer(); |
| 768 | } |
| 769 | |
| 770 | /* |
| @@ -776,42 +809,42 @@ | |
| 776 | login_needed(); |
| 777 | } |
| 778 | |
| 779 | style_header("Timeline Display Preferences"); |
| 780 | db_begin_transaction(); |
| 781 | @ <form action="%s(g.zBaseURL)/setup_timeline" method="POST"> |
| 782 | login_insert_csrf_secret(); |
| 783 | |
| 784 | @ <hr> |
| 785 | onoff_attribute("Allow block-markup in timeline", |
| 786 | "timeline-block-markup", "tbm", 0); |
| 787 | @ <p>In timeline displays, check-in comments can be displayed with or |
| 788 | @ without block markup (paragraphs, tables, etc.)</p> |
| 789 | |
| 790 | @ <hr> |
| 791 | onoff_attribute("Use Universal Coordinated Time (UTC)", |
| 792 | "timeline-utc", "utc", 1); |
| 793 | @ <p>Show times as UTC (also sometimes called Greenwich Mean Time (GMT) or |
| 794 | @ Zulu) instead of in local time.</p> |
| 795 | |
| 796 | @ <hr> |
| 797 | onoff_attribute("Show version differences by default", |
| 798 | "show-version-diffs", "vdiff", 0); |
| 799 | @ <p>On the version-information pages linked from the timeline can either |
| 800 | @ show complete diffs of all file changes, or can just list the names of |
| 801 | @ the files that have changed. Users can get to either page by |
| 802 | @ clicking. This setting selects the default.</p> |
| 803 | |
| 804 | @ <hr> |
| 805 | entry_attribute("Max timeline comment length", 6, |
| 806 | "timeline-max-comment", "tmc", "0"); |
| 807 | @ <p>The maximum length of a comment to be displayed in a timeline. |
| 808 | @ "0" there is no length limit.</p> |
| 809 | |
| 810 | @ <hr> |
| 811 | @ <p><input type="submit" name="submit" value="Apply Changes"></p> |
| 812 | @ </form> |
| 813 | db_end_transaction(0); |
| 814 | style_footer(); |
| 815 | } |
| 816 | |
| 817 | /* |
| @@ -823,11 +856,11 @@ | |
| 823 | login_needed(); |
| 824 | } |
| 825 | |
| 826 | style_header("WWW Configuration"); |
| 827 | db_begin_transaction(); |
| 828 | @ <form action="%s(g.zBaseURL)/setup_config" method="POST"> |
| 829 | login_insert_csrf_secret(); |
| 830 | @ <hr /> |
| 831 | entry_attribute("Project Name", 60, "project-name", "pn", ""); |
| 832 | @ <p>Give your project a name so visitors know what this site is about. |
| 833 | @ The project name will also be used as the RSS feed title.</p> |
| @@ -840,36 +873,37 @@ | |
| 840 | entry_attribute("Index Page", 60, "index-page", "idxpg", "/home"); |
| 841 | @ <p>Enter the pathname of the page to display when the "Home" menu |
| 842 | @ option is selected and when no pathname is |
| 843 | @ specified in the URL. For example, if you visit the url:</p> |
| 844 | @ |
| 845 | @ <blockquote>%h(g.zBaseURL)</blockquote> |
| 846 | @ |
| 847 | @ <p>And you have specified an index page of "/home" the above will |
| 848 | @ automatically redirect to:</p> |
| 849 | @ |
| 850 | @ <blockquote>%h(g.zBaseURL)/home</blockquote> |
| 851 | @ |
| 852 | @ <p>The default "/home" page displays a Wiki page with the same name |
| 853 | @ as the Project Name specified above. Some sites prefer to redirect |
| 854 | @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p> |
| 855 | @ <hr /> |
| 856 | onoff_attribute("Use HTML as wiki markup language", |
| 857 | "wiki-use-html", "wiki-use-html", 0); |
| 858 | @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed but |
| 859 | @ all other wiki formatting will be ignored. This option is helpful if you have |
| 860 | @ chosen to use a rich HTML editor for wiki markup such as TinyMCE.</p> |
| 861 | @ <p><strong>CAUTION:</strong> when |
| 862 | @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki. |
| 863 | @ No sanitization is done. This means that it is very possible for malicious |
| 864 | @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p> |
| 865 | @ <p>This should <strong>only</strong> be enabled when wiki editing is limited |
| 866 | @ to trusted users. It should <strong>not</strong> be used on a publically |
| 867 | @ editable wiki.</p> |
| 868 | @ <hr /> |
| 869 | @ <p><input type="submit" name="submit" value="Apply Changes"></p> |
| 870 | @ </form> |
| 871 | db_end_transaction(0); |
| 872 | style_footer(); |
| 873 | } |
| 874 | |
| 875 | /* |
| @@ -892,30 +926,27 @@ | |
| 892 | if( P("submit")!=0 ){ |
| 893 | db_end_transaction(0); |
| 894 | cgi_redirect("setup_editcss"); |
| 895 | } |
| 896 | style_header("Edit CSS"); |
| 897 | @ <form action="%s(g.zBaseURL)/setup_editcss" method="POST"> |
| 898 | login_insert_csrf_secret(); |
| 899 | @ Edit the CSS below:<br /> |
| 900 | textarea_attribute("", 40, 80, "css", "css", zDefaultCSS); |
| 901 | @ <br /> |
| 902 | @ <input type="submit" name="submit" value="Apply Changes"> |
| 903 | @ <input type="submit" name="clear" value="Revert To Default"> |
| 904 | @ </form> |
| 905 | @ <p><b>Note:</b> Press your browser Reload button after modifying the |
| 906 | @ CSS in order to pull in the modified CSS file.</p> |
| 907 | @ <hr> |
| 908 | @ The default CSS is shown below for reference. Other examples |
| 909 | @ of CSS files can be seen on the <a href="setup_skin">skins page</a>. |
| 910 | @ See also the <a href="setup_header">header</a> and |
| 911 | @ <a href="setup_footer">footer</a> editing screens. |
| 912 | @ <blockquote><pre> |
| 913 | @ %h(zDefaultCSS) |
| 914 | @ %h(zTableLabelValueCSS) |
| 915 | @ %h(zDivSidebox) |
| 916 | @ %h(zDivSideboxTitle) |
| 917 | @ </pre></blockquote> |
| 918 | style_footer(); |
| 919 | db_end_transaction(0); |
| 920 | } |
| 921 | |
| @@ -933,21 +964,21 @@ | |
| 933 | cgi_replace_parameter("header", zDefaultHeader); |
| 934 | }else{ |
| 935 | textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader); |
| 936 | } |
| 937 | style_header("Edit Page Header"); |
| 938 | @ <form action="%s(g.zBaseURL)/setup_header" method="POST"> |
| 939 | login_insert_csrf_secret(); |
| 940 | @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to |
| 941 | @ generate the beginning of every page through start of the main |
| 942 | @ menu.</p> |
| 943 | textarea_attribute("", 40, 80, "header", "header", zDefaultHeader); |
| 944 | @ <br /> |
| 945 | @ <input type="submit" name="submit" value="Apply Changes"> |
| 946 | @ <input type="submit" name="clear" value="Revert To Default"> |
| 947 | @ </form> |
| 948 | @ <hr> |
| 949 | @ The default header is shown below for reference. Other examples |
| 950 | @ of headers can be seen on the <a href="setup_skin">skins page</a>. |
| 951 | @ See also the <a href="setup_editcss">CSS</a> and |
| 952 | @ <a href="setup_footer">footer</a> editing screeens. |
| 953 | @ <blockquote><pre> |
| @@ -971,20 +1002,20 @@ | |
| 971 | cgi_replace_parameter("footer", zDefaultFooter); |
| 972 | }else{ |
| 973 | textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter); |
| 974 | } |
| 975 | style_header("Edit Page Footer"); |
| 976 | @ <form action="%s(g.zBaseURL)/setup_footer" method="POST"> |
| 977 | login_insert_csrf_secret(); |
| 978 | @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to |
| 979 | @ generate the end of every page.</p> |
| 980 | textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter); |
| 981 | @ <br /> |
| 982 | @ <input type="submit" name="submit" value="Apply Changes"> |
| 983 | @ <input type="submit" name="clear" value="Revert To Default"> |
| 984 | @ </form> |
| 985 | @ <hr> |
| 986 | @ The default footer is shown below for reference. Other examples |
| 987 | @ of footers can be seen on the <a href="setup_skin">skins page</a>. |
| 988 | @ See also the <a href="setup_editcss">CSS</a> and |
| 989 | @ <a href="setup_header">header</a> editing screens. |
| 990 | @ <blockquote><pre> |
| @@ -1034,31 +1065,31 @@ | |
| 1034 | cgi_redirect("setup_logo"); |
| 1035 | } |
| 1036 | style_header("Edit Project Logo"); |
| 1037 | @ <p>The current project logo has a MIME-Type of <b>%h(zMime)</b> and looks |
| 1038 | @ like this:</p> |
| 1039 | @ <blockquote><img src="%s(g.zTop)/logo" alt="logo"></blockquote> |
| 1040 | @ |
| 1041 | @ <p>The logo is accessible to all users at this URL: |
| 1042 | @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>. |
| 1043 | @ The logo may or may not appear on each |
| 1044 | @ page depending on the <a href="setup_editcss">CSS</a> and |
| 1045 | @ <a href="setup_header">header setup</a>.</p> |
| 1046 | @ |
| 1047 | @ <form action="%s(g.zBaseURL)/setup_logo" method="POST" |
| 1048 | @ enctype="multipart/form-data"> |
| 1049 | @ <p>To set a new logo image, select a file to use as the logo using |
| 1050 | @ the entry box below and then press the "Change Logo" button.</p> |
| 1051 | login_insert_csrf_secret(); |
| 1052 | @ Logo Image file: |
| 1053 | @ <input type="file" name="im" size="60" accepts="image/*"><br> |
| 1054 | @ <input type="submit" name="set" value="Change Logo"> |
| 1055 | @ <input type="submit" name="clr" value="Revert To Default"> |
| 1056 | @ </form> |
| 1057 | @ |
| 1058 | @ <p><b>Note:</b> Your browser has probably cached the logo image, so |
| 1059 | @ you will probably need to press the Reload button on your browser after |
| 1060 | @ changing the logo to provoke your browser to reload the new logo image. |
| 1061 | @ </p> |
| 1062 | style_footer(); |
| 1063 | db_end_transaction(0); |
| 1064 | } |
| 1065 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -99,42 +99,40 @@ | |
| 99 | return; |
| 100 | } |
| 101 | |
| 102 | style_submenu_element("Add", "Add User", "setup_uedit"); |
| 103 | style_header("User List"); |
| 104 | @ <table class="usetupLayoutTable"> |
| 105 | @ <tr><td class="usetupColumnLayout"> |
| 106 | @ <span class="note">Users:</span> |
| 107 | @ <table class="usetupUserList"> |
| 108 | @ <tr> |
| 109 | @ <th class="usetupListUser" style="text-align: right;padding-right: 20px;">User ID</th> |
| 110 | @ <th class="usetupListCap" style="text-align: center;padding-right: 15px;">Capabilities</th> |
| 111 | @ <th class="usetupListCon" style="text-align: left;">Contact Info</th> |
| 112 | @ </tr> |
| 113 | db_prepare(&s, "SELECT uid, login, cap, info FROM user ORDER BY login"); |
| 114 | while( db_step(&s)==SQLITE_ROW ){ |
| 115 | const char *zCap = db_column_text(&s, 2); |
| 116 | if( strstr(zCap, "s") ) zCap = "s"; |
| 117 | @ <tr> |
| 118 | @ <td class="usetupListUser" style="text-align: right;padding-right: 20px;white-space:nowrap;"> |
| 119 | if( g.okAdmin && (zCap[0]!='s' || g.okSetup) ){ |
| 120 | @ <a href="setup_uedit?id=%d(db_column_int(&s,0))"> |
| 121 | } |
| 122 | @ %h(db_column_text(&s,1)) |
| 123 | if( g.okAdmin ){ |
| 124 | @ </a> |
| 125 | } |
| 126 | @ </td> |
| 127 | @ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td> |
| 128 | @ <td class="usetupListCon" style="text-align: left;">%s(db_column_text(&s,3))</td> |
| 129 | @ </tr> |
| 130 | } |
| 131 | @ </table> |
| 132 | @ </td><td class="usetupColumnLayout"> |
| 133 | @ <span class="note">Notes:</span> |
| 134 | @ <ol> |
| 135 | @ <li><p>The permission flags are as follows:</p> |
| 136 | @ <table> |
| 137 | @ <tr><td valign="top"><b>a</b></td> |
| 138 | @ <td><i>Admin:</i> Create and delete users</td></tr> |
| @@ -181,31 +179,35 @@ | |
| 179 | @ user <tt>developer</tt></td></tr> |
| 180 | @ <tr><td valign="top"><b>w</b></td> |
| 181 | @ <td><i>Write-Tkt:</i> Edit tickets</td></tr> |
| 182 | @ <tr><td valign="top"><b>z</b></td> |
| 183 | @ <td><i>Zip download:</i> Download a baseline via the |
| 184 | @ <tt>/zip</tt> URL even without |
| 185 | @ check<span class="capability">o</span>ut |
| 186 | @ and <span class="capability">h</span>istory permissions</td></tr> |
| 187 | @ </table> |
| 188 | @ </li> |
| 189 | @ |
| 190 | @ <li><p> |
| 191 | @ Every user, logged in or not, inherits the privileges of |
| 192 | @ <span class="usertype">nobody</span>. |
| 193 | @ </p></li> |
| 194 | @ |
| 195 | @ <li><p> |
| 196 | @ Any human can login as <span class="usertype">anonymous</span> since the |
| 197 | @ password is clearly displayed on the login page for them to type. The |
| 198 | @ purpose of requiring anonymous to log in is to prevent access by spiders. |
| 199 | @ Every logged-in user inherits the combined privileges of |
| 200 | @ <span class="usertype">anonymous</span> and |
| 201 | @ <span class="usertype">nobody</span>. |
| 202 | @ </p></li> |
| 203 | @ |
| 204 | @ <li><p> |
| 205 | @ Users with privilege <span class="capability">v</span> inherit the combined |
| 206 | @ privileges of <span class="usertype">developer</span>, |
| 207 | @ <span class="usertype">anonymous</span>, and |
| 208 | @ <span class="usertype">nobody</span>. |
| 209 | @ </p></li> |
| 210 | @ |
| 211 | @ </ol> |
| 212 | @ </td></tr></table> |
| 213 | style_footer(); |
| @@ -323,12 +325,12 @@ | |
| 325 | } |
| 326 | if( uid>0 && |
| 327 | db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid) |
| 328 | ){ |
| 329 | style_header("User Creation Error"); |
| 330 | @ <span class="loginError">Login "%h(zLogin)" is already used by |
| 331 | @ a different user.</span> |
| 332 | @ |
| 333 | @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p> |
| 334 | style_footer(); |
| 335 | return; |
| 336 | } |
| @@ -353,65 +355,69 @@ | |
| 355 | if( uid ){ |
| 356 | zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); |
| 357 | zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); |
| 358 | zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); |
| 359 | zPw = db_text("", "SELECT pw FROM user WHERE uid=%d", uid); |
| 360 | if( strchr(zCap, 'a') ) oaa = " checked=\"checked\""; |
| 361 | if( strchr(zCap, 'b') ) oab = " checked=\"checked\""; |
| 362 | if( strchr(zCap, 'c') ) oac = " checked=\"checked\""; |
| 363 | if( strchr(zCap, 'd') ) oad = " checked=\"checked\""; |
| 364 | if( strchr(zCap, 'e') ) oae = " checked=\"checked\""; |
| 365 | if( strchr(zCap, 'f') ) oaf = " checked=\"checked\""; |
| 366 | if( strchr(zCap, 'g') ) oag = " checked=\"checked\""; |
| 367 | if( strchr(zCap, 'h') ) oah = " checked=\"checked\""; |
| 368 | if( strchr(zCap, 'i') ) oai = " checked=\"checked\""; |
| 369 | if( strchr(zCap, 'j') ) oaj = " checked=\"checked\""; |
| 370 | if( strchr(zCap, 'k') ) oak = " checked=\"checked\""; |
| 371 | if( strchr(zCap, 'm') ) oam = " checked=\"checked\""; |
| 372 | if( strchr(zCap, 'n') ) oan = " checked=\"checked\""; |
| 373 | if( strchr(zCap, 'o') ) oao = " checked=\"checked\""; |
| 374 | if( strchr(zCap, 'p') ) oap = " checked=\"checked\""; |
| 375 | if( strchr(zCap, 'r') ) oar = " checked=\"checked\""; |
| 376 | if( strchr(zCap, 's') ) oas = " checked=\"checked\""; |
| 377 | if( strchr(zCap, 't') ) oat = " checked=\"checked\""; |
| 378 | if( strchr(zCap, 'u') ) oau = " checked=\"checked\""; |
| 379 | if( strchr(zCap, 'v') ) oav = " checked=\"checked\""; |
| 380 | if( strchr(zCap, 'w') ) oaw = " checked=\"checked\""; |
| 381 | if( strchr(zCap, 'z') ) oaz = " checked=\"checked\""; |
| 382 | } |
| 383 | |
| 384 | /* figure out inherited permissions */ |
| 385 | memset(inherit, 0, sizeof(inherit)); |
| 386 | if( strcmp(zLogin, "developer") ){ |
| 387 | char *z1, *z2; |
| 388 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); |
| 389 | while( z1 && *z1 ){ |
| 390 | inherit[0x7f & *(z1++)] = |
| 391 | "<span class=\"ueditInheritDeveloper\">•</span>"; |
| 392 | } |
| 393 | free(z2); |
| 394 | } |
| 395 | if( strcmp(zLogin, "reader") ){ |
| 396 | char *z1, *z2; |
| 397 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); |
| 398 | while( z1 && *z1 ){ |
| 399 | inherit[0x7f & *(z1++)] = |
| 400 | "<span class=\"ueditInheritReader\">•</span>"; |
| 401 | } |
| 402 | free(z2); |
| 403 | } |
| 404 | if( strcmp(zLogin, "anonymous") ){ |
| 405 | char *z1, *z2; |
| 406 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); |
| 407 | while( z1 && *z1 ){ |
| 408 | inherit[0x7f & *(z1++)] = |
| 409 | "<span class=\"ueditInheritAnonymous\">•</span>"; |
| 410 | } |
| 411 | free(z2); |
| 412 | } |
| 413 | if( strcmp(zLogin, "nobody") ){ |
| 414 | char *z1, *z2; |
| 415 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); |
| 416 | while( z1 && *z1 ){ |
| 417 | inherit[0x7f & *(z1++)] = |
| 418 | "<span class=\"ueditInheritNobody\">•</span>"; |
| 419 | } |
| 420 | free(z2); |
| 421 | } |
| 422 | |
| 423 | /* Begin generating the page |
| @@ -420,77 +426,79 @@ | |
| 426 | if( uid ){ |
| 427 | style_header(mprintf("Edit User %h", zLogin)); |
| 428 | }else{ |
| 429 | style_header("Add A New User"); |
| 430 | } |
| 431 | @ <div class="ueditCapBox"> |
| 432 | @ <form action="%s(g.zPath)" method="post"><div> |
| 433 | login_insert_csrf_secret(); |
| 434 | @ <table> |
| 435 | @ <tr> |
| 436 | @ <td class="usetupEditLabel">User ID:</td> |
| 437 | if( uid ){ |
| 438 | @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td> |
| 439 | }else{ |
| 440 | @ <td>(new user)<input type="hidden" name="id" value="0" /></td> |
| 441 | } |
| 442 | @ </tr> |
| 443 | @ <tr> |
| 444 | @ <td class="usetupEditLabel">Login:</td> |
| 445 | @ <td><input type="text" name="login" value="%h(zLogin)" /></td> |
| 446 | @ </tr> |
| 447 | @ <tr> |
| 448 | @ <td class="usetupEditLabel">Contact Info:</td> |
| 449 | @ <td><input type="text" name="info" size="40" value="%h(zInfo)" /></td> |
| 450 | @ </tr> |
| 451 | @ <tr> |
| 452 | @ <td class="usetupEditLabel">Capabilities:</td> |
| 453 | @ <td> |
| 454 | #define B(x) inherit[x] |
| 455 | if( g.okSetup ){ |
| 456 | @ <input type="checkbox" name="as"%s(oas) />%s(B('s'))Setup<br /> |
| 457 | } |
| 458 | @ <input type="checkbox" name="aa"%s(oaa) />%s(B('a'))Admin<br /> |
| 459 | @ <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br /> |
| 460 | @ <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br /> |
| 461 | @ <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br /> |
| 462 | @ <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br /> |
| 463 | @ <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br /> |
| 464 | @ <input type="checkbox" name="ah"%s(oah) />%s(B('h'))History<br /> |
| 465 | @ <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br /> |
| 466 | @ <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br /> |
| 467 | @ <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br /> |
| 468 | @ <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br /> |
| 469 | @ <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br /> |
| 470 | @ <input type="checkbox" name="am"%s(oam) />%s(B('m'))Append Wiki<br /> |
| 471 | @ <input type="checkbox" name="ak"%s(oak) />%s(B('k'))Write Wiki<br /> |
| 472 | @ <input type="checkbox" name="ab"%s(oab) />%s(B('b'))Attachments<br /> |
| 473 | @ <input type="checkbox" name="ar"%s(oar) />%s(B('r'))Read Ticket<br /> |
| 474 | @ <input type="checkbox" name="an"%s(oan) />%s(B('n'))New Ticket<br /> |
| 475 | @ <input type="checkbox" name="ac"%s(oac) />%s(B('c'))Append Ticket<br /> |
| 476 | @ <input type="checkbox" name="aw"%s(oaw) />%s(B('w'))Write Ticket<br /> |
| 477 | @ <input type="checkbox" name="at"%s(oat) />%s(B('t'))Ticket Report<br /> |
| 478 | @ <input type="checkbox" name="az"%s(oaz) />%s(B('z'))Download Zip |
| 479 | @ </td> |
| 480 | @ </tr> |
| 481 | @ <tr> |
| 482 | @ <td align="right">Password:</td> |
| 483 | if( zPw[0] ){ |
| 484 | /* Obscure the password for all users */ |
| 485 | @ <td><input type="password" name="pw" value="**********" /></td> |
| 486 | }else{ |
| 487 | /* Show an empty password as an empty input field */ |
| 488 | @ <td><input type="password" name="pw" value="" /></td> |
| 489 | } |
| 490 | @ </tr> |
| 491 | if( !higherUser ){ |
| 492 | @ <tr> |
| 493 | @ <td> </td> |
| 494 | @ <td><input type="submit" name="submit" value="Apply Changes" /></td> |
| 495 | @ </tr> |
| 496 | } |
| 497 | @ </table> |
| 498 | @ </div></form> |
| 499 | @ </div> |
| 500 | @ <h2>Privileges And Capabilities:</h2> |
| 501 | @ <ul> |
| 502 | if( higherUser ){ |
| 503 | @ <li><p><font color="blue"><b> |
| 504 | @ User %h(zLogin) has Setup privileges and you only have Admin privileges |
| @@ -497,95 +505,114 @@ | |
| 505 | @ so you are not permitted to make changes to %h(zLogin). |
| 506 | @ </b></font></p></li> |
| 507 | @ |
| 508 | } |
| 509 | @ <li><p> |
| 510 | @ The <span class="capability">Setup</span> user can make arbitrary |
| 511 | @ configuration changes. An <span class="usertype">Admin</span> user |
| 512 | @ can add other users and change user privileges |
| 513 | @ and reset user passwords. Both automatically get all other privileges |
| 514 | @ listed below. Use these two settings with discretion. |
| 515 | @ </p></li> |
| 516 | @ |
| 517 | @ <li><p> |
| 518 | @ The "<span class="ueditInheritNobody"><big>•</big></span>" mark |
| 519 | @ indicates the privileges of <span class="usertype">nobody</span> that |
| 520 | @ are available to all users regardless of whether or not they are logged in. |
| 521 | @ </p></li> |
| 522 | @ |
| 523 | @ <li><p> |
| 524 | @ The "<span class="ueditInheritAnonymous"><big>•</big></span>" mark |
| 525 | @ indicates the privileges of <span class="usertype">anonymous</span> that |
| 526 | @ are inherited by all logged-in users. |
| 527 | @ </p></li> |
| 528 | @ |
| 529 | @ <li><p> |
| 530 | @ The "<span class="ueditInheritDeveloper"><big>•</big></span>" mark |
| 531 | @ indicates the privileges of <span class="usertype">developer</span> that |
| 532 | @ are inherited by all users with the |
| 533 | @ <span class="capability">Developer</span> privilege. |
| 534 | @ </p></li> |
| 535 | @ |
| 536 | @ <li><p> |
| 537 | @ The "<span class="ueditInheritReader"><big>•</big></span>" mark |
| 538 | @ indicates the privileges of <span class="usertype">reader</span> that |
| 539 | @ are inherited by all users with the <span class="capability">Reader</span> |
| 540 | @ privilege. |
| 541 | @ </p></li> |
| 542 | @ |
| 543 | @ <li><p> |
| 544 | @ The <span class="capability">Delete</span> privilege give the user the |
| 545 | @ ability to erase wiki, tickets, and attachments that have been added |
| 546 | @ by anonymous users. This capability is intended for deletion of spam. |
| 547 | @ The delete capability is only in effect for 24 hours after the item |
| 548 | @ is first posted. The <span class="usertype">Setup</span> user can |
| 549 | @ delete anything at any time. |
| 550 | @ </p></li> |
| 551 | @ |
| 552 | @ <li><p> |
| 553 | @ The <span class="capability">History</span> privilege allows a user |
| 554 | @ to see most hyperlinks. This is recommended ON for most logged-in users |
| 555 | @ but OFF for user "nobody" to avoid problems with spiders trying to walk |
| 556 | @ every historical version of every baseline and file. |
| 557 | @ </p></li> |
| 558 | @ |
| 559 | @ <li><p> |
| 560 | @ The <span class="capability">Zip</span> privilege allows a user to |
| 561 | @ see the "download as ZIP" |
| 562 | @ hyperlink and permits access to the <tt>/zip</tt> page. This allows |
| 563 | @ users to download ZIP archives without granting other rights like |
| 564 | @ <span class="capability">Read</span> or |
| 565 | @ <span class="capability">History</span>. This privilege is recommended for |
| 566 | @ user <span class="usertype">nobody</span> so that automatic package |
| 567 | @ downloaders can obtain the sources without going through the login |
| 568 | @ procedure. |
| 569 | @ </p></li> |
| 570 | @ |
| 571 | @ <li><p> |
| 572 | @ The <span class="capability">Check-in</span> privilege allows remote |
| 573 | @ users to "push". The <span class="capability">Check-out</span> privilege |
| 574 | @ allows remote users to "pull". The <span class="capability">Clone</span> |
| 575 | @ privilege allows remote users to "clone". |
| 576 | @ </p></li> |
| 577 | @ |
| 578 | @ <li><p> |
| 579 | @ The <span class="capability">Read Wiki</span>, |
| 580 | @ <span class="capability">New Wiki</span>, |
| 581 | @ <span class="capability">Append Wiki</span>, and |
| 582 | @ <b>Write Wiki</b> privileges control access to wiki pages. The |
| 583 | @ <span class="capability">Read Ticket</span>, |
| 584 | @ <span class="capability">New Ticket</span>, |
| 585 | @ <span class="capability">Append Ticket</span>, and |
| 586 | @ <span class="capability">Write Ticket</span> privileges control access |
| 587 | @ to trouble tickets. |
| 588 | @ The <span class="capability">Ticket Report</span> privilege allows |
| 589 | @ the user to create or edit ticket report formats. |
| 590 | @ </p></li> |
| 591 | @ |
| 592 | @ <li><p> |
| 593 | @ Users with the <span class="capability">Password</span> privilege |
| 594 | @ are allowed to change their own password. Recommended ON for most |
| 595 | @ users but OFF for special users <span class="usertype">developer</span>, |
| 596 | @ <span class="usertype">anonymous</span>, |
| 597 | @ and <span class="usertype">nobody</span>. |
| 598 | @ </p></li> |
| 599 | @ |
| 600 | @ <li><p> |
| 601 | @ The <span class="capability">EMail</span> privilege allows the display of |
| 602 | @ sensitive information such as the email address of users and contact |
| 603 | @ information on tickets. Recommended OFF for |
| 604 | @ <span class="usertype">anonymousy</span> and for |
| 605 | @ <span class="usertype">nobody</span> but ON for |
| 606 | @ <span class="usertype">developer</span>. |
| 607 | @ </p></li> |
| 608 | @ |
| 609 | @ <li><p> |
| 610 | @ The <span class="capability">Attachment</span> privilege is needed in |
| 611 | @ order to add attachments to tickets or wiki. Write privilege on the |
| 612 | @ ticket or wiki is also required. |
| 613 | @ </p></li> |
| 614 | @ |
| 615 | @ <li><p> |
| 616 | @ Login is prohibited if the password is an empty string. |
| 617 | @ </p></li> |
| 618 | @ </ul> |
| @@ -592,42 +619,46 @@ | |
| 619 | @ |
| 620 | @ <h2>Special Logins</h2> |
| 621 | @ |
| 622 | @ <ul> |
| 623 | @ <li><p> |
| 624 | @ No login is required for user <span class="usertype">nobody</span>. The |
| 625 | @ capabilities of the <span class="usertype">nobody</span> user are |
| 626 | @ inherited by all users, regardless of whether or not they are logged in. |
| 627 | @ To disable universal access to the repository, make sure no user named |
| 628 | @ <span class="usertype">nobody</span> exists or that the |
| 629 | @ <span class="usertype">nobody</span> user has no capabilities |
| 630 | @ enabled. The password for <span class="usertype">nobody</span> is ignore. |
| 631 | @ To avoid problems with spiders overloading the server, it is recommended |
| 632 | @ that the <span class="capability">h</span> (History) capability be turned |
| 633 | @ off for the <span class="usertype">nobody</span> user. |
| 634 | @ </p></li> |
| 635 | @ |
| 636 | @ <li><p> |
| 637 | @ Login is required for user <span class="usertype">anonymous</span> but the |
| 638 | @ password is displayed on the login screen beside the password entry box |
| 639 | @ so anybody who can read should be able to login as anonymous. |
| 640 | @ On the other hand, spiders and web-crawlers will typically not |
| 641 | @ be able to login. Set the capabilities of the |
| 642 | @ <span class="usertype">anonymous</span> |
| 643 | @ user to things that you want any human to be able to do, but not any |
| 644 | @ spider. Every other logged-in user inherits the privileges of |
| 645 | @ <span class="usertype">anonymous</span>. |
| 646 | @ </p></li> |
| 647 | @ |
| 648 | @ <li><p> |
| 649 | @ The <span class="usertype">developer</span> user is intended as a template |
| 650 | @ for trusted users with check-in privileges. When adding new trusted users, |
| 651 | @ simply select the <span class="capability">developer</span> privilege to |
| 652 | @ cause the new user to inherit all privileges of the |
| 653 | @ <span class="usertype">developer</span> |
| 654 | @ user. Similarly, the <span class="usertype">reader</span> user is a |
| 655 | @ template for users who are allowed more access than |
| 656 | @ <span class="usertype">anonymous</span>, |
| 657 | @ but less than a <span class="usertype">developer</span>. |
| 658 | @ </p></li> |
| 659 | @ </ul> |
| 660 | style_footer(); |
| 661 | } |
| 662 | |
| 663 | |
| 664 | /* |
| @@ -651,13 +682,14 @@ | |
| 682 | db_set(zVar, iQ ? "1" : "0", 0); |
| 683 | iVal = iQ; |
| 684 | } |
| 685 | } |
| 686 | if( iVal ){ |
| 687 | @ <input type="checkbox" name="%s(zQParm)" checked="checked" /> |
| 688 | @ <b>%s(zLabel)</b> |
| 689 | }else{ |
| 690 | @ <input type="checkbox" name="%s(zQParm)" /><b>%s(zLabel)</b> |
| 691 | } |
| 692 | } |
| 693 | |
| 694 | /* |
| 695 | ** Generate an entry box for an attribute. |
| @@ -674,11 +706,11 @@ | |
| 706 | if( zQ && strcmp(zQ,zVal)!=0 ){ |
| 707 | login_verify_csrf_secret(); |
| 708 | db_set(zVar, zQ, 0); |
| 709 | zVal = zQ; |
| 710 | } |
| 711 | @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" /> |
| 712 | @ <b>%s(zLabel)</b> |
| 713 | } |
| 714 | |
| 715 | /* |
| 716 | ** Generate a text box for an attribute. |
| @@ -698,11 +730,12 @@ | |
| 730 | db_set(zVar, zQ, 0); |
| 731 | z = zQ; |
| 732 | } |
| 733 | if( rows>0 && cols>0 ){ |
| 734 | @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea> |
| 735 | if (zLabel && *zLabel) |
| 736 | @ <span class="textareaLabel">%s(zLabel)</span> |
| 737 | } |
| 738 | } |
| 739 | |
| 740 | |
| 741 | /* |
| @@ -714,57 +747,57 @@ | |
| 747 | login_needed(); |
| 748 | } |
| 749 | |
| 750 | style_header("Access Control Settings"); |
| 751 | db_begin_transaction(); |
| 752 | @ <form action="%s(g.zBaseURL)/setup_access" method="post"><div> |
| 753 | login_insert_csrf_secret(); |
| 754 | @ <hr /> |
| 755 | onoff_attribute("Require password for local access", |
| 756 | "localauth", "localauth", 0); |
| 757 | @ <p>When enabled, the password sign-in is required for |
| 758 | @ web access coming from 127.0.0.1. When disabled, web access |
| 759 | @ from 127.0.0.1 is allows without any login - the user id is selected |
| 760 | @ from the ~/.fossil database. Password login is always required |
| 761 | @ for incoming web connections on internet addresses other than |
| 762 | @ 127.0.0.1.</p> |
| 763 | |
| 764 | @ <hr /> |
| 765 | onoff_attribute("Allow REMOTE_USER authentication", |
| 766 | "remote_user_ok", "remote_user_ok", 0); |
| 767 | @ <p>When enabled, if the REMOTE_USER environment variable is set to the |
| 768 | @ login name of a valid user and no other login credentials are available, |
| 769 | @ then the REMOTE_USER is accepted as an authenticated user. |
| 770 | @ </p> |
| 771 | |
| 772 | @ <hr /> |
| 773 | entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766"); |
| 774 | @ <p>The number of hours for which a login is valid. This must be a |
| 775 | @ positive number. The default is 8760 hours which is approximately equal |
| 776 | @ to a year.</p> |
| 777 | |
| 778 | @ <hr /> |
| 779 | entry_attribute("Download packet limit", 10, "max-download", "mxdwn", |
| 780 | "5000000"); |
| 781 | @ <p>Fossil tries to limit out-bound sync, clone, and pull packets |
| 782 | @ to this many bytes, uncompressed. If the client requires more data |
| 783 | @ than this, then the client will issue multiple HTTP requests. |
| 784 | @ Values below 1 million are not recommended. 5 million is a |
| 785 | @ reasonable number.</p> |
| 786 | |
| 787 | @ <hr /> |
| 788 | onoff_attribute("Show javascript button to fill in CAPTCHA", |
| 789 | "auto-captcha", "autocaptcha", 0); |
| 790 | @ <p>When enabled, a button appears on the login screen for user |
| 791 | @ "anonymous" that will automatically fill in the CAPTCHA password. |
| 792 | @ This is less secure that forcing the user to do it manually, but is |
| 793 | @ probably secure enough and it is certainly more convenient for |
| 794 | @ anonymous users.</p> |
| 795 | |
| 796 | @ <hr /> |
| 797 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 798 | @ </div></form> |
| 799 | db_end_transaction(0); |
| 800 | style_footer(); |
| 801 | } |
| 802 | |
| 803 | /* |
| @@ -776,42 +809,42 @@ | |
| 809 | login_needed(); |
| 810 | } |
| 811 | |
| 812 | style_header("Timeline Display Preferences"); |
| 813 | db_begin_transaction(); |
| 814 | @ <form action="%s(g.zBaseURL)/setup_timeline" method="post"><div> |
| 815 | login_insert_csrf_secret(); |
| 816 | |
| 817 | @ <hr /> |
| 818 | onoff_attribute("Allow block-markup in timeline", |
| 819 | "timeline-block-markup", "tbm", 0); |
| 820 | @ <p>In timeline displays, check-in comments can be displayed with or |
| 821 | @ without block markup (paragraphs, tables, etc.)</p> |
| 822 | |
| 823 | @ <hr /> |
| 824 | onoff_attribute("Use Universal Coordinated Time (UTC)", |
| 825 | "timeline-utc", "utc", 1); |
| 826 | @ <p>Show times as UTC (also sometimes called Greenwich Mean Time (GMT) or |
| 827 | @ Zulu) instead of in local time.</p> |
| 828 | |
| 829 | @ <hr /> |
| 830 | onoff_attribute("Show version differences by default", |
| 831 | "show-version-diffs", "vdiff", 0); |
| 832 | @ <p>On the version-information pages linked from the timeline can either |
| 833 | @ show complete diffs of all file changes, or can just list the names of |
| 834 | @ the files that have changed. Users can get to either page by |
| 835 | @ clicking. This setting selects the default.</p> |
| 836 | |
| 837 | @ <hr /> |
| 838 | entry_attribute("Max timeline comment length", 6, |
| 839 | "timeline-max-comment", "tmc", "0"); |
| 840 | @ <p>The maximum length of a comment to be displayed in a timeline. |
| 841 | @ "0" there is no length limit.</p> |
| 842 | |
| 843 | @ <hr /> |
| 844 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 845 | @ </div></form> |
| 846 | db_end_transaction(0); |
| 847 | style_footer(); |
| 848 | } |
| 849 | |
| 850 | /* |
| @@ -823,11 +856,11 @@ | |
| 856 | login_needed(); |
| 857 | } |
| 858 | |
| 859 | style_header("WWW Configuration"); |
| 860 | db_begin_transaction(); |
| 861 | @ <form action="%s(g.zBaseURL)/setup_config" method="post"><div> |
| 862 | login_insert_csrf_secret(); |
| 863 | @ <hr /> |
| 864 | entry_attribute("Project Name", 60, "project-name", "pn", ""); |
| 865 | @ <p>Give your project a name so visitors know what this site is about. |
| 866 | @ The project name will also be used as the RSS feed title.</p> |
| @@ -840,36 +873,37 @@ | |
| 873 | entry_attribute("Index Page", 60, "index-page", "idxpg", "/home"); |
| 874 | @ <p>Enter the pathname of the page to display when the "Home" menu |
| 875 | @ option is selected and when no pathname is |
| 876 | @ specified in the URL. For example, if you visit the url:</p> |
| 877 | @ |
| 878 | @ <blockquote><p>%h(g.zBaseURL)</p></blockquote> |
| 879 | @ |
| 880 | @ <p>And you have specified an index page of "/home" the above will |
| 881 | @ automatically redirect to:</p> |
| 882 | @ |
| 883 | @ <blockquote><p>%h(g.zBaseURL)/home</p></blockquote> |
| 884 | @ |
| 885 | @ <p>The default "/home" page displays a Wiki page with the same name |
| 886 | @ as the Project Name specified above. Some sites prefer to redirect |
| 887 | @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p> |
| 888 | @ <hr /> |
| 889 | onoff_attribute("Use HTML as wiki markup language", |
| 890 | "wiki-use-html", "wiki-use-html", 0); |
| 891 | @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed |
| 892 | @ but all other wiki formatting will be ignored. This option is helpful |
| 893 | @ if you have chosen to use a rich HTML editor for wiki markup such as |
| 894 | @ TinyMCE.</p> |
| 895 | @ <p><strong>CAUTION:</strong> when |
| 896 | @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki. |
| 897 | @ No sanitization is done. This means that it is very possible for malicious |
| 898 | @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p> |
| 899 | @ <p>This should <strong>only</strong> be enabled when wiki editing is limited |
| 900 | @ to trusted users. It should <strong>not</strong> be used on a publically |
| 901 | @ editable wiki.</p> |
| 902 | @ <hr /> |
| 903 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 904 | @ </div></form> |
| 905 | db_end_transaction(0); |
| 906 | style_footer(); |
| 907 | } |
| 908 | |
| 909 | /* |
| @@ -892,30 +926,27 @@ | |
| 926 | if( P("submit")!=0 ){ |
| 927 | db_end_transaction(0); |
| 928 | cgi_redirect("setup_editcss"); |
| 929 | } |
| 930 | style_header("Edit CSS"); |
| 931 | @ <form action="%s(g.zBaseURL)/setup_editcss" method="post"><div> |
| 932 | login_insert_csrf_secret(); |
| 933 | @ Edit the CSS below:<br /> |
| 934 | textarea_attribute("", 40, 80, "css", "css", zDefaultCSS); |
| 935 | @ <br /> |
| 936 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 937 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 938 | @ </div></form> |
| 939 | @ <p><span class="note">Note:</span> Press your browser Reload button after |
| 940 | @ modifying the CSS in order to pull in the modified CSS file.</p> |
| 941 | @ <hr /> |
| 942 | @ The default CSS is shown below for reference. Other examples |
| 943 | @ of CSS files can be seen on the <a href="setup_skin">skins page</a>. |
| 944 | @ See also the <a href="setup_header">header</a> and |
| 945 | @ <a href="setup_footer">footer</a> editing screens. |
| 946 | @ <blockquote><pre> |
| 947 | cgi_append_default_css(); |
| 948 | @ </pre></blockquote> |
| 949 | style_footer(); |
| 950 | db_end_transaction(0); |
| 951 | } |
| 952 | |
| @@ -933,21 +964,21 @@ | |
| 964 | cgi_replace_parameter("header", zDefaultHeader); |
| 965 | }else{ |
| 966 | textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader); |
| 967 | } |
| 968 | style_header("Edit Page Header"); |
| 969 | @ <form action="%s(g.zBaseURL)/setup_header" method="post"><div> |
| 970 | login_insert_csrf_secret(); |
| 971 | @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to |
| 972 | @ generate the beginning of every page through start of the main |
| 973 | @ menu.</p> |
| 974 | textarea_attribute("", 40, 80, "header", "header", zDefaultHeader); |
| 975 | @ <br /> |
| 976 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 977 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 978 | @ </div></form> |
| 979 | @ <hr /> |
| 980 | @ The default header is shown below for reference. Other examples |
| 981 | @ of headers can be seen on the <a href="setup_skin">skins page</a>. |
| 982 | @ See also the <a href="setup_editcss">CSS</a> and |
| 983 | @ <a href="setup_footer">footer</a> editing screeens. |
| 984 | @ <blockquote><pre> |
| @@ -971,20 +1002,20 @@ | |
| 1002 | cgi_replace_parameter("footer", zDefaultFooter); |
| 1003 | }else{ |
| 1004 | textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter); |
| 1005 | } |
| 1006 | style_header("Edit Page Footer"); |
| 1007 | @ <form action="%s(g.zBaseURL)/setup_footer" method="post"><div> |
| 1008 | login_insert_csrf_secret(); |
| 1009 | @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to |
| 1010 | @ generate the end of every page.</p> |
| 1011 | textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter); |
| 1012 | @ <br /> |
| 1013 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1014 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1015 | @ </div></form> |
| 1016 | @ <hr /> |
| 1017 | @ The default footer is shown below for reference. Other examples |
| 1018 | @ of footers can be seen on the <a href="setup_skin">skins page</a>. |
| 1019 | @ See also the <a href="setup_editcss">CSS</a> and |
| 1020 | @ <a href="setup_header">header</a> editing screens. |
| 1021 | @ <blockquote><pre> |
| @@ -1034,31 +1065,31 @@ | |
| 1065 | cgi_redirect("setup_logo"); |
| 1066 | } |
| 1067 | style_header("Edit Project Logo"); |
| 1068 | @ <p>The current project logo has a MIME-Type of <b>%h(zMime)</b> and looks |
| 1069 | @ like this:</p> |
| 1070 | @ <blockquote><p><img src="%s(g.zTop)/logo" alt="logo" /></p></blockquote> |
| 1071 | @ |
| 1072 | @ <p>The logo is accessible to all users at this URL: |
| 1073 | @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>. |
| 1074 | @ The logo may or may not appear on each |
| 1075 | @ page depending on the <a href="setup_editcss">CSS</a> and |
| 1076 | @ <a href="setup_header">header setup</a>.</p> |
| 1077 | @ |
| 1078 | @ <form action="%s(g.zBaseURL)/setup_logo" method="post" |
| 1079 | @ enctype="multipart/form-data"><div> |
| 1080 | @ <p>To set a new logo image, select a file to use as the logo using |
| 1081 | @ the entry box below and then press the "Change Logo" button.</p> |
| 1082 | login_insert_csrf_secret(); |
| 1083 | @ Logo Image file: |
| 1084 | @ <input type="file" name="im" size="60" accept="image/*" /><br /> |
| 1085 | @ <input type="submit" name="set" value="Change Logo" /> |
| 1086 | @ <input type="submit" name="clr" value="Revert To Default" /> |
| 1087 | @ </div></form> |
| 1088 | @ |
| 1089 | @ <p><span class="note">Note:</span> Your browser has probably cached the |
| 1090 | @ logo image, so you will probably need to press the Reload button on your |
| 1091 | @ browser after changing the logo to provoke your browser to reload the new |
| 1092 | @ logo image. </p> |
| 1093 | style_footer(); |
| 1094 | db_end_transaction(0); |
| 1095 | } |
| 1096 |
+29
-26
| --- src/shun.c | ||
| +++ src/shun.c | ||
| @@ -112,63 +112,63 @@ | ||
| 112 | 112 | @ or artifacts that by design or accident interfere with the processing |
| 113 | 113 | @ of the repository. Do not shun artifacts merely to remove them from |
| 114 | 114 | @ sight - set the "hidden" tag on such artifacts instead.</p> |
| 115 | 115 | @ |
| 116 | 116 | @ <blockquote> |
| 117 | - @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> | |
| 117 | + @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div> | |
| 118 | 118 | login_insert_csrf_secret(); |
| 119 | - @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50"> | |
| 120 | - @ <input type="submit" name="add" value="Shun"> | |
| 121 | - @ </form> | |
| 119 | + @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" /> | |
| 120 | + @ <input type="submit" name="add" value="Shun" /> | |
| 121 | + @ </div></form> | |
| 122 | 122 | @ </blockquote> |
| 123 | 123 | @ |
| 124 | 124 | @ <p>Enter the UUID of a previous shunned artifact to cause it to be |
| 125 | 125 | @ accepted again in the repository. The artifact content is not |
| 126 | 126 | @ restored because the content is unknown. The only change is that |
| 127 | 127 | @ the formerly shunned artifact will be accepted on subsequent sync |
| 128 | 128 | @ operations.</p> |
| 129 | 129 | @ |
| 130 | 130 | @ <blockquote> |
| 131 | - @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> | |
| 131 | + @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div> | |
| 132 | 132 | login_insert_csrf_secret(); |
| 133 | - @ <input type="text" name="uuid" size="50"> | |
| 134 | - @ <input type="submit" name="sub" value="Accept"> | |
| 135 | - @ </form> | |
| 133 | + @ <input type="text" name="uuid" size="50" /> | |
| 134 | + @ <input type="submit" name="sub" value="Accept" /> | |
| 135 | + @ </div></form> | |
| 136 | 136 | @ </blockquote> |
| 137 | 137 | @ |
| 138 | 138 | @ <p>Press the Rebuild button below to rebuild the respository. The |
| 139 | 139 | @ content of newly shunned artifacts is not purged until the repository |
| 140 | 140 | @ is rebuilt. On larger repositories, the rebuild may take minute or |
| 141 | 141 | @ two, so be patient after pressing the button.</p> |
| 142 | 142 | @ |
| 143 | 143 | @ <blockquote> |
| 144 | - @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> | |
| 144 | + @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div> | |
| 145 | 145 | login_insert_csrf_secret(); |
| 146 | - @ <input type="submit" name="rebuild" value="Rebuild"> | |
| 147 | - @ </form> | |
| 146 | + @ <input type="submit" name="rebuild" value="Rebuild" /> | |
| 147 | + @ </div></form> | |
| 148 | 148 | @ </blockquote> |
| 149 | 149 | @ |
| 150 | - @ <hr><p>Shunned Artifacts:</p> | |
| 151 | - @ <blockquote> | |
| 150 | + @ <hr /><p>Shunned Artifacts:</p> | |
| 151 | + @ <blockquote><p> | |
| 152 | 152 | db_prepare(&q, |
| 153 | 153 | "SELECT uuid, EXISTS(SELECT 1 FROM blob WHERE blob.uuid=shun.uuid)" |
| 154 | 154 | " FROM shun ORDER BY uuid"); |
| 155 | 155 | while( db_step(&q)==SQLITE_ROW ){ |
| 156 | 156 | const char *zUuid = db_column_text(&q, 0); |
| 157 | 157 | int stillExists = db_column_int(&q, 1); |
| 158 | 158 | cnt++; |
| 159 | 159 | if( stillExists ){ |
| 160 | - @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br> | |
| 160 | + @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br /> | |
| 161 | 161 | }else{ |
| 162 | - @ <b>%s(zUuid)</b><br> | |
| 162 | + @ <b>%s(zUuid)</b><br /> | |
| 163 | 163 | } |
| 164 | 164 | } |
| 165 | 165 | if( cnt==0 ){ |
| 166 | 166 | @ <i>no artifacts are shunned on this server</i> |
| 167 | 167 | } |
| 168 | 168 | db_finalize(&q); |
| 169 | - @ </blockquote> | |
| 169 | + @ </p></blockquote> | |
| 170 | 170 | style_footer(); |
| 171 | 171 | } |
| 172 | 172 | |
| 173 | 173 | /* |
| 174 | 174 | ** Remove from the BLOB table all artifacts that are in the SHUN table. |
| @@ -229,14 +229,15 @@ | ||
| 229 | 229 | @ |
| 230 | 230 | @ <p>Click on the "rcvid" to show a list of specific artifacts received |
| 231 | 231 | @ by a transaction. After identifying illicit artifacts, remove them |
| 232 | 232 | @ using the "Shun" feature.</p> |
| 233 | 233 | @ |
| 234 | - @ <table cellpadding=0 cellspacing=0 border=0> | |
| 235 | - @ <tr><th>rcvid</th><th width=15> | |
| 236 | - @ <th>Date</th><th width=15><th>User</th> | |
| 237 | - @ <th width=15><th>IP Address</th></tr> | |
| 234 | + @ <table cellpadding="0" cellspacing="0" border="0"> | |
| 235 | + @ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th> | |
| 236 | + @ <th style="padding-right: 15px;text-align: left;">Date</th> | |
| 237 | + @ <th style="padding-right: 15px;text-align: left;">User</th> | |
| 238 | + @ <th style="text-align: left;">IP Address</th></tr> | |
| 238 | 239 | cnt = 0; |
| 239 | 240 | while( db_step(&q)==SQLITE_ROW ){ |
| 240 | 241 | int rcvid = db_column_int(&q, 0); |
| 241 | 242 | const char *zUser = db_column_text(&q, 1); |
| 242 | 243 | const char *zDate = db_column_text(&q, 2); |
| @@ -245,14 +246,14 @@ | ||
| 245 | 246 | style_submenu_element("Older", "Older", |
| 246 | 247 | "rcvfromlist?ofst=%d", ofst+30); |
| 247 | 248 | }else{ |
| 248 | 249 | cnt++; |
| 249 | 250 | @ <tr> |
| 250 | - @ <td><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td><td> | |
| 251 | - @ <td>%s(zDate)</td><td> | |
| 252 | - @ <td>%h(zUser)</td><td> | |
| 253 | - @ <td> %s(zIpAddr) </td> | |
| 251 | + @ <td style="padding-right: 15px;text-align: right;"><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td> | |
| 252 | + @ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td> | |
| 253 | + @ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td> | |
| 254 | + @ <td style="text-align: left;">%s(zIpAddr)</td> | |
| 254 | 255 | @ </tr> |
| 255 | 256 | } |
| 256 | 257 | } |
| 257 | 258 | db_finalize(&q); |
| 258 | 259 | @ </table> |
| @@ -277,11 +278,11 @@ | ||
| 277 | 278 | "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" |
| 278 | 279 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 279 | 280 | " WHERE rcvid=%d", |
| 280 | 281 | rcvid |
| 281 | 282 | ); |
| 282 | - @ <table cellspacing=15 cellpadding=0 border=0> | |
| 283 | + @ <table cellspacing="15" cellpadding="0" border="0"> | |
| 283 | 284 | @ <tr><td valign="top" align="right"><b>rcvid:</b></td> |
| 284 | 285 | @ <td valign="top">%d(rcvid)</td></tr> |
| 285 | 286 | if( db_step(&q)==SQLITE_ROW ){ |
| 286 | 287 | const char *zUser = db_column_text(&q, 0); |
| 287 | 288 | const char *zDate = db_column_text(&q, 1); |
| @@ -302,10 +303,12 @@ | ||
| 302 | 303 | while( db_step(&q)==SQLITE_ROW ){ |
| 303 | 304 | int rid = db_column_int(&q, 0); |
| 304 | 305 | const char *zUuid = db_column_text(&q, 1); |
| 305 | 306 | int size = db_column_int(&q, 2); |
| 306 | 307 | @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">%s(zUuid)</a> |
| 307 | - @ (rid: %d(rid), size: %d(size))<br> | |
| 308 | + @ (rid: %d(rid), size: %d(size))<br /> | |
| 308 | 309 | } |
| 309 | 310 | @ </td></tr> |
| 310 | 311 | @ </table> |
| 312 | + db_finalize(&q); | |
| 313 | + style_footer(); | |
| 311 | 314 | } |
| 312 | 315 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -112,63 +112,63 @@ | |
| 112 | @ or artifacts that by design or accident interfere with the processing |
| 113 | @ of the repository. Do not shun artifacts merely to remove them from |
| 114 | @ sight - set the "hidden" tag on such artifacts instead.</p> |
| 115 | @ |
| 116 | @ <blockquote> |
| 117 | @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> |
| 118 | login_insert_csrf_secret(); |
| 119 | @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50"> |
| 120 | @ <input type="submit" name="add" value="Shun"> |
| 121 | @ </form> |
| 122 | @ </blockquote> |
| 123 | @ |
| 124 | @ <p>Enter the UUID of a previous shunned artifact to cause it to be |
| 125 | @ accepted again in the repository. The artifact content is not |
| 126 | @ restored because the content is unknown. The only change is that |
| 127 | @ the formerly shunned artifact will be accepted on subsequent sync |
| 128 | @ operations.</p> |
| 129 | @ |
| 130 | @ <blockquote> |
| 131 | @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> |
| 132 | login_insert_csrf_secret(); |
| 133 | @ <input type="text" name="uuid" size="50"> |
| 134 | @ <input type="submit" name="sub" value="Accept"> |
| 135 | @ </form> |
| 136 | @ </blockquote> |
| 137 | @ |
| 138 | @ <p>Press the Rebuild button below to rebuild the respository. The |
| 139 | @ content of newly shunned artifacts is not purged until the repository |
| 140 | @ is rebuilt. On larger repositories, the rebuild may take minute or |
| 141 | @ two, so be patient after pressing the button.</p> |
| 142 | @ |
| 143 | @ <blockquote> |
| 144 | @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> |
| 145 | login_insert_csrf_secret(); |
| 146 | @ <input type="submit" name="rebuild" value="Rebuild"> |
| 147 | @ </form> |
| 148 | @ </blockquote> |
| 149 | @ |
| 150 | @ <hr><p>Shunned Artifacts:</p> |
| 151 | @ <blockquote> |
| 152 | db_prepare(&q, |
| 153 | "SELECT uuid, EXISTS(SELECT 1 FROM blob WHERE blob.uuid=shun.uuid)" |
| 154 | " FROM shun ORDER BY uuid"); |
| 155 | while( db_step(&q)==SQLITE_ROW ){ |
| 156 | const char *zUuid = db_column_text(&q, 0); |
| 157 | int stillExists = db_column_int(&q, 1); |
| 158 | cnt++; |
| 159 | if( stillExists ){ |
| 160 | @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br> |
| 161 | }else{ |
| 162 | @ <b>%s(zUuid)</b><br> |
| 163 | } |
| 164 | } |
| 165 | if( cnt==0 ){ |
| 166 | @ <i>no artifacts are shunned on this server</i> |
| 167 | } |
| 168 | db_finalize(&q); |
| 169 | @ </blockquote> |
| 170 | style_footer(); |
| 171 | } |
| 172 | |
| 173 | /* |
| 174 | ** Remove from the BLOB table all artifacts that are in the SHUN table. |
| @@ -229,14 +229,15 @@ | |
| 229 | @ |
| 230 | @ <p>Click on the "rcvid" to show a list of specific artifacts received |
| 231 | @ by a transaction. After identifying illicit artifacts, remove them |
| 232 | @ using the "Shun" feature.</p> |
| 233 | @ |
| 234 | @ <table cellpadding=0 cellspacing=0 border=0> |
| 235 | @ <tr><th>rcvid</th><th width=15> |
| 236 | @ <th>Date</th><th width=15><th>User</th> |
| 237 | @ <th width=15><th>IP Address</th></tr> |
| 238 | cnt = 0; |
| 239 | while( db_step(&q)==SQLITE_ROW ){ |
| 240 | int rcvid = db_column_int(&q, 0); |
| 241 | const char *zUser = db_column_text(&q, 1); |
| 242 | const char *zDate = db_column_text(&q, 2); |
| @@ -245,14 +246,14 @@ | |
| 245 | style_submenu_element("Older", "Older", |
| 246 | "rcvfromlist?ofst=%d", ofst+30); |
| 247 | }else{ |
| 248 | cnt++; |
| 249 | @ <tr> |
| 250 | @ <td><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td><td> |
| 251 | @ <td>%s(zDate)</td><td> |
| 252 | @ <td>%h(zUser)</td><td> |
| 253 | @ <td> %s(zIpAddr) </td> |
| 254 | @ </tr> |
| 255 | } |
| 256 | } |
| 257 | db_finalize(&q); |
| 258 | @ </table> |
| @@ -277,11 +278,11 @@ | |
| 277 | "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" |
| 278 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 279 | " WHERE rcvid=%d", |
| 280 | rcvid |
| 281 | ); |
| 282 | @ <table cellspacing=15 cellpadding=0 border=0> |
| 283 | @ <tr><td valign="top" align="right"><b>rcvid:</b></td> |
| 284 | @ <td valign="top">%d(rcvid)</td></tr> |
| 285 | if( db_step(&q)==SQLITE_ROW ){ |
| 286 | const char *zUser = db_column_text(&q, 0); |
| 287 | const char *zDate = db_column_text(&q, 1); |
| @@ -302,10 +303,12 @@ | |
| 302 | while( db_step(&q)==SQLITE_ROW ){ |
| 303 | int rid = db_column_int(&q, 0); |
| 304 | const char *zUuid = db_column_text(&q, 1); |
| 305 | int size = db_column_int(&q, 2); |
| 306 | @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">%s(zUuid)</a> |
| 307 | @ (rid: %d(rid), size: %d(size))<br> |
| 308 | } |
| 309 | @ </td></tr> |
| 310 | @ </table> |
| 311 | } |
| 312 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -112,63 +112,63 @@ | |
| 112 | @ or artifacts that by design or accident interfere with the processing |
| 113 | @ of the repository. Do not shun artifacts merely to remove them from |
| 114 | @ sight - set the "hidden" tag on such artifacts instead.</p> |
| 115 | @ |
| 116 | @ <blockquote> |
| 117 | @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div> |
| 118 | login_insert_csrf_secret(); |
| 119 | @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" /> |
| 120 | @ <input type="submit" name="add" value="Shun" /> |
| 121 | @ </div></form> |
| 122 | @ </blockquote> |
| 123 | @ |
| 124 | @ <p>Enter the UUID of a previous shunned artifact to cause it to be |
| 125 | @ accepted again in the repository. The artifact content is not |
| 126 | @ restored because the content is unknown. The only change is that |
| 127 | @ the formerly shunned artifact will be accepted on subsequent sync |
| 128 | @ operations.</p> |
| 129 | @ |
| 130 | @ <blockquote> |
| 131 | @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div> |
| 132 | login_insert_csrf_secret(); |
| 133 | @ <input type="text" name="uuid" size="50" /> |
| 134 | @ <input type="submit" name="sub" value="Accept" /> |
| 135 | @ </div></form> |
| 136 | @ </blockquote> |
| 137 | @ |
| 138 | @ <p>Press the Rebuild button below to rebuild the respository. The |
| 139 | @ content of newly shunned artifacts is not purged until the repository |
| 140 | @ is rebuilt. On larger repositories, the rebuild may take minute or |
| 141 | @ two, so be patient after pressing the button.</p> |
| 142 | @ |
| 143 | @ <blockquote> |
| 144 | @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div> |
| 145 | login_insert_csrf_secret(); |
| 146 | @ <input type="submit" name="rebuild" value="Rebuild" /> |
| 147 | @ </div></form> |
| 148 | @ </blockquote> |
| 149 | @ |
| 150 | @ <hr /><p>Shunned Artifacts:</p> |
| 151 | @ <blockquote><p> |
| 152 | db_prepare(&q, |
| 153 | "SELECT uuid, EXISTS(SELECT 1 FROM blob WHERE blob.uuid=shun.uuid)" |
| 154 | " FROM shun ORDER BY uuid"); |
| 155 | while( db_step(&q)==SQLITE_ROW ){ |
| 156 | const char *zUuid = db_column_text(&q, 0); |
| 157 | int stillExists = db_column_int(&q, 1); |
| 158 | cnt++; |
| 159 | if( stillExists ){ |
| 160 | @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br /> |
| 161 | }else{ |
| 162 | @ <b>%s(zUuid)</b><br /> |
| 163 | } |
| 164 | } |
| 165 | if( cnt==0 ){ |
| 166 | @ <i>no artifacts are shunned on this server</i> |
| 167 | } |
| 168 | db_finalize(&q); |
| 169 | @ </p></blockquote> |
| 170 | style_footer(); |
| 171 | } |
| 172 | |
| 173 | /* |
| 174 | ** Remove from the BLOB table all artifacts that are in the SHUN table. |
| @@ -229,14 +229,15 @@ | |
| 229 | @ |
| 230 | @ <p>Click on the "rcvid" to show a list of specific artifacts received |
| 231 | @ by a transaction. After identifying illicit artifacts, remove them |
| 232 | @ using the "Shun" feature.</p> |
| 233 | @ |
| 234 | @ <table cellpadding="0" cellspacing="0" border="0"> |
| 235 | @ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th> |
| 236 | @ <th style="padding-right: 15px;text-align: left;">Date</th> |
| 237 | @ <th style="padding-right: 15px;text-align: left;">User</th> |
| 238 | @ <th style="text-align: left;">IP Address</th></tr> |
| 239 | cnt = 0; |
| 240 | while( db_step(&q)==SQLITE_ROW ){ |
| 241 | int rcvid = db_column_int(&q, 0); |
| 242 | const char *zUser = db_column_text(&q, 1); |
| 243 | const char *zDate = db_column_text(&q, 2); |
| @@ -245,14 +246,14 @@ | |
| 246 | style_submenu_element("Older", "Older", |
| 247 | "rcvfromlist?ofst=%d", ofst+30); |
| 248 | }else{ |
| 249 | cnt++; |
| 250 | @ <tr> |
| 251 | @ <td style="padding-right: 15px;text-align: right;"><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td> |
| 252 | @ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td> |
| 253 | @ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td> |
| 254 | @ <td style="text-align: left;">%s(zIpAddr)</td> |
| 255 | @ </tr> |
| 256 | } |
| 257 | } |
| 258 | db_finalize(&q); |
| 259 | @ </table> |
| @@ -277,11 +278,11 @@ | |
| 278 | "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" |
| 279 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 280 | " WHERE rcvid=%d", |
| 281 | rcvid |
| 282 | ); |
| 283 | @ <table cellspacing="15" cellpadding="0" border="0"> |
| 284 | @ <tr><td valign="top" align="right"><b>rcvid:</b></td> |
| 285 | @ <td valign="top">%d(rcvid)</td></tr> |
| 286 | if( db_step(&q)==SQLITE_ROW ){ |
| 287 | const char *zUser = db_column_text(&q, 0); |
| 288 | const char *zDate = db_column_text(&q, 1); |
| @@ -302,10 +303,12 @@ | |
| 303 | while( db_step(&q)==SQLITE_ROW ){ |
| 304 | int rid = db_column_int(&q, 0); |
| 305 | const char *zUuid = db_column_text(&q, 1); |
| 306 | int size = db_column_int(&q, 2); |
| 307 | @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">%s(zUuid)</a> |
| 308 | @ (rid: %d(rid), size: %d(size))<br /> |
| 309 | } |
| 310 | @ </td></tr> |
| 311 | @ </table> |
| 312 | db_finalize(&q); |
| 313 | style_footer(); |
| 314 | } |
| 315 |
+11
-11
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -165,11 +165,11 @@ | ||
| 165 | 165 | @ <body> |
| 166 | 166 | @ <div class="header"> |
| 167 | 167 | @ <div class="logo"> |
| 168 | 168 | @ <img src="$baseurl/logo" alt="logo"> |
| 169 | 169 | @ </div> |
| 170 | -@ <div class="title"><small>$<project_name></small><br>$<title></div> | |
| 170 | +@ <div class="title"><small>$<project_name></small><br />$<title></div> | |
| 171 | 171 | @ <div class="status"><nobr><th1> |
| 172 | 172 | @ if {[info exists login]} { |
| 173 | 173 | @ puts "Logged in as $login" |
| 174 | 174 | @ } else { |
| 175 | 175 | @ puts "Not logged in" |
| @@ -600,11 +600,11 @@ | ||
| 600 | 600 | @ </head> |
| 601 | 601 | @ <body> |
| 602 | 602 | @ <div class="header"> |
| 603 | 603 | @ <div class="logo"> |
| 604 | 604 | @ <!-- <img src="$baseurl/logo" alt="logo"> --> |
| 605 | -@ <br><nobr>$<project_name></nobr> | |
| 605 | +@ <br /><nobr>$<project_name></nobr> | |
| 606 | 606 | @ </div> |
| 607 | 607 | @ <div class="title">$<title></div> |
| 608 | 608 | @ <div class="status"><nobr><th1> |
| 609 | 609 | @ if {[info exists login]} { |
| 610 | 610 | @ puts "Logged in as $login" |
| @@ -731,18 +731,18 @@ | ||
| 731 | 731 | db_begin_transaction(); |
| 732 | 732 | |
| 733 | 733 | /* Process requests to delete a user-defined skin */ |
| 734 | 734 | if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){ |
| 735 | 735 | style_header("Confirm Custom Skin Delete"); |
| 736 | - @ <form action="%s(g.zBaseURL)/setup_skin" method="POST"> | |
| 736 | + @ <form action="%s(g.zBaseURL)/setup_skin" method="post"><div> | |
| 737 | 737 | @ <p>Deletion of a custom skin is a permanent action that cannot |
| 738 | 738 | @ be undone. Please confirm that this is what you want to do:</p> |
| 739 | - @ <input type="hidden" name="sn" value="%h(P("sn"))"> | |
| 740 | - @ <input type="submit" name="del2" value="Confirm - Delete The Skin"> | |
| 741 | - @ <input type="submit" name="cancel" value="Cancel - Do Not Delete"> | |
| 739 | + @ <input type="hidden" name="sn" value="%h(P("sn"))" /> | |
| 740 | + @ <input type="submit" name="del2" value="Confirm - Delete The Skin" /> | |
| 741 | + @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" /> | |
| 742 | 742 | login_insert_csrf_secret(); |
| 743 | - @ </form> | |
| 743 | + @ </div></form> | |
| 744 | 744 | style_footer(); |
| 745 | 745 | return; |
| 746 | 746 | } |
| 747 | 747 | if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){ |
| 748 | 748 | db_multi_exec("DELETE FROM config WHERE name=%Q", zName); |
| @@ -812,15 +812,15 @@ | ||
| 812 | 812 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 813 | 813 | z = aBuiltinSkin[i].zName; |
| 814 | 814 | if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ |
| 815 | 815 | @ <li><p>%h(z). <b>Currently In Use</b></p> |
| 816 | 816 | }else{ |
| 817 | - @ <li><form action="%s(g.zBaseURL)/setup_skin" method="POST"> | |
| 817 | + @ <li><form action="%s(g.zBaseURL)/setup_skin" method="post"><div> | |
| 818 | 818 | @ %h(z). |
| 819 | - @ <input type="hidden" name="sn" value="%h(z)"> | |
| 820 | - @ <input type="submit" name="load" value="Use This Skin"> | |
| 821 | - @ </form></li> | |
| 819 | + @ <input type="hidden" name="sn" value="%h(z)" /> | |
| 820 | + @ <input type="submit" name="load" value="Use This Skin" /> | |
| 821 | + @ </div></form></li> | |
| 822 | 822 | } |
| 823 | 823 | } |
| 824 | 824 | db_prepare(&q, |
| 825 | 825 | "SELECT substr(name, 6), value FROM config" |
| 826 | 826 | " WHERE name GLOB 'skin:*'" |
| 827 | 827 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -165,11 +165,11 @@ | |
| 165 | @ <body> |
| 166 | @ <div class="header"> |
| 167 | @ <div class="logo"> |
| 168 | @ <img src="$baseurl/logo" alt="logo"> |
| 169 | @ </div> |
| 170 | @ <div class="title"><small>$<project_name></small><br>$<title></div> |
| 171 | @ <div class="status"><nobr><th1> |
| 172 | @ if {[info exists login]} { |
| 173 | @ puts "Logged in as $login" |
| 174 | @ } else { |
| 175 | @ puts "Not logged in" |
| @@ -600,11 +600,11 @@ | |
| 600 | @ </head> |
| 601 | @ <body> |
| 602 | @ <div class="header"> |
| 603 | @ <div class="logo"> |
| 604 | @ <!-- <img src="$baseurl/logo" alt="logo"> --> |
| 605 | @ <br><nobr>$<project_name></nobr> |
| 606 | @ </div> |
| 607 | @ <div class="title">$<title></div> |
| 608 | @ <div class="status"><nobr><th1> |
| 609 | @ if {[info exists login]} { |
| 610 | @ puts "Logged in as $login" |
| @@ -731,18 +731,18 @@ | |
| 731 | db_begin_transaction(); |
| 732 | |
| 733 | /* Process requests to delete a user-defined skin */ |
| 734 | if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){ |
| 735 | style_header("Confirm Custom Skin Delete"); |
| 736 | @ <form action="%s(g.zBaseURL)/setup_skin" method="POST"> |
| 737 | @ <p>Deletion of a custom skin is a permanent action that cannot |
| 738 | @ be undone. Please confirm that this is what you want to do:</p> |
| 739 | @ <input type="hidden" name="sn" value="%h(P("sn"))"> |
| 740 | @ <input type="submit" name="del2" value="Confirm - Delete The Skin"> |
| 741 | @ <input type="submit" name="cancel" value="Cancel - Do Not Delete"> |
| 742 | login_insert_csrf_secret(); |
| 743 | @ </form> |
| 744 | style_footer(); |
| 745 | return; |
| 746 | } |
| 747 | if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){ |
| 748 | db_multi_exec("DELETE FROM config WHERE name=%Q", zName); |
| @@ -812,15 +812,15 @@ | |
| 812 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 813 | z = aBuiltinSkin[i].zName; |
| 814 | if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ |
| 815 | @ <li><p>%h(z). <b>Currently In Use</b></p> |
| 816 | }else{ |
| 817 | @ <li><form action="%s(g.zBaseURL)/setup_skin" method="POST"> |
| 818 | @ %h(z). |
| 819 | @ <input type="hidden" name="sn" value="%h(z)"> |
| 820 | @ <input type="submit" name="load" value="Use This Skin"> |
| 821 | @ </form></li> |
| 822 | } |
| 823 | } |
| 824 | db_prepare(&q, |
| 825 | "SELECT substr(name, 6), value FROM config" |
| 826 | " WHERE name GLOB 'skin:*'" |
| 827 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -165,11 +165,11 @@ | |
| 165 | @ <body> |
| 166 | @ <div class="header"> |
| 167 | @ <div class="logo"> |
| 168 | @ <img src="$baseurl/logo" alt="logo"> |
| 169 | @ </div> |
| 170 | @ <div class="title"><small>$<project_name></small><br />$<title></div> |
| 171 | @ <div class="status"><nobr><th1> |
| 172 | @ if {[info exists login]} { |
| 173 | @ puts "Logged in as $login" |
| 174 | @ } else { |
| 175 | @ puts "Not logged in" |
| @@ -600,11 +600,11 @@ | |
| 600 | @ </head> |
| 601 | @ <body> |
| 602 | @ <div class="header"> |
| 603 | @ <div class="logo"> |
| 604 | @ <!-- <img src="$baseurl/logo" alt="logo"> --> |
| 605 | @ <br /><nobr>$<project_name></nobr> |
| 606 | @ </div> |
| 607 | @ <div class="title">$<title></div> |
| 608 | @ <div class="status"><nobr><th1> |
| 609 | @ if {[info exists login]} { |
| 610 | @ puts "Logged in as $login" |
| @@ -731,18 +731,18 @@ | |
| 731 | db_begin_transaction(); |
| 732 | |
| 733 | /* Process requests to delete a user-defined skin */ |
| 734 | if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){ |
| 735 | style_header("Confirm Custom Skin Delete"); |
| 736 | @ <form action="%s(g.zBaseURL)/setup_skin" method="post"><div> |
| 737 | @ <p>Deletion of a custom skin is a permanent action that cannot |
| 738 | @ be undone. Please confirm that this is what you want to do:</p> |
| 739 | @ <input type="hidden" name="sn" value="%h(P("sn"))" /> |
| 740 | @ <input type="submit" name="del2" value="Confirm - Delete The Skin" /> |
| 741 | @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" /> |
| 742 | login_insert_csrf_secret(); |
| 743 | @ </div></form> |
| 744 | style_footer(); |
| 745 | return; |
| 746 | } |
| 747 | if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){ |
| 748 | db_multi_exec("DELETE FROM config WHERE name=%Q", zName); |
| @@ -812,15 +812,15 @@ | |
| 812 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 813 | z = aBuiltinSkin[i].zName; |
| 814 | if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ |
| 815 | @ <li><p>%h(z). <b>Currently In Use</b></p> |
| 816 | }else{ |
| 817 | @ <li><form action="%s(g.zBaseURL)/setup_skin" method="post"><div> |
| 818 | @ %h(z). |
| 819 | @ <input type="hidden" name="sn" value="%h(z)" /> |
| 820 | @ <input type="submit" name="load" value="Use This Skin" /> |
| 821 | @ </div></form></li> |
| 822 | } |
| 823 | } |
| 824 | db_prepare(&q, |
| 825 | "SELECT substr(name, 6), value FROM config" |
| 826 | " WHERE name GLOB 'skin:*'" |
| 827 |
+18
-6
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -28,15 +28,17 @@ | ||
| 28 | 28 | ** Show statistics and global information about the repository. |
| 29 | 29 | */ |
| 30 | 30 | void stat_page(void){ |
| 31 | 31 | i64 t; |
| 32 | 32 | int n, m, fsize; |
| 33 | + int szMax, szAvg; | |
| 33 | 34 | char zBuf[100]; |
| 35 | + | |
| 34 | 36 | login_check_credentials(); |
| 35 | 37 | if( !g.okRead ){ login_needed(); return; } |
| 36 | 38 | style_header("Repository Statistics"); |
| 37 | - @ <p><table class="label-value"> | |
| 39 | + @ <table class="label-value"> | |
| 38 | 40 | @ <tr><th>Repository Size:</th><td> |
| 39 | 41 | fsize = file_size(g.zRepositoryName); |
| 40 | 42 | @ %d(fsize) bytes |
| 41 | 43 | @ </td></tr> |
| 42 | 44 | @ <tr><th>Number Of Artifacts:</th><td> |
| @@ -44,14 +46,21 @@ | ||
| 44 | 46 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 45 | 47 | @ %d(n) (stored as %d(n-m) full text and %d(m) delta blobs) |
| 46 | 48 | @ </td></tr> |
| 47 | 49 | if( n>0 ){ |
| 48 | 50 | int a, b; |
| 51 | + Stmt q; | |
| 49 | 52 | @ <tr><th>Uncompressed Artifact Size:</th><td> |
| 50 | - t = db_int64(0, "SELECT total(size) FROM blob WHERE size>0"); | |
| 53 | + db_prepare(&q, "SELECT total(size), avg(size), max(size)" | |
| 54 | + " FROM blob WHERE size>0"); | |
| 55 | + db_step(&q); | |
| 56 | + t = db_column_int64(&q, 0); | |
| 57 | + szAvg = db_column_int(&q, 1); | |
| 58 | + szMax = db_column_int(&q, 2); | |
| 59 | + db_finalize(&q); | |
| 51 | 60 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", t); |
| 52 | - @ %d((int)(((double)t)/(double)n)) bytes average, %s(zBuf) bytes total | |
| 61 | + @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) bytes total | |
| 53 | 62 | @ </td></tr> |
| 54 | 63 | @ <tr><th>Compression Ratio:</th><td> |
| 55 | 64 | if( t/fsize < 5 ){ |
| 56 | 65 | b = 10; |
| 57 | 66 | fsize /= 10; |
| @@ -82,10 +91,12 @@ | ||
| 82 | 91 | @ </td></tr> |
| 83 | 92 | @ <tr><th>Duration Of Project:</th><td> |
| 84 | 93 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 85 | 94 | " + 0.99"); |
| 86 | 95 | @ %d(n) days |
| 96 | + sqlite3_snprintf(sizeof(zBuf), zBuf, "%.2f", n/365.24); | |
| 97 | + @ or approximately %s(zBuf) years | |
| 87 | 98 | @ </td></tr> |
| 88 | 99 | @ <tr><th>Project ID:</th><td> |
| 89 | 100 | @ %h(db_get("project-code","")) |
| 90 | 101 | @ </td></tr> |
| 91 | 102 | @ <tr><th>Server ID:</th><td> |
| @@ -94,19 +105,20 @@ | ||
| 94 | 105 | |
| 95 | 106 | @ <tr><th>Fossil Version:</th><td> |
| 96 | 107 | @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) |
| 97 | 108 | @ </td></tr> |
| 98 | 109 | @ <tr><th>SQLite Version:</th><td> |
| 99 | - @ %h(db_text(0, "SELECT substr(sqlite_source_id(),1,30)")) | |
| 100 | - @ (%h(SQLITE_VERSION)) | |
| 110 | + sqlite3_snprintf(sizeof(zBuf), zBuf, "%.19s [%.10s] (%s)", | |
| 111 | + SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20], SQLITE_VERSION); | |
| 112 | + @ %s(zBuf) | |
| 101 | 113 | @ </td></tr> |
| 102 | 114 | @ <tr><th>Database Stats:</th><td> |
| 103 | 115 | @ %d(db_int(0, "PRAGMA %s.page_count", g.zRepoDb)) pages, |
| 104 | 116 | @ %d(db_int(0, "PRAGMA %s.page_size", g.zRepoDb)) bytes/page, |
| 105 | 117 | @ %d(db_int(0, "PRAGMA %s.freelist_count", g.zRepoDb)) free pages, |
| 106 | 118 | @ %s(db_text(0, "PRAGMA %s.encoding", g.zRepoDb)), |
| 107 | 119 | @ %s(db_text(0, "PRAGMA %s.journal_mode", g.zRepoDb)) mode |
| 108 | 120 | @ </td></tr> |
| 109 | 121 | |
| 110 | - @ </table></p> | |
| 122 | + @ </table> | |
| 111 | 123 | style_footer(); |
| 112 | 124 | } |
| 113 | 125 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -28,15 +28,17 @@ | |
| 28 | ** Show statistics and global information about the repository. |
| 29 | */ |
| 30 | void stat_page(void){ |
| 31 | i64 t; |
| 32 | int n, m, fsize; |
| 33 | char zBuf[100]; |
| 34 | login_check_credentials(); |
| 35 | if( !g.okRead ){ login_needed(); return; } |
| 36 | style_header("Repository Statistics"); |
| 37 | @ <p><table class="label-value"> |
| 38 | @ <tr><th>Repository Size:</th><td> |
| 39 | fsize = file_size(g.zRepositoryName); |
| 40 | @ %d(fsize) bytes |
| 41 | @ </td></tr> |
| 42 | @ <tr><th>Number Of Artifacts:</th><td> |
| @@ -44,14 +46,21 @@ | |
| 44 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 45 | @ %d(n) (stored as %d(n-m) full text and %d(m) delta blobs) |
| 46 | @ </td></tr> |
| 47 | if( n>0 ){ |
| 48 | int a, b; |
| 49 | @ <tr><th>Uncompressed Artifact Size:</th><td> |
| 50 | t = db_int64(0, "SELECT total(size) FROM blob WHERE size>0"); |
| 51 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", t); |
| 52 | @ %d((int)(((double)t)/(double)n)) bytes average, %s(zBuf) bytes total |
| 53 | @ </td></tr> |
| 54 | @ <tr><th>Compression Ratio:</th><td> |
| 55 | if( t/fsize < 5 ){ |
| 56 | b = 10; |
| 57 | fsize /= 10; |
| @@ -82,10 +91,12 @@ | |
| 82 | @ </td></tr> |
| 83 | @ <tr><th>Duration Of Project:</th><td> |
| 84 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 85 | " + 0.99"); |
| 86 | @ %d(n) days |
| 87 | @ </td></tr> |
| 88 | @ <tr><th>Project ID:</th><td> |
| 89 | @ %h(db_get("project-code","")) |
| 90 | @ </td></tr> |
| 91 | @ <tr><th>Server ID:</th><td> |
| @@ -94,19 +105,20 @@ | |
| 94 | |
| 95 | @ <tr><th>Fossil Version:</th><td> |
| 96 | @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) |
| 97 | @ </td></tr> |
| 98 | @ <tr><th>SQLite Version:</th><td> |
| 99 | @ %h(db_text(0, "SELECT substr(sqlite_source_id(),1,30)")) |
| 100 | @ (%h(SQLITE_VERSION)) |
| 101 | @ </td></tr> |
| 102 | @ <tr><th>Database Stats:</th><td> |
| 103 | @ %d(db_int(0, "PRAGMA %s.page_count", g.zRepoDb)) pages, |
| 104 | @ %d(db_int(0, "PRAGMA %s.page_size", g.zRepoDb)) bytes/page, |
| 105 | @ %d(db_int(0, "PRAGMA %s.freelist_count", g.zRepoDb)) free pages, |
| 106 | @ %s(db_text(0, "PRAGMA %s.encoding", g.zRepoDb)), |
| 107 | @ %s(db_text(0, "PRAGMA %s.journal_mode", g.zRepoDb)) mode |
| 108 | @ </td></tr> |
| 109 | |
| 110 | @ </table></p> |
| 111 | style_footer(); |
| 112 | } |
| 113 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -28,15 +28,17 @@ | |
| 28 | ** Show statistics and global information about the repository. |
| 29 | */ |
| 30 | void stat_page(void){ |
| 31 | i64 t; |
| 32 | int n, m, fsize; |
| 33 | int szMax, szAvg; |
| 34 | char zBuf[100]; |
| 35 | |
| 36 | login_check_credentials(); |
| 37 | if( !g.okRead ){ login_needed(); return; } |
| 38 | style_header("Repository Statistics"); |
| 39 | @ <table class="label-value"> |
| 40 | @ <tr><th>Repository Size:</th><td> |
| 41 | fsize = file_size(g.zRepositoryName); |
| 42 | @ %d(fsize) bytes |
| 43 | @ </td></tr> |
| 44 | @ <tr><th>Number Of Artifacts:</th><td> |
| @@ -44,14 +46,21 @@ | |
| 46 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 47 | @ %d(n) (stored as %d(n-m) full text and %d(m) delta blobs) |
| 48 | @ </td></tr> |
| 49 | if( n>0 ){ |
| 50 | int a, b; |
| 51 | Stmt q; |
| 52 | @ <tr><th>Uncompressed Artifact Size:</th><td> |
| 53 | db_prepare(&q, "SELECT total(size), avg(size), max(size)" |
| 54 | " FROM blob WHERE size>0"); |
| 55 | db_step(&q); |
| 56 | t = db_column_int64(&q, 0); |
| 57 | szAvg = db_column_int(&q, 1); |
| 58 | szMax = db_column_int(&q, 2); |
| 59 | db_finalize(&q); |
| 60 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", t); |
| 61 | @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) bytes total |
| 62 | @ </td></tr> |
| 63 | @ <tr><th>Compression Ratio:</th><td> |
| 64 | if( t/fsize < 5 ){ |
| 65 | b = 10; |
| 66 | fsize /= 10; |
| @@ -82,10 +91,12 @@ | |
| 91 | @ </td></tr> |
| 92 | @ <tr><th>Duration Of Project:</th><td> |
| 93 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 94 | " + 0.99"); |
| 95 | @ %d(n) days |
| 96 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%.2f", n/365.24); |
| 97 | @ or approximately %s(zBuf) years |
| 98 | @ </td></tr> |
| 99 | @ <tr><th>Project ID:</th><td> |
| 100 | @ %h(db_get("project-code","")) |
| 101 | @ </td></tr> |
| 102 | @ <tr><th>Server ID:</th><td> |
| @@ -94,19 +105,20 @@ | |
| 105 | |
| 106 | @ <tr><th>Fossil Version:</th><td> |
| 107 | @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) |
| 108 | @ </td></tr> |
| 109 | @ <tr><th>SQLite Version:</th><td> |
| 110 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%.19s [%.10s] (%s)", |
| 111 | SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20], SQLITE_VERSION); |
| 112 | @ %s(zBuf) |
| 113 | @ </td></tr> |
| 114 | @ <tr><th>Database Stats:</th><td> |
| 115 | @ %d(db_int(0, "PRAGMA %s.page_count", g.zRepoDb)) pages, |
| 116 | @ %d(db_int(0, "PRAGMA %s.page_size", g.zRepoDb)) bytes/page, |
| 117 | @ %d(db_int(0, "PRAGMA %s.freelist_count", g.zRepoDb)) free pages, |
| 118 | @ %s(db_text(0, "PRAGMA %s.encoding", g.zRepoDb)), |
| 119 | @ %s(db_text(0, "PRAGMA %s.journal_mode", g.zRepoDb)) mode |
| 120 | @ </td></tr> |
| 121 | |
| 122 | @ </table> |
| 123 | style_footer(); |
| 124 | } |
| 125 |
+316
-50
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -139,20 +139,23 @@ | ||
| 139 | 139 | } |
| 140 | 140 | @ <div class="content"> |
| 141 | 141 | cgi_destination(CGI_BODY); |
| 142 | 142 | |
| 143 | 143 | /* Put the footer at the bottom of the page. |
| 144 | + ** the additional clear/both is needed to extend the content | |
| 145 | + ** part to the end of an optional sidebox. | |
| 144 | 146 | */ |
| 145 | - @ </div><br clear="both"/> | |
| 147 | + @ <div style="clear: both;"></div> | |
| 148 | + @ </div> | |
| 146 | 149 | zFooter = db_get("footer", (char*)zDefaultFooter); |
| 147 | 150 | if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1); |
| 148 | 151 | Th_Render(zFooter); |
| 149 | 152 | if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1); |
| 150 | 153 | |
| 151 | 154 | /* Render trace log if TH1 tracing is enabled. */ |
| 152 | 155 | if( g.thTrace ){ |
| 153 | - cgi_append_content("<font color=\"red\"><hr>\n", -1); | |
| 156 | + cgi_append_content("<font color=\"red\"><hr />\n", -1); | |
| 154 | 157 | cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog)); |
| 155 | 158 | cgi_append_content("</font>\n", -1); |
| 156 | 159 | } |
| 157 | 160 | } |
| 158 | 161 | |
| @@ -179,27 +182,27 @@ | ||
| 179 | 182 | const char zDefaultHeader[] = |
| 180 | 183 | @ <html> |
| 181 | 184 | @ <head> |
| 182 | 185 | @ <title>$<project_name>: $<title></title> |
| 183 | 186 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 184 | -@ href="$baseurl/timeline.rss"> | |
| 187 | +@ href="$baseurl/timeline.rss" /> | |
| 185 | 188 | @ <link rel="stylesheet" href="$baseurl/style.css?default" type="text/css" |
| 186 | -@ media="screen"> | |
| 189 | +@ media="screen" /> | |
| 187 | 190 | @ </head> |
| 188 | 191 | @ <body> |
| 189 | 192 | @ <div class="header"> |
| 190 | 193 | @ <div class="logo"> |
| 191 | 194 | @ <img src="$baseurl/logo" alt="logo"> |
| 192 | 195 | @ </div> |
| 193 | -@ <div class="title"><small>$<project_name></small><br>$<title></div> | |
| 194 | -@ <div class="status"><nobr><th1> | |
| 196 | +@ <div class="title"><small>$<project_name></small><br />$<title></div> | |
| 197 | +@ <div class="status"><th1> | |
| 195 | 198 | @ if {[info exists login]} { |
| 196 | 199 | @ puts "Logged in as $login" |
| 197 | 200 | @ } else { |
| 198 | 201 | @ puts "Not logged in" |
| 199 | 202 | @ } |
| 200 | -@ </th1></nobr></div> | |
| 203 | +@ </th1></div> | |
| 201 | 204 | @ </div> |
| 202 | 205 | @ <div class="mainmenu"><th1> |
| 203 | 206 | @ html "<a href='$baseurl$index_page'>Home</a> " |
| 204 | 207 | @ if {[anycap jor]} { |
| 205 | 208 | @ html "<a href='$baseurl/timeline'>Timeline</a> " |
| @@ -274,11 +277,11 @@ | ||
| 274 | 277 | @ font-weight: bold; |
| 275 | 278 | @ text-align: center; |
| 276 | 279 | @ padding: 0 0 0 1em; |
| 277 | 280 | @ color: #558195; |
| 278 | 281 | @ vertical-align: bottom; |
| 279 | -@ width: 100%; | |
| 282 | +@ width: 100% ; | |
| 280 | 283 | @ } |
| 281 | 284 | @ |
| 282 | 285 | @ /* The login status message in the top right-hand corner */ |
| 283 | 286 | @ div.status { |
| 284 | 287 | @ display: table-cell; |
| @@ -286,16 +289,17 @@ | ||
| 286 | 289 | @ vertical-align: bottom; |
| 287 | 290 | @ color: #558195; |
| 288 | 291 | @ font-size: 0.8em; |
| 289 | 292 | @ font-weight: bold; |
| 290 | 293 | @ min-width: 200px; |
| 294 | +@ white-space: nowrap; | |
| 291 | 295 | @ } |
| 292 | 296 | @ |
| 293 | 297 | @ /* The header across the top of the page */ |
| 294 | 298 | @ div.header { |
| 295 | 299 | @ display: table; |
| 296 | -@ width: 100%; | |
| 300 | +@ width: 100% ; | |
| 297 | 301 | @ } |
| 298 | 302 | @ |
| 299 | 303 | @ /* The main menu bar that appears at the top of the page beneath |
| 300 | 304 | @ ** the header */ |
| 301 | 305 | @ div.mainmenu { |
| @@ -339,10 +343,11 @@ | ||
| 339 | 343 | @ padding: 1px 1px 1px 1px; |
| 340 | 344 | @ font-size: 1.2em; |
| 341 | 345 | @ font-weight: bold; |
| 342 | 346 | @ background-color: #558195; |
| 343 | 347 | @ color: white; |
| 348 | +@ white-space: nowrap; | |
| 344 | 349 | @ } |
| 345 | 350 | @ |
| 346 | 351 | @ /* The "Date" that occurs on the left hand side of timelines */ |
| 347 | 352 | @ div.divider { |
| 348 | 353 | @ background: #a1c4d4; |
| @@ -368,83 +373,344 @@ | ||
| 368 | 373 | @ div.footer a { color: white; } |
| 369 | 374 | @ div.footer a:link { color: white; } |
| 370 | 375 | @ div.footer a:visited { color: white; } |
| 371 | 376 | @ div.footer a:hover { background-color: white; color: #558195; } |
| 372 | 377 | @ |
| 373 | -@ /* <verbatim> blocks */ | |
| 378 | +@ /* verbatim blocks */ | |
| 374 | 379 | @ pre.verbatim { |
| 375 | 380 | @ background-color: #f5f5f5; |
| 376 | 381 | @ padding: 0.5em; |
| 377 | 382 | @} |
| 378 | 383 | @ |
| 379 | -; | |
| 380 | -const char zTableLabelValueCSS[] = | |
| 381 | 384 | @ /* The label/value pairs on (for example) the ci page */ |
| 382 | 385 | @ table.label-value th { |
| 383 | 386 | @ vertical-align: top; |
| 384 | 387 | @ text-align: right; |
| 385 | 388 | @ padding: 0.2ex 2ex; |
| 386 | 389 | @ } |
| 387 | -; | |
| 388 | -const char zDivSidebox[] = | |
| 389 | -@ /* The nomenclature sidebox for branches,.. */ | |
| 390 | -@ div.sidebox { | |
| 391 | -@ float: right; | |
| 392 | -@ border-width: medium; | |
| 393 | -@ border-style: double; | |
| 394 | -@ margin: 10; | |
| 395 | -@ } | |
| 396 | -; | |
| 397 | -const char zDivSideboxTitle[] = | |
| 398 | -@ /* The nomenclature title in sideboxes for branches,.. */ | |
| 399 | -@ div.sideboxTitle { | |
| 400 | -@ display: inline; | |
| 401 | -@ font-weight: bold; | |
| 402 | -@ } | |
| 403 | -; | |
| 404 | - | |
| 405 | - | |
| 406 | -/* The following table holds the names of CSS elements and the CSS | |
| 407 | -** text that implements those elements. | |
| 408 | -*/ | |
| 409 | -static const struct { | |
| 410 | - const char *zElement; /* Name of the CSS element */ | |
| 411 | - const char *zText; /* Text of the element */ | |
| 412 | -} cssElements[] = { | |
| 413 | - { "table.label-value", zTableLabelValueCSS }, | |
| 414 | - { "div.sidebox", zDivSidebox }, | |
| 415 | - { "div.sideboxTitle", zDivSideboxTitle }, | |
| 416 | -}; | |
| 390 | +@ | |
| 391 | +; | |
| 392 | + | |
| 393 | + | |
| 394 | +/* The following table contains bits of default CSS that must | |
| 395 | +** be included if they are not found in the application-defined | |
| 396 | +** CSS. | |
| 397 | +*/ | |
| 398 | +const struct strctCssDefaults { | |
| 399 | + char const * const elementClass; /* Name of element needed */ | |
| 400 | + char const * const comment; /* Comment text */ | |
| 401 | + char const * const value; /* CSS text */ | |
| 402 | +} cssDefaultList[] = { | |
| 403 | + { "", | |
| 404 | + "", | |
| 405 | + zDefaultCSS | |
| 406 | + }, | |
| 407 | + { "div.sidebox", | |
| 408 | + "The nomenclature sidebox for branches,..", | |
| 409 | + @ float: right; | |
| 410 | + @ background-color: white; | |
| 411 | + @ border-width: medium; | |
| 412 | + @ border-style: double; | |
| 413 | + @ margin: 10; | |
| 414 | + }, | |
| 415 | + { "div.sideboxTitle", | |
| 416 | + "The nomenclature title in sideboxes for branches,..", | |
| 417 | + @ display: inline; | |
| 418 | + @ font-weight: bold; | |
| 419 | + }, | |
| 420 | + { "div.sideboxDescribed", | |
| 421 | + "The defined element in sideboxes for branches,..", | |
| 422 | + @ display: inline; | |
| 423 | + @ font-weight: bold; | |
| 424 | + }, | |
| 425 | + { "span.disabled", | |
| 426 | + "The defined element in sideboxes for branches,..", | |
| 427 | + @ color: red; | |
| 428 | + }, | |
| 429 | + { "span.timelineDisabled", | |
| 430 | + "The suppressed duplicates lines in timeline, ..", | |
| 431 | + @ font-style: italic; | |
| 432 | + @ font-size: small; | |
| 433 | + }, | |
| 434 | + { "table.timelineTable", | |
| 435 | + "the format for the timeline data table", | |
| 436 | + @ cellspacing: 0; | |
| 437 | + @ border: 0; | |
| 438 | + @ cellpadding: 0 | |
| 439 | + }, | |
| 440 | + { "td.timelineTableCell", | |
| 441 | + "the format for the timeline data cells", | |
| 442 | + @ valign: top; | |
| 443 | + @ align: left; | |
| 444 | + }, | |
| 445 | + { "span.timelineLeaf", | |
| 446 | + "the format for the timeline leaf marks", | |
| 447 | + @ font-weight: bold; | |
| 448 | + }, | |
| 449 | + { "a.timelineHistLink", | |
| 450 | + "the format for the timeline version links", | |
| 451 | + @ | |
| 452 | + }, | |
| 453 | + { "span.timelineHistDsp", | |
| 454 | + "the format for the timeline version display(no history permission!)", | |
| 455 | + @ font-weight: bold; | |
| 456 | + }, | |
| 457 | + { "td.timelineTime", | |
| 458 | + "the format for the timeline time display", | |
| 459 | + @ vertical-align: top; | |
| 460 | + @ text-align: right; | |
| 461 | + }, | |
| 462 | + { "td.timelineGraph", | |
| 463 | + "the format for the grap placeholder cells in timelines", | |
| 464 | + @ width: 20; | |
| 465 | + @ text-align: left; | |
| 466 | + @ vertical-align: top; | |
| 467 | + }, | |
| 468 | + { "a.tagLink", | |
| 469 | + "the format for the tag links", | |
| 470 | + @ | |
| 471 | + }, | |
| 472 | + { "span.tagDsp", | |
| 473 | + "the format for the tag display(no history permission!)", | |
| 474 | + @ font-weight: bold; | |
| 475 | + }, | |
| 476 | + { "span.wikiError", | |
| 477 | + "the format for wiki errors", | |
| 478 | + @ font-weight: bold; | |
| 479 | + @ color: red; | |
| 480 | + }, | |
| 481 | + { "span.infoTagCancelled", | |
| 482 | + "the format for fixed/canceled tags,..", | |
| 483 | + @ font-weight: bold; | |
| 484 | + @ text-decoration: line-through; | |
| 485 | + }, | |
| 486 | + { "span.infoTag", | |
| 487 | + "the format for tags,..", | |
| 488 | + @ font-weight: bold; | |
| 489 | + }, | |
| 490 | + { "span.wikiTagCancelled", | |
| 491 | + "the format for fixed/cancelled tags,.. on wiki pages", | |
| 492 | + @ text-decoration: line-through; | |
| 493 | + }, | |
| 494 | + { "table.browser", | |
| 495 | + "format for the file display table", | |
| 496 | + @ /* the format for wiki errors */ | |
| 497 | + @ width: 100% ; | |
| 498 | + @ border: 0; | |
| 499 | + }, | |
| 500 | + { "td.browser", | |
| 501 | + "format for cells in the file browser", | |
| 502 | + @ width: 24% ; | |
| 503 | + @ vertical-align: top; | |
| 504 | + }, | |
| 505 | + { "ul.browser", | |
| 506 | + "format for the list in the file browser", | |
| 507 | + @ margin-left: 0.5em; | |
| 508 | + @ padding-left: 0.5em; | |
| 509 | + }, | |
| 510 | + { "table.login_out", | |
| 511 | + "table format for login/out label/input table", | |
| 512 | + @ text-align: left; | |
| 513 | + @ margin-right: 10px; | |
| 514 | + @ margin-left: 10px; | |
| 515 | + @ margin-top: 10px; | |
| 516 | + }, | |
| 517 | + { "div.captcha", | |
| 518 | + "captcha display options", | |
| 519 | + @ text-align: center; | |
| 520 | + }, | |
| 521 | + { "table.captcha", | |
| 522 | + "format for the layout table, used for the captcha display", | |
| 523 | + @ margin: auto; | |
| 524 | + @ padding: 10px; | |
| 525 | + @ outline-width: 1; | |
| 526 | + @ outline-style: double; | |
| 527 | + }, | |
| 528 | + { "td.login_out_label", | |
| 529 | + "format for the label cells in the login/out table", | |
| 530 | + @ text-align: center; | |
| 531 | + }, | |
| 532 | + { "span.loginError", | |
| 533 | + "format for login error messages", | |
| 534 | + @ color: red; | |
| 535 | + }, | |
| 536 | + { "span.note", | |
| 537 | + "format for leading text for notes", | |
| 538 | + @ font-weight: bold; | |
| 539 | + }, | |
| 540 | + { "span.textareaLabel", | |
| 541 | + "format for textare labels", | |
| 542 | + @ font-weight: bold; | |
| 543 | + }, | |
| 544 | + { "table.usetupLayoutTable", | |
| 545 | + "format for the user setup layout table", | |
| 546 | + @ outline-style: none; | |
| 547 | + @ padding: 0; | |
| 548 | + @ margin: 25px; | |
| 549 | + }, | |
| 550 | + { "td.usetupColumnLayout", | |
| 551 | + "format of the columns on the user setup list page", | |
| 552 | + @ vertical-align: top | |
| 553 | + }, | |
| 554 | + { "table.usetupUserList", | |
| 555 | + "format for the user list table on the user setup page", | |
| 556 | + @ outline-style: double; | |
| 557 | + @ outline-width: 1; | |
| 558 | + @ padding: 10px; | |
| 559 | + }, | |
| 560 | + { "th.usetupListUser", | |
| 561 | + "format for table header user in user list on user setup page", | |
| 562 | + @ text-align: right; | |
| 563 | + @ padding-right: 20px; | |
| 564 | + }, | |
| 565 | + { "th.usetupListCap", | |
| 566 | + "format for table header capabilities in user list on user setup page", | |
| 567 | + @ text-align: center; | |
| 568 | + @ padding-right: 15px; | |
| 569 | + }, | |
| 570 | + { "th.usetupListCon", | |
| 571 | + "format for table header contact info in user list on user setup page", | |
| 572 | + @ text-align: left; | |
| 573 | + }, | |
| 574 | + { "td.usetupListUser", | |
| 575 | + "format for table cell user in user list on user setup page", | |
| 576 | + @ text-align: right; | |
| 577 | + @ padding-right: 20px; | |
| 578 | + @ white-space:nowrap; | |
| 579 | + }, | |
| 580 | + { "td.usetupListCap", | |
| 581 | + "format for table cell capabilities in user list on user setup page", | |
| 582 | + @ text-align: center; | |
| 583 | + @ padding-right: 15px; | |
| 584 | + }, | |
| 585 | + { "td.usetupListCon", | |
| 586 | + "format for table cell contact info in user list on user setup page", | |
| 587 | + @ text-align: left | |
| 588 | + }, | |
| 589 | + { "div.ueditCapBox", | |
| 590 | + "layout definition for the capabilities box on the user edit detail page", | |
| 591 | + @ float: left; | |
| 592 | + @ margin-right: 20px; | |
| 593 | + @ margin-bottom: 20px; | |
| 594 | + }, | |
| 595 | + { "td.usetupEditLabel", | |
| 596 | + "format of the label cells in the detailed user edit page", | |
| 597 | + @ text-align: right; | |
| 598 | + @ vertical-align: top; | |
| 599 | + @ white-space: nowrap; | |
| 600 | + }, | |
| 601 | + { "span.ueditInheritNobody", | |
| 602 | + "color for capabilities, inherited by nobody", | |
| 603 | + @ color: green; | |
| 604 | + }, | |
| 605 | + { "span.ueditInheritDeveloper", | |
| 606 | + "color for capabilities, inherited by developer", | |
| 607 | + @ color: red; | |
| 608 | + }, | |
| 609 | + { "span.ueditInheritReader", | |
| 610 | + "color for capabilities, inherited by reader", | |
| 611 | + @ color: black; | |
| 612 | + }, | |
| 613 | + { "span.ueditInheritAnonymous", | |
| 614 | + "color for capabilities, inherited by anonymous", | |
| 615 | + @ color: blue; | |
| 616 | + }, | |
| 617 | + { "span.capability", | |
| 618 | + "format for capabilites, mentioned on the user edit page", | |
| 619 | + @ font-weight: bold; | |
| 620 | + }, | |
| 621 | + { "span.usertype", | |
| 622 | + "format for different user types, mentioned on the user edit page", | |
| 623 | + @ font-weight: bold; | |
| 624 | + }, | |
| 625 | + { "span.usertype:before", | |
| 626 | + "leading text for user types, mentioned on the user edit page", | |
| 627 | + @ content:"'"; | |
| 628 | + }, | |
| 629 | + { "span.usertype:after", | |
| 630 | + "trailing text for user types, mentioned on the user edit page", | |
| 631 | + @ content:"'"; | |
| 632 | + }, | |
| 633 | + { "span.wikiruleHead", | |
| 634 | + "format for leading text in wikirules definitions", | |
| 635 | + @ font-weight: bold; | |
| 636 | + }, | |
| 637 | + { "td.tktDspLabel", | |
| 638 | + "format for labels on ticket display page", | |
| 639 | + @ text-align: right; | |
| 640 | + }, | |
| 641 | + { "td.tktDspValue", | |
| 642 | + "format for values on ticket display page", | |
| 643 | + @ text-align: left; | |
| 644 | + @ vertical-align: top; | |
| 645 | + @ background-color: #d0d0d0; | |
| 646 | + }, | |
| 647 | + { "span.tktError", | |
| 648 | + "format for ticket error messages", | |
| 649 | + @ color: red; | |
| 650 | + @ font-weight: bold; | |
| 651 | + }, | |
| 652 | + { 0, | |
| 653 | + 0, | |
| 654 | + 0 | |
| 655 | + } | |
| 656 | +}; | |
| 657 | + | |
| 658 | +/* | |
| 659 | +** Append all of the default CSS to the CGI output. | |
| 660 | +*/ | |
| 661 | +void cgi_append_default_css(void) { | |
| 662 | + int i; | |
| 663 | + | |
| 664 | + for (i=0;cssDefaultList[i].elementClass;i++){ | |
| 665 | + if (cssDefaultList[i].elementClass[0]){ | |
| 666 | + cgi_printf("/* %s */\n%s {\n%s\n}\n\n", | |
| 667 | + cssDefaultList[i].comment, | |
| 668 | + cssDefaultList[i].elementClass, | |
| 669 | + cssDefaultList[i].value | |
| 670 | + ); | |
| 671 | + }else{ | |
| 672 | + cgi_printf("%s", | |
| 673 | + cssDefaultList[i].value | |
| 674 | + ); | |
| 675 | + } | |
| 676 | + } | |
| 677 | +} | |
| 417 | 678 | |
| 418 | 679 | /* |
| 419 | 680 | ** WEBPAGE: style.css |
| 420 | 681 | */ |
| 421 | 682 | void page_style_css(void){ |
| 422 | - const char *zCSS; | |
| 683 | + const char *zCSS = 0; | |
| 423 | 684 | int i; |
| 424 | 685 | |
| 425 | 686 | cgi_set_content_type("text/css"); |
| 426 | 687 | zCSS = db_get("css",(char*)zDefaultCSS); |
| 427 | 688 | /* append user defined css */ |
| 428 | 689 | cgi_append_content(zCSS, -1); |
| 429 | 690 | /* add special missing definitions */ |
| 430 | - for(i=0; i<count(cssElements); i++){ | |
| 431 | - if( strstr(cssElements[i].zElement, zCSS)==0 ){ | |
| 432 | - cgi_append_content(cssElements[i].zText, -1); | |
| 691 | + for (i=1;cssDefaultList[i].elementClass;i++) | |
| 692 | + if (!strstr(zCSS,cssDefaultList[i].elementClass)) { | |
| 693 | + cgi_append_content("/* ", -1); | |
| 694 | + cgi_append_content(cssDefaultList[i].comment, -1); | |
| 695 | + cgi_append_content(" */\n", -1); | |
| 696 | + cgi_append_content(cssDefaultList[i].elementClass, -1); | |
| 697 | + cgi_append_content(" {\n", -1); | |
| 698 | + cgi_append_content(cssDefaultList[i].value, -1); | |
| 699 | + cgi_append_content("}\n\n", -1); | |
| 433 | 700 | } |
| 434 | - } | |
| 435 | 701 | g.isConst = 1; |
| 436 | 702 | } |
| 437 | 703 | |
| 438 | 704 | /* |
| 439 | 705 | ** WEBPAGE: test_env |
| 440 | 706 | */ |
| 441 | 707 | void page_test_env(void){ |
| 442 | 708 | style_header("Environment Test"); |
| 443 | 709 | #if !defined(_WIN32) |
| 444 | - @ uid=%d(getuid()), gid=%d(getgid())<br> | |
| 710 | + @ uid=%d(getuid()), gid=%d(getgid())<br /> | |
| 445 | 711 | #endif |
| 446 | - @ g.zBaseURL = %h(g.zBaseURL)<br> | |
| 447 | - @ g.zTop = %h(g.zTop)<br> | |
| 712 | + @ g.zBaseURL = %h(g.zBaseURL)<br /> | |
| 713 | + @ g.zTop = %h(g.zTop)<br /> | |
| 448 | 714 | cgi_print_all(); |
| 449 | 715 | style_footer(); |
| 450 | 716 | } |
| 451 | 717 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -139,20 +139,23 @@ | |
| 139 | } |
| 140 | @ <div class="content"> |
| 141 | cgi_destination(CGI_BODY); |
| 142 | |
| 143 | /* Put the footer at the bottom of the page. |
| 144 | */ |
| 145 | @ </div><br clear="both"/> |
| 146 | zFooter = db_get("footer", (char*)zDefaultFooter); |
| 147 | if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1); |
| 148 | Th_Render(zFooter); |
| 149 | if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1); |
| 150 | |
| 151 | /* Render trace log if TH1 tracing is enabled. */ |
| 152 | if( g.thTrace ){ |
| 153 | cgi_append_content("<font color=\"red\"><hr>\n", -1); |
| 154 | cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog)); |
| 155 | cgi_append_content("</font>\n", -1); |
| 156 | } |
| 157 | } |
| 158 | |
| @@ -179,27 +182,27 @@ | |
| 179 | const char zDefaultHeader[] = |
| 180 | @ <html> |
| 181 | @ <head> |
| 182 | @ <title>$<project_name>: $<title></title> |
| 183 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 184 | @ href="$baseurl/timeline.rss"> |
| 185 | @ <link rel="stylesheet" href="$baseurl/style.css?default" type="text/css" |
| 186 | @ media="screen"> |
| 187 | @ </head> |
| 188 | @ <body> |
| 189 | @ <div class="header"> |
| 190 | @ <div class="logo"> |
| 191 | @ <img src="$baseurl/logo" alt="logo"> |
| 192 | @ </div> |
| 193 | @ <div class="title"><small>$<project_name></small><br>$<title></div> |
| 194 | @ <div class="status"><nobr><th1> |
| 195 | @ if {[info exists login]} { |
| 196 | @ puts "Logged in as $login" |
| 197 | @ } else { |
| 198 | @ puts "Not logged in" |
| 199 | @ } |
| 200 | @ </th1></nobr></div> |
| 201 | @ </div> |
| 202 | @ <div class="mainmenu"><th1> |
| 203 | @ html "<a href='$baseurl$index_page'>Home</a> " |
| 204 | @ if {[anycap jor]} { |
| 205 | @ html "<a href='$baseurl/timeline'>Timeline</a> " |
| @@ -274,11 +277,11 @@ | |
| 274 | @ font-weight: bold; |
| 275 | @ text-align: center; |
| 276 | @ padding: 0 0 0 1em; |
| 277 | @ color: #558195; |
| 278 | @ vertical-align: bottom; |
| 279 | @ width: 100%; |
| 280 | @ } |
| 281 | @ |
| 282 | @ /* The login status message in the top right-hand corner */ |
| 283 | @ div.status { |
| 284 | @ display: table-cell; |
| @@ -286,16 +289,17 @@ | |
| 286 | @ vertical-align: bottom; |
| 287 | @ color: #558195; |
| 288 | @ font-size: 0.8em; |
| 289 | @ font-weight: bold; |
| 290 | @ min-width: 200px; |
| 291 | @ } |
| 292 | @ |
| 293 | @ /* The header across the top of the page */ |
| 294 | @ div.header { |
| 295 | @ display: table; |
| 296 | @ width: 100%; |
| 297 | @ } |
| 298 | @ |
| 299 | @ /* The main menu bar that appears at the top of the page beneath |
| 300 | @ ** the header */ |
| 301 | @ div.mainmenu { |
| @@ -339,10 +343,11 @@ | |
| 339 | @ padding: 1px 1px 1px 1px; |
| 340 | @ font-size: 1.2em; |
| 341 | @ font-weight: bold; |
| 342 | @ background-color: #558195; |
| 343 | @ color: white; |
| 344 | @ } |
| 345 | @ |
| 346 | @ /* The "Date" that occurs on the left hand side of timelines */ |
| 347 | @ div.divider { |
| 348 | @ background: #a1c4d4; |
| @@ -368,83 +373,344 @@ | |
| 368 | @ div.footer a { color: white; } |
| 369 | @ div.footer a:link { color: white; } |
| 370 | @ div.footer a:visited { color: white; } |
| 371 | @ div.footer a:hover { background-color: white; color: #558195; } |
| 372 | @ |
| 373 | @ /* <verbatim> blocks */ |
| 374 | @ pre.verbatim { |
| 375 | @ background-color: #f5f5f5; |
| 376 | @ padding: 0.5em; |
| 377 | @} |
| 378 | @ |
| 379 | ; |
| 380 | const char zTableLabelValueCSS[] = |
| 381 | @ /* The label/value pairs on (for example) the ci page */ |
| 382 | @ table.label-value th { |
| 383 | @ vertical-align: top; |
| 384 | @ text-align: right; |
| 385 | @ padding: 0.2ex 2ex; |
| 386 | @ } |
| 387 | ; |
| 388 | const char zDivSidebox[] = |
| 389 | @ /* The nomenclature sidebox for branches,.. */ |
| 390 | @ div.sidebox { |
| 391 | @ float: right; |
| 392 | @ border-width: medium; |
| 393 | @ border-style: double; |
| 394 | @ margin: 10; |
| 395 | @ } |
| 396 | ; |
| 397 | const char zDivSideboxTitle[] = |
| 398 | @ /* The nomenclature title in sideboxes for branches,.. */ |
| 399 | @ div.sideboxTitle { |
| 400 | @ display: inline; |
| 401 | @ font-weight: bold; |
| 402 | @ } |
| 403 | ; |
| 404 | |
| 405 | |
| 406 | /* The following table holds the names of CSS elements and the CSS |
| 407 | ** text that implements those elements. |
| 408 | */ |
| 409 | static const struct { |
| 410 | const char *zElement; /* Name of the CSS element */ |
| 411 | const char *zText; /* Text of the element */ |
| 412 | } cssElements[] = { |
| 413 | { "table.label-value", zTableLabelValueCSS }, |
| 414 | { "div.sidebox", zDivSidebox }, |
| 415 | { "div.sideboxTitle", zDivSideboxTitle }, |
| 416 | }; |
| 417 | |
| 418 | /* |
| 419 | ** WEBPAGE: style.css |
| 420 | */ |
| 421 | void page_style_css(void){ |
| 422 | const char *zCSS; |
| 423 | int i; |
| 424 | |
| 425 | cgi_set_content_type("text/css"); |
| 426 | zCSS = db_get("css",(char*)zDefaultCSS); |
| 427 | /* append user defined css */ |
| 428 | cgi_append_content(zCSS, -1); |
| 429 | /* add special missing definitions */ |
| 430 | for(i=0; i<count(cssElements); i++){ |
| 431 | if( strstr(cssElements[i].zElement, zCSS)==0 ){ |
| 432 | cgi_append_content(cssElements[i].zText, -1); |
| 433 | } |
| 434 | } |
| 435 | g.isConst = 1; |
| 436 | } |
| 437 | |
| 438 | /* |
| 439 | ** WEBPAGE: test_env |
| 440 | */ |
| 441 | void page_test_env(void){ |
| 442 | style_header("Environment Test"); |
| 443 | #if !defined(_WIN32) |
| 444 | @ uid=%d(getuid()), gid=%d(getgid())<br> |
| 445 | #endif |
| 446 | @ g.zBaseURL = %h(g.zBaseURL)<br> |
| 447 | @ g.zTop = %h(g.zTop)<br> |
| 448 | cgi_print_all(); |
| 449 | style_footer(); |
| 450 | } |
| 451 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -139,20 +139,23 @@ | |
| 139 | } |
| 140 | @ <div class="content"> |
| 141 | cgi_destination(CGI_BODY); |
| 142 | |
| 143 | /* Put the footer at the bottom of the page. |
| 144 | ** the additional clear/both is needed to extend the content |
| 145 | ** part to the end of an optional sidebox. |
| 146 | */ |
| 147 | @ <div style="clear: both;"></div> |
| 148 | @ </div> |
| 149 | zFooter = db_get("footer", (char*)zDefaultFooter); |
| 150 | if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1); |
| 151 | Th_Render(zFooter); |
| 152 | if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1); |
| 153 | |
| 154 | /* Render trace log if TH1 tracing is enabled. */ |
| 155 | if( g.thTrace ){ |
| 156 | cgi_append_content("<font color=\"red\"><hr />\n", -1); |
| 157 | cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog)); |
| 158 | cgi_append_content("</font>\n", -1); |
| 159 | } |
| 160 | } |
| 161 | |
| @@ -179,27 +182,27 @@ | |
| 182 | const char zDefaultHeader[] = |
| 183 | @ <html> |
| 184 | @ <head> |
| 185 | @ <title>$<project_name>: $<title></title> |
| 186 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 187 | @ href="$baseurl/timeline.rss" /> |
| 188 | @ <link rel="stylesheet" href="$baseurl/style.css?default" type="text/css" |
| 189 | @ media="screen" /> |
| 190 | @ </head> |
| 191 | @ <body> |
| 192 | @ <div class="header"> |
| 193 | @ <div class="logo"> |
| 194 | @ <img src="$baseurl/logo" alt="logo"> |
| 195 | @ </div> |
| 196 | @ <div class="title"><small>$<project_name></small><br />$<title></div> |
| 197 | @ <div class="status"><th1> |
| 198 | @ if {[info exists login]} { |
| 199 | @ puts "Logged in as $login" |
| 200 | @ } else { |
| 201 | @ puts "Not logged in" |
| 202 | @ } |
| 203 | @ </th1></div> |
| 204 | @ </div> |
| 205 | @ <div class="mainmenu"><th1> |
| 206 | @ html "<a href='$baseurl$index_page'>Home</a> " |
| 207 | @ if {[anycap jor]} { |
| 208 | @ html "<a href='$baseurl/timeline'>Timeline</a> " |
| @@ -274,11 +277,11 @@ | |
| 277 | @ font-weight: bold; |
| 278 | @ text-align: center; |
| 279 | @ padding: 0 0 0 1em; |
| 280 | @ color: #558195; |
| 281 | @ vertical-align: bottom; |
| 282 | @ width: 100% ; |
| 283 | @ } |
| 284 | @ |
| 285 | @ /* The login status message in the top right-hand corner */ |
| 286 | @ div.status { |
| 287 | @ display: table-cell; |
| @@ -286,16 +289,17 @@ | |
| 289 | @ vertical-align: bottom; |
| 290 | @ color: #558195; |
| 291 | @ font-size: 0.8em; |
| 292 | @ font-weight: bold; |
| 293 | @ min-width: 200px; |
| 294 | @ white-space: nowrap; |
| 295 | @ } |
| 296 | @ |
| 297 | @ /* The header across the top of the page */ |
| 298 | @ div.header { |
| 299 | @ display: table; |
| 300 | @ width: 100% ; |
| 301 | @ } |
| 302 | @ |
| 303 | @ /* The main menu bar that appears at the top of the page beneath |
| 304 | @ ** the header */ |
| 305 | @ div.mainmenu { |
| @@ -339,10 +343,11 @@ | |
| 343 | @ padding: 1px 1px 1px 1px; |
| 344 | @ font-size: 1.2em; |
| 345 | @ font-weight: bold; |
| 346 | @ background-color: #558195; |
| 347 | @ color: white; |
| 348 | @ white-space: nowrap; |
| 349 | @ } |
| 350 | @ |
| 351 | @ /* The "Date" that occurs on the left hand side of timelines */ |
| 352 | @ div.divider { |
| 353 | @ background: #a1c4d4; |
| @@ -368,83 +373,344 @@ | |
| 373 | @ div.footer a { color: white; } |
| 374 | @ div.footer a:link { color: white; } |
| 375 | @ div.footer a:visited { color: white; } |
| 376 | @ div.footer a:hover { background-color: white; color: #558195; } |
| 377 | @ |
| 378 | @ /* verbatim blocks */ |
| 379 | @ pre.verbatim { |
| 380 | @ background-color: #f5f5f5; |
| 381 | @ padding: 0.5em; |
| 382 | @} |
| 383 | @ |
| 384 | @ /* The label/value pairs on (for example) the ci page */ |
| 385 | @ table.label-value th { |
| 386 | @ vertical-align: top; |
| 387 | @ text-align: right; |
| 388 | @ padding: 0.2ex 2ex; |
| 389 | @ } |
| 390 | @ |
| 391 | ; |
| 392 | |
| 393 | |
| 394 | /* The following table contains bits of default CSS that must |
| 395 | ** be included if they are not found in the application-defined |
| 396 | ** CSS. |
| 397 | */ |
| 398 | const struct strctCssDefaults { |
| 399 | char const * const elementClass; /* Name of element needed */ |
| 400 | char const * const comment; /* Comment text */ |
| 401 | char const * const value; /* CSS text */ |
| 402 | } cssDefaultList[] = { |
| 403 | { "", |
| 404 | "", |
| 405 | zDefaultCSS |
| 406 | }, |
| 407 | { "div.sidebox", |
| 408 | "The nomenclature sidebox for branches,..", |
| 409 | @ float: right; |
| 410 | @ background-color: white; |
| 411 | @ border-width: medium; |
| 412 | @ border-style: double; |
| 413 | @ margin: 10; |
| 414 | }, |
| 415 | { "div.sideboxTitle", |
| 416 | "The nomenclature title in sideboxes for branches,..", |
| 417 | @ display: inline; |
| 418 | @ font-weight: bold; |
| 419 | }, |
| 420 | { "div.sideboxDescribed", |
| 421 | "The defined element in sideboxes for branches,..", |
| 422 | @ display: inline; |
| 423 | @ font-weight: bold; |
| 424 | }, |
| 425 | { "span.disabled", |
| 426 | "The defined element in sideboxes for branches,..", |
| 427 | @ color: red; |
| 428 | }, |
| 429 | { "span.timelineDisabled", |
| 430 | "The suppressed duplicates lines in timeline, ..", |
| 431 | @ font-style: italic; |
| 432 | @ font-size: small; |
| 433 | }, |
| 434 | { "table.timelineTable", |
| 435 | "the format for the timeline data table", |
| 436 | @ cellspacing: 0; |
| 437 | @ border: 0; |
| 438 | @ cellpadding: 0 |
| 439 | }, |
| 440 | { "td.timelineTableCell", |
| 441 | "the format for the timeline data cells", |
| 442 | @ valign: top; |
| 443 | @ align: left; |
| 444 | }, |
| 445 | { "span.timelineLeaf", |
| 446 | "the format for the timeline leaf marks", |
| 447 | @ font-weight: bold; |
| 448 | }, |
| 449 | { "a.timelineHistLink", |
| 450 | "the format for the timeline version links", |
| 451 | @ |
| 452 | }, |
| 453 | { "span.timelineHistDsp", |
| 454 | "the format for the timeline version display(no history permission!)", |
| 455 | @ font-weight: bold; |
| 456 | }, |
| 457 | { "td.timelineTime", |
| 458 | "the format for the timeline time display", |
| 459 | @ vertical-align: top; |
| 460 | @ text-align: right; |
| 461 | }, |
| 462 | { "td.timelineGraph", |
| 463 | "the format for the grap placeholder cells in timelines", |
| 464 | @ width: 20; |
| 465 | @ text-align: left; |
| 466 | @ vertical-align: top; |
| 467 | }, |
| 468 | { "a.tagLink", |
| 469 | "the format for the tag links", |
| 470 | @ |
| 471 | }, |
| 472 | { "span.tagDsp", |
| 473 | "the format for the tag display(no history permission!)", |
| 474 | @ font-weight: bold; |
| 475 | }, |
| 476 | { "span.wikiError", |
| 477 | "the format for wiki errors", |
| 478 | @ font-weight: bold; |
| 479 | @ color: red; |
| 480 | }, |
| 481 | { "span.infoTagCancelled", |
| 482 | "the format for fixed/canceled tags,..", |
| 483 | @ font-weight: bold; |
| 484 | @ text-decoration: line-through; |
| 485 | }, |
| 486 | { "span.infoTag", |
| 487 | "the format for tags,..", |
| 488 | @ font-weight: bold; |
| 489 | }, |
| 490 | { "span.wikiTagCancelled", |
| 491 | "the format for fixed/cancelled tags,.. on wiki pages", |
| 492 | @ text-decoration: line-through; |
| 493 | }, |
| 494 | { "table.browser", |
| 495 | "format for the file display table", |
| 496 | @ /* the format for wiki errors */ |
| 497 | @ width: 100% ; |
| 498 | @ border: 0; |
| 499 | }, |
| 500 | { "td.browser", |
| 501 | "format for cells in the file browser", |
| 502 | @ width: 24% ; |
| 503 | @ vertical-align: top; |
| 504 | }, |
| 505 | { "ul.browser", |
| 506 | "format for the list in the file browser", |
| 507 | @ margin-left: 0.5em; |
| 508 | @ padding-left: 0.5em; |
| 509 | }, |
| 510 | { "table.login_out", |
| 511 | "table format for login/out label/input table", |
| 512 | @ text-align: left; |
| 513 | @ margin-right: 10px; |
| 514 | @ margin-left: 10px; |
| 515 | @ margin-top: 10px; |
| 516 | }, |
| 517 | { "div.captcha", |
| 518 | "captcha display options", |
| 519 | @ text-align: center; |
| 520 | }, |
| 521 | { "table.captcha", |
| 522 | "format for the layout table, used for the captcha display", |
| 523 | @ margin: auto; |
| 524 | @ padding: 10px; |
| 525 | @ outline-width: 1; |
| 526 | @ outline-style: double; |
| 527 | }, |
| 528 | { "td.login_out_label", |
| 529 | "format for the label cells in the login/out table", |
| 530 | @ text-align: center; |
| 531 | }, |
| 532 | { "span.loginError", |
| 533 | "format for login error messages", |
| 534 | @ color: red; |
| 535 | }, |
| 536 | { "span.note", |
| 537 | "format for leading text for notes", |
| 538 | @ font-weight: bold; |
| 539 | }, |
| 540 | { "span.textareaLabel", |
| 541 | "format for textare labels", |
| 542 | @ font-weight: bold; |
| 543 | }, |
| 544 | { "table.usetupLayoutTable", |
| 545 | "format for the user setup layout table", |
| 546 | @ outline-style: none; |
| 547 | @ padding: 0; |
| 548 | @ margin: 25px; |
| 549 | }, |
| 550 | { "td.usetupColumnLayout", |
| 551 | "format of the columns on the user setup list page", |
| 552 | @ vertical-align: top |
| 553 | }, |
| 554 | { "table.usetupUserList", |
| 555 | "format for the user list table on the user setup page", |
| 556 | @ outline-style: double; |
| 557 | @ outline-width: 1; |
| 558 | @ padding: 10px; |
| 559 | }, |
| 560 | { "th.usetupListUser", |
| 561 | "format for table header user in user list on user setup page", |
| 562 | @ text-align: right; |
| 563 | @ padding-right: 20px; |
| 564 | }, |
| 565 | { "th.usetupListCap", |
| 566 | "format for table header capabilities in user list on user setup page", |
| 567 | @ text-align: center; |
| 568 | @ padding-right: 15px; |
| 569 | }, |
| 570 | { "th.usetupListCon", |
| 571 | "format for table header contact info in user list on user setup page", |
| 572 | @ text-align: left; |
| 573 | }, |
| 574 | { "td.usetupListUser", |
| 575 | "format for table cell user in user list on user setup page", |
| 576 | @ text-align: right; |
| 577 | @ padding-right: 20px; |
| 578 | @ white-space:nowrap; |
| 579 | }, |
| 580 | { "td.usetupListCap", |
| 581 | "format for table cell capabilities in user list on user setup page", |
| 582 | @ text-align: center; |
| 583 | @ padding-right: 15px; |
| 584 | }, |
| 585 | { "td.usetupListCon", |
| 586 | "format for table cell contact info in user list on user setup page", |
| 587 | @ text-align: left |
| 588 | }, |
| 589 | { "div.ueditCapBox", |
| 590 | "layout definition for the capabilities box on the user edit detail page", |
| 591 | @ float: left; |
| 592 | @ margin-right: 20px; |
| 593 | @ margin-bottom: 20px; |
| 594 | }, |
| 595 | { "td.usetupEditLabel", |
| 596 | "format of the label cells in the detailed user edit page", |
| 597 | @ text-align: right; |
| 598 | @ vertical-align: top; |
| 599 | @ white-space: nowrap; |
| 600 | }, |
| 601 | { "span.ueditInheritNobody", |
| 602 | "color for capabilities, inherited by nobody", |
| 603 | @ color: green; |
| 604 | }, |
| 605 | { "span.ueditInheritDeveloper", |
| 606 | "color for capabilities, inherited by developer", |
| 607 | @ color: red; |
| 608 | }, |
| 609 | { "span.ueditInheritReader", |
| 610 | "color for capabilities, inherited by reader", |
| 611 | @ color: black; |
| 612 | }, |
| 613 | { "span.ueditInheritAnonymous", |
| 614 | "color for capabilities, inherited by anonymous", |
| 615 | @ color: blue; |
| 616 | }, |
| 617 | { "span.capability", |
| 618 | "format for capabilites, mentioned on the user edit page", |
| 619 | @ font-weight: bold; |
| 620 | }, |
| 621 | { "span.usertype", |
| 622 | "format for different user types, mentioned on the user edit page", |
| 623 | @ font-weight: bold; |
| 624 | }, |
| 625 | { "span.usertype:before", |
| 626 | "leading text for user types, mentioned on the user edit page", |
| 627 | @ content:"'"; |
| 628 | }, |
| 629 | { "span.usertype:after", |
| 630 | "trailing text for user types, mentioned on the user edit page", |
| 631 | @ content:"'"; |
| 632 | }, |
| 633 | { "span.wikiruleHead", |
| 634 | "format for leading text in wikirules definitions", |
| 635 | @ font-weight: bold; |
| 636 | }, |
| 637 | { "td.tktDspLabel", |
| 638 | "format for labels on ticket display page", |
| 639 | @ text-align: right; |
| 640 | }, |
| 641 | { "td.tktDspValue", |
| 642 | "format for values on ticket display page", |
| 643 | @ text-align: left; |
| 644 | @ vertical-align: top; |
| 645 | @ background-color: #d0d0d0; |
| 646 | }, |
| 647 | { "span.tktError", |
| 648 | "format for ticket error messages", |
| 649 | @ color: red; |
| 650 | @ font-weight: bold; |
| 651 | }, |
| 652 | { 0, |
| 653 | 0, |
| 654 | 0 |
| 655 | } |
| 656 | }; |
| 657 | |
| 658 | /* |
| 659 | ** Append all of the default CSS to the CGI output. |
| 660 | */ |
| 661 | void cgi_append_default_css(void) { |
| 662 | int i; |
| 663 | |
| 664 | for (i=0;cssDefaultList[i].elementClass;i++){ |
| 665 | if (cssDefaultList[i].elementClass[0]){ |
| 666 | cgi_printf("/* %s */\n%s {\n%s\n}\n\n", |
| 667 | cssDefaultList[i].comment, |
| 668 | cssDefaultList[i].elementClass, |
| 669 | cssDefaultList[i].value |
| 670 | ); |
| 671 | }else{ |
| 672 | cgi_printf("%s", |
| 673 | cssDefaultList[i].value |
| 674 | ); |
| 675 | } |
| 676 | } |
| 677 | } |
| 678 | |
| 679 | /* |
| 680 | ** WEBPAGE: style.css |
| 681 | */ |
| 682 | void page_style_css(void){ |
| 683 | const char *zCSS = 0; |
| 684 | int i; |
| 685 | |
| 686 | cgi_set_content_type("text/css"); |
| 687 | zCSS = db_get("css",(char*)zDefaultCSS); |
| 688 | /* append user defined css */ |
| 689 | cgi_append_content(zCSS, -1); |
| 690 | /* add special missing definitions */ |
| 691 | for (i=1;cssDefaultList[i].elementClass;i++) |
| 692 | if (!strstr(zCSS,cssDefaultList[i].elementClass)) { |
| 693 | cgi_append_content("/* ", -1); |
| 694 | cgi_append_content(cssDefaultList[i].comment, -1); |
| 695 | cgi_append_content(" */\n", -1); |
| 696 | cgi_append_content(cssDefaultList[i].elementClass, -1); |
| 697 | cgi_append_content(" {\n", -1); |
| 698 | cgi_append_content(cssDefaultList[i].value, -1); |
| 699 | cgi_append_content("}\n\n", -1); |
| 700 | } |
| 701 | g.isConst = 1; |
| 702 | } |
| 703 | |
| 704 | /* |
| 705 | ** WEBPAGE: test_env |
| 706 | */ |
| 707 | void page_test_env(void){ |
| 708 | style_header("Environment Test"); |
| 709 | #if !defined(_WIN32) |
| 710 | @ uid=%d(getuid()), gid=%d(getgid())<br /> |
| 711 | #endif |
| 712 | @ g.zBaseURL = %h(g.zBaseURL)<br /> |
| 713 | @ g.zTop = %h(g.zTop)<br /> |
| 714 | cgi_print_all(); |
| 715 | style_footer(); |
| 716 | } |
| 717 |
+8
-6
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -514,13 +514,14 @@ | ||
| 514 | 514 | ); |
| 515 | 515 | @ <ul> |
| 516 | 516 | while( db_step(&q)==SQLITE_ROW ){ |
| 517 | 517 | const char *zName = db_column_text(&q, 0); |
| 518 | 518 | if( g.okHistory ){ |
| 519 | - @ <li><a href=%s(g.zBaseURL)/timeline?t=%T(zName)>%h(zName)</a></li> | |
| 519 | + @ <li><a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zName)"> | |
| 520 | + @ %h(zName)</a></li> | |
| 520 | 521 | }else{ |
| 521 | - @ <li><strong>%h(zName)</strong></li> | |
| 522 | + @ <li><span class="tagDsp">%h(zName)</span></li> | |
| 522 | 523 | } |
| 523 | 524 | } |
| 524 | 525 | @ </ul> |
| 525 | 526 | db_finalize(&q); |
| 526 | 527 | style_footer(); |
| @@ -542,13 +543,14 @@ | ||
| 542 | 543 | rid |
| 543 | 544 | ); |
| 544 | 545 | while( db_step(&q)==SQLITE_ROW ){ |
| 545 | 546 | const char *zTagName = db_column_text(&q, 0); |
| 546 | 547 | if( g.okHistory ){ |
| 547 | - @ <a href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">[%h(zTagName)]</a> | |
| 548 | + @ <a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zTagName)"> | |
| 549 | + @ [%h(zTagName)]</a> | |
| 548 | 550 | }else{ |
| 549 | - @ <b>[%h(zTagName)]</b> | |
| 551 | + @ <span class="tagDsp">[%h(zTagName)]</span> | |
| 550 | 552 | } |
| 551 | 553 | } |
| 552 | 554 | db_finalize(&q); |
| 553 | 555 | } |
| 554 | 556 | |
| @@ -573,14 +575,14 @@ | ||
| 573 | 575 | " ORDER BY event.mtime DESC", |
| 574 | 576 | timeline_query_for_www() |
| 575 | 577 | ); |
| 576 | 578 | www_print_timeline(&q, 0, tagtimeline_extra); |
| 577 | 579 | db_finalize(&q); |
| 578 | - @ <br clear="both"> | |
| 579 | - @ <script> | |
| 580 | + @ <br /> | |
| 581 | + @ <script type="text/JavaScript"> | |
| 580 | 582 | @ function xin(id){ |
| 581 | 583 | @ } |
| 582 | 584 | @ function xout(id){ |
| 583 | 585 | @ } |
| 584 | 586 | @ </script> |
| 585 | 587 | style_footer(); |
| 586 | 588 | } |
| 587 | 589 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -514,13 +514,14 @@ | |
| 514 | ); |
| 515 | @ <ul> |
| 516 | while( db_step(&q)==SQLITE_ROW ){ |
| 517 | const char *zName = db_column_text(&q, 0); |
| 518 | if( g.okHistory ){ |
| 519 | @ <li><a href=%s(g.zBaseURL)/timeline?t=%T(zName)>%h(zName)</a></li> |
| 520 | }else{ |
| 521 | @ <li><strong>%h(zName)</strong></li> |
| 522 | } |
| 523 | } |
| 524 | @ </ul> |
| 525 | db_finalize(&q); |
| 526 | style_footer(); |
| @@ -542,13 +543,14 @@ | |
| 542 | rid |
| 543 | ); |
| 544 | while( db_step(&q)==SQLITE_ROW ){ |
| 545 | const char *zTagName = db_column_text(&q, 0); |
| 546 | if( g.okHistory ){ |
| 547 | @ <a href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">[%h(zTagName)]</a> |
| 548 | }else{ |
| 549 | @ <b>[%h(zTagName)]</b> |
| 550 | } |
| 551 | } |
| 552 | db_finalize(&q); |
| 553 | } |
| 554 | |
| @@ -573,14 +575,14 @@ | |
| 573 | " ORDER BY event.mtime DESC", |
| 574 | timeline_query_for_www() |
| 575 | ); |
| 576 | www_print_timeline(&q, 0, tagtimeline_extra); |
| 577 | db_finalize(&q); |
| 578 | @ <br clear="both"> |
| 579 | @ <script> |
| 580 | @ function xin(id){ |
| 581 | @ } |
| 582 | @ function xout(id){ |
| 583 | @ } |
| 584 | @ </script> |
| 585 | style_footer(); |
| 586 | } |
| 587 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -514,13 +514,14 @@ | |
| 514 | ); |
| 515 | @ <ul> |
| 516 | while( db_step(&q)==SQLITE_ROW ){ |
| 517 | const char *zName = db_column_text(&q, 0); |
| 518 | if( g.okHistory ){ |
| 519 | @ <li><a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zName)"> |
| 520 | @ %h(zName)</a></li> |
| 521 | }else{ |
| 522 | @ <li><span class="tagDsp">%h(zName)</span></li> |
| 523 | } |
| 524 | } |
| 525 | @ </ul> |
| 526 | db_finalize(&q); |
| 527 | style_footer(); |
| @@ -542,13 +543,14 @@ | |
| 543 | rid |
| 544 | ); |
| 545 | while( db_step(&q)==SQLITE_ROW ){ |
| 546 | const char *zTagName = db_column_text(&q, 0); |
| 547 | if( g.okHistory ){ |
| 548 | @ <a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zTagName)"> |
| 549 | @ [%h(zTagName)]</a> |
| 550 | }else{ |
| 551 | @ <span class="tagDsp">[%h(zTagName)]</span> |
| 552 | } |
| 553 | } |
| 554 | db_finalize(&q); |
| 555 | } |
| 556 | |
| @@ -573,14 +575,14 @@ | |
| 575 | " ORDER BY event.mtime DESC", |
| 576 | timeline_query_for_www() |
| 577 | ); |
| 578 | www_print_timeline(&q, 0, tagtimeline_extra); |
| 579 | db_finalize(&q); |
| 580 | @ <br /> |
| 581 | @ <script type="text/JavaScript"> |
| 582 | @ function xin(id){ |
| 583 | @ } |
| 584 | @ function xout(id){ |
| 585 | @ } |
| 586 | @ </script> |
| 587 | style_footer(); |
| 588 | } |
| 589 |
+2
-1
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -278,11 +278,12 @@ | ||
| 278 | 278 | blob_reset(&name); |
| 279 | 279 | for(i=0; i<nElem; i++){ |
| 280 | 280 | zH = htmlize((char*)azElem[i], aszElem[i]); |
| 281 | 281 | if( zValue && aszElem[i]==nValue |
| 282 | 282 | && memcmp(zValue, azElem[i], nValue)==0 ){ |
| 283 | - z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH); | |
| 283 | + z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>", | |
| 284 | + zH, zH); | |
| 284 | 285 | }else{ |
| 285 | 286 | z = mprintf("<option value=\"%s\">%s</option>", zH, zH); |
| 286 | 287 | } |
| 287 | 288 | free(zH); |
| 288 | 289 | sendText(z, -1, 0); |
| 289 | 290 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -278,11 +278,12 @@ | |
| 278 | blob_reset(&name); |
| 279 | for(i=0; i<nElem; i++){ |
| 280 | zH = htmlize((char*)azElem[i], aszElem[i]); |
| 281 | if( zValue && aszElem[i]==nValue |
| 282 | && memcmp(zValue, azElem[i], nValue)==0 ){ |
| 283 | z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH); |
| 284 | }else{ |
| 285 | z = mprintf("<option value=\"%s\">%s</option>", zH, zH); |
| 286 | } |
| 287 | free(zH); |
| 288 | sendText(z, -1, 0); |
| 289 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -278,11 +278,12 @@ | |
| 278 | blob_reset(&name); |
| 279 | for(i=0; i<nElem; i++){ |
| 280 | zH = htmlize((char*)azElem[i], aszElem[i]); |
| 281 | if( zValue && aszElem[i]==nValue |
| 282 | && memcmp(zValue, azElem[i], nValue)==0 ){ |
| 283 | z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>", |
| 284 | zH, zH); |
| 285 | }else{ |
| 286 | z = mprintf("<option value=\"%s\">%s</option>", zH, zH); |
| 287 | } |
| 288 | free(zH); |
| 289 | sendText(z, -1, 0); |
| 290 |
+33
-24
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -48,13 +48,14 @@ | ||
| 48 | 48 | */ |
| 49 | 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | 50 | char zShortUuid[UUID_SIZE+1]; |
| 51 | 51 | shorten_uuid(zShortUuid, zUuid); |
| 52 | 52 | if( g.okHistory ){ |
| 53 | - @ <a href="%s(g.zBaseURL)/info/%s(zShortUuid)">[%s(zShortUuid)]</a> | |
| 53 | + @ <a class="timelineHistLink" href="%s(g.zBaseURL)/info/%s(zShortUuid)"> | |
| 54 | + @ [%s(zShortUuid)]</a> | |
| 54 | 55 | }else{ |
| 55 | - @ <b>[%s(zShortUuid)]</b> | |
| 56 | + @ <span class="timelineHistDsp">[%s(zShortUuid)]</span> | |
| 56 | 57 | } |
| 57 | 58 | } |
| 58 | 59 | |
| 59 | 60 | /* |
| 60 | 61 | ** Generate a hyperlink that invokes javascript to highlight |
| @@ -83,11 +84,11 @@ | ||
| 83 | 84 | void hyperlink_to_diff(const char *zV1, const char *zV2){ |
| 84 | 85 | if( g.okHistory ){ |
| 85 | 86 | if( zV2==0 ){ |
| 86 | 87 | @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a> |
| 87 | 88 | }else{ |
| 88 | - @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> | |
| 89 | + @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> | |
| 89 | 90 | } |
| 90 | 91 | } |
| 91 | 92 | } |
| 92 | 93 | |
| 93 | 94 | /* |
| @@ -109,11 +110,11 @@ | ||
| 109 | 110 | */ |
| 110 | 111 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 111 | 112 | if( zSuf==0 ) zSuf = ""; |
| 112 | 113 | if( g.okHistory ){ |
| 113 | 114 | if( zD && zD[0] ){ |
| 114 | - @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) | |
| 115 | + @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) | |
| 115 | 116 | }else{ |
| 116 | 117 | @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 117 | 118 | } |
| 118 | 119 | }else{ |
| 119 | 120 | @ %s(zU) |
| @@ -189,14 +190,17 @@ | ||
| 189 | 190 | }else{ |
| 190 | 191 | wikiFlags = WIKI_INLINE | WIKI_NOBLOCK; |
| 191 | 192 | } |
| 192 | 193 | if( tmFlags & TIMELINE_GRAPH ){ |
| 193 | 194 | pGraph = graph_init(); |
| 195 | + /* style is not moved to css, because this is | |
| 196 | + ** a technical div for the timeline graph | |
| 197 | + */ | |
| 194 | 198 | @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div> |
| 195 | 199 | } |
| 196 | 200 | |
| 197 | - @ <table cellspacing=0 border=0 cellpadding=0> | |
| 201 | + @ <table class="timelineTable"> | |
| 198 | 202 | blob_zero(&comment); |
| 199 | 203 | while( db_step(pQuery)==SQLITE_ROW ){ |
| 200 | 204 | int rid = db_column_int(pQuery, 0); |
| 201 | 205 | const char *zUuid = db_column_text(pQuery, 1); |
| 202 | 206 | int isLeaf = db_column_int(pQuery, 5); |
| @@ -218,30 +222,30 @@ | ||
| 218 | 222 | } |
| 219 | 223 | } |
| 220 | 224 | } |
| 221 | 225 | prevTagid = tagid; |
| 222 | 226 | if( suppressCnt ){ |
| 223 | - @ <tr><td><td><td> | |
| 224 | - @ <small><i>... %d(suppressCnt) similar | |
| 225 | - @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr> | |
| 227 | + @ <tr><td /><td /><td> | |
| 228 | + @ <span class="timelineDisabled">... %d(suppressCnt) similar | |
| 229 | + @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr> | |
| 226 | 230 | suppressCnt = 0; |
| 227 | 231 | } |
| 228 | 232 | if( strcmp(zType,"div")==0 ){ |
| 229 | - @ <tr><td colspan=3><hr></td></tr> | |
| 233 | + @ <tr><td colspan="3"><hr /></td></tr> | |
| 230 | 234 | continue; |
| 231 | 235 | } |
| 232 | 236 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 233 | 237 | sprintf(zPrevDate, "%.10s", zDate); |
| 234 | 238 | @ <tr><td> |
| 235 | - @ <div class="divider"><nobr>%s(zPrevDate)</nobr></div> | |
| 239 | + @ <div class="divider">%s(zPrevDate)</div> | |
| 236 | 240 | @ </td></tr> |
| 237 | 241 | } |
| 238 | 242 | memcpy(zTime, &zDate[11], 5); |
| 239 | 243 | zTime[5] = 0; |
| 240 | 244 | @ <tr> |
| 241 | - @ <td valign="top" align="right">%s(zTime)</td> | |
| 242 | - @ <td width="20" align="left" valign="top"> | |
| 245 | + @ <td class="timelineTime">%s(zTime)</td> | |
| 246 | + @ <td class="timelineGraph"> | |
| 243 | 247 | if( pGraph && zType[0]=='c' ){ |
| 244 | 248 | int nParent = 0; |
| 245 | 249 | int aParent[32]; |
| 246 | 250 | const char *zBr; |
| 247 | 251 | int gidx; |
| @@ -267,24 +271,25 @@ | ||
| 267 | 271 | } |
| 268 | 272 | gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr); |
| 269 | 273 | db_reset(&qbranch); |
| 270 | 274 | @ <div id="m%d(gidx)"></div> |
| 271 | 275 | } |
| 276 | + @</td> | |
| 272 | 277 | if( zBgClr && zBgClr[0] ){ |
| 273 | - @ <td valign="top" align="left" bgcolor="%h(zBgClr)"> | |
| 278 | + @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> | |
| 274 | 279 | }else{ |
| 275 | - @ <td valign="top" align="left"> | |
| 280 | + @ <td class="timelineTableCell"> | |
| 276 | 281 | } |
| 277 | 282 | if( zType[0]=='c' ){ |
| 278 | 283 | hyperlink_to_uuid(zUuid); |
| 279 | 284 | if( isLeaf ){ |
| 280 | 285 | if( db_exists("SELECT 1 FROM tagxref" |
| 281 | 286 | " WHERE rid=%d AND tagid=%d AND tagtype>0", |
| 282 | 287 | rid, TAG_CLOSED) ){ |
| 283 | - @ <b>Closed-Leaf:</b> | |
| 288 | + @ <span class="timelineLeaf">Closed-Leaf:</span> | |
| 284 | 289 | }else{ |
| 285 | - @ <b>Leaf:</b> | |
| 290 | + @ <span class="timelineLeaf">Leaf:</span> | |
| 286 | 291 | } |
| 287 | 292 | } |
| 288 | 293 | }else if( (tmFlags & TIMELINE_ARTID)!=0 ){ |
| 289 | 294 | hyperlink_to_uuid(zUuid); |
| 290 | 295 | } |
| @@ -309,23 +314,27 @@ | ||
| 309 | 314 | xExtra(rid); |
| 310 | 315 | } |
| 311 | 316 | @ </td></tr> |
| 312 | 317 | } |
| 313 | 318 | if( suppressCnt ){ |
| 314 | - @ <tr><td><td><td> | |
| 315 | - @ <small><i>... %d(suppressCnt) similar | |
| 316 | - @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr> | |
| 319 | + @ <tr><td /><td /><td> | |
| 320 | + @ <span class="timelineDisabled">... %d(suppressCnt) similar | |
| 321 | + @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr> | |
| 317 | 322 | suppressCnt = 0; |
| 318 | 323 | } |
| 319 | 324 | if( pGraph ){ |
| 320 | 325 | graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0); |
| 321 | 326 | if( pGraph->nErr ){ |
| 322 | 327 | graph_free(pGraph); |
| 323 | 328 | pGraph = 0; |
| 324 | 329 | }else{ |
| 325 | - @ <tr><td><td> | |
| 330 | + /* style is not moved to css, because this is | |
| 331 | + ** a technical div for the timeline graph | |
| 332 | + */ | |
| 333 | + @ <tr><td /><td> | |
| 326 | 334 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 335 | + @ </td></tr> | |
| 327 | 336 | } |
| 328 | 337 | } |
| 329 | 338 | @ </table> |
| 330 | 339 | timeline_output_graph_javascript(pGraph); |
| 331 | 340 | } |
| @@ -337,11 +346,11 @@ | ||
| 337 | 346 | void timeline_output_graph_javascript(GraphContext *pGraph){ |
| 338 | 347 | if( pGraph && pGraph->nErr==0 ){ |
| 339 | 348 | GraphRow *pRow; |
| 340 | 349 | int i; |
| 341 | 350 | char cSep; |
| 342 | - @ <script type="text/JavaScript"> | |
| 351 | + @ <script type="text/JavaScript"> | |
| 343 | 352 | cgi_printf("var rowinfo = [\n"); |
| 344 | 353 | for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ |
| 345 | 354 | cgi_printf("{id:\"m%d\",bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,au:", |
| 346 | 355 | pRow->idx, |
| 347 | 356 | pRow->zBgClr, |
| @@ -883,15 +892,15 @@ | ||
| 883 | 892 | }else if( zBrName ){ |
| 884 | 893 | blob_appendf(&desc, " related to \"%h\"", zBrName); |
| 885 | 894 | tmFlags |= TIMELINE_DISJOINT; |
| 886 | 895 | } |
| 887 | 896 | if( zAfter ){ |
| 888 | - blob_appendf(&desc, " occurring on or after %h.<br>", zAfter); | |
| 897 | + blob_appendf(&desc, " occurring on or after %h.<br />", zAfter); | |
| 889 | 898 | }else if( zBefore ){ |
| 890 | - blob_appendf(&desc, " occurring on or before %h.<br>", zBefore); | |
| 899 | + blob_appendf(&desc, " occurring on or before %h.<br />", zBefore); | |
| 891 | 900 | }else if( zCirca ){ |
| 892 | - blob_appendf(&desc, " occurring around %h.<br>", zCirca); | |
| 901 | + blob_appendf(&desc, " occurring around %h.<br />", zCirca); | |
| 893 | 902 | } |
| 894 | 903 | if( zSearch ){ |
| 895 | 904 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 896 | 905 | } |
| 897 | 906 | if( g.okHistory ){ |
| 898 | 907 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -48,13 +48,14 @@ | |
| 48 | */ |
| 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | char zShortUuid[UUID_SIZE+1]; |
| 51 | shorten_uuid(zShortUuid, zUuid); |
| 52 | if( g.okHistory ){ |
| 53 | @ <a href="%s(g.zBaseURL)/info/%s(zShortUuid)">[%s(zShortUuid)]</a> |
| 54 | }else{ |
| 55 | @ <b>[%s(zShortUuid)]</b> |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /* |
| 60 | ** Generate a hyperlink that invokes javascript to highlight |
| @@ -83,11 +84,11 @@ | |
| 83 | void hyperlink_to_diff(const char *zV1, const char *zV2){ |
| 84 | if( g.okHistory ){ |
| 85 | if( zV2==0 ){ |
| 86 | @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a> |
| 87 | }else{ |
| 88 | @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | /* |
| @@ -109,11 +110,11 @@ | |
| 109 | */ |
| 110 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 111 | if( zSuf==0 ) zSuf = ""; |
| 112 | if( g.okHistory ){ |
| 113 | if( zD && zD[0] ){ |
| 114 | @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 115 | }else{ |
| 116 | @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 117 | } |
| 118 | }else{ |
| 119 | @ %s(zU) |
| @@ -189,14 +190,17 @@ | |
| 189 | }else{ |
| 190 | wikiFlags = WIKI_INLINE | WIKI_NOBLOCK; |
| 191 | } |
| 192 | if( tmFlags & TIMELINE_GRAPH ){ |
| 193 | pGraph = graph_init(); |
| 194 | @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div> |
| 195 | } |
| 196 | |
| 197 | @ <table cellspacing=0 border=0 cellpadding=0> |
| 198 | blob_zero(&comment); |
| 199 | while( db_step(pQuery)==SQLITE_ROW ){ |
| 200 | int rid = db_column_int(pQuery, 0); |
| 201 | const char *zUuid = db_column_text(pQuery, 1); |
| 202 | int isLeaf = db_column_int(pQuery, 5); |
| @@ -218,30 +222,30 @@ | |
| 218 | } |
| 219 | } |
| 220 | } |
| 221 | prevTagid = tagid; |
| 222 | if( suppressCnt ){ |
| 223 | @ <tr><td><td><td> |
| 224 | @ <small><i>... %d(suppressCnt) similar |
| 225 | @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr> |
| 226 | suppressCnt = 0; |
| 227 | } |
| 228 | if( strcmp(zType,"div")==0 ){ |
| 229 | @ <tr><td colspan=3><hr></td></tr> |
| 230 | continue; |
| 231 | } |
| 232 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 233 | sprintf(zPrevDate, "%.10s", zDate); |
| 234 | @ <tr><td> |
| 235 | @ <div class="divider"><nobr>%s(zPrevDate)</nobr></div> |
| 236 | @ </td></tr> |
| 237 | } |
| 238 | memcpy(zTime, &zDate[11], 5); |
| 239 | zTime[5] = 0; |
| 240 | @ <tr> |
| 241 | @ <td valign="top" align="right">%s(zTime)</td> |
| 242 | @ <td width="20" align="left" valign="top"> |
| 243 | if( pGraph && zType[0]=='c' ){ |
| 244 | int nParent = 0; |
| 245 | int aParent[32]; |
| 246 | const char *zBr; |
| 247 | int gidx; |
| @@ -267,24 +271,25 @@ | |
| 267 | } |
| 268 | gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr); |
| 269 | db_reset(&qbranch); |
| 270 | @ <div id="m%d(gidx)"></div> |
| 271 | } |
| 272 | if( zBgClr && zBgClr[0] ){ |
| 273 | @ <td valign="top" align="left" bgcolor="%h(zBgClr)"> |
| 274 | }else{ |
| 275 | @ <td valign="top" align="left"> |
| 276 | } |
| 277 | if( zType[0]=='c' ){ |
| 278 | hyperlink_to_uuid(zUuid); |
| 279 | if( isLeaf ){ |
| 280 | if( db_exists("SELECT 1 FROM tagxref" |
| 281 | " WHERE rid=%d AND tagid=%d AND tagtype>0", |
| 282 | rid, TAG_CLOSED) ){ |
| 283 | @ <b>Closed-Leaf:</b> |
| 284 | }else{ |
| 285 | @ <b>Leaf:</b> |
| 286 | } |
| 287 | } |
| 288 | }else if( (tmFlags & TIMELINE_ARTID)!=0 ){ |
| 289 | hyperlink_to_uuid(zUuid); |
| 290 | } |
| @@ -309,23 +314,27 @@ | |
| 309 | xExtra(rid); |
| 310 | } |
| 311 | @ </td></tr> |
| 312 | } |
| 313 | if( suppressCnt ){ |
| 314 | @ <tr><td><td><td> |
| 315 | @ <small><i>... %d(suppressCnt) similar |
| 316 | @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr> |
| 317 | suppressCnt = 0; |
| 318 | } |
| 319 | if( pGraph ){ |
| 320 | graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0); |
| 321 | if( pGraph->nErr ){ |
| 322 | graph_free(pGraph); |
| 323 | pGraph = 0; |
| 324 | }else{ |
| 325 | @ <tr><td><td> |
| 326 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 327 | } |
| 328 | } |
| 329 | @ </table> |
| 330 | timeline_output_graph_javascript(pGraph); |
| 331 | } |
| @@ -337,11 +346,11 @@ | |
| 337 | void timeline_output_graph_javascript(GraphContext *pGraph){ |
| 338 | if( pGraph && pGraph->nErr==0 ){ |
| 339 | GraphRow *pRow; |
| 340 | int i; |
| 341 | char cSep; |
| 342 | @ <script type="text/JavaScript"> |
| 343 | cgi_printf("var rowinfo = [\n"); |
| 344 | for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ |
| 345 | cgi_printf("{id:\"m%d\",bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,au:", |
| 346 | pRow->idx, |
| 347 | pRow->zBgClr, |
| @@ -883,15 +892,15 @@ | |
| 883 | }else if( zBrName ){ |
| 884 | blob_appendf(&desc, " related to \"%h\"", zBrName); |
| 885 | tmFlags |= TIMELINE_DISJOINT; |
| 886 | } |
| 887 | if( zAfter ){ |
| 888 | blob_appendf(&desc, " occurring on or after %h.<br>", zAfter); |
| 889 | }else if( zBefore ){ |
| 890 | blob_appendf(&desc, " occurring on or before %h.<br>", zBefore); |
| 891 | }else if( zCirca ){ |
| 892 | blob_appendf(&desc, " occurring around %h.<br>", zCirca); |
| 893 | } |
| 894 | if( zSearch ){ |
| 895 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 896 | } |
| 897 | if( g.okHistory ){ |
| 898 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -48,13 +48,14 @@ | |
| 48 | */ |
| 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | char zShortUuid[UUID_SIZE+1]; |
| 51 | shorten_uuid(zShortUuid, zUuid); |
| 52 | if( g.okHistory ){ |
| 53 | @ <a class="timelineHistLink" href="%s(g.zBaseURL)/info/%s(zShortUuid)"> |
| 54 | @ [%s(zShortUuid)]</a> |
| 55 | }else{ |
| 56 | @ <span class="timelineHistDsp">[%s(zShortUuid)]</span> |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | /* |
| 61 | ** Generate a hyperlink that invokes javascript to highlight |
| @@ -83,11 +84,11 @@ | |
| 84 | void hyperlink_to_diff(const char *zV1, const char *zV2){ |
| 85 | if( g.okHistory ){ |
| 86 | if( zV2==0 ){ |
| 87 | @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a> |
| 88 | }else{ |
| 89 | @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | /* |
| @@ -109,11 +110,11 @@ | |
| 110 | */ |
| 111 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 112 | if( zSuf==0 ) zSuf = ""; |
| 113 | if( g.okHistory ){ |
| 114 | if( zD && zD[0] ){ |
| 115 | @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 116 | }else{ |
| 117 | @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 118 | } |
| 119 | }else{ |
| 120 | @ %s(zU) |
| @@ -189,14 +190,17 @@ | |
| 190 | }else{ |
| 191 | wikiFlags = WIKI_INLINE | WIKI_NOBLOCK; |
| 192 | } |
| 193 | if( tmFlags & TIMELINE_GRAPH ){ |
| 194 | pGraph = graph_init(); |
| 195 | /* style is not moved to css, because this is |
| 196 | ** a technical div for the timeline graph |
| 197 | */ |
| 198 | @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div> |
| 199 | } |
| 200 | |
| 201 | @ <table class="timelineTable"> |
| 202 | blob_zero(&comment); |
| 203 | while( db_step(pQuery)==SQLITE_ROW ){ |
| 204 | int rid = db_column_int(pQuery, 0); |
| 205 | const char *zUuid = db_column_text(pQuery, 1); |
| 206 | int isLeaf = db_column_int(pQuery, 5); |
| @@ -218,30 +222,30 @@ | |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | prevTagid = tagid; |
| 226 | if( suppressCnt ){ |
| 227 | @ <tr><td /><td /><td> |
| 228 | @ <span class="timelineDisabled">... %d(suppressCnt) similar |
| 229 | @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr> |
| 230 | suppressCnt = 0; |
| 231 | } |
| 232 | if( strcmp(zType,"div")==0 ){ |
| 233 | @ <tr><td colspan="3"><hr /></td></tr> |
| 234 | continue; |
| 235 | } |
| 236 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 237 | sprintf(zPrevDate, "%.10s", zDate); |
| 238 | @ <tr><td> |
| 239 | @ <div class="divider">%s(zPrevDate)</div> |
| 240 | @ </td></tr> |
| 241 | } |
| 242 | memcpy(zTime, &zDate[11], 5); |
| 243 | zTime[5] = 0; |
| 244 | @ <tr> |
| 245 | @ <td class="timelineTime">%s(zTime)</td> |
| 246 | @ <td class="timelineGraph"> |
| 247 | if( pGraph && zType[0]=='c' ){ |
| 248 | int nParent = 0; |
| 249 | int aParent[32]; |
| 250 | const char *zBr; |
| 251 | int gidx; |
| @@ -267,24 +271,25 @@ | |
| 271 | } |
| 272 | gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr); |
| 273 | db_reset(&qbranch); |
| 274 | @ <div id="m%d(gidx)"></div> |
| 275 | } |
| 276 | @</td> |
| 277 | if( zBgClr && zBgClr[0] ){ |
| 278 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 279 | }else{ |
| 280 | @ <td class="timelineTableCell"> |
| 281 | } |
| 282 | if( zType[0]=='c' ){ |
| 283 | hyperlink_to_uuid(zUuid); |
| 284 | if( isLeaf ){ |
| 285 | if( db_exists("SELECT 1 FROM tagxref" |
| 286 | " WHERE rid=%d AND tagid=%d AND tagtype>0", |
| 287 | rid, TAG_CLOSED) ){ |
| 288 | @ <span class="timelineLeaf">Closed-Leaf:</span> |
| 289 | }else{ |
| 290 | @ <span class="timelineLeaf">Leaf:</span> |
| 291 | } |
| 292 | } |
| 293 | }else if( (tmFlags & TIMELINE_ARTID)!=0 ){ |
| 294 | hyperlink_to_uuid(zUuid); |
| 295 | } |
| @@ -309,23 +314,27 @@ | |
| 314 | xExtra(rid); |
| 315 | } |
| 316 | @ </td></tr> |
| 317 | } |
| 318 | if( suppressCnt ){ |
| 319 | @ <tr><td /><td /><td> |
| 320 | @ <span class="timelineDisabled">... %d(suppressCnt) similar |
| 321 | @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr> |
| 322 | suppressCnt = 0; |
| 323 | } |
| 324 | if( pGraph ){ |
| 325 | graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0); |
| 326 | if( pGraph->nErr ){ |
| 327 | graph_free(pGraph); |
| 328 | pGraph = 0; |
| 329 | }else{ |
| 330 | /* style is not moved to css, because this is |
| 331 | ** a technical div for the timeline graph |
| 332 | */ |
| 333 | @ <tr><td /><td> |
| 334 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 335 | @ </td></tr> |
| 336 | } |
| 337 | } |
| 338 | @ </table> |
| 339 | timeline_output_graph_javascript(pGraph); |
| 340 | } |
| @@ -337,11 +346,11 @@ | |
| 346 | void timeline_output_graph_javascript(GraphContext *pGraph){ |
| 347 | if( pGraph && pGraph->nErr==0 ){ |
| 348 | GraphRow *pRow; |
| 349 | int i; |
| 350 | char cSep; |
| 351 | @ <script type="text/JavaScript"> |
| 352 | cgi_printf("var rowinfo = [\n"); |
| 353 | for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ |
| 354 | cgi_printf("{id:\"m%d\",bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,au:", |
| 355 | pRow->idx, |
| 356 | pRow->zBgClr, |
| @@ -883,15 +892,15 @@ | |
| 892 | }else if( zBrName ){ |
| 893 | blob_appendf(&desc, " related to \"%h\"", zBrName); |
| 894 | tmFlags |= TIMELINE_DISJOINT; |
| 895 | } |
| 896 | if( zAfter ){ |
| 897 | blob_appendf(&desc, " occurring on or after %h.<br />", zAfter); |
| 898 | }else if( zBefore ){ |
| 899 | blob_appendf(&desc, " occurring on or before %h.<br />", zBefore); |
| 900 | }else if( zCirca ){ |
| 901 | blob_appendf(&desc, " occurring around %h.<br />", zCirca); |
| 902 | } |
| 903 | if( zSearch ){ |
| 904 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 905 | } |
| 906 | if( g.okHistory ){ |
| 907 |
+16
-13
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -313,11 +313,11 @@ | ||
| 313 | 313 | style_submenu_element("New Ticket", "Create a new ticket", |
| 314 | 314 | "%s/tktnew", g.zTop); |
| 315 | 315 | } |
| 316 | 316 | if( g.okApndTkt && g.okAttach ){ |
| 317 | 317 | style_submenu_element("Attach", "Add An Attachment", |
| 318 | - "%s/attachadd?tkt=%T&from=%s/tktview/%t", | |
| 318 | + "%s/attachadd?tkt=%T&from=%s/tktview/%t", | |
| 319 | 319 | g.zTop, zUuid, g.zTop, zUuid); |
| 320 | 320 | } |
| 321 | 321 | style_header("View Ticket"); |
| 322 | 322 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1); |
| 323 | 323 | ticket_init(); |
| @@ -342,24 +342,24 @@ | ||
| 342 | 342 | while( db_step(&q)==SQLITE_ROW ){ |
| 343 | 343 | const char *zDate = db_column_text(&q, 0); |
| 344 | 344 | const char *zFile = db_column_text(&q, 1); |
| 345 | 345 | const char *zUser = db_column_text(&q, 2); |
| 346 | 346 | if( cnt==0 ){ |
| 347 | - @ <hr><h2>Attachments:</h2> | |
| 347 | + @ <hr /><h2>Attachments:</h2> | |
| 348 | 348 | @ <ul> |
| 349 | 349 | } |
| 350 | 350 | cnt++; |
| 351 | 351 | if( g.okRead && g.okHistory ){ |
| 352 | - @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)"> | |
| 352 | + @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)"> | |
| 353 | 353 | @ %h(zFile)</a> |
| 354 | 354 | }else{ |
| 355 | 355 | @ %h(zFile) |
| 356 | 356 | } |
| 357 | 357 | @ added by %h(zUser) on |
| 358 | 358 | hyperlink_to_date(zDate, "."); |
| 359 | 359 | if( g.okWrTkt && g.okAttach ){ |
| 360 | - @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>] | |
| 360 | + @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>] | |
| 361 | 361 | } |
| 362 | 362 | } |
| 363 | 363 | if( cnt ){ |
| 364 | 364 | @ </ul> |
| 365 | 365 | } |
| @@ -511,12 +511,13 @@ | ||
| 511 | 511 | if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1); |
| 512 | 512 | ticket_init(); |
| 513 | 513 | getAllTicketFields(); |
| 514 | 514 | initializeVariablesFromDb(); |
| 515 | 515 | initializeVariablesFromCGI(); |
| 516 | - @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> | |
| 516 | + @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p> | |
| 517 | 517 | login_insert_csrf_secret(); |
| 518 | + @ </p> | |
| 518 | 519 | zScript = ticket_newpage_code(); |
| 519 | 520 | Th_Store("login", g.zLogin); |
| 520 | 521 | Th_Store("date", db_text(0, "SELECT datetime('now')")); |
| 521 | 522 | Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, |
| 522 | 523 | (void*)&zNewUuid, 0); |
| @@ -554,34 +555,36 @@ | ||
| 554 | 555 | cgi_redirectf("tktview?name=%T", zName); |
| 555 | 556 | } |
| 556 | 557 | style_header("Edit Ticket"); |
| 557 | 558 | if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE |
| 558 | 559 | || !validate16(zName,nName) ){ |
| 559 | - @ <font color="red"><b>Not a valid ticket id: \"%h(zName)\"</b></font> | |
| 560 | + @ <span class="tktError">Not a valid ticket id: \"%h(zName)\"</span> | |
| 560 | 561 | style_footer(); |
| 561 | 562 | return; |
| 562 | 563 | } |
| 563 | 564 | nRec = db_int(0, "SELECT count(*) FROM ticket WHERE tkt_uuid GLOB '%q*'", |
| 564 | 565 | zName); |
| 565 | 566 | if( nRec==0 ){ |
| 566 | - @ <font color="red"><b>No such ticket: \"%h(zName)\"</b></font> | |
| 567 | + @ <span class="tktError">No such ticket: \"%h(zName)\"</span> | |
| 567 | 568 | style_footer(); |
| 568 | 569 | return; |
| 569 | 570 | } |
| 570 | 571 | if( nRec>1 ){ |
| 571 | - @ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font> | |
| 572 | + @ <span class="tktError"><b>%d(nRec) tickets begin with: | |
| 573 | + @ \"%h(zName)\"</span> | |
| 572 | 574 | style_footer(); |
| 573 | 575 | return; |
| 574 | 576 | } |
| 575 | 577 | if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1); |
| 576 | 578 | ticket_init(); |
| 577 | 579 | getAllTicketFields(); |
| 578 | 580 | initializeVariablesFromCGI(); |
| 579 | 581 | initializeVariablesFromDb(); |
| 580 | - @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> | |
| 581 | - @ <input type="hidden" name="name" value="%s(zName)"> | |
| 582 | + @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p> | |
| 583 | + @ <input type="hidden" name="name" value="%s(zName)" /> | |
| 582 | 584 | login_insert_csrf_secret(); |
| 585 | + @ </p> | |
| 583 | 586 | zScript = ticket_editpage_code(); |
| 584 | 587 | Th_Store("login", g.zLogin); |
| 585 | 588 | Th_Store("date", db_text(0, "SELECT datetime('now')")); |
| 586 | 589 | Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0); |
| 587 | 590 | Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0); |
| @@ -624,11 +627,11 @@ | ||
| 624 | 627 | return 0; |
| 625 | 628 | } |
| 626 | 629 | |
| 627 | 630 | /* |
| 628 | 631 | ** WEBPAGE: tkttimeline |
| 629 | -** URL: /tkttimeline?name=TICKETUUID&y=TYPE | |
| 632 | +** URL: /tkttimeline?name=TICKETUUID&y=TYPE | |
| 630 | 633 | ** |
| 631 | 634 | ** Show the change history for a single ticket in timeline format. |
| 632 | 635 | */ |
| 633 | 636 | void tkttimeline_page(void){ |
| 634 | 637 | Stmt q; |
| @@ -644,11 +647,11 @@ | ||
| 644 | 647 | if( !g.okHistory || !g.okRdTkt ){ login_needed(); return; } |
| 645 | 648 | zUuid = PD("name",""); |
| 646 | 649 | zType = PD("y","a"); |
| 647 | 650 | if( zType[0]!='c' ){ |
| 648 | 651 | style_submenu_element("Check-ins", "Check-ins", |
| 649 | - "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); | |
| 652 | + "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); | |
| 650 | 653 | }else{ |
| 651 | 654 | style_submenu_element("Timeline", "Timeline", |
| 652 | 655 | "%s/tkttimeline?name=%T", g.zTop, zUuid); |
| 653 | 656 | } |
| 654 | 657 | style_submenu_element("History", "History", |
| @@ -776,12 +779,12 @@ | ||
| 776 | 779 | @ <p>Ticket change |
| 777 | 780 | @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>] |
| 778 | 781 | @ (rid %d(rid)) by |
| 779 | 782 | hyperlink_to_user(m.zUser,zDate," on"); |
| 780 | 783 | hyperlink_to_date(zDate, ":"); |
| 781 | - ticket_output_change_artifact(&m); | |
| 782 | 784 | @ </p> |
| 785 | + ticket_output_change_artifact(&m); | |
| 783 | 786 | } |
| 784 | 787 | manifest_clear(&m); |
| 785 | 788 | } |
| 786 | 789 | } |
| 787 | 790 | db_finalize(&q); |
| 788 | 791 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -313,11 +313,11 @@ | |
| 313 | style_submenu_element("New Ticket", "Create a new ticket", |
| 314 | "%s/tktnew", g.zTop); |
| 315 | } |
| 316 | if( g.okApndTkt && g.okAttach ){ |
| 317 | style_submenu_element("Attach", "Add An Attachment", |
| 318 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 319 | g.zTop, zUuid, g.zTop, zUuid); |
| 320 | } |
| 321 | style_header("View Ticket"); |
| 322 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1); |
| 323 | ticket_init(); |
| @@ -342,24 +342,24 @@ | |
| 342 | while( db_step(&q)==SQLITE_ROW ){ |
| 343 | const char *zDate = db_column_text(&q, 0); |
| 344 | const char *zFile = db_column_text(&q, 1); |
| 345 | const char *zUser = db_column_text(&q, 2); |
| 346 | if( cnt==0 ){ |
| 347 | @ <hr><h2>Attachments:</h2> |
| 348 | @ <ul> |
| 349 | } |
| 350 | cnt++; |
| 351 | if( g.okRead && g.okHistory ){ |
| 352 | @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)"> |
| 353 | @ %h(zFile)</a> |
| 354 | }else{ |
| 355 | @ %h(zFile) |
| 356 | } |
| 357 | @ added by %h(zUser) on |
| 358 | hyperlink_to_date(zDate, "."); |
| 359 | if( g.okWrTkt && g.okAttach ){ |
| 360 | @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>] |
| 361 | } |
| 362 | } |
| 363 | if( cnt ){ |
| 364 | @ </ul> |
| 365 | } |
| @@ -511,12 +511,13 @@ | |
| 511 | if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1); |
| 512 | ticket_init(); |
| 513 | getAllTicketFields(); |
| 514 | initializeVariablesFromDb(); |
| 515 | initializeVariablesFromCGI(); |
| 516 | @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> |
| 517 | login_insert_csrf_secret(); |
| 518 | zScript = ticket_newpage_code(); |
| 519 | Th_Store("login", g.zLogin); |
| 520 | Th_Store("date", db_text(0, "SELECT datetime('now')")); |
| 521 | Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, |
| 522 | (void*)&zNewUuid, 0); |
| @@ -554,34 +555,36 @@ | |
| 554 | cgi_redirectf("tktview?name=%T", zName); |
| 555 | } |
| 556 | style_header("Edit Ticket"); |
| 557 | if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE |
| 558 | || !validate16(zName,nName) ){ |
| 559 | @ <font color="red"><b>Not a valid ticket id: \"%h(zName)\"</b></font> |
| 560 | style_footer(); |
| 561 | return; |
| 562 | } |
| 563 | nRec = db_int(0, "SELECT count(*) FROM ticket WHERE tkt_uuid GLOB '%q*'", |
| 564 | zName); |
| 565 | if( nRec==0 ){ |
| 566 | @ <font color="red"><b>No such ticket: \"%h(zName)\"</b></font> |
| 567 | style_footer(); |
| 568 | return; |
| 569 | } |
| 570 | if( nRec>1 ){ |
| 571 | @ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font> |
| 572 | style_footer(); |
| 573 | return; |
| 574 | } |
| 575 | if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1); |
| 576 | ticket_init(); |
| 577 | getAllTicketFields(); |
| 578 | initializeVariablesFromCGI(); |
| 579 | initializeVariablesFromDb(); |
| 580 | @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> |
| 581 | @ <input type="hidden" name="name" value="%s(zName)"> |
| 582 | login_insert_csrf_secret(); |
| 583 | zScript = ticket_editpage_code(); |
| 584 | Th_Store("login", g.zLogin); |
| 585 | Th_Store("date", db_text(0, "SELECT datetime('now')")); |
| 586 | Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0); |
| 587 | Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0); |
| @@ -624,11 +627,11 @@ | |
| 624 | return 0; |
| 625 | } |
| 626 | |
| 627 | /* |
| 628 | ** WEBPAGE: tkttimeline |
| 629 | ** URL: /tkttimeline?name=TICKETUUID&y=TYPE |
| 630 | ** |
| 631 | ** Show the change history for a single ticket in timeline format. |
| 632 | */ |
| 633 | void tkttimeline_page(void){ |
| 634 | Stmt q; |
| @@ -644,11 +647,11 @@ | |
| 644 | if( !g.okHistory || !g.okRdTkt ){ login_needed(); return; } |
| 645 | zUuid = PD("name",""); |
| 646 | zType = PD("y","a"); |
| 647 | if( zType[0]!='c' ){ |
| 648 | style_submenu_element("Check-ins", "Check-ins", |
| 649 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| 650 | }else{ |
| 651 | style_submenu_element("Timeline", "Timeline", |
| 652 | "%s/tkttimeline?name=%T", g.zTop, zUuid); |
| 653 | } |
| 654 | style_submenu_element("History", "History", |
| @@ -776,12 +779,12 @@ | |
| 776 | @ <p>Ticket change |
| 777 | @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>] |
| 778 | @ (rid %d(rid)) by |
| 779 | hyperlink_to_user(m.zUser,zDate," on"); |
| 780 | hyperlink_to_date(zDate, ":"); |
| 781 | ticket_output_change_artifact(&m); |
| 782 | @ </p> |
| 783 | } |
| 784 | manifest_clear(&m); |
| 785 | } |
| 786 | } |
| 787 | db_finalize(&q); |
| 788 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -313,11 +313,11 @@ | |
| 313 | style_submenu_element("New Ticket", "Create a new ticket", |
| 314 | "%s/tktnew", g.zTop); |
| 315 | } |
| 316 | if( g.okApndTkt && g.okAttach ){ |
| 317 | style_submenu_element("Attach", "Add An Attachment", |
| 318 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 319 | g.zTop, zUuid, g.zTop, zUuid); |
| 320 | } |
| 321 | style_header("View Ticket"); |
| 322 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1); |
| 323 | ticket_init(); |
| @@ -342,24 +342,24 @@ | |
| 342 | while( db_step(&q)==SQLITE_ROW ){ |
| 343 | const char *zDate = db_column_text(&q, 0); |
| 344 | const char *zFile = db_column_text(&q, 1); |
| 345 | const char *zUser = db_column_text(&q, 2); |
| 346 | if( cnt==0 ){ |
| 347 | @ <hr /><h2>Attachments:</h2> |
| 348 | @ <ul> |
| 349 | } |
| 350 | cnt++; |
| 351 | if( g.okRead && g.okHistory ){ |
| 352 | @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)"> |
| 353 | @ %h(zFile)</a> |
| 354 | }else{ |
| 355 | @ %h(zFile) |
| 356 | } |
| 357 | @ added by %h(zUser) on |
| 358 | hyperlink_to_date(zDate, "."); |
| 359 | if( g.okWrTkt && g.okAttach ){ |
| 360 | @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>] |
| 361 | } |
| 362 | } |
| 363 | if( cnt ){ |
| 364 | @ </ul> |
| 365 | } |
| @@ -511,12 +511,13 @@ | |
| 511 | if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1); |
| 512 | ticket_init(); |
| 513 | getAllTicketFields(); |
| 514 | initializeVariablesFromDb(); |
| 515 | initializeVariablesFromCGI(); |
| 516 | @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p> |
| 517 | login_insert_csrf_secret(); |
| 518 | @ </p> |
| 519 | zScript = ticket_newpage_code(); |
| 520 | Th_Store("login", g.zLogin); |
| 521 | Th_Store("date", db_text(0, "SELECT datetime('now')")); |
| 522 | Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, |
| 523 | (void*)&zNewUuid, 0); |
| @@ -554,34 +555,36 @@ | |
| 555 | cgi_redirectf("tktview?name=%T", zName); |
| 556 | } |
| 557 | style_header("Edit Ticket"); |
| 558 | if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE |
| 559 | || !validate16(zName,nName) ){ |
| 560 | @ <span class="tktError">Not a valid ticket id: \"%h(zName)\"</span> |
| 561 | style_footer(); |
| 562 | return; |
| 563 | } |
| 564 | nRec = db_int(0, "SELECT count(*) FROM ticket WHERE tkt_uuid GLOB '%q*'", |
| 565 | zName); |
| 566 | if( nRec==0 ){ |
| 567 | @ <span class="tktError">No such ticket: \"%h(zName)\"</span> |
| 568 | style_footer(); |
| 569 | return; |
| 570 | } |
| 571 | if( nRec>1 ){ |
| 572 | @ <span class="tktError"><b>%d(nRec) tickets begin with: |
| 573 | @ \"%h(zName)\"</span> |
| 574 | style_footer(); |
| 575 | return; |
| 576 | } |
| 577 | if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1); |
| 578 | ticket_init(); |
| 579 | getAllTicketFields(); |
| 580 | initializeVariablesFromCGI(); |
| 581 | initializeVariablesFromDb(); |
| 582 | @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p> |
| 583 | @ <input type="hidden" name="name" value="%s(zName)" /> |
| 584 | login_insert_csrf_secret(); |
| 585 | @ </p> |
| 586 | zScript = ticket_editpage_code(); |
| 587 | Th_Store("login", g.zLogin); |
| 588 | Th_Store("date", db_text(0, "SELECT datetime('now')")); |
| 589 | Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0); |
| 590 | Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0); |
| @@ -624,11 +627,11 @@ | |
| 627 | return 0; |
| 628 | } |
| 629 | |
| 630 | /* |
| 631 | ** WEBPAGE: tkttimeline |
| 632 | ** URL: /tkttimeline?name=TICKETUUID&y=TYPE |
| 633 | ** |
| 634 | ** Show the change history for a single ticket in timeline format. |
| 635 | */ |
| 636 | void tkttimeline_page(void){ |
| 637 | Stmt q; |
| @@ -644,11 +647,11 @@ | |
| 647 | if( !g.okHistory || !g.okRdTkt ){ login_needed(); return; } |
| 648 | zUuid = PD("name",""); |
| 649 | zType = PD("y","a"); |
| 650 | if( zType[0]!='c' ){ |
| 651 | style_submenu_element("Check-ins", "Check-ins", |
| 652 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| 653 | }else{ |
| 654 | style_submenu_element("Timeline", "Timeline", |
| 655 | "%s/tkttimeline?name=%T", g.zTop, zUuid); |
| 656 | } |
| 657 | style_submenu_element("History", "History", |
| @@ -776,12 +779,12 @@ | |
| 779 | @ <p>Ticket change |
| 780 | @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>] |
| 781 | @ (rid %d(rid)) by |
| 782 | hyperlink_to_user(m.zUser,zDate," on"); |
| 783 | hyperlink_to_date(zDate, ":"); |
| 784 | @ </p> |
| 785 | ticket_output_change_artifact(&m); |
| 786 | } |
| 787 | manifest_clear(&m); |
| 788 | } |
| 789 | } |
| 790 | db_finalize(&q); |
| 791 |
+94
-98
| --- src/tktsetup.c | ||
| +++ src/tktsetup.c | ||
| @@ -130,21 +130,21 @@ | ||
| 130 | 130 | db_set(zDbField, z, 0); |
| 131 | 131 | if( xRebuild ) xRebuild(); |
| 132 | 132 | cgi_redirect("tktsetup"); |
| 133 | 133 | } |
| 134 | 134 | } |
| 135 | - @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST"> | |
| 135 | + @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="post"><div> | |
| 136 | 136 | login_insert_csrf_secret(); |
| 137 | 137 | @ <p>%s(zDesc)</p> |
| 138 | 138 | @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea> |
| 139 | - @ <blockquote> | |
| 140 | - @ <input type="submit" name="submit" value="Apply Changes"> | |
| 141 | - @ <input type="submit" name="clear" value="Revert To Default"> | |
| 142 | - @ <input type="submit" name="setup" value="Cancel"> | |
| 143 | - @ </blockquote> | |
| 144 | - @ </form> | |
| 145 | - @ <hr> | |
| 139 | + @ <blockquote><p> | |
| 140 | + @ <input type="submit" name="submit" value="Apply Changes" /> | |
| 141 | + @ <input type="submit" name="clear" value="Revert To Default" /> | |
| 142 | + @ <input type="submit" name="setup" value="Cancel" /> | |
| 143 | + @ </p></blockquote> | |
| 144 | + @ </div></form> | |
| 145 | + @ <hr /> | |
| 146 | 146 | @ <h2>Default %s(zTitle)</h2> |
| 147 | 147 | @ <blockquote><pre> |
| 148 | 148 | @ %h(zDfltValue) |
| 149 | 149 | @ </pre></blockquote> |
| 150 | 150 | style_footer(); |
| @@ -153,13 +153,13 @@ | ||
| 153 | 153 | /* |
| 154 | 154 | ** WEBPAGE: tktsetup_tab |
| 155 | 155 | */ |
| 156 | 156 | void tktsetup_tab_page(void){ |
| 157 | 157 | static const char zDesc[] = |
| 158 | - @ <p>Enter a valid CREATE TABLE statement for the "ticket" table. The | |
| 158 | + @ Enter a valid CREATE TABLE statement for the "ticket" table. The | |
| 159 | 159 | @ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime" |
| 160 | - @ with an unique index on "tkt_uuid" and "tkt_mtime".</p> | |
| 160 | + @ with an unique index on "tkt_uuid" and "tkt_mtime". | |
| 161 | 161 | ; |
| 162 | 162 | tktsetup_generic( |
| 163 | 163 | "Ticket Table Schema", |
| 164 | 164 | "ticket-table", |
| 165 | 165 | zDefaultTicketTable, |
| @@ -229,12 +229,12 @@ | ||
| 229 | 229 | /* |
| 230 | 230 | ** WEBPAGE: tktsetup_com |
| 231 | 231 | */ |
| 232 | 232 | void tktsetup_com_page(void){ |
| 233 | 233 | static const char zDesc[] = |
| 234 | - @ <p>Enter TH1 script that initializes variables prior to generating | |
| 235 | - @ any of the ticket view, edit, or creation pages.</p> | |
| 234 | + @ Enter TH1 script that initializes variables prior to generating | |
| 235 | + @ any of the ticket view, edit, or creation pages. | |
| 236 | 236 | ; |
| 237 | 237 | tktsetup_generic( |
| 238 | 238 | "Ticket Common Script", |
| 239 | 239 | "ticket-common", |
| 240 | 240 | zDefaultTicketCommon, |
| @@ -250,80 +250,80 @@ | ||
| 250 | 250 | @ if {[info exists submit]} { |
| 251 | 251 | @ set status Open |
| 252 | 252 | @ submit_ticket |
| 253 | 253 | @ } |
| 254 | 254 | @ </th1> |
| 255 | -@ <h1 align="center">Enter A New Ticket</h1> | |
| 255 | +@ <h1 style="text-align: center;">Enter A New Ticket</h1> | |
| 256 | 256 | @ <table cellpadding="5"> |
| 257 | 257 | @ <tr> |
| 258 | 258 | @ <td colspan="2"> |
| 259 | -@ Enter a one-line summary of the ticket:<br> | |
| 260 | -@ <input type="text" name="title" size="60" value="$<title>"> | |
| 259 | +@ Enter a one-line summary of the ticket:<br /> | |
| 260 | +@ <input type="text" name="title" size="60" value="$<title>" /> | |
| 261 | 261 | @ </td> |
| 262 | 262 | @ </tr> |
| 263 | 263 | @ |
| 264 | 264 | @ <tr> |
| 265 | -@ <td align="right">Type: | |
| 265 | +@ <td style="text-align: center;">Type: | |
| 266 | 266 | @ <th1>combobox type $type_choices 1</th1> |
| 267 | 267 | @ </td> |
| 268 | 268 | @ <td>What type of ticket is this?</td> |
| 269 | 269 | @ </tr> |
| 270 | 270 | @ |
| 271 | 271 | @ <tr> |
| 272 | -@ <td align="right">Version: | |
| 273 | -@ <input type="text" name="foundin" size="20" value="$<foundin>"> | |
| 272 | +@ <td style="text-align: center;">Version: | |
| 273 | +@ <input type="text" name="foundin" size="20" value="$<foundin>" /> | |
| 274 | 274 | @ </td> |
| 275 | 275 | @ <td>In what version or build number do you observe the problem?</td> |
| 276 | 276 | @ </tr> |
| 277 | 277 | @ |
| 278 | 278 | @ <tr> |
| 279 | -@ <td align="right">Severity: | |
| 279 | +@ <td style="text-align: center;">Severity: | |
| 280 | 280 | @ <th1>combobox severity $severity_choices 1</th1> |
| 281 | 281 | @ </td> |
| 282 | 282 | @ <td>How debilitating is the problem? How badly does the problem |
| 283 | 283 | @ affect the operation of the product?</td> |
| 284 | 284 | @ </tr> |
| 285 | 285 | @ |
| 286 | 286 | @ <tr> |
| 287 | -@ <td align="right">EMail: | |
| 288 | -@ <input type="text" name="private_contact" value="$<private_contact>" size="30"> | |
| 287 | +@ <td style="text-align: center;">EMail: | |
| 288 | +@ <input type="text" name="private_contact" value="$<private_contact>" size="30" /> | |
| 289 | 289 | @ </td> |
| 290 | -@ <td><u>Not publicly visible</u>. Used by developers to contact you with | |
| 291 | -@ questions.</td> | |
| 290 | +@ <td><span style="text-decoration: underline;">Not publicly visible</span>. | |
| 291 | +@ Used by developers to contact you with questions.</td> | |
| 292 | 292 | @ </tr> |
| 293 | 293 | @ |
| 294 | 294 | @ <tr> |
| 295 | 295 | @ <td colspan="2"> |
| 296 | 296 | @ Enter a detailed description of the problem. |
| 297 | 297 | @ For code defects, be sure to provide details on exactly how |
| 298 | 298 | @ the problem can be reproduced. Provide as much detail as |
| 299 | 299 | @ possible. |
| 300 | -@ <br> | |
| 300 | +@ <br /> | |
| 301 | 301 | @ <th1>set nline [linecount $comment 50 10]</th1> |
| 302 | 302 | @ <textarea name="comment" cols="80" rows="$nline" |
| 303 | -@ wrap="virtual" class="wikiedit">$<comment></textarea><br> | |
| 304 | -@ <input type="submit" name="preview" value="Preview"> | |
| 303 | +@ wrap="virtual" class="wikiedit">$<comment></textarea><br /> | |
| 304 | +@ <input type="submit" name="preview" value="Preview" /></td> | |
| 305 | 305 | @ </tr> |
| 306 | 306 | @ |
| 307 | 307 | @ <th1>enable_output [info exists preview]</th1> |
| 308 | 308 | @ <tr><td colspan="2"> |
| 309 | -@ Description Preview:<br><hr> | |
| 309 | +@ Description Preview:<br /><hr /> | |
| 310 | 310 | @ <th1>wiki $comment</th1> |
| 311 | -@ <hr> | |
| 311 | +@ <hr /> | |
| 312 | 312 | @ </td></tr> |
| 313 | 313 | @ <th1>enable_output 1</th1> |
| 314 | 314 | @ |
| 315 | 315 | @ <tr> |
| 316 | -@ <td align="right"> | |
| 317 | -@ <input type="submit" name="submit" value="Submit"> | |
| 316 | +@ <td style="text-align: center;"> | |
| 317 | +@ <input type="submit" name="submit" value="Submit" /> | |
| 318 | 318 | @ </td> |
| 319 | 319 | @ <td>After filling in the information above, press this button to create |
| 320 | 320 | @ the new ticket</td> |
| 321 | 321 | @ </tr> |
| 322 | 322 | @ <tr> |
| 323 | -@ <td align="right"> | |
| 324 | -@ <input type="submit" name="cancel" value="Cancel"> | |
| 323 | +@ <td style="text-align: center;"> | |
| 324 | +@ <input type="submit" name="cancel" value="Cancel" /> | |
| 325 | 325 | @ </td> |
| 326 | 326 | @ <td>Abandon and forget this ticket</td> |
| 327 | 327 | @ </tr> |
| 328 | 328 | @ </table> |
| 329 | 329 | ; |
| @@ -338,12 +338,12 @@ | ||
| 338 | 338 | /* |
| 339 | 339 | ** WEBPAGE: tktsetup_newpage |
| 340 | 340 | */ |
| 341 | 341 | void tktsetup_newpage_page(void){ |
| 342 | 342 | static const char zDesc[] = |
| 343 | - @ <p>Enter HTML with embedded TH1 script that will render the "new ticket" | |
| 344 | - @ page</p> | |
| 343 | + @ Enter HTML with embedded TH1 script that will render the "new ticket" | |
| 344 | + @ page | |
| 345 | 345 | ; |
| 346 | 346 | tktsetup_generic( |
| 347 | 347 | "HTML For New Tickets", |
| 348 | 348 | "ticket-newpage", |
| 349 | 349 | zDefaultNew, |
| @@ -354,51 +354,50 @@ | ||
| 354 | 354 | ); |
| 355 | 355 | } |
| 356 | 356 | |
| 357 | 357 | static const char zDefaultView[] = |
| 358 | 358 | @ <table cellpadding="5"> |
| 359 | -@ <tr><td align="right">Ticket UUID:</td><td bgcolor="#d0d0d0" colspan="3"> | |
| 360 | -@ $<tkt_uuid> | |
| 361 | -@ </td></tr> | |
| 362 | -@ <tr><td align="right">Title:</td> | |
| 363 | -@ <td bgcolor="#d0d0d0" colspan="3" valign="top"> | |
| 359 | +@ <tr><td class="tktDspLabel">Ticket UUID:</td> | |
| 360 | +@ <td class="tktDspValue" colspan="3">$<tkt_uuid></td></tr> | |
| 361 | +@ <tr><td class="tktDspLabel">Title:</td> | |
| 362 | +@ <td class="tktDspValue" colspan="3"> | |
| 364 | 363 | @ <th1>wiki $title</th1> |
| 365 | 364 | @ </td></tr> |
| 366 | -@ <tr><td align="right">Status:</td><td bgcolor="#d0d0d0"> | |
| 365 | +@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue"> | |
| 367 | 366 | @ $<status> |
| 368 | 367 | @ </td> |
| 369 | -@ <td align="right">Type:</td><td bgcolor="#d0d0d0"> | |
| 368 | +@ <td class="tktDspLabel">Type:</td><td class="tktDspValue"> | |
| 370 | 369 | @ $<type> |
| 371 | 370 | @ </td></tr> |
| 372 | -@ <tr><td align="right">Severity:</td><td bgcolor="#d0d0d0"> | |
| 371 | +@ <tr><td class="tktDspLabel">Severity:</td><td class="tktDspValue"> | |
| 373 | 372 | @ $<severity> |
| 374 | 373 | @ </td> |
| 375 | -@ <td align="right">Priority:</td><td bgcolor="#d0d0d0"> | |
| 374 | +@ <td class="tktDspLabel">Priority:</td><td class="tktDspValue"> | |
| 376 | 375 | @ $<priority> |
| 377 | 376 | @ </td></tr> |
| 378 | -@ <tr><td align="right">Subsystem:</td><td bgcolor="#d0d0d0"> | |
| 377 | +@ <tr><td class="tktDspLabel">Subsystem:</td><td class="tktDspValue"> | |
| 379 | 378 | @ $<subsystem> |
| 380 | 379 | @ </td> |
| 381 | -@ <td align="right">Resolution:</td><td bgcolor="#d0d0d0"> | |
| 380 | +@ <td class="tktDspLabel">Resolution:</td><td class="tktDspValue"> | |
| 382 | 381 | @ $<resolution> |
| 383 | 382 | @ </td></tr> |
| 384 | -@ <tr><td align="right">Last Modified:</td><td bgcolor="#d0d0d0"> | |
| 383 | +@ <tr><td class="tktDspLabel">Last Modified:</td><td class="tktDspValue"> | |
| 385 | 384 | @ $<tkt_datetime> |
| 386 | 385 | @ </td> |
| 387 | 386 | @ <th1>enable_output [hascap e]</th1> |
| 388 | -@ <td align="right">Contact:</td><td bgcolor="#d0d0d0"> | |
| 387 | +@ <td class="tktDspLabel">Contact:</td><td class="tktDspValue"> | |
| 389 | 388 | @ $<private_contact> |
| 390 | 389 | @ </td> |
| 391 | 390 | @ <th1>enable_output 1</th1> |
| 392 | 391 | @ </tr> |
| 393 | -@ <tr><td align="right">Version Found In:</td> | |
| 394 | -@ <td colspan="3" valign="top" bgcolor="#d0d0d0"> | |
| 392 | +@ <tr><td class="tktDspLabel">Version Found In:</td> | |
| 393 | +@ <td colspan="3" valign="top" class="tktDspValue"> | |
| 395 | 394 | @ $<foundin> |
| 396 | 395 | @ </td></tr> |
| 397 | 396 | @ <tr><td>Description & Comments:</td></tr> |
| 398 | -@ <tr><td colspan="4" bgcolor="#d0d0d0"> | |
| 399 | -@ <span bgcolor="#d0d0d0"><th1>wiki $comment</th1></span> | |
| 397 | +@ <tr><td colspan="4" class="tktDspValue"> | |
| 398 | +@ <th1>wiki $comment</th1> | |
| 400 | 399 | @ </td></tr> |
| 401 | 400 | @ </table> |
| 402 | 401 | ; |
| 403 | 402 | |
| 404 | 403 | |
| @@ -412,12 +411,11 @@ | ||
| 412 | 411 | /* |
| 413 | 412 | ** WEBPAGE: tktsetup_viewpage |
| 414 | 413 | */ |
| 415 | 414 | void tktsetup_viewpage_page(void){ |
| 416 | 415 | static const char zDesc[] = |
| 417 | - @ <p>Enter HTML with embedded TH1 script that will render the "view ticket" | |
| 418 | - @ page</p> | |
| 416 | + @ Enter HTML with embedded TH1 script that will render the "view ticket" page | |
| 419 | 417 | ; |
| 420 | 418 | tktsetup_generic( |
| 421 | 419 | "HTML For Viewing Tickets", |
| 422 | 420 | "ticket-viewpage", |
| 423 | 421 | zDefaultView, |
| @@ -432,51 +430,51 @@ | ||
| 432 | 430 | @ <th1> |
| 433 | 431 | @ if {![info exists username]} {set username $login} |
| 434 | 432 | @ if {[info exists submit]} { |
| 435 | 433 | @ if {[info exists cmappnd]} { |
| 436 | 434 | @ if {[string length $cmappnd]>0} { |
| 437 | -@ set ctxt "\n\n<hr><i>[htmlize $login]" | |
| 435 | +@ set ctxt "\n\n<hr /><i>[htmlize $login]" | |
| 438 | 436 | @ if {$username ne $login} { |
| 439 | 437 | @ set ctxt "$ctxt claiming to be [htmlize $username]" |
| 440 | 438 | @ } |
| 441 | -@ set ctxt "$ctxt added on [date]:</i><br>\n$cmappnd" | |
| 439 | +@ set ctxt "$ctxt added on [date]:</i><br />\n$cmappnd" | |
| 442 | 440 | @ append_field comment $ctxt |
| 443 | 441 | @ } |
| 444 | 442 | @ } |
| 445 | 443 | @ submit_ticket |
| 446 | 444 | @ } |
| 447 | 445 | @ </th1> |
| 448 | 446 | @ <table cellpadding="5"> |
| 449 | -@ <tr><td align="right">Title:</td><td> | |
| 450 | -@ <input type="text" name="title" value="$<title>" size="60"> | |
| 447 | +@ <tr><td class="tktDspLabel">Title:</td><td> | |
| 448 | +@ <input type="text" name="title" value="$<title>" size="60" /> | |
| 451 | 449 | @ </td></tr> |
| 452 | -@ <tr><td align="right">Status:</td><td> | |
| 450 | +@ <tr><td class="tktDspLabel">Status:</td><td> | |
| 453 | 451 | @ <th1>combobox status $status_choices 1</th1> |
| 454 | 452 | @ </td></tr> |
| 455 | -@ <tr><td align="right">Type:</td><td> | |
| 453 | +@ <tr><td class="tktDspLabel">Type:</td><td> | |
| 456 | 454 | @ <th1>combobox type $type_choices 1</th1> |
| 457 | 455 | @ </td></tr> |
| 458 | -@ <tr><td align="right">Severity:</td><td> | |
| 456 | +@ <tr><td class="tktDspLabel">Severity:</td><td> | |
| 459 | 457 | @ <th1>combobox severity $severity_choices 1</th1> |
| 460 | 458 | @ </td></tr> |
| 461 | -@ <tr><td align="right">Priority:</td><td> | |
| 459 | +@ <tr><td class="tktDspLabel">Priority:</td><td> | |
| 462 | 460 | @ <th1>combobox priority $priority_choices 1</th1> |
| 463 | 461 | @ </td></tr> |
| 464 | -@ <tr><td align="right">Resolution:</td><td> | |
| 462 | +@ <tr><td class="tktDspLabel">Resolution:</td><td> | |
| 465 | 463 | @ <th1>combobox resolution $resolution_choices 1</th1> |
| 466 | 464 | @ </td></tr> |
| 467 | -@ <tr><td align="right">Subsystem:</td><td> | |
| 465 | +@ <tr><td class="tktDspLabel">Subsystem:</td><td> | |
| 468 | 466 | @ <th1>combobox subsystem $subsystem_choices 1</th1> |
| 469 | 467 | @ </td></tr> |
| 470 | 468 | @ <th1>enable_output [hascap e]</th1> |
| 471 | -@ <tr><td align="right">Contact:</td><td> | |
| 469 | +@ <tr><td class="tktDspLabel">Contact:</td><td> | |
| 472 | 470 | @ <input type="text" name="private_contact" size="40" |
| 473 | -@ value="$<private_contact>"> | |
| 471 | +@ value="$<private_contact>" /> | |
| 474 | 472 | @ </td></tr> |
| 475 | 473 | @ <th1>enable_output 1</th1> |
| 476 | -@ <tr><td align="right">Version Found In:</td><td> | |
| 477 | -@ <input type="text" name="foundin" size="50" value="$<foundin>"> | |
| 474 | +@ <tr><td class="tktDspLabel">Version Found In:</td><td> | |
| 475 | +@ <input type="text" name="foundin" size="50" value="$<foundin>" /> | |
| 478 | 476 | @ </td></tr> |
| 479 | 477 | @ <tr><td colspan="2"> |
| 480 | 478 | @ <th1> |
| 481 | 479 | @ if {![info exists eall]} {set eall 0} |
| 482 | 480 | @ if {[info exists aonlybtn]} {set eall 0} |
| @@ -484,45 +482,45 @@ | ||
| 484 | 482 | @ if {![hascap w]} {set eall 0} |
| 485 | 483 | @ if {![info exists cmappnd]} {set cmappnd {}} |
| 486 | 484 | @ set nline [linecount $comment 15 10] |
| 487 | 485 | @ enable_output $eall |
| 488 | 486 | @ </th1> |
| 489 | -@ Description And Comments:<br> | |
| 487 | +@ Description And Comments:<br /> | |
| 490 | 488 | @ <textarea name="comment" cols="80" rows="$nline" |
| 491 | -@ wrap="virtual" class="wikiedit">$<comment></textarea><br> | |
| 492 | -@ <input type="hidden" name="eall" value="1"> | |
| 493 | -@ <input type="submit" name="aonlybtn" value="Append Remark"> | |
| 494 | -@ <input type="submit" name="preview1btn" value="Preview"> | |
| 489 | +@ wrap="virtual" class="wikiedit">$<comment></textarea><br /> | |
| 490 | +@ <input type="hidden" name="eall" value="1" /> | |
| 491 | +@ <input type="submit" name="aonlybtn" value="Append Remark" /> | |
| 492 | +@ <input type="submit" name="preview1btn" value="Preview" /> | |
| 495 | 493 | @ <th1>enable_output [expr {!$eall}]</th1> |
| 496 | 494 | @ Append Remark from |
| 497 | -@ <input type="text" name="username" value="$<username>" size="30">:<br> | |
| 495 | +@ <input type="text" name="username" value="$<username>" size="30" />:<br /> | |
| 498 | 496 | @ <textarea name="cmappnd" cols="80" rows="15" |
| 499 | -@ wrap="virtual" class="wikiedit">$<cmappnd></textarea><br> | |
| 497 | +@ wrap="virtual" class="wikiedit">$<cmappnd></textarea><br /> | |
| 500 | 498 | @ <th1>enable_output [expr {[hascap w] && !$eall}]</th1> |
| 501 | -@ <input type="submit" name="eallbtn" value="Edit All"> | |
| 499 | +@ <input type="submit" name="eallbtn" value="Edit All" /> | |
| 502 | 500 | @ <th1>enable_output [expr {!$eall}]</th1> |
| 503 | -@ <input type="submit" name="preview2btn" value="Preview"> | |
| 501 | +@ <input type="submit" name="preview2btn" value="Preview" /> | |
| 504 | 502 | @ <th1>enable_output 1</th1> |
| 505 | 503 | @ </td></tr> |
| 506 | 504 | @ |
| 507 | 505 | @ <th1>enable_output [info exists preview1btn]</th1> |
| 508 | 506 | @ <tr><td colspan="2"> |
| 509 | -@ Description Preview:<br><hr> | |
| 507 | +@ Description Preview:<br /><hr /> | |
| 510 | 508 | @ <th1>wiki $comment</th1> |
| 511 | -@ <hr> | |
| 509 | +@ <hr /> | |
| 512 | 510 | @ </td></tr> |
| 513 | 511 | @ <th1>enable_output [info exists preview2btn]</th1> |
| 514 | 512 | @ <tr><td colspan="2"> |
| 515 | -@ Description Preview:<br><hr> | |
| 513 | +@ Description Preview:<br /><hr /> | |
| 516 | 514 | @ <th1>wiki $cmappnd</th1> |
| 517 | -@ <hr> | |
| 515 | +@ <hr /> | |
| 518 | 516 | @ </td></tr> |
| 519 | 517 | @ <th1>enable_output 1</th1> |
| 520 | 518 | @ |
| 521 | 519 | @ <tr><td align="right"></td><td> |
| 522 | -@ <input type="submit" name="submit" value="Submit Changes"> | |
| 523 | -@ <input type="submit" name="cancel" value="Cancel"> | |
| 520 | +@ <input type="submit" name="submit" value="Submit Changes" /> | |
| 521 | +@ <input type="submit" name="cancel" value="Cancel" /> | |
| 524 | 522 | @ </td></tr> |
| 525 | 523 | @ </table> |
| 526 | 524 | ; |
| 527 | 525 | |
| 528 | 526 | /* |
| @@ -535,12 +533,11 @@ | ||
| 535 | 533 | /* |
| 536 | 534 | ** WEBPAGE: tktsetup_editpage |
| 537 | 535 | */ |
| 538 | 536 | void tktsetup_editpage_page(void){ |
| 539 | 537 | static const char zDesc[] = |
| 540 | - @ <p>Enter HTML with embedded TH1 script that will render the "edit ticket" | |
| 541 | - @ page</p> | |
| 538 | + @ Enter HTML with embedded TH1 script that will render the "edit ticket" page | |
| 542 | 539 | ; |
| 543 | 540 | tktsetup_generic( |
| 544 | 541 | "HTML For Editing Tickets", |
| 545 | 542 | "ticket-editpage", |
| 546 | 543 | zDefaultEdit, |
| @@ -585,12 +582,11 @@ | ||
| 585 | 582 | /* |
| 586 | 583 | ** WEBPAGE: tktsetup_reportlist |
| 587 | 584 | */ |
| 588 | 585 | void tktsetup_reportlist(void){ |
| 589 | 586 | static const char zDesc[] = |
| 590 | - @ <p>Enter HTML with embedded TH1 script that will render the "report list" | |
| 591 | - @ page</p> | |
| 587 | + @ Enter HTML with embedded TH1 script that will render the "report list" page | |
| 592 | 588 | ; |
| 593 | 589 | tktsetup_generic( |
| 594 | 590 | "HTML For Report List", |
| 595 | 591 | "ticket-reportlist", |
| 596 | 592 | zDefaultReportList, |
| @@ -633,13 +629,13 @@ | ||
| 633 | 629 | /* |
| 634 | 630 | ** WEBPAGE: tktsetup_rpttplt |
| 635 | 631 | */ |
| 636 | 632 | void tktsetup_rpttplt_page(void){ |
| 637 | 633 | static const char zDesc[] = |
| 638 | - @ <p>Enter the default ticket report format template. This is the | |
| 634 | + @ Enter the default ticket report format template. This is the | |
| 639 | 635 | @ the template report format that initially appears when creating a |
| 640 | - @ new ticket summary report.</p> | |
| 636 | + @ new ticket summary report. | |
| 641 | 637 | ; |
| 642 | 638 | tktsetup_generic( |
| 643 | 639 | "Default Report Template", |
| 644 | 640 | "ticket-report-template", |
| 645 | 641 | zDefaultReport, |
| @@ -674,13 +670,13 @@ | ||
| 674 | 670 | /* |
| 675 | 671 | ** WEBPAGE: tktsetup_keytplt |
| 676 | 672 | */ |
| 677 | 673 | void tktsetup_keytplt_page(void){ |
| 678 | 674 | static const char zDesc[] = |
| 679 | - @ <p>Enter the default ticket report color-key template. This is the | |
| 675 | + @ Enter the default ticket report color-key template. This is the | |
| 680 | 676 | @ the color-key that initially appears when creating a |
| 681 | - @ new ticket summary report.</p> | |
| 677 | + @ new ticket summary report. | |
| 682 | 678 | ; |
| 683 | 679 | tktsetup_generic( |
| 684 | 680 | "Default Report Color-Key Template", |
| 685 | 681 | "ticket-key-template", |
| 686 | 682 | zDefaultKey, |
| @@ -703,34 +699,34 @@ | ||
| 703 | 699 | if( P("setup") ){ |
| 704 | 700 | cgi_redirect("tktsetup"); |
| 705 | 701 | } |
| 706 | 702 | style_header("Ticket Display On Timelines"); |
| 707 | 703 | db_begin_transaction(); |
| 708 | - @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST"> | |
| 704 | + @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="post"><div> | |
| 709 | 705 | login_insert_csrf_secret(); |
| 710 | 706 | |
| 711 | - @ <hr> | |
| 707 | + @ <hr /> | |
| 712 | 708 | entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title"); |
| 713 | 709 | @ <p>An SQL expression in a query against the TICKET table that will |
| 714 | 710 | @ return the title of the ticket for display purposes.</p> |
| 715 | 711 | |
| 716 | - @ <hr> | |
| 712 | + @ <hr /> | |
| 717 | 713 | entry_attribute("Ticket Status", 40, "ticket-status-column", "s", "status"); |
| 718 | 714 | @ <p>The name of the column in the TICKET table that contains the ticket |
| 719 | 715 | @ status in human-readable form. Case sensitive.</p> |
| 720 | 716 | |
| 721 | - @ <hr> | |
| 717 | + @ <hr /> | |
| 722 | 718 | entry_attribute("Ticket Closed", 40, "ticket-closed-expr", "c", |
| 723 | 719 | "status='Closed'"); |
| 724 | 720 | @ <p>An SQL expression that evaluates to true in a TICKET table query if |
| 725 | 721 | @ the ticket is closed.</p> |
| 726 | 722 | |
| 727 | - @ <hr> | |
| 723 | + @ <hr /> | |
| 728 | 724 | @ <p> |
| 729 | - @ <input type="submit" name="submit" value="Apply Changes"> | |
| 730 | - @ <input type="submit" name="setup" value="Cancel"> | |
| 725 | + @ <input type="submit" name="submit" value="Apply Changes" /> | |
| 726 | + @ <input type="submit" name="setup" value="Cancel" /> | |
| 731 | 727 | @ </p> |
| 732 | - @ </form> | |
| 728 | + @ </div></form> | |
| 733 | 729 | db_end_transaction(0); |
| 734 | 730 | style_footer(); |
| 735 | 731 | |
| 736 | 732 | } |
| 737 | 733 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -130,21 +130,21 @@ | |
| 130 | db_set(zDbField, z, 0); |
| 131 | if( xRebuild ) xRebuild(); |
| 132 | cgi_redirect("tktsetup"); |
| 133 | } |
| 134 | } |
| 135 | @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST"> |
| 136 | login_insert_csrf_secret(); |
| 137 | @ <p>%s(zDesc)</p> |
| 138 | @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea> |
| 139 | @ <blockquote> |
| 140 | @ <input type="submit" name="submit" value="Apply Changes"> |
| 141 | @ <input type="submit" name="clear" value="Revert To Default"> |
| 142 | @ <input type="submit" name="setup" value="Cancel"> |
| 143 | @ </blockquote> |
| 144 | @ </form> |
| 145 | @ <hr> |
| 146 | @ <h2>Default %s(zTitle)</h2> |
| 147 | @ <blockquote><pre> |
| 148 | @ %h(zDfltValue) |
| 149 | @ </pre></blockquote> |
| 150 | style_footer(); |
| @@ -153,13 +153,13 @@ | |
| 153 | /* |
| 154 | ** WEBPAGE: tktsetup_tab |
| 155 | */ |
| 156 | void tktsetup_tab_page(void){ |
| 157 | static const char zDesc[] = |
| 158 | @ <p>Enter a valid CREATE TABLE statement for the "ticket" table. The |
| 159 | @ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime" |
| 160 | @ with an unique index on "tkt_uuid" and "tkt_mtime".</p> |
| 161 | ; |
| 162 | tktsetup_generic( |
| 163 | "Ticket Table Schema", |
| 164 | "ticket-table", |
| 165 | zDefaultTicketTable, |
| @@ -229,12 +229,12 @@ | |
| 229 | /* |
| 230 | ** WEBPAGE: tktsetup_com |
| 231 | */ |
| 232 | void tktsetup_com_page(void){ |
| 233 | static const char zDesc[] = |
| 234 | @ <p>Enter TH1 script that initializes variables prior to generating |
| 235 | @ any of the ticket view, edit, or creation pages.</p> |
| 236 | ; |
| 237 | tktsetup_generic( |
| 238 | "Ticket Common Script", |
| 239 | "ticket-common", |
| 240 | zDefaultTicketCommon, |
| @@ -250,80 +250,80 @@ | |
| 250 | @ if {[info exists submit]} { |
| 251 | @ set status Open |
| 252 | @ submit_ticket |
| 253 | @ } |
| 254 | @ </th1> |
| 255 | @ <h1 align="center">Enter A New Ticket</h1> |
| 256 | @ <table cellpadding="5"> |
| 257 | @ <tr> |
| 258 | @ <td colspan="2"> |
| 259 | @ Enter a one-line summary of the ticket:<br> |
| 260 | @ <input type="text" name="title" size="60" value="$<title>"> |
| 261 | @ </td> |
| 262 | @ </tr> |
| 263 | @ |
| 264 | @ <tr> |
| 265 | @ <td align="right">Type: |
| 266 | @ <th1>combobox type $type_choices 1</th1> |
| 267 | @ </td> |
| 268 | @ <td>What type of ticket is this?</td> |
| 269 | @ </tr> |
| 270 | @ |
| 271 | @ <tr> |
| 272 | @ <td align="right">Version: |
| 273 | @ <input type="text" name="foundin" size="20" value="$<foundin>"> |
| 274 | @ </td> |
| 275 | @ <td>In what version or build number do you observe the problem?</td> |
| 276 | @ </tr> |
| 277 | @ |
| 278 | @ <tr> |
| 279 | @ <td align="right">Severity: |
| 280 | @ <th1>combobox severity $severity_choices 1</th1> |
| 281 | @ </td> |
| 282 | @ <td>How debilitating is the problem? How badly does the problem |
| 283 | @ affect the operation of the product?</td> |
| 284 | @ </tr> |
| 285 | @ |
| 286 | @ <tr> |
| 287 | @ <td align="right">EMail: |
| 288 | @ <input type="text" name="private_contact" value="$<private_contact>" size="30"> |
| 289 | @ </td> |
| 290 | @ <td><u>Not publicly visible</u>. Used by developers to contact you with |
| 291 | @ questions.</td> |
| 292 | @ </tr> |
| 293 | @ |
| 294 | @ <tr> |
| 295 | @ <td colspan="2"> |
| 296 | @ Enter a detailed description of the problem. |
| 297 | @ For code defects, be sure to provide details on exactly how |
| 298 | @ the problem can be reproduced. Provide as much detail as |
| 299 | @ possible. |
| 300 | @ <br> |
| 301 | @ <th1>set nline [linecount $comment 50 10]</th1> |
| 302 | @ <textarea name="comment" cols="80" rows="$nline" |
| 303 | @ wrap="virtual" class="wikiedit">$<comment></textarea><br> |
| 304 | @ <input type="submit" name="preview" value="Preview"> |
| 305 | @ </tr> |
| 306 | @ |
| 307 | @ <th1>enable_output [info exists preview]</th1> |
| 308 | @ <tr><td colspan="2"> |
| 309 | @ Description Preview:<br><hr> |
| 310 | @ <th1>wiki $comment</th1> |
| 311 | @ <hr> |
| 312 | @ </td></tr> |
| 313 | @ <th1>enable_output 1</th1> |
| 314 | @ |
| 315 | @ <tr> |
| 316 | @ <td align="right"> |
| 317 | @ <input type="submit" name="submit" value="Submit"> |
| 318 | @ </td> |
| 319 | @ <td>After filling in the information above, press this button to create |
| 320 | @ the new ticket</td> |
| 321 | @ </tr> |
| 322 | @ <tr> |
| 323 | @ <td align="right"> |
| 324 | @ <input type="submit" name="cancel" value="Cancel"> |
| 325 | @ </td> |
| 326 | @ <td>Abandon and forget this ticket</td> |
| 327 | @ </tr> |
| 328 | @ </table> |
| 329 | ; |
| @@ -338,12 +338,12 @@ | |
| 338 | /* |
| 339 | ** WEBPAGE: tktsetup_newpage |
| 340 | */ |
| 341 | void tktsetup_newpage_page(void){ |
| 342 | static const char zDesc[] = |
| 343 | @ <p>Enter HTML with embedded TH1 script that will render the "new ticket" |
| 344 | @ page</p> |
| 345 | ; |
| 346 | tktsetup_generic( |
| 347 | "HTML For New Tickets", |
| 348 | "ticket-newpage", |
| 349 | zDefaultNew, |
| @@ -354,51 +354,50 @@ | |
| 354 | ); |
| 355 | } |
| 356 | |
| 357 | static const char zDefaultView[] = |
| 358 | @ <table cellpadding="5"> |
| 359 | @ <tr><td align="right">Ticket UUID:</td><td bgcolor="#d0d0d0" colspan="3"> |
| 360 | @ $<tkt_uuid> |
| 361 | @ </td></tr> |
| 362 | @ <tr><td align="right">Title:</td> |
| 363 | @ <td bgcolor="#d0d0d0" colspan="3" valign="top"> |
| 364 | @ <th1>wiki $title</th1> |
| 365 | @ </td></tr> |
| 366 | @ <tr><td align="right">Status:</td><td bgcolor="#d0d0d0"> |
| 367 | @ $<status> |
| 368 | @ </td> |
| 369 | @ <td align="right">Type:</td><td bgcolor="#d0d0d0"> |
| 370 | @ $<type> |
| 371 | @ </td></tr> |
| 372 | @ <tr><td align="right">Severity:</td><td bgcolor="#d0d0d0"> |
| 373 | @ $<severity> |
| 374 | @ </td> |
| 375 | @ <td align="right">Priority:</td><td bgcolor="#d0d0d0"> |
| 376 | @ $<priority> |
| 377 | @ </td></tr> |
| 378 | @ <tr><td align="right">Subsystem:</td><td bgcolor="#d0d0d0"> |
| 379 | @ $<subsystem> |
| 380 | @ </td> |
| 381 | @ <td align="right">Resolution:</td><td bgcolor="#d0d0d0"> |
| 382 | @ $<resolution> |
| 383 | @ </td></tr> |
| 384 | @ <tr><td align="right">Last Modified:</td><td bgcolor="#d0d0d0"> |
| 385 | @ $<tkt_datetime> |
| 386 | @ </td> |
| 387 | @ <th1>enable_output [hascap e]</th1> |
| 388 | @ <td align="right">Contact:</td><td bgcolor="#d0d0d0"> |
| 389 | @ $<private_contact> |
| 390 | @ </td> |
| 391 | @ <th1>enable_output 1</th1> |
| 392 | @ </tr> |
| 393 | @ <tr><td align="right">Version Found In:</td> |
| 394 | @ <td colspan="3" valign="top" bgcolor="#d0d0d0"> |
| 395 | @ $<foundin> |
| 396 | @ </td></tr> |
| 397 | @ <tr><td>Description & Comments:</td></tr> |
| 398 | @ <tr><td colspan="4" bgcolor="#d0d0d0"> |
| 399 | @ <span bgcolor="#d0d0d0"><th1>wiki $comment</th1></span> |
| 400 | @ </td></tr> |
| 401 | @ </table> |
| 402 | ; |
| 403 | |
| 404 | |
| @@ -412,12 +411,11 @@ | |
| 412 | /* |
| 413 | ** WEBPAGE: tktsetup_viewpage |
| 414 | */ |
| 415 | void tktsetup_viewpage_page(void){ |
| 416 | static const char zDesc[] = |
| 417 | @ <p>Enter HTML with embedded TH1 script that will render the "view ticket" |
| 418 | @ page</p> |
| 419 | ; |
| 420 | tktsetup_generic( |
| 421 | "HTML For Viewing Tickets", |
| 422 | "ticket-viewpage", |
| 423 | zDefaultView, |
| @@ -432,51 +430,51 @@ | |
| 432 | @ <th1> |
| 433 | @ if {![info exists username]} {set username $login} |
| 434 | @ if {[info exists submit]} { |
| 435 | @ if {[info exists cmappnd]} { |
| 436 | @ if {[string length $cmappnd]>0} { |
| 437 | @ set ctxt "\n\n<hr><i>[htmlize $login]" |
| 438 | @ if {$username ne $login} { |
| 439 | @ set ctxt "$ctxt claiming to be [htmlize $username]" |
| 440 | @ } |
| 441 | @ set ctxt "$ctxt added on [date]:</i><br>\n$cmappnd" |
| 442 | @ append_field comment $ctxt |
| 443 | @ } |
| 444 | @ } |
| 445 | @ submit_ticket |
| 446 | @ } |
| 447 | @ </th1> |
| 448 | @ <table cellpadding="5"> |
| 449 | @ <tr><td align="right">Title:</td><td> |
| 450 | @ <input type="text" name="title" value="$<title>" size="60"> |
| 451 | @ </td></tr> |
| 452 | @ <tr><td align="right">Status:</td><td> |
| 453 | @ <th1>combobox status $status_choices 1</th1> |
| 454 | @ </td></tr> |
| 455 | @ <tr><td align="right">Type:</td><td> |
| 456 | @ <th1>combobox type $type_choices 1</th1> |
| 457 | @ </td></tr> |
| 458 | @ <tr><td align="right">Severity:</td><td> |
| 459 | @ <th1>combobox severity $severity_choices 1</th1> |
| 460 | @ </td></tr> |
| 461 | @ <tr><td align="right">Priority:</td><td> |
| 462 | @ <th1>combobox priority $priority_choices 1</th1> |
| 463 | @ </td></tr> |
| 464 | @ <tr><td align="right">Resolution:</td><td> |
| 465 | @ <th1>combobox resolution $resolution_choices 1</th1> |
| 466 | @ </td></tr> |
| 467 | @ <tr><td align="right">Subsystem:</td><td> |
| 468 | @ <th1>combobox subsystem $subsystem_choices 1</th1> |
| 469 | @ </td></tr> |
| 470 | @ <th1>enable_output [hascap e]</th1> |
| 471 | @ <tr><td align="right">Contact:</td><td> |
| 472 | @ <input type="text" name="private_contact" size="40" |
| 473 | @ value="$<private_contact>"> |
| 474 | @ </td></tr> |
| 475 | @ <th1>enable_output 1</th1> |
| 476 | @ <tr><td align="right">Version Found In:</td><td> |
| 477 | @ <input type="text" name="foundin" size="50" value="$<foundin>"> |
| 478 | @ </td></tr> |
| 479 | @ <tr><td colspan="2"> |
| 480 | @ <th1> |
| 481 | @ if {![info exists eall]} {set eall 0} |
| 482 | @ if {[info exists aonlybtn]} {set eall 0} |
| @@ -484,45 +482,45 @@ | |
| 484 | @ if {![hascap w]} {set eall 0} |
| 485 | @ if {![info exists cmappnd]} {set cmappnd {}} |
| 486 | @ set nline [linecount $comment 15 10] |
| 487 | @ enable_output $eall |
| 488 | @ </th1> |
| 489 | @ Description And Comments:<br> |
| 490 | @ <textarea name="comment" cols="80" rows="$nline" |
| 491 | @ wrap="virtual" class="wikiedit">$<comment></textarea><br> |
| 492 | @ <input type="hidden" name="eall" value="1"> |
| 493 | @ <input type="submit" name="aonlybtn" value="Append Remark"> |
| 494 | @ <input type="submit" name="preview1btn" value="Preview"> |
| 495 | @ <th1>enable_output [expr {!$eall}]</th1> |
| 496 | @ Append Remark from |
| 497 | @ <input type="text" name="username" value="$<username>" size="30">:<br> |
| 498 | @ <textarea name="cmappnd" cols="80" rows="15" |
| 499 | @ wrap="virtual" class="wikiedit">$<cmappnd></textarea><br> |
| 500 | @ <th1>enable_output [expr {[hascap w] && !$eall}]</th1> |
| 501 | @ <input type="submit" name="eallbtn" value="Edit All"> |
| 502 | @ <th1>enable_output [expr {!$eall}]</th1> |
| 503 | @ <input type="submit" name="preview2btn" value="Preview"> |
| 504 | @ <th1>enable_output 1</th1> |
| 505 | @ </td></tr> |
| 506 | @ |
| 507 | @ <th1>enable_output [info exists preview1btn]</th1> |
| 508 | @ <tr><td colspan="2"> |
| 509 | @ Description Preview:<br><hr> |
| 510 | @ <th1>wiki $comment</th1> |
| 511 | @ <hr> |
| 512 | @ </td></tr> |
| 513 | @ <th1>enable_output [info exists preview2btn]</th1> |
| 514 | @ <tr><td colspan="2"> |
| 515 | @ Description Preview:<br><hr> |
| 516 | @ <th1>wiki $cmappnd</th1> |
| 517 | @ <hr> |
| 518 | @ </td></tr> |
| 519 | @ <th1>enable_output 1</th1> |
| 520 | @ |
| 521 | @ <tr><td align="right"></td><td> |
| 522 | @ <input type="submit" name="submit" value="Submit Changes"> |
| 523 | @ <input type="submit" name="cancel" value="Cancel"> |
| 524 | @ </td></tr> |
| 525 | @ </table> |
| 526 | ; |
| 527 | |
| 528 | /* |
| @@ -535,12 +533,11 @@ | |
| 535 | /* |
| 536 | ** WEBPAGE: tktsetup_editpage |
| 537 | */ |
| 538 | void tktsetup_editpage_page(void){ |
| 539 | static const char zDesc[] = |
| 540 | @ <p>Enter HTML with embedded TH1 script that will render the "edit ticket" |
| 541 | @ page</p> |
| 542 | ; |
| 543 | tktsetup_generic( |
| 544 | "HTML For Editing Tickets", |
| 545 | "ticket-editpage", |
| 546 | zDefaultEdit, |
| @@ -585,12 +582,11 @@ | |
| 585 | /* |
| 586 | ** WEBPAGE: tktsetup_reportlist |
| 587 | */ |
| 588 | void tktsetup_reportlist(void){ |
| 589 | static const char zDesc[] = |
| 590 | @ <p>Enter HTML with embedded TH1 script that will render the "report list" |
| 591 | @ page</p> |
| 592 | ; |
| 593 | tktsetup_generic( |
| 594 | "HTML For Report List", |
| 595 | "ticket-reportlist", |
| 596 | zDefaultReportList, |
| @@ -633,13 +629,13 @@ | |
| 633 | /* |
| 634 | ** WEBPAGE: tktsetup_rpttplt |
| 635 | */ |
| 636 | void tktsetup_rpttplt_page(void){ |
| 637 | static const char zDesc[] = |
| 638 | @ <p>Enter the default ticket report format template. This is the |
| 639 | @ the template report format that initially appears when creating a |
| 640 | @ new ticket summary report.</p> |
| 641 | ; |
| 642 | tktsetup_generic( |
| 643 | "Default Report Template", |
| 644 | "ticket-report-template", |
| 645 | zDefaultReport, |
| @@ -674,13 +670,13 @@ | |
| 674 | /* |
| 675 | ** WEBPAGE: tktsetup_keytplt |
| 676 | */ |
| 677 | void tktsetup_keytplt_page(void){ |
| 678 | static const char zDesc[] = |
| 679 | @ <p>Enter the default ticket report color-key template. This is the |
| 680 | @ the color-key that initially appears when creating a |
| 681 | @ new ticket summary report.</p> |
| 682 | ; |
| 683 | tktsetup_generic( |
| 684 | "Default Report Color-Key Template", |
| 685 | "ticket-key-template", |
| 686 | zDefaultKey, |
| @@ -703,34 +699,34 @@ | |
| 703 | if( P("setup") ){ |
| 704 | cgi_redirect("tktsetup"); |
| 705 | } |
| 706 | style_header("Ticket Display On Timelines"); |
| 707 | db_begin_transaction(); |
| 708 | @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST"> |
| 709 | login_insert_csrf_secret(); |
| 710 | |
| 711 | @ <hr> |
| 712 | entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title"); |
| 713 | @ <p>An SQL expression in a query against the TICKET table that will |
| 714 | @ return the title of the ticket for display purposes.</p> |
| 715 | |
| 716 | @ <hr> |
| 717 | entry_attribute("Ticket Status", 40, "ticket-status-column", "s", "status"); |
| 718 | @ <p>The name of the column in the TICKET table that contains the ticket |
| 719 | @ status in human-readable form. Case sensitive.</p> |
| 720 | |
| 721 | @ <hr> |
| 722 | entry_attribute("Ticket Closed", 40, "ticket-closed-expr", "c", |
| 723 | "status='Closed'"); |
| 724 | @ <p>An SQL expression that evaluates to true in a TICKET table query if |
| 725 | @ the ticket is closed.</p> |
| 726 | |
| 727 | @ <hr> |
| 728 | @ <p> |
| 729 | @ <input type="submit" name="submit" value="Apply Changes"> |
| 730 | @ <input type="submit" name="setup" value="Cancel"> |
| 731 | @ </p> |
| 732 | @ </form> |
| 733 | db_end_transaction(0); |
| 734 | style_footer(); |
| 735 | |
| 736 | } |
| 737 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -130,21 +130,21 @@ | |
| 130 | db_set(zDbField, z, 0); |
| 131 | if( xRebuild ) xRebuild(); |
| 132 | cgi_redirect("tktsetup"); |
| 133 | } |
| 134 | } |
| 135 | @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="post"><div> |
| 136 | login_insert_csrf_secret(); |
| 137 | @ <p>%s(zDesc)</p> |
| 138 | @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea> |
| 139 | @ <blockquote><p> |
| 140 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 141 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 142 | @ <input type="submit" name="setup" value="Cancel" /> |
| 143 | @ </p></blockquote> |
| 144 | @ </div></form> |
| 145 | @ <hr /> |
| 146 | @ <h2>Default %s(zTitle)</h2> |
| 147 | @ <blockquote><pre> |
| 148 | @ %h(zDfltValue) |
| 149 | @ </pre></blockquote> |
| 150 | style_footer(); |
| @@ -153,13 +153,13 @@ | |
| 153 | /* |
| 154 | ** WEBPAGE: tktsetup_tab |
| 155 | */ |
| 156 | void tktsetup_tab_page(void){ |
| 157 | static const char zDesc[] = |
| 158 | @ Enter a valid CREATE TABLE statement for the "ticket" table. The |
| 159 | @ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime" |
| 160 | @ with an unique index on "tkt_uuid" and "tkt_mtime". |
| 161 | ; |
| 162 | tktsetup_generic( |
| 163 | "Ticket Table Schema", |
| 164 | "ticket-table", |
| 165 | zDefaultTicketTable, |
| @@ -229,12 +229,12 @@ | |
| 229 | /* |
| 230 | ** WEBPAGE: tktsetup_com |
| 231 | */ |
| 232 | void tktsetup_com_page(void){ |
| 233 | static const char zDesc[] = |
| 234 | @ Enter TH1 script that initializes variables prior to generating |
| 235 | @ any of the ticket view, edit, or creation pages. |
| 236 | ; |
| 237 | tktsetup_generic( |
| 238 | "Ticket Common Script", |
| 239 | "ticket-common", |
| 240 | zDefaultTicketCommon, |
| @@ -250,80 +250,80 @@ | |
| 250 | @ if {[info exists submit]} { |
| 251 | @ set status Open |
| 252 | @ submit_ticket |
| 253 | @ } |
| 254 | @ </th1> |
| 255 | @ <h1 style="text-align: center;">Enter A New Ticket</h1> |
| 256 | @ <table cellpadding="5"> |
| 257 | @ <tr> |
| 258 | @ <td colspan="2"> |
| 259 | @ Enter a one-line summary of the ticket:<br /> |
| 260 | @ <input type="text" name="title" size="60" value="$<title>" /> |
| 261 | @ </td> |
| 262 | @ </tr> |
| 263 | @ |
| 264 | @ <tr> |
| 265 | @ <td style="text-align: center;">Type: |
| 266 | @ <th1>combobox type $type_choices 1</th1> |
| 267 | @ </td> |
| 268 | @ <td>What type of ticket is this?</td> |
| 269 | @ </tr> |
| 270 | @ |
| 271 | @ <tr> |
| 272 | @ <td style="text-align: center;">Version: |
| 273 | @ <input type="text" name="foundin" size="20" value="$<foundin>" /> |
| 274 | @ </td> |
| 275 | @ <td>In what version or build number do you observe the problem?</td> |
| 276 | @ </tr> |
| 277 | @ |
| 278 | @ <tr> |
| 279 | @ <td style="text-align: center;">Severity: |
| 280 | @ <th1>combobox severity $severity_choices 1</th1> |
| 281 | @ </td> |
| 282 | @ <td>How debilitating is the problem? How badly does the problem |
| 283 | @ affect the operation of the product?</td> |
| 284 | @ </tr> |
| 285 | @ |
| 286 | @ <tr> |
| 287 | @ <td style="text-align: center;">EMail: |
| 288 | @ <input type="text" name="private_contact" value="$<private_contact>" size="30" /> |
| 289 | @ </td> |
| 290 | @ <td><span style="text-decoration: underline;">Not publicly visible</span>. |
| 291 | @ Used by developers to contact you with questions.</td> |
| 292 | @ </tr> |
| 293 | @ |
| 294 | @ <tr> |
| 295 | @ <td colspan="2"> |
| 296 | @ Enter a detailed description of the problem. |
| 297 | @ For code defects, be sure to provide details on exactly how |
| 298 | @ the problem can be reproduced. Provide as much detail as |
| 299 | @ possible. |
| 300 | @ <br /> |
| 301 | @ <th1>set nline [linecount $comment 50 10]</th1> |
| 302 | @ <textarea name="comment" cols="80" rows="$nline" |
| 303 | @ wrap="virtual" class="wikiedit">$<comment></textarea><br /> |
| 304 | @ <input type="submit" name="preview" value="Preview" /></td> |
| 305 | @ </tr> |
| 306 | @ |
| 307 | @ <th1>enable_output [info exists preview]</th1> |
| 308 | @ <tr><td colspan="2"> |
| 309 | @ Description Preview:<br /><hr /> |
| 310 | @ <th1>wiki $comment</th1> |
| 311 | @ <hr /> |
| 312 | @ </td></tr> |
| 313 | @ <th1>enable_output 1</th1> |
| 314 | @ |
| 315 | @ <tr> |
| 316 | @ <td style="text-align: center;"> |
| 317 | @ <input type="submit" name="submit" value="Submit" /> |
| 318 | @ </td> |
| 319 | @ <td>After filling in the information above, press this button to create |
| 320 | @ the new ticket</td> |
| 321 | @ </tr> |
| 322 | @ <tr> |
| 323 | @ <td style="text-align: center;"> |
| 324 | @ <input type="submit" name="cancel" value="Cancel" /> |
| 325 | @ </td> |
| 326 | @ <td>Abandon and forget this ticket</td> |
| 327 | @ </tr> |
| 328 | @ </table> |
| 329 | ; |
| @@ -338,12 +338,12 @@ | |
| 338 | /* |
| 339 | ** WEBPAGE: tktsetup_newpage |
| 340 | */ |
| 341 | void tktsetup_newpage_page(void){ |
| 342 | static const char zDesc[] = |
| 343 | @ Enter HTML with embedded TH1 script that will render the "new ticket" |
| 344 | @ page |
| 345 | ; |
| 346 | tktsetup_generic( |
| 347 | "HTML For New Tickets", |
| 348 | "ticket-newpage", |
| 349 | zDefaultNew, |
| @@ -354,51 +354,50 @@ | |
| 354 | ); |
| 355 | } |
| 356 | |
| 357 | static const char zDefaultView[] = |
| 358 | @ <table cellpadding="5"> |
| 359 | @ <tr><td class="tktDspLabel">Ticket UUID:</td> |
| 360 | @ <td class="tktDspValue" colspan="3">$<tkt_uuid></td></tr> |
| 361 | @ <tr><td class="tktDspLabel">Title:</td> |
| 362 | @ <td class="tktDspValue" colspan="3"> |
| 363 | @ <th1>wiki $title</th1> |
| 364 | @ </td></tr> |
| 365 | @ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue"> |
| 366 | @ $<status> |
| 367 | @ </td> |
| 368 | @ <td class="tktDspLabel">Type:</td><td class="tktDspValue"> |
| 369 | @ $<type> |
| 370 | @ </td></tr> |
| 371 | @ <tr><td class="tktDspLabel">Severity:</td><td class="tktDspValue"> |
| 372 | @ $<severity> |
| 373 | @ </td> |
| 374 | @ <td class="tktDspLabel">Priority:</td><td class="tktDspValue"> |
| 375 | @ $<priority> |
| 376 | @ </td></tr> |
| 377 | @ <tr><td class="tktDspLabel">Subsystem:</td><td class="tktDspValue"> |
| 378 | @ $<subsystem> |
| 379 | @ </td> |
| 380 | @ <td class="tktDspLabel">Resolution:</td><td class="tktDspValue"> |
| 381 | @ $<resolution> |
| 382 | @ </td></tr> |
| 383 | @ <tr><td class="tktDspLabel">Last Modified:</td><td class="tktDspValue"> |
| 384 | @ $<tkt_datetime> |
| 385 | @ </td> |
| 386 | @ <th1>enable_output [hascap e]</th1> |
| 387 | @ <td class="tktDspLabel">Contact:</td><td class="tktDspValue"> |
| 388 | @ $<private_contact> |
| 389 | @ </td> |
| 390 | @ <th1>enable_output 1</th1> |
| 391 | @ </tr> |
| 392 | @ <tr><td class="tktDspLabel">Version Found In:</td> |
| 393 | @ <td colspan="3" valign="top" class="tktDspValue"> |
| 394 | @ $<foundin> |
| 395 | @ </td></tr> |
| 396 | @ <tr><td>Description & Comments:</td></tr> |
| 397 | @ <tr><td colspan="4" class="tktDspValue"> |
| 398 | @ <th1>wiki $comment</th1> |
| 399 | @ </td></tr> |
| 400 | @ </table> |
| 401 | ; |
| 402 | |
| 403 | |
| @@ -412,12 +411,11 @@ | |
| 411 | /* |
| 412 | ** WEBPAGE: tktsetup_viewpage |
| 413 | */ |
| 414 | void tktsetup_viewpage_page(void){ |
| 415 | static const char zDesc[] = |
| 416 | @ Enter HTML with embedded TH1 script that will render the "view ticket" page |
| 417 | ; |
| 418 | tktsetup_generic( |
| 419 | "HTML For Viewing Tickets", |
| 420 | "ticket-viewpage", |
| 421 | zDefaultView, |
| @@ -432,51 +430,51 @@ | |
| 430 | @ <th1> |
| 431 | @ if {![info exists username]} {set username $login} |
| 432 | @ if {[info exists submit]} { |
| 433 | @ if {[info exists cmappnd]} { |
| 434 | @ if {[string length $cmappnd]>0} { |
| 435 | @ set ctxt "\n\n<hr /><i>[htmlize $login]" |
| 436 | @ if {$username ne $login} { |
| 437 | @ set ctxt "$ctxt claiming to be [htmlize $username]" |
| 438 | @ } |
| 439 | @ set ctxt "$ctxt added on [date]:</i><br />\n$cmappnd" |
| 440 | @ append_field comment $ctxt |
| 441 | @ } |
| 442 | @ } |
| 443 | @ submit_ticket |
| 444 | @ } |
| 445 | @ </th1> |
| 446 | @ <table cellpadding="5"> |
| 447 | @ <tr><td class="tktDspLabel">Title:</td><td> |
| 448 | @ <input type="text" name="title" value="$<title>" size="60" /> |
| 449 | @ </td></tr> |
| 450 | @ <tr><td class="tktDspLabel">Status:</td><td> |
| 451 | @ <th1>combobox status $status_choices 1</th1> |
| 452 | @ </td></tr> |
| 453 | @ <tr><td class="tktDspLabel">Type:</td><td> |
| 454 | @ <th1>combobox type $type_choices 1</th1> |
| 455 | @ </td></tr> |
| 456 | @ <tr><td class="tktDspLabel">Severity:</td><td> |
| 457 | @ <th1>combobox severity $severity_choices 1</th1> |
| 458 | @ </td></tr> |
| 459 | @ <tr><td class="tktDspLabel">Priority:</td><td> |
| 460 | @ <th1>combobox priority $priority_choices 1</th1> |
| 461 | @ </td></tr> |
| 462 | @ <tr><td class="tktDspLabel">Resolution:</td><td> |
| 463 | @ <th1>combobox resolution $resolution_choices 1</th1> |
| 464 | @ </td></tr> |
| 465 | @ <tr><td class="tktDspLabel">Subsystem:</td><td> |
| 466 | @ <th1>combobox subsystem $subsystem_choices 1</th1> |
| 467 | @ </td></tr> |
| 468 | @ <th1>enable_output [hascap e]</th1> |
| 469 | @ <tr><td class="tktDspLabel">Contact:</td><td> |
| 470 | @ <input type="text" name="private_contact" size="40" |
| 471 | @ value="$<private_contact>" /> |
| 472 | @ </td></tr> |
| 473 | @ <th1>enable_output 1</th1> |
| 474 | @ <tr><td class="tktDspLabel">Version Found In:</td><td> |
| 475 | @ <input type="text" name="foundin" size="50" value="$<foundin>" /> |
| 476 | @ </td></tr> |
| 477 | @ <tr><td colspan="2"> |
| 478 | @ <th1> |
| 479 | @ if {![info exists eall]} {set eall 0} |
| 480 | @ if {[info exists aonlybtn]} {set eall 0} |
| @@ -484,45 +482,45 @@ | |
| 482 | @ if {![hascap w]} {set eall 0} |
| 483 | @ if {![info exists cmappnd]} {set cmappnd {}} |
| 484 | @ set nline [linecount $comment 15 10] |
| 485 | @ enable_output $eall |
| 486 | @ </th1> |
| 487 | @ Description And Comments:<br /> |
| 488 | @ <textarea name="comment" cols="80" rows="$nline" |
| 489 | @ wrap="virtual" class="wikiedit">$<comment></textarea><br /> |
| 490 | @ <input type="hidden" name="eall" value="1" /> |
| 491 | @ <input type="submit" name="aonlybtn" value="Append Remark" /> |
| 492 | @ <input type="submit" name="preview1btn" value="Preview" /> |
| 493 | @ <th1>enable_output [expr {!$eall}]</th1> |
| 494 | @ Append Remark from |
| 495 | @ <input type="text" name="username" value="$<username>" size="30" />:<br /> |
| 496 | @ <textarea name="cmappnd" cols="80" rows="15" |
| 497 | @ wrap="virtual" class="wikiedit">$<cmappnd></textarea><br /> |
| 498 | @ <th1>enable_output [expr {[hascap w] && !$eall}]</th1> |
| 499 | @ <input type="submit" name="eallbtn" value="Edit All" /> |
| 500 | @ <th1>enable_output [expr {!$eall}]</th1> |
| 501 | @ <input type="submit" name="preview2btn" value="Preview" /> |
| 502 | @ <th1>enable_output 1</th1> |
| 503 | @ </td></tr> |
| 504 | @ |
| 505 | @ <th1>enable_output [info exists preview1btn]</th1> |
| 506 | @ <tr><td colspan="2"> |
| 507 | @ Description Preview:<br /><hr /> |
| 508 | @ <th1>wiki $comment</th1> |
| 509 | @ <hr /> |
| 510 | @ </td></tr> |
| 511 | @ <th1>enable_output [info exists preview2btn]</th1> |
| 512 | @ <tr><td colspan="2"> |
| 513 | @ Description Preview:<br /><hr /> |
| 514 | @ <th1>wiki $cmappnd</th1> |
| 515 | @ <hr /> |
| 516 | @ </td></tr> |
| 517 | @ <th1>enable_output 1</th1> |
| 518 | @ |
| 519 | @ <tr><td align="right"></td><td> |
| 520 | @ <input type="submit" name="submit" value="Submit Changes" /> |
| 521 | @ <input type="submit" name="cancel" value="Cancel" /> |
| 522 | @ </td></tr> |
| 523 | @ </table> |
| 524 | ; |
| 525 | |
| 526 | /* |
| @@ -535,12 +533,11 @@ | |
| 533 | /* |
| 534 | ** WEBPAGE: tktsetup_editpage |
| 535 | */ |
| 536 | void tktsetup_editpage_page(void){ |
| 537 | static const char zDesc[] = |
| 538 | @ Enter HTML with embedded TH1 script that will render the "edit ticket" page |
| 539 | ; |
| 540 | tktsetup_generic( |
| 541 | "HTML For Editing Tickets", |
| 542 | "ticket-editpage", |
| 543 | zDefaultEdit, |
| @@ -585,12 +582,11 @@ | |
| 582 | /* |
| 583 | ** WEBPAGE: tktsetup_reportlist |
| 584 | */ |
| 585 | void tktsetup_reportlist(void){ |
| 586 | static const char zDesc[] = |
| 587 | @ Enter HTML with embedded TH1 script that will render the "report list" page |
| 588 | ; |
| 589 | tktsetup_generic( |
| 590 | "HTML For Report List", |
| 591 | "ticket-reportlist", |
| 592 | zDefaultReportList, |
| @@ -633,13 +629,13 @@ | |
| 629 | /* |
| 630 | ** WEBPAGE: tktsetup_rpttplt |
| 631 | */ |
| 632 | void tktsetup_rpttplt_page(void){ |
| 633 | static const char zDesc[] = |
| 634 | @ Enter the default ticket report format template. This is the |
| 635 | @ the template report format that initially appears when creating a |
| 636 | @ new ticket summary report. |
| 637 | ; |
| 638 | tktsetup_generic( |
| 639 | "Default Report Template", |
| 640 | "ticket-report-template", |
| 641 | zDefaultReport, |
| @@ -674,13 +670,13 @@ | |
| 670 | /* |
| 671 | ** WEBPAGE: tktsetup_keytplt |
| 672 | */ |
| 673 | void tktsetup_keytplt_page(void){ |
| 674 | static const char zDesc[] = |
| 675 | @ Enter the default ticket report color-key template. This is the |
| 676 | @ the color-key that initially appears when creating a |
| 677 | @ new ticket summary report. |
| 678 | ; |
| 679 | tktsetup_generic( |
| 680 | "Default Report Color-Key Template", |
| 681 | "ticket-key-template", |
| 682 | zDefaultKey, |
| @@ -703,34 +699,34 @@ | |
| 699 | if( P("setup") ){ |
| 700 | cgi_redirect("tktsetup"); |
| 701 | } |
| 702 | style_header("Ticket Display On Timelines"); |
| 703 | db_begin_transaction(); |
| 704 | @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="post"><div> |
| 705 | login_insert_csrf_secret(); |
| 706 | |
| 707 | @ <hr /> |
| 708 | entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title"); |
| 709 | @ <p>An SQL expression in a query against the TICKET table that will |
| 710 | @ return the title of the ticket for display purposes.</p> |
| 711 | |
| 712 | @ <hr /> |
| 713 | entry_attribute("Ticket Status", 40, "ticket-status-column", "s", "status"); |
| 714 | @ <p>The name of the column in the TICKET table that contains the ticket |
| 715 | @ status in human-readable form. Case sensitive.</p> |
| 716 | |
| 717 | @ <hr /> |
| 718 | entry_attribute("Ticket Closed", 40, "ticket-closed-expr", "c", |
| 719 | "status='Closed'"); |
| 720 | @ <p>An SQL expression that evaluates to true in a TICKET table query if |
| 721 | @ the ticket is closed.</p> |
| 722 | |
| 723 | @ <hr /> |
| 724 | @ <p> |
| 725 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 726 | @ <input type="submit" name="setup" value="Cancel" /> |
| 727 | @ </p> |
| 728 | @ </div></form> |
| 729 | db_end_transaction(0); |
| 730 | style_footer(); |
| 731 | |
| 732 | } |
| 733 |
+11
-8
| --- src/translate.c | ||
| +++ src/translate.c | ||
| @@ -66,15 +66,16 @@ | ||
| 66 | 66 | |
| 67 | 67 | /* |
| 68 | 68 | ** Translate the input stream into the output stream |
| 69 | 69 | */ |
| 70 | 70 | static void trans(FILE *in, FILE *out){ |
| 71 | - int i, j, k; /* Loop counters */ | |
| 72 | - char c1, c2; /* Characters used to start a comment */ | |
| 73 | - int lastWasEq = 0; /* True if last non-whitespace character was "=" */ | |
| 74 | - char zLine[2000]; /* A single line of input */ | |
| 75 | - char zOut[4000]; /* The input line translated into appropriate output */ | |
| 71 | + int i, j, k; /* Loop counters */ | |
| 72 | + char c1, c2; /* Characters used to start a comment */ | |
| 73 | + int lastWasEq = 0; /* True if last non-whitespace character was "=" */ | |
| 74 | + int lastWasComma = 0; /* True if last non-whitespace character was "," */ | |
| 75 | + char zLine[2000]; /* A single line of input */ | |
| 76 | + char zOut[4000]; /* The input line translated into appropriate output */ | |
| 76 | 77 | |
| 77 | 78 | c1 = c2 = '-'; |
| 78 | 79 | while( fgets(zLine, sizeof(zLine), in) ){ |
| 79 | 80 | for(i=0; zLine[i] && isspace(zLine[i]); i++){} |
| 80 | 81 | if( zLine[i]!='@' ){ |
| @@ -85,14 +86,16 @@ | ||
| 85 | 86 | c1 = zLine[14]; |
| 86 | 87 | c2 = zLine[15]; |
| 87 | 88 | } |
| 88 | 89 | i += strlen(&zLine[i]); |
| 89 | 90 | while( i>0 && isspace(zLine[i-1]) ){ i--; } |
| 90 | - lastWasEq = i>0 && zLine[i-1]=='='; | |
| 91 | - }else if( lastWasEq ){ | |
| 91 | + lastWasEq = i>0 && zLine[i-1]=='='; | |
| 92 | + lastWasComma = i>0 && zLine[i-1]==','; | |
| 93 | + }else if( lastWasEq || lastWasComma){ | |
| 92 | 94 | /* If the last non-whitespace character before the first @ was |
| 93 | - ** an "=" then generate a string literal. But skip comments | |
| 95 | + ** an "="(var init/set) or a ","(const definition in list) then | |
| 96 | + ** generate a string literal. But skip comments | |
| 94 | 97 | ** consisting of all text between c1 and c2 (default "--") |
| 95 | 98 | ** and end of line. |
| 96 | 99 | */ |
| 97 | 100 | int indent, omitline; |
| 98 | 101 | i++; |
| 99 | 102 |
| --- src/translate.c | |
| +++ src/translate.c | |
| @@ -66,15 +66,16 @@ | |
| 66 | |
| 67 | /* |
| 68 | ** Translate the input stream into the output stream |
| 69 | */ |
| 70 | static void trans(FILE *in, FILE *out){ |
| 71 | int i, j, k; /* Loop counters */ |
| 72 | char c1, c2; /* Characters used to start a comment */ |
| 73 | int lastWasEq = 0; /* True if last non-whitespace character was "=" */ |
| 74 | char zLine[2000]; /* A single line of input */ |
| 75 | char zOut[4000]; /* The input line translated into appropriate output */ |
| 76 | |
| 77 | c1 = c2 = '-'; |
| 78 | while( fgets(zLine, sizeof(zLine), in) ){ |
| 79 | for(i=0; zLine[i] && isspace(zLine[i]); i++){} |
| 80 | if( zLine[i]!='@' ){ |
| @@ -85,14 +86,16 @@ | |
| 85 | c1 = zLine[14]; |
| 86 | c2 = zLine[15]; |
| 87 | } |
| 88 | i += strlen(&zLine[i]); |
| 89 | while( i>0 && isspace(zLine[i-1]) ){ i--; } |
| 90 | lastWasEq = i>0 && zLine[i-1]=='='; |
| 91 | }else if( lastWasEq ){ |
| 92 | /* If the last non-whitespace character before the first @ was |
| 93 | ** an "=" then generate a string literal. But skip comments |
| 94 | ** consisting of all text between c1 and c2 (default "--") |
| 95 | ** and end of line. |
| 96 | */ |
| 97 | int indent, omitline; |
| 98 | i++; |
| 99 |
| --- src/translate.c | |
| +++ src/translate.c | |
| @@ -66,15 +66,16 @@ | |
| 66 | |
| 67 | /* |
| 68 | ** Translate the input stream into the output stream |
| 69 | */ |
| 70 | static void trans(FILE *in, FILE *out){ |
| 71 | int i, j, k; /* Loop counters */ |
| 72 | char c1, c2; /* Characters used to start a comment */ |
| 73 | int lastWasEq = 0; /* True if last non-whitespace character was "=" */ |
| 74 | int lastWasComma = 0; /* True if last non-whitespace character was "," */ |
| 75 | char zLine[2000]; /* A single line of input */ |
| 76 | char zOut[4000]; /* The input line translated into appropriate output */ |
| 77 | |
| 78 | c1 = c2 = '-'; |
| 79 | while( fgets(zLine, sizeof(zLine), in) ){ |
| 80 | for(i=0; zLine[i] && isspace(zLine[i]); i++){} |
| 81 | if( zLine[i]!='@' ){ |
| @@ -85,14 +86,16 @@ | |
| 86 | c1 = zLine[14]; |
| 87 | c2 = zLine[15]; |
| 88 | } |
| 89 | i += strlen(&zLine[i]); |
| 90 | while( i>0 && isspace(zLine[i-1]) ){ i--; } |
| 91 | lastWasEq = i>0 && zLine[i-1]=='='; |
| 92 | lastWasComma = i>0 && zLine[i-1]==','; |
| 93 | }else if( lastWasEq || lastWasComma){ |
| 94 | /* If the last non-whitespace character before the first @ was |
| 95 | ** an "="(var init/set) or a ","(const definition in list) then |
| 96 | ** generate a string literal. But skip comments |
| 97 | ** consisting of all text between c1 and c2 (default "--") |
| 98 | ** and end of line. |
| 99 | */ |
| 100 | int indent, omitline; |
| 101 | i++; |
| 102 |
+1
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -111,10 +111,11 @@ | ||
| 111 | 111 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 112 | 112 | " WHERE event.objid=leaves.rid" |
| 113 | 113 | " ORDER BY event.mtime DESC"); |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | + if( tid==vid ) return; /* Nothing to update */ | |
| 116 | 117 | db_begin_transaction(); |
| 117 | 118 | vfile_check_signature(vid, 1); |
| 118 | 119 | if( !nochangeFlag ) undo_begin(); |
| 119 | 120 | load_vfile_from_rid(tid); |
| 120 | 121 | |
| 121 | 122 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -111,10 +111,11 @@ | |
| 111 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 112 | " WHERE event.objid=leaves.rid" |
| 113 | " ORDER BY event.mtime DESC"); |
| 114 | } |
| 115 | |
| 116 | db_begin_transaction(); |
| 117 | vfile_check_signature(vid, 1); |
| 118 | if( !nochangeFlag ) undo_begin(); |
| 119 | load_vfile_from_rid(tid); |
| 120 | |
| 121 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -111,10 +111,11 @@ | |
| 111 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 112 | " WHERE event.objid=leaves.rid" |
| 113 | " ORDER BY event.mtime DESC"); |
| 114 | } |
| 115 | |
| 116 | if( tid==vid ) return; /* Nothing to update */ |
| 117 | db_begin_transaction(); |
| 118 | vfile_check_signature(vid, 1); |
| 119 | if( !nochangeFlag ) undo_begin(); |
| 120 | load_vfile_from_rid(tid); |
| 121 | |
| 122 |
+1
-1
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -351,11 +351,11 @@ | ||
| 351 | 351 | zName2 = 0; |
| 352 | 352 | z = zValue2; |
| 353 | 353 | if( z==0 ) continue; |
| 354 | 354 | } |
| 355 | 355 | blob_appendf(&p->url, "%s%s=%T", zSep, p->azName[i], z); |
| 356 | - zSep = "&"; | |
| 356 | + zSep = "&"; | |
| 357 | 357 | } |
| 358 | 358 | if( zName1 && zValue1 ){ |
| 359 | 359 | blob_appendf(&p->url, "%s%s=%T", zSep, zName1, zValue1); |
| 360 | 360 | } |
| 361 | 361 | if( zName2 && zValue2 ){ |
| 362 | 362 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -351,11 +351,11 @@ | |
| 351 | zName2 = 0; |
| 352 | z = zValue2; |
| 353 | if( z==0 ) continue; |
| 354 | } |
| 355 | blob_appendf(&p->url, "%s%s=%T", zSep, p->azName[i], z); |
| 356 | zSep = "&"; |
| 357 | } |
| 358 | if( zName1 && zValue1 ){ |
| 359 | blob_appendf(&p->url, "%s%s=%T", zSep, zName1, zValue1); |
| 360 | } |
| 361 | if( zName2 && zValue2 ){ |
| 362 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -351,11 +351,11 @@ | |
| 351 | zName2 = 0; |
| 352 | z = zValue2; |
| 353 | if( z==0 ) continue; |
| 354 | } |
| 355 | blob_appendf(&p->url, "%s%s=%T", zSep, p->azName[i], z); |
| 356 | zSep = "&"; |
| 357 | } |
| 358 | if( zName1 && zValue1 ){ |
| 359 | blob_appendf(&p->url, "%s%s=%T", zSep, zName1, zValue1); |
| 360 | } |
| 361 | if( zName2 && zValue2 ){ |
| 362 |
+46
-46
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -48,15 +48,15 @@ | ||
| 48 | 48 | /* |
| 49 | 49 | ** Output rules for well-formed wiki pages |
| 50 | 50 | */ |
| 51 | 51 | static void well_formed_wiki_name_rules(void){ |
| 52 | 52 | @ <ul> |
| 53 | - @ <li> Must not begin or end with a space. | |
| 53 | + @ <li> Must not begin or end with a space.</li> | |
| 54 | 54 | @ <li> Must not contain any control characters, including tab or |
| 55 | - @ newline. | |
| 56 | - @ <li> Must not have two or more spaces in a row internally. | |
| 57 | - @ <li> Must be between 3 and 100 characters in length. | |
| 55 | + @ newline.</li> | |
| 56 | + @ <li> Must not have two or more spaces in a row internally.</li> | |
| 57 | + @ <li> Must be between 3 and 100 characters in length.</li> | |
| 58 | 58 | @ </ul> |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | /* |
| 62 | 62 | ** Check a wiki name. If it is not well-formed, then issue an error |
| @@ -63,12 +63,12 @@ | ||
| 63 | 63 | ** and return true. If it is well-formed, return false. |
| 64 | 64 | */ |
| 65 | 65 | static int check_name(const char *z){ |
| 66 | 66 | if( !wiki_name_is_wellformed((const unsigned char *)z) ){ |
| 67 | 67 | style_header("Wiki Page Name Error"); |
| 68 | - @ The wiki name "<b>%h(z)</b>" is not well-formed. Rules for | |
| 69 | - @ wiki page names: | |
| 68 | + @ The wiki name "<span class="wikiError">%h(z)</span>" is not well-formed. | |
| 69 | + @ Rules for wiki page names: | |
| 70 | 70 | well_formed_wiki_name_rules(); |
| 71 | 71 | style_footer(); |
| 72 | 72 | return 1; |
| 73 | 73 | } |
| 74 | 74 | return 0; |
| @@ -155,14 +155,14 @@ | ||
| 155 | 155 | if( g.okNewWiki ){ |
| 156 | 156 | @ <li> Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li> |
| 157 | 157 | } |
| 158 | 158 | @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a> |
| 159 | 159 | @ available on this server.</li> |
| 160 | - @ <li> <form method="GET" action="%s(g.zBaseURL)/wfind"> | |
| 161 | - @ Search wiki titles: <input type="text" name="title"/> | |
| 162 | - @ <input type="submit" /> | |
| 163 | - @ </li> | |
| 160 | + @ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div> | |
| 161 | + @ Search wiki titles: <input type="text" name="title"/> | |
| 162 | + @ <input type="submit" /></div></form> | |
| 163 | + @ </li> | |
| 164 | 164 | @ </ul> |
| 165 | 165 | style_footer(); |
| 166 | 166 | return; |
| 167 | 167 | } |
| 168 | 168 | if( check_name(zPageName) ) return; |
| @@ -194,11 +194,11 @@ | ||
| 194 | 194 | style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T", |
| 195 | 195 | g.zTop, zPageName); |
| 196 | 196 | } |
| 197 | 197 | if( rid && g.okApndWiki && g.okAttach ){ |
| 198 | 198 | style_submenu_element("Attach", "Add An Attachment", |
| 199 | - "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T", | |
| 199 | + "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T", | |
| 200 | 200 | g.zTop, zPageName, g.zTop, zPageName); |
| 201 | 201 | } |
| 202 | 202 | if( rid && g.okApndWiki ){ |
| 203 | 203 | style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T", |
| 204 | 204 | g.zTop, zPageName); |
| @@ -227,19 +227,20 @@ | ||
| 227 | 227 | @ <hr><h2>Attachments:</h2> |
| 228 | 228 | @ <ul> |
| 229 | 229 | } |
| 230 | 230 | cnt++; |
| 231 | 231 | if( g.okHistory && g.okRead ){ |
| 232 | - @ <li><a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)"> | |
| 232 | + @ <li> | |
| 233 | + @ <a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)"> | |
| 233 | 234 | @ %h(zFile)</a> |
| 234 | 235 | }else{ |
| 235 | 236 | @ <li>%h(zFile) |
| 236 | 237 | } |
| 237 | 238 | @ added by %h(zUser) on |
| 238 | 239 | hyperlink_to_date(zDate, "."); |
| 239 | 240 | if( g.okWrWiki && g.okAttach ){ |
| 240 | - @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>] | |
| 241 | + @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>] | |
| 241 | 242 | } |
| 242 | 243 | } |
| 243 | 244 | if( cnt ){ |
| 244 | 245 | @ </ul> |
| 245 | 246 | } |
| @@ -351,30 +352,30 @@ | ||
| 351 | 352 | zHtmlPageName = mprintf("Edit: %s", zPageName); |
| 352 | 353 | style_header(zHtmlPageName); |
| 353 | 354 | if( P("preview")!=0 ){ |
| 354 | 355 | blob_zero(&wiki); |
| 355 | 356 | blob_append(&wiki, zBody, -1); |
| 356 | - @ Preview:<hr> | |
| 357 | + @ Preview:<hr /> | |
| 357 | 358 | wiki_convert(&wiki, 0, 0); |
| 358 | - @ <hr> | |
| 359 | + @ <hr /> | |
| 359 | 360 | blob_reset(&wiki); |
| 360 | 361 | } |
| 361 | 362 | for(n=2, z=zBody; z[0]; z++){ |
| 362 | 363 | if( z[0]=='\n' ) n++; |
| 363 | 364 | } |
| 364 | 365 | if( n<20 ) n = 20; |
| 365 | 366 | if( n>40 ) n = 40; |
| 366 | - @ <form method="POST" action="%s(g.zBaseURL)/wikiedit"> | |
| 367 | + @ <form method="post" action="%s(g.zBaseURL)/wikiedit"><div> | |
| 367 | 368 | login_insert_csrf_secret(); |
| 368 | - @ <input type="hidden" name="name" value="%h(zPageName)"> | |
| 369 | + @ <input type="hidden" name="name" value="%h(zPageName)" /> | |
| 369 | 370 | @ <textarea name="w" class="wikiedit" cols="80" |
| 370 | 371 | @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> |
| 371 | - @ <br> | |
| 372 | - @ <input type="submit" name="preview" value="Preview Your Changes"> | |
| 373 | - @ <input type="submit" name="submit" value="Apply These Changes"> | |
| 374 | - @ <input type="submit" name="cancel" value="Cancel"> | |
| 375 | - @ </form> | |
| 372 | + @ <br /> | |
| 373 | + @ <input type="submit" name="preview" value="Preview Your Changes" /> | |
| 374 | + @ <input type="submit" name="submit" value="Apply These Changes" /> | |
| 375 | + @ <input type="submit" name="cancel" value="Cancel" /> | |
| 376 | + @ </div></form> | |
| 376 | 377 | if( !isSandbox ){ |
| 377 | 378 | manifest_clear(&m); |
| 378 | 379 | } |
| 379 | 380 | style_footer(); |
| 380 | 381 | } |
| @@ -396,21 +397,20 @@ | ||
| 396 | 397 | zName = PD("name",""); |
| 397 | 398 | if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){ |
| 398 | 399 | cgi_redirectf("wikiedit?name=%T", zName); |
| 399 | 400 | } |
| 400 | 401 | style_header("Create A New Wiki Page"); |
| 401 | - @ <p>Rules for wiki page names: | |
| 402 | + @ <p>Rules for wiki page names:</p> | |
| 402 | 403 | well_formed_wiki_name_rules(); |
| 403 | - @ </p> | |
| 404 | - @ <form method="POST" action="%s(g.zBaseURL)/wikinew"> | |
| 404 | + @ <form method="post" action="%s(g.zBaseURL)/wikinew"> | |
| 405 | 405 | @ <p>Name of new wiki page: |
| 406 | - @ <input type="text" width="35" name="name" value="%h(zName)"> | |
| 407 | - @ <input type="submit" value="Create"> | |
| 406 | + @ <input style="width: 35;" type="text" name="name" value="%h(zName)" /> | |
| 407 | + @ <input type="submit" value="Create" /> | |
| 408 | 408 | @ </p></form> |
| 409 | 409 | if( zName[0] ){ |
| 410 | - @ <p><b><font color="red"> | |
| 411 | - @ "%h(zName)" is not a valid wiki page name!</font></b></p> | |
| 410 | + @ <p><span class="wikiError"> | |
| 411 | + @ "%h(zName)" is not a valid wiki page name!</span></p> | |
| 412 | 412 | } |
| 413 | 413 | style_footer(); |
| 414 | 414 | } |
| 415 | 415 | |
| 416 | 416 | |
| @@ -537,15 +537,15 @@ | ||
| 537 | 537 | zUser = PD("u", g.zLogin); |
| 538 | 538 | @ <form method="POST" action="%s(g.zBaseURL)/wikiappend"> |
| 539 | 539 | login_insert_csrf_secret(); |
| 540 | 540 | @ <input type="hidden" name="name" value="%h(zPageName)"> |
| 541 | 541 | @ Your Name: |
| 542 | - @ <input type="text" name="u" size="20" value="%h(zUser)"><br> | |
| 543 | - @ Comment to append:<br> | |
| 542 | + @ <input type="text" name="u" size="20" value="%h(zUser)"><br /> | |
| 543 | + @ Comment to append:<br /> | |
| 544 | 544 | @ <textarea name="r" class="wikiedit" cols="80" |
| 545 | 545 | @ rows="10" wrap="virtual">%h(PD("r",""))</textarea> |
| 546 | - @ <br> | |
| 546 | + @ <br /> | |
| 547 | 547 | @ <input type="submit" name="preview" value="Preview Your Comment"> |
| 548 | 548 | @ <input type="submit" name="submit" value="Append Your Changes"> |
| 549 | 549 | @ <input type="submit" name="cancel" value="Cancel"> |
| 550 | 550 | @ </form> |
| 551 | 551 | style_footer(); |
| @@ -560,11 +560,11 @@ | ||
| 560 | 560 | ** Function called to output extra text at the end of each line in |
| 561 | 561 | ** a wiki history listing. |
| 562 | 562 | */ |
| 563 | 563 | static void wiki_history_extra(int rid){ |
| 564 | 564 | if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){ |
| 565 | - @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a> | |
| 565 | + @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a> | |
| 566 | 566 | } |
| 567 | 567 | } |
| 568 | 568 | |
| 569 | 569 | /* |
| 570 | 570 | ** WEBPAGE: whistory |
| @@ -740,39 +740,39 @@ | ||
| 740 | 740 | @ </ol> |
| 741 | 741 | @ <p>We call the first five rules above "wiki" formatting rules. The |
| 742 | 742 | @ last two rules are the HTML formatting rule.</p> |
| 743 | 743 | @ <h2>Formatting Rule Details</h2> |
| 744 | 744 | @ <ol> |
| 745 | - @ <li> <p><b>Paragraphs</b>. Any sequence of one or more blank lines forms | |
| 745 | + @ <li> <p><span class="wikiruleHead">Paragraphs</span>. Any sequence of one or more blank lines forms | |
| 746 | 746 | @ a paragraph break. Centered or right-justified paragraphs are not |
| 747 | 747 | @ supported by wiki markup, but you can do these things if you need them |
| 748 | - @ using HTML.</p> | |
| 749 | - @ <li> <p><b>Bullet Lists</b>. | |
| 748 | + @ using HTML.</p></li> | |
| 749 | + @ <li> <p><span class="wikiruleHead">Bullet Lists</span>. | |
| 750 | 750 | @ A bullet list item is a line that begins with a single "*" character |
| 751 | 751 | @ surrounded on |
| 752 | 752 | @ both sides by two or more spaces or by a tab. Only a single level |
| 753 | - @ of bullet list is supported by wiki. For nested lists, use HTML.</p> | |
| 754 | - @ <li> <p><b>Enumeration Lists</b>. | |
| 753 | + @ of bullet list is supported by wiki. For nested lists, use HTML.</p></li> | |
| 754 | + @ <li> <p><span class="wikiruleHead">Enumeration Lists</span>. | |
| 755 | 755 | @ An enumeration list item is a line that begins with a single "#" character |
| 756 | 756 | @ surrounded on both sides by two or more spaces or by a tab. Only a single |
| 757 | 757 | @ level of enumeration list is supported by wiki. For nested lists or for |
| 758 | - @ enumerations that count using letters or roman numerials, use HTML.</p> | |
| 759 | - @ <li> <p><b>Indented Paragraphs</b>. | |
| 758 | + @ enumerations that count using letters or roman numerials, use HTML.</p></li> | |
| 759 | + @ <li> <p><span class="wikiruleHead">Indented Paragraphs</span>. | |
| 760 | 760 | @ Any paragraph that begins with two or more spaces or a tab and |
| 761 | 761 | @ which is not a bullet or enumeration list item is rendered |
| 762 | 762 | @ indented. Only a single level of indentation is supported by wiki; use |
| 763 | - @ HTML for deeper indentation.</p> | |
| 764 | - @ <li> <p><b>Hyperlinks</b>. | |
| 763 | + @ HTML for deeper indentation.</p></li> | |
| 764 | + @ <li> <p><span class="wikiruleHead">Hyperlinks</span>. | |
| 765 | 765 | @ Text within square brackets ("[...]") becomes a hyperlink. The |
| 766 | 766 | @ target can be a wiki page name, the artifact ID of a check-in or ticket, |
| 767 | 767 | @ the name of an image, or a URL. By default, the target is displayed |
| 768 | 768 | @ as the text of the hyperlink. But you can specify alternative text |
| 769 | 769 | @ after the target name separated by a "|" character.</p> |
| 770 | 770 | @ <p>You can also link to internal anchor names using [#anchor-name], providing |
| 771 | 771 | @ you have added the necessary "<a name="anchor-name"></a>" |
| 772 | - @ tag to your wiki page.</p> | |
| 773 | - @ <li> <p><b>HTML</b>. | |
| 772 | + @ tag to your wiki page.</p></li> | |
| 773 | + @ <li> <p><span class="wikiruleHead">HTML</span>. | |
| 774 | 774 | @ The following standard HTML elements may be used: |
| 775 | 775 | @ <a> |
| 776 | 776 | @ <address> |
| 777 | 777 | @ <b> |
| 778 | 778 | @ <big> |
| @@ -822,16 +822,16 @@ | ||
| 822 | 822 | @ <verbatim> and <nowiki>. |
| 823 | 823 | @ No other elements are allowed. All attributes are checked and |
| 824 | 824 | @ only a few benign attributes are allowed on each element. |
| 825 | 825 | @ In particular, any attributes that specify javascript or CSS |
| 826 | 826 | @ are elided.</p></li> |
| 827 | - @ <li><p><b>Special Markup.</b> | |
| 827 | + @ <li><p><span class="wikiruleHead">Special Markup.</span> | |
| 828 | 828 | @ The <nowiki> tag disables all wiki formatting rules |
| 829 | 829 | @ through the matching </nowiki> element. |
| 830 | 830 | @ The <verbatim> tag works like <pre> with the addition |
| 831 | 831 | @ that it also disables all wiki and HTML markup |
| 832 | - @ through the matching </verbatim>. | |
| 832 | + @ through the matching </verbatim>.</p></li> | |
| 833 | 833 | @ </ol> |
| 834 | 834 | style_footer(); |
| 835 | 835 | } |
| 836 | 836 | |
| 837 | 837 | /* |
| 838 | 838 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -48,15 +48,15 @@ | |
| 48 | /* |
| 49 | ** Output rules for well-formed wiki pages |
| 50 | */ |
| 51 | static void well_formed_wiki_name_rules(void){ |
| 52 | @ <ul> |
| 53 | @ <li> Must not begin or end with a space. |
| 54 | @ <li> Must not contain any control characters, including tab or |
| 55 | @ newline. |
| 56 | @ <li> Must not have two or more spaces in a row internally. |
| 57 | @ <li> Must be between 3 and 100 characters in length. |
| 58 | @ </ul> |
| 59 | } |
| 60 | |
| 61 | /* |
| 62 | ** Check a wiki name. If it is not well-formed, then issue an error |
| @@ -63,12 +63,12 @@ | |
| 63 | ** and return true. If it is well-formed, return false. |
| 64 | */ |
| 65 | static int check_name(const char *z){ |
| 66 | if( !wiki_name_is_wellformed((const unsigned char *)z) ){ |
| 67 | style_header("Wiki Page Name Error"); |
| 68 | @ The wiki name "<b>%h(z)</b>" is not well-formed. Rules for |
| 69 | @ wiki page names: |
| 70 | well_formed_wiki_name_rules(); |
| 71 | style_footer(); |
| 72 | return 1; |
| 73 | } |
| 74 | return 0; |
| @@ -155,14 +155,14 @@ | |
| 155 | if( g.okNewWiki ){ |
| 156 | @ <li> Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li> |
| 157 | } |
| 158 | @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a> |
| 159 | @ available on this server.</li> |
| 160 | @ <li> <form method="GET" action="%s(g.zBaseURL)/wfind"> |
| 161 | @ Search wiki titles: <input type="text" name="title"/> |
| 162 | @ <input type="submit" /> |
| 163 | @ </li> |
| 164 | @ </ul> |
| 165 | style_footer(); |
| 166 | return; |
| 167 | } |
| 168 | if( check_name(zPageName) ) return; |
| @@ -194,11 +194,11 @@ | |
| 194 | style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T", |
| 195 | g.zTop, zPageName); |
| 196 | } |
| 197 | if( rid && g.okApndWiki && g.okAttach ){ |
| 198 | style_submenu_element("Attach", "Add An Attachment", |
| 199 | "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T", |
| 200 | g.zTop, zPageName, g.zTop, zPageName); |
| 201 | } |
| 202 | if( rid && g.okApndWiki ){ |
| 203 | style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T", |
| 204 | g.zTop, zPageName); |
| @@ -227,19 +227,20 @@ | |
| 227 | @ <hr><h2>Attachments:</h2> |
| 228 | @ <ul> |
| 229 | } |
| 230 | cnt++; |
| 231 | if( g.okHistory && g.okRead ){ |
| 232 | @ <li><a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)"> |
| 233 | @ %h(zFile)</a> |
| 234 | }else{ |
| 235 | @ <li>%h(zFile) |
| 236 | } |
| 237 | @ added by %h(zUser) on |
| 238 | hyperlink_to_date(zDate, "."); |
| 239 | if( g.okWrWiki && g.okAttach ){ |
| 240 | @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>] |
| 241 | } |
| 242 | } |
| 243 | if( cnt ){ |
| 244 | @ </ul> |
| 245 | } |
| @@ -351,30 +352,30 @@ | |
| 351 | zHtmlPageName = mprintf("Edit: %s", zPageName); |
| 352 | style_header(zHtmlPageName); |
| 353 | if( P("preview")!=0 ){ |
| 354 | blob_zero(&wiki); |
| 355 | blob_append(&wiki, zBody, -1); |
| 356 | @ Preview:<hr> |
| 357 | wiki_convert(&wiki, 0, 0); |
| 358 | @ <hr> |
| 359 | blob_reset(&wiki); |
| 360 | } |
| 361 | for(n=2, z=zBody; z[0]; z++){ |
| 362 | if( z[0]=='\n' ) n++; |
| 363 | } |
| 364 | if( n<20 ) n = 20; |
| 365 | if( n>40 ) n = 40; |
| 366 | @ <form method="POST" action="%s(g.zBaseURL)/wikiedit"> |
| 367 | login_insert_csrf_secret(); |
| 368 | @ <input type="hidden" name="name" value="%h(zPageName)"> |
| 369 | @ <textarea name="w" class="wikiedit" cols="80" |
| 370 | @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> |
| 371 | @ <br> |
| 372 | @ <input type="submit" name="preview" value="Preview Your Changes"> |
| 373 | @ <input type="submit" name="submit" value="Apply These Changes"> |
| 374 | @ <input type="submit" name="cancel" value="Cancel"> |
| 375 | @ </form> |
| 376 | if( !isSandbox ){ |
| 377 | manifest_clear(&m); |
| 378 | } |
| 379 | style_footer(); |
| 380 | } |
| @@ -396,21 +397,20 @@ | |
| 396 | zName = PD("name",""); |
| 397 | if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){ |
| 398 | cgi_redirectf("wikiedit?name=%T", zName); |
| 399 | } |
| 400 | style_header("Create A New Wiki Page"); |
| 401 | @ <p>Rules for wiki page names: |
| 402 | well_formed_wiki_name_rules(); |
| 403 | @ </p> |
| 404 | @ <form method="POST" action="%s(g.zBaseURL)/wikinew"> |
| 405 | @ <p>Name of new wiki page: |
| 406 | @ <input type="text" width="35" name="name" value="%h(zName)"> |
| 407 | @ <input type="submit" value="Create"> |
| 408 | @ </p></form> |
| 409 | if( zName[0] ){ |
| 410 | @ <p><b><font color="red"> |
| 411 | @ "%h(zName)" is not a valid wiki page name!</font></b></p> |
| 412 | } |
| 413 | style_footer(); |
| 414 | } |
| 415 | |
| 416 | |
| @@ -537,15 +537,15 @@ | |
| 537 | zUser = PD("u", g.zLogin); |
| 538 | @ <form method="POST" action="%s(g.zBaseURL)/wikiappend"> |
| 539 | login_insert_csrf_secret(); |
| 540 | @ <input type="hidden" name="name" value="%h(zPageName)"> |
| 541 | @ Your Name: |
| 542 | @ <input type="text" name="u" size="20" value="%h(zUser)"><br> |
| 543 | @ Comment to append:<br> |
| 544 | @ <textarea name="r" class="wikiedit" cols="80" |
| 545 | @ rows="10" wrap="virtual">%h(PD("r",""))</textarea> |
| 546 | @ <br> |
| 547 | @ <input type="submit" name="preview" value="Preview Your Comment"> |
| 548 | @ <input type="submit" name="submit" value="Append Your Changes"> |
| 549 | @ <input type="submit" name="cancel" value="Cancel"> |
| 550 | @ </form> |
| 551 | style_footer(); |
| @@ -560,11 +560,11 @@ | |
| 560 | ** Function called to output extra text at the end of each line in |
| 561 | ** a wiki history listing. |
| 562 | */ |
| 563 | static void wiki_history_extra(int rid){ |
| 564 | if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){ |
| 565 | @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a> |
| 566 | } |
| 567 | } |
| 568 | |
| 569 | /* |
| 570 | ** WEBPAGE: whistory |
| @@ -740,39 +740,39 @@ | |
| 740 | @ </ol> |
| 741 | @ <p>We call the first five rules above "wiki" formatting rules. The |
| 742 | @ last two rules are the HTML formatting rule.</p> |
| 743 | @ <h2>Formatting Rule Details</h2> |
| 744 | @ <ol> |
| 745 | @ <li> <p><b>Paragraphs</b>. Any sequence of one or more blank lines forms |
| 746 | @ a paragraph break. Centered or right-justified paragraphs are not |
| 747 | @ supported by wiki markup, but you can do these things if you need them |
| 748 | @ using HTML.</p> |
| 749 | @ <li> <p><b>Bullet Lists</b>. |
| 750 | @ A bullet list item is a line that begins with a single "*" character |
| 751 | @ surrounded on |
| 752 | @ both sides by two or more spaces or by a tab. Only a single level |
| 753 | @ of bullet list is supported by wiki. For nested lists, use HTML.</p> |
| 754 | @ <li> <p><b>Enumeration Lists</b>. |
| 755 | @ An enumeration list item is a line that begins with a single "#" character |
| 756 | @ surrounded on both sides by two or more spaces or by a tab. Only a single |
| 757 | @ level of enumeration list is supported by wiki. For nested lists or for |
| 758 | @ enumerations that count using letters or roman numerials, use HTML.</p> |
| 759 | @ <li> <p><b>Indented Paragraphs</b>. |
| 760 | @ Any paragraph that begins with two or more spaces or a tab and |
| 761 | @ which is not a bullet or enumeration list item is rendered |
| 762 | @ indented. Only a single level of indentation is supported by wiki; use |
| 763 | @ HTML for deeper indentation.</p> |
| 764 | @ <li> <p><b>Hyperlinks</b>. |
| 765 | @ Text within square brackets ("[...]") becomes a hyperlink. The |
| 766 | @ target can be a wiki page name, the artifact ID of a check-in or ticket, |
| 767 | @ the name of an image, or a URL. By default, the target is displayed |
| 768 | @ as the text of the hyperlink. But you can specify alternative text |
| 769 | @ after the target name separated by a "|" character.</p> |
| 770 | @ <p>You can also link to internal anchor names using [#anchor-name], providing |
| 771 | @ you have added the necessary "<a name="anchor-name"></a>" |
| 772 | @ tag to your wiki page.</p> |
| 773 | @ <li> <p><b>HTML</b>. |
| 774 | @ The following standard HTML elements may be used: |
| 775 | @ <a> |
| 776 | @ <address> |
| 777 | @ <b> |
| 778 | @ <big> |
| @@ -822,16 +822,16 @@ | |
| 822 | @ <verbatim> and <nowiki>. |
| 823 | @ No other elements are allowed. All attributes are checked and |
| 824 | @ only a few benign attributes are allowed on each element. |
| 825 | @ In particular, any attributes that specify javascript or CSS |
| 826 | @ are elided.</p></li> |
| 827 | @ <li><p><b>Special Markup.</b> |
| 828 | @ The <nowiki> tag disables all wiki formatting rules |
| 829 | @ through the matching </nowiki> element. |
| 830 | @ The <verbatim> tag works like <pre> with the addition |
| 831 | @ that it also disables all wiki and HTML markup |
| 832 | @ through the matching </verbatim>. |
| 833 | @ </ol> |
| 834 | style_footer(); |
| 835 | } |
| 836 | |
| 837 | /* |
| 838 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -48,15 +48,15 @@ | |
| 48 | /* |
| 49 | ** Output rules for well-formed wiki pages |
| 50 | */ |
| 51 | static void well_formed_wiki_name_rules(void){ |
| 52 | @ <ul> |
| 53 | @ <li> Must not begin or end with a space.</li> |
| 54 | @ <li> Must not contain any control characters, including tab or |
| 55 | @ newline.</li> |
| 56 | @ <li> Must not have two or more spaces in a row internally.</li> |
| 57 | @ <li> Must be between 3 and 100 characters in length.</li> |
| 58 | @ </ul> |
| 59 | } |
| 60 | |
| 61 | /* |
| 62 | ** Check a wiki name. If it is not well-formed, then issue an error |
| @@ -63,12 +63,12 @@ | |
| 63 | ** and return true. If it is well-formed, return false. |
| 64 | */ |
| 65 | static int check_name(const char *z){ |
| 66 | if( !wiki_name_is_wellformed((const unsigned char *)z) ){ |
| 67 | style_header("Wiki Page Name Error"); |
| 68 | @ The wiki name "<span class="wikiError">%h(z)</span>" is not well-formed. |
| 69 | @ Rules for wiki page names: |
| 70 | well_formed_wiki_name_rules(); |
| 71 | style_footer(); |
| 72 | return 1; |
| 73 | } |
| 74 | return 0; |
| @@ -155,14 +155,14 @@ | |
| 155 | if( g.okNewWiki ){ |
| 156 | @ <li> Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li> |
| 157 | } |
| 158 | @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a> |
| 159 | @ available on this server.</li> |
| 160 | @ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div> |
| 161 | @ Search wiki titles: <input type="text" name="title"/> |
| 162 | @ <input type="submit" /></div></form> |
| 163 | @ </li> |
| 164 | @ </ul> |
| 165 | style_footer(); |
| 166 | return; |
| 167 | } |
| 168 | if( check_name(zPageName) ) return; |
| @@ -194,11 +194,11 @@ | |
| 194 | style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T", |
| 195 | g.zTop, zPageName); |
| 196 | } |
| 197 | if( rid && g.okApndWiki && g.okAttach ){ |
| 198 | style_submenu_element("Attach", "Add An Attachment", |
| 199 | "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T", |
| 200 | g.zTop, zPageName, g.zTop, zPageName); |
| 201 | } |
| 202 | if( rid && g.okApndWiki ){ |
| 203 | style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T", |
| 204 | g.zTop, zPageName); |
| @@ -227,19 +227,20 @@ | |
| 227 | @ <hr><h2>Attachments:</h2> |
| 228 | @ <ul> |
| 229 | } |
| 230 | cnt++; |
| 231 | if( g.okHistory && g.okRead ){ |
| 232 | @ <li> |
| 233 | @ <a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)"> |
| 234 | @ %h(zFile)</a> |
| 235 | }else{ |
| 236 | @ <li>%h(zFile) |
| 237 | } |
| 238 | @ added by %h(zUser) on |
| 239 | hyperlink_to_date(zDate, "."); |
| 240 | if( g.okWrWiki && g.okAttach ){ |
| 241 | @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>] |
| 242 | } |
| 243 | } |
| 244 | if( cnt ){ |
| 245 | @ </ul> |
| 246 | } |
| @@ -351,30 +352,30 @@ | |
| 352 | zHtmlPageName = mprintf("Edit: %s", zPageName); |
| 353 | style_header(zHtmlPageName); |
| 354 | if( P("preview")!=0 ){ |
| 355 | blob_zero(&wiki); |
| 356 | blob_append(&wiki, zBody, -1); |
| 357 | @ Preview:<hr /> |
| 358 | wiki_convert(&wiki, 0, 0); |
| 359 | @ <hr /> |
| 360 | blob_reset(&wiki); |
| 361 | } |
| 362 | for(n=2, z=zBody; z[0]; z++){ |
| 363 | if( z[0]=='\n' ) n++; |
| 364 | } |
| 365 | if( n<20 ) n = 20; |
| 366 | if( n>40 ) n = 40; |
| 367 | @ <form method="post" action="%s(g.zBaseURL)/wikiedit"><div> |
| 368 | login_insert_csrf_secret(); |
| 369 | @ <input type="hidden" name="name" value="%h(zPageName)" /> |
| 370 | @ <textarea name="w" class="wikiedit" cols="80" |
| 371 | @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> |
| 372 | @ <br /> |
| 373 | @ <input type="submit" name="preview" value="Preview Your Changes" /> |
| 374 | @ <input type="submit" name="submit" value="Apply These Changes" /> |
| 375 | @ <input type="submit" name="cancel" value="Cancel" /> |
| 376 | @ </div></form> |
| 377 | if( !isSandbox ){ |
| 378 | manifest_clear(&m); |
| 379 | } |
| 380 | style_footer(); |
| 381 | } |
| @@ -396,21 +397,20 @@ | |
| 397 | zName = PD("name",""); |
| 398 | if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){ |
| 399 | cgi_redirectf("wikiedit?name=%T", zName); |
| 400 | } |
| 401 | style_header("Create A New Wiki Page"); |
| 402 | @ <p>Rules for wiki page names:</p> |
| 403 | well_formed_wiki_name_rules(); |
| 404 | @ <form method="post" action="%s(g.zBaseURL)/wikinew"> |
| 405 | @ <p>Name of new wiki page: |
| 406 | @ <input style="width: 35;" type="text" name="name" value="%h(zName)" /> |
| 407 | @ <input type="submit" value="Create" /> |
| 408 | @ </p></form> |
| 409 | if( zName[0] ){ |
| 410 | @ <p><span class="wikiError"> |
| 411 | @ "%h(zName)" is not a valid wiki page name!</span></p> |
| 412 | } |
| 413 | style_footer(); |
| 414 | } |
| 415 | |
| 416 | |
| @@ -537,15 +537,15 @@ | |
| 537 | zUser = PD("u", g.zLogin); |
| 538 | @ <form method="POST" action="%s(g.zBaseURL)/wikiappend"> |
| 539 | login_insert_csrf_secret(); |
| 540 | @ <input type="hidden" name="name" value="%h(zPageName)"> |
| 541 | @ Your Name: |
| 542 | @ <input type="text" name="u" size="20" value="%h(zUser)"><br /> |
| 543 | @ Comment to append:<br /> |
| 544 | @ <textarea name="r" class="wikiedit" cols="80" |
| 545 | @ rows="10" wrap="virtual">%h(PD("r",""))</textarea> |
| 546 | @ <br /> |
| 547 | @ <input type="submit" name="preview" value="Preview Your Comment"> |
| 548 | @ <input type="submit" name="submit" value="Append Your Changes"> |
| 549 | @ <input type="submit" name="cancel" value="Cancel"> |
| 550 | @ </form> |
| 551 | style_footer(); |
| @@ -560,11 +560,11 @@ | |
| 560 | ** Function called to output extra text at the end of each line in |
| 561 | ** a wiki history listing. |
| 562 | */ |
| 563 | static void wiki_history_extra(int rid){ |
| 564 | if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){ |
| 565 | @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a> |
| 566 | } |
| 567 | } |
| 568 | |
| 569 | /* |
| 570 | ** WEBPAGE: whistory |
| @@ -740,39 +740,39 @@ | |
| 740 | @ </ol> |
| 741 | @ <p>We call the first five rules above "wiki" formatting rules. The |
| 742 | @ last two rules are the HTML formatting rule.</p> |
| 743 | @ <h2>Formatting Rule Details</h2> |
| 744 | @ <ol> |
| 745 | @ <li> <p><span class="wikiruleHead">Paragraphs</span>. Any sequence of one or more blank lines forms |
| 746 | @ a paragraph break. Centered or right-justified paragraphs are not |
| 747 | @ supported by wiki markup, but you can do these things if you need them |
| 748 | @ using HTML.</p></li> |
| 749 | @ <li> <p><span class="wikiruleHead">Bullet Lists</span>. |
| 750 | @ A bullet list item is a line that begins with a single "*" character |
| 751 | @ surrounded on |
| 752 | @ both sides by two or more spaces or by a tab. Only a single level |
| 753 | @ of bullet list is supported by wiki. For nested lists, use HTML.</p></li> |
| 754 | @ <li> <p><span class="wikiruleHead">Enumeration Lists</span>. |
| 755 | @ An enumeration list item is a line that begins with a single "#" character |
| 756 | @ surrounded on both sides by two or more spaces or by a tab. Only a single |
| 757 | @ level of enumeration list is supported by wiki. For nested lists or for |
| 758 | @ enumerations that count using letters or roman numerials, use HTML.</p></li> |
| 759 | @ <li> <p><span class="wikiruleHead">Indented Paragraphs</span>. |
| 760 | @ Any paragraph that begins with two or more spaces or a tab and |
| 761 | @ which is not a bullet or enumeration list item is rendered |
| 762 | @ indented. Only a single level of indentation is supported by wiki; use |
| 763 | @ HTML for deeper indentation.</p></li> |
| 764 | @ <li> <p><span class="wikiruleHead">Hyperlinks</span>. |
| 765 | @ Text within square brackets ("[...]") becomes a hyperlink. The |
| 766 | @ target can be a wiki page name, the artifact ID of a check-in or ticket, |
| 767 | @ the name of an image, or a URL. By default, the target is displayed |
| 768 | @ as the text of the hyperlink. But you can specify alternative text |
| 769 | @ after the target name separated by a "|" character.</p> |
| 770 | @ <p>You can also link to internal anchor names using [#anchor-name], providing |
| 771 | @ you have added the necessary "<a name="anchor-name"></a>" |
| 772 | @ tag to your wiki page.</p></li> |
| 773 | @ <li> <p><span class="wikiruleHead">HTML</span>. |
| 774 | @ The following standard HTML elements may be used: |
| 775 | @ <a> |
| 776 | @ <address> |
| 777 | @ <b> |
| 778 | @ <big> |
| @@ -822,16 +822,16 @@ | |
| 822 | @ <verbatim> and <nowiki>. |
| 823 | @ No other elements are allowed. All attributes are checked and |
| 824 | @ only a few benign attributes are allowed on each element. |
| 825 | @ In particular, any attributes that specify javascript or CSS |
| 826 | @ are elided.</p></li> |
| 827 | @ <li><p><span class="wikiruleHead">Special Markup.</span> |
| 828 | @ The <nowiki> tag disables all wiki formatting rules |
| 829 | @ through the matching </nowiki> element. |
| 830 | @ The <verbatim> tag works like <pre> with the addition |
| 831 | @ that it also disables all wiki and HTML markup |
| 832 | @ through the matching </verbatim>.</p></li> |
| 833 | @ </ol> |
| 834 | style_footer(); |
| 835 | } |
| 836 | |
| 837 | /* |
| 838 |
+47
-21
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -321,21 +321,21 @@ | ||
| 321 | 321 | } |
| 322 | 322 | |
| 323 | 323 | /* |
| 324 | 324 | ** Token types |
| 325 | 325 | */ |
| 326 | -#define TOKEN_MARKUP 1 /* <...> */ | |
| 327 | -#define TOKEN_CHARACTER 2 /* "&" or "<" not part of markup */ | |
| 328 | -#define TOKEN_LINK 3 /* [...] */ | |
| 329 | -#define TOKEN_PARAGRAPH 4 /* blank lines */ | |
| 330 | -#define TOKEN_NEWLINE 5 /* A single "\n" */ | |
| 331 | -#define TOKEN_BUL_LI 6 /* " * " */ | |
| 332 | -#define TOKEN_NUM_LI 7 /* " # " */ | |
| 333 | -#define TOKEN_ENUM 8 /* " \(?\d+[.)]? " */ | |
| 334 | -#define TOKEN_INDENT 9 /* " " */ | |
| 335 | -#define TOKEN_RAW 10 /* Output exactly (used when wiki-use-html==1) */ | |
| 336 | -#define TOKEN_TEXT 11 /* None of the above */ | |
| 326 | +#define TOKEN_MARKUP 1 /* <...> */ | |
| 327 | +#define TOKEN_CHARACTER 2 /* "&" or "<" not part of markup */ | |
| 328 | +#define TOKEN_LINK 3 /* [...] */ | |
| 329 | +#define TOKEN_PARAGRAPH 4 /* blank lines */ | |
| 330 | +#define TOKEN_NEWLINE 5 /* A single "\n" */ | |
| 331 | +#define TOKEN_BUL_LI 6 /* " * " */ | |
| 332 | +#define TOKEN_NUM_LI 7 /* " # " */ | |
| 333 | +#define TOKEN_ENUM 8 /* " \(?\d+[.)]? " */ | |
| 334 | +#define TOKEN_INDENT 9 /* " " */ | |
| 335 | +#define TOKEN_RAW 10 /* Output exactly (used when wiki-use-html==1) */ | |
| 336 | +#define TOKEN_TEXT 11 /* None of the above */ | |
| 337 | 337 | |
| 338 | 338 | /* |
| 339 | 339 | ** State flags |
| 340 | 340 | */ |
| 341 | 341 | #define AT_NEWLINE 0x001 /* At start of a line */ |
| @@ -745,10 +745,13 @@ | ||
| 745 | 745 | static void renderMarkup(Blob *pOut, ParsedMarkup *p){ |
| 746 | 746 | int i; |
| 747 | 747 | if( p->endTag ){ |
| 748 | 748 | blob_appendf(pOut, "</%s>", aMarkup[p->iCode].zName); |
| 749 | 749 | }else{ |
| 750 | + /* Close active paragraph for several elements, which are not allowed | |
| 751 | + ** in paragraphs in XHTML. | |
| 752 | + */ | |
| 750 | 753 | blob_appendf(pOut, "<%s", aMarkup[p->iCode].zName); |
| 751 | 754 | for(i=0; i<p->nAttr; i++){ |
| 752 | 755 | blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iACode].zName); |
| 753 | 756 | if( p->aAttr[i].zValue ){ |
| 754 | 757 | const char *zVal = p->aAttr[i].zValue; |
| @@ -756,10 +759,13 @@ | ||
| 756 | 759 | blob_appendf(pOut, "=\"%s%s\"", g.zBaseURL, zVal); |
| 757 | 760 | }else{ |
| 758 | 761 | blob_appendf(pOut, "=\"%s\"", zVal); |
| 759 | 762 | } |
| 760 | 763 | } |
| 764 | + } | |
| 765 | + if (p->iType & MUTYPE_SINGLE){ | |
| 766 | + blob_append(pOut, " /", 2); | |
| 761 | 767 | } |
| 762 | 768 | blob_append(pOut, ">", 1); |
| 763 | 769 | } |
| 764 | 770 | } |
| 765 | 771 | |
| @@ -885,12 +891,13 @@ | ||
| 885 | 891 | |
| 886 | 892 | /* |
| 887 | 893 | ** Begin a new paragraph if that something that is needed. |
| 888 | 894 | */ |
| 889 | 895 | static void startAutoParagraph(Renderer *p){ |
| 890 | - if( p->wantAutoParagraph==0 || p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return; | |
| 891 | - blob_appendf(p->pOut, "<p>", -1); | |
| 896 | + if( p->wantAutoParagraph==0 ) return; | |
| 897 | + if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return; | |
| 898 | + blob_appendf(p->pOut, "<p type=\"auto\">", -1); | |
| 892 | 899 | pushStack(p, MARKUP_P); |
| 893 | 900 | p->wantAutoParagraph = 0; |
| 894 | 901 | p->inAutoParagraph = 1; |
| 895 | 902 | } |
| 896 | 903 | |
| @@ -1019,17 +1026,18 @@ | ||
| 1019 | 1026 | /* Special display processing for tickets. Display the hyperlink |
| 1020 | 1027 | ** as crossed out if the ticket is closed. |
| 1021 | 1028 | */ |
| 1022 | 1029 | if( isClosed ){ |
| 1023 | 1030 | if( g.okHistory ){ |
| 1024 | - blob_appendf(p->pOut,"<a href=\"%s/info/%s\"><s>", | |
| 1025 | - g.zBaseURL, zTarget | |
| 1031 | + blob_appendf(p->pOut, | |
| 1032 | + "<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">", | |
| 1033 | + g.zBaseURL, zTarget | |
| 1026 | 1034 | ); |
| 1027 | - zTerm = "</s></a>"; | |
| 1035 | + zTerm = "</span></a>"; | |
| 1028 | 1036 | }else{ |
| 1029 | - blob_appendf(p->pOut,"<s>"); | |
| 1030 | - zTerm = "</s>"; | |
| 1037 | + blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">"); | |
| 1038 | + zTerm = "</span>"; | |
| 1031 | 1039 | } |
| 1032 | 1040 | }else{ |
| 1033 | 1041 | if( g.okHistory ){ |
| 1034 | 1042 | blob_appendf(p->pOut,"<a href=\"%s/info/%s\">", |
| 1035 | 1043 | g.zBaseURL, zTarget |
| @@ -1133,10 +1141,11 @@ | ||
| 1133 | 1141 | }else{ |
| 1134 | 1142 | if( p->wikiList!=MARKUP_UL ){ |
| 1135 | 1143 | if( p->wikiList ){ |
| 1136 | 1144 | popStackToTag(p, p->wikiList); |
| 1137 | 1145 | } |
| 1146 | + endAutoParagraph(p); | |
| 1138 | 1147 | pushStack(p, MARKUP_UL); |
| 1139 | 1148 | blob_append(p->pOut, "<ul>", 4); |
| 1140 | 1149 | p->wikiList = MARKUP_UL; |
| 1141 | 1150 | } |
| 1142 | 1151 | popStackToTag(p, MARKUP_LI); |
| @@ -1152,10 +1161,11 @@ | ||
| 1152 | 1161 | }else{ |
| 1153 | 1162 | if( p->wikiList!=MARKUP_OL ){ |
| 1154 | 1163 | if( p->wikiList ){ |
| 1155 | 1164 | popStackToTag(p, p->wikiList); |
| 1156 | 1165 | } |
| 1166 | + endAutoParagraph(p); | |
| 1157 | 1167 | pushStack(p, MARKUP_OL); |
| 1158 | 1168 | blob_append(p->pOut, "<ol>", 4); |
| 1159 | 1169 | p->wikiList = MARKUP_OL; |
| 1160 | 1170 | } |
| 1161 | 1171 | popStackToTag(p, MARKUP_LI); |
| @@ -1171,10 +1181,11 @@ | ||
| 1171 | 1181 | }else{ |
| 1172 | 1182 | if( p->wikiList!=MARKUP_OL ){ |
| 1173 | 1183 | if( p->wikiList ){ |
| 1174 | 1184 | popStackToTag(p, p->wikiList); |
| 1175 | 1185 | } |
| 1186 | + endAutoParagraph(p); | |
| 1176 | 1187 | pushStack(p, MARKUP_OL); |
| 1177 | 1188 | blob_append(p->pOut, "<ol>", 4); |
| 1178 | 1189 | p->wikiList = MARKUP_OL; |
| 1179 | 1190 | } |
| 1180 | 1191 | popStackToTag(p, MARKUP_LI); |
| @@ -1233,11 +1244,13 @@ | ||
| 1233 | 1244 | p->state = savedState; |
| 1234 | 1245 | blob_append(p->pOut, zClose, -1); |
| 1235 | 1246 | break; |
| 1236 | 1247 | } |
| 1237 | 1248 | case TOKEN_TEXT: { |
| 1238 | - startAutoParagraph(p); | |
| 1249 | + int i; | |
| 1250 | + for(i=0; i<n && isspace(z[i]); i++){} | |
| 1251 | + if( i<n ) startAutoParagraph(p); | |
| 1239 | 1252 | blob_append(p->pOut, z, n); |
| 1240 | 1253 | break; |
| 1241 | 1254 | } |
| 1242 | 1255 | case TOKEN_RAW: { |
| 1243 | 1256 | blob_append(p->pOut, z, n); |
| @@ -1347,16 +1360,19 @@ | ||
| 1347 | 1360 | blob_appendf(p->pOut, "<pre name='code' class='%s'>", |
| 1348 | 1361 | markup.aAttr[vAttrIdx].zValue); |
| 1349 | 1362 | vAttrDidAppend=1; |
| 1350 | 1363 | } |
| 1351 | 1364 | } |
| 1352 | - if( !vAttrDidAppend ) | |
| 1365 | + if( !vAttrDidAppend ) { | |
| 1366 | + endAutoParagraph(p); | |
| 1353 | 1367 | blob_append(p->pOut, "<pre class='verbatim'>",-1); |
| 1368 | + } | |
| 1354 | 1369 | p->wantAutoParagraph = 0; |
| 1355 | 1370 | }else |
| 1356 | 1371 | if( markup.iType==MUTYPE_LI ){ |
| 1357 | 1372 | if( backupToType(p, MUTYPE_LIST)==0 ){ |
| 1373 | + endAutoParagraph(p); | |
| 1358 | 1374 | pushStack(p, MARKUP_UL); |
| 1359 | 1375 | blob_append(p->pOut, "<ul>", 4); |
| 1360 | 1376 | } |
| 1361 | 1377 | pushStack(p, MARKUP_LI); |
| 1362 | 1378 | renderMarkup(p->pOut, &markup); |
| @@ -1384,12 +1400,22 @@ | ||
| 1384 | 1400 | pushStack(p, markup.iCode); |
| 1385 | 1401 | }else |
| 1386 | 1402 | { |
| 1387 | 1403 | if( markup.iType==MUTYPE_FONT ){ |
| 1388 | 1404 | startAutoParagraph(p); |
| 1389 | - }else if( markup.iType==MUTYPE_BLOCK ){ | |
| 1405 | + }else if( markup.iType==MUTYPE_BLOCK || markup.iType==MUTYPE_LIST ){ | |
| 1390 | 1406 | p->wantAutoParagraph = 0; |
| 1407 | + } | |
| 1408 | + if( markup.iCode==MARKUP_HR | |
| 1409 | + || markup.iCode==MARKUP_H1 | |
| 1410 | + || markup.iCode==MARKUP_H2 | |
| 1411 | + || markup.iCode==MARKUP_H3 | |
| 1412 | + || markup.iCode==MARKUP_H4 | |
| 1413 | + || markup.iCode==MARKUP_H5 | |
| 1414 | + || markup.iCode==MARKUP_P | |
| 1415 | + ){ | |
| 1416 | + endAutoParagraph(p); | |
| 1391 | 1417 | } |
| 1392 | 1418 | if( (markup.iType & MUTYPE_STACK )!=0 ){ |
| 1393 | 1419 | pushStack(p, markup.iCode); |
| 1394 | 1420 | } |
| 1395 | 1421 | renderMarkup(p->pOut, &markup); |
| 1396 | 1422 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -321,21 +321,21 @@ | |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | ** Token types |
| 325 | */ |
| 326 | #define TOKEN_MARKUP 1 /* <...> */ |
| 327 | #define TOKEN_CHARACTER 2 /* "&" or "<" not part of markup */ |
| 328 | #define TOKEN_LINK 3 /* [...] */ |
| 329 | #define TOKEN_PARAGRAPH 4 /* blank lines */ |
| 330 | #define TOKEN_NEWLINE 5 /* A single "\n" */ |
| 331 | #define TOKEN_BUL_LI 6 /* " * " */ |
| 332 | #define TOKEN_NUM_LI 7 /* " # " */ |
| 333 | #define TOKEN_ENUM 8 /* " \(?\d+[.)]? " */ |
| 334 | #define TOKEN_INDENT 9 /* " " */ |
| 335 | #define TOKEN_RAW 10 /* Output exactly (used when wiki-use-html==1) */ |
| 336 | #define TOKEN_TEXT 11 /* None of the above */ |
| 337 | |
| 338 | /* |
| 339 | ** State flags |
| 340 | */ |
| 341 | #define AT_NEWLINE 0x001 /* At start of a line */ |
| @@ -745,10 +745,13 @@ | |
| 745 | static void renderMarkup(Blob *pOut, ParsedMarkup *p){ |
| 746 | int i; |
| 747 | if( p->endTag ){ |
| 748 | blob_appendf(pOut, "</%s>", aMarkup[p->iCode].zName); |
| 749 | }else{ |
| 750 | blob_appendf(pOut, "<%s", aMarkup[p->iCode].zName); |
| 751 | for(i=0; i<p->nAttr; i++){ |
| 752 | blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iACode].zName); |
| 753 | if( p->aAttr[i].zValue ){ |
| 754 | const char *zVal = p->aAttr[i].zValue; |
| @@ -756,10 +759,13 @@ | |
| 756 | blob_appendf(pOut, "=\"%s%s\"", g.zBaseURL, zVal); |
| 757 | }else{ |
| 758 | blob_appendf(pOut, "=\"%s\"", zVal); |
| 759 | } |
| 760 | } |
| 761 | } |
| 762 | blob_append(pOut, ">", 1); |
| 763 | } |
| 764 | } |
| 765 | |
| @@ -885,12 +891,13 @@ | |
| 885 | |
| 886 | /* |
| 887 | ** Begin a new paragraph if that something that is needed. |
| 888 | */ |
| 889 | static void startAutoParagraph(Renderer *p){ |
| 890 | if( p->wantAutoParagraph==0 || p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return; |
| 891 | blob_appendf(p->pOut, "<p>", -1); |
| 892 | pushStack(p, MARKUP_P); |
| 893 | p->wantAutoParagraph = 0; |
| 894 | p->inAutoParagraph = 1; |
| 895 | } |
| 896 | |
| @@ -1019,17 +1026,18 @@ | |
| 1019 | /* Special display processing for tickets. Display the hyperlink |
| 1020 | ** as crossed out if the ticket is closed. |
| 1021 | */ |
| 1022 | if( isClosed ){ |
| 1023 | if( g.okHistory ){ |
| 1024 | blob_appendf(p->pOut,"<a href=\"%s/info/%s\"><s>", |
| 1025 | g.zBaseURL, zTarget |
| 1026 | ); |
| 1027 | zTerm = "</s></a>"; |
| 1028 | }else{ |
| 1029 | blob_appendf(p->pOut,"<s>"); |
| 1030 | zTerm = "</s>"; |
| 1031 | } |
| 1032 | }else{ |
| 1033 | if( g.okHistory ){ |
| 1034 | blob_appendf(p->pOut,"<a href=\"%s/info/%s\">", |
| 1035 | g.zBaseURL, zTarget |
| @@ -1133,10 +1141,11 @@ | |
| 1133 | }else{ |
| 1134 | if( p->wikiList!=MARKUP_UL ){ |
| 1135 | if( p->wikiList ){ |
| 1136 | popStackToTag(p, p->wikiList); |
| 1137 | } |
| 1138 | pushStack(p, MARKUP_UL); |
| 1139 | blob_append(p->pOut, "<ul>", 4); |
| 1140 | p->wikiList = MARKUP_UL; |
| 1141 | } |
| 1142 | popStackToTag(p, MARKUP_LI); |
| @@ -1152,10 +1161,11 @@ | |
| 1152 | }else{ |
| 1153 | if( p->wikiList!=MARKUP_OL ){ |
| 1154 | if( p->wikiList ){ |
| 1155 | popStackToTag(p, p->wikiList); |
| 1156 | } |
| 1157 | pushStack(p, MARKUP_OL); |
| 1158 | blob_append(p->pOut, "<ol>", 4); |
| 1159 | p->wikiList = MARKUP_OL; |
| 1160 | } |
| 1161 | popStackToTag(p, MARKUP_LI); |
| @@ -1171,10 +1181,11 @@ | |
| 1171 | }else{ |
| 1172 | if( p->wikiList!=MARKUP_OL ){ |
| 1173 | if( p->wikiList ){ |
| 1174 | popStackToTag(p, p->wikiList); |
| 1175 | } |
| 1176 | pushStack(p, MARKUP_OL); |
| 1177 | blob_append(p->pOut, "<ol>", 4); |
| 1178 | p->wikiList = MARKUP_OL; |
| 1179 | } |
| 1180 | popStackToTag(p, MARKUP_LI); |
| @@ -1233,11 +1244,13 @@ | |
| 1233 | p->state = savedState; |
| 1234 | blob_append(p->pOut, zClose, -1); |
| 1235 | break; |
| 1236 | } |
| 1237 | case TOKEN_TEXT: { |
| 1238 | startAutoParagraph(p); |
| 1239 | blob_append(p->pOut, z, n); |
| 1240 | break; |
| 1241 | } |
| 1242 | case TOKEN_RAW: { |
| 1243 | blob_append(p->pOut, z, n); |
| @@ -1347,16 +1360,19 @@ | |
| 1347 | blob_appendf(p->pOut, "<pre name='code' class='%s'>", |
| 1348 | markup.aAttr[vAttrIdx].zValue); |
| 1349 | vAttrDidAppend=1; |
| 1350 | } |
| 1351 | } |
| 1352 | if( !vAttrDidAppend ) |
| 1353 | blob_append(p->pOut, "<pre class='verbatim'>",-1); |
| 1354 | p->wantAutoParagraph = 0; |
| 1355 | }else |
| 1356 | if( markup.iType==MUTYPE_LI ){ |
| 1357 | if( backupToType(p, MUTYPE_LIST)==0 ){ |
| 1358 | pushStack(p, MARKUP_UL); |
| 1359 | blob_append(p->pOut, "<ul>", 4); |
| 1360 | } |
| 1361 | pushStack(p, MARKUP_LI); |
| 1362 | renderMarkup(p->pOut, &markup); |
| @@ -1384,12 +1400,22 @@ | |
| 1384 | pushStack(p, markup.iCode); |
| 1385 | }else |
| 1386 | { |
| 1387 | if( markup.iType==MUTYPE_FONT ){ |
| 1388 | startAutoParagraph(p); |
| 1389 | }else if( markup.iType==MUTYPE_BLOCK ){ |
| 1390 | p->wantAutoParagraph = 0; |
| 1391 | } |
| 1392 | if( (markup.iType & MUTYPE_STACK )!=0 ){ |
| 1393 | pushStack(p, markup.iCode); |
| 1394 | } |
| 1395 | renderMarkup(p->pOut, &markup); |
| 1396 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -321,21 +321,21 @@ | |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | ** Token types |
| 325 | */ |
| 326 | #define TOKEN_MARKUP 1 /* <...> */ |
| 327 | #define TOKEN_CHARACTER 2 /* "&" or "<" not part of markup */ |
| 328 | #define TOKEN_LINK 3 /* [...] */ |
| 329 | #define TOKEN_PARAGRAPH 4 /* blank lines */ |
| 330 | #define TOKEN_NEWLINE 5 /* A single "\n" */ |
| 331 | #define TOKEN_BUL_LI 6 /* " * " */ |
| 332 | #define TOKEN_NUM_LI 7 /* " # " */ |
| 333 | #define TOKEN_ENUM 8 /* " \(?\d+[.)]? " */ |
| 334 | #define TOKEN_INDENT 9 /* " " */ |
| 335 | #define TOKEN_RAW 10 /* Output exactly (used when wiki-use-html==1) */ |
| 336 | #define TOKEN_TEXT 11 /* None of the above */ |
| 337 | |
| 338 | /* |
| 339 | ** State flags |
| 340 | */ |
| 341 | #define AT_NEWLINE 0x001 /* At start of a line */ |
| @@ -745,10 +745,13 @@ | |
| 745 | static void renderMarkup(Blob *pOut, ParsedMarkup *p){ |
| 746 | int i; |
| 747 | if( p->endTag ){ |
| 748 | blob_appendf(pOut, "</%s>", aMarkup[p->iCode].zName); |
| 749 | }else{ |
| 750 | /* Close active paragraph for several elements, which are not allowed |
| 751 | ** in paragraphs in XHTML. |
| 752 | */ |
| 753 | blob_appendf(pOut, "<%s", aMarkup[p->iCode].zName); |
| 754 | for(i=0; i<p->nAttr; i++){ |
| 755 | blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iACode].zName); |
| 756 | if( p->aAttr[i].zValue ){ |
| 757 | const char *zVal = p->aAttr[i].zValue; |
| @@ -756,10 +759,13 @@ | |
| 759 | blob_appendf(pOut, "=\"%s%s\"", g.zBaseURL, zVal); |
| 760 | }else{ |
| 761 | blob_appendf(pOut, "=\"%s\"", zVal); |
| 762 | } |
| 763 | } |
| 764 | } |
| 765 | if (p->iType & MUTYPE_SINGLE){ |
| 766 | blob_append(pOut, " /", 2); |
| 767 | } |
| 768 | blob_append(pOut, ">", 1); |
| 769 | } |
| 770 | } |
| 771 | |
| @@ -885,12 +891,13 @@ | |
| 891 | |
| 892 | /* |
| 893 | ** Begin a new paragraph if that something that is needed. |
| 894 | */ |
| 895 | static void startAutoParagraph(Renderer *p){ |
| 896 | if( p->wantAutoParagraph==0 ) return; |
| 897 | if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return; |
| 898 | blob_appendf(p->pOut, "<p type=\"auto\">", -1); |
| 899 | pushStack(p, MARKUP_P); |
| 900 | p->wantAutoParagraph = 0; |
| 901 | p->inAutoParagraph = 1; |
| 902 | } |
| 903 | |
| @@ -1019,17 +1026,18 @@ | |
| 1026 | /* Special display processing for tickets. Display the hyperlink |
| 1027 | ** as crossed out if the ticket is closed. |
| 1028 | */ |
| 1029 | if( isClosed ){ |
| 1030 | if( g.okHistory ){ |
| 1031 | blob_appendf(p->pOut, |
| 1032 | "<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">", |
| 1033 | g.zBaseURL, zTarget |
| 1034 | ); |
| 1035 | zTerm = "</span></a>"; |
| 1036 | }else{ |
| 1037 | blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">"); |
| 1038 | zTerm = "</span>"; |
| 1039 | } |
| 1040 | }else{ |
| 1041 | if( g.okHistory ){ |
| 1042 | blob_appendf(p->pOut,"<a href=\"%s/info/%s\">", |
| 1043 | g.zBaseURL, zTarget |
| @@ -1133,10 +1141,11 @@ | |
| 1141 | }else{ |
| 1142 | if( p->wikiList!=MARKUP_UL ){ |
| 1143 | if( p->wikiList ){ |
| 1144 | popStackToTag(p, p->wikiList); |
| 1145 | } |
| 1146 | endAutoParagraph(p); |
| 1147 | pushStack(p, MARKUP_UL); |
| 1148 | blob_append(p->pOut, "<ul>", 4); |
| 1149 | p->wikiList = MARKUP_UL; |
| 1150 | } |
| 1151 | popStackToTag(p, MARKUP_LI); |
| @@ -1152,10 +1161,11 @@ | |
| 1161 | }else{ |
| 1162 | if( p->wikiList!=MARKUP_OL ){ |
| 1163 | if( p->wikiList ){ |
| 1164 | popStackToTag(p, p->wikiList); |
| 1165 | } |
| 1166 | endAutoParagraph(p); |
| 1167 | pushStack(p, MARKUP_OL); |
| 1168 | blob_append(p->pOut, "<ol>", 4); |
| 1169 | p->wikiList = MARKUP_OL; |
| 1170 | } |
| 1171 | popStackToTag(p, MARKUP_LI); |
| @@ -1171,10 +1181,11 @@ | |
| 1181 | }else{ |
| 1182 | if( p->wikiList!=MARKUP_OL ){ |
| 1183 | if( p->wikiList ){ |
| 1184 | popStackToTag(p, p->wikiList); |
| 1185 | } |
| 1186 | endAutoParagraph(p); |
| 1187 | pushStack(p, MARKUP_OL); |
| 1188 | blob_append(p->pOut, "<ol>", 4); |
| 1189 | p->wikiList = MARKUP_OL; |
| 1190 | } |
| 1191 | popStackToTag(p, MARKUP_LI); |
| @@ -1233,11 +1244,13 @@ | |
| 1244 | p->state = savedState; |
| 1245 | blob_append(p->pOut, zClose, -1); |
| 1246 | break; |
| 1247 | } |
| 1248 | case TOKEN_TEXT: { |
| 1249 | int i; |
| 1250 | for(i=0; i<n && isspace(z[i]); i++){} |
| 1251 | if( i<n ) startAutoParagraph(p); |
| 1252 | blob_append(p->pOut, z, n); |
| 1253 | break; |
| 1254 | } |
| 1255 | case TOKEN_RAW: { |
| 1256 | blob_append(p->pOut, z, n); |
| @@ -1347,16 +1360,19 @@ | |
| 1360 | blob_appendf(p->pOut, "<pre name='code' class='%s'>", |
| 1361 | markup.aAttr[vAttrIdx].zValue); |
| 1362 | vAttrDidAppend=1; |
| 1363 | } |
| 1364 | } |
| 1365 | if( !vAttrDidAppend ) { |
| 1366 | endAutoParagraph(p); |
| 1367 | blob_append(p->pOut, "<pre class='verbatim'>",-1); |
| 1368 | } |
| 1369 | p->wantAutoParagraph = 0; |
| 1370 | }else |
| 1371 | if( markup.iType==MUTYPE_LI ){ |
| 1372 | if( backupToType(p, MUTYPE_LIST)==0 ){ |
| 1373 | endAutoParagraph(p); |
| 1374 | pushStack(p, MARKUP_UL); |
| 1375 | blob_append(p->pOut, "<ul>", 4); |
| 1376 | } |
| 1377 | pushStack(p, MARKUP_LI); |
| 1378 | renderMarkup(p->pOut, &markup); |
| @@ -1384,12 +1400,22 @@ | |
| 1400 | pushStack(p, markup.iCode); |
| 1401 | }else |
| 1402 | { |
| 1403 | if( markup.iType==MUTYPE_FONT ){ |
| 1404 | startAutoParagraph(p); |
| 1405 | }else if( markup.iType==MUTYPE_BLOCK || markup.iType==MUTYPE_LIST ){ |
| 1406 | p->wantAutoParagraph = 0; |
| 1407 | } |
| 1408 | if( markup.iCode==MARKUP_HR |
| 1409 | || markup.iCode==MARKUP_H1 |
| 1410 | || markup.iCode==MARKUP_H2 |
| 1411 | || markup.iCode==MARKUP_H3 |
| 1412 | || markup.iCode==MARKUP_H4 |
| 1413 | || markup.iCode==MARKUP_H5 |
| 1414 | || markup.iCode==MARKUP_P |
| 1415 | ){ |
| 1416 | endAutoParagraph(p); |
| 1417 | } |
| 1418 | if( (markup.iType & MUTYPE_STACK )!=0 ){ |
| 1419 | pushStack(p, markup.iCode); |
| 1420 | } |
| 1421 | renderMarkup(p->pOut, &markup); |
| 1422 |