diff --git a/include/class.format.php b/include/class.format.php index b8cfe03be6f60302ce9f5fabd972b012c1694248..70b06a8a37c09f05f0e27017f9d520c08f99cd29 100644 --- a/include/class.format.php +++ b/include/class.format.php @@ -352,7 +352,7 @@ class Format { } //Format text for display.. - function display($text, $inline_images=true) { + function display($text, $inline_images=true, $balance=true) { // Make showing offsite images optional $text = preg_replace_callback('/<img ([^>]*)(src="http[^"]+")([^>]*)\/>/', function($match) { @@ -363,8 +363,10 @@ class Format { }, $text); - //make urls clickable. - $text = self::html_balance($text, false); + if ($balance) + $text = self::html_balance($text, false); + + // make urls clickable. $text = Format::clickableurls($text); if ($inline_images) diff --git a/include/class.thread.php b/include/class.thread.php index c3d58f3b9f56783ef491e18ed35c91bf013a61ba..5b412f2357ca7f25d211bb77a3f4bfc669e9542d 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -378,6 +378,7 @@ class Thread extends VerySimpleModel { ) { $vars['userId'] = $mailinfo['userId'] ?: $C->getUserId(); $vars['message'] = $body; + $vars['flags'] = ThreadEntry::FLAG_COLLABORATOR; if ($object instanceof Threadable) return $object->postThreadEntry('M', $vars); @@ -611,6 +612,9 @@ implements TemplateVariable { const FLAG_GUARDED = 0x0008; // No replace on edit const FLAG_RESENT = 0x0010; + const FLAG_COLLABORATOR = 0x0020; // Message from collaborator + const FLAG_BALANCED = 0x0040; // HTML does not need to be balanced on ::display() + const PERM_EDIT = 'thread.edit'; var $_headers; @@ -665,7 +669,9 @@ implements TemplateVariable { } function getBody() { - return ThreadEntryBody::fromFormattedText($this->body, $this->format); + return ThreadEntryBody::fromFormattedText($this->body, $this->format, + array('balanced' => $this->hasFlag(self::FLAG_BALANCED)) + ); } function setBody($body) { @@ -1354,8 +1360,13 @@ implements TemplateVariable { 'user_id' => $vars['userId'], 'poster' => $poster, 'source' => $vars['source'], + 'flags' => $vars['flags'] ?: 0, )); + if ($entry->format == 'html') + // The current codebase properly balances html + $entry->flags |= self::FLAG_BALANCED; + if (!isset($vars['attachments']) || !$vars['attachments']) // Otherwise, body will be configured in a block below (after // inline attachments are saved and updated in the database) @@ -2113,12 +2124,12 @@ class ThreadEntryBody /* extends SplString */ { return Format::searchable($this->body); } - static function fromFormattedText($text, $format=false) { + static function fromFormattedText($text, $format=false, $options=array()) { switch ($format) { case 'text': return new TextThreadEntryBody($text); case 'html': - return new HtmlThreadEntryBody($text, array('strip-embedded'=>false)); + return new HtmlThreadEntryBody($text, array('strip-embedded'=>false) + $options); default: return new ThreadEntryBody($text); } @@ -2207,7 +2218,7 @@ class HtmlThreadEntryBody extends ThreadEntryBody { case 'pdf': return Format::clickableurls($this->body); default: - return Format::display($this->body); + return Format::display($this->body, true, !$this->options['balanced']); } } } diff --git a/include/staff/templates/thread-entry.tmpl.php b/include/staff/templates/thread-entry.tmpl.php index 5b9c3b132a04de1efbbe530a8059d6dee1d6e6b3..3f3bfee7c97316a62a87ac00716eafdc7e513a32 100644 --- a/include/staff/templates/thread-entry.tmpl.php +++ b/include/staff/templates/thread-entry.tmpl.php @@ -41,9 +41,12 @@ if ($user) echo sprintf(__('Edited on %s by %s'), Format::datetime($entry->updated), ($editor = $entry->getEditor()) ? $editor->getName() : ''); ?>"><?php echo __('Edited'); ?></span> -<?php } ?> -<?php if ($entry->flags & ThreadEntry::FLAG_RESENT) { ?> +<?php } + if ($entry->flags & ThreadEntry::FLAG_RESENT) { ?> <span class="label label-bare"><?php echo __('Resent'); ?></span> +<?php } + if ($entry->flags & ThreadEntry::FLAG_COLLABORATOR) { ?> + <span class="label label-bare"><?php echo __('Collaborator'); ?></span> <?php } ?> </span> </div> diff --git a/scp/css/scp.css b/scp/css/scp.css index 9014081c9fd20d07e6ecafd6d292209da26b9303..12389fb2660b96b1adcc3e97199fd26bae6e3f7c 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -971,6 +971,9 @@ img.avatar { display: inline-block; margin-left: 15px; } +.thread-entry .header .button { + margin-top: -4px; +} .thread-entry .thread-body { border: 1px solid #ddd; diff --git a/scp/js/thread.js b/scp/js/thread.js index 434c8d05d9ac57360ce742abaa11e5c6e1cd8cc5..c590323161e6a3be7ac8d31ffa732802344fceda 100644 --- a/scp/js/thread.js +++ b/scp/js/thread.js @@ -65,7 +65,7 @@ var thread = { .text(' ' + __('Show Images')) .click(function(ev) { imgs.each(function(i, img) { - this.showExternalImage(img); + thread.showExternalImage(img); $(img).removeClass('non-local-image') // Remove placeholder sizing .css({'display':'inline-block'})