Fossil SCM
Changes anchor tags (<a>) so that the href= attribute can be set by javascript rather than by HTML. This is to make it harder for spiders to follow the hyperlinks to every diff and annotation in the project history. It all seems to work, but it needs further testing and review before going live.
Commit
8ae52fc4183f3100ce47ca69f1545e3425001f28
Parent
f9711803e22ee88…
17 files changed
+7
-9
+21
-20
+3
-3
+6
-13
+4
-9
+60
-75
+6
-4
+9
+7
+10
-11
+18
-9
+86
+2
-2
+32
-51
+8
-8
+18
-20
+8
-10
+7
-9
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -321,18 +321,18 @@ | ||
| 321 | 321 | style_submenu_element("All", "All", "brlist?all"); |
| 322 | 322 | } |
| 323 | 323 | login_anonymous_available(); |
| 324 | 324 | style_sidebox_begin("Nomenclature:", "33%"); |
| 325 | 325 | @ <ol> |
| 326 | - @ <li> An <div class="sideboxDescribed"><a href="brlist"> | |
| 326 | + @ <li> An <div class="sideboxDescribed">%z(href("brlist")) | |
| 327 | 327 | @ open branch</a></div> is a branch that has one or |
| 328 | - @ more <a href="leaves">open leaves.</a> | |
| 328 | + @ more %z(href("leaves"))open leaves.</a> | |
| 329 | 329 | @ The presence of open leaves presumably means |
| 330 | 330 | @ that the branch is still being extended with new check-ins.</li> |
| 331 | - @ <li> A <div class="sideboxDescribed"><a href="brlist?closed"> | |
| 331 | + @ <li> A <div class="sideboxDescribed">%z(href("brlist?closed")) | |
| 332 | 332 | @ closed branch</a></div> is a branch with only |
| 333 | - @ <div class="sideboxDescribed"><a href="leaves?closed"> | |
| 333 | + @ <div class="sideboxDescribed">%z(href("leaves?closed")) | |
| 334 | 334 | @ closed leaves</a></div>. |
| 335 | 335 | @ Closed branches are fixed and do not change (unless they are first |
| 336 | 336 | @ reopened)</li> |
| 337 | 337 | @ </ol> |
| 338 | 338 | style_sidebox_end(); |
| @@ -356,14 +356,12 @@ | ||
| 356 | 356 | } |
| 357 | 357 | if( colorTest ){ |
| 358 | 358 | const char *zColor = hash_color(zBr); |
| 359 | 359 | @ <li><span style="background-color: %s(zColor)"> |
| 360 | 360 | @ %h(zBr) → %s(zColor)</span></li> |
| 361 | - }else if( g.perm.History ){ | |
| 362 | - @ <li><a href="%s(g.zTop)/timeline?r=%T(zBr)")>%h(zBr)</a></li> | |
| 363 | 361 | }else{ |
| 364 | - @ <li><b>%h(zBr)</b></li> | |
| 362 | + @ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li> | |
| 365 | 363 | } |
| 366 | 364 | } |
| 367 | 365 | if( cnt ){ |
| 368 | 366 | @ </ul> |
| 369 | 367 | } |
| @@ -382,11 +380,11 @@ | ||
| 382 | 380 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 383 | 381 | ** to the end of the line. |
| 384 | 382 | */ |
| 385 | 383 | static void brtimeline_extra(int rid){ |
| 386 | 384 | Stmt q; |
| 387 | - if( !g.perm.History ) return; | |
| 385 | + if( !g.perm.Hyperlink ) return; | |
| 388 | 386 | db_prepare(&q, |
| 389 | 387 | "SELECT substr(tagname,5) FROM tagxref, tag" |
| 390 | 388 | " WHERE tagxref.rid=%d" |
| 391 | 389 | " AND tagxref.tagid=tag.tagid" |
| 392 | 390 | " AND tagxref.tagtype>0" |
| @@ -393,11 +391,11 @@ | ||
| 393 | 391 | " AND tag.tagname GLOB 'sym-*'", |
| 394 | 392 | rid |
| 395 | 393 | ); |
| 396 | 394 | while( db_step(&q)==SQLITE_ROW ){ |
| 397 | 395 | const char *zTagName = db_column_text(&q, 0); |
| 398 | - @ <a href="%s(g.zTop)/timeline?r=%T(zTagName)">[timeline]</a> | |
| 396 | + @ %z(href("%R/timeline?r=%T",zTagName))[timeline]</a> | |
| 399 | 397 | } |
| 400 | 398 | db_finalize(&q); |
| 401 | 399 | } |
| 402 | 400 | |
| 403 | 401 | /* |
| 404 | 402 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -321,18 +321,18 @@ | |
| 321 | style_submenu_element("All", "All", "brlist?all"); |
| 322 | } |
| 323 | login_anonymous_available(); |
| 324 | style_sidebox_begin("Nomenclature:", "33%"); |
| 325 | @ <ol> |
| 326 | @ <li> An <div class="sideboxDescribed"><a href="brlist"> |
| 327 | @ open branch</a></div> is a branch that has one or |
| 328 | @ more <a href="leaves">open leaves.</a> |
| 329 | @ The presence of open leaves presumably means |
| 330 | @ that the branch is still being extended with new check-ins.</li> |
| 331 | @ <li> A <div class="sideboxDescribed"><a href="brlist?closed"> |
| 332 | @ closed branch</a></div> is a branch with only |
| 333 | @ <div class="sideboxDescribed"><a href="leaves?closed"> |
| 334 | @ closed leaves</a></div>. |
| 335 | @ Closed branches are fixed and do not change (unless they are first |
| 336 | @ reopened)</li> |
| 337 | @ </ol> |
| 338 | style_sidebox_end(); |
| @@ -356,14 +356,12 @@ | |
| 356 | } |
| 357 | if( colorTest ){ |
| 358 | const char *zColor = hash_color(zBr); |
| 359 | @ <li><span style="background-color: %s(zColor)"> |
| 360 | @ %h(zBr) → %s(zColor)</span></li> |
| 361 | }else if( g.perm.History ){ |
| 362 | @ <li><a href="%s(g.zTop)/timeline?r=%T(zBr)")>%h(zBr)</a></li> |
| 363 | }else{ |
| 364 | @ <li><b>%h(zBr)</b></li> |
| 365 | } |
| 366 | } |
| 367 | if( cnt ){ |
| 368 | @ </ul> |
| 369 | } |
| @@ -382,11 +380,11 @@ | |
| 382 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 383 | ** to the end of the line. |
| 384 | */ |
| 385 | static void brtimeline_extra(int rid){ |
| 386 | Stmt q; |
| 387 | if( !g.perm.History ) return; |
| 388 | db_prepare(&q, |
| 389 | "SELECT substr(tagname,5) FROM tagxref, tag" |
| 390 | " WHERE tagxref.rid=%d" |
| 391 | " AND tagxref.tagid=tag.tagid" |
| 392 | " AND tagxref.tagtype>0" |
| @@ -393,11 +391,11 @@ | |
| 393 | " AND tag.tagname GLOB 'sym-*'", |
| 394 | rid |
| 395 | ); |
| 396 | while( db_step(&q)==SQLITE_ROW ){ |
| 397 | const char *zTagName = db_column_text(&q, 0); |
| 398 | @ <a href="%s(g.zTop)/timeline?r=%T(zTagName)">[timeline]</a> |
| 399 | } |
| 400 | db_finalize(&q); |
| 401 | } |
| 402 | |
| 403 | /* |
| 404 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -321,18 +321,18 @@ | |
| 321 | style_submenu_element("All", "All", "brlist?all"); |
| 322 | } |
| 323 | login_anonymous_available(); |
| 324 | style_sidebox_begin("Nomenclature:", "33%"); |
| 325 | @ <ol> |
| 326 | @ <li> An <div class="sideboxDescribed">%z(href("brlist")) |
| 327 | @ open branch</a></div> is a branch that has one or |
| 328 | @ more %z(href("leaves"))open leaves.</a> |
| 329 | @ The presence of open leaves presumably means |
| 330 | @ that the branch is still being extended with new check-ins.</li> |
| 331 | @ <li> A <div class="sideboxDescribed">%z(href("brlist?closed")) |
| 332 | @ closed branch</a></div> is a branch with only |
| 333 | @ <div class="sideboxDescribed">%z(href("leaves?closed")) |
| 334 | @ closed leaves</a></div>. |
| 335 | @ Closed branches are fixed and do not change (unless they are first |
| 336 | @ reopened)</li> |
| 337 | @ </ol> |
| 338 | style_sidebox_end(); |
| @@ -356,14 +356,12 @@ | |
| 356 | } |
| 357 | if( colorTest ){ |
| 358 | const char *zColor = hash_color(zBr); |
| 359 | @ <li><span style="background-color: %s(zColor)"> |
| 360 | @ %h(zBr) → %s(zColor)</span></li> |
| 361 | }else{ |
| 362 | @ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li> |
| 363 | } |
| 364 | } |
| 365 | if( cnt ){ |
| 366 | @ </ul> |
| 367 | } |
| @@ -382,11 +380,11 @@ | |
| 380 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 381 | ** to the end of the line. |
| 382 | */ |
| 383 | static void brtimeline_extra(int rid){ |
| 384 | Stmt q; |
| 385 | if( !g.perm.Hyperlink ) return; |
| 386 | db_prepare(&q, |
| 387 | "SELECT substr(tagname,5) FROM tagxref, tag" |
| 388 | " WHERE tagxref.rid=%d" |
| 389 | " AND tagxref.tagid=tag.tagid" |
| 390 | " AND tagxref.tagtype>0" |
| @@ -393,11 +391,11 @@ | |
| 391 | " AND tag.tagname GLOB 'sym-*'", |
| 392 | rid |
| 393 | ); |
| 394 | while( db_step(&q)==SQLITE_ROW ){ |
| 395 | const char *zTagName = db_column_text(&q, 0); |
| 396 | @ %z(href("%R/timeline?r=%T",zTagName))[timeline]</a> |
| 397 | } |
| 398 | db_finalize(&q); |
| 399 | } |
| 400 | |
| 401 | /* |
| 402 |
+21
-20
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -79,15 +79,17 @@ | ||
| 79 | 79 | |
| 80 | 80 | for(i=0; zPath[i]; i=j){ |
| 81 | 81 | for(j=i; zPath[j] && zPath[j]!='/'; j++){} |
| 82 | 82 | if( zPath[j] && g.perm.History ){ |
| 83 | 83 | if( zCI ){ |
| 84 | - blob_appendf(pOut, "%s<a href=\"%s/dir?ci=%S&name=%#T\">%#h</a>", | |
| 85 | - zSep, g.zTop, zCI, j, zPath, j-i, &zPath[i]); | |
| 84 | + char *zLink = href("%R/dir?ci=%S&name=%#T", zCI, j, zPath); | |
| 85 | + blob_appendf(pOut, "%s%z%#h</a>", | |
| 86 | + zSep, zLink, j-i, &zPath[i]); | |
| 86 | 87 | }else{ |
| 87 | - blob_appendf(pOut, "%s<a href=\"%s/dir?name=%#T\">%#h</a>", | |
| 88 | - zSep, g.zTop, j, zPath, j-i, &zPath[i]); | |
| 88 | + char *zLink = href("%R/dir?name=%#T", j, zPath); | |
| 89 | + blob_appendf(pOut, "%s%z%#h</a>", | |
| 90 | + zSep, zLink, j-i, &zPath[i]); | |
| 89 | 91 | } |
| 90 | 92 | }else{ |
| 91 | 93 | blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]); |
| 92 | 94 | } |
| 93 | 95 | zSep = "/"; |
| @@ -155,39 +157,38 @@ | ||
| 155 | 157 | } |
| 156 | 158 | if( zCI ){ |
| 157 | 159 | char zShort[20]; |
| 158 | 160 | memcpy(zShort, zUuid, 10); |
| 159 | 161 | zShort[10] = 0; |
| 160 | - @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>] | |
| 162 | + @ <h2>Files of check-in [%z(href("vinfo?name=%T",zUuid))%s(zShort)</a>] | |
| 161 | 163 | @ %s(blob_str(&dirname))</h2> |
| 162 | - zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix); | |
| 164 | + zSubdirLink = mprintf("%R/dir?ci=%S&name=%T", zUuid, zPrefix); | |
| 163 | 165 | if( zD ){ |
| 164 | - style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid); | |
| 165 | - style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD); | |
| 166 | + style_submenu_element("Top", "Top", "%R/dir?ci=%S", zUuid); | |
| 167 | + style_submenu_element("All", "All", "%R/dir?name=%t", zD); | |
| 166 | 168 | }else{ |
| 167 | - style_submenu_element("All", "All", "%s/dir", g.zTop); | |
| 169 | + style_submenu_element("All", "All", "%R/dir"); | |
| 168 | 170 | } |
| 169 | 171 | }else{ |
| 170 | 172 | int hasTrunk; |
| 171 | 173 | @ <h2>The union of all files from all check-ins |
| 172 | 174 | @ %s(blob_str(&dirname))</h2> |
| 173 | 175 | hasTrunk = db_exists( |
| 174 | 176 | "SELECT 1 FROM tagxref WHERE tagid=%d AND value='trunk'", |
| 175 | 177 | TAG_BRANCH); |
| 176 | - zSubdirLink = mprintf("%s/dir?name=%T", g.zTop, zPrefix); | |
| 178 | + zSubdirLink = mprintf("%R/dir?name=%T", zPrefix); | |
| 177 | 179 | if( zD ){ |
| 178 | - style_submenu_element("Top", "Top", "%s/dir", g.zTop); | |
| 179 | - style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip", | |
| 180 | - g.zTop, zD); | |
| 180 | + style_submenu_element("Top", "Top", "%R/dir"); | |
| 181 | + style_submenu_element("Tip", "Tip", "%R/dir?name=%t&ci=tip", zD); | |
| 181 | 182 | if( hasTrunk ){ |
| 182 | - style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk", | |
| 183 | - g.zTop,zD); | |
| 183 | + style_submenu_element("Trunk", "Trunk", "%R/dir?name=%t&ci=trunk", | |
| 184 | + zD); | |
| 184 | 185 | } |
| 185 | 186 | }else{ |
| 186 | - style_submenu_element("Tip", "Tip", "%s/dir?ci=tip", g.zTop); | |
| 187 | + style_submenu_element("Tip", "Tip", "%R/dir?ci=tip"); | |
| 187 | 188 | if( hasTrunk ){ |
| 188 | - style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zTop); | |
| 189 | + style_submenu_element("Trunk", "Trunk", "%R/dir?ci=trunk"); | |
| 189 | 190 | } |
| 190 | 191 | } |
| 191 | 192 | } |
| 192 | 193 | |
| 193 | 194 | /* Compute the temporary table "localfiles" containing the names |
| @@ -278,19 +279,19 @@ | ||
| 278 | 279 | } |
| 279 | 280 | i++; |
| 280 | 281 | zFN = db_column_text(&q, 0); |
| 281 | 282 | if( zFN[0]=='/' ){ |
| 282 | 283 | zFN++; |
| 283 | - @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> | |
| 284 | + @ <li>%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li> | |
| 284 | 285 | }else if( zCI ){ |
| 285 | 286 | const char *zUuid = db_column_text(&q, 1); |
| 286 | - @ <li><a href="%s(g.zTop)/artifact/%s(zUuid)">%h(zFN)</a></li> | |
| 287 | + @ <li>%z(href("%R/artifact/%s",zUuid))%h(zFN)</a></li> | |
| 287 | 288 | }else{ |
| 288 | - @ <li><a href="%s(g.zTop)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN) | |
| 289 | + @ <li>%z(href("%R/finfo?name=%T%T",zPrefix,zFN))%h(zFN) | |
| 289 | 290 | @ </a></li> |
| 290 | 291 | } |
| 291 | 292 | } |
| 292 | 293 | db_finalize(&q); |
| 293 | 294 | manifest_destroy(pM); |
| 294 | 295 | @ </ul></td></tr></table> |
| 295 | 296 | style_footer(); |
| 296 | 297 | } |
| 297 | 298 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -79,15 +79,17 @@ | |
| 79 | |
| 80 | for(i=0; zPath[i]; i=j){ |
| 81 | for(j=i; zPath[j] && zPath[j]!='/'; j++){} |
| 82 | if( zPath[j] && g.perm.History ){ |
| 83 | if( zCI ){ |
| 84 | blob_appendf(pOut, "%s<a href=\"%s/dir?ci=%S&name=%#T\">%#h</a>", |
| 85 | zSep, g.zTop, zCI, j, zPath, j-i, &zPath[i]); |
| 86 | }else{ |
| 87 | blob_appendf(pOut, "%s<a href=\"%s/dir?name=%#T\">%#h</a>", |
| 88 | zSep, g.zTop, j, zPath, j-i, &zPath[i]); |
| 89 | } |
| 90 | }else{ |
| 91 | blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]); |
| 92 | } |
| 93 | zSep = "/"; |
| @@ -155,39 +157,38 @@ | |
| 155 | } |
| 156 | if( zCI ){ |
| 157 | char zShort[20]; |
| 158 | memcpy(zShort, zUuid, 10); |
| 159 | zShort[10] = 0; |
| 160 | @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>] |
| 161 | @ %s(blob_str(&dirname))</h2> |
| 162 | zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix); |
| 163 | if( zD ){ |
| 164 | style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid); |
| 165 | style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD); |
| 166 | }else{ |
| 167 | style_submenu_element("All", "All", "%s/dir", g.zTop); |
| 168 | } |
| 169 | }else{ |
| 170 | int hasTrunk; |
| 171 | @ <h2>The union of all files from all check-ins |
| 172 | @ %s(blob_str(&dirname))</h2> |
| 173 | hasTrunk = db_exists( |
| 174 | "SELECT 1 FROM tagxref WHERE tagid=%d AND value='trunk'", |
| 175 | TAG_BRANCH); |
| 176 | zSubdirLink = mprintf("%s/dir?name=%T", g.zTop, zPrefix); |
| 177 | if( zD ){ |
| 178 | style_submenu_element("Top", "Top", "%s/dir", g.zTop); |
| 179 | style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip", |
| 180 | g.zTop, zD); |
| 181 | if( hasTrunk ){ |
| 182 | style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk", |
| 183 | g.zTop,zD); |
| 184 | } |
| 185 | }else{ |
| 186 | style_submenu_element("Tip", "Tip", "%s/dir?ci=tip", g.zTop); |
| 187 | if( hasTrunk ){ |
| 188 | style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zTop); |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | /* Compute the temporary table "localfiles" containing the names |
| @@ -278,19 +279,19 @@ | |
| 278 | } |
| 279 | i++; |
| 280 | zFN = db_column_text(&q, 0); |
| 281 | if( zFN[0]=='/' ){ |
| 282 | zFN++; |
| 283 | @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> |
| 284 | }else if( zCI ){ |
| 285 | const char *zUuid = db_column_text(&q, 1); |
| 286 | @ <li><a href="%s(g.zTop)/artifact/%s(zUuid)">%h(zFN)</a></li> |
| 287 | }else{ |
| 288 | @ <li><a href="%s(g.zTop)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN) |
| 289 | @ </a></li> |
| 290 | } |
| 291 | } |
| 292 | db_finalize(&q); |
| 293 | manifest_destroy(pM); |
| 294 | @ </ul></td></tr></table> |
| 295 | style_footer(); |
| 296 | } |
| 297 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -79,15 +79,17 @@ | |
| 79 | |
| 80 | for(i=0; zPath[i]; i=j){ |
| 81 | for(j=i; zPath[j] && zPath[j]!='/'; j++){} |
| 82 | if( zPath[j] && g.perm.History ){ |
| 83 | if( zCI ){ |
| 84 | char *zLink = href("%R/dir?ci=%S&name=%#T", zCI, j, zPath); |
| 85 | blob_appendf(pOut, "%s%z%#h</a>", |
| 86 | zSep, zLink, j-i, &zPath[i]); |
| 87 | }else{ |
| 88 | char *zLink = href("%R/dir?name=%#T", j, zPath); |
| 89 | blob_appendf(pOut, "%s%z%#h</a>", |
| 90 | zSep, zLink, j-i, &zPath[i]); |
| 91 | } |
| 92 | }else{ |
| 93 | blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]); |
| 94 | } |
| 95 | zSep = "/"; |
| @@ -155,39 +157,38 @@ | |
| 157 | } |
| 158 | if( zCI ){ |
| 159 | char zShort[20]; |
| 160 | memcpy(zShort, zUuid, 10); |
| 161 | zShort[10] = 0; |
| 162 | @ <h2>Files of check-in [%z(href("vinfo?name=%T",zUuid))%s(zShort)</a>] |
| 163 | @ %s(blob_str(&dirname))</h2> |
| 164 | zSubdirLink = mprintf("%R/dir?ci=%S&name=%T", zUuid, zPrefix); |
| 165 | if( zD ){ |
| 166 | style_submenu_element("Top", "Top", "%R/dir?ci=%S", zUuid); |
| 167 | style_submenu_element("All", "All", "%R/dir?name=%t", zD); |
| 168 | }else{ |
| 169 | style_submenu_element("All", "All", "%R/dir"); |
| 170 | } |
| 171 | }else{ |
| 172 | int hasTrunk; |
| 173 | @ <h2>The union of all files from all check-ins |
| 174 | @ %s(blob_str(&dirname))</h2> |
| 175 | hasTrunk = db_exists( |
| 176 | "SELECT 1 FROM tagxref WHERE tagid=%d AND value='trunk'", |
| 177 | TAG_BRANCH); |
| 178 | zSubdirLink = mprintf("%R/dir?name=%T", zPrefix); |
| 179 | if( zD ){ |
| 180 | style_submenu_element("Top", "Top", "%R/dir"); |
| 181 | style_submenu_element("Tip", "Tip", "%R/dir?name=%t&ci=tip", zD); |
| 182 | if( hasTrunk ){ |
| 183 | style_submenu_element("Trunk", "Trunk", "%R/dir?name=%t&ci=trunk", |
| 184 | zD); |
| 185 | } |
| 186 | }else{ |
| 187 | style_submenu_element("Tip", "Tip", "%R/dir?ci=tip"); |
| 188 | if( hasTrunk ){ |
| 189 | style_submenu_element("Trunk", "Trunk", "%R/dir?ci=trunk"); |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | /* Compute the temporary table "localfiles" containing the names |
| @@ -278,19 +279,19 @@ | |
| 279 | } |
| 280 | i++; |
| 281 | zFN = db_column_text(&q, 0); |
| 282 | if( zFN[0]=='/' ){ |
| 283 | zFN++; |
| 284 | @ <li>%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li> |
| 285 | }else if( zCI ){ |
| 286 | const char *zUuid = db_column_text(&q, 1); |
| 287 | @ <li>%z(href("%R/artifact/%s",zUuid))%h(zFN)</a></li> |
| 288 | }else{ |
| 289 | @ <li>%z(href("%R/finfo?name=%T%T",zPrefix,zFN))%h(zFN) |
| 290 | @ </a></li> |
| 291 | } |
| 292 | } |
| 293 | db_finalize(&q); |
| 294 | manifest_destroy(pM); |
| 295 | @ </ul></td></tr></table> |
| 296 | style_footer(); |
| 297 | } |
| 298 |
+3
-3
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -1778,12 +1778,12 @@ | ||
| 1778 | 1778 | const char *zUuid = db_column_text(&q, 1); |
| 1779 | 1779 | const char *zDate = db_column_text(&q, 2); |
| 1780 | 1780 | const char *zUser = db_column_text(&q, 3); |
| 1781 | 1781 | if( webLabel ){ |
| 1782 | 1782 | zLabel = mprintf( |
| 1783 | - "<a href='%s/info/%s' target='infowindow'>%.10s</a> %s %13.13s", | |
| 1784 | - g.zTop, zUuid, zUuid, zDate, zUser | |
| 1783 | + "<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s", | |
| 1784 | + zUuid, zUuid, zDate, zUser | |
| 1785 | 1785 | ); |
| 1786 | 1786 | }else{ |
| 1787 | 1787 | zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser); |
| 1788 | 1788 | } |
| 1789 | 1789 | p->nVers++; |
| @@ -1821,11 +1821,11 @@ | ||
| 1821 | 1821 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 1822 | 1822 | fossil_redirect_home(); |
| 1823 | 1823 | } |
| 1824 | 1824 | style_header("File Annotation"); |
| 1825 | 1825 | if( P("filevers") ) annFlags |= ANN_FILE_VERS; |
| 1826 | - annotate_file(&ann, fnid, mid, g.perm.History, iLimit, annFlags); | |
| 1826 | + annotate_file(&ann, fnid, mid, g.perm.Hyperlink, iLimit, annFlags); | |
| 1827 | 1827 | if( P("log") ){ |
| 1828 | 1828 | int i; |
| 1829 | 1829 | @ <h2>Versions analyzed:</h2> |
| 1830 | 1830 | @ <ol> |
| 1831 | 1831 | for(i=0; i<ann.nVers; i++){ |
| 1832 | 1832 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1778,12 +1778,12 @@ | |
| 1778 | const char *zUuid = db_column_text(&q, 1); |
| 1779 | const char *zDate = db_column_text(&q, 2); |
| 1780 | const char *zUser = db_column_text(&q, 3); |
| 1781 | if( webLabel ){ |
| 1782 | zLabel = mprintf( |
| 1783 | "<a href='%s/info/%s' target='infowindow'>%.10s</a> %s %13.13s", |
| 1784 | g.zTop, zUuid, zUuid, zDate, zUser |
| 1785 | ); |
| 1786 | }else{ |
| 1787 | zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser); |
| 1788 | } |
| 1789 | p->nVers++; |
| @@ -1821,11 +1821,11 @@ | |
| 1821 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 1822 | fossil_redirect_home(); |
| 1823 | } |
| 1824 | style_header("File Annotation"); |
| 1825 | if( P("filevers") ) annFlags |= ANN_FILE_VERS; |
| 1826 | annotate_file(&ann, fnid, mid, g.perm.History, iLimit, annFlags); |
| 1827 | if( P("log") ){ |
| 1828 | int i; |
| 1829 | @ <h2>Versions analyzed:</h2> |
| 1830 | @ <ol> |
| 1831 | for(i=0; i<ann.nVers; i++){ |
| 1832 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1778,12 +1778,12 @@ | |
| 1778 | const char *zUuid = db_column_text(&q, 1); |
| 1779 | const char *zDate = db_column_text(&q, 2); |
| 1780 | const char *zUser = db_column_text(&q, 3); |
| 1781 | if( webLabel ){ |
| 1782 | zLabel = mprintf( |
| 1783 | "<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s", |
| 1784 | zUuid, zUuid, zDate, zUser |
| 1785 | ); |
| 1786 | }else{ |
| 1787 | zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser); |
| 1788 | } |
| 1789 | p->nVers++; |
| @@ -1821,11 +1821,11 @@ | |
| 1821 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 1822 | fossil_redirect_home(); |
| 1823 | } |
| 1824 | style_header("File Annotation"); |
| 1825 | if( P("filevers") ) annFlags |= ANN_FILE_VERS; |
| 1826 | annotate_file(&ann, fnid, mid, g.perm.Hyperlink, iLimit, annFlags); |
| 1827 | if( P("log") ){ |
| 1828 | int i; |
| 1829 | @ <h2>Versions analyzed:</h2> |
| 1830 | @ <ol> |
| 1831 | for(i=0; i<ann.nVers; i++){ |
| 1832 |
+6
-13
| --- src/event.c | ||
| +++ src/event.c | ||
| @@ -31,20 +31,13 @@ | ||
| 31 | 31 | /* |
| 32 | 32 | ** Output a hyperlink to an event given its tagid. |
| 33 | 33 | */ |
| 34 | 34 | void hyperlink_to_event_tagid(int tagid){ |
| 35 | 35 | char *zEventId; |
| 36 | - char zShort[12]; | |
| 37 | - | |
| 38 | 36 | zEventId = db_text(0, "SELECT substr(tagname, 7) FROM tag WHERE tagid=%d", |
| 39 | 37 | tagid); |
| 40 | - sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zEventId); | |
| 41 | - if( g.perm.History ){ | |
| 42 | - @ [<a href="%s(g.zTop)/event?name=%s(zEventId)">%s(zShort)</a>] | |
| 43 | - }else{ | |
| 44 | - @ [%s(zShort)] | |
| 45 | - } | |
| 38 | + @ [%z(href("%R/event/%s",zEventId))%S(zEventId)</a>] | |
| 46 | 39 | free(zEventId); |
| 47 | 40 | } |
| 48 | 41 | |
| 49 | 42 | /* |
| 50 | 43 | ** WEBPAGE: event |
| @@ -130,11 +123,11 @@ | ||
| 130 | 123 | g.zTop, zEventId); |
| 131 | 124 | } |
| 132 | 125 | zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate); |
| 133 | 126 | style_submenu_element("Context", "Context", "%s/timeline?c=%T", |
| 134 | 127 | g.zTop, zETime); |
| 135 | - if( g.perm.History ){ | |
| 128 | + if( g.perm.Hyperlink ){ | |
| 136 | 129 | if( showDetail ){ |
| 137 | 130 | style_submenu_element("Plain", "Plain", "%s/event?name=%s&aid=%s", |
| 138 | 131 | g.zTop, zEventId, zUuid); |
| 139 | 132 | if( nextRid ){ |
| 140 | 133 | char *zNext; |
| @@ -157,20 +150,20 @@ | ||
| 157 | 150 | "%s/event?name=%s&aid=%s&detail=1", |
| 158 | 151 | g.zTop, zEventId, zUuid); |
| 159 | 152 | } |
| 160 | 153 | } |
| 161 | 154 | |
| 162 | - if( showDetail && g.perm.History ){ | |
| 155 | + if( showDetail && g.perm.Hyperlink ){ | |
| 163 | 156 | int i; |
| 164 | 157 | const char *zClr = 0; |
| 165 | 158 | Blob comment; |
| 166 | 159 | |
| 167 | 160 | zATime = db_text(0, "SELECT datetime(%.17g)", pEvent->rDate); |
| 168 | - @ <p>Event [<a href="%s(g.zTop)/artifact/%s(zUuid)">%S(zUuid)</a>] at | |
| 169 | - @ [<a href="%s(g.zTop)/timeline?c=%T(zETime)">%s(zETime)</a>] | |
| 161 | + @ <p>Event [%z(href("%R/artifact/%s",zUuid))%S(zUuid)</a>] at | |
| 162 | + @ [%z(href("%R/timeline?c=%T",zETime))%s(zETime)</a>] | |
| 170 | 163 | @ entered by user <b>%h(pEvent->zUser)</b> on |
| 171 | - @ [<a href="%s(g.zTop)/timeline?c=%T(zATime)">%s(zATime)</a>]:</p> | |
| 164 | + @ [%z(href("%R/timeline?c=%T",zATime))%s(zATime)</a>]:</p> | |
| 172 | 165 | @ <blockquote> |
| 173 | 166 | for(i=0; i<pEvent->nTag; i++){ |
| 174 | 167 | if( fossil_strcmp(pEvent->aTag[i].zName,"+bgcolor")==0 ){ |
| 175 | 168 | zClr = pEvent->aTag[i].zValue; |
| 176 | 169 | } |
| 177 | 170 |
| --- src/event.c | |
| +++ src/event.c | |
| @@ -31,20 +31,13 @@ | |
| 31 | /* |
| 32 | ** Output a hyperlink to an event given its tagid. |
| 33 | */ |
| 34 | void hyperlink_to_event_tagid(int tagid){ |
| 35 | char *zEventId; |
| 36 | char zShort[12]; |
| 37 | |
| 38 | zEventId = db_text(0, "SELECT substr(tagname, 7) FROM tag WHERE tagid=%d", |
| 39 | tagid); |
| 40 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zEventId); |
| 41 | if( g.perm.History ){ |
| 42 | @ [<a href="%s(g.zTop)/event?name=%s(zEventId)">%s(zShort)</a>] |
| 43 | }else{ |
| 44 | @ [%s(zShort)] |
| 45 | } |
| 46 | free(zEventId); |
| 47 | } |
| 48 | |
| 49 | /* |
| 50 | ** WEBPAGE: event |
| @@ -130,11 +123,11 @@ | |
| 130 | g.zTop, zEventId); |
| 131 | } |
| 132 | zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate); |
| 133 | style_submenu_element("Context", "Context", "%s/timeline?c=%T", |
| 134 | g.zTop, zETime); |
| 135 | if( g.perm.History ){ |
| 136 | if( showDetail ){ |
| 137 | style_submenu_element("Plain", "Plain", "%s/event?name=%s&aid=%s", |
| 138 | g.zTop, zEventId, zUuid); |
| 139 | if( nextRid ){ |
| 140 | char *zNext; |
| @@ -157,20 +150,20 @@ | |
| 157 | "%s/event?name=%s&aid=%s&detail=1", |
| 158 | g.zTop, zEventId, zUuid); |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | if( showDetail && g.perm.History ){ |
| 163 | int i; |
| 164 | const char *zClr = 0; |
| 165 | Blob comment; |
| 166 | |
| 167 | zATime = db_text(0, "SELECT datetime(%.17g)", pEvent->rDate); |
| 168 | @ <p>Event [<a href="%s(g.zTop)/artifact/%s(zUuid)">%S(zUuid)</a>] at |
| 169 | @ [<a href="%s(g.zTop)/timeline?c=%T(zETime)">%s(zETime)</a>] |
| 170 | @ entered by user <b>%h(pEvent->zUser)</b> on |
| 171 | @ [<a href="%s(g.zTop)/timeline?c=%T(zATime)">%s(zATime)</a>]:</p> |
| 172 | @ <blockquote> |
| 173 | for(i=0; i<pEvent->nTag; i++){ |
| 174 | if( fossil_strcmp(pEvent->aTag[i].zName,"+bgcolor")==0 ){ |
| 175 | zClr = pEvent->aTag[i].zValue; |
| 176 | } |
| 177 |
| --- src/event.c | |
| +++ src/event.c | |
| @@ -31,20 +31,13 @@ | |
| 31 | /* |
| 32 | ** Output a hyperlink to an event given its tagid. |
| 33 | */ |
| 34 | void hyperlink_to_event_tagid(int tagid){ |
| 35 | char *zEventId; |
| 36 | zEventId = db_text(0, "SELECT substr(tagname, 7) FROM tag WHERE tagid=%d", |
| 37 | tagid); |
| 38 | @ [%z(href("%R/event/%s",zEventId))%S(zEventId)</a>] |
| 39 | free(zEventId); |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | ** WEBPAGE: event |
| @@ -130,11 +123,11 @@ | |
| 123 | g.zTop, zEventId); |
| 124 | } |
| 125 | zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate); |
| 126 | style_submenu_element("Context", "Context", "%s/timeline?c=%T", |
| 127 | g.zTop, zETime); |
| 128 | if( g.perm.Hyperlink ){ |
| 129 | if( showDetail ){ |
| 130 | style_submenu_element("Plain", "Plain", "%s/event?name=%s&aid=%s", |
| 131 | g.zTop, zEventId, zUuid); |
| 132 | if( nextRid ){ |
| 133 | char *zNext; |
| @@ -157,20 +150,20 @@ | |
| 150 | "%s/event?name=%s&aid=%s&detail=1", |
| 151 | g.zTop, zEventId, zUuid); |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | if( showDetail && g.perm.Hyperlink ){ |
| 156 | int i; |
| 157 | const char *zClr = 0; |
| 158 | Blob comment; |
| 159 | |
| 160 | zATime = db_text(0, "SELECT datetime(%.17g)", pEvent->rDate); |
| 161 | @ <p>Event [%z(href("%R/artifact/%s",zUuid))%S(zUuid)</a>] at |
| 162 | @ [%z(href("%R/timeline?c=%T",zETime))%s(zETime)</a>] |
| 163 | @ entered by user <b>%h(pEvent->zUser)</b> on |
| 164 | @ [%z(href("%R/timeline?c=%T",zATime))%s(zATime)</a>]:</p> |
| 165 | @ <blockquote> |
| 166 | for(i=0; i<pEvent->nTag; i++){ |
| 167 | if( fossil_strcmp(pEvent->aTag[i].zName,"+bgcolor")==0 ){ |
| 168 | zClr = pEvent->aTag[i].zValue; |
| 169 | } |
| 170 |
+4
-9
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -305,26 +305,21 @@ | ||
| 305 | 305 | @ </td></tr> |
| 306 | 306 | } |
| 307 | 307 | memcpy(zTime, &zDate[11], 5); |
| 308 | 308 | zTime[5] = 0; |
| 309 | 309 | @ <tr><td class="timelineTime"> |
| 310 | - @ <a href="%s(g.zTop)/timeline?c=%t(zDate)">%s(zTime)</a></td> | |
| 310 | + @ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td> | |
| 311 | 311 | @ <td class="timelineGraph"><div id="m%d(gidx)"></div></td> |
| 312 | 312 | if( zBgClr && zBgClr[0] ){ |
| 313 | 313 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 314 | 314 | }else{ |
| 315 | 315 | @ <td class="timelineTableCell"> |
| 316 | 316 | } |
| 317 | 317 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); |
| 318 | 318 | sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); |
| 319 | 319 | if( zUuid ){ |
| 320 | - if( g.perm.History ){ | |
| 321 | - @ <a href="%s(g.zTop)/artifact/%s(zUuid)">[%S(zUuid)]</a> | |
| 322 | - }else{ | |
| 323 | - @ [%S(zUuid)] | |
| 324 | - } | |
| 325 | - @ part of check-in | |
| 320 | + @ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> part of check-in | |
| 326 | 321 | }else{ |
| 327 | 322 | @ <b>Deleted</b> by check-in |
| 328 | 323 | } |
| 329 | 324 | hyperlink_to_uuid(zShortCkin); |
| 330 | 325 | @ %h(zCom) (user: |
| @@ -331,13 +326,13 @@ | ||
| 331 | 326 | hyperlink_to_user(zUser, zDate, ""); |
| 332 | 327 | @ branch: %h(zBr)) |
| 333 | 328 | if( g.perm.History && zUuid ){ |
| 334 | 329 | const char *z = zFilename; |
| 335 | 330 | if( fpid ){ |
| 336 | - @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&v2=%s(zUuid)">[diff]</a> | |
| 331 | + @ %z(href("%R/fdiff?v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> | |
| 337 | 332 | } |
| 338 | - @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(z)"> | |
| 333 | + @ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z)) | |
| 339 | 334 | @ [annotate]</a> |
| 340 | 335 | } |
| 341 | 336 | @ </td></tr> |
| 342 | 337 | } |
| 343 | 338 | db_finalize(&q); |
| 344 | 339 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -305,26 +305,21 @@ | |
| 305 | @ </td></tr> |
| 306 | } |
| 307 | memcpy(zTime, &zDate[11], 5); |
| 308 | zTime[5] = 0; |
| 309 | @ <tr><td class="timelineTime"> |
| 310 | @ <a href="%s(g.zTop)/timeline?c=%t(zDate)">%s(zTime)</a></td> |
| 311 | @ <td class="timelineGraph"><div id="m%d(gidx)"></div></td> |
| 312 | if( zBgClr && zBgClr[0] ){ |
| 313 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 314 | }else{ |
| 315 | @ <td class="timelineTableCell"> |
| 316 | } |
| 317 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); |
| 318 | sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); |
| 319 | if( zUuid ){ |
| 320 | if( g.perm.History ){ |
| 321 | @ <a href="%s(g.zTop)/artifact/%s(zUuid)">[%S(zUuid)]</a> |
| 322 | }else{ |
| 323 | @ [%S(zUuid)] |
| 324 | } |
| 325 | @ part of check-in |
| 326 | }else{ |
| 327 | @ <b>Deleted</b> by check-in |
| 328 | } |
| 329 | hyperlink_to_uuid(zShortCkin); |
| 330 | @ %h(zCom) (user: |
| @@ -331,13 +326,13 @@ | |
| 331 | hyperlink_to_user(zUser, zDate, ""); |
| 332 | @ branch: %h(zBr)) |
| 333 | if( g.perm.History && zUuid ){ |
| 334 | const char *z = zFilename; |
| 335 | if( fpid ){ |
| 336 | @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&v2=%s(zUuid)">[diff]</a> |
| 337 | } |
| 338 | @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(z)"> |
| 339 | @ [annotate]</a> |
| 340 | } |
| 341 | @ </td></tr> |
| 342 | } |
| 343 | db_finalize(&q); |
| 344 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -305,26 +305,21 @@ | |
| 305 | @ </td></tr> |
| 306 | } |
| 307 | memcpy(zTime, &zDate[11], 5); |
| 308 | zTime[5] = 0; |
| 309 | @ <tr><td class="timelineTime"> |
| 310 | @ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td> |
| 311 | @ <td class="timelineGraph"><div id="m%d(gidx)"></div></td> |
| 312 | if( zBgClr && zBgClr[0] ){ |
| 313 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 314 | }else{ |
| 315 | @ <td class="timelineTableCell"> |
| 316 | } |
| 317 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); |
| 318 | sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); |
| 319 | if( zUuid ){ |
| 320 | @ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> part of check-in |
| 321 | }else{ |
| 322 | @ <b>Deleted</b> by check-in |
| 323 | } |
| 324 | hyperlink_to_uuid(zShortCkin); |
| 325 | @ %h(zCom) (user: |
| @@ -331,13 +326,13 @@ | |
| 326 | hyperlink_to_user(zUser, zDate, ""); |
| 327 | @ branch: %h(zBr)) |
| 328 | if( g.perm.History && zUuid ){ |
| 329 | const char *z = zFilename; |
| 330 | if( fpid ){ |
| 331 | @ %z(href("%R/fdiff?v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> |
| 332 | } |
| 333 | @ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z)) |
| 334 | @ [annotate]</a> |
| 335 | } |
| 336 | @ </td></tr> |
| 337 | } |
| 338 | db_finalize(&q); |
| 339 |
+60
-75
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -261,11 +261,11 @@ | ||
| 261 | 261 | @ propagates to descendants |
| 262 | 262 | } |
| 263 | 263 | #if 0 |
| 264 | 264 | if( zValue && fossil_strcmp(zTagname,"branch")==0 ){ |
| 265 | 265 | @ |
| 266 | - @ <a href="%s(g.zTop)/timeline?r=%T(zValue)">branch timeline</a> | |
| 266 | + @ %z(href("%R/timeline?r=%T",zValue))branch timeline</a> | |
| 267 | 267 | } |
| 268 | 268 | #endif |
| 269 | 269 | } |
| 270 | 270 | if( zSrcUuid && zSrcUuid[0] ){ |
| 271 | 271 | if( tagtype==0 ){ |
| @@ -333,11 +333,11 @@ | ||
| 333 | 333 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 334 | 334 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 335 | 335 | int diffFlags, /* Flags for text_diff(). Zero to omit diffs */ |
| 336 | 336 | int mperm /* executable or symlink permission for zNew */ |
| 337 | 337 | ){ |
| 338 | - if( !g.perm.History ){ | |
| 338 | + if( !g.perm.Hyperlink ){ | |
| 339 | 339 | if( zNew==0 ){ |
| 340 | 340 | @ <p>Deleted %h(zName)</p> |
| 341 | 341 | }else if( zOld==0 ){ |
| 342 | 342 | @ <p>Added %h(zName)</p> |
| 343 | 343 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| @@ -354,35 +354,35 @@ | ||
| 354 | 354 | @ </pre> |
| 355 | 355 | } |
| 356 | 356 | }else{ |
| 357 | 357 | if( zOld && zNew ){ |
| 358 | 358 | if( fossil_strcmp(zOld, zNew)!=0 ){ |
| 359 | - @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> | |
| 360 | - @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> | |
| 361 | - @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> | |
| 359 | + @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a> | |
| 360 | + @ from %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a> | |
| 361 | + @ to %z(href("%R/artifact/%s",zNew))[%S(zNew)].</a> | |
| 362 | 362 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| 363 | 363 | @ <p>Name change from |
| 364 | - @ from <a href="%s(g.zTop)/finfo?name=%T(zOldName)">%h(zOldName)</a> | |
| 365 | - @ to <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>. | |
| 364 | + @ from %z(href("%R/finfo?name=%T",zOldName))%h(zOldName)</a> | |
| 365 | + @ to %z(href("%R/finfo?name=%T",zName))%h(zName)</a>. | |
| 366 | 366 | }else{ |
| 367 | 367 | @ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for |
| 368 | - @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> | |
| 368 | + @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> | |
| 369 | 369 | } |
| 370 | 370 | }else if( zOld ){ |
| 371 | - @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> | |
| 372 | - @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> | |
| 371 | + @ <p>Deleted %z(href("%s/finfo?name=%T",g.zTop,zName))%h(zName)</a> | |
| 372 | + @ version %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a> | |
| 373 | 373 | }else{ |
| 374 | - @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> | |
| 375 | - @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a> | |
| 374 | + @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a> | |
| 375 | + @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a> | |
| 376 | 376 | } |
| 377 | 377 | if( diffFlags ){ |
| 378 | 378 | @ <pre style="white-space:pre;"> |
| 379 | 379 | append_diff(zOld, zNew, diffFlags); |
| 380 | 380 | @ </pre> |
| 381 | 381 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 382 | 382 | @ |
| 383 | - @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> | |
| 383 | + @ %z(href("%R/fdiff?v1=%S&v2=%S",zOld,zNew))[diff]</a> | |
| 384 | 384 | } |
| 385 | 385 | @ </p> |
| 386 | 386 | } |
| 387 | 387 | } |
| 388 | 388 | |
| @@ -535,47 +535,47 @@ | ||
| 535 | 535 | @ <tr><th>Received From:</th> |
| 536 | 536 | @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr> |
| 537 | 537 | } |
| 538 | 538 | db_finalize(&q); |
| 539 | 539 | } |
| 540 | - if( g.perm.History ){ | |
| 540 | + if( g.perm.Hyperlink ){ | |
| 541 | 541 | const char *zProjName = db_get("project-name", "unnamed"); |
| 542 | 542 | @ <tr><th>Timelines:</th><td> |
| 543 | - @ <a href="%s(g.zTop)/timeline?f=%S(zUuid)">family</a> | |
| 543 | + @ %z(href("%R/timeline?f=%S",zUuid))family</a> | |
| 544 | 544 | if( zParent ){ |
| 545 | - @ | <a href="%s(g.zTop)/timeline?p=%S(zUuid)">ancestors</a> | |
| 545 | + @ | %z(href("%R/timeline?p=%S",zUuid))ancestors</a> | |
| 546 | 546 | } |
| 547 | 547 | if( !isLeaf ){ |
| 548 | - @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a> | |
| 548 | + @ | %z(href("%R/timeline?d=%S",zUuid))descendants</a> | |
| 549 | 549 | } |
| 550 | 550 | if( zParent && !isLeaf ){ |
| 551 | - @ | <a href="%s(g.zTop)/timeline?dp=%S(zUuid)">both</a> | |
| 551 | + @ | %z(href("%R/timeline?dp=%S",zUuid))both</a> | |
| 552 | 552 | } |
| 553 | 553 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 554 | 554 | " WHERE rid=%d AND tagtype>0 " |
| 555 | 555 | " AND tag.tagid=tagxref.tagid " |
| 556 | 556 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| 557 | 557 | while( db_step(&q)==SQLITE_ROW ){ |
| 558 | 558 | const char *zTagName = db_column_text(&q, 0); |
| 559 | - @ | <a href="%s(g.zTop)/timeline?r=%T(zTagName)">%h(zTagName)</a> | |
| 559 | + @ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a> | |
| 560 | 560 | } |
| 561 | 561 | db_finalize(&q); |
| 562 | 562 | @ </td></tr> |
| 563 | 563 | @ <tr><th>Other Links:</th> |
| 564 | 564 | @ <td> |
| 565 | - @ <a href="%s(g.zTop)/dir?ci=%S(zUuid)">files</a> | |
| 565 | + @ %z(href("%R/dir?ci=%S",zUuid))files</a> | |
| 566 | 566 | if( g.perm.Zip ){ |
| 567 | - char *zUrl = mprintf("%s/tarball/%s-%S.tar.gz?uuid=%s", | |
| 568 | - g.zTop, zProjName, zUuid, zUuid); | |
| 569 | - @ | <a href="%s(zUrl)">Tarball</a> | |
| 570 | - @ | <a href="%s(g.zTop)/zip/%s(zProjName)-%S(zUuid).zip?uuid=%s(zUuid)"> | |
| 567 | + char *zUrl = mprintf("%R/tarball/%s-%S.tar.gz?uuid=%s", | |
| 568 | + zProjName, zUuid, zUuid); | |
| 569 | + @ | %z(href("%s",zUrl))Tarball</a> | |
| 570 | + @ | %z(href("%R/zip/%s-%S.zip?uuid=%s",zProjName,zUuid,zUuid)) | |
| 571 | 571 | @ ZIP archive</a> |
| 572 | 572 | fossil_free(zUrl); |
| 573 | 573 | } |
| 574 | - @ | <a href="%s(g.zTop)/artifact/%S(zUuid)">manifest</a> | |
| 574 | + @ | %z(href("%R/artifact/%S",zUuid))manifest</a> | |
| 575 | 575 | if( g.perm.Write ){ |
| 576 | - @ | <a href="%s(g.zTop)/ci_edit?r=%S(zUuid)">edit</a> | |
| 576 | + @ | %z(href("%R/ci_edit?r=%S",zUuid))edit</a> | |
| 577 | 577 | } |
| 578 | 578 | @ </td> |
| 579 | 579 | @ </tr> |
| 580 | 580 | } |
| 581 | 581 | @ </table> |
| @@ -590,43 +590,43 @@ | ||
| 590 | 590 | @ <div class="sectionmenu"> |
| 591 | 591 | showDiff = g.zPath[0]!='c'; |
| 592 | 592 | if( db_get_boolean("show-version-diffs", 0)==0 ){ |
| 593 | 593 | showDiff = !showDiff; |
| 594 | 594 | if( showDiff ){ |
| 595 | - @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)"> | |
| 595 | + @ %z(xhref("class='button'","%R/vinfo/%T",zName))) | |
| 596 | 596 | @ hide diffs</a> |
| 597 | 597 | if( sideBySide ){ |
| 598 | - @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0"> | |
| 598 | + @ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName)) | |
| 599 | 599 | @ unified diffs</a> |
| 600 | 600 | }else{ |
| 601 | - @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1"> | |
| 601 | + @ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName)) | |
| 602 | 602 | @ side-by-side diffs</a> |
| 603 | 603 | } |
| 604 | 604 | }else{ |
| 605 | - @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0"> | |
| 605 | + @ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName)) | |
| 606 | 606 | @ show unified diffs</a> |
| 607 | - @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1"> | |
| 607 | + @ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName)) | |
| 608 | 608 | @ show side-by-side diffs</a> |
| 609 | 609 | } |
| 610 | 610 | }else{ |
| 611 | 611 | if( showDiff ){ |
| 612 | - @ <a class="button" href="%s(g.zTop)/ci/%T(zName)">hide diffs</a> | |
| 612 | + @ %z(xhref("class='button'","%R/ci/%T",zName))hide diffs</a> | |
| 613 | 613 | if( sideBySide ){ |
| 614 | - @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=0"> | |
| 614 | + @ %z(xhref("class='button'","%R/info/%T?sbs=0",zName)) | |
| 615 | 615 | @ unified diffs</a> |
| 616 | 616 | }else{ |
| 617 | - @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=1"> | |
| 617 | + @ %z(xhref("class='button'","%R/info/%T?sbs=1",zName)) | |
| 618 | 618 | @ side-by-side diffs</a> |
| 619 | 619 | } |
| 620 | 620 | }else{ |
| 621 | - @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=0"> | |
| 621 | + @ %z(xhref("class='button'","%R/vinfo/%T?sbs=0",zName)) | |
| 622 | 622 | @ show unified diffs</a> |
| 623 | - @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=1"> | |
| 623 | + @ %z(xhref("class='button'","%R/vinfo/%T?sbs=1",zName)) | |
| 624 | 624 | @ show side-by-side diffs</a> |
| 625 | 625 | } |
| 626 | 626 | } |
| 627 | - @ <a class="button" href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)"> | |
| 627 | + @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid)) | |
| 628 | 628 | @ patch</a></div> |
| 629 | 629 | db_prepare(&q, |
| 630 | 630 | "SELECT name," |
| 631 | 631 | " mperm," |
| 632 | 632 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| @@ -698,15 +698,15 @@ | ||
| 698 | 698 | if( g.perm.Setup ){ |
| 699 | 699 | @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> |
| 700 | 700 | } |
| 701 | 701 | @ <tr><th>Original User:</th><td> |
| 702 | 702 | hyperlink_to_user(zUser, zDate, "</td></tr>"); |
| 703 | - if( g.perm.History ){ | |
| 703 | + if( g.perm.Hyperlink ){ | |
| 704 | 704 | @ <tr><th>Commands:</th> |
| 705 | 705 | @ <td> |
| 706 | - @ <a href="%s(g.zTop)/whistory?name=%t(zName)">history</a> | |
| 707 | - @ | <a href="%s(g.zTop)/artifact/%S(zUuid)">raw-text</a> | |
| 706 | + @ &z(href("%R/whistory?name=%t",zName))history</a> | |
| 707 | + @ | %z(href("%R/artifact/%S",zUuid))raw-text</a> | |
| 708 | 708 | @ </td> |
| 709 | 709 | @ </tr> |
| 710 | 710 | } |
| 711 | 711 | @ </table></p> |
| 712 | 712 | }else{ |
| @@ -936,34 +936,26 @@ | ||
| 936 | 936 | }else if( mPerm==PERM_EXE ){ |
| 937 | 937 | @ <li>Executable file |
| 938 | 938 | }else{ |
| 939 | 939 | @ <li>File |
| 940 | 940 | } |
| 941 | - if( g.perm.History ){ | |
| 942 | - @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> | |
| 943 | - }else{ | |
| 944 | - @ %h(zName) | |
| 945 | - } | |
| 941 | + @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> | |
| 946 | 942 | @ <ul> |
| 947 | 943 | prevName = fossil_strdup(zName); |
| 948 | 944 | } |
| 949 | 945 | @ <li> |
| 950 | 946 | hyperlink_to_date(zDate,""); |
| 951 | 947 | @ - part of checkin |
| 952 | 948 | hyperlink_to_uuid(zVers); |
| 953 | 949 | if( zBr && zBr[0] ){ |
| 954 | - if( g.perm.History ){ | |
| 955 | - @ on branch <a href="%s(g.zTop)/timeline?r=%T(zBr)">%h(zBr)</a> | |
| 956 | - }else{ | |
| 957 | - @ on branch %h(zBr) | |
| 958 | - } | |
| 950 | + @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a> | |
| 959 | 951 | } |
| 960 | 952 | @ - %w(zCom) (user: |
| 961 | 953 | hyperlink_to_user(zUser,zDate,""); |
| 962 | 954 | @ ) |
| 963 | - if( g.perm.History ){ | |
| 964 | - @ <a href="%s(g.zTop)/annotate?checkin=%S(zVers)&filename=%T(zName)"> | |
| 955 | + if( g.perm.Hyperlink ){ | |
| 956 | + @ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName)) | |
| 965 | 957 | @ [annotate]</a> |
| 966 | 958 | } |
| 967 | 959 | cnt++; |
| 968 | 960 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 969 | 961 | blob_append(pDownloadName, zName, -1); |
| @@ -989,16 +981,11 @@ | ||
| 989 | 981 | if( cnt>0 ){ |
| 990 | 982 | @ Also wiki page |
| 991 | 983 | }else{ |
| 992 | 984 | @ Wiki page |
| 993 | 985 | } |
| 994 | - if( g.perm.History ){ | |
| 995 | - @ [<a href="%s(g.zTop)/wiki?name=%t(zPagename)">%h(zPagename)</a>] | |
| 996 | - }else{ | |
| 997 | - @ [%h(zPagename)] | |
| 998 | - } | |
| 999 | - @ by | |
| 986 | + @ [%z(href("%R/wiki?name=%t",zPagename))%h(zPagename)</a>] by | |
| 1000 | 987 | hyperlink_to_user(zUser,zDate," on"); |
| 1001 | 988 | hyperlink_to_date(zDate,"."); |
| 1002 | 989 | nWiki++; |
| 1003 | 990 | cnt++; |
| 1004 | 991 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| @@ -1065,18 +1052,18 @@ | ||
| 1065 | 1052 | @ Also attachment "%h(zFilename)" to |
| 1066 | 1053 | }else{ |
| 1067 | 1054 | @ Attachment "%h(zFilename)" to |
| 1068 | 1055 | } |
| 1069 | 1056 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1070 | - if( g.perm.History && g.perm.RdTkt ){ | |
| 1071 | - @ ticket [<a href="%s(g.zTop)/tktview?name=%S(zTarget)">%S(zTarget)</a>] | |
| 1057 | + if( g.perm.Hyperlink && g.perm.RdTkt ){ | |
| 1058 | + @ ticket [%z(href("%R/tktview?name=%S",zTarget))%S(zTarget)</a>] | |
| 1072 | 1059 | }else{ |
| 1073 | 1060 | @ ticket [%S(zTarget)] |
| 1074 | 1061 | } |
| 1075 | 1062 | }else{ |
| 1076 | - if( g.perm.History && g.perm.RdWiki ){ | |
| 1077 | - @ wiki page [<a href="%s(g.zTop)/wiki?name=%t(zTarget)">%h(zTarget)</a>] | |
| 1063 | + if( g.perm.Hyperlink && g.perm.RdWiki ){ | |
| 1064 | + @ wiki page [%z(href("%R/wiki?name=%t",zTarget)))%h(zTarget)</a>] | |
| 1078 | 1065 | }else{ |
| 1079 | 1066 | @ wiki page [%h(zTarget)] |
| 1080 | 1067 | } |
| 1081 | 1068 | } |
| 1082 | 1069 | @ added by |
| @@ -1091,12 +1078,12 @@ | ||
| 1091 | 1078 | if( cnt==0 ){ |
| 1092 | 1079 | @ Control artifact. |
| 1093 | 1080 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1094 | 1081 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1095 | 1082 | } |
| 1096 | - }else if( linkToView && g.perm.History ){ | |
| 1097 | - @ <a href="%s(g.zTop)/artifact/%S(zUuid)">[view]</a> | |
| 1083 | + }else if( linkToView && g.perm.Hyperlink ){ | |
| 1084 | + @ %z(href("%R/artifact/%S",zUuid))[view]</a> | |
| 1098 | 1085 | } |
| 1099 | 1086 | } |
| 1100 | 1087 | |
| 1101 | 1088 | |
| 1102 | 1089 | /* |
| @@ -1160,18 +1147,17 @@ | ||
| 1160 | 1147 | g.zTop, P("v1"), P("v2")); |
| 1161 | 1148 | } |
| 1162 | 1149 | |
| 1163 | 1150 | if( P("smhdr")!=0 ){ |
| 1164 | 1151 | @ <h2>Differences From Artifact |
| 1165 | - @ <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a> To | |
| 1166 | - @ <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>.</h2> | |
| 1152 | + @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To | |
| 1153 | + @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2> | |
| 1167 | 1154 | }else{ |
| 1168 | 1155 | @ <h2>Differences From |
| 1169 | - @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2> | |
| 1156 | + @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2> | |
| 1170 | 1157 | object_description(v1, 0, 0); |
| 1171 | - @ <h2>To Artifact | |
| 1172 | - @ <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2> | |
| 1158 | + @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2> | |
| 1173 | 1159 | object_description(v2, 0, 0); |
| 1174 | 1160 | } |
| 1175 | 1161 | @ <hr /> |
| 1176 | 1162 | @ <div class="%s(zStyle)"> |
| 1177 | 1163 | @ %s(blob_str(&diff)) |
| @@ -1522,18 +1508,17 @@ | ||
| 1522 | 1508 | } |
| 1523 | 1509 | style_header("Ticket Change Details"); |
| 1524 | 1510 | zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate); |
| 1525 | 1511 | memcpy(zTktName, pTktChng->zTicketUuid, 10); |
| 1526 | 1512 | zTktName[10] = 0; |
| 1527 | - if( g.perm.History ){ | |
| 1513 | + if( g.perm.Hyperlink ){ | |
| 1528 | 1514 | @ <h2>Changes to ticket |
| 1529 | - @ <a href="%s(pTktChng->zTicketUuid)">%s(zTktName)</a></h2> | |
| 1515 | + @ %z(href("%R/tktview/%s",pTktChng->zTicketUuid)))%s(zTktName)</a></h2> | |
| 1530 | 1516 | @ |
| 1531 | 1517 | @ <p>By %h(pTktChng->zUser) on %s(zDate). See also: |
| 1532 | - @ <a href="%s(g.zTop)/artifact/%T(zUuid)">artifact content</a>, and | |
| 1533 | - @ <a href="%s(g.zTop)/tkthistory/%s(pTktChng->zTicketUuid)">ticket | |
| 1534 | - @ history</a></p> | |
| 1518 | + @ %z(href("%R/artifact/%T",zUuid))artifact content</a>, and | |
| 1519 | + @ %z(href("%R/tkthistory/%s",pTktChng->zTicketUuid))ticket history</a></p> | |
| 1535 | 1520 | }else{ |
| 1536 | 1521 | @ <h2>Changes to ticket %s(zTktName)</h2> |
| 1537 | 1522 | @ |
| 1538 | 1523 | @ <p>By %h(pTktChng->zUser) on %s(zDate). |
| 1539 | 1524 | @ </p> |
| @@ -1965,11 +1950,11 @@ | ||
| 1965 | 1950 | @ </blockquote> |
| 1966 | 1951 | @ <hr /> |
| 1967 | 1952 | blob_reset(&suffix); |
| 1968 | 1953 | } |
| 1969 | 1954 | @ <p>Make changes to attributes of check-in |
| 1970 | - @ [<a href="ci?name=%s(zUuid)">%s(zUuid)</a>]:</p> | |
| 1955 | + @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> | |
| 1971 | 1956 | @ <form action="%s(g.zTop)/ci_edit" method="post"><div> |
| 1972 | 1957 | login_insert_csrf_secret(); |
| 1973 | 1958 | @ <input type="hidden" name="r" value="%S(zUuid)" /> |
| 1974 | 1959 | @ <table border="0" cellspacing="10"> |
| 1975 | 1960 | |
| 1976 | 1961 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -261,11 +261,11 @@ | |
| 261 | @ propagates to descendants |
| 262 | } |
| 263 | #if 0 |
| 264 | if( zValue && fossil_strcmp(zTagname,"branch")==0 ){ |
| 265 | @ |
| 266 | @ <a href="%s(g.zTop)/timeline?r=%T(zValue)">branch timeline</a> |
| 267 | } |
| 268 | #endif |
| 269 | } |
| 270 | if( zSrcUuid && zSrcUuid[0] ){ |
| 271 | if( tagtype==0 ){ |
| @@ -333,11 +333,11 @@ | |
| 333 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 334 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 335 | int diffFlags, /* Flags for text_diff(). Zero to omit diffs */ |
| 336 | int mperm /* executable or symlink permission for zNew */ |
| 337 | ){ |
| 338 | if( !g.perm.History ){ |
| 339 | if( zNew==0 ){ |
| 340 | @ <p>Deleted %h(zName)</p> |
| 341 | }else if( zOld==0 ){ |
| 342 | @ <p>Added %h(zName)</p> |
| 343 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| @@ -354,35 +354,35 @@ | |
| 354 | @ </pre> |
| 355 | } |
| 356 | }else{ |
| 357 | if( zOld && zNew ){ |
| 358 | if( fossil_strcmp(zOld, zNew)!=0 ){ |
| 359 | @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 360 | @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 361 | @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> |
| 362 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| 363 | @ <p>Name change from |
| 364 | @ from <a href="%s(g.zTop)/finfo?name=%T(zOldName)">%h(zOldName)</a> |
| 365 | @ to <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>. |
| 366 | }else{ |
| 367 | @ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for |
| 368 | @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 369 | } |
| 370 | }else if( zOld ){ |
| 371 | @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 372 | @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 373 | }else{ |
| 374 | @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 375 | @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a> |
| 376 | } |
| 377 | if( diffFlags ){ |
| 378 | @ <pre style="white-space:pre;"> |
| 379 | append_diff(zOld, zNew, diffFlags); |
| 380 | @ </pre> |
| 381 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 382 | @ |
| 383 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 384 | } |
| 385 | @ </p> |
| 386 | } |
| 387 | } |
| 388 | |
| @@ -535,47 +535,47 @@ | |
| 535 | @ <tr><th>Received From:</th> |
| 536 | @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr> |
| 537 | } |
| 538 | db_finalize(&q); |
| 539 | } |
| 540 | if( g.perm.History ){ |
| 541 | const char *zProjName = db_get("project-name", "unnamed"); |
| 542 | @ <tr><th>Timelines:</th><td> |
| 543 | @ <a href="%s(g.zTop)/timeline?f=%S(zUuid)">family</a> |
| 544 | if( zParent ){ |
| 545 | @ | <a href="%s(g.zTop)/timeline?p=%S(zUuid)">ancestors</a> |
| 546 | } |
| 547 | if( !isLeaf ){ |
| 548 | @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a> |
| 549 | } |
| 550 | if( zParent && !isLeaf ){ |
| 551 | @ | <a href="%s(g.zTop)/timeline?dp=%S(zUuid)">both</a> |
| 552 | } |
| 553 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 554 | " WHERE rid=%d AND tagtype>0 " |
| 555 | " AND tag.tagid=tagxref.tagid " |
| 556 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| 557 | while( db_step(&q)==SQLITE_ROW ){ |
| 558 | const char *zTagName = db_column_text(&q, 0); |
| 559 | @ | <a href="%s(g.zTop)/timeline?r=%T(zTagName)">%h(zTagName)</a> |
| 560 | } |
| 561 | db_finalize(&q); |
| 562 | @ </td></tr> |
| 563 | @ <tr><th>Other Links:</th> |
| 564 | @ <td> |
| 565 | @ <a href="%s(g.zTop)/dir?ci=%S(zUuid)">files</a> |
| 566 | if( g.perm.Zip ){ |
| 567 | char *zUrl = mprintf("%s/tarball/%s-%S.tar.gz?uuid=%s", |
| 568 | g.zTop, zProjName, zUuid, zUuid); |
| 569 | @ | <a href="%s(zUrl)">Tarball</a> |
| 570 | @ | <a href="%s(g.zTop)/zip/%s(zProjName)-%S(zUuid).zip?uuid=%s(zUuid)"> |
| 571 | @ ZIP archive</a> |
| 572 | fossil_free(zUrl); |
| 573 | } |
| 574 | @ | <a href="%s(g.zTop)/artifact/%S(zUuid)">manifest</a> |
| 575 | if( g.perm.Write ){ |
| 576 | @ | <a href="%s(g.zTop)/ci_edit?r=%S(zUuid)">edit</a> |
| 577 | } |
| 578 | @ </td> |
| 579 | @ </tr> |
| 580 | } |
| 581 | @ </table> |
| @@ -590,43 +590,43 @@ | |
| 590 | @ <div class="sectionmenu"> |
| 591 | showDiff = g.zPath[0]!='c'; |
| 592 | if( db_get_boolean("show-version-diffs", 0)==0 ){ |
| 593 | showDiff = !showDiff; |
| 594 | if( showDiff ){ |
| 595 | @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)"> |
| 596 | @ hide diffs</a> |
| 597 | if( sideBySide ){ |
| 598 | @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0"> |
| 599 | @ unified diffs</a> |
| 600 | }else{ |
| 601 | @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1"> |
| 602 | @ side-by-side diffs</a> |
| 603 | } |
| 604 | }else{ |
| 605 | @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0"> |
| 606 | @ show unified diffs</a> |
| 607 | @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1"> |
| 608 | @ show side-by-side diffs</a> |
| 609 | } |
| 610 | }else{ |
| 611 | if( showDiff ){ |
| 612 | @ <a class="button" href="%s(g.zTop)/ci/%T(zName)">hide diffs</a> |
| 613 | if( sideBySide ){ |
| 614 | @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=0"> |
| 615 | @ unified diffs</a> |
| 616 | }else{ |
| 617 | @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=1"> |
| 618 | @ side-by-side diffs</a> |
| 619 | } |
| 620 | }else{ |
| 621 | @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=0"> |
| 622 | @ show unified diffs</a> |
| 623 | @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=1"> |
| 624 | @ show side-by-side diffs</a> |
| 625 | } |
| 626 | } |
| 627 | @ <a class="button" href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)"> |
| 628 | @ patch</a></div> |
| 629 | db_prepare(&q, |
| 630 | "SELECT name," |
| 631 | " mperm," |
| 632 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| @@ -698,15 +698,15 @@ | |
| 698 | if( g.perm.Setup ){ |
| 699 | @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> |
| 700 | } |
| 701 | @ <tr><th>Original User:</th><td> |
| 702 | hyperlink_to_user(zUser, zDate, "</td></tr>"); |
| 703 | if( g.perm.History ){ |
| 704 | @ <tr><th>Commands:</th> |
| 705 | @ <td> |
| 706 | @ <a href="%s(g.zTop)/whistory?name=%t(zName)">history</a> |
| 707 | @ | <a href="%s(g.zTop)/artifact/%S(zUuid)">raw-text</a> |
| 708 | @ </td> |
| 709 | @ </tr> |
| 710 | } |
| 711 | @ </table></p> |
| 712 | }else{ |
| @@ -936,34 +936,26 @@ | |
| 936 | }else if( mPerm==PERM_EXE ){ |
| 937 | @ <li>Executable file |
| 938 | }else{ |
| 939 | @ <li>File |
| 940 | } |
| 941 | if( g.perm.History ){ |
| 942 | @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 943 | }else{ |
| 944 | @ %h(zName) |
| 945 | } |
| 946 | @ <ul> |
| 947 | prevName = fossil_strdup(zName); |
| 948 | } |
| 949 | @ <li> |
| 950 | hyperlink_to_date(zDate,""); |
| 951 | @ - part of checkin |
| 952 | hyperlink_to_uuid(zVers); |
| 953 | if( zBr && zBr[0] ){ |
| 954 | if( g.perm.History ){ |
| 955 | @ on branch <a href="%s(g.zTop)/timeline?r=%T(zBr)">%h(zBr)</a> |
| 956 | }else{ |
| 957 | @ on branch %h(zBr) |
| 958 | } |
| 959 | } |
| 960 | @ - %w(zCom) (user: |
| 961 | hyperlink_to_user(zUser,zDate,""); |
| 962 | @ ) |
| 963 | if( g.perm.History ){ |
| 964 | @ <a href="%s(g.zTop)/annotate?checkin=%S(zVers)&filename=%T(zName)"> |
| 965 | @ [annotate]</a> |
| 966 | } |
| 967 | cnt++; |
| 968 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 969 | blob_append(pDownloadName, zName, -1); |
| @@ -989,16 +981,11 @@ | |
| 989 | if( cnt>0 ){ |
| 990 | @ Also wiki page |
| 991 | }else{ |
| 992 | @ Wiki page |
| 993 | } |
| 994 | if( g.perm.History ){ |
| 995 | @ [<a href="%s(g.zTop)/wiki?name=%t(zPagename)">%h(zPagename)</a>] |
| 996 | }else{ |
| 997 | @ [%h(zPagename)] |
| 998 | } |
| 999 | @ by |
| 1000 | hyperlink_to_user(zUser,zDate," on"); |
| 1001 | hyperlink_to_date(zDate,"."); |
| 1002 | nWiki++; |
| 1003 | cnt++; |
| 1004 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| @@ -1065,18 +1052,18 @@ | |
| 1065 | @ Also attachment "%h(zFilename)" to |
| 1066 | }else{ |
| 1067 | @ Attachment "%h(zFilename)" to |
| 1068 | } |
| 1069 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1070 | if( g.perm.History && g.perm.RdTkt ){ |
| 1071 | @ ticket [<a href="%s(g.zTop)/tktview?name=%S(zTarget)">%S(zTarget)</a>] |
| 1072 | }else{ |
| 1073 | @ ticket [%S(zTarget)] |
| 1074 | } |
| 1075 | }else{ |
| 1076 | if( g.perm.History && g.perm.RdWiki ){ |
| 1077 | @ wiki page [<a href="%s(g.zTop)/wiki?name=%t(zTarget)">%h(zTarget)</a>] |
| 1078 | }else{ |
| 1079 | @ wiki page [%h(zTarget)] |
| 1080 | } |
| 1081 | } |
| 1082 | @ added by |
| @@ -1091,12 +1078,12 @@ | |
| 1091 | if( cnt==0 ){ |
| 1092 | @ Control artifact. |
| 1093 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1094 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1095 | } |
| 1096 | }else if( linkToView && g.perm.History ){ |
| 1097 | @ <a href="%s(g.zTop)/artifact/%S(zUuid)">[view]</a> |
| 1098 | } |
| 1099 | } |
| 1100 | |
| 1101 | |
| 1102 | /* |
| @@ -1160,18 +1147,17 @@ | |
| 1160 | g.zTop, P("v1"), P("v2")); |
| 1161 | } |
| 1162 | |
| 1163 | if( P("smhdr")!=0 ){ |
| 1164 | @ <h2>Differences From Artifact |
| 1165 | @ <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a> To |
| 1166 | @ <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>.</h2> |
| 1167 | }else{ |
| 1168 | @ <h2>Differences From |
| 1169 | @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2> |
| 1170 | object_description(v1, 0, 0); |
| 1171 | @ <h2>To Artifact |
| 1172 | @ <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2> |
| 1173 | object_description(v2, 0, 0); |
| 1174 | } |
| 1175 | @ <hr /> |
| 1176 | @ <div class="%s(zStyle)"> |
| 1177 | @ %s(blob_str(&diff)) |
| @@ -1522,18 +1508,17 @@ | |
| 1522 | } |
| 1523 | style_header("Ticket Change Details"); |
| 1524 | zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate); |
| 1525 | memcpy(zTktName, pTktChng->zTicketUuid, 10); |
| 1526 | zTktName[10] = 0; |
| 1527 | if( g.perm.History ){ |
| 1528 | @ <h2>Changes to ticket |
| 1529 | @ <a href="%s(pTktChng->zTicketUuid)">%s(zTktName)</a></h2> |
| 1530 | @ |
| 1531 | @ <p>By %h(pTktChng->zUser) on %s(zDate). See also: |
| 1532 | @ <a href="%s(g.zTop)/artifact/%T(zUuid)">artifact content</a>, and |
| 1533 | @ <a href="%s(g.zTop)/tkthistory/%s(pTktChng->zTicketUuid)">ticket |
| 1534 | @ history</a></p> |
| 1535 | }else{ |
| 1536 | @ <h2>Changes to ticket %s(zTktName)</h2> |
| 1537 | @ |
| 1538 | @ <p>By %h(pTktChng->zUser) on %s(zDate). |
| 1539 | @ </p> |
| @@ -1965,11 +1950,11 @@ | |
| 1965 | @ </blockquote> |
| 1966 | @ <hr /> |
| 1967 | blob_reset(&suffix); |
| 1968 | } |
| 1969 | @ <p>Make changes to attributes of check-in |
| 1970 | @ [<a href="ci?name=%s(zUuid)">%s(zUuid)</a>]:</p> |
| 1971 | @ <form action="%s(g.zTop)/ci_edit" method="post"><div> |
| 1972 | login_insert_csrf_secret(); |
| 1973 | @ <input type="hidden" name="r" value="%S(zUuid)" /> |
| 1974 | @ <table border="0" cellspacing="10"> |
| 1975 | |
| 1976 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -261,11 +261,11 @@ | |
| 261 | @ propagates to descendants |
| 262 | } |
| 263 | #if 0 |
| 264 | if( zValue && fossil_strcmp(zTagname,"branch")==0 ){ |
| 265 | @ |
| 266 | @ %z(href("%R/timeline?r=%T",zValue))branch timeline</a> |
| 267 | } |
| 268 | #endif |
| 269 | } |
| 270 | if( zSrcUuid && zSrcUuid[0] ){ |
| 271 | if( tagtype==0 ){ |
| @@ -333,11 +333,11 @@ | |
| 333 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 334 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 335 | int diffFlags, /* Flags for text_diff(). Zero to omit diffs */ |
| 336 | int mperm /* executable or symlink permission for zNew */ |
| 337 | ){ |
| 338 | if( !g.perm.Hyperlink ){ |
| 339 | if( zNew==0 ){ |
| 340 | @ <p>Deleted %h(zName)</p> |
| 341 | }else if( zOld==0 ){ |
| 342 | @ <p>Added %h(zName)</p> |
| 343 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| @@ -354,35 +354,35 @@ | |
| 354 | @ </pre> |
| 355 | } |
| 356 | }else{ |
| 357 | if( zOld && zNew ){ |
| 358 | if( fossil_strcmp(zOld, zNew)!=0 ){ |
| 359 | @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 360 | @ from %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a> |
| 361 | @ to %z(href("%R/artifact/%s",zNew))[%S(zNew)].</a> |
| 362 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| 363 | @ <p>Name change from |
| 364 | @ from %z(href("%R/finfo?name=%T",zOldName))%h(zOldName)</a> |
| 365 | @ to %z(href("%R/finfo?name=%T",zName))%h(zName)</a>. |
| 366 | }else{ |
| 367 | @ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for |
| 368 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 369 | } |
| 370 | }else if( zOld ){ |
| 371 | @ <p>Deleted %z(href("%s/finfo?name=%T",g.zTop,zName))%h(zName)</a> |
| 372 | @ version %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a> |
| 373 | }else{ |
| 374 | @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 375 | @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a> |
| 376 | } |
| 377 | if( diffFlags ){ |
| 378 | @ <pre style="white-space:pre;"> |
| 379 | append_diff(zOld, zNew, diffFlags); |
| 380 | @ </pre> |
| 381 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 382 | @ |
| 383 | @ %z(href("%R/fdiff?v1=%S&v2=%S",zOld,zNew))[diff]</a> |
| 384 | } |
| 385 | @ </p> |
| 386 | } |
| 387 | } |
| 388 | |
| @@ -535,47 +535,47 @@ | |
| 535 | @ <tr><th>Received From:</th> |
| 536 | @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr> |
| 537 | } |
| 538 | db_finalize(&q); |
| 539 | } |
| 540 | if( g.perm.Hyperlink ){ |
| 541 | const char *zProjName = db_get("project-name", "unnamed"); |
| 542 | @ <tr><th>Timelines:</th><td> |
| 543 | @ %z(href("%R/timeline?f=%S",zUuid))family</a> |
| 544 | if( zParent ){ |
| 545 | @ | %z(href("%R/timeline?p=%S",zUuid))ancestors</a> |
| 546 | } |
| 547 | if( !isLeaf ){ |
| 548 | @ | %z(href("%R/timeline?d=%S",zUuid))descendants</a> |
| 549 | } |
| 550 | if( zParent && !isLeaf ){ |
| 551 | @ | %z(href("%R/timeline?dp=%S",zUuid))both</a> |
| 552 | } |
| 553 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 554 | " WHERE rid=%d AND tagtype>0 " |
| 555 | " AND tag.tagid=tagxref.tagid " |
| 556 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| 557 | while( db_step(&q)==SQLITE_ROW ){ |
| 558 | const char *zTagName = db_column_text(&q, 0); |
| 559 | @ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a> |
| 560 | } |
| 561 | db_finalize(&q); |
| 562 | @ </td></tr> |
| 563 | @ <tr><th>Other Links:</th> |
| 564 | @ <td> |
| 565 | @ %z(href("%R/dir?ci=%S",zUuid))files</a> |
| 566 | if( g.perm.Zip ){ |
| 567 | char *zUrl = mprintf("%R/tarball/%s-%S.tar.gz?uuid=%s", |
| 568 | zProjName, zUuid, zUuid); |
| 569 | @ | %z(href("%s",zUrl))Tarball</a> |
| 570 | @ | %z(href("%R/zip/%s-%S.zip?uuid=%s",zProjName,zUuid,zUuid)) |
| 571 | @ ZIP archive</a> |
| 572 | fossil_free(zUrl); |
| 573 | } |
| 574 | @ | %z(href("%R/artifact/%S",zUuid))manifest</a> |
| 575 | if( g.perm.Write ){ |
| 576 | @ | %z(href("%R/ci_edit?r=%S",zUuid))edit</a> |
| 577 | } |
| 578 | @ </td> |
| 579 | @ </tr> |
| 580 | } |
| 581 | @ </table> |
| @@ -590,43 +590,43 @@ | |
| 590 | @ <div class="sectionmenu"> |
| 591 | showDiff = g.zPath[0]!='c'; |
| 592 | if( db_get_boolean("show-version-diffs", 0)==0 ){ |
| 593 | showDiff = !showDiff; |
| 594 | if( showDiff ){ |
| 595 | @ %z(xhref("class='button'","%R/vinfo/%T",zName))) |
| 596 | @ hide diffs</a> |
| 597 | if( sideBySide ){ |
| 598 | @ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName)) |
| 599 | @ unified diffs</a> |
| 600 | }else{ |
| 601 | @ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName)) |
| 602 | @ side-by-side diffs</a> |
| 603 | } |
| 604 | }else{ |
| 605 | @ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName)) |
| 606 | @ show unified diffs</a> |
| 607 | @ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName)) |
| 608 | @ show side-by-side diffs</a> |
| 609 | } |
| 610 | }else{ |
| 611 | if( showDiff ){ |
| 612 | @ %z(xhref("class='button'","%R/ci/%T",zName))hide diffs</a> |
| 613 | if( sideBySide ){ |
| 614 | @ %z(xhref("class='button'","%R/info/%T?sbs=0",zName)) |
| 615 | @ unified diffs</a> |
| 616 | }else{ |
| 617 | @ %z(xhref("class='button'","%R/info/%T?sbs=1",zName)) |
| 618 | @ side-by-side diffs</a> |
| 619 | } |
| 620 | }else{ |
| 621 | @ %z(xhref("class='button'","%R/vinfo/%T?sbs=0",zName)) |
| 622 | @ show unified diffs</a> |
| 623 | @ %z(xhref("class='button'","%R/vinfo/%T?sbs=1",zName)) |
| 624 | @ show side-by-side diffs</a> |
| 625 | } |
| 626 | } |
| 627 | @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid)) |
| 628 | @ patch</a></div> |
| 629 | db_prepare(&q, |
| 630 | "SELECT name," |
| 631 | " mperm," |
| 632 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| @@ -698,15 +698,15 @@ | |
| 698 | if( g.perm.Setup ){ |
| 699 | @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> |
| 700 | } |
| 701 | @ <tr><th>Original User:</th><td> |
| 702 | hyperlink_to_user(zUser, zDate, "</td></tr>"); |
| 703 | if( g.perm.Hyperlink ){ |
| 704 | @ <tr><th>Commands:</th> |
| 705 | @ <td> |
| 706 | @ &z(href("%R/whistory?name=%t",zName))history</a> |
| 707 | @ | %z(href("%R/artifact/%S",zUuid))raw-text</a> |
| 708 | @ </td> |
| 709 | @ </tr> |
| 710 | } |
| 711 | @ </table></p> |
| 712 | }else{ |
| @@ -936,34 +936,26 @@ | |
| 936 | }else if( mPerm==PERM_EXE ){ |
| 937 | @ <li>Executable file |
| 938 | }else{ |
| 939 | @ <li>File |
| 940 | } |
| 941 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 942 | @ <ul> |
| 943 | prevName = fossil_strdup(zName); |
| 944 | } |
| 945 | @ <li> |
| 946 | hyperlink_to_date(zDate,""); |
| 947 | @ - part of checkin |
| 948 | hyperlink_to_uuid(zVers); |
| 949 | if( zBr && zBr[0] ){ |
| 950 | @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a> |
| 951 | } |
| 952 | @ - %w(zCom) (user: |
| 953 | hyperlink_to_user(zUser,zDate,""); |
| 954 | @ ) |
| 955 | if( g.perm.Hyperlink ){ |
| 956 | @ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName)) |
| 957 | @ [annotate]</a> |
| 958 | } |
| 959 | cnt++; |
| 960 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 961 | blob_append(pDownloadName, zName, -1); |
| @@ -989,16 +981,11 @@ | |
| 981 | if( cnt>0 ){ |
| 982 | @ Also wiki page |
| 983 | }else{ |
| 984 | @ Wiki page |
| 985 | } |
| 986 | @ [%z(href("%R/wiki?name=%t",zPagename))%h(zPagename)</a>] by |
| 987 | hyperlink_to_user(zUser,zDate," on"); |
| 988 | hyperlink_to_date(zDate,"."); |
| 989 | nWiki++; |
| 990 | cnt++; |
| 991 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| @@ -1065,18 +1052,18 @@ | |
| 1052 | @ Also attachment "%h(zFilename)" to |
| 1053 | }else{ |
| 1054 | @ Attachment "%h(zFilename)" to |
| 1055 | } |
| 1056 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1057 | if( g.perm.Hyperlink && g.perm.RdTkt ){ |
| 1058 | @ ticket [%z(href("%R/tktview?name=%S",zTarget))%S(zTarget)</a>] |
| 1059 | }else{ |
| 1060 | @ ticket [%S(zTarget)] |
| 1061 | } |
| 1062 | }else{ |
| 1063 | if( g.perm.Hyperlink && g.perm.RdWiki ){ |
| 1064 | @ wiki page [%z(href("%R/wiki?name=%t",zTarget)))%h(zTarget)</a>] |
| 1065 | }else{ |
| 1066 | @ wiki page [%h(zTarget)] |
| 1067 | } |
| 1068 | } |
| 1069 | @ added by |
| @@ -1091,12 +1078,12 @@ | |
| 1078 | if( cnt==0 ){ |
| 1079 | @ Control artifact. |
| 1080 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1081 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1082 | } |
| 1083 | }else if( linkToView && g.perm.Hyperlink ){ |
| 1084 | @ %z(href("%R/artifact/%S",zUuid))[view]</a> |
| 1085 | } |
| 1086 | } |
| 1087 | |
| 1088 | |
| 1089 | /* |
| @@ -1160,18 +1147,17 @@ | |
| 1147 | g.zTop, P("v1"), P("v2")); |
| 1148 | } |
| 1149 | |
| 1150 | if( P("smhdr")!=0 ){ |
| 1151 | @ <h2>Differences From Artifact |
| 1152 | @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To |
| 1153 | @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2> |
| 1154 | }else{ |
| 1155 | @ <h2>Differences From |
| 1156 | @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2> |
| 1157 | object_description(v1, 0, 0); |
| 1158 | @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2> |
| 1159 | object_description(v2, 0, 0); |
| 1160 | } |
| 1161 | @ <hr /> |
| 1162 | @ <div class="%s(zStyle)"> |
| 1163 | @ %s(blob_str(&diff)) |
| @@ -1522,18 +1508,17 @@ | |
| 1508 | } |
| 1509 | style_header("Ticket Change Details"); |
| 1510 | zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate); |
| 1511 | memcpy(zTktName, pTktChng->zTicketUuid, 10); |
| 1512 | zTktName[10] = 0; |
| 1513 | if( g.perm.Hyperlink ){ |
| 1514 | @ <h2>Changes to ticket |
| 1515 | @ %z(href("%R/tktview/%s",pTktChng->zTicketUuid)))%s(zTktName)</a></h2> |
| 1516 | @ |
| 1517 | @ <p>By %h(pTktChng->zUser) on %s(zDate). See also: |
| 1518 | @ %z(href("%R/artifact/%T",zUuid))artifact content</a>, and |
| 1519 | @ %z(href("%R/tkthistory/%s",pTktChng->zTicketUuid))ticket history</a></p> |
| 1520 | }else{ |
| 1521 | @ <h2>Changes to ticket %s(zTktName)</h2> |
| 1522 | @ |
| 1523 | @ <p>By %h(pTktChng->zUser) on %s(zDate). |
| 1524 | @ </p> |
| @@ -1965,11 +1950,11 @@ | |
| 1950 | @ </blockquote> |
| 1951 | @ <hr /> |
| 1952 | blob_reset(&suffix); |
| 1953 | } |
| 1954 | @ <p>Make changes to attributes of check-in |
| 1955 | @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> |
| 1956 | @ <form action="%s(g.zTop)/ci_edit" method="post"><div> |
| 1957 | login_insert_csrf_secret(); |
| 1958 | @ <input type="hidden" name="r" value="%S(zUuid)" /> |
| 1959 | @ <table border="0" cellspacing="10"> |
| 1960 | |
| 1961 |
+6
-4
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -911,11 +911,12 @@ | ||
| 911 | 911 | } |
| 912 | 912 | |
| 913 | 913 | /* Set the capabilities */ |
| 914 | 914 | login_replace_capabilities(zCap, 0); |
| 915 | 915 | login_set_anon_nobody_capabilities(); |
| 916 | - if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1) | |
| 916 | + if( zCap[0] && !g.perm.History && !g.perm.Link | |
| 917 | + && db_get_boolean("auto-enable-hyperlinks",1) | |
| 917 | 918 | && isHuman(P("HTTP_USER_AGENT")) ){ |
| 918 | 919 | g.perm.History = 1; |
| 919 | 920 | } |
| 920 | 921 | |
| 921 | 922 | /* If the public-pages glob pattern is defined and REQUEST_URI matches |
| @@ -983,11 +984,12 @@ | ||
| 983 | 984 | case 'i': g.perm.Read = g.perm.Write = 1; break; |
| 984 | 985 | case 'o': g.perm.Read = 1; break; |
| 985 | 986 | case 'z': g.perm.Zip = 1; break; |
| 986 | 987 | |
| 987 | 988 | case 'd': g.perm.Delete = 1; break; |
| 988 | - case 'h': g.perm.History = 1; break; | |
| 989 | + case 'h': g.perm.History = g.perm.Hyperlink = 1; break; | |
| 990 | + case 'l': g.perm.Link = g.perm.Hyperlink = 1; break; | |
| 989 | 991 | case 'g': g.perm.Clone = 1; break; |
| 990 | 992 | case 'p': g.perm.Password = 1; break; |
| 991 | 993 | |
| 992 | 994 | case 'j': g.perm.RdWiki = 1; break; |
| 993 | 995 | case 'k': g.perm.WrWiki = g.perm.RdWiki = g.perm.ApndWiki =1; break; |
| @@ -1057,11 +1059,11 @@ | ||
| 1057 | 1059 | case 'g': rc = g.perm.Clone; break; |
| 1058 | 1060 | case 'h': rc = g.perm.History; break; |
| 1059 | 1061 | case 'i': rc = g.perm.Write; break; |
| 1060 | 1062 | case 'j': rc = g.perm.RdWiki; break; |
| 1061 | 1063 | case 'k': rc = g.perm.WrWiki; break; |
| 1062 | - /* case 'l': */ | |
| 1064 | + case 'l': rc = g.perm.Link; break; | |
| 1063 | 1065 | case 'm': rc = g.perm.ApndWiki; break; |
| 1064 | 1066 | case 'n': rc = g.perm.NewTkt; break; |
| 1065 | 1067 | case 'o': rc = g.perm.Read; break; |
| 1066 | 1068 | case 'p': rc = g.perm.Password; break; |
| 1067 | 1069 | /* case 'q': */ |
| @@ -1135,11 +1137,11 @@ | ||
| 1135 | 1137 | ** the anonymous user has okHistory permission, then paint a mesage |
| 1136 | 1138 | ** to inform the user that much more information is available by |
| 1137 | 1139 | ** logging in as anonymous. |
| 1138 | 1140 | */ |
| 1139 | 1141 | void login_anonymous_available(void){ |
| 1140 | - if( !g.perm.History && | |
| 1142 | + if( !g.perm.History && !g.perm.Link && | |
| 1141 | 1143 | db_exists("SELECT 1 FROM user" |
| 1142 | 1144 | " WHERE login='anonymous'" |
| 1143 | 1145 | " AND cap LIKE '%%h%%'") ){ |
| 1144 | 1146 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1145 | 1147 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1146 | 1148 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -911,11 +911,12 @@ | |
| 911 | } |
| 912 | |
| 913 | /* Set the capabilities */ |
| 914 | login_replace_capabilities(zCap, 0); |
| 915 | login_set_anon_nobody_capabilities(); |
| 916 | if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1) |
| 917 | && isHuman(P("HTTP_USER_AGENT")) ){ |
| 918 | g.perm.History = 1; |
| 919 | } |
| 920 | |
| 921 | /* If the public-pages glob pattern is defined and REQUEST_URI matches |
| @@ -983,11 +984,12 @@ | |
| 983 | case 'i': g.perm.Read = g.perm.Write = 1; break; |
| 984 | case 'o': g.perm.Read = 1; break; |
| 985 | case 'z': g.perm.Zip = 1; break; |
| 986 | |
| 987 | case 'd': g.perm.Delete = 1; break; |
| 988 | case 'h': g.perm.History = 1; break; |
| 989 | case 'g': g.perm.Clone = 1; break; |
| 990 | case 'p': g.perm.Password = 1; break; |
| 991 | |
| 992 | case 'j': g.perm.RdWiki = 1; break; |
| 993 | case 'k': g.perm.WrWiki = g.perm.RdWiki = g.perm.ApndWiki =1; break; |
| @@ -1057,11 +1059,11 @@ | |
| 1057 | case 'g': rc = g.perm.Clone; break; |
| 1058 | case 'h': rc = g.perm.History; break; |
| 1059 | case 'i': rc = g.perm.Write; break; |
| 1060 | case 'j': rc = g.perm.RdWiki; break; |
| 1061 | case 'k': rc = g.perm.WrWiki; break; |
| 1062 | /* case 'l': */ |
| 1063 | case 'm': rc = g.perm.ApndWiki; break; |
| 1064 | case 'n': rc = g.perm.NewTkt; break; |
| 1065 | case 'o': rc = g.perm.Read; break; |
| 1066 | case 'p': rc = g.perm.Password; break; |
| 1067 | /* case 'q': */ |
| @@ -1135,11 +1137,11 @@ | |
| 1135 | ** the anonymous user has okHistory permission, then paint a mesage |
| 1136 | ** to inform the user that much more information is available by |
| 1137 | ** logging in as anonymous. |
| 1138 | */ |
| 1139 | void login_anonymous_available(void){ |
| 1140 | if( !g.perm.History && |
| 1141 | db_exists("SELECT 1 FROM user" |
| 1142 | " WHERE login='anonymous'" |
| 1143 | " AND cap LIKE '%%h%%'") ){ |
| 1144 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1145 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1146 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -911,11 +911,12 @@ | |
| 911 | } |
| 912 | |
| 913 | /* Set the capabilities */ |
| 914 | login_replace_capabilities(zCap, 0); |
| 915 | login_set_anon_nobody_capabilities(); |
| 916 | if( zCap[0] && !g.perm.History && !g.perm.Link |
| 917 | && db_get_boolean("auto-enable-hyperlinks",1) |
| 918 | && isHuman(P("HTTP_USER_AGENT")) ){ |
| 919 | g.perm.History = 1; |
| 920 | } |
| 921 | |
| 922 | /* If the public-pages glob pattern is defined and REQUEST_URI matches |
| @@ -983,11 +984,12 @@ | |
| 984 | case 'i': g.perm.Read = g.perm.Write = 1; break; |
| 985 | case 'o': g.perm.Read = 1; break; |
| 986 | case 'z': g.perm.Zip = 1; break; |
| 987 | |
| 988 | case 'd': g.perm.Delete = 1; break; |
| 989 | case 'h': g.perm.History = g.perm.Hyperlink = 1; break; |
| 990 | case 'l': g.perm.Link = g.perm.Hyperlink = 1; break; |
| 991 | case 'g': g.perm.Clone = 1; break; |
| 992 | case 'p': g.perm.Password = 1; break; |
| 993 | |
| 994 | case 'j': g.perm.RdWiki = 1; break; |
| 995 | case 'k': g.perm.WrWiki = g.perm.RdWiki = g.perm.ApndWiki =1; break; |
| @@ -1057,11 +1059,11 @@ | |
| 1059 | case 'g': rc = g.perm.Clone; break; |
| 1060 | case 'h': rc = g.perm.History; break; |
| 1061 | case 'i': rc = g.perm.Write; break; |
| 1062 | case 'j': rc = g.perm.RdWiki; break; |
| 1063 | case 'k': rc = g.perm.WrWiki; break; |
| 1064 | case 'l': rc = g.perm.Link; break; |
| 1065 | case 'm': rc = g.perm.ApndWiki; break; |
| 1066 | case 'n': rc = g.perm.NewTkt; break; |
| 1067 | case 'o': rc = g.perm.Read; break; |
| 1068 | case 'p': rc = g.perm.Password; break; |
| 1069 | /* case 'q': */ |
| @@ -1135,11 +1137,11 @@ | |
| 1137 | ** the anonymous user has okHistory permission, then paint a mesage |
| 1138 | ** to inform the user that much more information is available by |
| 1139 | ** logging in as anonymous. |
| 1140 | */ |
| 1141 | void login_anonymous_available(void){ |
| 1142 | if( !g.perm.History && !g.perm.Link && |
| 1143 | db_exists("SELECT 1 FROM user" |
| 1144 | " WHERE login='anonymous'" |
| 1145 | " AND cap LIKE '%%h%%'") ){ |
| 1146 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1147 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1148 |
+9
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -51,10 +51,17 @@ | ||
| 51 | 51 | */ |
| 52 | 52 | #define MX_AUX 5 |
| 53 | 53 | |
| 54 | 54 | /* |
| 55 | 55 | ** Holds flags for fossil user permissions. |
| 56 | +** | |
| 57 | +** History enables various hyperlinks directly, with an href= attribute | |
| 58 | +** in the HTML. Link puts an id= attribute in HTML and then adds the | |
| 59 | +** href= attribute using javascript. The Link option is designed to make | |
| 60 | +** it harder for bots and spiders to follow hyperlinks, and yet give the | |
| 61 | +** same experience to users. the Hyperlink permission is a composite which | |
| 62 | +** is enabled if either History or Hyperlink is turned on. | |
| 56 | 63 | */ |
| 57 | 64 | struct FossilUserPerms { |
| 58 | 65 | char Setup; /* s: use Setup screens on web interface */ |
| 59 | 66 | char Admin; /* a: administrative permission */ |
| 60 | 67 | char Delete; /* d: delete wiki or tickets */ |
| @@ -61,10 +68,11 @@ | ||
| 61 | 68 | char Password; /* p: change password */ |
| 62 | 69 | char Query; /* q: create new reports */ |
| 63 | 70 | char Write; /* i: xfer inbound. checkin */ |
| 64 | 71 | char Read; /* o: xfer outbound. checkout */ |
| 65 | 72 | char History; /* h: access historical information. */ |
| 73 | + char Link; /* l: enable href= using javascript */ | |
| 66 | 74 | char Clone; /* g: clone */ |
| 67 | 75 | char RdWiki; /* j: view wiki via web */ |
| 68 | 76 | char NewWiki; /* f: create new wiki via web */ |
| 69 | 77 | char ApndWiki; /* m: append to wiki via web */ |
| 70 | 78 | char WrWiki; /* k: edit wiki via web */ |
| @@ -75,10 +83,11 @@ | ||
| 75 | 83 | char Attach; /* b: add attachments */ |
| 76 | 84 | char TktFmt; /* t: create new ticket report formats */ |
| 77 | 85 | char RdAddr; /* e: read email addresses or other private data */ |
| 78 | 86 | char Zip; /* z: download zipped artifact via /zip URL */ |
| 79 | 87 | char Private; /* x: can send and receive private content */ |
| 88 | + char Hyperlink; /* "h" or "l" */ | |
| 80 | 89 | }; |
| 81 | 90 | |
| 82 | 91 | #ifdef FOSSIL_ENABLE_TCL |
| 83 | 92 | /* |
| 84 | 93 | ** All Tcl related context information is in this structure. This structure |
| 85 | 94 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -51,10 +51,17 @@ | |
| 51 | */ |
| 52 | #define MX_AUX 5 |
| 53 | |
| 54 | /* |
| 55 | ** Holds flags for fossil user permissions. |
| 56 | */ |
| 57 | struct FossilUserPerms { |
| 58 | char Setup; /* s: use Setup screens on web interface */ |
| 59 | char Admin; /* a: administrative permission */ |
| 60 | char Delete; /* d: delete wiki or tickets */ |
| @@ -61,10 +68,11 @@ | |
| 61 | char Password; /* p: change password */ |
| 62 | char Query; /* q: create new reports */ |
| 63 | char Write; /* i: xfer inbound. checkin */ |
| 64 | char Read; /* o: xfer outbound. checkout */ |
| 65 | char History; /* h: access historical information. */ |
| 66 | char Clone; /* g: clone */ |
| 67 | char RdWiki; /* j: view wiki via web */ |
| 68 | char NewWiki; /* f: create new wiki via web */ |
| 69 | char ApndWiki; /* m: append to wiki via web */ |
| 70 | char WrWiki; /* k: edit wiki via web */ |
| @@ -75,10 +83,11 @@ | |
| 75 | char Attach; /* b: add attachments */ |
| 76 | char TktFmt; /* t: create new ticket report formats */ |
| 77 | char RdAddr; /* e: read email addresses or other private data */ |
| 78 | char Zip; /* z: download zipped artifact via /zip URL */ |
| 79 | char Private; /* x: can send and receive private content */ |
| 80 | }; |
| 81 | |
| 82 | #ifdef FOSSIL_ENABLE_TCL |
| 83 | /* |
| 84 | ** All Tcl related context information is in this structure. This structure |
| 85 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -51,10 +51,17 @@ | |
| 51 | */ |
| 52 | #define MX_AUX 5 |
| 53 | |
| 54 | /* |
| 55 | ** Holds flags for fossil user permissions. |
| 56 | ** |
| 57 | ** History enables various hyperlinks directly, with an href= attribute |
| 58 | ** in the HTML. Link puts an id= attribute in HTML and then adds the |
| 59 | ** href= attribute using javascript. The Link option is designed to make |
| 60 | ** it harder for bots and spiders to follow hyperlinks, and yet give the |
| 61 | ** same experience to users. the Hyperlink permission is a composite which |
| 62 | ** is enabled if either History or Hyperlink is turned on. |
| 63 | */ |
| 64 | struct FossilUserPerms { |
| 65 | char Setup; /* s: use Setup screens on web interface */ |
| 66 | char Admin; /* a: administrative permission */ |
| 67 | char Delete; /* d: delete wiki or tickets */ |
| @@ -61,10 +68,11 @@ | |
| 68 | char Password; /* p: change password */ |
| 69 | char Query; /* q: create new reports */ |
| 70 | char Write; /* i: xfer inbound. checkin */ |
| 71 | char Read; /* o: xfer outbound. checkout */ |
| 72 | char History; /* h: access historical information. */ |
| 73 | char Link; /* l: enable href= using javascript */ |
| 74 | char Clone; /* g: clone */ |
| 75 | char RdWiki; /* j: view wiki via web */ |
| 76 | char NewWiki; /* f: create new wiki via web */ |
| 77 | char ApndWiki; /* m: append to wiki via web */ |
| 78 | char WrWiki; /* k: edit wiki via web */ |
| @@ -75,10 +83,11 @@ | |
| 83 | char Attach; /* b: add attachments */ |
| 84 | char TktFmt; /* t: create new ticket report formats */ |
| 85 | char RdAddr; /* e: read email addresses or other private data */ |
| 86 | char Zip; /* z: download zipped artifact via /zip URL */ |
| 87 | char Private; /* x: can send and receive private content */ |
| 88 | char Hyperlink; /* "h" or "l" */ |
| 89 | }; |
| 90 | |
| 91 | #ifdef FOSSIL_ENABLE_TCL |
| 92 | /* |
| 93 | ** All Tcl related context information is in this structure. This structure |
| 94 |
+7
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -47,10 +47,11 @@ | ||
| 47 | 47 | #define etFOSSILIZE 19 /* The fossil header encoding format. */ |
| 48 | 48 | #define etPATH 20 /* Path type */ |
| 49 | 49 | #define etWIKISTR 21 /* Wiki text rendered from a char*: %w */ |
| 50 | 50 | #define etWIKIBLOB 22 /* Wiki text rendered from a Blob*: %W */ |
| 51 | 51 | #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ |
| 52 | +#define etROOT 24 /* String value of g.zTop: % */ | |
| 52 | 53 | |
| 53 | 54 | |
| 54 | 55 | /* |
| 55 | 56 | ** An "etByte" is an 8-bit unsigned value. |
| 56 | 57 | */ |
| @@ -93,10 +94,11 @@ | ||
| 93 | 94 | { 'b', 0, 2, etBLOB, 0, 0 }, |
| 94 | 95 | { 'B', 0, 2, etBLOBSQL, 0, 0 }, |
| 95 | 96 | { 'w', 0, 2, etWIKISTR, 0, 0 }, |
| 96 | 97 | { 'W', 0, 2, etWIKIBLOB, 0, 0 }, |
| 97 | 98 | { 'h', 0, 4, etHTMLIZE, 0, 0 }, |
| 99 | + { 'R', 0, 0, etROOT, 0, 0 }, | |
| 98 | 100 | { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ |
| 99 | 101 | { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ |
| 100 | 102 | { 'F', 0, 4, etFOSSILIZE, 0, 0 }, |
| 101 | 103 | { 'S', 0, 4, etSTRINGID, 0, 0 }, |
| 102 | 104 | { 'c', 0, 0, etCHARX, 0, 0 }, |
| @@ -570,10 +572,15 @@ | ||
| 570 | 572 | bufpt[i]=e[i]; |
| 571 | 573 | } |
| 572 | 574 | } |
| 573 | 575 | bufpt[length]='\0'; |
| 574 | 576 | break; |
| 577 | + } | |
| 578 | + case etROOT: { | |
| 579 | + bufpt = g.zTop; | |
| 580 | + length = (int)strlen(bufpt); | |
| 581 | + break; | |
| 575 | 582 | } |
| 576 | 583 | case etSTRINGID: { |
| 577 | 584 | precision = 16; |
| 578 | 585 | /* Fall through */ |
| 579 | 586 | } |
| 580 | 587 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -47,10 +47,11 @@ | |
| 47 | #define etFOSSILIZE 19 /* The fossil header encoding format. */ |
| 48 | #define etPATH 20 /* Path type */ |
| 49 | #define etWIKISTR 21 /* Wiki text rendered from a char*: %w */ |
| 50 | #define etWIKIBLOB 22 /* Wiki text rendered from a Blob*: %W */ |
| 51 | #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ |
| 52 | |
| 53 | |
| 54 | /* |
| 55 | ** An "etByte" is an 8-bit unsigned value. |
| 56 | */ |
| @@ -93,10 +94,11 @@ | |
| 93 | { 'b', 0, 2, etBLOB, 0, 0 }, |
| 94 | { 'B', 0, 2, etBLOBSQL, 0, 0 }, |
| 95 | { 'w', 0, 2, etWIKISTR, 0, 0 }, |
| 96 | { 'W', 0, 2, etWIKIBLOB, 0, 0 }, |
| 97 | { 'h', 0, 4, etHTMLIZE, 0, 0 }, |
| 98 | { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ |
| 99 | { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ |
| 100 | { 'F', 0, 4, etFOSSILIZE, 0, 0 }, |
| 101 | { 'S', 0, 4, etSTRINGID, 0, 0 }, |
| 102 | { 'c', 0, 0, etCHARX, 0, 0 }, |
| @@ -570,10 +572,15 @@ | |
| 570 | bufpt[i]=e[i]; |
| 571 | } |
| 572 | } |
| 573 | bufpt[length]='\0'; |
| 574 | break; |
| 575 | } |
| 576 | case etSTRINGID: { |
| 577 | precision = 16; |
| 578 | /* Fall through */ |
| 579 | } |
| 580 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -47,10 +47,11 @@ | |
| 47 | #define etFOSSILIZE 19 /* The fossil header encoding format. */ |
| 48 | #define etPATH 20 /* Path type */ |
| 49 | #define etWIKISTR 21 /* Wiki text rendered from a char*: %w */ |
| 50 | #define etWIKIBLOB 22 /* Wiki text rendered from a Blob*: %W */ |
| 51 | #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ |
| 52 | #define etROOT 24 /* String value of g.zTop: % */ |
| 53 | |
| 54 | |
| 55 | /* |
| 56 | ** An "etByte" is an 8-bit unsigned value. |
| 57 | */ |
| @@ -93,10 +94,11 @@ | |
| 94 | { 'b', 0, 2, etBLOB, 0, 0 }, |
| 95 | { 'B', 0, 2, etBLOBSQL, 0, 0 }, |
| 96 | { 'w', 0, 2, etWIKISTR, 0, 0 }, |
| 97 | { 'W', 0, 2, etWIKIBLOB, 0, 0 }, |
| 98 | { 'h', 0, 4, etHTMLIZE, 0, 0 }, |
| 99 | { 'R', 0, 0, etROOT, 0, 0 }, |
| 100 | { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ |
| 101 | { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ |
| 102 | { 'F', 0, 4, etFOSSILIZE, 0, 0 }, |
| 103 | { 'S', 0, 4, etSTRINGID, 0, 0 }, |
| 104 | { 'c', 0, 0, etCHARX, 0, 0 }, |
| @@ -570,10 +572,15 @@ | |
| 572 | bufpt[i]=e[i]; |
| 573 | } |
| 574 | } |
| 575 | bufpt[length]='\0'; |
| 576 | break; |
| 577 | } |
| 578 | case etROOT: { |
| 579 | bufpt = g.zTop; |
| 580 | length = (int)strlen(bufpt); |
| 581 | break; |
| 582 | } |
| 583 | case etSTRINGID: { |
| 584 | precision = 16; |
| 585 | /* Fall through */ |
| 586 | } |
| 587 |
+10
-11
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -56,26 +56,29 @@ | ||
| 56 | 56 | cnt++; |
| 57 | 57 | blob_appendf(&ril, "<li>"); |
| 58 | 58 | if( zTitle[0] == '_' ){ |
| 59 | 59 | blob_appendf(&ril, "%s", zTitle); |
| 60 | 60 | } else { |
| 61 | - blob_appendf(&ril, "<a href=\"rptview?rn=%d\" rel=\"nofollow\">%h</a>", rn, zTitle); | |
| 61 | + blob_appendf(&ril, "%z%h</a>", href("%R/rptview?rn=%d", rn), zTitle); | |
| 62 | 62 | } |
| 63 | 63 | blob_appendf(&ril, " "); |
| 64 | 64 | if( g.perm.Write && zOwner && zOwner[0] ){ |
| 65 | 65 | blob_appendf(&ril, "(by <i>%h</i></i>) ", zOwner); |
| 66 | 66 | } |
| 67 | 67 | if( g.perm.TktFmt ){ |
| 68 | - blob_appendf(&ril, "[<a href=\"rptedit?rn=%d&copy=1\" rel=\"nofollow\">copy</a>] ", rn); | |
| 68 | + blob_appendf(&ril, "[%zcopy</a>] ", | |
| 69 | + href("%R/rptedit?rn=%d&copy=1", rn)); | |
| 69 | 70 | } |
| 70 | 71 | if( g.perm.Admin |
| 71 | 72 | || (g.perm.WrTkt && zOwner && fossil_strcmp(g.zLogin,zOwner)==0) |
| 72 | 73 | ){ |
| 73 | - blob_appendf(&ril, "[<a href=\"rptedit?rn=%d\" rel=\"nofollow\">edit</a>] ", rn); | |
| 74 | + blob_appendf(&ril, "[%zedit</a>]", | |
| 75 | + href("%R/rptedit?rn=%d", rn)); | |
| 74 | 76 | } |
| 75 | 77 | if( g.perm.TktFmt ){ |
| 76 | - blob_appendf(&ril, "[<a href=\"rptsql?rn=%d\" rel=\"nofollow\">sql</a>] ", rn); | |
| 78 | + blob_appendf(&ril, "[%zsql</a>]", | |
| 79 | + href("%R/rptsql?rn=%d", rn)); | |
| 77 | 80 | } |
| 78 | 81 | blob_appendf(&ril, "</li>\n"); |
| 79 | 82 | } |
| 80 | 83 | |
| 81 | 84 | Th_Store("report_items", blob_str(&ril)); |
| @@ -720,11 +723,11 @@ | ||
| 720 | 723 | if( i==pState->iBg ) continue; |
| 721 | 724 | zData = azArg[i]; |
| 722 | 725 | if( zData==0 ) zData = ""; |
| 723 | 726 | if( pState->iNewRow>=0 && i>=pState->iNewRow ){ |
| 724 | 727 | if( zTid && g.perm.Write ){ |
| 725 | - @ <td valign="top"><a href="tktedit/%h(zTid)">edit</a></td> | |
| 728 | + @ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td> | |
| 726 | 729 | zTid = 0; |
| 727 | 730 | } |
| 728 | 731 | if( zData[0] ){ |
| 729 | 732 | Blob content; |
| 730 | 733 | @ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)> |
| @@ -732,25 +735,21 @@ | ||
| 732 | 735 | wiki_convert(&content, 0, 0); |
| 733 | 736 | blob_reset(&content); |
| 734 | 737 | } |
| 735 | 738 | }else if( azName[i][0]=='#' ){ |
| 736 | 739 | zTid = zData; |
| 737 | - if( g.perm.History ){ | |
| 738 | - @ <td valign="top"><a href="tktview?name=%h(zData)">%h(zData)</a></td> | |
| 739 | - }else{ | |
| 740 | - @ <td valign="top">%h(zData)</td> | |
| 741 | - } | |
| 740 | + @ <td valign="top">%z(href("%R/tktview?name=%h",zData))%h(zData)</a></td> | |
| 742 | 741 | }else if( zData[0]==0 ){ |
| 743 | 742 | @ <td valign="top"> </td> |
| 744 | 743 | }else{ |
| 745 | 744 | @ <td valign="top"> |
| 746 | 745 | @ %h(zData) |
| 747 | 746 | @ </td> |
| 748 | 747 | } |
| 749 | 748 | } |
| 750 | 749 | if( zTid && g.perm.Write ){ |
| 751 | - @ <td valign="top"><a href="tktedit/%h(zTid)">edit</a></td> | |
| 750 | + @ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td> | |
| 752 | 751 | } |
| 753 | 752 | @ </tr> |
| 754 | 753 | return 0; |
| 755 | 754 | } |
| 756 | 755 | |
| 757 | 756 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -56,26 +56,29 @@ | |
| 56 | cnt++; |
| 57 | blob_appendf(&ril, "<li>"); |
| 58 | if( zTitle[0] == '_' ){ |
| 59 | blob_appendf(&ril, "%s", zTitle); |
| 60 | } else { |
| 61 | blob_appendf(&ril, "<a href=\"rptview?rn=%d\" rel=\"nofollow\">%h</a>", rn, zTitle); |
| 62 | } |
| 63 | blob_appendf(&ril, " "); |
| 64 | if( g.perm.Write && zOwner && zOwner[0] ){ |
| 65 | blob_appendf(&ril, "(by <i>%h</i></i>) ", zOwner); |
| 66 | } |
| 67 | if( g.perm.TktFmt ){ |
| 68 | blob_appendf(&ril, "[<a href=\"rptedit?rn=%d&copy=1\" rel=\"nofollow\">copy</a>] ", rn); |
| 69 | } |
| 70 | if( g.perm.Admin |
| 71 | || (g.perm.WrTkt && zOwner && fossil_strcmp(g.zLogin,zOwner)==0) |
| 72 | ){ |
| 73 | blob_appendf(&ril, "[<a href=\"rptedit?rn=%d\" rel=\"nofollow\">edit</a>] ", rn); |
| 74 | } |
| 75 | if( g.perm.TktFmt ){ |
| 76 | blob_appendf(&ril, "[<a href=\"rptsql?rn=%d\" rel=\"nofollow\">sql</a>] ", rn); |
| 77 | } |
| 78 | blob_appendf(&ril, "</li>\n"); |
| 79 | } |
| 80 | |
| 81 | Th_Store("report_items", blob_str(&ril)); |
| @@ -720,11 +723,11 @@ | |
| 720 | if( i==pState->iBg ) continue; |
| 721 | zData = azArg[i]; |
| 722 | if( zData==0 ) zData = ""; |
| 723 | if( pState->iNewRow>=0 && i>=pState->iNewRow ){ |
| 724 | if( zTid && g.perm.Write ){ |
| 725 | @ <td valign="top"><a href="tktedit/%h(zTid)">edit</a></td> |
| 726 | zTid = 0; |
| 727 | } |
| 728 | if( zData[0] ){ |
| 729 | Blob content; |
| 730 | @ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)> |
| @@ -732,25 +735,21 @@ | |
| 732 | wiki_convert(&content, 0, 0); |
| 733 | blob_reset(&content); |
| 734 | } |
| 735 | }else if( azName[i][0]=='#' ){ |
| 736 | zTid = zData; |
| 737 | if( g.perm.History ){ |
| 738 | @ <td valign="top"><a href="tktview?name=%h(zData)">%h(zData)</a></td> |
| 739 | }else{ |
| 740 | @ <td valign="top">%h(zData)</td> |
| 741 | } |
| 742 | }else if( zData[0]==0 ){ |
| 743 | @ <td valign="top"> </td> |
| 744 | }else{ |
| 745 | @ <td valign="top"> |
| 746 | @ %h(zData) |
| 747 | @ </td> |
| 748 | } |
| 749 | } |
| 750 | if( zTid && g.perm.Write ){ |
| 751 | @ <td valign="top"><a href="tktedit/%h(zTid)">edit</a></td> |
| 752 | } |
| 753 | @ </tr> |
| 754 | return 0; |
| 755 | } |
| 756 | |
| 757 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -56,26 +56,29 @@ | |
| 56 | cnt++; |
| 57 | blob_appendf(&ril, "<li>"); |
| 58 | if( zTitle[0] == '_' ){ |
| 59 | blob_appendf(&ril, "%s", zTitle); |
| 60 | } else { |
| 61 | blob_appendf(&ril, "%z%h</a>", href("%R/rptview?rn=%d", rn), zTitle); |
| 62 | } |
| 63 | blob_appendf(&ril, " "); |
| 64 | if( g.perm.Write && zOwner && zOwner[0] ){ |
| 65 | blob_appendf(&ril, "(by <i>%h</i></i>) ", zOwner); |
| 66 | } |
| 67 | if( g.perm.TktFmt ){ |
| 68 | blob_appendf(&ril, "[%zcopy</a>] ", |
| 69 | href("%R/rptedit?rn=%d&copy=1", rn)); |
| 70 | } |
| 71 | if( g.perm.Admin |
| 72 | || (g.perm.WrTkt && zOwner && fossil_strcmp(g.zLogin,zOwner)==0) |
| 73 | ){ |
| 74 | blob_appendf(&ril, "[%zedit</a>]", |
| 75 | href("%R/rptedit?rn=%d", rn)); |
| 76 | } |
| 77 | if( g.perm.TktFmt ){ |
| 78 | blob_appendf(&ril, "[%zsql</a>]", |
| 79 | href("%R/rptsql?rn=%d", rn)); |
| 80 | } |
| 81 | blob_appendf(&ril, "</li>\n"); |
| 82 | } |
| 83 | |
| 84 | Th_Store("report_items", blob_str(&ril)); |
| @@ -720,11 +723,11 @@ | |
| 723 | if( i==pState->iBg ) continue; |
| 724 | zData = azArg[i]; |
| 725 | if( zData==0 ) zData = ""; |
| 726 | if( pState->iNewRow>=0 && i>=pState->iNewRow ){ |
| 727 | if( zTid && g.perm.Write ){ |
| 728 | @ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td> |
| 729 | zTid = 0; |
| 730 | } |
| 731 | if( zData[0] ){ |
| 732 | Blob content; |
| 733 | @ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)> |
| @@ -732,25 +735,21 @@ | |
| 735 | wiki_convert(&content, 0, 0); |
| 736 | blob_reset(&content); |
| 737 | } |
| 738 | }else if( azName[i][0]=='#' ){ |
| 739 | zTid = zData; |
| 740 | @ <td valign="top">%z(href("%R/tktview?name=%h",zData))%h(zData)</a></td> |
| 741 | }else if( zData[0]==0 ){ |
| 742 | @ <td valign="top"> </td> |
| 743 | }else{ |
| 744 | @ <td valign="top"> |
| 745 | @ %h(zData) |
| 746 | @ </td> |
| 747 | } |
| 748 | } |
| 749 | if( zTid && g.perm.Write ){ |
| 750 | @ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td> |
| 751 | } |
| 752 | @ </tr> |
| 753 | return 0; |
| 754 | } |
| 755 | |
| 756 |
+18
-9
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -170,10 +170,13 @@ | ||
| 170 | 170 | @ <td><i>Check-In:</i> Commit new versions in the repository</td></tr> |
| 171 | 171 | @ <tr><td valign="top"><b>j</b></td> |
| 172 | 172 | @ <td><i>Read-Wiki:</i> View wiki pages</td></tr> |
| 173 | 173 | @ <tr><td valign="top"><b>k</b></td> |
| 174 | 174 | @ <td><i>Write-Wiki:</i> Edit wiki pages</td></tr> |
| 175 | + @ <tr><td valign="top"><b>l</b></td> | |
| 176 | + @ <td><i>Link-Late:</i> Use javascript for hyperlinks to | |
| 177 | + @ discourage bots</td></tr> | |
| 175 | 178 | @ <tr><td valign="top"><b>m</b></td> |
| 176 | 179 | @ <td><i>Append-Wiki:</i> Append to wiki pages</td></tr> |
| 177 | 180 | @ <tr><td valign="top"><b>n</b></td> |
| 178 | 181 | @ <td><i>New-Tkt:</i> Create new tickets</td></tr> |
| 179 | 182 | @ <tr><td valign="top"><b>o</b></td> |
| @@ -248,11 +251,11 @@ | ||
| 248 | 251 | ** WEBPAGE: /setup_uedit |
| 249 | 252 | */ |
| 250 | 253 | void user_edit(void){ |
| 251 | 254 | const char *zId, *zLogin, *zInfo, *zCap, *zPw; |
| 252 | 255 | char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap; |
| 253 | - char *oak, *oad, *oac, *oaf, *oam, *oah, *oag, *oae; | |
| 256 | + char *oak, *oad, *oac, *oaf, *oam, *oah, *oal, *oag, *oae; | |
| 254 | 257 | char *oat, *oau, *oav, *oab, *oax, *oaz; |
| 255 | 258 | const char *zGroup; |
| 256 | 259 | const char *zOldLogin; |
| 257 | 260 | char *inherit[128]; |
| 258 | 261 | int doWrite; |
| @@ -304,10 +307,11 @@ | ||
| 304 | 307 | int aw = P("aw")!=0; |
| 305 | 308 | int ac = P("ac")!=0; |
| 306 | 309 | int af = P("af")!=0; |
| 307 | 310 | int am = P("am")!=0; |
| 308 | 311 | int ah = P("ah")!=0; |
| 312 | + int al = P("al")!=0; | |
| 309 | 313 | int ag = P("ag")!=0; |
| 310 | 314 | int at = P("at")!=0; |
| 311 | 315 | int au = P("au")!=0; |
| 312 | 316 | int av = P("av")!=0; |
| 313 | 317 | int ax = P("ax")!=0; |
| @@ -321,10 +325,11 @@ | ||
| 321 | 325 | if( ah ){ zCap[i++] = 'h'; } |
| 322 | 326 | if( ag ){ zCap[i++] = 'g'; } |
| 323 | 327 | if( ai ){ zCap[i++] = 'i'; } |
| 324 | 328 | if( aj ){ zCap[i++] = 'j'; } |
| 325 | 329 | if( ak ){ zCap[i++] = 'k'; } |
| 330 | + if( al ){ zCap[i++] = 'l'; } | |
| 326 | 331 | if( am ){ zCap[i++] = 'm'; } |
| 327 | 332 | if( an ){ zCap[i++] = 'n'; } |
| 328 | 333 | if( ao ){ zCap[i++] = 'o'; } |
| 329 | 334 | if( ap ){ zCap[i++] = 'p'; } |
| 330 | 335 | if( ar ){ zCap[i++] = 'r'; } |
| @@ -412,11 +417,11 @@ | ||
| 412 | 417 | */ |
| 413 | 418 | zLogin = ""; |
| 414 | 419 | zInfo = ""; |
| 415 | 420 | zCap = ""; |
| 416 | 421 | zPw = ""; |
| 417 | - oaa = oab = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oam = | |
| 422 | + oaa = oab = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oal = oam = | |
| 418 | 423 | oan = oao = oap = oar = oas = oat = oau = oav = oaw = oax = oaz = ""; |
| 419 | 424 | if( uid ){ |
| 420 | 425 | zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); |
| 421 | 426 | zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); |
| 422 | 427 | zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); |
| @@ -430,10 +435,11 @@ | ||
| 430 | 435 | if( strchr(zCap, 'g') ) oag = " checked=\"checked\""; |
| 431 | 436 | if( strchr(zCap, 'h') ) oah = " checked=\"checked\""; |
| 432 | 437 | if( strchr(zCap, 'i') ) oai = " checked=\"checked\""; |
| 433 | 438 | if( strchr(zCap, 'j') ) oaj = " checked=\"checked\""; |
| 434 | 439 | if( strchr(zCap, 'k') ) oak = " checked=\"checked\""; |
| 440 | + if( strchr(zCap, 'l') ) oal = " checked=\"checked\""; | |
| 435 | 441 | if( strchr(zCap, 'm') ) oam = " checked=\"checked\""; |
| 436 | 442 | if( strchr(zCap, 'n') ) oan = " checked=\"checked\""; |
| 437 | 443 | if( strchr(zCap, 'o') ) oao = " checked=\"checked\""; |
| 438 | 444 | if( strchr(zCap, 'p') ) oap = " checked=\"checked\""; |
| 439 | 445 | if( strchr(zCap, 'r') ) oar = " checked=\"checked\""; |
| @@ -524,11 +530,12 @@ | ||
| 524 | 530 | @ <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br /> |
| 525 | 531 | @ <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br /> |
| 526 | 532 | @ <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br /> |
| 527 | 533 | @ <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br /> |
| 528 | 534 | @ <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br /> |
| 529 | - @ <input type="checkbox" name="ah"%s(oah) />%s(B('h'))History<br /> | |
| 535 | + @ <input type="checkbox" name="ah"%s(oah) />%s(B('h'))Hyperlinks<br /> | |
| 536 | + @ <input type="checkbox" name="al"%s(oal) />%s(B('l'))Links-deferred<br /> | |
| 530 | 537 | @ <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br /> |
| 531 | 538 | @ <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br /> |
| 532 | 539 | @ <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br /> |
| 533 | 540 | @ <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br /> |
| 534 | 541 | @ <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br /> |
| @@ -625,24 +632,26 @@ | ||
| 625 | 632 | @ is first posted. The <span class="usertype">Setup</span> user can |
| 626 | 633 | @ delete anything at any time. |
| 627 | 634 | @ </p></li> |
| 628 | 635 | @ |
| 629 | 636 | @ <li><p> |
| 630 | - @ The <span class="capability">History</span> privilege allows a user | |
| 637 | + @ The <span class="capability">Hyperlinks</span> privilege allows a user | |
| 631 | 638 | @ to see most hyperlinks. This is recommended ON for most logged-in users |
| 632 | 639 | @ but OFF for user "nobody" to avoid problems with spiders trying to walk |
| 633 | - @ every historical version of every baseline and file. | |
| 640 | + @ every historical version of every baseline and file. The | |
| 641 | + @ <span class="capability">Link-deferred</span> privilege enables hyperlinks | |
| 642 | + @ using javascript, which makes them harder for bots and spiders to find. | |
| 634 | 643 | @ </p></li> |
| 635 | 644 | @ |
| 636 | 645 | @ <li><p> |
| 637 | 646 | @ The <span class="capability">Zip</span> privilege allows a user to |
| 638 | 647 | @ see the "download as ZIP" |
| 639 | 648 | @ hyperlink and permits access to the <tt>/zip</tt> page. This allows |
| 640 | 649 | @ users to download ZIP archives without granting other rights like |
| 641 | 650 | @ <span class="capability">Read</span> or |
| 642 | - @ <span class="capability">History</span>. This privilege is recommended for | |
| 643 | - @ user <span class="usertype">nobody</span> so that automatic package | |
| 651 | + @ <span class="capability">Hyperlink</span>. The "z" privilege is recommended | |
| 652 | + @ for user <span class="usertype">nobody</span> so that automatic package | |
| 644 | 653 | @ downloaders can obtain the sources without going through the login |
| 645 | 654 | @ procedure. |
| 646 | 655 | @ </p></li> |
| 647 | 656 | @ |
| 648 | 657 | @ <li><p> |
| @@ -704,12 +713,12 @@ | ||
| 704 | 713 | @ To disable universal access to the repository, make sure no user named |
| 705 | 714 | @ <span class="usertype">nobody</span> exists or that the |
| 706 | 715 | @ <span class="usertype">nobody</span> user has no capabilities |
| 707 | 716 | @ enabled. The password for <span class="usertype">nobody</span> is ignore. |
| 708 | 717 | @ To avoid problems with spiders overloading the server, it is recommended |
| 709 | - @ that the <span class="capability">h</span> (History) capability be turned | |
| 710 | - @ off for the <span class="usertype">nobody</span> user. | |
| 718 | + @ that the <span class="capability">h</span> (Hyperlinks) capability be | |
| 719 | + @ turned off for the <span class="usertype">nobody</span> user. | |
| 711 | 720 | @ </p></li> |
| 712 | 721 | @ |
| 713 | 722 | @ <li><p> |
| 714 | 723 | @ Login is required for user <span class="usertype">anonymous</span> but the |
| 715 | 724 | @ password is displayed on the login screen beside the password entry box |
| 716 | 725 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -170,10 +170,13 @@ | |
| 170 | @ <td><i>Check-In:</i> Commit new versions in the repository</td></tr> |
| 171 | @ <tr><td valign="top"><b>j</b></td> |
| 172 | @ <td><i>Read-Wiki:</i> View wiki pages</td></tr> |
| 173 | @ <tr><td valign="top"><b>k</b></td> |
| 174 | @ <td><i>Write-Wiki:</i> Edit wiki pages</td></tr> |
| 175 | @ <tr><td valign="top"><b>m</b></td> |
| 176 | @ <td><i>Append-Wiki:</i> Append to wiki pages</td></tr> |
| 177 | @ <tr><td valign="top"><b>n</b></td> |
| 178 | @ <td><i>New-Tkt:</i> Create new tickets</td></tr> |
| 179 | @ <tr><td valign="top"><b>o</b></td> |
| @@ -248,11 +251,11 @@ | |
| 248 | ** WEBPAGE: /setup_uedit |
| 249 | */ |
| 250 | void user_edit(void){ |
| 251 | const char *zId, *zLogin, *zInfo, *zCap, *zPw; |
| 252 | char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap; |
| 253 | char *oak, *oad, *oac, *oaf, *oam, *oah, *oag, *oae; |
| 254 | char *oat, *oau, *oav, *oab, *oax, *oaz; |
| 255 | const char *zGroup; |
| 256 | const char *zOldLogin; |
| 257 | char *inherit[128]; |
| 258 | int doWrite; |
| @@ -304,10 +307,11 @@ | |
| 304 | int aw = P("aw")!=0; |
| 305 | int ac = P("ac")!=0; |
| 306 | int af = P("af")!=0; |
| 307 | int am = P("am")!=0; |
| 308 | int ah = P("ah")!=0; |
| 309 | int ag = P("ag")!=0; |
| 310 | int at = P("at")!=0; |
| 311 | int au = P("au")!=0; |
| 312 | int av = P("av")!=0; |
| 313 | int ax = P("ax")!=0; |
| @@ -321,10 +325,11 @@ | |
| 321 | if( ah ){ zCap[i++] = 'h'; } |
| 322 | if( ag ){ zCap[i++] = 'g'; } |
| 323 | if( ai ){ zCap[i++] = 'i'; } |
| 324 | if( aj ){ zCap[i++] = 'j'; } |
| 325 | if( ak ){ zCap[i++] = 'k'; } |
| 326 | if( am ){ zCap[i++] = 'm'; } |
| 327 | if( an ){ zCap[i++] = 'n'; } |
| 328 | if( ao ){ zCap[i++] = 'o'; } |
| 329 | if( ap ){ zCap[i++] = 'p'; } |
| 330 | if( ar ){ zCap[i++] = 'r'; } |
| @@ -412,11 +417,11 @@ | |
| 412 | */ |
| 413 | zLogin = ""; |
| 414 | zInfo = ""; |
| 415 | zCap = ""; |
| 416 | zPw = ""; |
| 417 | oaa = oab = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oam = |
| 418 | oan = oao = oap = oar = oas = oat = oau = oav = oaw = oax = oaz = ""; |
| 419 | if( uid ){ |
| 420 | zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); |
| 421 | zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); |
| 422 | zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); |
| @@ -430,10 +435,11 @@ | |
| 430 | if( strchr(zCap, 'g') ) oag = " checked=\"checked\""; |
| 431 | if( strchr(zCap, 'h') ) oah = " checked=\"checked\""; |
| 432 | if( strchr(zCap, 'i') ) oai = " checked=\"checked\""; |
| 433 | if( strchr(zCap, 'j') ) oaj = " checked=\"checked\""; |
| 434 | if( strchr(zCap, 'k') ) oak = " checked=\"checked\""; |
| 435 | if( strchr(zCap, 'm') ) oam = " checked=\"checked\""; |
| 436 | if( strchr(zCap, 'n') ) oan = " checked=\"checked\""; |
| 437 | if( strchr(zCap, 'o') ) oao = " checked=\"checked\""; |
| 438 | if( strchr(zCap, 'p') ) oap = " checked=\"checked\""; |
| 439 | if( strchr(zCap, 'r') ) oar = " checked=\"checked\""; |
| @@ -524,11 +530,12 @@ | |
| 524 | @ <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br /> |
| 525 | @ <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br /> |
| 526 | @ <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br /> |
| 527 | @ <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br /> |
| 528 | @ <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br /> |
| 529 | @ <input type="checkbox" name="ah"%s(oah) />%s(B('h'))History<br /> |
| 530 | @ <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br /> |
| 531 | @ <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br /> |
| 532 | @ <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br /> |
| 533 | @ <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br /> |
| 534 | @ <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br /> |
| @@ -625,24 +632,26 @@ | |
| 625 | @ is first posted. The <span class="usertype">Setup</span> user can |
| 626 | @ delete anything at any time. |
| 627 | @ </p></li> |
| 628 | @ |
| 629 | @ <li><p> |
| 630 | @ The <span class="capability">History</span> privilege allows a user |
| 631 | @ to see most hyperlinks. This is recommended ON for most logged-in users |
| 632 | @ but OFF for user "nobody" to avoid problems with spiders trying to walk |
| 633 | @ every historical version of every baseline and file. |
| 634 | @ </p></li> |
| 635 | @ |
| 636 | @ <li><p> |
| 637 | @ The <span class="capability">Zip</span> privilege allows a user to |
| 638 | @ see the "download as ZIP" |
| 639 | @ hyperlink and permits access to the <tt>/zip</tt> page. This allows |
| 640 | @ users to download ZIP archives without granting other rights like |
| 641 | @ <span class="capability">Read</span> or |
| 642 | @ <span class="capability">History</span>. This privilege is recommended for |
| 643 | @ user <span class="usertype">nobody</span> so that automatic package |
| 644 | @ downloaders can obtain the sources without going through the login |
| 645 | @ procedure. |
| 646 | @ </p></li> |
| 647 | @ |
| 648 | @ <li><p> |
| @@ -704,12 +713,12 @@ | |
| 704 | @ To disable universal access to the repository, make sure no user named |
| 705 | @ <span class="usertype">nobody</span> exists or that the |
| 706 | @ <span class="usertype">nobody</span> user has no capabilities |
| 707 | @ enabled. The password for <span class="usertype">nobody</span> is ignore. |
| 708 | @ To avoid problems with spiders overloading the server, it is recommended |
| 709 | @ that the <span class="capability">h</span> (History) capability be turned |
| 710 | @ off for the <span class="usertype">nobody</span> user. |
| 711 | @ </p></li> |
| 712 | @ |
| 713 | @ <li><p> |
| 714 | @ Login is required for user <span class="usertype">anonymous</span> but the |
| 715 | @ password is displayed on the login screen beside the password entry box |
| 716 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -170,10 +170,13 @@ | |
| 170 | @ <td><i>Check-In:</i> Commit new versions in the repository</td></tr> |
| 171 | @ <tr><td valign="top"><b>j</b></td> |
| 172 | @ <td><i>Read-Wiki:</i> View wiki pages</td></tr> |
| 173 | @ <tr><td valign="top"><b>k</b></td> |
| 174 | @ <td><i>Write-Wiki:</i> Edit wiki pages</td></tr> |
| 175 | @ <tr><td valign="top"><b>l</b></td> |
| 176 | @ <td><i>Link-Late:</i> Use javascript for hyperlinks to |
| 177 | @ discourage bots</td></tr> |
| 178 | @ <tr><td valign="top"><b>m</b></td> |
| 179 | @ <td><i>Append-Wiki:</i> Append to wiki pages</td></tr> |
| 180 | @ <tr><td valign="top"><b>n</b></td> |
| 181 | @ <td><i>New-Tkt:</i> Create new tickets</td></tr> |
| 182 | @ <tr><td valign="top"><b>o</b></td> |
| @@ -248,11 +251,11 @@ | |
| 251 | ** WEBPAGE: /setup_uedit |
| 252 | */ |
| 253 | void user_edit(void){ |
| 254 | const char *zId, *zLogin, *zInfo, *zCap, *zPw; |
| 255 | char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap; |
| 256 | char *oak, *oad, *oac, *oaf, *oam, *oah, *oal, *oag, *oae; |
| 257 | char *oat, *oau, *oav, *oab, *oax, *oaz; |
| 258 | const char *zGroup; |
| 259 | const char *zOldLogin; |
| 260 | char *inherit[128]; |
| 261 | int doWrite; |
| @@ -304,10 +307,11 @@ | |
| 307 | int aw = P("aw")!=0; |
| 308 | int ac = P("ac")!=0; |
| 309 | int af = P("af")!=0; |
| 310 | int am = P("am")!=0; |
| 311 | int ah = P("ah")!=0; |
| 312 | int al = P("al")!=0; |
| 313 | int ag = P("ag")!=0; |
| 314 | int at = P("at")!=0; |
| 315 | int au = P("au")!=0; |
| 316 | int av = P("av")!=0; |
| 317 | int ax = P("ax")!=0; |
| @@ -321,10 +325,11 @@ | |
| 325 | if( ah ){ zCap[i++] = 'h'; } |
| 326 | if( ag ){ zCap[i++] = 'g'; } |
| 327 | if( ai ){ zCap[i++] = 'i'; } |
| 328 | if( aj ){ zCap[i++] = 'j'; } |
| 329 | if( ak ){ zCap[i++] = 'k'; } |
| 330 | if( al ){ zCap[i++] = 'l'; } |
| 331 | if( am ){ zCap[i++] = 'm'; } |
| 332 | if( an ){ zCap[i++] = 'n'; } |
| 333 | if( ao ){ zCap[i++] = 'o'; } |
| 334 | if( ap ){ zCap[i++] = 'p'; } |
| 335 | if( ar ){ zCap[i++] = 'r'; } |
| @@ -412,11 +417,11 @@ | |
| 417 | */ |
| 418 | zLogin = ""; |
| 419 | zInfo = ""; |
| 420 | zCap = ""; |
| 421 | zPw = ""; |
| 422 | oaa = oab = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oal = oam = |
| 423 | oan = oao = oap = oar = oas = oat = oau = oav = oaw = oax = oaz = ""; |
| 424 | if( uid ){ |
| 425 | zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); |
| 426 | zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); |
| 427 | zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); |
| @@ -430,10 +435,11 @@ | |
| 435 | if( strchr(zCap, 'g') ) oag = " checked=\"checked\""; |
| 436 | if( strchr(zCap, 'h') ) oah = " checked=\"checked\""; |
| 437 | if( strchr(zCap, 'i') ) oai = " checked=\"checked\""; |
| 438 | if( strchr(zCap, 'j') ) oaj = " checked=\"checked\""; |
| 439 | if( strchr(zCap, 'k') ) oak = " checked=\"checked\""; |
| 440 | if( strchr(zCap, 'l') ) oal = " checked=\"checked\""; |
| 441 | if( strchr(zCap, 'm') ) oam = " checked=\"checked\""; |
| 442 | if( strchr(zCap, 'n') ) oan = " checked=\"checked\""; |
| 443 | if( strchr(zCap, 'o') ) oao = " checked=\"checked\""; |
| 444 | if( strchr(zCap, 'p') ) oap = " checked=\"checked\""; |
| 445 | if( strchr(zCap, 'r') ) oar = " checked=\"checked\""; |
| @@ -524,11 +530,12 @@ | |
| 530 | @ <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br /> |
| 531 | @ <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br /> |
| 532 | @ <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br /> |
| 533 | @ <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br /> |
| 534 | @ <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br /> |
| 535 | @ <input type="checkbox" name="ah"%s(oah) />%s(B('h'))Hyperlinks<br /> |
| 536 | @ <input type="checkbox" name="al"%s(oal) />%s(B('l'))Links-deferred<br /> |
| 537 | @ <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br /> |
| 538 | @ <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br /> |
| 539 | @ <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br /> |
| 540 | @ <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br /> |
| 541 | @ <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br /> |
| @@ -625,24 +632,26 @@ | |
| 632 | @ is first posted. The <span class="usertype">Setup</span> user can |
| 633 | @ delete anything at any time. |
| 634 | @ </p></li> |
| 635 | @ |
| 636 | @ <li><p> |
| 637 | @ The <span class="capability">Hyperlinks</span> privilege allows a user |
| 638 | @ to see most hyperlinks. This is recommended ON for most logged-in users |
| 639 | @ but OFF for user "nobody" to avoid problems with spiders trying to walk |
| 640 | @ every historical version of every baseline and file. The |
| 641 | @ <span class="capability">Link-deferred</span> privilege enables hyperlinks |
| 642 | @ using javascript, which makes them harder for bots and spiders to find. |
| 643 | @ </p></li> |
| 644 | @ |
| 645 | @ <li><p> |
| 646 | @ The <span class="capability">Zip</span> privilege allows a user to |
| 647 | @ see the "download as ZIP" |
| 648 | @ hyperlink and permits access to the <tt>/zip</tt> page. This allows |
| 649 | @ users to download ZIP archives without granting other rights like |
| 650 | @ <span class="capability">Read</span> or |
| 651 | @ <span class="capability">Hyperlink</span>. The "z" privilege is recommended |
| 652 | @ for user <span class="usertype">nobody</span> so that automatic package |
| 653 | @ downloaders can obtain the sources without going through the login |
| 654 | @ procedure. |
| 655 | @ </p></li> |
| 656 | @ |
| 657 | @ <li><p> |
| @@ -704,12 +713,12 @@ | |
| 713 | @ To disable universal access to the repository, make sure no user named |
| 714 | @ <span class="usertype">nobody</span> exists or that the |
| 715 | @ <span class="usertype">nobody</span> user has no capabilities |
| 716 | @ enabled. The password for <span class="usertype">nobody</span> is ignore. |
| 717 | @ To avoid problems with spiders overloading the server, it is recommended |
| 718 | @ that the <span class="capability">h</span> (Hyperlinks) capability be |
| 719 | @ turned off for the <span class="usertype">nobody</span> user. |
| 720 | @ </p></li> |
| 721 | @ |
| 722 | @ <li><p> |
| 723 | @ Login is required for user <span class="usertype">anonymous</span> but the |
| 724 | @ password is displayed on the login screen beside the password entry box |
| 725 |
+86
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -45,10 +45,93 @@ | ||
| 45 | 45 | /* |
| 46 | 46 | ** remember, if a sidebox was used |
| 47 | 47 | */ |
| 48 | 48 | static int sideboxUsed = 0; |
| 49 | 49 | |
| 50 | + | |
| 51 | +/* | |
| 52 | +** List of hyperlinks that need to be resolved by javascript in | |
| 53 | +** the footer. | |
| 54 | +*/ | |
| 55 | +char **aHref = 0; | |
| 56 | +int nHref = 0; | |
| 57 | +int nHrefAlloc = 0; | |
| 58 | + | |
| 59 | +/* | |
| 60 | +** Generate and return a anchor tag like this: | |
| 61 | +** | |
| 62 | +** <a href="URL"> | |
| 63 | +** or <a id="ID"> | |
| 64 | +** | |
| 65 | +** The form of the anchor tag is determined by the g.perm.History | |
| 66 | +** variable. The href="URL" form is used if g.perm.History is true. | |
| 67 | +** If g.perm.History is false and g.perm.Link is true then the | |
| 68 | +** id="ID" form is used and javascript is generated in the footer to cause | |
| 69 | +** href values to be inserted after the page has loaded. If both | |
| 70 | +** g.perm.History and g.perm.Link are false, then the <a id="ID"> form is | |
| 71 | +** generated but the javascript is not generated so the links never | |
| 72 | +** activate. | |
| 73 | +** | |
| 74 | +** Handling the href="URL" using javascript is a defense against bots. | |
| 75 | +** | |
| 76 | +** The name of this routine is deliberately kept short so that can be | |
| 77 | +** easily used within @-lines. Example: | |
| 78 | +** | |
| 79 | +** @ %z(href("%s/artifact/%s",g.zTop,zUuid))%h(zFN)</a> | |
| 80 | +** | |
| 81 | +** Note %z format. The string returned by this function is always | |
| 82 | +** obtained from fossil_malloc(). | |
| 83 | +** | |
| 84 | +** There are two versions of this routine href() does a plain hyperlink | |
| 85 | +** and xhref() adds extra attribute text. | |
| 86 | +*/ | |
| 87 | +char *xhref(const char *zExtra, const char *zFormat, ...){ | |
| 88 | + char *zUrl; | |
| 89 | + va_list ap; | |
| 90 | + va_start(ap, zFormat); | |
| 91 | + zUrl = vmprintf(zFormat, ap); | |
| 92 | + va_end(ap); | |
| 93 | + if( g.perm.History ){ | |
| 94 | + return mprintf("<a %s href=\"%z\">", zExtra, zUrl); | |
| 95 | + } | |
| 96 | + if( nHref>=nHrefAlloc ){ | |
| 97 | + nHrefAlloc = nHrefAlloc*2 + 10; | |
| 98 | + aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); | |
| 99 | + } | |
| 100 | + aHref[nHref++] = zUrl; | |
| 101 | + return mprintf("<a %s id=%d>", zExtra, nHref); | |
| 102 | +} | |
| 103 | +char *href(const char *zFormat, ...){ | |
| 104 | + char *zUrl; | |
| 105 | + va_list ap; | |
| 106 | + va_start(ap, zFormat); | |
| 107 | + zUrl = vmprintf(zFormat, ap); | |
| 108 | + va_end(ap); | |
| 109 | + if( g.perm.History ){ | |
| 110 | + return mprintf("<a href=\"%z\">", zUrl); | |
| 111 | + } | |
| 112 | + if( nHref>=nHrefAlloc ){ | |
| 113 | + nHrefAlloc = nHrefAlloc*2 + 10; | |
| 114 | + aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); | |
| 115 | + } | |
| 116 | + aHref[nHref++] = zUrl; | |
| 117 | + return mprintf("<a id=%d>", nHref); | |
| 118 | +} | |
| 119 | + | |
| 120 | +/* | |
| 121 | +** Generate javascript that will set the href= attribute on all anchors. | |
| 122 | +*/ | |
| 123 | +void style_resolve_href(void){ | |
| 124 | + int i; | |
| 125 | + if( !g.perm.Link || nHref==0 ) return; | |
| 126 | + @ <script> | |
| 127 | + for(i=0; i<nHref; i++){ | |
| 128 | + @ document.getElementById(%d(i+1)).href="%s(aHref[i])"; | |
| 129 | + } | |
| 130 | + @ </script> | |
| 131 | +} | |
| 132 | + | |
| 50 | 133 | /* |
| 51 | 134 | ** Add a new element to the submenu |
| 52 | 135 | */ |
| 53 | 136 | void style_submenu_element( |
| 54 | 137 | const char *zLabel, |
| @@ -164,10 +247,13 @@ | ||
| 164 | 247 | if( g.thTrace ){ |
| 165 | 248 | cgi_append_content("<span class=\"thTrace\"><hr />\n", -1); |
| 166 | 249 | cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog)); |
| 167 | 250 | cgi_append_content("</span>\n", -1); |
| 168 | 251 | } |
| 252 | + | |
| 253 | + /* Set the href= field on hyperlinks */ | |
| 254 | + style_resolve_href(); | |
| 169 | 255 | } |
| 170 | 256 | |
| 171 | 257 | /* |
| 172 | 258 | ** Begin a side-box on the right-hand side of a page. The title and |
| 173 | 259 | ** the width of the box are given as arguments. The width is usually |
| 174 | 260 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -45,10 +45,93 @@ | |
| 45 | /* |
| 46 | ** remember, if a sidebox was used |
| 47 | */ |
| 48 | static int sideboxUsed = 0; |
| 49 | |
| 50 | /* |
| 51 | ** Add a new element to the submenu |
| 52 | */ |
| 53 | void style_submenu_element( |
| 54 | const char *zLabel, |
| @@ -164,10 +247,13 @@ | |
| 164 | if( g.thTrace ){ |
| 165 | cgi_append_content("<span class=\"thTrace\"><hr />\n", -1); |
| 166 | cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog)); |
| 167 | cgi_append_content("</span>\n", -1); |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | /* |
| 172 | ** Begin a side-box on the right-hand side of a page. The title and |
| 173 | ** the width of the box are given as arguments. The width is usually |
| 174 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -45,10 +45,93 @@ | |
| 45 | /* |
| 46 | ** remember, if a sidebox was used |
| 47 | */ |
| 48 | static int sideboxUsed = 0; |
| 49 | |
| 50 | |
| 51 | /* |
| 52 | ** List of hyperlinks that need to be resolved by javascript in |
| 53 | ** the footer. |
| 54 | */ |
| 55 | char **aHref = 0; |
| 56 | int nHref = 0; |
| 57 | int nHrefAlloc = 0; |
| 58 | |
| 59 | /* |
| 60 | ** Generate and return a anchor tag like this: |
| 61 | ** |
| 62 | ** <a href="URL"> |
| 63 | ** or <a id="ID"> |
| 64 | ** |
| 65 | ** The form of the anchor tag is determined by the g.perm.History |
| 66 | ** variable. The href="URL" form is used if g.perm.History is true. |
| 67 | ** If g.perm.History is false and g.perm.Link is true then the |
| 68 | ** id="ID" form is used and javascript is generated in the footer to cause |
| 69 | ** href values to be inserted after the page has loaded. If both |
| 70 | ** g.perm.History and g.perm.Link are false, then the <a id="ID"> form is |
| 71 | ** generated but the javascript is not generated so the links never |
| 72 | ** activate. |
| 73 | ** |
| 74 | ** Handling the href="URL" using javascript is a defense against bots. |
| 75 | ** |
| 76 | ** The name of this routine is deliberately kept short so that can be |
| 77 | ** easily used within @-lines. Example: |
| 78 | ** |
| 79 | ** @ %z(href("%s/artifact/%s",g.zTop,zUuid))%h(zFN)</a> |
| 80 | ** |
| 81 | ** Note %z format. The string returned by this function is always |
| 82 | ** obtained from fossil_malloc(). |
| 83 | ** |
| 84 | ** There are two versions of this routine href() does a plain hyperlink |
| 85 | ** and xhref() adds extra attribute text. |
| 86 | */ |
| 87 | char *xhref(const char *zExtra, const char *zFormat, ...){ |
| 88 | char *zUrl; |
| 89 | va_list ap; |
| 90 | va_start(ap, zFormat); |
| 91 | zUrl = vmprintf(zFormat, ap); |
| 92 | va_end(ap); |
| 93 | if( g.perm.History ){ |
| 94 | return mprintf("<a %s href=\"%z\">", zExtra, zUrl); |
| 95 | } |
| 96 | if( nHref>=nHrefAlloc ){ |
| 97 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 98 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 99 | } |
| 100 | aHref[nHref++] = zUrl; |
| 101 | return mprintf("<a %s id=%d>", zExtra, nHref); |
| 102 | } |
| 103 | char *href(const char *zFormat, ...){ |
| 104 | char *zUrl; |
| 105 | va_list ap; |
| 106 | va_start(ap, zFormat); |
| 107 | zUrl = vmprintf(zFormat, ap); |
| 108 | va_end(ap); |
| 109 | if( g.perm.History ){ |
| 110 | return mprintf("<a href=\"%z\">", zUrl); |
| 111 | } |
| 112 | if( nHref>=nHrefAlloc ){ |
| 113 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 114 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 115 | } |
| 116 | aHref[nHref++] = zUrl; |
| 117 | return mprintf("<a id=%d>", nHref); |
| 118 | } |
| 119 | |
| 120 | /* |
| 121 | ** Generate javascript that will set the href= attribute on all anchors. |
| 122 | */ |
| 123 | void style_resolve_href(void){ |
| 124 | int i; |
| 125 | if( !g.perm.Link || nHref==0 ) return; |
| 126 | @ <script> |
| 127 | for(i=0; i<nHref; i++){ |
| 128 | @ document.getElementById(%d(i+1)).href="%s(aHref[i])"; |
| 129 | } |
| 130 | @ </script> |
| 131 | } |
| 132 | |
| 133 | /* |
| 134 | ** Add a new element to the submenu |
| 135 | */ |
| 136 | void style_submenu_element( |
| 137 | const char *zLabel, |
| @@ -164,10 +247,13 @@ | |
| 247 | if( g.thTrace ){ |
| 248 | cgi_append_content("<span class=\"thTrace\"><hr />\n", -1); |
| 249 | cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog)); |
| 250 | cgi_append_content("</span>\n", -1); |
| 251 | } |
| 252 | |
| 253 | /* Set the href= field on hyperlinks */ |
| 254 | style_resolve_href(); |
| 255 | } |
| 256 | |
| 257 | /* |
| 258 | ** Begin a side-box on the right-hand side of a page. The title and |
| 259 | ** the width of the box are given as arguments. The width is usually |
| 260 |
+2
-2
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -548,12 +548,12 @@ | ||
| 548 | 548 | " ORDER BY tagname" |
| 549 | 549 | ); |
| 550 | 550 | @ <ul> |
| 551 | 551 | while( db_step(&q)==SQLITE_ROW ){ |
| 552 | 552 | const char *zName = db_column_text(&q, 0); |
| 553 | - if( g.perm.History ){ | |
| 554 | - @ <li><a class="tagLink" href="%s(g.zTop)/timeline?t=%T(zName)"> | |
| 553 | + if( g.perm.Hyperlink ){ | |
| 554 | + @ <li>%z(xhref("class='taglink'","%R/timeline?t=%T",zName)) | |
| 555 | 555 | @ %h(zName)</a></li> |
| 556 | 556 | }else{ |
| 557 | 557 | @ <li><span class="tagDsp">%h(zName)</span></li> |
| 558 | 558 | } |
| 559 | 559 | } |
| 560 | 560 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -548,12 +548,12 @@ | |
| 548 | " ORDER BY tagname" |
| 549 | ); |
| 550 | @ <ul> |
| 551 | while( db_step(&q)==SQLITE_ROW ){ |
| 552 | const char *zName = db_column_text(&q, 0); |
| 553 | if( g.perm.History ){ |
| 554 | @ <li><a class="tagLink" href="%s(g.zTop)/timeline?t=%T(zName)"> |
| 555 | @ %h(zName)</a></li> |
| 556 | }else{ |
| 557 | @ <li><span class="tagDsp">%h(zName)</span></li> |
| 558 | } |
| 559 | } |
| 560 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -548,12 +548,12 @@ | |
| 548 | " ORDER BY tagname" |
| 549 | ); |
| 550 | @ <ul> |
| 551 | while( db_step(&q)==SQLITE_ROW ){ |
| 552 | const char *zName = db_column_text(&q, 0); |
| 553 | if( g.perm.Hyperlink ){ |
| 554 | @ <li>%z(xhref("class='taglink'","%R/timeline?t=%T",zName)) |
| 555 | @ %h(zName)</a></li> |
| 556 | }else{ |
| 557 | @ <li><span class="tagDsp">%h(zName)</span></li> |
| 558 | } |
| 559 | } |
| 560 |
+32
-51
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -47,37 +47,37 @@ | ||
| 47 | 47 | ** Generate a hyperlink to a version. |
| 48 | 48 | */ |
| 49 | 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | 50 | char z[UUID_SIZE+1]; |
| 51 | 51 | shorten_uuid(z, zUuid); |
| 52 | - if( g.perm.History ){ | |
| 53 | - @ <a class="timelineHistLink" href="%s(g.zTop)/info/%s(z)">[%s(z)]</a> | |
| 52 | + if( g.perm.Hyperlink ){ | |
| 53 | + @ %z(xhref("class='timelineHistLink'","%R/info/%s",z))[%s(z)]</a> | |
| 54 | 54 | }else{ |
| 55 | 55 | @ <span class="timelineHistDsp">[%s(z)]</span> |
| 56 | 56 | } |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | /* |
| 60 | 60 | ** Generate a hyperlink to a diff between two versions. |
| 61 | 61 | */ |
| 62 | 62 | void hyperlink_to_diff(const char *zV1, const char *zV2){ |
| 63 | - if( g.perm.History ){ | |
| 63 | + if( g.perm.Hyperlink ){ | |
| 64 | 64 | if( zV2==0 ){ |
| 65 | - @ <a href="%s(g.zTop)/diff?v2=%s(zV1)">[diff]</a> | |
| 65 | + @ %z(href("%R/diff?v2=%s",zV1))[diff]</a> | |
| 66 | 66 | }else{ |
| 67 | - @ <a href="%s(g.zTop)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> | |
| 67 | + @ %z(href("%R/diff?v1=%s&v2=%s",zV1,zV2))[diff]</a> | |
| 68 | 68 | } |
| 69 | 69 | } |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | /* |
| 73 | 73 | ** Generate a hyperlink to a date & time. |
| 74 | 74 | */ |
| 75 | 75 | void hyperlink_to_date(const char *zDate, const char *zSuffix){ |
| 76 | 76 | if( zSuffix==0 ) zSuffix = ""; |
| 77 | - if( g.perm.History ){ | |
| 78 | - @ <a href="%s(g.zTop)/timeline?c=%T(zDate)">%s(zDate)</a>%s(zSuffix) | |
| 77 | + if( g.perm.Hyperlink ){ | |
| 78 | + @ %z(href("%R/timeline?c=%T",zDate))%s(zDate)</a>%s(zSuffix) | |
| 79 | 79 | }else{ |
| 80 | 80 | @ %s(zDate)%s(zSuffix) |
| 81 | 81 | } |
| 82 | 82 | } |
| 83 | 83 | |
| @@ -86,15 +86,15 @@ | ||
| 86 | 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | 87 | ** is centered on that date+time. |
| 88 | 88 | */ |
| 89 | 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | 90 | if( zSuf==0 ) zSuf = ""; |
| 91 | - if( g.perm.History ){ | |
| 91 | + if( g.perm.Hyperlink ){ | |
| 92 | 92 | if( zD && zD[0] ){ |
| 93 | - @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) | |
| 93 | + @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) | |
| 94 | 94 | }else{ |
| 95 | - @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf) | |
| 95 | + @ %z(href("%R/timeline?u=%T",zU))%h(zU)</a>%s(zSuf) | |
| 96 | 96 | } |
| 97 | 97 | }else{ |
| 98 | 98 | @ %s(zU) |
| 99 | 99 | } |
| 100 | 100 | } |
| @@ -353,39 +353,37 @@ | ||
| 353 | 353 | |
| 354 | 354 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 355 | 355 | ** with a hyperlink to another timeline for that user. |
| 356 | 356 | */ |
| 357 | 357 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 358 | - if( g.perm.History && fossil_strcmp(zUser, zThisUser)!=0 ){ | |
| 359 | - char *zLink = mprintf("%s/timeline?u=%h&c=%t&nd", | |
| 360 | - g.zTop, zUser, zDate); | |
| 361 | - @ (user: <a href="%s(zLink)">%h(zUser)</a>%s(zTagList?",":"\051") | |
| 362 | - fossil_free(zLink); | |
| 358 | + if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ | |
| 359 | + char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); | |
| 360 | + @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") | |
| 363 | 361 | }else{ |
| 364 | 362 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 365 | 363 | } |
| 366 | 364 | |
| 367 | 365 | /* Generate a "detail" link for tags. */ |
| 368 | - if( zType[0]=='g' && g.perm.History ){ | |
| 369 | - @ [<a href="%s(g.zTop)/info/%S(zUuid)">details</a>] | |
| 366 | + if( zType[0]=='g' && g.perm.Hyperlink ){ | |
| 367 | + @ [%z(href("%R/info/%S",zUuid))details</a>] | |
| 370 | 368 | } |
| 371 | 369 | |
| 372 | 370 | /* Generate the "tags: TAGLIST" at the end of the comment, together |
| 373 | 371 | ** with hyperlinks to the tag list. |
| 374 | 372 | */ |
| 375 | 373 | if( zTagList ){ |
| 376 | - if( g.perm.History ){ | |
| 374 | + if( g.perm.Hyperlink ){ | |
| 377 | 375 | int i; |
| 378 | 376 | const char *z = zTagList; |
| 379 | 377 | Blob links; |
| 380 | 378 | blob_zero(&links); |
| 381 | 379 | while( z && z[0] ){ |
| 382 | 380 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 383 | 381 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 384 | 382 | blob_appendf(&links, |
| 385 | - "<a href=\"%s/timeline?r=%#t&nd&c=%s\">%#h</a>%.2s", | |
| 386 | - g.zTop, i, z, zDate, i, z, &z[i] | |
| 383 | + "%z%#h</a>%.2s", | |
| 384 | + href("%R/timeline?r=%#t&nd&c=%s",i,z,zDate), i,z, &z[i] | |
| 387 | 385 | ); |
| 388 | 386 | }else{ |
| 389 | 387 | blob_appendf(&links, "%#h", i+2, z); |
| 390 | 388 | } |
| 391 | 389 | if( z[i]==0 ) break; |
| @@ -403,11 +401,11 @@ | ||
| 403 | 401 | if( xExtra ){ |
| 404 | 402 | xExtra(rid); |
| 405 | 403 | } |
| 406 | 404 | |
| 407 | 405 | /* Generate the file-change list if requested */ |
| 408 | - if( (tmFlags & TIMELINE_FCHANGES)!=0 && zType[0]=='c' && g.perm.History ){ | |
| 406 | + if( (tmFlags & TIMELINE_FCHANGES)!=0 && zType[0]=='c' && g.perm.Hyperlink ){ | |
| 409 | 407 | int inUl = 0; |
| 410 | 408 | if( !fchngQueryInit ){ |
| 411 | 409 | db_prepare(&fchngQuery, |
| 412 | 410 | "SELECT (pid==0) AS isnew," |
| 413 | 411 | " (fid==0) AS isdel," |
| @@ -433,26 +431,26 @@ | ||
| 433 | 431 | @ <ul class="filelist"> |
| 434 | 432 | inUl = 1; |
| 435 | 433 | } |
| 436 | 434 | if( isNew ){ |
| 437 | 435 | @ <li> %h(zFilename) (new file) |
| 438 | - @ <a href="%s(g.zTop)/artifact/%S(zNew)" | |
| 439 | - @ target="diffwindow">[view]</a></li> | |
| 436 | + @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) | |
| 437 | + @ [view]</a></li> | |
| 440 | 438 | }else if( isDel ){ |
| 441 | 439 | @ <li> %h(zFilename) (deleted)</li> |
| 442 | 440 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 443 | 441 | @ <li> %h(zOldName) → %h(zFilename) |
| 444 | - @ <a href="%s(g.zTop)/artifact/%S(zNew)" | |
| 445 | - @ target="diffwindow">[view]</a></li> | |
| 442 | + @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) | |
| 443 | + @ [view]</a></li> | |
| 446 | 444 | }else{ |
| 447 | 445 | if( zOldName!=0 ){ |
| 448 | 446 | @ <li> %h(zOldName) → %h(zFilename) |
| 449 | 447 | }else{ |
| 450 | 448 | @ <li> %h(zFilename) |
| 451 | 449 | } |
| 452 | - @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)" | |
| 453 | - @ target="diffwindow">[diff]</a></li> | |
| 450 | + @ %z(xhref("target='diffwindow'","%R/fdiff?v1=%S&v2=%S",zOld,zNew)) | |
| 451 | + @ [diff]</a></li> | |
| 454 | 452 | } |
| 455 | 453 | } |
| 456 | 454 | db_reset(&fchngQuery); |
| 457 | 455 | if( inUl ){ |
| 458 | 456 | @ </ul> |
| @@ -974,21 +972,13 @@ | ||
| 974 | 972 | p = p->u.pTo; |
| 975 | 973 | } |
| 976 | 974 | blob_append(&sql, ")", -1); |
| 977 | 975 | path_reset(); |
| 978 | 976 | blob_append(&desc, "All nodes on the path from ", -1); |
| 979 | - if( g.perm.History ){ | |
| 980 | - blob_appendf(&desc, "<a href='%s/info/%h'>[%h]</a>", g.zTop,zFrom,zFrom); | |
| 981 | - }else{ | |
| 982 | - blob_appendf(&desc, "[%h]", zFrom); | |
| 983 | - } | |
| 977 | + blob_appendf(&desc, "%z%h</a>", href("%R/info/%h", zFrom), zFrom); | |
| 984 | 978 | blob_append(&desc, " and ", -1); |
| 985 | - if( g.perm.History ){ | |
| 986 | - blob_appendf(&desc, "<a href='%s/info/%h'>[%h]</a>.", g.zTop, zTo, zTo); | |
| 987 | - }else{ | |
| 988 | - blob_appendf(&desc, "[%h].", zTo); | |
| 989 | - } | |
| 979 | + blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo); | |
| 990 | 980 | tmFlags |= TIMELINE_DISJOINT; |
| 991 | 981 | db_multi_exec("%s", blob_str(&sql)); |
| 992 | 982 | }else if( (p_rid || d_rid) && g.perm.Read ){ |
| 993 | 983 | /* If p= or d= is present, ignore all other parameters other than n= */ |
| 994 | 984 | char *zUuid; |
| @@ -1021,16 +1011,12 @@ | ||
| 1021 | 1011 | blob_appendf(&desc, "%d ancestors", np); |
| 1022 | 1012 | db_multi_exec("%s", blob_str(&sql)); |
| 1023 | 1013 | } |
| 1024 | 1014 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1025 | 1015 | } |
| 1026 | - if( g.perm.History ){ | |
| 1027 | - blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", | |
| 1028 | - g.zTop, zUuid, zUuid); | |
| 1029 | - }else{ | |
| 1030 | - blob_appendf(&desc, " of check-in [%.10s]", zUuid); | |
| 1031 | - } | |
| 1016 | + blob_appendf(&desc, " of %z[%.10s]</a>", | |
| 1017 | + href("%R/info/%s", zUuid), zUuid); | |
| 1032 | 1018 | }else if( f_rid && g.perm.Read ){ |
| 1033 | 1019 | /* If f= is present, ignore all other parameters other than n= */ |
| 1034 | 1020 | char *zUuid; |
| 1035 | 1021 | db_multi_exec( |
| 1036 | 1022 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);" |
| @@ -1042,16 +1028,11 @@ | ||
| 1042 | 1028 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1043 | 1029 | db_multi_exec("%s", blob_str(&sql)); |
| 1044 | 1030 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1045 | 1031 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1046 | 1032 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1047 | - if( g.perm.History ){ | |
| 1048 | - blob_appendf(&desc, "<a href='%s/info/%s'>[%.10s]</a>", | |
| 1049 | - g.zTop, zUuid, zUuid); | |
| 1050 | - }else{ | |
| 1051 | - blob_appendf(&desc, "[%.10s]", zUuid); | |
| 1052 | - } | |
| 1033 | + blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid); | |
| 1053 | 1034 | }else{ |
| 1054 | 1035 | /* Otherwise, a timeline based on a span of time */ |
| 1055 | 1036 | int n; |
| 1056 | 1037 | const char *zEType = "timeline item"; |
| 1057 | 1038 | char *zDate; |
| @@ -1219,11 +1200,11 @@ | ||
| 1219 | 1200 | blob_appendf(&desc, " occurring around %h.<br />", zCirca); |
| 1220 | 1201 | } |
| 1221 | 1202 | if( zSearch ){ |
| 1222 | 1203 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1223 | 1204 | } |
| 1224 | - if( g.perm.History ){ | |
| 1205 | + if( g.perm.Hyperlink ){ | |
| 1225 | 1206 | if( zAfter || n==nEntry ){ |
| 1226 | 1207 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1227 | 1208 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1228 | 1209 | free(zDate); |
| 1229 | 1210 | } |
| @@ -1623,11 +1604,11 @@ | ||
| 1623 | 1604 | */ |
| 1624 | 1605 | void test_timewarp_page(void){ |
| 1625 | 1606 | Stmt q; |
| 1626 | 1607 | |
| 1627 | 1608 | login_check_credentials(); |
| 1628 | - if( !g.perm.Read || !g.perm.History ){ login_needed(); return; } | |
| 1609 | + if( !g.perm.Read || !g.perm.Hyperlink ){ login_needed(); return; } | |
| 1629 | 1610 | style_header("Instances of timewarp"); |
| 1630 | 1611 | @ <ul> |
| 1631 | 1612 | db_prepare(&q, |
| 1632 | 1613 | "SELECT blob.uuid " |
| 1633 | 1614 | " FROM plink p, plink c, blob" |
| 1634 | 1615 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -47,37 +47,37 @@ | |
| 47 | ** Generate a hyperlink to a version. |
| 48 | */ |
| 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | char z[UUID_SIZE+1]; |
| 51 | shorten_uuid(z, zUuid); |
| 52 | if( g.perm.History ){ |
| 53 | @ <a class="timelineHistLink" href="%s(g.zTop)/info/%s(z)">[%s(z)]</a> |
| 54 | }else{ |
| 55 | @ <span class="timelineHistDsp">[%s(z)]</span> |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /* |
| 60 | ** Generate a hyperlink to a diff between two versions. |
| 61 | */ |
| 62 | void hyperlink_to_diff(const char *zV1, const char *zV2){ |
| 63 | if( g.perm.History ){ |
| 64 | if( zV2==0 ){ |
| 65 | @ <a href="%s(g.zTop)/diff?v2=%s(zV1)">[diff]</a> |
| 66 | }else{ |
| 67 | @ <a href="%s(g.zTop)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | /* |
| 73 | ** Generate a hyperlink to a date & time. |
| 74 | */ |
| 75 | void hyperlink_to_date(const char *zDate, const char *zSuffix){ |
| 76 | if( zSuffix==0 ) zSuffix = ""; |
| 77 | if( g.perm.History ){ |
| 78 | @ <a href="%s(g.zTop)/timeline?c=%T(zDate)">%s(zDate)</a>%s(zSuffix) |
| 79 | }else{ |
| 80 | @ %s(zDate)%s(zSuffix) |
| 81 | } |
| 82 | } |
| 83 | |
| @@ -86,15 +86,15 @@ | |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zSuf==0 ) zSuf = ""; |
| 91 | if( g.perm.History ){ |
| 92 | if( zD && zD[0] ){ |
| 93 | @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 94 | }else{ |
| 95 | @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 96 | } |
| 97 | }else{ |
| 98 | @ %s(zU) |
| 99 | } |
| 100 | } |
| @@ -353,39 +353,37 @@ | |
| 353 | |
| 354 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 355 | ** with a hyperlink to another timeline for that user. |
| 356 | */ |
| 357 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 358 | if( g.perm.History && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 359 | char *zLink = mprintf("%s/timeline?u=%h&c=%t&nd", |
| 360 | g.zTop, zUser, zDate); |
| 361 | @ (user: <a href="%s(zLink)">%h(zUser)</a>%s(zTagList?",":"\051") |
| 362 | fossil_free(zLink); |
| 363 | }else{ |
| 364 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 365 | } |
| 366 | |
| 367 | /* Generate a "detail" link for tags. */ |
| 368 | if( zType[0]=='g' && g.perm.History ){ |
| 369 | @ [<a href="%s(g.zTop)/info/%S(zUuid)">details</a>] |
| 370 | } |
| 371 | |
| 372 | /* Generate the "tags: TAGLIST" at the end of the comment, together |
| 373 | ** with hyperlinks to the tag list. |
| 374 | */ |
| 375 | if( zTagList ){ |
| 376 | if( g.perm.History ){ |
| 377 | int i; |
| 378 | const char *z = zTagList; |
| 379 | Blob links; |
| 380 | blob_zero(&links); |
| 381 | while( z && z[0] ){ |
| 382 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 383 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 384 | blob_appendf(&links, |
| 385 | "<a href=\"%s/timeline?r=%#t&nd&c=%s\">%#h</a>%.2s", |
| 386 | g.zTop, i, z, zDate, i, z, &z[i] |
| 387 | ); |
| 388 | }else{ |
| 389 | blob_appendf(&links, "%#h", i+2, z); |
| 390 | } |
| 391 | if( z[i]==0 ) break; |
| @@ -403,11 +401,11 @@ | |
| 403 | if( xExtra ){ |
| 404 | xExtra(rid); |
| 405 | } |
| 406 | |
| 407 | /* Generate the file-change list if requested */ |
| 408 | if( (tmFlags & TIMELINE_FCHANGES)!=0 && zType[0]=='c' && g.perm.History ){ |
| 409 | int inUl = 0; |
| 410 | if( !fchngQueryInit ){ |
| 411 | db_prepare(&fchngQuery, |
| 412 | "SELECT (pid==0) AS isnew," |
| 413 | " (fid==0) AS isdel," |
| @@ -433,26 +431,26 @@ | |
| 433 | @ <ul class="filelist"> |
| 434 | inUl = 1; |
| 435 | } |
| 436 | if( isNew ){ |
| 437 | @ <li> %h(zFilename) (new file) |
| 438 | @ <a href="%s(g.zTop)/artifact/%S(zNew)" |
| 439 | @ target="diffwindow">[view]</a></li> |
| 440 | }else if( isDel ){ |
| 441 | @ <li> %h(zFilename) (deleted)</li> |
| 442 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 443 | @ <li> %h(zOldName) → %h(zFilename) |
| 444 | @ <a href="%s(g.zTop)/artifact/%S(zNew)" |
| 445 | @ target="diffwindow">[view]</a></li> |
| 446 | }else{ |
| 447 | if( zOldName!=0 ){ |
| 448 | @ <li> %h(zOldName) → %h(zFilename) |
| 449 | }else{ |
| 450 | @ <li> %h(zFilename) |
| 451 | } |
| 452 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)" |
| 453 | @ target="diffwindow">[diff]</a></li> |
| 454 | } |
| 455 | } |
| 456 | db_reset(&fchngQuery); |
| 457 | if( inUl ){ |
| 458 | @ </ul> |
| @@ -974,21 +972,13 @@ | |
| 974 | p = p->u.pTo; |
| 975 | } |
| 976 | blob_append(&sql, ")", -1); |
| 977 | path_reset(); |
| 978 | blob_append(&desc, "All nodes on the path from ", -1); |
| 979 | if( g.perm.History ){ |
| 980 | blob_appendf(&desc, "<a href='%s/info/%h'>[%h]</a>", g.zTop,zFrom,zFrom); |
| 981 | }else{ |
| 982 | blob_appendf(&desc, "[%h]", zFrom); |
| 983 | } |
| 984 | blob_append(&desc, " and ", -1); |
| 985 | if( g.perm.History ){ |
| 986 | blob_appendf(&desc, "<a href='%s/info/%h'>[%h]</a>.", g.zTop, zTo, zTo); |
| 987 | }else{ |
| 988 | blob_appendf(&desc, "[%h].", zTo); |
| 989 | } |
| 990 | tmFlags |= TIMELINE_DISJOINT; |
| 991 | db_multi_exec("%s", blob_str(&sql)); |
| 992 | }else if( (p_rid || d_rid) && g.perm.Read ){ |
| 993 | /* If p= or d= is present, ignore all other parameters other than n= */ |
| 994 | char *zUuid; |
| @@ -1021,16 +1011,12 @@ | |
| 1021 | blob_appendf(&desc, "%d ancestors", np); |
| 1022 | db_multi_exec("%s", blob_str(&sql)); |
| 1023 | } |
| 1024 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1025 | } |
| 1026 | if( g.perm.History ){ |
| 1027 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 1028 | g.zTop, zUuid, zUuid); |
| 1029 | }else{ |
| 1030 | blob_appendf(&desc, " of check-in [%.10s]", zUuid); |
| 1031 | } |
| 1032 | }else if( f_rid && g.perm.Read ){ |
| 1033 | /* If f= is present, ignore all other parameters other than n= */ |
| 1034 | char *zUuid; |
| 1035 | db_multi_exec( |
| 1036 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);" |
| @@ -1042,16 +1028,11 @@ | |
| 1042 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1043 | db_multi_exec("%s", blob_str(&sql)); |
| 1044 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1045 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1046 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1047 | if( g.perm.History ){ |
| 1048 | blob_appendf(&desc, "<a href='%s/info/%s'>[%.10s]</a>", |
| 1049 | g.zTop, zUuid, zUuid); |
| 1050 | }else{ |
| 1051 | blob_appendf(&desc, "[%.10s]", zUuid); |
| 1052 | } |
| 1053 | }else{ |
| 1054 | /* Otherwise, a timeline based on a span of time */ |
| 1055 | int n; |
| 1056 | const char *zEType = "timeline item"; |
| 1057 | char *zDate; |
| @@ -1219,11 +1200,11 @@ | |
| 1219 | blob_appendf(&desc, " occurring around %h.<br />", zCirca); |
| 1220 | } |
| 1221 | if( zSearch ){ |
| 1222 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1223 | } |
| 1224 | if( g.perm.History ){ |
| 1225 | if( zAfter || n==nEntry ){ |
| 1226 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1227 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1228 | free(zDate); |
| 1229 | } |
| @@ -1623,11 +1604,11 @@ | |
| 1623 | */ |
| 1624 | void test_timewarp_page(void){ |
| 1625 | Stmt q; |
| 1626 | |
| 1627 | login_check_credentials(); |
| 1628 | if( !g.perm.Read || !g.perm.History ){ login_needed(); return; } |
| 1629 | style_header("Instances of timewarp"); |
| 1630 | @ <ul> |
| 1631 | db_prepare(&q, |
| 1632 | "SELECT blob.uuid " |
| 1633 | " FROM plink p, plink c, blob" |
| 1634 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -47,37 +47,37 @@ | |
| 47 | ** Generate a hyperlink to a version. |
| 48 | */ |
| 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | char z[UUID_SIZE+1]; |
| 51 | shorten_uuid(z, zUuid); |
| 52 | if( g.perm.Hyperlink ){ |
| 53 | @ %z(xhref("class='timelineHistLink'","%R/info/%s",z))[%s(z)]</a> |
| 54 | }else{ |
| 55 | @ <span class="timelineHistDsp">[%s(z)]</span> |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /* |
| 60 | ** Generate a hyperlink to a diff between two versions. |
| 61 | */ |
| 62 | void hyperlink_to_diff(const char *zV1, const char *zV2){ |
| 63 | if( g.perm.Hyperlink ){ |
| 64 | if( zV2==0 ){ |
| 65 | @ %z(href("%R/diff?v2=%s",zV1))[diff]</a> |
| 66 | }else{ |
| 67 | @ %z(href("%R/diff?v1=%s&v2=%s",zV1,zV2))[diff]</a> |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | /* |
| 73 | ** Generate a hyperlink to a date & time. |
| 74 | */ |
| 75 | void hyperlink_to_date(const char *zDate, const char *zSuffix){ |
| 76 | if( zSuffix==0 ) zSuffix = ""; |
| 77 | if( g.perm.Hyperlink ){ |
| 78 | @ %z(href("%R/timeline?c=%T",zDate))%s(zDate)</a>%s(zSuffix) |
| 79 | }else{ |
| 80 | @ %s(zDate)%s(zSuffix) |
| 81 | } |
| 82 | } |
| 83 | |
| @@ -86,15 +86,15 @@ | |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zSuf==0 ) zSuf = ""; |
| 91 | if( g.perm.Hyperlink ){ |
| 92 | if( zD && zD[0] ){ |
| 93 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 94 | }else{ |
| 95 | @ %z(href("%R/timeline?u=%T",zU))%h(zU)</a>%s(zSuf) |
| 96 | } |
| 97 | }else{ |
| 98 | @ %s(zU) |
| 99 | } |
| 100 | } |
| @@ -353,39 +353,37 @@ | |
| 353 | |
| 354 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 355 | ** with a hyperlink to another timeline for that user. |
| 356 | */ |
| 357 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 358 | if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 359 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); |
| 360 | @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") |
| 361 | }else{ |
| 362 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 363 | } |
| 364 | |
| 365 | /* Generate a "detail" link for tags. */ |
| 366 | if( zType[0]=='g' && g.perm.Hyperlink ){ |
| 367 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 368 | } |
| 369 | |
| 370 | /* Generate the "tags: TAGLIST" at the end of the comment, together |
| 371 | ** with hyperlinks to the tag list. |
| 372 | */ |
| 373 | if( zTagList ){ |
| 374 | if( g.perm.Hyperlink ){ |
| 375 | int i; |
| 376 | const char *z = zTagList; |
| 377 | Blob links; |
| 378 | blob_zero(&links); |
| 379 | while( z && z[0] ){ |
| 380 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 381 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 382 | blob_appendf(&links, |
| 383 | "%z%#h</a>%.2s", |
| 384 | href("%R/timeline?r=%#t&nd&c=%s",i,z,zDate), i,z, &z[i] |
| 385 | ); |
| 386 | }else{ |
| 387 | blob_appendf(&links, "%#h", i+2, z); |
| 388 | } |
| 389 | if( z[i]==0 ) break; |
| @@ -403,11 +401,11 @@ | |
| 401 | if( xExtra ){ |
| 402 | xExtra(rid); |
| 403 | } |
| 404 | |
| 405 | /* Generate the file-change list if requested */ |
| 406 | if( (tmFlags & TIMELINE_FCHANGES)!=0 && zType[0]=='c' && g.perm.Hyperlink ){ |
| 407 | int inUl = 0; |
| 408 | if( !fchngQueryInit ){ |
| 409 | db_prepare(&fchngQuery, |
| 410 | "SELECT (pid==0) AS isnew," |
| 411 | " (fid==0) AS isdel," |
| @@ -433,26 +431,26 @@ | |
| 431 | @ <ul class="filelist"> |
| 432 | inUl = 1; |
| 433 | } |
| 434 | if( isNew ){ |
| 435 | @ <li> %h(zFilename) (new file) |
| 436 | @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) |
| 437 | @ [view]</a></li> |
| 438 | }else if( isDel ){ |
| 439 | @ <li> %h(zFilename) (deleted)</li> |
| 440 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 441 | @ <li> %h(zOldName) → %h(zFilename) |
| 442 | @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) |
| 443 | @ [view]</a></li> |
| 444 | }else{ |
| 445 | if( zOldName!=0 ){ |
| 446 | @ <li> %h(zOldName) → %h(zFilename) |
| 447 | }else{ |
| 448 | @ <li> %h(zFilename) |
| 449 | } |
| 450 | @ %z(xhref("target='diffwindow'","%R/fdiff?v1=%S&v2=%S",zOld,zNew)) |
| 451 | @ [diff]</a></li> |
| 452 | } |
| 453 | } |
| 454 | db_reset(&fchngQuery); |
| 455 | if( inUl ){ |
| 456 | @ </ul> |
| @@ -974,21 +972,13 @@ | |
| 972 | p = p->u.pTo; |
| 973 | } |
| 974 | blob_append(&sql, ")", -1); |
| 975 | path_reset(); |
| 976 | blob_append(&desc, "All nodes on the path from ", -1); |
| 977 | blob_appendf(&desc, "%z%h</a>", href("%R/info/%h", zFrom), zFrom); |
| 978 | blob_append(&desc, " and ", -1); |
| 979 | blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo); |
| 980 | tmFlags |= TIMELINE_DISJOINT; |
| 981 | db_multi_exec("%s", blob_str(&sql)); |
| 982 | }else if( (p_rid || d_rid) && g.perm.Read ){ |
| 983 | /* If p= or d= is present, ignore all other parameters other than n= */ |
| 984 | char *zUuid; |
| @@ -1021,16 +1011,12 @@ | |
| 1011 | blob_appendf(&desc, "%d ancestors", np); |
| 1012 | db_multi_exec("%s", blob_str(&sql)); |
| 1013 | } |
| 1014 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1015 | } |
| 1016 | blob_appendf(&desc, " of %z[%.10s]</a>", |
| 1017 | href("%R/info/%s", zUuid), zUuid); |
| 1018 | }else if( f_rid && g.perm.Read ){ |
| 1019 | /* If f= is present, ignore all other parameters other than n= */ |
| 1020 | char *zUuid; |
| 1021 | db_multi_exec( |
| 1022 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);" |
| @@ -1042,16 +1028,11 @@ | |
| 1028 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1029 | db_multi_exec("%s", blob_str(&sql)); |
| 1030 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1031 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1032 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1033 | blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid); |
| 1034 | }else{ |
| 1035 | /* Otherwise, a timeline based on a span of time */ |
| 1036 | int n; |
| 1037 | const char *zEType = "timeline item"; |
| 1038 | char *zDate; |
| @@ -1219,11 +1200,11 @@ | |
| 1200 | blob_appendf(&desc, " occurring around %h.<br />", zCirca); |
| 1201 | } |
| 1202 | if( zSearch ){ |
| 1203 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1204 | } |
| 1205 | if( g.perm.Hyperlink ){ |
| 1206 | if( zAfter || n==nEntry ){ |
| 1207 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1208 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1209 | free(zDate); |
| 1210 | } |
| @@ -1623,11 +1604,11 @@ | |
| 1604 | */ |
| 1605 | void test_timewarp_page(void){ |
| 1606 | Stmt q; |
| 1607 | |
| 1608 | login_check_credentials(); |
| 1609 | if( !g.perm.Read || !g.perm.Hyperlink ){ login_needed(); return; } |
| 1610 | style_header("Instances of timewarp"); |
| 1611 | @ <ul> |
| 1612 | db_prepare(&q, |
| 1613 | "SELECT blob.uuid " |
| 1614 | " FROM plink p, plink c, blob" |
| 1615 |
+8
-8
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -305,11 +305,11 @@ | ||
| 305 | 305 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 306 | 306 | if( g.perm.WrTkt || g.perm.ApndTkt ){ |
| 307 | 307 | style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", |
| 308 | 308 | g.zTop, PD("name","")); |
| 309 | 309 | } |
| 310 | - if( g.perm.History ){ | |
| 310 | + if( g.perm.Hyperlink ){ | |
| 311 | 311 | style_submenu_element("History", "History Of This Ticket", |
| 312 | 312 | "%s/tkthistory/%T", g.zTop, zUuid); |
| 313 | 313 | style_submenu_element("Timeline", "Timeline Of This Ticket", |
| 314 | 314 | "%s/tkttimeline/%T", g.zTop, zUuid); |
| 315 | 315 | style_submenu_element("Check-ins", "Check-ins Of This Ticket", |
| @@ -353,20 +353,20 @@ | ||
| 353 | 353 | @ <hr /><h2>Attachments:</h2> |
| 354 | 354 | @ <ul> |
| 355 | 355 | } |
| 356 | 356 | cnt++; |
| 357 | 357 | @ <li> |
| 358 | - if( g.perm.Read && g.perm.History ){ | |
| 359 | - @ <a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)"> | |
| 358 | + if( g.perm.Read && g.perm.Hyperlink ){ | |
| 359 | + @ %z(href("%R/attachview?tkt=%s&file=%t",zFullName,zFile)) | |
| 360 | 360 | @ %h(zFile)</a> |
| 361 | 361 | }else{ |
| 362 | 362 | @ %h(zFile) |
| 363 | 363 | } |
| 364 | 364 | @ added by %h(zUser) on |
| 365 | 365 | hyperlink_to_date(zDate, "."); |
| 366 | 366 | if( g.perm.WrTkt && g.perm.Attach ){ |
| 367 | - @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>] | |
| 367 | + @ [%z(href("%R/attachdelete?tkt=%s&file=%t&from=%R/tktview%%3fname=%s",zFullName,zFile,zFullName))delete</a>] | |
| 368 | 368 | } |
| 369 | 369 | @ </li> |
| 370 | 370 | } |
| 371 | 371 | if( cnt ){ |
| 372 | 372 | @ </ul> |
| @@ -662,11 +662,11 @@ | ||
| 662 | 662 | int tagid; |
| 663 | 663 | char zGlobPattern[50]; |
| 664 | 664 | const char *zType; |
| 665 | 665 | |
| 666 | 666 | login_check_credentials(); |
| 667 | - if( !g.perm.History || !g.perm.RdTkt ){ login_needed(); return; } | |
| 667 | + if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } | |
| 668 | 668 | zUuid = PD("name",""); |
| 669 | 669 | zType = PD("y","a"); |
| 670 | 670 | if( zType[0]!='c' ){ |
| 671 | 671 | style_submenu_element("Check-ins", "Check-ins", |
| 672 | 672 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| @@ -736,11 +736,11 @@ | ||
| 736 | 736 | char *zTitle; |
| 737 | 737 | const char *zUuid; |
| 738 | 738 | int tagid; |
| 739 | 739 | |
| 740 | 740 | login_check_credentials(); |
| 741 | - if( !g.perm.History || !g.perm.RdTkt ){ login_needed(); return; } | |
| 741 | + if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } | |
| 742 | 742 | zUuid = PD("name",""); |
| 743 | 743 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 744 | 744 | style_submenu_element("Status", "Status", |
| 745 | 745 | "%s/info/%s", g.zTop, zUuid); |
| 746 | 746 | style_submenu_element("Check-ins", "Check-ins", |
| @@ -786,20 +786,20 @@ | ||
| 786 | 786 | @ <p>Delete attachment "%h(zFile)" |
| 787 | 787 | }else{ |
| 788 | 788 | @ |
| 789 | 789 | @ <p>Add attachment "%h(zFile)" |
| 790 | 790 | } |
| 791 | - @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>] | |
| 791 | + @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] | |
| 792 | 792 | @ (rid %d(rid)) by |
| 793 | 793 | hyperlink_to_user(zUser,zDate," on"); |
| 794 | 794 | hyperlink_to_date(zDate, ".</p>"); |
| 795 | 795 | }else{ |
| 796 | 796 | pTicket = manifest_get(rid, CFTYPE_TICKET); |
| 797 | 797 | if( pTicket ){ |
| 798 | 798 | @ |
| 799 | 799 | @ <p>Ticket change |
| 800 | - @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>] | |
| 800 | + @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] | |
| 801 | 801 | @ (rid %d(rid)) by |
| 802 | 802 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 803 | 803 | hyperlink_to_date(zDate, ":"); |
| 804 | 804 | @ </p> |
| 805 | 805 | ticket_output_change_artifact(pTicket); |
| 806 | 806 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 306 | if( g.perm.WrTkt || g.perm.ApndTkt ){ |
| 307 | style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", |
| 308 | g.zTop, PD("name","")); |
| 309 | } |
| 310 | if( g.perm.History ){ |
| 311 | style_submenu_element("History", "History Of This Ticket", |
| 312 | "%s/tkthistory/%T", g.zTop, zUuid); |
| 313 | style_submenu_element("Timeline", "Timeline Of This Ticket", |
| 314 | "%s/tkttimeline/%T", g.zTop, zUuid); |
| 315 | style_submenu_element("Check-ins", "Check-ins Of This Ticket", |
| @@ -353,20 +353,20 @@ | |
| 353 | @ <hr /><h2>Attachments:</h2> |
| 354 | @ <ul> |
| 355 | } |
| 356 | cnt++; |
| 357 | @ <li> |
| 358 | if( g.perm.Read && g.perm.History ){ |
| 359 | @ <a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)"> |
| 360 | @ %h(zFile)</a> |
| 361 | }else{ |
| 362 | @ %h(zFile) |
| 363 | } |
| 364 | @ added by %h(zUser) on |
| 365 | hyperlink_to_date(zDate, "."); |
| 366 | if( g.perm.WrTkt && g.perm.Attach ){ |
| 367 | @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>] |
| 368 | } |
| 369 | @ </li> |
| 370 | } |
| 371 | if( cnt ){ |
| 372 | @ </ul> |
| @@ -662,11 +662,11 @@ | |
| 662 | int tagid; |
| 663 | char zGlobPattern[50]; |
| 664 | const char *zType; |
| 665 | |
| 666 | login_check_credentials(); |
| 667 | if( !g.perm.History || !g.perm.RdTkt ){ login_needed(); return; } |
| 668 | zUuid = PD("name",""); |
| 669 | zType = PD("y","a"); |
| 670 | if( zType[0]!='c' ){ |
| 671 | style_submenu_element("Check-ins", "Check-ins", |
| 672 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| @@ -736,11 +736,11 @@ | |
| 736 | char *zTitle; |
| 737 | const char *zUuid; |
| 738 | int tagid; |
| 739 | |
| 740 | login_check_credentials(); |
| 741 | if( !g.perm.History || !g.perm.RdTkt ){ login_needed(); return; } |
| 742 | zUuid = PD("name",""); |
| 743 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 744 | style_submenu_element("Status", "Status", |
| 745 | "%s/info/%s", g.zTop, zUuid); |
| 746 | style_submenu_element("Check-ins", "Check-ins", |
| @@ -786,20 +786,20 @@ | |
| 786 | @ <p>Delete attachment "%h(zFile)" |
| 787 | }else{ |
| 788 | @ |
| 789 | @ <p>Add attachment "%h(zFile)" |
| 790 | } |
| 791 | @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>] |
| 792 | @ (rid %d(rid)) by |
| 793 | hyperlink_to_user(zUser,zDate," on"); |
| 794 | hyperlink_to_date(zDate, ".</p>"); |
| 795 | }else{ |
| 796 | pTicket = manifest_get(rid, CFTYPE_TICKET); |
| 797 | if( pTicket ){ |
| 798 | @ |
| 799 | @ <p>Ticket change |
| 800 | @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>] |
| 801 | @ (rid %d(rid)) by |
| 802 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 803 | hyperlink_to_date(zDate, ":"); |
| 804 | @ </p> |
| 805 | ticket_output_change_artifact(pTicket); |
| 806 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 306 | if( g.perm.WrTkt || g.perm.ApndTkt ){ |
| 307 | style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", |
| 308 | g.zTop, PD("name","")); |
| 309 | } |
| 310 | if( g.perm.Hyperlink ){ |
| 311 | style_submenu_element("History", "History Of This Ticket", |
| 312 | "%s/tkthistory/%T", g.zTop, zUuid); |
| 313 | style_submenu_element("Timeline", "Timeline Of This Ticket", |
| 314 | "%s/tkttimeline/%T", g.zTop, zUuid); |
| 315 | style_submenu_element("Check-ins", "Check-ins Of This Ticket", |
| @@ -353,20 +353,20 @@ | |
| 353 | @ <hr /><h2>Attachments:</h2> |
| 354 | @ <ul> |
| 355 | } |
| 356 | cnt++; |
| 357 | @ <li> |
| 358 | if( g.perm.Read && g.perm.Hyperlink ){ |
| 359 | @ %z(href("%R/attachview?tkt=%s&file=%t",zFullName,zFile)) |
| 360 | @ %h(zFile)</a> |
| 361 | }else{ |
| 362 | @ %h(zFile) |
| 363 | } |
| 364 | @ added by %h(zUser) on |
| 365 | hyperlink_to_date(zDate, "."); |
| 366 | if( g.perm.WrTkt && g.perm.Attach ){ |
| 367 | @ [%z(href("%R/attachdelete?tkt=%s&file=%t&from=%R/tktview%%3fname=%s",zFullName,zFile,zFullName))delete</a>] |
| 368 | } |
| 369 | @ </li> |
| 370 | } |
| 371 | if( cnt ){ |
| 372 | @ </ul> |
| @@ -662,11 +662,11 @@ | |
| 662 | int tagid; |
| 663 | char zGlobPattern[50]; |
| 664 | const char *zType; |
| 665 | |
| 666 | login_check_credentials(); |
| 667 | if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } |
| 668 | zUuid = PD("name",""); |
| 669 | zType = PD("y","a"); |
| 670 | if( zType[0]!='c' ){ |
| 671 | style_submenu_element("Check-ins", "Check-ins", |
| 672 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| @@ -736,11 +736,11 @@ | |
| 736 | char *zTitle; |
| 737 | const char *zUuid; |
| 738 | int tagid; |
| 739 | |
| 740 | login_check_credentials(); |
| 741 | if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } |
| 742 | zUuid = PD("name",""); |
| 743 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 744 | style_submenu_element("Status", "Status", |
| 745 | "%s/info/%s", g.zTop, zUuid); |
| 746 | style_submenu_element("Check-ins", "Check-ins", |
| @@ -786,20 +786,20 @@ | |
| 786 | @ <p>Delete attachment "%h(zFile)" |
| 787 | }else{ |
| 788 | @ |
| 789 | @ <p>Add attachment "%h(zFile)" |
| 790 | } |
| 791 | @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] |
| 792 | @ (rid %d(rid)) by |
| 793 | hyperlink_to_user(zUser,zDate," on"); |
| 794 | hyperlink_to_date(zDate, ".</p>"); |
| 795 | }else{ |
| 796 | pTicket = manifest_get(rid, CFTYPE_TICKET); |
| 797 | if( pTicket ){ |
| 798 | @ |
| 799 | @ <p>Ticket change |
| 800 | @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] |
| 801 | @ (rid %d(rid)) by |
| 802 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 803 | hyperlink_to_date(zDate, ":"); |
| 804 | @ </p> |
| 805 | ticket_output_change_artifact(pTicket); |
| 806 |
+18
-20
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -104,11 +104,11 @@ | ||
| 104 | 104 | return; |
| 105 | 105 | } |
| 106 | 106 | style_header("Home"); |
| 107 | 107 | @ <p>This is a stub home-page for the project. |
| 108 | 108 | @ To fill in this page, first go to |
| 109 | - @ <a href="%s(g.zTop)/setup_config">setup/config</a> | |
| 109 | + @ %z(href("%R/setup_config"))setup/config</a> | |
| 110 | 110 | @ and establish a "Project Name". Then create a |
| 111 | 111 | @ wiki page with that name. The content of that wiki page |
| 112 | 112 | @ will be displayed in place of this message.</p> |
| 113 | 113 | style_footer(); |
| 114 | 114 | } |
| @@ -142,27 +142,25 @@ | ||
| 142 | 142 | if( zPageName==0 ){ |
| 143 | 143 | style_header("Wiki"); |
| 144 | 144 | @ <ul> |
| 145 | 145 | { char *zHomePageName = db_get("project-name",0); |
| 146 | 146 | if( zHomePageName ){ |
| 147 | - @ <li> <a href="%s(g.zTop)/wiki?name=%t(zHomePageName)"> | |
| 147 | + @ <li> %z(href("%R/wiki?name=%t",zHomePageName)) | |
| 148 | 148 | @ %h(zHomePageName)</a> wiki home page.</li> |
| 149 | 149 | } |
| 150 | 150 | } |
| 151 | - @ <li> <a href="%s(g.zTop)/timeline?y=w">Recent changes</a> to wiki | |
| 152 | - @ pages. </li> | |
| 153 | - @ <li> <a href="%s(g.zTop)/wiki_rules">Formatting rules</a> for | |
| 154 | - @ wiki.</li> | |
| 155 | - @ <li> Use the <a href="%s(g.zTop)/wiki?name=Sandbox">Sandbox</a> | |
| 151 | + @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> | |
| 152 | + @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li> | |
| 153 | + @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> | |
| 156 | 154 | @ to experiment.</li> |
| 157 | 155 | if( g.perm.NewWiki ){ |
| 158 | - @ <li> Create a <a href="%s(g.zTop)/wikinew">new wiki page</a>.</li> | |
| 156 | + @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> | |
| 159 | 157 | if( g.perm.Write ){ |
| 160 | - @ <li> Create a <a href="%s(g.zTop)/eventedit">new event</a>.</li> | |
| 158 | + @ <li> Create a %z(href("%R/eventedit"))new event</a>.</li> | |
| 161 | 159 | } |
| 162 | 160 | } |
| 163 | - @ <li> <a href="%s(g.zTop)/wcontent">List of All Wiki Pages</a> | |
| 161 | + @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> | |
| 164 | 162 | @ available on this server.</li> |
| 165 | 163 | @ <li> <form method="get" action="%s(g.zTop)/wfind"><div> |
| 166 | 164 | @ Search wiki titles: <input type="text" name="title"/> |
| 167 | 165 | @ <input type="submit" /></div></form> |
| 168 | 166 | @ </li> |
| @@ -199,11 +197,11 @@ | ||
| 199 | 197 | } |
| 200 | 198 | if( rid && g.perm.ApndWiki ){ |
| 201 | 199 | style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T", |
| 202 | 200 | g.zTop, zPageName); |
| 203 | 201 | } |
| 204 | - if( g.perm.History ){ | |
| 202 | + if( g.perm.Hyperlink ){ | |
| 205 | 203 | style_submenu_element("History", "History", "%s/whistory?name=%T", |
| 206 | 204 | g.zTop, zPageName); |
| 207 | 205 | } |
| 208 | 206 | } |
| 209 | 207 | style_header(zPageName); |
| @@ -225,20 +223,20 @@ | ||
| 225 | 223 | @ <hr /><h2>Attachments:</h2> |
| 226 | 224 | @ <ul> |
| 227 | 225 | } |
| 228 | 226 | cnt++; |
| 229 | 227 | @ <li> |
| 230 | - if( g.perm.History && g.perm.Read ){ | |
| 231 | - @ <a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)"> | |
| 228 | + if( g.perm.Hyperlink && g.perm.Read ){ | |
| 229 | + @ %z(href("%R/attachview?page=%T&file=%t",zPageName,zFile)) | |
| 232 | 230 | @ %h(zFile)</a> |
| 233 | 231 | }else{ |
| 234 | 232 | @ %h(zFile) |
| 235 | 233 | } |
| 236 | 234 | @ added by %h(zUser) on |
| 237 | 235 | hyperlink_to_date(zDate, "."); |
| 238 | 236 | if( g.perm.WrWiki && g.perm.Attach ){ |
| 239 | - @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>] | |
| 237 | + @ [%z(href("%R/attachdelete?page=%t&file=%t&from=%R/wiki%%3fname=%f",zPageName,zFile,zPageName))delete</a>] | |
| 240 | 238 | } |
| 241 | 239 | @ </li> |
| 242 | 240 | } |
| 243 | 241 | if( cnt ){ |
| 244 | 242 | @ </ul> |
| @@ -544,11 +542,11 @@ | ||
| 544 | 542 | ** Function called to output extra text at the end of each line in |
| 545 | 543 | ** a wiki history listing. |
| 546 | 544 | */ |
| 547 | 545 | static void wiki_history_extra(int rid){ |
| 548 | 546 | if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){ |
| 549 | - @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a> | |
| 547 | + @ %z(href("%R/wdiff?name=%t&a=%d",zWikiPageName,rid))[diff]</a> | |
| 550 | 548 | } |
| 551 | 549 | } |
| 552 | 550 | |
| 553 | 551 | /* |
| 554 | 552 | ** WEBPAGE: whistory |
| @@ -560,11 +558,11 @@ | ||
| 560 | 558 | Stmt q; |
| 561 | 559 | char *zTitle; |
| 562 | 560 | char *zSQL; |
| 563 | 561 | const char *zPageName; |
| 564 | 562 | login_check_credentials(); |
| 565 | - if( !g.perm.History ){ login_needed(); return; } | |
| 563 | + if( !g.perm.Hyperlink ){ login_needed(); return; } | |
| 566 | 564 | zPageName = PD("name",""); |
| 567 | 565 | zTitle = mprintf("History Of %s", zPageName); |
| 568 | 566 | style_header(zTitle); |
| 569 | 567 | free(zTitle); |
| 570 | 568 | |
| @@ -597,11 +595,11 @@ | ||
| 597 | 595 | Blob w1, w2, d; |
| 598 | 596 | int diffFlags; |
| 599 | 597 | |
| 600 | 598 | login_check_credentials(); |
| 601 | 599 | rid1 = atoi(PD("a","0")); |
| 602 | - if( !g.perm.History ){ login_needed(); return; } | |
| 600 | + if( !g.perm.Hyperlink ){ login_needed(); return; } | |
| 603 | 601 | if( rid1==0 ) fossil_redirect_home(); |
| 604 | 602 | rid2 = atoi(PD("b","0")); |
| 605 | 603 | zPageName = PD("name",""); |
| 606 | 604 | zTitle = mprintf("Changes To %s", zPageName); |
| 607 | 605 | style_header(zTitle); |
| @@ -674,13 +672,13 @@ | ||
| 674 | 672 | wiki_prepare_page_list(&q); |
| 675 | 673 | while( db_step(&q)==SQLITE_ROW ){ |
| 676 | 674 | const char *zName = db_column_text(&q, 0); |
| 677 | 675 | int size = db_column_int(&q, 1); |
| 678 | 676 | if( size>0 ){ |
| 679 | - @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li> | |
| 677 | + @ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li> | |
| 680 | 678 | }else if( showAll ){ |
| 681 | - @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)"><s>%h(zName)</s></a></li> | |
| 679 | + @ <li>%z(href("%R/wiki?name=%T",zName))<s>%h(zName)</s></a></li> | |
| 682 | 680 | } |
| 683 | 681 | } |
| 684 | 682 | db_finalize(&q); |
| 685 | 683 | @ </ul> |
| 686 | 684 | style_footer(); |
| @@ -704,11 +702,11 @@ | ||
| 704 | 702 | "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'" |
| 705 | 703 | " ORDER BY lower(tagname) /*sort*/" , |
| 706 | 704 | zTitle); |
| 707 | 705 | while( db_step(&q)==SQLITE_ROW ){ |
| 708 | 706 | const char *zName = db_column_text(&q, 0); |
| 709 | - @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li> | |
| 707 | + @ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li> | |
| 710 | 708 | } |
| 711 | 709 | db_finalize(&q); |
| 712 | 710 | @ </ul> |
| 713 | 711 | style_footer(); |
| 714 | 712 | } |
| 715 | 713 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -104,11 +104,11 @@ | |
| 104 | return; |
| 105 | } |
| 106 | style_header("Home"); |
| 107 | @ <p>This is a stub home-page for the project. |
| 108 | @ To fill in this page, first go to |
| 109 | @ <a href="%s(g.zTop)/setup_config">setup/config</a> |
| 110 | @ and establish a "Project Name". Then create a |
| 111 | @ wiki page with that name. The content of that wiki page |
| 112 | @ will be displayed in place of this message.</p> |
| 113 | style_footer(); |
| 114 | } |
| @@ -142,27 +142,25 @@ | |
| 142 | if( zPageName==0 ){ |
| 143 | style_header("Wiki"); |
| 144 | @ <ul> |
| 145 | { char *zHomePageName = db_get("project-name",0); |
| 146 | if( zHomePageName ){ |
| 147 | @ <li> <a href="%s(g.zTop)/wiki?name=%t(zHomePageName)"> |
| 148 | @ %h(zHomePageName)</a> wiki home page.</li> |
| 149 | } |
| 150 | } |
| 151 | @ <li> <a href="%s(g.zTop)/timeline?y=w">Recent changes</a> to wiki |
| 152 | @ pages. </li> |
| 153 | @ <li> <a href="%s(g.zTop)/wiki_rules">Formatting rules</a> for |
| 154 | @ wiki.</li> |
| 155 | @ <li> Use the <a href="%s(g.zTop)/wiki?name=Sandbox">Sandbox</a> |
| 156 | @ to experiment.</li> |
| 157 | if( g.perm.NewWiki ){ |
| 158 | @ <li> Create a <a href="%s(g.zTop)/wikinew">new wiki page</a>.</li> |
| 159 | if( g.perm.Write ){ |
| 160 | @ <li> Create a <a href="%s(g.zTop)/eventedit">new event</a>.</li> |
| 161 | } |
| 162 | } |
| 163 | @ <li> <a href="%s(g.zTop)/wcontent">List of All Wiki Pages</a> |
| 164 | @ available on this server.</li> |
| 165 | @ <li> <form method="get" action="%s(g.zTop)/wfind"><div> |
| 166 | @ Search wiki titles: <input type="text" name="title"/> |
| 167 | @ <input type="submit" /></div></form> |
| 168 | @ </li> |
| @@ -199,11 +197,11 @@ | |
| 199 | } |
| 200 | if( rid && g.perm.ApndWiki ){ |
| 201 | style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T", |
| 202 | g.zTop, zPageName); |
| 203 | } |
| 204 | if( g.perm.History ){ |
| 205 | style_submenu_element("History", "History", "%s/whistory?name=%T", |
| 206 | g.zTop, zPageName); |
| 207 | } |
| 208 | } |
| 209 | style_header(zPageName); |
| @@ -225,20 +223,20 @@ | |
| 225 | @ <hr /><h2>Attachments:</h2> |
| 226 | @ <ul> |
| 227 | } |
| 228 | cnt++; |
| 229 | @ <li> |
| 230 | if( g.perm.History && g.perm.Read ){ |
| 231 | @ <a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)"> |
| 232 | @ %h(zFile)</a> |
| 233 | }else{ |
| 234 | @ %h(zFile) |
| 235 | } |
| 236 | @ added by %h(zUser) on |
| 237 | hyperlink_to_date(zDate, "."); |
| 238 | if( g.perm.WrWiki && g.perm.Attach ){ |
| 239 | @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>] |
| 240 | } |
| 241 | @ </li> |
| 242 | } |
| 243 | if( cnt ){ |
| 244 | @ </ul> |
| @@ -544,11 +542,11 @@ | |
| 544 | ** Function called to output extra text at the end of each line in |
| 545 | ** a wiki history listing. |
| 546 | */ |
| 547 | static void wiki_history_extra(int rid){ |
| 548 | if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){ |
| 549 | @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a> |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | /* |
| 554 | ** WEBPAGE: whistory |
| @@ -560,11 +558,11 @@ | |
| 560 | Stmt q; |
| 561 | char *zTitle; |
| 562 | char *zSQL; |
| 563 | const char *zPageName; |
| 564 | login_check_credentials(); |
| 565 | if( !g.perm.History ){ login_needed(); return; } |
| 566 | zPageName = PD("name",""); |
| 567 | zTitle = mprintf("History Of %s", zPageName); |
| 568 | style_header(zTitle); |
| 569 | free(zTitle); |
| 570 | |
| @@ -597,11 +595,11 @@ | |
| 597 | Blob w1, w2, d; |
| 598 | int diffFlags; |
| 599 | |
| 600 | login_check_credentials(); |
| 601 | rid1 = atoi(PD("a","0")); |
| 602 | if( !g.perm.History ){ login_needed(); return; } |
| 603 | if( rid1==0 ) fossil_redirect_home(); |
| 604 | rid2 = atoi(PD("b","0")); |
| 605 | zPageName = PD("name",""); |
| 606 | zTitle = mprintf("Changes To %s", zPageName); |
| 607 | style_header(zTitle); |
| @@ -674,13 +672,13 @@ | |
| 674 | wiki_prepare_page_list(&q); |
| 675 | while( db_step(&q)==SQLITE_ROW ){ |
| 676 | const char *zName = db_column_text(&q, 0); |
| 677 | int size = db_column_int(&q, 1); |
| 678 | if( size>0 ){ |
| 679 | @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li> |
| 680 | }else if( showAll ){ |
| 681 | @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)"><s>%h(zName)</s></a></li> |
| 682 | } |
| 683 | } |
| 684 | db_finalize(&q); |
| 685 | @ </ul> |
| 686 | style_footer(); |
| @@ -704,11 +702,11 @@ | |
| 704 | "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'" |
| 705 | " ORDER BY lower(tagname) /*sort*/" , |
| 706 | zTitle); |
| 707 | while( db_step(&q)==SQLITE_ROW ){ |
| 708 | const char *zName = db_column_text(&q, 0); |
| 709 | @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li> |
| 710 | } |
| 711 | db_finalize(&q); |
| 712 | @ </ul> |
| 713 | style_footer(); |
| 714 | } |
| 715 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -104,11 +104,11 @@ | |
| 104 | return; |
| 105 | } |
| 106 | style_header("Home"); |
| 107 | @ <p>This is a stub home-page for the project. |
| 108 | @ To fill in this page, first go to |
| 109 | @ %z(href("%R/setup_config"))setup/config</a> |
| 110 | @ and establish a "Project Name". Then create a |
| 111 | @ wiki page with that name. The content of that wiki page |
| 112 | @ will be displayed in place of this message.</p> |
| 113 | style_footer(); |
| 114 | } |
| @@ -142,27 +142,25 @@ | |
| 142 | if( zPageName==0 ){ |
| 143 | style_header("Wiki"); |
| 144 | @ <ul> |
| 145 | { char *zHomePageName = db_get("project-name",0); |
| 146 | if( zHomePageName ){ |
| 147 | @ <li> %z(href("%R/wiki?name=%t",zHomePageName)) |
| 148 | @ %h(zHomePageName)</a> wiki home page.</li> |
| 149 | } |
| 150 | } |
| 151 | @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> |
| 152 | @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li> |
| 153 | @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> |
| 154 | @ to experiment.</li> |
| 155 | if( g.perm.NewWiki ){ |
| 156 | @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> |
| 157 | if( g.perm.Write ){ |
| 158 | @ <li> Create a %z(href("%R/eventedit"))new event</a>.</li> |
| 159 | } |
| 160 | } |
| 161 | @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> |
| 162 | @ available on this server.</li> |
| 163 | @ <li> <form method="get" action="%s(g.zTop)/wfind"><div> |
| 164 | @ Search wiki titles: <input type="text" name="title"/> |
| 165 | @ <input type="submit" /></div></form> |
| 166 | @ </li> |
| @@ -199,11 +197,11 @@ | |
| 197 | } |
| 198 | if( rid && g.perm.ApndWiki ){ |
| 199 | style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T", |
| 200 | g.zTop, zPageName); |
| 201 | } |
| 202 | if( g.perm.Hyperlink ){ |
| 203 | style_submenu_element("History", "History", "%s/whistory?name=%T", |
| 204 | g.zTop, zPageName); |
| 205 | } |
| 206 | } |
| 207 | style_header(zPageName); |
| @@ -225,20 +223,20 @@ | |
| 223 | @ <hr /><h2>Attachments:</h2> |
| 224 | @ <ul> |
| 225 | } |
| 226 | cnt++; |
| 227 | @ <li> |
| 228 | if( g.perm.Hyperlink && g.perm.Read ){ |
| 229 | @ %z(href("%R/attachview?page=%T&file=%t",zPageName,zFile)) |
| 230 | @ %h(zFile)</a> |
| 231 | }else{ |
| 232 | @ %h(zFile) |
| 233 | } |
| 234 | @ added by %h(zUser) on |
| 235 | hyperlink_to_date(zDate, "."); |
| 236 | if( g.perm.WrWiki && g.perm.Attach ){ |
| 237 | @ [%z(href("%R/attachdelete?page=%t&file=%t&from=%R/wiki%%3fname=%f",zPageName,zFile,zPageName))delete</a>] |
| 238 | } |
| 239 | @ </li> |
| 240 | } |
| 241 | if( cnt ){ |
| 242 | @ </ul> |
| @@ -544,11 +542,11 @@ | |
| 542 | ** Function called to output extra text at the end of each line in |
| 543 | ** a wiki history listing. |
| 544 | */ |
| 545 | static void wiki_history_extra(int rid){ |
| 546 | if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){ |
| 547 | @ %z(href("%R/wdiff?name=%t&a=%d",zWikiPageName,rid))[diff]</a> |
| 548 | } |
| 549 | } |
| 550 | |
| 551 | /* |
| 552 | ** WEBPAGE: whistory |
| @@ -560,11 +558,11 @@ | |
| 558 | Stmt q; |
| 559 | char *zTitle; |
| 560 | char *zSQL; |
| 561 | const char *zPageName; |
| 562 | login_check_credentials(); |
| 563 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 564 | zPageName = PD("name",""); |
| 565 | zTitle = mprintf("History Of %s", zPageName); |
| 566 | style_header(zTitle); |
| 567 | free(zTitle); |
| 568 | |
| @@ -597,11 +595,11 @@ | |
| 595 | Blob w1, w2, d; |
| 596 | int diffFlags; |
| 597 | |
| 598 | login_check_credentials(); |
| 599 | rid1 = atoi(PD("a","0")); |
| 600 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 601 | if( rid1==0 ) fossil_redirect_home(); |
| 602 | rid2 = atoi(PD("b","0")); |
| 603 | zPageName = PD("name",""); |
| 604 | zTitle = mprintf("Changes To %s", zPageName); |
| 605 | style_header(zTitle); |
| @@ -674,13 +672,13 @@ | |
| 672 | wiki_prepare_page_list(&q); |
| 673 | while( db_step(&q)==SQLITE_ROW ){ |
| 674 | const char *zName = db_column_text(&q, 0); |
| 675 | int size = db_column_int(&q, 1); |
| 676 | if( size>0 ){ |
| 677 | @ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li> |
| 678 | }else if( showAll ){ |
| 679 | @ <li>%z(href("%R/wiki?name=%T",zName))<s>%h(zName)</s></a></li> |
| 680 | } |
| 681 | } |
| 682 | db_finalize(&q); |
| 683 | @ </ul> |
| 684 | style_footer(); |
| @@ -704,11 +702,11 @@ | |
| 702 | "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'" |
| 703 | " ORDER BY lower(tagname) /*sort*/" , |
| 704 | zTitle); |
| 705 | while( db_step(&q)==SQLITE_ROW ){ |
| 706 | const char *zName = db_column_text(&q, 0); |
| 707 | @ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li> |
| 708 | } |
| 709 | db_finalize(&q); |
| 710 | @ </ul> |
| 711 | style_footer(); |
| 712 | } |
| 713 |
+8
-10
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -1049,11 +1049,11 @@ | ||
| 1049 | 1049 | blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget); |
| 1050 | 1050 | }else{ |
| 1051 | 1051 | zTerm = ""; |
| 1052 | 1052 | } |
| 1053 | 1053 | }else if( zTarget[0]=='.' || zTarget[0]=='#' ){ |
| 1054 | - if( 1 /* g.perm.History */ ){ | |
| 1054 | + if( 1 ){ | |
| 1055 | 1055 | blob_appendf(p->pOut, "<a href=\"%h\">", zTarget); |
| 1056 | 1056 | }else{ |
| 1057 | 1057 | zTerm = ""; |
| 1058 | 1058 | } |
| 1059 | 1059 | }else if( is_valid_uuid(zTarget) ){ |
| @@ -1061,36 +1061,34 @@ | ||
| 1061 | 1061 | if( is_ticket(zTarget, &isClosed) ){ |
| 1062 | 1062 | /* Special display processing for tickets. Display the hyperlink |
| 1063 | 1063 | ** as crossed out if the ticket is closed. |
| 1064 | 1064 | */ |
| 1065 | 1065 | if( isClosed ){ |
| 1066 | - if( g.perm.History ){ | |
| 1066 | + if( g.perm.Hyperlink ){ | |
| 1067 | 1067 | blob_appendf(p->pOut, |
| 1068 | - "<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">[", | |
| 1069 | - g.zTop, zTarget | |
| 1068 | + "%z<span class=\"wikiTagCancelled\">[", | |
| 1069 | + href("%R/info/%s",zTarget) | |
| 1070 | 1070 | ); |
| 1071 | 1071 | zTerm = "]</span></a>"; |
| 1072 | 1072 | }else{ |
| 1073 | 1073 | blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">["); |
| 1074 | 1074 | zTerm = "]</span>"; |
| 1075 | 1075 | } |
| 1076 | 1076 | }else{ |
| 1077 | - if( g.perm.History ){ | |
| 1078 | - blob_appendf(p->pOut,"<a href=\"%s/info/%s\">[", | |
| 1079 | - g.zTop, zTarget | |
| 1080 | - ); | |
| 1077 | + if( g.perm.Hyperlink ){ | |
| 1078 | + blob_appendf(p->pOut,"%z[", href("%R/info/%s", zTarget)); | |
| 1081 | 1079 | zTerm = "]</a>"; |
| 1082 | 1080 | }else{ |
| 1083 | 1081 | blob_appendf(p->pOut, "["); |
| 1084 | 1082 | zTerm = "]"; |
| 1085 | 1083 | } |
| 1086 | 1084 | } |
| 1087 | 1085 | }else if( !in_this_repo(zTarget) ){ |
| 1088 | 1086 | blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget); |
| 1089 | 1087 | zTerm = "]</span>"; |
| 1090 | - }else if( g.perm.History ){ | |
| 1091 | - blob_appendf(p->pOut, "<a href=\"%s/info/%s\">[", g.zTop, zTarget); | |
| 1088 | + }else if( g.perm.Hyperlink ){ | |
| 1089 | + blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget)); | |
| 1092 | 1090 | zTerm = "]</a>"; |
| 1093 | 1091 | } |
| 1094 | 1092 | }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-' |
| 1095 | 1093 | && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){ |
| 1096 | 1094 | blob_appendf(p->pOut, "<a href=\"%s/timeline?c=%T\">", g.zTop, zTarget); |
| 1097 | 1095 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1049,11 +1049,11 @@ | |
| 1049 | blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget); |
| 1050 | }else{ |
| 1051 | zTerm = ""; |
| 1052 | } |
| 1053 | }else if( zTarget[0]=='.' || zTarget[0]=='#' ){ |
| 1054 | if( 1 /* g.perm.History */ ){ |
| 1055 | blob_appendf(p->pOut, "<a href=\"%h\">", zTarget); |
| 1056 | }else{ |
| 1057 | zTerm = ""; |
| 1058 | } |
| 1059 | }else if( is_valid_uuid(zTarget) ){ |
| @@ -1061,36 +1061,34 @@ | |
| 1061 | if( is_ticket(zTarget, &isClosed) ){ |
| 1062 | /* Special display processing for tickets. Display the hyperlink |
| 1063 | ** as crossed out if the ticket is closed. |
| 1064 | */ |
| 1065 | if( isClosed ){ |
| 1066 | if( g.perm.History ){ |
| 1067 | blob_appendf(p->pOut, |
| 1068 | "<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">[", |
| 1069 | g.zTop, zTarget |
| 1070 | ); |
| 1071 | zTerm = "]</span></a>"; |
| 1072 | }else{ |
| 1073 | blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">["); |
| 1074 | zTerm = "]</span>"; |
| 1075 | } |
| 1076 | }else{ |
| 1077 | if( g.perm.History ){ |
| 1078 | blob_appendf(p->pOut,"<a href=\"%s/info/%s\">[", |
| 1079 | g.zTop, zTarget |
| 1080 | ); |
| 1081 | zTerm = "]</a>"; |
| 1082 | }else{ |
| 1083 | blob_appendf(p->pOut, "["); |
| 1084 | zTerm = "]"; |
| 1085 | } |
| 1086 | } |
| 1087 | }else if( !in_this_repo(zTarget) ){ |
| 1088 | blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget); |
| 1089 | zTerm = "]</span>"; |
| 1090 | }else if( g.perm.History ){ |
| 1091 | blob_appendf(p->pOut, "<a href=\"%s/info/%s\">[", g.zTop, zTarget); |
| 1092 | zTerm = "]</a>"; |
| 1093 | } |
| 1094 | }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-' |
| 1095 | && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){ |
| 1096 | blob_appendf(p->pOut, "<a href=\"%s/timeline?c=%T\">", g.zTop, zTarget); |
| 1097 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1049,11 +1049,11 @@ | |
| 1049 | blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget); |
| 1050 | }else{ |
| 1051 | zTerm = ""; |
| 1052 | } |
| 1053 | }else if( zTarget[0]=='.' || zTarget[0]=='#' ){ |
| 1054 | if( 1 ){ |
| 1055 | blob_appendf(p->pOut, "<a href=\"%h\">", zTarget); |
| 1056 | }else{ |
| 1057 | zTerm = ""; |
| 1058 | } |
| 1059 | }else if( is_valid_uuid(zTarget) ){ |
| @@ -1061,36 +1061,34 @@ | |
| 1061 | if( is_ticket(zTarget, &isClosed) ){ |
| 1062 | /* Special display processing for tickets. Display the hyperlink |
| 1063 | ** as crossed out if the ticket is closed. |
| 1064 | */ |
| 1065 | if( isClosed ){ |
| 1066 | if( g.perm.Hyperlink ){ |
| 1067 | blob_appendf(p->pOut, |
| 1068 | "%z<span class=\"wikiTagCancelled\">[", |
| 1069 | href("%R/info/%s",zTarget) |
| 1070 | ); |
| 1071 | zTerm = "]</span></a>"; |
| 1072 | }else{ |
| 1073 | blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">["); |
| 1074 | zTerm = "]</span>"; |
| 1075 | } |
| 1076 | }else{ |
| 1077 | if( g.perm.Hyperlink ){ |
| 1078 | blob_appendf(p->pOut,"%z[", href("%R/info/%s", zTarget)); |
| 1079 | zTerm = "]</a>"; |
| 1080 | }else{ |
| 1081 | blob_appendf(p->pOut, "["); |
| 1082 | zTerm = "]"; |
| 1083 | } |
| 1084 | } |
| 1085 | }else if( !in_this_repo(zTarget) ){ |
| 1086 | blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget); |
| 1087 | zTerm = "]</span>"; |
| 1088 | }else if( g.perm.Hyperlink ){ |
| 1089 | blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget)); |
| 1090 | zTerm = "]</a>"; |
| 1091 | } |
| 1092 | }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-' |
| 1093 | && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){ |
| 1094 | blob_appendf(p->pOut, "<a href=\"%s/timeline?c=%T\">", g.zTop, zTarget); |
| 1095 |