Fossil SCM
In the forum, provide a hyperlink from the name of the author of each post to a timeline of their most recent posts.
Commit
46d7ccd45e66a8b467ad3c10ae3b7871094015f53246f192675e25ec6c749fd4
Parent
1464e18add63901…
1 file changed
+19
-9
+19
-9
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -383,10 +383,13 @@ | ||
| 383 | 383 | ** If it does, that becomes the new display name. If not, let the display |
| 384 | 384 | ** name just be the login. |
| 385 | 385 | ** |
| 386 | 386 | ** Space to hold the returned name is obtained from fossil_strdup() or |
| 387 | 387 | ** mprintf() and should be freed by the caller. |
| 388 | +** | |
| 389 | +** HTML markup within the reply has been property escaped. Hyperlinks | |
| 390 | +** may have been added. The result is safe for use with %s. | |
| 388 | 391 | */ |
| 389 | 392 | static char *display_name_from_login(const char *zLogin){ |
| 390 | 393 | static Stmt q; |
| 391 | 394 | char *zResult; |
| 392 | 395 | db_static_prepare(&q, |
| @@ -394,16 +397,19 @@ | ||
| 394 | 397 | ); |
| 395 | 398 | db_bind_text(&q, "$login", zLogin); |
| 396 | 399 | if( db_step(&q)==SQLITE_ROW && db_column_type(&q,0)==SQLITE_TEXT ){ |
| 397 | 400 | const char *zDisplay = db_column_text(&q,0); |
| 398 | 401 | if( fossil_strcmp(zDisplay,zLogin)==0 ){ |
| 399 | - zResult = fossil_strdup(zLogin); | |
| 402 | + zResult = mprintf("%z%h</a>", | |
| 403 | + href("%R/timeline?ss=v&y=f&vfx&u=%t",zLogin),zLogin); | |
| 400 | 404 | }else{ |
| 401 | - zResult = mprintf("%s (%s)", zDisplay, zLogin); | |
| 405 | + zResult = mprintf("%s (%z%h</a>)", zDisplay, | |
| 406 | + href("%R/timeline?ss=v&y=f&vfx&u=%t",zLogin),zLogin); | |
| 402 | 407 | } |
| 403 | 408 | }else{ |
| 404 | - zResult = fossil_strdup(zLogin); | |
| 409 | + zResult = mprintf("%z%h</a>", | |
| 410 | + href("%R/timeline?ss=v&y=f&vfx&u=%t",zLogin),zLogin); | |
| 405 | 411 | } |
| 406 | 412 | db_reset(&q); |
| 407 | 413 | return zResult; |
| 408 | 414 | } |
| 409 | 415 | |
| @@ -414,10 +420,13 @@ | ||
| 414 | 420 | ** Manifest object for itself. |
| 415 | 421 | ** |
| 416 | 422 | ** Memory to hold the display name is attached to p->zDisplayName |
| 417 | 423 | ** and will be freed together with the ForumPost object p when it |
| 418 | 424 | ** is freed. |
| 425 | +** | |
| 426 | +** The returned text has had all HTML markup escaped and is safe for | |
| 427 | +** use within %s. | |
| 419 | 428 | */ |
| 420 | 429 | static char *forum_post_display_name(ForumPost *p, Manifest *pManifest){ |
| 421 | 430 | Manifest *pToFree = 0; |
| 422 | 431 | if( p->zDisplayName ) return p->zDisplayName; |
| 423 | 432 | if( pManifest==0 ){ |
| @@ -481,11 +490,12 @@ | ||
| 481 | 490 | ** * The post is unedited |
| 482 | 491 | ** * The post was last edited by the original author |
| 483 | 492 | ** * The post was last edited by a different person |
| 484 | 493 | */ |
| 485 | 494 | if( p->pEditHead ){ |
| 486 | - zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", p->pEditHead->rDate); | |
| 495 | + zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", | |
| 496 | + p->pEditHead->rDate); | |
| 487 | 497 | }else{ |
| 488 | 498 | zPosterName = forum_post_display_name(p, pManifest); |
| 489 | 499 | zEditorName = zPosterName; |
| 490 | 500 | } |
| 491 | 501 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", p->rDate); |
| @@ -494,23 +504,23 @@ | ||
| 494 | 504 | zEditorName = forum_post_display_name(p, pManifest); |
| 495 | 505 | zHist = bHist ? "" : "&hist"; |
| 496 | 506 | @ <h3 class='forumPostHdr'>(%d(p->sid)\ |
| 497 | 507 | @ .%0*d(fossil_num_digits(p->nEdit))(p->rev)) \ |
| 498 | 508 | if( fossil_strcmp(zPosterName, zEditorName)==0 ){ |
| 499 | - @ By %h(zPosterName) on %h(zDate) edited from \ | |
| 509 | + @ By %s(zPosterName) on %h(zDate) edited from \ | |
| 500 | 510 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 501 | 511 | @ %d(p->sid).%0*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 502 | 512 | }else{ |
| 503 | - @ Originally by %h(zPosterName) \ | |
| 504 | - @ with edits by %h(zEditorName) on %h(zDate) from \ | |
| 513 | + @ Originally by %s(zPosterName) \ | |
| 514 | + @ with edits by %s(zEditorName) on %h(zDate) from \ | |
| 505 | 515 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 506 | 516 | @ %d(p->sid).%0*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 507 | 517 | } |
| 508 | 518 | }else{ |
| 509 | 519 | zPosterName = forum_post_display_name(p, pManifest); |
| 510 | 520 | @ <h3 class='forumPostHdr'>(%d(p->sid)) \ |
| 511 | - @ By %h(zPosterName) on %h(zDate) | |
| 521 | + @ By %s(zPosterName) on %h(zDate) | |
| 512 | 522 | } |
| 513 | 523 | fossil_free(zDate); |
| 514 | 524 | |
| 515 | 525 | |
| 516 | 526 | /* If debugging is enabled, link to the artifact page. */ |
| @@ -1289,11 +1299,11 @@ | ||
| 1289 | 1299 | @ <h1>Thread: %h(pRootPost->zThreadTitle)</h1> |
| 1290 | 1300 | } |
| 1291 | 1301 | @ <h2>Replying To:</h2> |
| 1292 | 1302 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pPost->rDate); |
| 1293 | 1303 | zDisplayName = display_name_from_login(pPost->zUser); |
| 1294 | - @ <h3 class='forumPostHdr'>By %h(zDisplayName) on %h(zDate)</h3> | |
| 1304 | + @ <h3 class='forumPostHdr'>By %s(zDisplayName) on %h(zDate)</h3> | |
| 1295 | 1305 | fossil_free(zDisplayName); |
| 1296 | 1306 | fossil_free(zDate); |
| 1297 | 1307 | forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit", 1); |
| 1298 | 1308 | if( P("preview") && !whitespace_only(zContent) ){ |
| 1299 | 1309 | @ <h2>Preview:</h2> |
| 1300 | 1310 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -383,10 +383,13 @@ | |
| 383 | ** If it does, that becomes the new display name. If not, let the display |
| 384 | ** name just be the login. |
| 385 | ** |
| 386 | ** Space to hold the returned name is obtained from fossil_strdup() or |
| 387 | ** mprintf() and should be freed by the caller. |
| 388 | */ |
| 389 | static char *display_name_from_login(const char *zLogin){ |
| 390 | static Stmt q; |
| 391 | char *zResult; |
| 392 | db_static_prepare(&q, |
| @@ -394,16 +397,19 @@ | |
| 394 | ); |
| 395 | db_bind_text(&q, "$login", zLogin); |
| 396 | if( db_step(&q)==SQLITE_ROW && db_column_type(&q,0)==SQLITE_TEXT ){ |
| 397 | const char *zDisplay = db_column_text(&q,0); |
| 398 | if( fossil_strcmp(zDisplay,zLogin)==0 ){ |
| 399 | zResult = fossil_strdup(zLogin); |
| 400 | }else{ |
| 401 | zResult = mprintf("%s (%s)", zDisplay, zLogin); |
| 402 | } |
| 403 | }else{ |
| 404 | zResult = fossil_strdup(zLogin); |
| 405 | } |
| 406 | db_reset(&q); |
| 407 | return zResult; |
| 408 | } |
| 409 | |
| @@ -414,10 +420,13 @@ | |
| 414 | ** Manifest object for itself. |
| 415 | ** |
| 416 | ** Memory to hold the display name is attached to p->zDisplayName |
| 417 | ** and will be freed together with the ForumPost object p when it |
| 418 | ** is freed. |
| 419 | */ |
| 420 | static char *forum_post_display_name(ForumPost *p, Manifest *pManifest){ |
| 421 | Manifest *pToFree = 0; |
| 422 | if( p->zDisplayName ) return p->zDisplayName; |
| 423 | if( pManifest==0 ){ |
| @@ -481,11 +490,12 @@ | |
| 481 | ** * The post is unedited |
| 482 | ** * The post was last edited by the original author |
| 483 | ** * The post was last edited by a different person |
| 484 | */ |
| 485 | if( p->pEditHead ){ |
| 486 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", p->pEditHead->rDate); |
| 487 | }else{ |
| 488 | zPosterName = forum_post_display_name(p, pManifest); |
| 489 | zEditorName = zPosterName; |
| 490 | } |
| 491 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", p->rDate); |
| @@ -494,23 +504,23 @@ | |
| 494 | zEditorName = forum_post_display_name(p, pManifest); |
| 495 | zHist = bHist ? "" : "&hist"; |
| 496 | @ <h3 class='forumPostHdr'>(%d(p->sid)\ |
| 497 | @ .%0*d(fossil_num_digits(p->nEdit))(p->rev)) \ |
| 498 | if( fossil_strcmp(zPosterName, zEditorName)==0 ){ |
| 499 | @ By %h(zPosterName) on %h(zDate) edited from \ |
| 500 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 501 | @ %d(p->sid).%0*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 502 | }else{ |
| 503 | @ Originally by %h(zPosterName) \ |
| 504 | @ with edits by %h(zEditorName) on %h(zDate) from \ |
| 505 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 506 | @ %d(p->sid).%0*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 507 | } |
| 508 | }else{ |
| 509 | zPosterName = forum_post_display_name(p, pManifest); |
| 510 | @ <h3 class='forumPostHdr'>(%d(p->sid)) \ |
| 511 | @ By %h(zPosterName) on %h(zDate) |
| 512 | } |
| 513 | fossil_free(zDate); |
| 514 | |
| 515 | |
| 516 | /* If debugging is enabled, link to the artifact page. */ |
| @@ -1289,11 +1299,11 @@ | |
| 1289 | @ <h1>Thread: %h(pRootPost->zThreadTitle)</h1> |
| 1290 | } |
| 1291 | @ <h2>Replying To:</h2> |
| 1292 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pPost->rDate); |
| 1293 | zDisplayName = display_name_from_login(pPost->zUser); |
| 1294 | @ <h3 class='forumPostHdr'>By %h(zDisplayName) on %h(zDate)</h3> |
| 1295 | fossil_free(zDisplayName); |
| 1296 | fossil_free(zDate); |
| 1297 | forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit", 1); |
| 1298 | if( P("preview") && !whitespace_only(zContent) ){ |
| 1299 | @ <h2>Preview:</h2> |
| 1300 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -383,10 +383,13 @@ | |
| 383 | ** If it does, that becomes the new display name. If not, let the display |
| 384 | ** name just be the login. |
| 385 | ** |
| 386 | ** Space to hold the returned name is obtained from fossil_strdup() or |
| 387 | ** mprintf() and should be freed by the caller. |
| 388 | ** |
| 389 | ** HTML markup within the reply has been property escaped. Hyperlinks |
| 390 | ** may have been added. The result is safe for use with %s. |
| 391 | */ |
| 392 | static char *display_name_from_login(const char *zLogin){ |
| 393 | static Stmt q; |
| 394 | char *zResult; |
| 395 | db_static_prepare(&q, |
| @@ -394,16 +397,19 @@ | |
| 397 | ); |
| 398 | db_bind_text(&q, "$login", zLogin); |
| 399 | if( db_step(&q)==SQLITE_ROW && db_column_type(&q,0)==SQLITE_TEXT ){ |
| 400 | const char *zDisplay = db_column_text(&q,0); |
| 401 | if( fossil_strcmp(zDisplay,zLogin)==0 ){ |
| 402 | zResult = mprintf("%z%h</a>", |
| 403 | href("%R/timeline?ss=v&y=f&vfx&u=%t",zLogin),zLogin); |
| 404 | }else{ |
| 405 | zResult = mprintf("%s (%z%h</a>)", zDisplay, |
| 406 | href("%R/timeline?ss=v&y=f&vfx&u=%t",zLogin),zLogin); |
| 407 | } |
| 408 | }else{ |
| 409 | zResult = mprintf("%z%h</a>", |
| 410 | href("%R/timeline?ss=v&y=f&vfx&u=%t",zLogin),zLogin); |
| 411 | } |
| 412 | db_reset(&q); |
| 413 | return zResult; |
| 414 | } |
| 415 | |
| @@ -414,10 +420,13 @@ | |
| 420 | ** Manifest object for itself. |
| 421 | ** |
| 422 | ** Memory to hold the display name is attached to p->zDisplayName |
| 423 | ** and will be freed together with the ForumPost object p when it |
| 424 | ** is freed. |
| 425 | ** |
| 426 | ** The returned text has had all HTML markup escaped and is safe for |
| 427 | ** use within %s. |
| 428 | */ |
| 429 | static char *forum_post_display_name(ForumPost *p, Manifest *pManifest){ |
| 430 | Manifest *pToFree = 0; |
| 431 | if( p->zDisplayName ) return p->zDisplayName; |
| 432 | if( pManifest==0 ){ |
| @@ -481,11 +490,12 @@ | |
| 490 | ** * The post is unedited |
| 491 | ** * The post was last edited by the original author |
| 492 | ** * The post was last edited by a different person |
| 493 | */ |
| 494 | if( p->pEditHead ){ |
| 495 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", |
| 496 | p->pEditHead->rDate); |
| 497 | }else{ |
| 498 | zPosterName = forum_post_display_name(p, pManifest); |
| 499 | zEditorName = zPosterName; |
| 500 | } |
| 501 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", p->rDate); |
| @@ -494,23 +504,23 @@ | |
| 504 | zEditorName = forum_post_display_name(p, pManifest); |
| 505 | zHist = bHist ? "" : "&hist"; |
| 506 | @ <h3 class='forumPostHdr'>(%d(p->sid)\ |
| 507 | @ .%0*d(fossil_num_digits(p->nEdit))(p->rev)) \ |
| 508 | if( fossil_strcmp(zPosterName, zEditorName)==0 ){ |
| 509 | @ By %s(zPosterName) on %h(zDate) edited from \ |
| 510 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 511 | @ %d(p->sid).%0*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 512 | }else{ |
| 513 | @ Originally by %s(zPosterName) \ |
| 514 | @ with edits by %s(zEditorName) on %h(zDate) from \ |
| 515 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 516 | @ %d(p->sid).%0*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 517 | } |
| 518 | }else{ |
| 519 | zPosterName = forum_post_display_name(p, pManifest); |
| 520 | @ <h3 class='forumPostHdr'>(%d(p->sid)) \ |
| 521 | @ By %s(zPosterName) on %h(zDate) |
| 522 | } |
| 523 | fossil_free(zDate); |
| 524 | |
| 525 | |
| 526 | /* If debugging is enabled, link to the artifact page. */ |
| @@ -1289,11 +1299,11 @@ | |
| 1299 | @ <h1>Thread: %h(pRootPost->zThreadTitle)</h1> |
| 1300 | } |
| 1301 | @ <h2>Replying To:</h2> |
| 1302 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pPost->rDate); |
| 1303 | zDisplayName = display_name_from_login(pPost->zUser); |
| 1304 | @ <h3 class='forumPostHdr'>By %s(zDisplayName) on %h(zDate)</h3> |
| 1305 | fossil_free(zDisplayName); |
| 1306 | fossil_free(zDate); |
| 1307 | forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit", 1); |
| 1308 | if( P("preview") && !whitespace_only(zContent) ){ |
| 1309 | @ <h2>Preview:</h2> |
| 1310 |