PowerGlove (OP)
|
![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
January 04, 2023, 08:43:43 AM Last edit: April 27, 2024, 09:47:02 PM by PowerGlove Merited by LoyceV (42), hugeblack (25), theymos (20), vapourminer (20), Welsh (20), dkbit98 (20), NotATether (20), ABCbits (11), Mitchell (10), fillippone (10), TryNinja (8), hosseinimr93 (8), dbshck (8), ibminer (5), Pmalek (4), Cyrus (3), EFS (2), NeuroticFish (2), Halab (2), DdmrDdmr (2), tranthidung (2), Husna QA (2), julerz12 (1), Fivestar4everMVP (1), vv181 (1), GazetaBitcoin (1), SatoPrincess (1) |
|
Anyone else notice that if you wrap something that contains really long lines with [code] tags, that it'll look okay in the actual post, but if you browse your post history afterwards, it'll render much wider than the surrounding posts and throw everything out? Here's an example of what I mean: I recently posted some code that contained a few really long lines, here. If you look at that post, it renders without issue (i.e. that post doesn't render wider than the other posts in that thread). But, if you look (currently) at the first page of my post history, you'll see that the posts on that page are rendering strangely, making them difficult to read without lots of horizontal scrolling. I messed around for a few (very frustrating) hours trying to get to the bottom of this, and managed to come up with the following SMF patch: --- /var/www/baseline/Themes/default/Profile.template.php 2007-02-03 15:55:14.000000000 +0000 +++ /var/www/modified/Themes/default/Profile.template.php 2023-01-06 00:15:50.000000000 +0000 @@ -341,42 +341,45 @@ if (!empty($context['posts'])) { // Page numbers. echo ' <tr class="catbg3"> <td colspan="3"> ', $txt[139], ': ', $context['page_index'], ' </td> </tr> </table>'; // Button shortcuts $quote_button = create_button('quote.gif', 145, 'smf240', 'align="middle"'); $reply_button = create_button('reply_sm.gif', 146, 146, 'align="middle"'); $remove_button = create_button('delete.gif', 121, 31, 'align="middle"'); $notify_button = create_button('notify_sm.gif', 131, 125, 'align="middle"'); // For every post to be displayed, give it its own subtable, and show the important details of the post. foreach ($context['posts'] as $post) { + // style="table-layout: fixed;" was added to each subtable as a partial fix for code sometimes rendering too wide (see https://bitcointalk.org/index.php?topic=5432954). + // This could also have been done further up the hierarchy, but this is a more natural place to apply the fix, and (surprisingly) produces slightly superior results, too. + // There's a second (progressive enhancement) part to this fix, after this foreach. echo ' - <table border="0" width="85%" cellspacing="1" cellpadding="0" class="bordercolor" align="center"> + <table border="0" width="85%" cellspacing="1" cellpadding="0" class="bordercolor" align="center" style="table-layout: fixed;"> <tr> <td width="100%"> <table border="0" width="100%" cellspacing="0" cellpadding="4" class="bordercolor" align="center"> <tr class="titlebg2"> <td style="padding: 0 1ex;"> ', $post['counter'], ' </td> <td width="75%" class="middletext"> <a href="', $scripturl, '#', $post['category']['id'], '">', $post['category']['name'], '</a> / <a href="', $scripturl, '?board=', $post['board']['id'], '.0">', $post['board']['name'], '</a> / <a href="', $scripturl, '?topic=', $post['topic'], '.', $post['start'], '#msg', $post['id'], '">', $post['subject'], '</a> </td> <td class="middletext" align="right" style="padding: 0 1ex; white-space: nowrap;"> ', $txt[30], ': ', $post['time'], ' </td> </tr> <tr> <td width="100%" height="80" colspan="3" valign="top" class="windowbg2"> <div class="post">', $post['body'], '</div> </td> </tr> <tr> @@ -391,40 +394,67 @@ if ($post['can_reply']) echo ' <a href="', $scripturl, '?action=post;topic=', $post['topic'], '.', $post['start'], '">', $reply_button, '</a>', $context['menu_separator'], ' <a href="', $scripturl, '?action=post;topic=', $post['topic'], '.', $post['start'], ';quote=', $post['id'], ';sesc=', $context['session_id'], '">', $quote_button, '</a>'; if ($post['can_reply'] && $post['can_mark_notify']) echo ' ', $context['menu_separator']; if ($post['can_mark_notify']) echo ' <a href="' . $scripturl . '?action=notify;topic=' . $post['topic'] . '.' . $post['start'] . '">' . $notify_button . '</a>'; echo ' </span></td> </tr> </table> </td> </tr> </table>'; } + // This is the second part of the fix for code sometimes rendering too wide (the first part is at the top of the preceding foreach). + // The first part only prevents the problem from affecting surrounding posts, but when JavaScript is available, a more complete fix can be made. + // This code visits each eligible element and (defensively) sets the width to the same computed value. + // The width is computed once and then reused, not because of performance considerations (that's a nice consequence), but because that approach fixed some (rare) problem cases that came up in testing. + // The initial version of this code didn't account for the presence of <pre> elements being browser-dependent (that's what the "target" variable now does). + echo ' + <script language="JavaScript" type="text/javascript"><!-- // --><![CDATA[ + window.addEventListener("load", fix_wide_code_elements, false); + function fix_wide_code_elements() { + var all_code_elements = document.body.getElementsByClassName("code"); + var same_computed_width = 0; + for(var i = 0; i < all_code_elements.length; i++) { + var element = all_code_elements[i]; + if(element.tagName.toLowerCase() == "div") { + if(same_computed_width == 0) { + var target = element.firstElementChild && element.firstElementChild.tagName.toLowerCase() == "pre" ? element.firstElementChild : element; + element.style.width = ""; + target.style.whiteSpace = "pre-wrap"; + same_computed_width = element.clientWidth; + target.style.whiteSpace = ""; + } + element.style.width = same_computed_width != 0 ? same_computed_width + "px" : ""; + } + } + } + // ]]></script>'; + // Show more page numbers. echo ' <table border="0" width="85%" cellspacing="1" cellpadding="4" class="bordercolor" align="center"> <tr> <td colspan="3" class="catbg3"> ', $txt[139], ': ', $context['page_index'], ' </td> </tr> </table>'; } // No posts? Just end the table with a informative message. else echo ' <tr class="windowbg2"> <td> ', $txt[170], ' </td> </tr> </table>'; }
Edit: Updated to account for browser differences pointed out by shahzadafzal. @theymos: Please consider merging this fix, or applying your mind to the problem and coming up with something better. Thanks!
So, I ended up sinking more time into this problem and coming up with a (much) better patch... ![Smiley](https://bitcointalk.org/Smileys/default/smiley.gif) (Thanks to PX-Z for the script they left here, those particular DOM modifications weren't the ones I ended up using, but, the final fix I arrived at was definitely influenced by that post.) --- baseline/Themes/default/Profile.template.php 2007-02-03 15:55:14.000000000 +0000 +++ modified/Themes/default/Profile.template.php 2024-04-27 20:51:35.000000000 +0000 @@ -346,43 +346,48 @@ <td colspan="3"> ', $txt[139], ': ', $context['page_index'], ' </td> </tr> </table>'; // Button shortcuts $quote_button = create_button('quote.gif', 145, 'smf240', 'align="middle"'); $reply_button = create_button('reply_sm.gif', 146, 146, 'align="middle"'); $remove_button = create_button('delete.gif', 121, 31, 'align="middle"'); $notify_button = create_button('notify_sm.gif', 131, 125, 'align="middle"'); + // Controls whether or not an effort is made to prevent "wide" content from breaking the layout (e.g. code blocks containing really long lines). + $with_wide_fix = true; + // For every post to be displayed, give it its own subtable, and show the important details of the post. foreach ($context['posts'] as $post) { echo ' <table border="0" width="85%" cellspacing="1" cellpadding="0" class="bordercolor" align="center"> <tr> <td width="100%"> <table border="0" width="100%" cellspacing="0" cellpadding="4" class="bordercolor" align="center"> <tr class="titlebg2"> <td style="padding: 0 1ex;"> ', $post['counter'], ' </td> <td width="75%" class="middletext"> <a href="', $scripturl, '#', $post['category']['id'], '">', $post['category']['name'], '</a> / <a href="', $scripturl, '?board=', $post['board']['id'], '.0">', $post['board']['name'], '</a> / <a href="', $scripturl, '?topic=', $post['topic'], '.', $post['start'], '#msg', $post['id'], '">', $post['subject'], '</a> </td> <td class="middletext" align="right" style="padding: 0 1ex; white-space: nowrap;"> ', $txt[30], ': ', $post['time'], ' </td> - </tr> + </tr>', $with_wide_fix ? ' + </table> + <table style="table-layout: fixed;" border="0" width="100%" cellspacing="0" cellpadding="4" class="bordercolor" align="center">' : '', ' <tr> <td width="100%" height="80" colspan="3" valign="top" class="windowbg2"> <div class="post">', $post['body'], '</div> </td> </tr> <tr> <td colspan="3" class="windowbg2" align="', !$context['right_to_left'] ? 'right' : 'left', '"><span class="middletext">'; if ($post['can_delete']) echo ' <a href="', $scripturl, '?action=profile;u=', $context['current_member'], ';sa=showPosts;start=', $context['start'], ';delete=', $post['id'], ';sesc=', $context['session_id'], '" onclick="return confirm(\'', $txt[154], '?\');">', $remove_button, '</a>'; if ($post['can_delete'] && ($post['can_mark_notify'] || $post['can_reply']))
I also came up with a patch that fixes this problem when previewing PMs and when replying to PMs: --- baseline/Themes/default/PersonalMessage.template.php 2006-12-01 15:43:03.000000000 +0000 +++ modified/Themes/default/PersonalMessage.template.php 2024-04-27 20:51:50.000000000 +0000 @@ -855,29 +855,32 @@ <tr> <td class="windowbg">'; foreach ($context['send_log']['sent'] as $log_entry) echo '<span style="color: green">', $log_entry, '</span><br />'; foreach ($context['send_log']['failed'] as $log_entry) echo '<span style="color: red">', $log_entry, '</span><br />'; echo ' </td> </tr> </table><br />'; } + // Controls whether or not an effort is made to prevent "wide" content from breaking the layout (e.g. code blocks containing really long lines). + $with_wide_fix = true; + // Show the preview of the personal message. if (isset($context['preview_message'])) echo ' <br /> - <table border="0" width="80%" cellspacing="1" cellpadding="3" class="bordercolor" align="center"> + <table ', $with_wide_fix ? 'style="table-layout: fixed;" ' : '', 'border="0" width="80%" cellspacing="1" cellpadding="3" class="bordercolor" align="center"> <tr class="titlebg"> <td>', $context['preview_subject'], '</td> </tr> <tr> <td class="windowbg"> ', $context['preview_message'], ' </td> </tr> </table><br />'; // Main message editing box. echo ' @@ -985,30 +988,30 @@ </table>'; // Some hidden information is needed in order to make the spell checking work. if ($context['show_spellchecking']) echo ' <form name="spell_form" id="spell_form" method="post" accept-charset="', $context['character_set'], '" target="spellWindow" action="', $scripturl, '?action=spellcheck"><input type="hidden" name="spellstring" value="" /></form>'; // Show the message you're replying to. if ($context['reply']) echo ' <br /> <br /> - <table width="100%" border="0" cellspacing="1" cellpadding="4" class="bordercolor"> + <table ', $with_wide_fix ? 'style="table-layout: fixed;" ' : '', 'width="100%" border="0" cellspacing="1" cellpadding="4" class="bordercolor"> <tr> <td colspan="2" class="windowbg"><b>', $txt[319], ': ', $context['quoted_message']['subject'], '</b></td> </tr> <tr> - <td class="windowbg2"> + <td ', $with_wide_fix ? 'colspan="2" ' : '', 'class="windowbg2"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td class="windowbg2">', $txt[318], ': ', $context['quoted_message']['member']['name'], '</td> <td class="windowbg2" align="right">', $txt[30], ': ', $context['quoted_message']['time'], '</td> </tr> </table> </td> </tr> <tr> <td colspan="2" class="windowbg">', $context['quoted_message']['body'], '</td> </tr> </table>';
|